diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..5a1774a1a6d4abfa7fecb1ca439d4edcc9f3f5e2 --- /dev/null +++ b/.gitignore @@ -0,0 +1,34 @@ +.idea/ +certs/ + +.DS_Store + +.terraform +*.pem +*rke2.yaml + +*tfstate* +*terraform.lock* + +# dependencies +/node_modules + +# debug +npm-debug.log* + +# ignore developer specific files +# (used frequently in deployments) +patch.yaml +notes +ignore/* + +# Visual Studio Code +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +*.code-workspace + +# Local History for Visual Studio Code +.history/ diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000000000000000000000000000000000000..37888530cfc6768a01b86d324ac43bd6696cc0ba --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,6 @@ +include: + - project: 'big-bang/pipeline-templates/pipeline-templates' + ref: bbci-2-21 + file: '/pipelines/bigbang.yaml' +variables: + PIPELINE_REPO_BRANCH: "bbci-2-21" diff --git a/.gitlab/base_config.md.gotmpl b/.gitlab/base_config.md.gotmpl new file mode 100644 index 0000000000000000000000000000000000000000..d4bba3b02d9c88dfa4bb339f93884e3f7b24d500 --- /dev/null +++ b/.gitlab/base_config.md.gotmpl @@ -0,0 +1,18 @@ +{{ template "chart.header" . }} +{{ template "chart.deprecationWarning" . }} + +{{ template "chart.badgesSection" . }} + +{{ template "chart.description" . }} + +## Getting Started + +To start using Big Bang, you will need to create your own Big Bang environment tailored to your needs. The [Big Bang customer template](https://repo1.dso.mil/big-bang/customers/template) is provided for you to copy into your own Git repository and begin modifications. + +{{ template "chart.maintainersSection" . }} + +{{ template "chart.sourcesSection" . }} + +{{ template "chart.requirementsSection" . }} + +{{ template "chart.valuesSection" . }} diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000000000000000000000000000000000000..67d5ad42989578727fc587de5a0d03bbf7efff0a --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,915 @@ +# Big Bang Release Notes + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +--- +## [2.44.0] + +- [!2.44.0](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests?scope=all&utf8=%E2%9C%93&state=merged&milestone_title=2.44.0); List of merge requests in this release. + +## [2.43.0] + +- [!2.43.0](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests?scope=all&utf8=%E2%9C%93&state=merged&milestone_title=2.43.0); List of merge requests in this release. + +## [2.42.0] + +- [!2.42.0](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests?scope=all&utf8=%E2%9C%93&state=merged&milestone_title=2.42.0); List of merge requests in this release. + +## [2.41.0] + +- [!2.41.0](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests?scope=all&utf8=%E2%9C%93&state=merged&milestone_title=2.41.0); List of merge requests in this release. + +## [2.40.0] + +- [!2.40.0](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests?scope=all&utf8=%E2%9C%93&state=merged&milestone_title=2.40.0); List of merge requests in this release. + +## [2.39.1] + +- [!2.39.1](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests?scope=all&utf8=%E2%9C%93&state=merged&milestone_title=2.39.0); List of merge requests in this release. + +## [2.39.0] + +- [!2.39.0](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests?scope=all&utf8=%E2%9C%93&state=merged&milestone_title=2.39.0); List of merge requests in this release. + +## [2.38.0] + +- [!2.38.0](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests?scope=all&utf8=%E2%9C%93&state=merged&milestone_title=2.38.0); List of merge requests in this release. + +## [2.37.0] + +- [!2.37.0](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests?scope=all&utf8=%E2%9C%93&state=merged&milestone_title=2.37.0); List of merge requests in this release. + +## [2.36.0] + +- [!2.36.0](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests?scope=all&utf8=%E2%9C%93&state=merged&milestone_title=2.36.0); List of merge requests in this release. + +## [2.35.0] + +- [!2.35.0](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests?scope=all&utf8=%E2%9C%93&state=merged&milestone_title=2.35.0); List of merge requests in this release. + +## [2.34.0] + +- [!2.34.0](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests?scope=all&utf8=%E2%9C%93&state=merged&milestone_title=2.34.0); List of merge requests in this release. + +## [2.33.0] + +- [!2.33.0](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests?scope=all&utf8=%E2%9C%93&state=merged&milestone_title=2.33.0); List of merge requests in this release. + +## [2.32.0] + +- [!2.32.0](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests?scope=all&utf8=%E2%9C%93&state=merged&milestone_title=2.32.0); List of merge requests in this release. + +## [2.31.0] + +- [!2.31.0](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests?scope=all&utf8=%E2%9C%93&state=merged&milestone_title=2.31.0); List of merge requests in this release. + +## [2.30.0] + +- [!2.30.0](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests?scope=all&utf8=%E2%9C%93&state=merged&milestone_title=2.30.0); List of merge requests in this release. + +## [2.29.0] + +- [!2.29.0](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests?scope=all&utf8=%E2%9C%93&state=merged&milestone_title=2.29.0); List of merge requests in this release. + +## [2.28.1] + +- [!4445](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests/4445): gitlab update to 7.11.2-bb.5 +- [!4441](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests/4441): gitlab update to 7.11.2-bb.4 + +## [2.28.0] + +- [!2.28.0](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests?scope=all&utf8=%E2%9C%93&state=merged&milestone_title=2.28.0); List of merge requests in this release. + +## [2.27.0] + +- [!2.27.0](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests?scope=all&utf8=%E2%9C%93&state=merged&milestone_title=2.27.0); List of merge requests in this release. + +## [2.26.0] + +- [!2.26.0](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests?scope=all&utf8=%E2%9C%93&state=merged&milestone_title=2.26.0); List of merge requests in this release. + +## [2.25.0] + +- [!2.25.0](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests?scope=all&utf8=%E2%9C%93&state=merged&milestone_title=2.25.0); List of merge requests in this release. + +## [2.24.0] + +- [!2.24.0](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests?scope=all&utf8=%E2%9C%93&state=merged&milestone_title=2.24.0); List of merge requests in this release. + +## [2.23.1] + +- [!2.23.1](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests?scope=all&utf8=%E2%9C%93&state=merged&milestone_title=2.23.1); List of merge requests in this release. + +## [2.23.0] + +- [!2.23.0](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests?scope=all&utf8=%E2%9C%93&state=merged&milestone_title=2.23.0); List of merge requests in this release. + +## [2.22.0] + +- [!2.22.0](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests?scope=all&utf8=%E2%9C%93&state=merged&milestone_title=2.22.0); List of merge requests in this release. + +## [2.21.2] + +- [!2.21.2](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests?scope=all&utf8=%E2%9C%93&state=merged&milestone_title=2.21.2); List of merge requests in this release. + +## [2.21.1] + +- [!2.21.1](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests?scope=all&utf8=%E2%9C%93&state=merged&milestone_title=2.21.1); List of merge requests in this release. + +## [2.21.0] + +- [!2.21.0](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests?scope=all&utf8=%E2%9C%93&state=merged&milestone_title=2.21.0); List of merge requests in this release. + +## [2.20.0] + +- [!2.20.0](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests?scope=all&utf8=%E2%9C%93&state=merged&milestone_title=2.20.0); List of merge requests in this release. + +## [2.19.2] + +- [!3780](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests/3780); istio update pod security context +- [!3759](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests/3759); fluentbit update to 2.2.2 + +## [2.19.1] + +- [!3746](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests/3746); Gitlab update to 16.8.1 + +## [2.19.0] + +- [!2.19.0](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests?scope=all&utf8=%E2%9C%93&state=merged&milestone_title=2.19.0); List of merge requests in this release. + +## [2.18.0] + +- [!2.18.0](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests?scope=all&utf8=%E2%9C%93&state=merged&milestone_title=2.18.0); List of merge requests in this release. + +## [2.17.0] + +- [!2.17.0](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests?scope=all&utf8=%E2%9C%93&state=merged&milestone_title=2.17.0); List of merge requests in this release. + +## [2.16.0] + +- [!2.16.0](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests?scope=all&utf8=%E2%9C%93&state=merged&milestone_title=2.16.0); List of merge requests in this release. + +## [2.15.0] + +- [!2.15.0](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests?scope=all&utf8=%E2%9C%93&state=merged&milestone_title=2.15.0); List of merge requests in this release. + +## [2.14.0] + +- [!2.14.0](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests?scope=all&utf8=%E2%9C%93&state=merged&milestone_title=2.14.0); List of merge requests in this release. + +## [2.13.1] + +- [!1812](https://repo1.dso.mil/big-bang/bigbang/-/issues/1812): neuvector enforcer correct host-path-mount exception + +## [2.13.0] + +- [!2.13.0](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests?scope=all&utf8=%E2%9C%93&state=merged&milestone_title=2.13.0); List of merge requests in this release. + +## [2.12.0] + +- [!2.12.0](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests?scope=all&utf8=%E2%9C%93&state=merged&milestone_title=2.12.0); List of merge requests in this release. + +## [2.11.1] + +- [!3146](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests/3146): Kyverno update to 3.0.0-bb.3 +- [!3170](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests/3170): GitlabRunner update to 0.52.0-bb.6 +- [!3178](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests/3178): Gitlab update to 7.3.4-bb.0 +- [!3187](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests/3187): fluentbit update to 0.37.0-bb.1 + +## [2.11.0] + +- [!2.11.0](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests?scope=all&utf8=%E2%9C%93&state=merged&milestone_title=2.11.0); List of merge requests in this release. + +## [2.10.0] + +- [!2.10.0](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests?scope=all&utf8=%E2%9C%93&state=merged&milestone_title=2.10.0); List of merge requests in this release. + +## [2.9.0] + +- [!2.9.0](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests?scope=all&utf8=%E2%9C%93&state=merged&milestone_title=2.9.0); List of merge requests in this release. + +## [2.8.0] + +- List of merge requests in this release. + +- [!2971](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests/2971): Grafana chart indentation 6 -> 4 +- [!2950](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests/2950): velero update to 4.0.3-bb.0 +- [!2973](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests/2973): gitlab update to 7.2.0-bb.0 +- [!2974](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests/2974): authservice update to 0.5.3-bb.12 +- [!2936](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests/2936): argocd update to 5.39.0-bb.0 +- [!2964](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests/2964): neuvector update to 2.4.5-bb.2 +- [!2966](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests/2966): loki update to 5.9.2-bb.0 +- [!2975](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests/2975): promtail update to 6.13.1-bb.0 +- [!2930](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests/2930): Re-add IB key to Kyverno Policies test-values +- [!2963](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests/2963): kyvernoPolicies update to 1.1.0-bb.9 +- [!2972](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests/2972): istio & operator update to 1.18.2-bb.0 +- [!2938](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests/2938): Add 'comments' field to schema +- [!2957](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests/2957): fix for ca-secret creation logic +- [!2955](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests/2955): harbor update to 1.12.2-bb.7 +- [!2958](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests/2958): anchore update to 1.26.1-bb.0 +- [!2977](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests/2977): gitlab update to 7.2.2-bb.0 +- [!2961](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests/2961): Fixing conditional for grafana extraSecretMounts + +## [2.7.0] + +- [!2.7.0](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests?scope=all&utf8=%E2%9C%93&state=merged&milestone_title=2.7.0); List of merge requests in this release. + +## [2.6.0] + +- [!2.6.0](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests?scope=all&utf8=%E2%9C%93&state=merged&milestone_title=2.6.0); List of merge requests in this release. + +## [2.5.0] + +- [!2.5.0](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests?scope=all&utf8=%E2%9C%93&state=merged&milestone_title=2.5.0); List of merge requests in this release. + +## [2.4.0] + +- [!2.4.0](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests?scope=all&utf8=%E2%9C%93&state=merged&milestone_title=2.4.0); List of merge requests in this release. + +## [2.3.0] + +- [!2.3.0](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests?scope=all&utf8=%E2%9C%93&state=merged&milestone_title=2.3.0); List of merge requests in this release. + +## [2.2.0] + +- [!2.2.0](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests?scope=all&utf8=%E2%9C%93&state=merged&milestone_title=2.2.0); List of merge requests in this release. + +## [2.1.0] + +- [!2.1.0](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests?scope=all&utf8=%E2%9C%93&state=merged&milestone_title=2.1.0); List of merge requests in this release. + +## [2.0.1] + +- [!2713](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests/2713): Bug fix for Gitlab chart backup job template +- [!2712](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests/2712): Bug fix for Gitlab Runner network policy ranging template +- [!2707](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests/2707): Bug fix for missing Monitoring SSO keys in schema +- [!2703](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests/2703): Bug fix for Mattermost and Nexus HelmRepos + +## [2.0.0] + +- [!2.0.0](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests?scope=all&utf8=%E2%9C%93&state=merged&milestone_title=2.0.0); List of merge requests in this release. + +#### Breaking Changes + +This major release contains breaking changes. Review the [release notes](https://repo1.dso.mil/big-bang/bigbang/-/releases/2.0.0) or the [blog post](https://docs-bigbang.dso.mil/latest/blog/2-0-breaking-changes/) for more details before upgrading. + +## [1.57.1] + +- [!2659](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests/2659): Fix wrong ArgoCD image version + +## [1.57.0] + +- [!1.57.0](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests?scope=all&utf8=%E2%9C%93&state=merged&milestone_title=1.57.0); List of merge requests in this release. + +## [1.56.0] + +- [!1.56.0](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests?scope=all&utf8=%E2%9C%93&state=merged&milestone_title=1.56.0); List of merge requests in this release. + +## [1.55.0] + +- [!1.55.0](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests?scope=all&utf8=%E2%9C%93&state=merged&milestone_title=1.55.0); List of merge requests in this release. + +## [1.54.0] + +- [!1.54.0](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests?scope=all&utf8=%E2%9C%93&state=merged&milestone_title=1.54.0); List of merge requests in this release. + +## [1.53.0] + +- [!1.53.0](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests?scope=all&utf8=%E2%9C%93&state=merged&milestone_title=1.53.0); List of merge requests in this release. + +## [1.52.0] + +- [!1.52.0](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests?scope=all&utf8=%E2%9C%93&state=merged&milestone_title=1.52.0); List of merge requests in this release. + +## [1.51.0] + +- [!1.51.0](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests?scope=all&utf8=%E2%9C%93&state=merged&milestone_title=1.51.0); List of merge requests in this release. + +## [1.50.0] + +- [!1.50.0](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests?scope=all&utf8=%E2%9C%93&state=merged&milestone_title=1.50.0); List of merge requests in this release. + +## [1.49.0] + +- [!1.49.0](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests?scope=all&utf8=%E2%9C%93&state=merged&milestone_title=1.49.0); List of merge requests in this release. + +## [1.48.0] + +- [!1.48.0](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests?scope=all&utf8=%E2%9C%93&state=merged&milestone_title=1.48.0); List of merge requests in this release. + +## [1.47.0] + +- [!1.47.0](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests?scope=all&utf8=%E2%9C%93&state=merged&milestone_title=1.47.0); List of merge requests in this release. + +## [1.46.1] + +- [!2243](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/2243): Fix Loki Monolith mTLS + +## [1.46.0] + +- [!1.46.0](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests?scope=all&utf8=%E2%9C%93&state=merged&milestone_title=1.46.0); List of merge requests in this release. + +## [1.45.0] + +- [!1.45.0](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests?scope=all&utf8=%E2%9C%93&state=merged&milestone_title=1.45.0); List of merge requests in this release. + +## [1.44.0] + +- [!1.44.0](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests?scope=all&utf8=%E2%9C%93&state=merged&milestone_title=1.44.0); List of merge requests in this release. + +## [1.43.0] + +- [!1.43.0](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests?scope=all&utf8=%E2%9C%93&state=merged&milestone_title=1.43.0); List of merge requests in this release. + +## [1.42.0] + +- [!1.42.0](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests?scope=all&utf8=%E2%9C%93&state=merged&milestone_title=1.42.0); List of merge requests in this release. + +## [1.41.0] + +- [!1.41.0](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests?scope=all&utf8=%E2%9C%93&state=merged&milestone_title=1.41.0); List of merge requests in this release. + +## [1.40.0] + +- [!1.40.0](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests?scope=all&utf8=%E2%9C%93&state=merged&milestone_title=1.40.0); List of merge requests in this release. + +## [1.39.0] + +- [!1.39.0](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests?scope=all&utf8=%E2%9C%93&state=merged&milestone_title=1.39.0); List of merge requests in this release. + +## [1.38.0] + +- [!1.38.0](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests?scope=all&utf8=%E2%9C%93&state=merged&milestone_title=1.38.0); List of merge requests in this release. + +## [1.37.0] + +- [!1.37.0](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests?scope=all&utf8=%E2%9C%93&state=merged&milestone_title=1.37.0); List of merge requests in this release. + +## [1.36.0] + +- [!1.36.0](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests?scope=all&utf8=%E2%9C%93&state=merged&milestone_title=1.36.0); List of merge requests in this release. + +## [1.35.0] + +- [!1.35.0](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests?scope=all&utf8=%E2%9C%93&state=merged&milestone_title=1.35.0); List of merge requests in this release. + +## [1.34.0] + +- [!1.34.0](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests?scope=all&utf8=%E2%9C%93&state=merged&milestone_title=1.34.0); List of merge requests in this release. + +## [1.33.0] + +- [!1.33.0](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests?scope=all&utf8=%E2%9C%93&state=merged&milestone_title=1.33.0); List of merge requests in this release. + +## [1.32.0] + +- [!1.32.0](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests?scope=all&utf8=%E2%9C%93&state=merged&milestone_title=1.32.0); List of merge requests in this release. + +## [1.31.0] + +- [!1.31.0](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests?scope=all&utf8=%E2%9C%93&state=merged&milestone_title=1.31.0); List of merge requests in this release + +## [1.30.1] + +- [!1495](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/1495): Update ArgoCD image to 2.3.2 + +## [1.30.0] + +- [!1.30.0](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests?scope=all&utf8=%E2%9C%93&state=merged&milestone_title=1.30.0); List of merge requests in this release. + +## [1.29.0] + +- [!1.29.0](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests?scope=all&utf8=%E2%9C%93&state=merged&milestone_title=1.29.0); List of merge requests in this release. + +## [1.28.0] + +- [!1.28.0](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests?scope=all&utf8=%E2%9C%93&state=merged&milestone_title=1.28.0); List of merge requests in this release. + +## [1.27.1] + +- [!1346](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/1346): Update to re-enable Jaeger's sidecars + +## [1.27.0] + +- [!1.27.0](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests?scope=all&utf8=%E2%9C%93&state=merged&milestone_title=1.27.0); List of merge requests in this release. + +## [1.26.0] + +- [!1.26.0](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests?scope=all&utf8=%E2%9C%93&state=merged&milestone_title=1.26.0); List of merge requests in this release. + +## [1.25.1] + +- [!1256](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/1256): Gitlab version bump to `5.6.2-bb.0` app version `14.6.2` + +## [1.25.0] + +- [!1.25.0](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests?scope=all&utf8=%E2%9C%93&state=merged&milestone_title=1.25.0); List of merge requests in this release. + +## [1.24.0] + +- [!1.24.0](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests?scope=all&utf8=%E2%9C%93&state=merged&milestone_title=1.24.0); List of merge requests in this release. + +## [1.23.0] + +- [!1.23.0](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests?scope=all&utf8=%E2%9C%93&state=merged&milestone_title=1.23.0); List of merge requests in this release. + +## [1.22.0] + +- [!1.22.0](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests?scope=all&utf8=%E2%9C%93&state=merged&milestone_title=1.22.0); List of merge requests in this release. + +## [1.21.0] + +- [!1.21.0](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests?scope=all&utf8=%E2%9C%93&state=merged&milestone_title=1.21.0); List of merge requests in this release. + +## [1.20.0] + +- [!1.20.0](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests?scope=all&utf8=%E2%9C%93&state=merged&milestone_title=1.20.0); List of merge requests in this release. + +## [1.19.0] + +- [!1.19.0](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests?scope=all&utf8=%E2%9C%93&state=merged&milestone_title=1.19.0); List of merge requests in this release. + +## [1.18.0] + +- [!1.18.0](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests?scope=all&utf8=%E2%9C%93&state=merged&milestone_title=1.18.0); List of merge requests in this release. + +## [1.17.0] + +- [!1.17.0](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests?scope=all&utf8=%E2%9C%93&state=merged&milestone_title=1.17.0); List of merge requests in this release. + +## [1.16.2] + +- [!919](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/919): Sonarqube version `9.2.6-bb.17-1` version bump to address erroneous duplicate template definitions for tolerations, nodeSelector & affinity + +## [1.16.1] + +- [!887](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/887): Twistlock Network Policy & BigBang/Package value `networkPolicies.nodeCidr` for defender to console communication +- [!890](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/890): Adding violation exception for twistlock-defenders to use selinux `spc_t` settings + +## [1.16.0] + +- [!1.16.0](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests?scope=all&utf8=%E2%9C%93&state=merged&milestone_title=1.16.0); List of merge requests in this release. + +## [1.15.3] + +- [!887](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/887): Twistlock Network Policy & BigBang/Package value `networkPolicies.nodeCidr` for defender to console communication +- [!852](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/852): Adding violation exceptions to stop Gatekeeper blocking twistlock console deployment +- [!890](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/890): Adding violation exception for twistlock-defenders to use selinux `spc_t` settings + +## [1.15.2] + +- [!846](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/846): Istio-cni hub correction to point to valid repo in registry1 & Add install-cni image to synker.yaml for air-gapped environments + +## [1.15.1] + +- [!834](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/834): Update istio to version 1.9.8 +- [!818](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/818): Fix minio istio pass down +- [!831](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/831): Fix monitoring hostNetwork violation +- [!835](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/835): Fix fluentbit hostFilesystem violation + +## [1.15.0] + +- [!1.15.0](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests?scope=all&utf8=%E2%9C%93&state=merged&milestone_title=1.15.0); List of merge requests in this release. + +## [1.14.1] + +- [!771](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/771): Intermediate update to authservice package to allow for cleaner certificate formatting +- [!782](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/782): Bumping Authservice tag to 0.4.0-bb.13 to fix mapping for values passed to redis sub-chart and uploading correct dependency sub-chart + +## [1.14.0] + +- [!1.14.0](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests?scope=all&utf8=%E2%9C%93&state=merged&milestone_title=1.14.0); List of merge requests in this release. + +## [1.13.1] + +- [!722](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/722): Bumping Gatekeeper tag, reducing pod footprint, cleaning up constraints +- [!730](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/730): Bumping Gatekeeper tag, properly excluding all of "kube-system" namespace from gatekeeper via upstream recommendation, removing "kube-system" exclusions from package values. + +## [1.13.0] + +- [!1.13.0 Merge Requests](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests?scope=all&utf8=%E2%9C%93&state=merged&milestone_title=1.13.0); List of Merge Requests in this Release + +## [1.12.1] + +- [!769](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/769): Add `kube-system` namespace exception to all constraints that cause violations + +## [1.12.0] + +- [!1.12.0 Merge Requests](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests?scope=all&utf8=%E2%9C%93&state=merged&milestone_title=1.12.0); List of Merge Requests in this Release + +## [1.11.0] + +- [!1.11.0 Merge Requests](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests?scope=all&utf8=%E2%9C%93&state=merged&milestone_title=1.11.0); List of Merge Requests in this Release + +## [1.10.0] + +- [!1.10.0 Merge Requests](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests?scope=all&utf8=%E2%9C%93&state=merged&milestone_title=1.10.0); List of Merge Requests in this Release + +## [1.9.1] + +- [!534](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/534): Bumping monitoring chart version - Addresses un-reconcilable state of monitoring package when upgrading from previous version of BigBang to 1.9.0 + +## [1.9.0] + +- [!445](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/445): Nexus added to BB +- [!488](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/488): Authservice support external redis service +- [!490](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/490): New monitoring helm tests +- [!492](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/492): Add new robot account to CI +- [!495](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/495): Add shanks as maintainers +- [!497](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/497): CAC CI upgrades +- [!499](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/499): Mattermost Operator optional network policies +- [!503](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/503): Sonarqube optional network policies +- [!504](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/504): Gitlab optional network policies +- [!509](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/509): feat: Bumping monitoring tag version +- [!510](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/510): ECK Operator optional network policies +- [!511](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/511): Authservice optional network policies +- [!513](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/513): Monitoring optional network policies +- [!514](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/514): Cluster Auditor & OPA Gatekeeper constraint-templates and added conditional enforcement + +### Upgrade Notices + +This update includes network policies for multiple packages, please refer to each package's individual documentation on implementation. + +### Known Issues + +- If the following error is seen on any helm releases `scheme "" not supported` try updating flux to latest ib images. A simple way to do this is by adding registry credentials to the flux-system namespace and applying the flux.yaml: + +```bash +kubectl create secret docker-registry private-registry --docker-server=registry1.dso.mil --docker-username=<Your IronBank Username> --docker-password=<Your IronBank Personal Access Token> --docker-email=<Your E-mail Address> -n flux-system +curl https://repo1.dso.mil/platform-one/big-bang/bigbang/-/raw/master/scripts/deploy/flux.yaml | kubectl apply -f - +``` + +- There is a [known issue](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/issues/329) with Velero ability to restore PersistentVolumes. + +## [1.8.0] + +- [!447](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/447): Sonarqube upgrade app version 8.7.1 chart version 9.2.6-bb.8 +- [!406](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/406): Authservice Support For Non Keycloak OIDC Endpoints +- [!459](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/459): Gitlab update to fix monitoring +- [!463](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/463),[!480](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/480): update codeowners +- [!462](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/462): Document GitLab package architecture in charter +- [!453](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/453): Set Global Timeout for Flux & Allow for HelmRelease Flux Settings to be Populated via Values File +- [!466](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/466): Updating name for kiali oidc secret secret +- [!465](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/465): Mattermost update app version 5.34.2 chart version 0.1.5-bb.0 +- [!467](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/467): update changelog for release 1.7.0 +- [!468](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/468): Modify continuous integration (CI) pipeline script execution +- [!474](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/474): Update twistlock app version 21.04.412 chart version 0.0.4-bb.0 +- [!464](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/464): Documentation updates +- [!475](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/475): Anchore upgrade app version 0.9.3 chart version 1.12.13-bb.0 +- [!430](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/430): Charter update for istio architecture +- [!451](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/451),[!481](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/481),[!482](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/482): Breakout secrets into individual files in Package templates +- [!417](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/417): update Kibana +- [!350](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/350): Authservice Redirect URLs dont respect virtual service name overrides +- [!485](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/485): ArgoCD upgrade app version 1.8.4 chart version 2.14.7-bb.5 +- [!476](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/476): Charter documentation updates +- [!134](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/134),[!489](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/489): BETA release of Keycloak app version 13.0.0 helm chart version 11.0.0 +- [!342](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/342): Upgrade elasticsearch-kibana package app version 7.10.x chart version 0.1.11-bb.0 +- [!457](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/457): Add labels to authservice namespace in compliance with charter + +### Upgrade Notices + +- Release 1.8.0 upgrades Elasticsearch and Kibana to 7.10 versions and if the [autoRollingUpgrade](https://repo1.dso.mil/platform-one/big-bang/apps/core/elasticsearch-kibana/#autorollingupgrade) job does not complete successfully or is interfered with it could cause ECK data loss. Please leave autoRollingUpgrade enabled and read [documentation](https://repo1.dso.mil/platform-one/big-bang/apps/core/elasticsearch-kibana/-/blob/main/docs/troubleshooting.md) to prepare for upgrade issues. + +### Known Issues + +- If the following error is seen on any helm releases `scheme "" not supported` try updating flux to latest ib images. A simple way to do this is by adding registry credentials to the flux-system namespace and applying the flux.yaml: + +```bash +kubectl create secret docker-registry private-registry --docker-server=registry1.dso.mil --docker-username=<Your IronBank Username> --docker-password=<Your IronBank Personal Access Token> --docker-email=<Your E-mail Address> -n flux-system +curl https://repo1.dso.mil/platform-one/big-bang/bigbang/-/raw/master/scripts/deploy/flux.yaml | kubectl apply -f - +``` + +- There is a [known issue](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/issues/329) with Velero ability to restore PersistentVolumes. + +## [1.7.0] + +- [!453](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/453): Global Timeout for flux and allow for HR flux settings to be populated via values +- [!459](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/459): Gitlab monitoring fix +- [!406](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/406): Authservice Support For Non Keycloak OIDC Endpoints +- [!447](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/447): Sonarqube updated to 8.7.1 +- [!446](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/446): Mattermost elastic integration +- [!437](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/437): Postrenders +- [!440](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/440): GitLab Upgrade to 13.10.3 +- [!450](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/450): Ironbank image version check script + +- [!369](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/369): Update development-environment +- [!371](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/371): Update 2_getting_started +- [!483](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/438): cluster auditor architecture +- [!454](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/454): Storage Documentation +- [!221](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/221): Add initial thoughts on Hugo +- [!408](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/408): Adding Architecture Doc for ek package +- [!462](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/462): Document GitLab package architecture in charter +- [!463](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/463): Update CODEOWNERS + +### Upgrade Notice + +#### Sonarqube Release Information + +This release comes with a new version of Sonarqube which requires a manual database upgrade that can be easily done through the web interface. If you see a message stating Sonarqube is under maintenance go to the following url and click update database: + +``` +https://sonarqube.your.url/setup +``` + +After a few minutes you should be able to log back in. + +### Known Issues + +If the following error is seen on any helm releases `scheme "" not supported` try updating flux to latest ib images. A simple way to do this is by adding registry credentials to the flux-system namespace and applying the flux.yaml: + +```bash +kubectl create -n flux-system secret docker-registry private-registry --docker-server="https://registry1.dso.mil" --docker-username='<IB_Username>' --docker-password="<CLI_TOKEN>" +kubectl apply -f scripts/deploy/flux.yaml +``` + +## [1.6.2] + +- [!455](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/455): gatekeeper values not hardcoded + +## [1.6.1] + +- [#19](https://repo1.dso.mil/platform-one/big-bang/apps/core/istio-controlplane/-/issues/19): istio-cni image hub reverted to dsop.io domain +- [#387](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/issues/387): Latest Fluent-Bit release removed Grafana Dashboard Functionality + +## [1.6.0] + +### Upgrade Notice + +This update includes several major changes to istio. Kiali and Jaeger are now separated into their own repos, helmreleases, and namespaces. + +A manual cleanup task is required to delete the previous Kiali and Jaeger deployments post upgrade: + +```bash +kubectl delete deploy -n istio-system -l app=kiali +kubectl delete deploy -n istio-system -l app=jaeger +``` + +### Known Issues + +This update includes an update to the Anchore chart. There is a [known issue](https://github.com/anchore/anchore-engine/issues/882) with running this version (and some previous versions) on FIPS enabled nodes. All Anchore services continue to function properly on non-FIPS nodes. Once an upstream fix is pushed, we will update the BB version accordingly. + +Anchore's default resource requests/limits (specifically for memory for the RBAC Manager) may be problematic depending on the customer and usage. Currently Big Bang consumes the defaults from the upstream chart, but Anchore also provides a list of [requirements](https://docs.anchore.com/current/docs/overview/requirements/) that address best practices for configuration for production workloads. These recommendations can be used as BB value overrides to specify resource limits and requests (example: [RBAC Manager](https://repo1.dso.mil/platform-one/big-bang/apps/security-tools/anchore-enterprise/-/blob/main/chart/values.yaml#L868)). + +- [!436](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/436): Resolve "fluentbit requires modification to work when selinux: Enforcing" +- [!416](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/416): Fix Minio SecurityContext for Mattermost +- [!385](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/385): update anchore to 1.12.7-bb.2 +- [!330](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/330): upgrade to istio 1.8.4, split jaeger and kiali into separate deployments +- [!427](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/427): IronBank image for Cluster Auditor +- [!428](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/428): feat: Bumping eck-operator to 1.4.0-bb.1 +- [!421](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/421): Resolve "Upgrade eck-operator to 1.4.0" +- [!405](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/405): Upgrade OPA Gatekeeper +- [!443](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/443): Resolve "Fluentbit upgrade to application version 1.7.4" +- [!442](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/442): Resolve "feat: Update authservice to use latest IB image and templating" +- [!432](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/432): feat: ek package to 0.1.8-bb.0 for pod lifecycle support +- [!418](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/418): Minio VS update + +There are additional minor changes and documentation updates that are included with this release. Full changes can always be seen by viewing the commit logs and completed MRs. + +## [1.5.0] + +### Upgrade Notice + +This update includes several additions to fluent-bit which are recommended for production environments to increase reliability of log ingestion to the ECK stack. + +This is mainly accomplished within fluent-bit by introducing a [filesystem storage buffer](https://docs.fluentbit.io/manual/administration/buffering-and-storage#filesystem-buffering-to-the-rescue) interacting with a new `hostPath` volume in fluent-bit containers. +By default, this is mounted to nodes at `/var/log/flb-storage/`, however it can be updated in the package's values in 3 places: + +```yaml +storage_buffer: + path: /var/log/flb-storage/ + +extraVolumes: + - hostPath: + path: /var/log/flb-storage/ + type: DirectoryOrCreate + name: flb-storage + +extraVolumeMounts: + - mountPath: /var/log/flb-storage/ + name: flb-storage +``` + +- [!386](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/386): Updated Fluentbit to 1.7.2 which fixes #335. +- [!356](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/356): Enabled flux monitoring via Prometheus/Grafana in Monitoring package. +- [!380](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/380): Fixed `eckoperator.enabled` conditional. +- Added and Documented Affinity support. + - [!379](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/379) Twistlock + - [!393](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/393) Cluster Auditor + +## [1.4.0] + +### Upgrade Notice + +This update includes updated `EnvoyFilters` for `authservice` to fix #65 and is a component of a future upgrade to istio 1.8 (#191). + +**After upgrading BigBang to this version, you must follow the steps below to ensure apps protected by `authservice` are still protected.** + +In order to ensure sso for all services protected by `authservice` remain functional (`kiali`, `jaeger`, `prometheus`, and `alertmanager`), the `istio-proxy` sidecar attached to the `haproxy` infront of the services must be updated to `1.7.7`. + +The easiest way to do this is to cycle the pod: + +```bash +kubectl delete po -n authservice -l app.kubernetes.io/instance=authservice-haproxy-sso +``` + +> **Note**: these 4 services (`kiali`, `jaeger`, `prometheus`, and `alertmanager`) will be unavailable for ~10s while the pod cycles. In the future we aim to provide an HA implementation of authservice's haproxy so the above operations can happen without downtime. + +- [!300](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/300): Velero Addon Addition +- [!308](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/308): BigBang values migrated to Secret objects parsed by `HelmRelease` objects within chart. (also fixes #221) +- [!357](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/357): Updated Anchore (Engine 0.9.3, Enterprise 3.0.2). +- [!333](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/333): Updated Mattermost (Operator: 1.13.0, Instance: 5.32.1). +- [!346](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/346): Redis Integration with Anchore Enterprise Package. +- [!318](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/318): Redis Integration with ArgoCD Package. + +## [1.3.0] + +- [!322](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/322): Updated anchore to 0.9.2, enterprise 3.0.1, this also fixes #135 +- [!309](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/309): Add support for Gitlab CAC signed commits and custom CAs +- [!311](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/311): Update minio to `RELEASE.2020-11-19T23-48-16Z` and expose more user configuration options +- [!220](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/220): Added consolidatedflux installation (without `flux` cli) +- [!319](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/319): Updated gitlab-runner to `13.9.0` IronBank image (note this uses a different chart schema than previous versions, see [here](https://docs.gitlab.com/runner/install/kubernetes.html#additional-configuration) for more information) +- [!340](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/340): Package `bigbang` repo in `repositories.tar.gz` release artifact + +In addition, [Big Bang Pre-requisites](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/blob/1.4.0/docs/d_prerequisites.md) has been added as a location to store all (known) pre-requisites for running BigBang on various distributions. Over time, more distributions will be added as they are tested, community (and vendor) contributions are welcomed! + +## [1.2.0] + +- [!270](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/270): upgrade to flux 0.7.x, this requires updating flux and fixes #13 +- [!250](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/250): Filename spelling correction in scripts directory +- [!259](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/259), [!265](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/265), [!274](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/274): documentation updates +- [!263](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/263), [!271](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/271): Update codeowners +- [!263](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/263): add missing enterprise Anchore images to airgap bundle +- [!237](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/237): add gitlab-runner to test values +- [!266](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/266): update fluentbit package version +- [!269](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/269): Update charter/PackageOwner.md +- [!256](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/256): update developer documentation +- [!272](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/272): Remove CI jobs that check for things no longer required as part of the developer workflow +- [!264](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/264), [!238](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/238): Update BigBang repo url references from "umbrella" to "bigbang" +- [!249](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/249): image for gatekeeper is set in the chart and should not be hardcoded in the HelmRelease +- [!202](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/202): add initial support for openshift (ocp) +- [!272](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/272): upgrade argocd helm chart to 2.14.7-bb.0 +- [!232](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/232): Twistlock IB image and VirtualServcie customization +- [!210](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/210): only run cluster tests when chart contents have changed +- [!279](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/279): remove hardcoded ArgoCD server url config, allow users to set their own sso url +- [!215](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/215): add sample sso values +- [!286](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/286): add Ironbank defender image to synker config +- [!287](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/287): add gitlab runner images to synker config +- [!288](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/288): split minio into minio operator and minio and move to addons +- [!255](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/255): Integrate Mattermost Operator as an addon +- [!273](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/273): Integrate Mattermost as an addon +- [!291](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/291): enable MinIO in CI tests +- [!290](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/merge_requests/290): upgrade Mattermost chart version. Uses latest IronBank image + +## [1.1.0] + +- [&2](https://repo1.dso.mil/groups/platform-one/big-bang/-/epics/2): Add support for Gitlab (with sso) 13.8.0 +- [&3](https://repo1.dso.mil/groups/platform-one/big-bang/-/epics/3): Add support for Gitlab Runners 13.2.2 +- [&7](https://repo1.dso.mil/groups/platform-one/big-bang/-/epics/7): Add support for SonarQube (with sso) 8.6 +- [&15](https://repo1.dso.mil/groups/platform-one/big-bang/-/epics/15): Add support for Anchore (with sso) 0.8.1 +- [#129](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/issues/129): Updated FluentBit to 1.6.3 +- [#63](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/issues/63): Fix bug with elasticsearch failing to start due to invalid file permissions +- [#49](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/issues/49): Add consistent labels to authservice deployment +- [#32](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/issues/32): Add support for PodAntiAffinity and NodeAffinity for elasticsearch deployments +- [#6](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/issues/6): Add support for new elasticsearch cluster node types +- [#16](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/issues/16): Fix bug with incorrect git credentials being created when specifying a private repository +- [#66](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/issues/66): Fix bug with EnvoyFilter being applied in the wrong non-global namespace +- [#99](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/issues/99): Fix bug that allowed for incorrect ImagePullSecrets to be created when providing incomplete credentials + +## [1.0.8] + +- Added support for deployment of Minio operator and instance deployment of minio. + +## [1.0.7] + +- Added Kubernetes labels to all objects created by umbrella +- Add OIDC integration for Grafana +- Allow creation of wildcard cert for istio ingress to be passed to BigBang chart + +## [1.0.6] + +- Added [HAProxy Addon](https://repo1.dso.mil/platform-one/big-bang/apps/sandbox/haproxy) +- Added support for automatically populating configs and settings for the following placing SSO in front of apps without support: + +``` +istio: + sso: + enabled: true + prometheus: + client_id: + client_secret: + alertmanager: + client_id: + client_secret: + +monitoring: + sso: + enabled: true + kiali: + client_id: + client_secret: + jaeger: + client_id: + client_secret: +``` + +- Added authservice namespace where authservice addon and haproxy deployment will be created. +- Added global sso options for umbrella which will be applied to all configured authservice chains: + +``` +sso: + oidc: + host: login.dso.mil + realm: baby-yoda + certificate_authority: '' + jwks: "" + client_id: "" + client_secret: "" +``` + +- Updated syntax for authservice chains definition. + +## [1.0.5] + +- Bumped monitoring chart to consume kiwigrid/sidecar from IronBank + +## [1.0.4] + +- Bug fix where argocd's VirtualService wouldn't recieve the top level hostname value. + +## [1.0.3] + +- Added [Gitlab](https://repo1.dso.mil/platform-one/big-bang/apps/developer-tools/gitlab) +- Added ability to provide multiple registry credentials while maintaining current capabilities: + +``` +registryCredentials: + username: registry1user + password: somesecretpassword +``` + +or + +``` +registryCredentials: +- registry: registry1.dso.mil + username: registry1user + password: somesecretpassword +- registry: registry.dsop.io + username: registry1user + password: somesecretpassword +- registry: somewhere.else.io + username: someuser + password: someothersecret +``` + +will correctly create the ImagePullSecrets for all those registries + +## [1.0.2] + +### Changed + +- Updated istio-controlplane to [1.7.3-bb.5](https://repo1.dso.mil/platform-one/big-bang/apps/core/istio-controlplane/-/tags/1.7.3-bb.5) to allow + for setting ingressgateway to use nodeports + +## [1.0.1] + +### Changed + +- Updated Istio Control plane to support Node Ports for ingressGateway +- Update Istio Control plane to support SSO for Kiali and Jaeger +- Update Authservice to refact definitions of filter chains +- Updated documentation + +--- + +## [0.0.4] - 2020-12-16 + +### Changed + +- Update Monitoring to [11.0.0-bb.2](https://repo1.dso.mil/platform-one/big-bang/apps/core/monitoring/-/tags/11.0.0-bb.2) + +--- + +## [0.0.3] - 2020-12-15 + +### Added + +- Documentation in [docs](./docs) + +### Changed + +- Updated Argo to [2.9.5-bb.1](https://repo1.dso.mil/platform-one/big-bang/apps/core/argocd/-/merge_requests/10) for Iron Bank images +- Updated Authservice to [0.1.3-bb.0](https://repo1.dso.mil/platform-one/big-bang/apps/sandbox/authservice/-/blob/master/CHANGELOG.md#013-bb0) for authservice secret generation: <https://repo1.dso.mil/platform-one/big-bang/apps/sandbox/authservice/-/blob/master/CHANGELOG.md#013-bb0> +- Updated ECK-Operator to [1.3.1-bb.1](https://repo1.dso.mil/platform-one/big-bang/apps/core/eck-operator/-/tags/1.3.0-bb.1) +- Updated Twistlock to [0.0.2-bb.0](https://repo1.dso.mil/platform-one/big-bang/apps/security-tools/twistlock/-/tags/0.0.2-bb.0) to add istio.enabled flag +- Updated Elasticsearch Kibana to [0.1.2-bb.0](https://repo1.dso.mil/platform-one/big-bang/apps/core/elasticsearch-kibana/-/tags/0.1.2-bb.0) and Pass istio.enabled to Elasticsearch Kibana + +--- + +## [0.0.2] - 2020-12-11 + +### Added + +- Initial release of Big Bang + +--- diff --git a/CODEOWNERS b/CODEOWNERS index 4b2c36a7e8cc9dc202b75d4539819b245ad432c1..e951717d454d4d3f7e5aaa54a2954c90c98c8a51 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -1 +1,9 @@ -* @jaredmladner @julian.hair @alieberman @chris.oconnell @obuh.alozie @daniel.stocum @jeffv \ No newline at end of file +# Big Bang Maintainers +* @michaelmartin @chris.oconnell @andrewshoell @troymobley + +[Documentation] @michaelmartin @chris.oconnell @andrewshoell @troymobley +docs/ +*.md + +[Blog] @troymobley +blog/ diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000000000000000000000000000000000000..08013a3cc3034f3fc65a5d7f6191e79684843157 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,132 @@ +# Contributing to Big Bang + +Thanks for taking the time to contribute to Big Bang! + +If you are coming from `repo1.dso.mil` and have an account at `login.dso.mil`, please keep reading. If you are coming from or looking for the [project on Github](https://github.com/DoD-Platform-One) and wanting to make a Pull Request without a `dso.mil` account, please see the last section [External Github Contributions](#community-contributions-to-dod-platform-one-via-github). + +Table of Contents: + +- [Contributing to Big Bang](#contributing-to-big-bang) + - [Developers Guide](#developers-guide) + - [Iron Bank Images](#iron-bank-images) + - [Local Kubernetes cluster](#local-kubernetes-cluster) + - [Deploying Big Bang (Quick Start)](#deploying-big-bang-quick-start) + - [Testing Big Bang Development Changes](#testing-big-bang-development-changes) + - [DNS](#dns) + - [Secrets & Certificates](#secrets--certificates) + - [Merge requests process](#merge-requests-process) + - [Security Consideration](#security-considerations) + - [External Github Contributions](#community-contributions-to-dod-platform-one-via-github) + +## Developers Guide + +Big Bang is designed in such a way as to be as easily deployed locally as it is in production. In fact, most contributions begin locally. + +## Iron Bank Images + +Per the [charter](https://repo1.dso.mil/big-bang/charter), all Big Bang packages will leverage container images from [IronBank](https://ironbank.dso.mil/). In order to pull these images, ImagePullSecrets must be provided to Big Bang. To obtain access to these images, follow the guides provided in this document. These steps should NOT be used for production since the API keys for a user are only valid when the user is logged into [Registry1](https://registry1.dso.mil) + +1) Register for a free Iron Bank account [Here](https://sso-info.il2.dso.mil/new_account.html). +1) Log into the [Iron Bank Registry](https://registry1.dso.mil), in the top right click your *Username* and then *User Profile* to get access to your *CLI secret*/API keys. +1) When installing BigBang, set the Helm Values `registryCredentials.username` and `registryCredentials.password` to match your Registry1 username and API token. + +## Local Kubernetes cluster + +Follow the steps below to get a local Kubernetes cluster for Big Bang using [k3d](https://k3d.io/). + +```bash +# Create a local k3d cluster with the appropriate port forwards (tested on version 5.4.1). +k3d cluster create --k3s-arg "--no-deploy=metrics-server,traefik@server:*" -p 80:80@loadbalancer -p 443:443@loadbalancer +``` + +## Deploying Big Bang (Quick Start) + +For development, it is quicker to test changes without having to push to Git. To do this, we can bypass Flux2 and deploy Big Bang directly with its Helm chart. + +Start by creating `myvalues.yaml` to configure your local Big Bang. The Big Bang template repository contains a starter [development values.yaml](https://repo1.dso.mil/big-bang/customers/template/-/blob/main/package-strategy/configmap.yaml). + +Configure `myvalues.yaml` to suit your needs. + +```bash +# Deploy the latest fluxv2 with Iron Bank images +# For development, you can use flux from the internet using 'flux install` +# Be aware, the internet version is likely newer than the Iron Bank version +./scripts/install_flux.sh + +# Apply a local version of the Big Bang chart +# NOTE: This is the alternative to deploying a HelmRelease and having flux manage it, we use a local copy to avoid having to commit every change +helm upgrade -i bigbang chart -n bigbang --create-namespace -f myvalues.yaml + +# It may take Big Bang up to 10 minutes to recognize your changes and start to deploy them. This is based on the flux `interval` value set for polling. You can force Big Bang to immediately check for changes by running the ./scripts/sync.sh script. +./scripts/sync.sh +``` + +For more extensive development, use the [Development Guide](./docs/developer). + +## Testing Big Bang Development Changes + +Development changes should be tested using a full GitOps environment. The [Big Bang environment template](https://repo1.dso.mil/big-bang/customers/template/) should be replicated, either on a branch or new repository, to start your deployment. Follow the instructions in the [template's readme](https://repo1.dso.mil/big-bang/customers/template/-/tree/main/README.md) and in the [Big Bang docs](./docs) for configuration. + +Follow the [Big Bang documentation](./docs) for testing a full deployment of Big Bang. + +## DNS + +To ease with local development, the TLD `dev.bigbang.mil` is maintained by the Platform One team with the CNAME record: + +`CNAME: *.dev.bigbang.mil -> cluster.local` + +All routable endpoints BigBang deploys will use the TLD of `bigbang.dev` by default. It is expected that consumers modify this appropriately for their environment. + +## Secrets & Certificates + +Follow instructions in the [Big Bang encryption guide](./docs/understanding-bigbang/concepts/encryption.md) for how to encrypt and decrypt secrets. + +## Merge Requests Process + +The merge request process is provided as an overview of the pipeline stages required to get a commit merged. + +Follow instruction in [CI-Workflow](./docs/developer/ci-workflow.md) for specific details on the pipeline stages. + +## Security Considerations + +- To report a cybersecurity concern, follow this [link](https://jira.il2.dso.mil/servicedesk/customer/portal/81). +- Never push secrets or certificates into our repository. + +- Big Bang does not recommend using internal databases for production deployments. Please look into having external databases, each application will have guides to deploy production system. + +- For questions on CVEs and remediation, email Andrew Vu Big Bang Cyber Lead (andrew.vu.9@us.af.mil) or message on MatterMost IL4 (andrew.vu.9) for more information. + +# Community Contributions to DoD-Platform-One via Github + +## How to Contribute + +1. Fork this repository, develop, and test your changes. (if you do not have permissions to fork the repository, You can download the repo as a tar.gz file and upload to your own repo in your Gitlab instance instead) +1. Submit a pull request. +1. Keep an eye out for comments. From bots and maintainers to ensure CI is passing and issues or suggestions are addressed. + +### Technical Requirements + +* Pipelines which must pass will run on runners from `repo1.dso.mil` and a bot will comment the status and information from the pipeline. +* Any change to a Big Bang package chart requires a version bump following [semver](https://semver.org/) principles. See [Documentation Changes](#documentation-changes) and [Versioning](#versioning) below +* Big Bang Package Issues which need to be included in the Big Bang Umbrella chart are not complete when the package PR is merged so please do not close issues. A new tag will automatically get created on `repo1.dso.mil` along with an MR into the Big Bang Umbrella as part of the CI process. This repo1 MR is reviewed the Big Bang Product team to merge on the Gitlab side, upon which the issue will be closed. +* Changes to the Big Bang Umbrella get released separately according to our Release Schedule outlined in the [README](./README.md#release-schedule). + +Once changes have been merged, all subsequent automation will run on `repo1.dso.mil` with changes getting published back to Github. + +### Documentation Changes + +If your changes are to documentation or guides/images and not code, templates or variables then a `kind::docs` label will need to be added and will not kick off and wait for CI testing to complete. + +### Versioning + +Big Bang package chart `version` should follow [semver](https://semver.org/). + +Charts should start at `1.0.0` unless they are based off an upstream chart (shown in chart/Kptfile) in which case a bug fix would increment the `bb.X` suffix. + +Big Bang umbrella MRs will not need the version in `chart/Chart.yaml` edited via Pull Requests. + +### Generate README + +The readme of each Big Bang package chart can be re-generated with the following command: <https://repo1.dso.mil/big-bang/product/packages/gluon/-/blob/master/docs/bb-package-readme.md>. + +Big Bang umbrella MRs will not need the main README.md edited via Pull Requests. diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..2a6218e8a9b78ff68841d2c54b4cf868a3d94fb5 --- /dev/null +++ b/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2021 Platform One + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/README.md b/README.md index 28183c24b06e1f1af54ef3aa664aaba6826c6f5f..2088b8429ea2b43172ae50647f8ff96d1ad81acd 100644 --- a/README.md +++ b/README.md @@ -1,112 +1,86 @@ -# Testing Pipelines -The goal of this repository is to streamline testing of pipelines. Under normal circumstances projects in Repo1 do not allow redirection of the CI/CD pipeline references in settings or use of the `.gitlab-ci.yml` file. This repository has been set up to allow the CI/CD pipelines to be defined via the `.gitlab-ci.yml` file. - -[[_TOC_]] - -> The following guidelines will ensure concurrent testing of pipelines can occur - -### Set up -- Create a branch in [Pipeline Templates](https://repo1.dso.mil/big-bang/pipeline-templates/pipeline-templates), `${PIPELINE_REPO_BRANCH}` or use the default branch if you want to test a pipeline that is in production. -- Clone the target repo - - Add a remote `git remote add validator https://repo1.dso.mil/big-bang/pipeline-templates/package-validation.git` - - Create a branch `username-repo-master` | `git checkout -b username-repo-master` - - Add a .gitlab-ci.yml file - - Push `git push validator` -- If Fork Repo Tokens are needed reach out to a CODEOWNER to grant maintainer access - - Settings > CI/CD > Variables > Create a Variable `USERNAME_FORK_TOKEN` with the access token from your fork. - -### Variables -Any CI Variable can be overridden to get the tested pipeline to a desired state. Below are a few important ones - -- `CI_DEFAULT_BRANCH`: Set to `username-repo-master` to override the default branch of "master" || "main" -- `BB_AUTO_MR_TOKEN`: Set to `USERNAME_FORK_TOKEN` this is to prevent publicly saving repo access tokens in git history -- `PIPELINE_REPO_BRANCH`: Must match the branch name in pipeline-templates - -### Example .gitlab-ci.yml file -Replace values like `${VAR}` with your variables - -```yaml -include: # standard for the BB repo - - project: 'big-bang/pipeline-templates/pipeline-templates' - ref: "master" - file: '/pipelines/bigbang.yaml' -variables: - PIPELINE_REPO_BRANCH: '${PIPELINE_REPO_BRANCH}' - CI_DEFAULT_BRANCH: "`${username-repo-master}`" - # variables that can be overriden to target specific pipelines (NOT REQUIRED FOR ALL PIPELINES) - DEBUG_ENABLED: "true" - CLUSTER_TYPE: "RKE2" - JOB_TYPE: "nightly" - CI_PIPELINE_SOURCE: "schedule" -``` - -### Testing Master Branch Pipeline -Generally "master" or "main" pipelines only run on just that. This is due to rules in our pipelines that check that the `CI_DEFAULT_BRANCH == CI_COMMIT_BRANCH` By modifying `CI_DEFAULT_BRANCH` to be equal to the `username-repo-master` branch name in the `ci.yml` the pipeline will treat this branch as "master". - -```mermaid -flowchart LR -A[Pipeline Templates] --> B(gitlab-ci.yml) -B --> D[username-repo-master] -``` - -### Testing MR Pipelines -Create a branch `username-repo-update` and then create a MR into `username-repo-master` - -```mermaid -flowchart LR -A[Pipeline Templates] --> B(gitlab-ci.yml) -B --> C{MR} -C --> D[username-repo-master] -C --- E[username-repo-update] -``` - -### Example: Changing a CI job but it's not a bigbang package - -**Scenario**: - -You are looking to change the gitlab CI job definitions for a repo that has its own custom job YAML definitions such as [bbctl](https://repo1.dso.mil/big-bang/product/packages/bbctl). - -#### Walkthrough - -##### Phase 1: Change the job YAML in `pipeline-templates` on a working branch - -1. Find the job YAML for that repo in the pipeline templates repo at [`pipelines/bbctl.yaml`](https://repo1.dso.mil/big-bang/pipeline-templates/pipeline-templates/-/blob/master/pipelines/bbctl.yaml) -2. Pull the `pipeline-templates` repo down locally and make your own changes to `bbctl.yaml` -3. Commit that change and push it up to `pipeline-templates` on a working branch, say `myname-bbctl-job-tweaks`. - -##### Phase 2: Set up a working branch on `package-validation` to run your proposed new job YAML - -1. Clone the "target repo", i.e. the repository whose CI you're changing. In this case, that's bbctl: `git clone https://repo1.dso.mil/big-bang/product/packages/bbctl.git` -2. Add a new remote to your local checkout of that target repo (e.g. bbctl) **and point it to the package-validation repo**: `git remote add validator https://repo1.dso.mil/big-bang/pipeline-templates/package-validation.git` -3. Add a new `.gitlab-ci.yml` to your local checkout of the target repo (`bbctl`). Fill it in with the following content: - * ```yaml - include: # standard for the BB repo - - project: 'big-bang/pipeline-templates/pipeline-templates' - # 👇 this should point to your working branch over at pipeline-templates - ref: "myname-bbctl-job-tweaks" - file: '/pipelines/bigbang.yaml' - variables: - # 👇 this should ALSO point to your working branch over at pipeline-templates - PIPELINE_REPO_BRANCH: "myname-bbctl-job-tweaks" - # 👇 this is the branch where you'll be pushing this very .gitlab-ci.yml file to trigger a CI job - CI_DEFAULT_BRANCH: "myname-bbctl-master" - # variables that can be overriden to target specific pipelines (NOT REQUIRED FOR ALL PIPELINES) - DEBUG_ENABLED: "true" - CLUSTER_TYPE: "RKE2" - JOB_TYPE: "nightly" - CI_PIPELINE_SOURCE: "schedule" - ``` -4. Check out a new branch on your local `bbctl` repository and name it `myname-bbctl-master`. -5. `git add` and `git commit` your new `.gitlab-ci.yml` file to this `myname-bbctl-master` branch. -6. Push your `myname-bbctl-master` branch up to the `package-validation` repo: `git push validator myname-bbctl-master`. - -##### Phase 3: Iterate - -[Watch the CI pipeline that phase 2 hopefully triggered](https://repo1.dso.mil/big-bang/pipeline-templates/package-validation/-/pipelines) and see if it works as expected. - -- If it succeeds, you're ready to try to land an MR on the `pipeline-templates` repository with your changes to `pipelines/bbctl.yaml`. -- If it fails: - - Make more changes to your `myname-bbctl-job-tweaks` branch over on the `pipeline-templates` repo. - - Trigger another run of the new pipeline by bumping your `.gitlab-ci.yaml` in your local `bbctl` repo: `git commit --allow-empty -m "I'm updating the ci job to trigger a new run of the validator" && git push validator myname-bbctl-master`. - - Go look at the CI pipelines and see if they passed as intended. - - Repeat this phase until satisfied. \ No newline at end of file +# Big Bang + +Big Bang is a declarative, continuous delivery tool for deploying Department of Defense (DoD) hardened and approved packages into a Kubernetes cluster. + +> If viewing this from Github, note that this is a mirror of a government repo hosted on [Repo1](https://repo1.dso.mil/) by [DoD Platform One](http://p1.dso.mil/). Please direct all code changes, issues and comments to [https://repo1.dso.mil/big-bang/bigbang](https://repo1.dso.mil/big-bang/bigbang) + +## Usage & Scope + +Big Bang's scope is to provide publicly available installation manifests for packages required to adhere to the DoD DevSecOps Reference Architecture and additional useful utilities. Big Bang packages are broken into three categories: + +- **Core:** [Core packages](./docs/understanding-bigbang/package-architecture/README.md#core) are a group of capabilities required by the DoD DevSecOps Reference Architecture, that are supported directly by the Big Bang development team. The specific capabilities that are considered core currently are Service Mesh, Policy Enforcement, Logging, Monitoring, and Runtime Security. + +- **Add-ons:** [Addon packages](./docs/understanding-bigbang/package-architecture/README.md#addons) are any packages/capabilities that the Big Bang development team directly supports that do not fall under the above core definition. These serve to extend the functionality/features of Big Bang. + +- **Community:** [Community packages](https://repo1.dso.mil/big-bang/product/community) are any packages that are maintained by the broader Big Bang community (e.g., users and/or vendors). These packages could be alternatives to core or add-on packages, or even entirely new packages to help extend usage/functionality of Big Bang. + +In order for an installation of Big Bang to be a valid installation/configuration, you must install/deploy a core package of each category. For additional details on categories and options, see [here](./docs/understanding-bigbang/package-architecture/README.md##Core). + +Big Bang also builds tooling around the testing and validation of Big Bang packages. These tools are provided as-is, without support. + +Big Bang is intended to be used for deploying and maintaining a DoD hardened and approved set of packages into a Kubernetes cluster. Deployment and configuration of ingress/egress, load balancing, policy auditing, logging, and/or monitoring are handled via Big Bang. Additional packages (e.g., ArgoCD and GitLab) can also be enabled and customized to extend Big Bang's baseline. Once deployed, the Kubernetes cluster can be used to add mission specific applications. + +Additional information can be found in the [Big Bang Docs](./docs/README.md). + +## Getting Started + +- You will need to instantiate a Big Bang environment tailored to your needs. [The Big Bang customer template](https://repo1.dso.mil/big-bang/customers/template) is provided for you to copy into your own Git repository and begin modifications. +- There is a [Quick Start guide](https://repo1.dso.mil/big-bang/bigbang/-/blob/master/docs/guides/deployment-scenarios/quickstart.md) to be used as an example deployment scenario. + +## Contributing to Big Bang + +There are three primary ways to contribute to Big Bang. They are listed in the following: + +- [Contribute to the Big Bang Team's Backlog](https://repo1.dso.mil/big-bang/bigbang/-/issues). +- [Contribute to open-source projects under the Big Bang Technical Oversight Committee (BBTOC)](https://repo1.dso.mil/big-bang/product/bbtoc/-/blob/master/CONTRIBUTING.md). +- [Submit new package proposals](https://repo1.dso.mil/big-bang/product/bbtoc/-/issues/new?issue%5Bmilestone_id%5D=). + - Please review the [package integration guide](./docs/developer/package-integration/README.md) if you are interested in submitting a new package. + - A shepherd will be assigned to the project to create a repo in the [Big Bang Community Packages](https://repo1.dso.mil/big-bang/product/community). + +Additional information can be found in the [contributing guide](./CONTRIBUTING.md). + +## Release Schedule + +- Big Bang releases adopt a standardized versioning based on and loosely following the [Semantic Versioning 2.0.0 guidelines](https://semver.org/spec/v2.0.0.html) (major.minor.patch). These releases are not based on a fixed schedule and instead, follow the specifics in the scheme that is described in this section. + +### Patch Version + +A patch version increment is performed when there is a change in the tag (i.e., version number) of a Big Bang core package or a bug fix for a Big Bang template or values files. A change in the patch version number should be backwards compatible with previous patch changes within a minor version. If there is a significant functionality change in the a core package that requires adjustments to Big Bang templates, this would require a change in the minor or major version depending on the impact to the values and secrets used to integrated the package with Big Bang. + +NOTE: Patch versions would not typically be created for addon package updates, rather customers would be expected to be updating those packages via `git.tag`/`helmRepo.tag` changes directly, or "inheriting" those updates through another version. + +### Minor Version + +A minor version increment is required when there is a change in the integration of Big Bang with core or addon packages. For example, the following changes warrant a Minor version change: + +- Change in the umbrella values.yaml (except for changes to package version keys) +- Change in any Big Bang templates (non bug fix changes) + +Minor version changes should be backwards compatible. + +### Major Version + +A major version increment indicates a release that has significant changes, which could potentially break compatibility with previous versions. A major change is required when there are changes to the architecture of Big Bang or critical values file keys. For example removing a core package or changing significant values that propagate to all core and add-on packages are considered major version changes. Examples of major version changes are provided in the folowing: + +- Removal or renaming of Big Bang values.yaml top level keys (e.g., istio and/or git repository values). +- Change to the structure of chart/templates files or key values. +- Additional integration between core/add-on packages that require change to the charts of all packages. +- Modification of Big Bang GitOps engine (i.e., switching from FluxCD -> ArgoCD). + +To see what is on the roadmap or included in a given release you can still review our [project milestones](https://repo1.dso.mil/groups/big-bang/-/milestones). + +## Community + +The Big Bang Universe Community Slack workspace is a great place to go to get involved, interact with the community, and ask for help. You can join the workspace with [this invite link](https://join.slack.com/t/bigbanguniver-ft39451/shared_invite/zt-21zrvwacw-zoionTAz0UdzVbjnAFSnDw). + +## Navigating our Documentation + +> All Big Bang documentation is also provided at [https://docs-bigbang.dso.mil](https://docs-bigbang.dso.mil) offering a better experience and improved searchability. + +Several useful starting points in the Big Bang documentation are listed in the following: + +- [Developer Contribution Documentation](./docs/developer/README.md) +- [Key Big Bang Concept Overviews](./docs/understanding-bigbang/README.md) +- [User Guides for Big Bang](./docs/guides/README.md) +- [Big Bang Prerequisites](./docs/prerequisites/README.md) +- [Big Bang Example Configurations](https://repo1.dso.mil/big-bang/bigbang/-/tree/master/docs/assets/configs/example) diff --git a/base/flux/gotk-components.yaml b/base/flux/gotk-components.yaml new file mode 100644 index 0000000000000000000000000000000000000000..ee72e8e88eff960c48bbc449f5f5879ea5fd170d --- /dev/null +++ b/base/flux/gotk-components.yaml @@ -0,0 +1,12507 @@ +--- +# This manifest was generated by flux. DO NOT EDIT. +# Flux Version: v2.4.0 +# Components: source-controller,kustomize-controller,helm-controller,notification-controller +apiVersion: v1 +kind: Namespace +metadata: + labels: + app.kubernetes.io/instance: flux-system + app.kubernetes.io/part-of: flux + app.kubernetes.io/version: v2.4.0 + pod-security.kubernetes.io/warn: restricted + pod-security.kubernetes.io/warn-version: latest + name: flux-system +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + labels: + app.kubernetes.io/instance: flux-system + app.kubernetes.io/part-of: flux + app.kubernetes.io/version: v2.4.0 + name: allow-egress + namespace: flux-system +spec: + egress: + - {} + ingress: + - from: + - podSelector: {} + podSelector: {} + policyTypes: + - Ingress + - Egress +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + labels: + app.kubernetes.io/instance: flux-system + app.kubernetes.io/part-of: flux + app.kubernetes.io/version: v2.4.0 + name: allow-scraping + namespace: flux-system +spec: + ingress: + - from: + - namespaceSelector: {} + ports: + - port: 8080 + protocol: TCP + podSelector: {} + policyTypes: + - Ingress +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + labels: + app.kubernetes.io/instance: flux-system + app.kubernetes.io/part-of: flux + app.kubernetes.io/version: v2.4.0 + name: allow-webhooks + namespace: flux-system +spec: + ingress: + - from: + - namespaceSelector: {} + podSelector: + matchLabels: + app: notification-controller + policyTypes: + - Ingress +--- +apiVersion: v1 +kind: ResourceQuota +metadata: + labels: + app.kubernetes.io/instance: flux-system + app.kubernetes.io/part-of: flux + app.kubernetes.io/version: v2.4.0 + name: critical-pods-flux-system + namespace: flux-system +spec: + hard: + pods: "1000" + scopeSelector: + matchExpressions: + - operator: In + scopeName: PriorityClass + values: + - system-node-critical + - system-cluster-critical +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/instance: flux-system + app.kubernetes.io/part-of: flux + app.kubernetes.io/version: v2.4.0 + name: crd-controller-flux-system +rules: +- apiGroups: + - source.toolkit.fluxcd.io + resources: + - '*' + verbs: + - '*' +- apiGroups: + - kustomize.toolkit.fluxcd.io + resources: + - '*' + verbs: + - '*' +- apiGroups: + - helm.toolkit.fluxcd.io + resources: + - '*' + verbs: + - '*' +- apiGroups: + - notification.toolkit.fluxcd.io + resources: + - '*' + verbs: + - '*' +- apiGroups: + - image.toolkit.fluxcd.io + resources: + - '*' + verbs: + - '*' +- apiGroups: + - "" + resources: + - namespaces + - secrets + - configmaps + - serviceaccounts + verbs: + - get + - list + - watch +- apiGroups: + - "" + resources: + - events + verbs: + - create + - patch +- apiGroups: + - "" + resources: + - configmaps + verbs: + - get + - list + - watch + - create + - update + - patch + - delete +- apiGroups: + - "" + resources: + - configmaps/status + verbs: + - get + - update + - patch +- apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - get + - list + - watch + - create + - update + - patch + - delete +- nonResourceURLs: + - /livez/ping + verbs: + - head +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/instance: flux-system + app.kubernetes.io/part-of: flux + app.kubernetes.io/version: v2.4.0 + rbac.authorization.k8s.io/aggregate-to-admin: "true" + rbac.authorization.k8s.io/aggregate-to-edit: "true" + name: flux-edit-flux-system +rules: +- apiGroups: + - notification.toolkit.fluxcd.io + - source.toolkit.fluxcd.io + - helm.toolkit.fluxcd.io + - image.toolkit.fluxcd.io + - kustomize.toolkit.fluxcd.io + resources: + - '*' + verbs: + - create + - delete + - deletecollection + - patch + - update +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/instance: flux-system + app.kubernetes.io/part-of: flux + app.kubernetes.io/version: v2.4.0 + rbac.authorization.k8s.io/aggregate-to-admin: "true" + rbac.authorization.k8s.io/aggregate-to-edit: "true" + rbac.authorization.k8s.io/aggregate-to-view: "true" + name: flux-view-flux-system +rules: +- apiGroups: + - notification.toolkit.fluxcd.io + - source.toolkit.fluxcd.io + - helm.toolkit.fluxcd.io + - image.toolkit.fluxcd.io + - kustomize.toolkit.fluxcd.io + resources: + - '*' + verbs: + - get + - list + - watch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + app.kubernetes.io/instance: flux-system + app.kubernetes.io/part-of: flux + app.kubernetes.io/version: v2.4.0 + name: cluster-reconciler-flux-system +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: cluster-admin +subjects: +- kind: ServiceAccount + name: kustomize-controller + namespace: flux-system +- kind: ServiceAccount + name: helm-controller + namespace: flux-system +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + app.kubernetes.io/instance: flux-system + app.kubernetes.io/part-of: flux + app.kubernetes.io/version: v2.4.0 + name: crd-controller-flux-system +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: crd-controller-flux-system +subjects: +- kind: ServiceAccount + name: kustomize-controller + namespace: flux-system +- kind: ServiceAccount + name: helm-controller + namespace: flux-system +- kind: ServiceAccount + name: source-controller + namespace: flux-system +- kind: ServiceAccount + name: notification-controller + namespace: flux-system +- kind: ServiceAccount + name: image-reflector-controller + namespace: flux-system +- kind: ServiceAccount + name: image-automation-controller + namespace: flux-system +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.16.1 + labels: + app.kubernetes.io/component: source-controller + app.kubernetes.io/instance: flux-system + app.kubernetes.io/part-of: flux + app.kubernetes.io/version: v2.4.0 + name: buckets.source.toolkit.fluxcd.io +spec: + group: source.toolkit.fluxcd.io + names: + kind: Bucket + listKind: BucketList + plural: buckets + singular: bucket + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .spec.endpoint + name: Endpoint + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + - jsonPath: .status.conditions[?(@.type=="Ready")].status + name: Ready + type: string + - jsonPath: .status.conditions[?(@.type=="Ready")].message + name: Status + type: string + name: v1 + schema: + openAPIV3Schema: + description: Bucket is the Schema for the buckets API. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: |- + BucketSpec specifies the required configuration to produce an Artifact for + an object storage bucket. + properties: + bucketName: + description: BucketName is the name of the object storage bucket. + type: string + certSecretRef: + description: |- + CertSecretRef can be given the name of a Secret containing + either or both of + + - a PEM-encoded client certificate (`tls.crt`) and private + key (`tls.key`); + - a PEM-encoded CA certificate (`ca.crt`) + + and whichever are supplied, will be used for connecting to the + bucket. The client cert and key are useful if you are + authenticating with a certificate; the CA cert is useful if + you are using a self-signed server certificate. The Secret must + be of type `Opaque` or `kubernetes.io/tls`. + + This field is only supported for the `generic` provider. + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + endpoint: + description: Endpoint is the object storage address the BucketName + is located at. + type: string + ignore: + description: |- + Ignore overrides the set of excluded patterns in the .sourceignore format + (which is the same as .gitignore). If not provided, a default will be used, + consult the documentation for your version to find out what those are. + type: string + insecure: + description: Insecure allows connecting to a non-TLS HTTP Endpoint. + type: boolean + interval: + description: |- + Interval at which the Bucket Endpoint is checked for updates. + This interval is approximate and may be subject to jitter to ensure + efficient use of resources. + pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ + type: string + prefix: + description: Prefix to use for server-side filtering of files in the + Bucket. + type: string + provider: + default: generic + description: |- + Provider of the object storage bucket. + Defaults to 'generic', which expects an S3 (API) compatible object + storage. + enum: + - generic + - aws + - gcp + - azure + type: string + proxySecretRef: + description: |- + ProxySecretRef specifies the Secret containing the proxy configuration + to use while communicating with the Bucket server. + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + region: + description: Region of the Endpoint where the BucketName is located + in. + type: string + secretRef: + description: |- + SecretRef specifies the Secret containing authentication credentials + for the Bucket. + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + sts: + description: |- + STS specifies the required configuration to use a Security Token + Service for fetching temporary credentials to authenticate in a + Bucket provider. + + This field is only supported for the `aws` and `generic` providers. + properties: + certSecretRef: + description: |- + CertSecretRef can be given the name of a Secret containing + either or both of + + - a PEM-encoded client certificate (`tls.crt`) and private + key (`tls.key`); + - a PEM-encoded CA certificate (`ca.crt`) + + and whichever are supplied, will be used for connecting to the + STS endpoint. The client cert and key are useful if you are + authenticating with a certificate; the CA cert is useful if + you are using a self-signed server certificate. The Secret must + be of type `Opaque` or `kubernetes.io/tls`. + + This field is only supported for the `ldap` provider. + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + endpoint: + description: |- + Endpoint is the HTTP/S endpoint of the Security Token Service from + where temporary credentials will be fetched. + pattern: ^(http|https)://.*$ + type: string + provider: + description: Provider of the Security Token Service. + enum: + - aws + - ldap + type: string + secretRef: + description: |- + SecretRef specifies the Secret containing authentication credentials + for the STS endpoint. This Secret must contain the fields `username` + and `password` and is supported only for the `ldap` provider. + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + required: + - endpoint + - provider + type: object + suspend: + description: |- + Suspend tells the controller to suspend the reconciliation of this + Bucket. + type: boolean + timeout: + default: 60s + description: Timeout for fetch operations, defaults to 60s. + pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m))+$ + type: string + required: + - bucketName + - endpoint + - interval + type: object + x-kubernetes-validations: + - message: STS configuration is only supported for the 'aws' and 'generic' + Bucket providers + rule: self.provider == 'aws' || self.provider == 'generic' || !has(self.sts) + - message: '''aws'' is the only supported STS provider for the ''aws'' + Bucket provider' + rule: self.provider != 'aws' || !has(self.sts) || self.sts.provider + == 'aws' + - message: '''ldap'' is the only supported STS provider for the ''generic'' + Bucket provider' + rule: self.provider != 'generic' || !has(self.sts) || self.sts.provider + == 'ldap' + - message: spec.sts.secretRef is not required for the 'aws' STS provider + rule: '!has(self.sts) || self.sts.provider != ''aws'' || !has(self.sts.secretRef)' + - message: spec.sts.certSecretRef is not required for the 'aws' STS provider + rule: '!has(self.sts) || self.sts.provider != ''aws'' || !has(self.sts.certSecretRef)' + status: + default: + observedGeneration: -1 + description: BucketStatus records the observed state of a Bucket. + properties: + artifact: + description: Artifact represents the last successful Bucket reconciliation. + properties: + digest: + description: Digest is the digest of the file in the form of '<algorithm>:<checksum>'. + pattern: ^[a-z0-9]+(?:[.+_-][a-z0-9]+)*:[a-zA-Z0-9=_-]+$ + type: string + lastUpdateTime: + description: |- + LastUpdateTime is the timestamp corresponding to the last update of the + Artifact. + format: date-time + type: string + metadata: + additionalProperties: + type: string + description: Metadata holds upstream information such as OCI annotations. + type: object + path: + description: |- + Path is the relative file path of the Artifact. It can be used to locate + the file in the root of the Artifact storage on the local file system of + the controller managing the Source. + type: string + revision: + description: |- + Revision is a human-readable identifier traceable in the origin source + system. It can be a Git commit SHA, Git tag, a Helm chart version, etc. + type: string + size: + description: Size is the number of bytes in the file. + format: int64 + type: integer + url: + description: |- + URL is the HTTP address of the Artifact as exposed by the controller + managing the Source. It can be used to retrieve the Artifact for + consumption, e.g. by another controller applying the Artifact contents. + type: string + required: + - lastUpdateTime + - path + - revision + - url + type: object + conditions: + description: Conditions holds the conditions for the Bucket. + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + lastHandledReconcileAt: + description: |- + LastHandledReconcileAt holds the value of the most recent + reconcile request value, so a change of the annotation value + can be detected. + type: string + observedGeneration: + description: ObservedGeneration is the last observed generation of + the Bucket object. + format: int64 + type: integer + observedIgnore: + description: |- + ObservedIgnore is the observed exclusion patterns used for constructing + the source artifact. + type: string + url: + description: |- + URL is the dynamic fetch link for the latest Artifact. + It is provided on a "best effort" basis, and using the precise + BucketStatus.Artifact data is recommended. + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} + - additionalPrinterColumns: + - jsonPath: .spec.endpoint + name: Endpoint + type: string + - jsonPath: .status.conditions[?(@.type=="Ready")].status + name: Ready + type: string + - jsonPath: .status.conditions[?(@.type=="Ready")].message + name: Status + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + deprecated: true + deprecationWarning: v1beta1 Bucket is deprecated, upgrade to v1 + name: v1beta1 + schema: + openAPIV3Schema: + description: Bucket is the Schema for the buckets API + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: BucketSpec defines the desired state of an S3 compatible + bucket + properties: + accessFrom: + description: AccessFrom defines an Access Control List for allowing + cross-namespace references to this object. + properties: + namespaceSelectors: + description: |- + NamespaceSelectors is the list of namespace selectors to which this ACL applies. + Items in this list are evaluated using a logical OR operation. + items: + description: |- + NamespaceSelector selects the namespaces to which this ACL applies. + An empty map of MatchLabels matches all namespaces in a cluster. + properties: + matchLabels: + additionalProperties: + type: string + description: |- + MatchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + type: array + required: + - namespaceSelectors + type: object + bucketName: + description: The bucket name. + type: string + endpoint: + description: The bucket endpoint address. + type: string + ignore: + description: |- + Ignore overrides the set of excluded patterns in the .sourceignore format + (which is the same as .gitignore). If not provided, a default will be used, + consult the documentation for your version to find out what those are. + type: string + insecure: + description: Insecure allows connecting to a non-TLS S3 HTTP endpoint. + type: boolean + interval: + description: The interval at which to check for bucket updates. + type: string + provider: + default: generic + description: The S3 compatible storage provider name, default ('generic'). + enum: + - generic + - aws + - gcp + type: string + region: + description: The bucket region. + type: string + secretRef: + description: |- + The name of the secret containing authentication credentials + for the Bucket. + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + suspend: + description: This flag tells the controller to suspend the reconciliation + of this source. + type: boolean + timeout: + default: 60s + description: The timeout for download operations, defaults to 60s. + type: string + required: + - bucketName + - endpoint + - interval + type: object + status: + default: + observedGeneration: -1 + description: BucketStatus defines the observed state of a bucket + properties: + artifact: + description: Artifact represents the output of the last successful + Bucket sync. + properties: + checksum: + description: Checksum is the SHA256 checksum of the artifact. + type: string + lastUpdateTime: + description: |- + LastUpdateTime is the timestamp corresponding to the last update of this + artifact. + format: date-time + type: string + path: + description: Path is the relative file path of this artifact. + type: string + revision: + description: |- + Revision is a human readable identifier traceable in the origin source + system. It can be a Git commit SHA, Git tag, a Helm index timestamp, a Helm + chart version, etc. + type: string + url: + description: URL is the HTTP address of this artifact. + type: string + required: + - lastUpdateTime + - path + - url + type: object + conditions: + description: Conditions holds the conditions for the Bucket. + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + lastHandledReconcileAt: + description: |- + LastHandledReconcileAt holds the value of the most recent + reconcile request value, so a change of the annotation value + can be detected. + type: string + observedGeneration: + description: ObservedGeneration is the last observed generation. + format: int64 + type: integer + url: + description: URL is the download link for the artifact output of the + last Bucket sync. + type: string + type: object + type: object + served: true + storage: false + subresources: + status: {} + - additionalPrinterColumns: + - jsonPath: .spec.endpoint + name: Endpoint + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + - jsonPath: .status.conditions[?(@.type=="Ready")].status + name: Ready + type: string + - jsonPath: .status.conditions[?(@.type=="Ready")].message + name: Status + type: string + deprecated: true + deprecationWarning: v1beta2 Bucket is deprecated, upgrade to v1 + name: v1beta2 + schema: + openAPIV3Schema: + description: Bucket is the Schema for the buckets API. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: |- + BucketSpec specifies the required configuration to produce an Artifact for + an object storage bucket. + properties: + accessFrom: + description: |- + AccessFrom specifies an Access Control List for allowing cross-namespace + references to this object. + NOTE: Not implemented, provisional as of https://github.com/fluxcd/flux2/pull/2092 + properties: + namespaceSelectors: + description: |- + NamespaceSelectors is the list of namespace selectors to which this ACL applies. + Items in this list are evaluated using a logical OR operation. + items: + description: |- + NamespaceSelector selects the namespaces to which this ACL applies. + An empty map of MatchLabels matches all namespaces in a cluster. + properties: + matchLabels: + additionalProperties: + type: string + description: |- + MatchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + type: array + required: + - namespaceSelectors + type: object + bucketName: + description: BucketName is the name of the object storage bucket. + type: string + certSecretRef: + description: |- + CertSecretRef can be given the name of a Secret containing + either or both of + + - a PEM-encoded client certificate (`tls.crt`) and private + key (`tls.key`); + - a PEM-encoded CA certificate (`ca.crt`) + + and whichever are supplied, will be used for connecting to the + bucket. The client cert and key are useful if you are + authenticating with a certificate; the CA cert is useful if + you are using a self-signed server certificate. The Secret must + be of type `Opaque` or `kubernetes.io/tls`. + + This field is only supported for the `generic` provider. + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + endpoint: + description: Endpoint is the object storage address the BucketName + is located at. + type: string + ignore: + description: |- + Ignore overrides the set of excluded patterns in the .sourceignore format + (which is the same as .gitignore). If not provided, a default will be used, + consult the documentation for your version to find out what those are. + type: string + insecure: + description: Insecure allows connecting to a non-TLS HTTP Endpoint. + type: boolean + interval: + description: |- + Interval at which the Bucket Endpoint is checked for updates. + This interval is approximate and may be subject to jitter to ensure + efficient use of resources. + pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ + type: string + prefix: + description: Prefix to use for server-side filtering of files in the + Bucket. + type: string + provider: + default: generic + description: |- + Provider of the object storage bucket. + Defaults to 'generic', which expects an S3 (API) compatible object + storage. + enum: + - generic + - aws + - gcp + - azure + type: string + proxySecretRef: + description: |- + ProxySecretRef specifies the Secret containing the proxy configuration + to use while communicating with the Bucket server. + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + region: + description: Region of the Endpoint where the BucketName is located + in. + type: string + secretRef: + description: |- + SecretRef specifies the Secret containing authentication credentials + for the Bucket. + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + sts: + description: |- + STS specifies the required configuration to use a Security Token + Service for fetching temporary credentials to authenticate in a + Bucket provider. + + This field is only supported for the `aws` and `generic` providers. + properties: + certSecretRef: + description: |- + CertSecretRef can be given the name of a Secret containing + either or both of + + - a PEM-encoded client certificate (`tls.crt`) and private + key (`tls.key`); + - a PEM-encoded CA certificate (`ca.crt`) + + and whichever are supplied, will be used for connecting to the + STS endpoint. The client cert and key are useful if you are + authenticating with a certificate; the CA cert is useful if + you are using a self-signed server certificate. The Secret must + be of type `Opaque` or `kubernetes.io/tls`. + + This field is only supported for the `ldap` provider. + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + endpoint: + description: |- + Endpoint is the HTTP/S endpoint of the Security Token Service from + where temporary credentials will be fetched. + pattern: ^(http|https)://.*$ + type: string + provider: + description: Provider of the Security Token Service. + enum: + - aws + - ldap + type: string + secretRef: + description: |- + SecretRef specifies the Secret containing authentication credentials + for the STS endpoint. This Secret must contain the fields `username` + and `password` and is supported only for the `ldap` provider. + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + required: + - endpoint + - provider + type: object + suspend: + description: |- + Suspend tells the controller to suspend the reconciliation of this + Bucket. + type: boolean + timeout: + default: 60s + description: Timeout for fetch operations, defaults to 60s. + pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m))+$ + type: string + required: + - bucketName + - endpoint + - interval + type: object + x-kubernetes-validations: + - message: STS configuration is only supported for the 'aws' and 'generic' + Bucket providers + rule: self.provider == 'aws' || self.provider == 'generic' || !has(self.sts) + - message: '''aws'' is the only supported STS provider for the ''aws'' + Bucket provider' + rule: self.provider != 'aws' || !has(self.sts) || self.sts.provider + == 'aws' + - message: '''ldap'' is the only supported STS provider for the ''generic'' + Bucket provider' + rule: self.provider != 'generic' || !has(self.sts) || self.sts.provider + == 'ldap' + - message: spec.sts.secretRef is not required for the 'aws' STS provider + rule: '!has(self.sts) || self.sts.provider != ''aws'' || !has(self.sts.secretRef)' + - message: spec.sts.certSecretRef is not required for the 'aws' STS provider + rule: '!has(self.sts) || self.sts.provider != ''aws'' || !has(self.sts.certSecretRef)' + status: + default: + observedGeneration: -1 + description: BucketStatus records the observed state of a Bucket. + properties: + artifact: + description: Artifact represents the last successful Bucket reconciliation. + properties: + digest: + description: Digest is the digest of the file in the form of '<algorithm>:<checksum>'. + pattern: ^[a-z0-9]+(?:[.+_-][a-z0-9]+)*:[a-zA-Z0-9=_-]+$ + type: string + lastUpdateTime: + description: |- + LastUpdateTime is the timestamp corresponding to the last update of the + Artifact. + format: date-time + type: string + metadata: + additionalProperties: + type: string + description: Metadata holds upstream information such as OCI annotations. + type: object + path: + description: |- + Path is the relative file path of the Artifact. It can be used to locate + the file in the root of the Artifact storage on the local file system of + the controller managing the Source. + type: string + revision: + description: |- + Revision is a human-readable identifier traceable in the origin source + system. It can be a Git commit SHA, Git tag, a Helm chart version, etc. + type: string + size: + description: Size is the number of bytes in the file. + format: int64 + type: integer + url: + description: |- + URL is the HTTP address of the Artifact as exposed by the controller + managing the Source. It can be used to retrieve the Artifact for + consumption, e.g. by another controller applying the Artifact contents. + type: string + required: + - lastUpdateTime + - path + - revision + - url + type: object + conditions: + description: Conditions holds the conditions for the Bucket. + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + lastHandledReconcileAt: + description: |- + LastHandledReconcileAt holds the value of the most recent + reconcile request value, so a change of the annotation value + can be detected. + type: string + observedGeneration: + description: ObservedGeneration is the last observed generation of + the Bucket object. + format: int64 + type: integer + observedIgnore: + description: |- + ObservedIgnore is the observed exclusion patterns used for constructing + the source artifact. + type: string + url: + description: |- + URL is the dynamic fetch link for the latest Artifact. + It is provided on a "best effort" basis, and using the precise + BucketStatus.Artifact data is recommended. + type: string + type: object + type: object + served: true + storage: false + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.16.1 + labels: + app.kubernetes.io/component: source-controller + app.kubernetes.io/instance: flux-system + app.kubernetes.io/part-of: flux + app.kubernetes.io/version: v2.4.0 + name: gitrepositories.source.toolkit.fluxcd.io +spec: + group: source.toolkit.fluxcd.io + names: + kind: GitRepository + listKind: GitRepositoryList + plural: gitrepositories + shortNames: + - gitrepo + singular: gitrepository + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .spec.url + name: URL + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + - jsonPath: .status.conditions[?(@.type=="Ready")].status + name: Ready + type: string + - jsonPath: .status.conditions[?(@.type=="Ready")].message + name: Status + type: string + name: v1 + schema: + openAPIV3Schema: + description: GitRepository is the Schema for the gitrepositories API. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: |- + GitRepositorySpec specifies the required configuration to produce an + Artifact for a Git repository. + properties: + ignore: + description: |- + Ignore overrides the set of excluded patterns in the .sourceignore format + (which is the same as .gitignore). If not provided, a default will be used, + consult the documentation for your version to find out what those are. + type: string + include: + description: |- + Include specifies a list of GitRepository resources which Artifacts + should be included in the Artifact produced for this GitRepository. + items: + description: |- + GitRepositoryInclude specifies a local reference to a GitRepository which + Artifact (sub-)contents must be included, and where they should be placed. + properties: + fromPath: + description: |- + FromPath specifies the path to copy contents from, defaults to the root + of the Artifact. + type: string + repository: + description: |- + GitRepositoryRef specifies the GitRepository which Artifact contents + must be included. + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + toPath: + description: |- + ToPath specifies the path to copy contents to, defaults to the name of + the GitRepositoryRef. + type: string + required: + - repository + type: object + type: array + interval: + description: |- + Interval at which the GitRepository URL is checked for updates. + This interval is approximate and may be subject to jitter to ensure + efficient use of resources. + pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ + type: string + provider: + description: |- + Provider used for authentication, can be 'azure', 'generic'. + When not specified, defaults to 'generic'. + enum: + - generic + - azure + type: string + proxySecretRef: + description: |- + ProxySecretRef specifies the Secret containing the proxy configuration + to use while communicating with the Git server. + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + recurseSubmodules: + description: |- + RecurseSubmodules enables the initialization of all submodules within + the GitRepository as cloned from the URL, using their default settings. + type: boolean + ref: + description: |- + Reference specifies the Git reference to resolve and monitor for + changes, defaults to the 'master' branch. + properties: + branch: + description: Branch to check out, defaults to 'master' if no other + field is defined. + type: string + commit: + description: |- + Commit SHA to check out, takes precedence over all reference fields. + + This can be combined with Branch to shallow clone the branch, in which + the commit is expected to exist. + type: string + name: + description: |- + Name of the reference to check out; takes precedence over Branch, Tag and SemVer. + + It must be a valid Git reference: https://git-scm.com/docs/git-check-ref-format#_description + Examples: "refs/heads/main", "refs/tags/v0.1.0", "refs/pull/420/head", "refs/merge-requests/1/head" + type: string + semver: + description: SemVer tag expression to check out, takes precedence + over Tag. + type: string + tag: + description: Tag to check out, takes precedence over Branch. + type: string + type: object + secretRef: + description: |- + SecretRef specifies the Secret containing authentication credentials for + the GitRepository. + For HTTPS repositories the Secret must contain 'username' and 'password' + fields for basic auth or 'bearerToken' field for token auth. + For SSH repositories the Secret must contain 'identity' + and 'known_hosts' fields. + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + suspend: + description: |- + Suspend tells the controller to suspend the reconciliation of this + GitRepository. + type: boolean + timeout: + default: 60s + description: Timeout for Git operations like cloning, defaults to + 60s. + pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m))+$ + type: string + url: + description: URL specifies the Git repository URL, it can be an HTTP/S + or SSH address. + pattern: ^(http|https|ssh)://.*$ + type: string + verify: + description: |- + Verification specifies the configuration to verify the Git commit + signature(s). + properties: + mode: + default: HEAD + description: |- + Mode specifies which Git object(s) should be verified. + + The variants "head" and "HEAD" both imply the same thing, i.e. verify + the commit that the HEAD of the Git repository points to. The variant + "head" solely exists to ensure backwards compatibility. + enum: + - head + - HEAD + - Tag + - TagAndHEAD + type: string + secretRef: + description: |- + SecretRef specifies the Secret containing the public keys of trusted Git + authors. + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + required: + - secretRef + type: object + required: + - interval + - url + type: object + status: + default: + observedGeneration: -1 + description: GitRepositoryStatus records the observed state of a Git repository. + properties: + artifact: + description: Artifact represents the last successful GitRepository + reconciliation. + properties: + digest: + description: Digest is the digest of the file in the form of '<algorithm>:<checksum>'. + pattern: ^[a-z0-9]+(?:[.+_-][a-z0-9]+)*:[a-zA-Z0-9=_-]+$ + type: string + lastUpdateTime: + description: |- + LastUpdateTime is the timestamp corresponding to the last update of the + Artifact. + format: date-time + type: string + metadata: + additionalProperties: + type: string + description: Metadata holds upstream information such as OCI annotations. + type: object + path: + description: |- + Path is the relative file path of the Artifact. It can be used to locate + the file in the root of the Artifact storage on the local file system of + the controller managing the Source. + type: string + revision: + description: |- + Revision is a human-readable identifier traceable in the origin source + system. It can be a Git commit SHA, Git tag, a Helm chart version, etc. + type: string + size: + description: Size is the number of bytes in the file. + format: int64 + type: integer + url: + description: |- + URL is the HTTP address of the Artifact as exposed by the controller + managing the Source. It can be used to retrieve the Artifact for + consumption, e.g. by another controller applying the Artifact contents. + type: string + required: + - lastUpdateTime + - path + - revision + - url + type: object + conditions: + description: Conditions holds the conditions for the GitRepository. + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + includedArtifacts: + description: |- + IncludedArtifacts contains a list of the last successfully included + Artifacts as instructed by GitRepositorySpec.Include. + items: + description: Artifact represents the output of a Source reconciliation. + properties: + digest: + description: Digest is the digest of the file in the form of + '<algorithm>:<checksum>'. + pattern: ^[a-z0-9]+(?:[.+_-][a-z0-9]+)*:[a-zA-Z0-9=_-]+$ + type: string + lastUpdateTime: + description: |- + LastUpdateTime is the timestamp corresponding to the last update of the + Artifact. + format: date-time + type: string + metadata: + additionalProperties: + type: string + description: Metadata holds upstream information such as OCI + annotations. + type: object + path: + description: |- + Path is the relative file path of the Artifact. It can be used to locate + the file in the root of the Artifact storage on the local file system of + the controller managing the Source. + type: string + revision: + description: |- + Revision is a human-readable identifier traceable in the origin source + system. It can be a Git commit SHA, Git tag, a Helm chart version, etc. + type: string + size: + description: Size is the number of bytes in the file. + format: int64 + type: integer + url: + description: |- + URL is the HTTP address of the Artifact as exposed by the controller + managing the Source. It can be used to retrieve the Artifact for + consumption, e.g. by another controller applying the Artifact contents. + type: string + required: + - lastUpdateTime + - path + - revision + - url + type: object + type: array + lastHandledReconcileAt: + description: |- + LastHandledReconcileAt holds the value of the most recent + reconcile request value, so a change of the annotation value + can be detected. + type: string + observedGeneration: + description: |- + ObservedGeneration is the last observed generation of the GitRepository + object. + format: int64 + type: integer + observedIgnore: + description: |- + ObservedIgnore is the observed exclusion patterns used for constructing + the source artifact. + type: string + observedInclude: + description: |- + ObservedInclude is the observed list of GitRepository resources used to + produce the current Artifact. + items: + description: |- + GitRepositoryInclude specifies a local reference to a GitRepository which + Artifact (sub-)contents must be included, and where they should be placed. + properties: + fromPath: + description: |- + FromPath specifies the path to copy contents from, defaults to the root + of the Artifact. + type: string + repository: + description: |- + GitRepositoryRef specifies the GitRepository which Artifact contents + must be included. + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + toPath: + description: |- + ToPath specifies the path to copy contents to, defaults to the name of + the GitRepositoryRef. + type: string + required: + - repository + type: object + type: array + observedRecurseSubmodules: + description: |- + ObservedRecurseSubmodules is the observed resource submodules + configuration used to produce the current Artifact. + type: boolean + sourceVerificationMode: + description: |- + SourceVerificationMode is the last used verification mode indicating + which Git object(s) have been verified. + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} + - additionalPrinterColumns: + - jsonPath: .spec.url + name: URL + type: string + - jsonPath: .status.conditions[?(@.type=="Ready")].status + name: Ready + type: string + - jsonPath: .status.conditions[?(@.type=="Ready")].message + name: Status + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + deprecated: true + deprecationWarning: v1beta1 GitRepository is deprecated, upgrade to v1 + name: v1beta1 + schema: + openAPIV3Schema: + description: GitRepository is the Schema for the gitrepositories API + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: GitRepositorySpec defines the desired state of a Git repository. + properties: + accessFrom: + description: AccessFrom defines an Access Control List for allowing + cross-namespace references to this object. + properties: + namespaceSelectors: + description: |- + NamespaceSelectors is the list of namespace selectors to which this ACL applies. + Items in this list are evaluated using a logical OR operation. + items: + description: |- + NamespaceSelector selects the namespaces to which this ACL applies. + An empty map of MatchLabels matches all namespaces in a cluster. + properties: + matchLabels: + additionalProperties: + type: string + description: |- + MatchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + type: array + required: + - namespaceSelectors + type: object + gitImplementation: + default: go-git + description: |- + Determines which git client library to use. + Defaults to go-git, valid values are ('go-git', 'libgit2'). + enum: + - go-git + - libgit2 + type: string + ignore: + description: |- + Ignore overrides the set of excluded patterns in the .sourceignore format + (which is the same as .gitignore). If not provided, a default will be used, + consult the documentation for your version to find out what those are. + type: string + include: + description: Extra git repositories to map into the repository + items: + description: GitRepositoryInclude defines a source with a from and + to path. + properties: + fromPath: + description: The path to copy contents from, defaults to the + root directory. + type: string + repository: + description: Reference to a GitRepository to include. + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + toPath: + description: The path to copy contents to, defaults to the name + of the source ref. + type: string + required: + - repository + type: object + type: array + interval: + description: The interval at which to check for repository updates. + type: string + recurseSubmodules: + description: |- + When enabled, after the clone is created, initializes all submodules within, + using their default settings. + This option is available only when using the 'go-git' GitImplementation. + type: boolean + ref: + description: |- + The Git reference to checkout and monitor for changes, defaults to + master branch. + properties: + branch: + description: The Git branch to checkout, defaults to master. + type: string + commit: + description: The Git commit SHA to checkout, if specified Tag + filters will be ignored. + type: string + semver: + description: The Git tag semver expression, takes precedence over + Tag. + type: string + tag: + description: The Git tag to checkout, takes precedence over Branch. + type: string + type: object + secretRef: + description: |- + The secret name containing the Git credentials. + For HTTPS repositories the secret must contain username and password + fields. + For SSH repositories the secret must contain identity and known_hosts + fields. + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + suspend: + description: This flag tells the controller to suspend the reconciliation + of this source. + type: boolean + timeout: + default: 60s + description: The timeout for remote Git operations like cloning, defaults + to 60s. + type: string + url: + description: The repository URL, can be a HTTP/S or SSH address. + pattern: ^(http|https|ssh)://.*$ + type: string + verify: + description: Verify OpenPGP signature for the Git commit HEAD points + to. + properties: + mode: + description: Mode describes what git object should be verified, + currently ('head'). + enum: + - head + type: string + secretRef: + description: The secret name containing the public keys of all + trusted Git authors. + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + required: + - mode + type: object + required: + - interval + - url + type: object + status: + default: + observedGeneration: -1 + description: GitRepositoryStatus defines the observed state of a Git repository. + properties: + artifact: + description: Artifact represents the output of the last successful + repository sync. + properties: + checksum: + description: Checksum is the SHA256 checksum of the artifact. + type: string + lastUpdateTime: + description: |- + LastUpdateTime is the timestamp corresponding to the last update of this + artifact. + format: date-time + type: string + path: + description: Path is the relative file path of this artifact. + type: string + revision: + description: |- + Revision is a human readable identifier traceable in the origin source + system. It can be a Git commit SHA, Git tag, a Helm index timestamp, a Helm + chart version, etc. + type: string + url: + description: URL is the HTTP address of this artifact. + type: string + required: + - lastUpdateTime + - path + - url + type: object + conditions: + description: Conditions holds the conditions for the GitRepository. + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + includedArtifacts: + description: IncludedArtifacts represents the included artifacts from + the last successful repository sync. + items: + description: Artifact represents the output of a source synchronisation. + properties: + checksum: + description: Checksum is the SHA256 checksum of the artifact. + type: string + lastUpdateTime: + description: |- + LastUpdateTime is the timestamp corresponding to the last update of this + artifact. + format: date-time + type: string + path: + description: Path is the relative file path of this artifact. + type: string + revision: + description: |- + Revision is a human readable identifier traceable in the origin source + system. It can be a Git commit SHA, Git tag, a Helm index timestamp, a Helm + chart version, etc. + type: string + url: + description: URL is the HTTP address of this artifact. + type: string + required: + - lastUpdateTime + - path + - url + type: object + type: array + lastHandledReconcileAt: + description: |- + LastHandledReconcileAt holds the value of the most recent + reconcile request value, so a change of the annotation value + can be detected. + type: string + observedGeneration: + description: ObservedGeneration is the last observed generation. + format: int64 + type: integer + url: + description: |- + URL is the download link for the artifact output of the last repository + sync. + type: string + type: object + type: object + served: true + storage: false + subresources: + status: {} + - additionalPrinterColumns: + - jsonPath: .spec.url + name: URL + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + - jsonPath: .status.conditions[?(@.type=="Ready")].status + name: Ready + type: string + - jsonPath: .status.conditions[?(@.type=="Ready")].message + name: Status + type: string + deprecated: true + deprecationWarning: v1beta2 GitRepository is deprecated, upgrade to v1 + name: v1beta2 + schema: + openAPIV3Schema: + description: GitRepository is the Schema for the gitrepositories API. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: |- + GitRepositorySpec specifies the required configuration to produce an + Artifact for a Git repository. + properties: + accessFrom: + description: |- + AccessFrom specifies an Access Control List for allowing cross-namespace + references to this object. + NOTE: Not implemented, provisional as of https://github.com/fluxcd/flux2/pull/2092 + properties: + namespaceSelectors: + description: |- + NamespaceSelectors is the list of namespace selectors to which this ACL applies. + Items in this list are evaluated using a logical OR operation. + items: + description: |- + NamespaceSelector selects the namespaces to which this ACL applies. + An empty map of MatchLabels matches all namespaces in a cluster. + properties: + matchLabels: + additionalProperties: + type: string + description: |- + MatchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + type: array + required: + - namespaceSelectors + type: object + gitImplementation: + default: go-git + description: |- + GitImplementation specifies which Git client library implementation to + use. Defaults to 'go-git', valid values are ('go-git', 'libgit2'). + Deprecated: gitImplementation is deprecated now that 'go-git' is the + only supported implementation. + enum: + - go-git + - libgit2 + type: string + ignore: + description: |- + Ignore overrides the set of excluded patterns in the .sourceignore format + (which is the same as .gitignore). If not provided, a default will be used, + consult the documentation for your version to find out what those are. + type: string + include: + description: |- + Include specifies a list of GitRepository resources which Artifacts + should be included in the Artifact produced for this GitRepository. + items: + description: |- + GitRepositoryInclude specifies a local reference to a GitRepository which + Artifact (sub-)contents must be included, and where they should be placed. + properties: + fromPath: + description: |- + FromPath specifies the path to copy contents from, defaults to the root + of the Artifact. + type: string + repository: + description: |- + GitRepositoryRef specifies the GitRepository which Artifact contents + must be included. + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + toPath: + description: |- + ToPath specifies the path to copy contents to, defaults to the name of + the GitRepositoryRef. + type: string + required: + - repository + type: object + type: array + interval: + description: Interval at which to check the GitRepository for updates. + pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ + type: string + recurseSubmodules: + description: |- + RecurseSubmodules enables the initialization of all submodules within + the GitRepository as cloned from the URL, using their default settings. + type: boolean + ref: + description: |- + Reference specifies the Git reference to resolve and monitor for + changes, defaults to the 'master' branch. + properties: + branch: + description: Branch to check out, defaults to 'master' if no other + field is defined. + type: string + commit: + description: |- + Commit SHA to check out, takes precedence over all reference fields. + + This can be combined with Branch to shallow clone the branch, in which + the commit is expected to exist. + type: string + name: + description: |- + Name of the reference to check out; takes precedence over Branch, Tag and SemVer. + + It must be a valid Git reference: https://git-scm.com/docs/git-check-ref-format#_description + Examples: "refs/heads/main", "refs/tags/v0.1.0", "refs/pull/420/head", "refs/merge-requests/1/head" + type: string + semver: + description: SemVer tag expression to check out, takes precedence + over Tag. + type: string + tag: + description: Tag to check out, takes precedence over Branch. + type: string + type: object + secretRef: + description: |- + SecretRef specifies the Secret containing authentication credentials for + the GitRepository. + For HTTPS repositories the Secret must contain 'username' and 'password' + fields for basic auth or 'bearerToken' field for token auth. + For SSH repositories the Secret must contain 'identity' + and 'known_hosts' fields. + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + suspend: + description: |- + Suspend tells the controller to suspend the reconciliation of this + GitRepository. + type: boolean + timeout: + default: 60s + description: Timeout for Git operations like cloning, defaults to + 60s. + pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m))+$ + type: string + url: + description: URL specifies the Git repository URL, it can be an HTTP/S + or SSH address. + pattern: ^(http|https|ssh)://.*$ + type: string + verify: + description: |- + Verification specifies the configuration to verify the Git commit + signature(s). + properties: + mode: + description: Mode specifies what Git object should be verified, + currently ('head'). + enum: + - head + type: string + secretRef: + description: |- + SecretRef specifies the Secret containing the public keys of trusted Git + authors. + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + required: + - mode + - secretRef + type: object + required: + - interval + - url + type: object + status: + default: + observedGeneration: -1 + description: GitRepositoryStatus records the observed state of a Git repository. + properties: + artifact: + description: Artifact represents the last successful GitRepository + reconciliation. + properties: + digest: + description: Digest is the digest of the file in the form of '<algorithm>:<checksum>'. + pattern: ^[a-z0-9]+(?:[.+_-][a-z0-9]+)*:[a-zA-Z0-9=_-]+$ + type: string + lastUpdateTime: + description: |- + LastUpdateTime is the timestamp corresponding to the last update of the + Artifact. + format: date-time + type: string + metadata: + additionalProperties: + type: string + description: Metadata holds upstream information such as OCI annotations. + type: object + path: + description: |- + Path is the relative file path of the Artifact. It can be used to locate + the file in the root of the Artifact storage on the local file system of + the controller managing the Source. + type: string + revision: + description: |- + Revision is a human-readable identifier traceable in the origin source + system. It can be a Git commit SHA, Git tag, a Helm chart version, etc. + type: string + size: + description: Size is the number of bytes in the file. + format: int64 + type: integer + url: + description: |- + URL is the HTTP address of the Artifact as exposed by the controller + managing the Source. It can be used to retrieve the Artifact for + consumption, e.g. by another controller applying the Artifact contents. + type: string + required: + - lastUpdateTime + - path + - revision + - url + type: object + conditions: + description: Conditions holds the conditions for the GitRepository. + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + contentConfigChecksum: + description: |- + ContentConfigChecksum is a checksum of all the configurations related to + the content of the source artifact: + - .spec.ignore + - .spec.recurseSubmodules + - .spec.included and the checksum of the included artifacts + observed in .status.observedGeneration version of the object. This can + be used to determine if the content of the included repository has + changed. + It has the format of `<algo>:<checksum>`, for example: `sha256:<checksum>`. + + Deprecated: Replaced with explicit fields for observed artifact content + config in the status. + type: string + includedArtifacts: + description: |- + IncludedArtifacts contains a list of the last successfully included + Artifacts as instructed by GitRepositorySpec.Include. + items: + description: Artifact represents the output of a Source reconciliation. + properties: + digest: + description: Digest is the digest of the file in the form of + '<algorithm>:<checksum>'. + pattern: ^[a-z0-9]+(?:[.+_-][a-z0-9]+)*:[a-zA-Z0-9=_-]+$ + type: string + lastUpdateTime: + description: |- + LastUpdateTime is the timestamp corresponding to the last update of the + Artifact. + format: date-time + type: string + metadata: + additionalProperties: + type: string + description: Metadata holds upstream information such as OCI + annotations. + type: object + path: + description: |- + Path is the relative file path of the Artifact. It can be used to locate + the file in the root of the Artifact storage on the local file system of + the controller managing the Source. + type: string + revision: + description: |- + Revision is a human-readable identifier traceable in the origin source + system. It can be a Git commit SHA, Git tag, a Helm chart version, etc. + type: string + size: + description: Size is the number of bytes in the file. + format: int64 + type: integer + url: + description: |- + URL is the HTTP address of the Artifact as exposed by the controller + managing the Source. It can be used to retrieve the Artifact for + consumption, e.g. by another controller applying the Artifact contents. + type: string + required: + - lastUpdateTime + - path + - revision + - url + type: object + type: array + lastHandledReconcileAt: + description: |- + LastHandledReconcileAt holds the value of the most recent + reconcile request value, so a change of the annotation value + can be detected. + type: string + observedGeneration: + description: |- + ObservedGeneration is the last observed generation of the GitRepository + object. + format: int64 + type: integer + observedIgnore: + description: |- + ObservedIgnore is the observed exclusion patterns used for constructing + the source artifact. + type: string + observedInclude: + description: |- + ObservedInclude is the observed list of GitRepository resources used to + to produce the current Artifact. + items: + description: |- + GitRepositoryInclude specifies a local reference to a GitRepository which + Artifact (sub-)contents must be included, and where they should be placed. + properties: + fromPath: + description: |- + FromPath specifies the path to copy contents from, defaults to the root + of the Artifact. + type: string + repository: + description: |- + GitRepositoryRef specifies the GitRepository which Artifact contents + must be included. + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + toPath: + description: |- + ToPath specifies the path to copy contents to, defaults to the name of + the GitRepositoryRef. + type: string + required: + - repository + type: object + type: array + observedRecurseSubmodules: + description: |- + ObservedRecurseSubmodules is the observed resource submodules + configuration used to produce the current Artifact. + type: boolean + url: + description: |- + URL is the dynamic fetch link for the latest Artifact. + It is provided on a "best effort" basis, and using the precise + GitRepositoryStatus.Artifact data is recommended. + type: string + type: object + type: object + served: true + storage: false + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.16.1 + labels: + app.kubernetes.io/component: source-controller + app.kubernetes.io/instance: flux-system + app.kubernetes.io/part-of: flux + app.kubernetes.io/version: v2.4.0 + name: helmcharts.source.toolkit.fluxcd.io +spec: + group: source.toolkit.fluxcd.io + names: + kind: HelmChart + listKind: HelmChartList + plural: helmcharts + shortNames: + - hc + singular: helmchart + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .spec.chart + name: Chart + type: string + - jsonPath: .spec.version + name: Version + type: string + - jsonPath: .spec.sourceRef.kind + name: Source Kind + type: string + - jsonPath: .spec.sourceRef.name + name: Source Name + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + - jsonPath: .status.conditions[?(@.type=="Ready")].status + name: Ready + type: string + - jsonPath: .status.conditions[?(@.type=="Ready")].message + name: Status + type: string + name: v1 + schema: + openAPIV3Schema: + description: HelmChart is the Schema for the helmcharts API. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: HelmChartSpec specifies the desired state of a Helm chart. + properties: + chart: + description: |- + Chart is the name or path the Helm chart is available at in the + SourceRef. + type: string + ignoreMissingValuesFiles: + description: |- + IgnoreMissingValuesFiles controls whether to silently ignore missing values + files rather than failing. + type: boolean + interval: + description: |- + Interval at which the HelmChart SourceRef is checked for updates. + This interval is approximate and may be subject to jitter to ensure + efficient use of resources. + pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ + type: string + reconcileStrategy: + default: ChartVersion + description: |- + ReconcileStrategy determines what enables the creation of a new artifact. + Valid values are ('ChartVersion', 'Revision'). + See the documentation of the values for an explanation on their behavior. + Defaults to ChartVersion when omitted. + enum: + - ChartVersion + - Revision + type: string + sourceRef: + description: SourceRef is the reference to the Source the chart is + available at. + properties: + apiVersion: + description: APIVersion of the referent. + type: string + kind: + description: |- + Kind of the referent, valid values are ('HelmRepository', 'GitRepository', + 'Bucket'). + enum: + - HelmRepository + - GitRepository + - Bucket + type: string + name: + description: Name of the referent. + type: string + required: + - kind + - name + type: object + suspend: + description: |- + Suspend tells the controller to suspend the reconciliation of this + source. + type: boolean + valuesFiles: + description: |- + ValuesFiles is an alternative list of values files to use as the chart + values (values.yaml is not included by default), expected to be a + relative path in the SourceRef. + Values files are merged in the order of this list with the last file + overriding the first. Ignored when omitted. + items: + type: string + type: array + verify: + description: |- + Verify contains the secret name containing the trusted public keys + used to verify the signature and specifies which provider to use to check + whether OCI image is authentic. + This field is only supported when using HelmRepository source with spec.type 'oci'. + Chart dependencies, which are not bundled in the umbrella chart artifact, are not verified. + properties: + matchOIDCIdentity: + description: |- + MatchOIDCIdentity specifies the identity matching criteria to use + while verifying an OCI artifact which was signed using Cosign keyless + signing. The artifact's identity is deemed to be verified if any of the + specified matchers match against the identity. + items: + description: |- + OIDCIdentityMatch specifies options for verifying the certificate identity, + i.e. the issuer and the subject of the certificate. + properties: + issuer: + description: |- + Issuer specifies the regex pattern to match against to verify + the OIDC issuer in the Fulcio certificate. The pattern must be a + valid Go regular expression. + type: string + subject: + description: |- + Subject specifies the regex pattern to match against to verify + the identity subject in the Fulcio certificate. The pattern must + be a valid Go regular expression. + type: string + required: + - issuer + - subject + type: object + type: array + provider: + default: cosign + description: Provider specifies the technology used to sign the + OCI Artifact. + enum: + - cosign + - notation + type: string + secretRef: + description: |- + SecretRef specifies the Kubernetes Secret containing the + trusted public keys. + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + required: + - provider + type: object + version: + default: '*' + description: |- + Version is the chart version semver expression, ignored for charts from + GitRepository and Bucket sources. Defaults to latest when omitted. + type: string + required: + - chart + - interval + - sourceRef + type: object + status: + default: + observedGeneration: -1 + description: HelmChartStatus records the observed state of the HelmChart. + properties: + artifact: + description: Artifact represents the output of the last successful + reconciliation. + properties: + digest: + description: Digest is the digest of the file in the form of '<algorithm>:<checksum>'. + pattern: ^[a-z0-9]+(?:[.+_-][a-z0-9]+)*:[a-zA-Z0-9=_-]+$ + type: string + lastUpdateTime: + description: |- + LastUpdateTime is the timestamp corresponding to the last update of the + Artifact. + format: date-time + type: string + metadata: + additionalProperties: + type: string + description: Metadata holds upstream information such as OCI annotations. + type: object + path: + description: |- + Path is the relative file path of the Artifact. It can be used to locate + the file in the root of the Artifact storage on the local file system of + the controller managing the Source. + type: string + revision: + description: |- + Revision is a human-readable identifier traceable in the origin source + system. It can be a Git commit SHA, Git tag, a Helm chart version, etc. + type: string + size: + description: Size is the number of bytes in the file. + format: int64 + type: integer + url: + description: |- + URL is the HTTP address of the Artifact as exposed by the controller + managing the Source. It can be used to retrieve the Artifact for + consumption, e.g. by another controller applying the Artifact contents. + type: string + required: + - lastUpdateTime + - path + - revision + - url + type: object + conditions: + description: Conditions holds the conditions for the HelmChart. + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + lastHandledReconcileAt: + description: |- + LastHandledReconcileAt holds the value of the most recent + reconcile request value, so a change of the annotation value + can be detected. + type: string + observedChartName: + description: |- + ObservedChartName is the last observed chart name as specified by the + resolved chart reference. + type: string + observedGeneration: + description: |- + ObservedGeneration is the last observed generation of the HelmChart + object. + format: int64 + type: integer + observedSourceArtifactRevision: + description: |- + ObservedSourceArtifactRevision is the last observed Artifact.Revision + of the HelmChartSpec.SourceRef. + type: string + observedValuesFiles: + description: |- + ObservedValuesFiles are the observed value files of the last successful + reconciliation. + It matches the chart in the last successfully reconciled artifact. + items: + type: string + type: array + url: + description: |- + URL is the dynamic fetch link for the latest Artifact. + It is provided on a "best effort" basis, and using the precise + BucketStatus.Artifact data is recommended. + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} + - additionalPrinterColumns: + - jsonPath: .spec.chart + name: Chart + type: string + - jsonPath: .spec.version + name: Version + type: string + - jsonPath: .spec.sourceRef.kind + name: Source Kind + type: string + - jsonPath: .spec.sourceRef.name + name: Source Name + type: string + - jsonPath: .status.conditions[?(@.type=="Ready")].status + name: Ready + type: string + - jsonPath: .status.conditions[?(@.type=="Ready")].message + name: Status + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + deprecated: true + deprecationWarning: v1beta1 HelmChart is deprecated, upgrade to v1 + name: v1beta1 + schema: + openAPIV3Schema: + description: HelmChart is the Schema for the helmcharts API + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: HelmChartSpec defines the desired state of a Helm chart. + properties: + accessFrom: + description: AccessFrom defines an Access Control List for allowing + cross-namespace references to this object. + properties: + namespaceSelectors: + description: |- + NamespaceSelectors is the list of namespace selectors to which this ACL applies. + Items in this list are evaluated using a logical OR operation. + items: + description: |- + NamespaceSelector selects the namespaces to which this ACL applies. + An empty map of MatchLabels matches all namespaces in a cluster. + properties: + matchLabels: + additionalProperties: + type: string + description: |- + MatchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + type: array + required: + - namespaceSelectors + type: object + chart: + description: The name or path the Helm chart is available at in the + SourceRef. + type: string + interval: + description: The interval at which to check the Source for updates. + type: string + reconcileStrategy: + default: ChartVersion + description: |- + Determines what enables the creation of a new artifact. Valid values are + ('ChartVersion', 'Revision'). + See the documentation of the values for an explanation on their behavior. + Defaults to ChartVersion when omitted. + enum: + - ChartVersion + - Revision + type: string + sourceRef: + description: The reference to the Source the chart is available at. + properties: + apiVersion: + description: APIVersion of the referent. + type: string + kind: + description: |- + Kind of the referent, valid values are ('HelmRepository', 'GitRepository', + 'Bucket'). + enum: + - HelmRepository + - GitRepository + - Bucket + type: string + name: + description: Name of the referent. + type: string + required: + - kind + - name + type: object + suspend: + description: This flag tells the controller to suspend the reconciliation + of this source. + type: boolean + valuesFile: + description: |- + Alternative values file to use as the default chart values, expected to + be a relative path in the SourceRef. Deprecated in favor of ValuesFiles, + for backwards compatibility the file defined here is merged before the + ValuesFiles items. Ignored when omitted. + type: string + valuesFiles: + description: |- + Alternative list of values files to use as the chart values (values.yaml + is not included by default), expected to be a relative path in the SourceRef. + Values files are merged in the order of this list with the last file overriding + the first. Ignored when omitted. + items: + type: string + type: array + version: + default: '*' + description: |- + The chart version semver expression, ignored for charts from GitRepository + and Bucket sources. Defaults to latest when omitted. + type: string + required: + - chart + - interval + - sourceRef + type: object + status: + default: + observedGeneration: -1 + description: HelmChartStatus defines the observed state of the HelmChart. + properties: + artifact: + description: Artifact represents the output of the last successful + chart sync. + properties: + checksum: + description: Checksum is the SHA256 checksum of the artifact. + type: string + lastUpdateTime: + description: |- + LastUpdateTime is the timestamp corresponding to the last update of this + artifact. + format: date-time + type: string + path: + description: Path is the relative file path of this artifact. + type: string + revision: + description: |- + Revision is a human readable identifier traceable in the origin source + system. It can be a Git commit SHA, Git tag, a Helm index timestamp, a Helm + chart version, etc. + type: string + url: + description: URL is the HTTP address of this artifact. + type: string + required: + - lastUpdateTime + - path + - url + type: object + conditions: + description: Conditions holds the conditions for the HelmChart. + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + lastHandledReconcileAt: + description: |- + LastHandledReconcileAt holds the value of the most recent + reconcile request value, so a change of the annotation value + can be detected. + type: string + observedGeneration: + description: ObservedGeneration is the last observed generation. + format: int64 + type: integer + url: + description: URL is the download link for the last chart pulled. + type: string + type: object + type: object + served: true + storage: false + subresources: + status: {} + - additionalPrinterColumns: + - jsonPath: .spec.chart + name: Chart + type: string + - jsonPath: .spec.version + name: Version + type: string + - jsonPath: .spec.sourceRef.kind + name: Source Kind + type: string + - jsonPath: .spec.sourceRef.name + name: Source Name + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + - jsonPath: .status.conditions[?(@.type=="Ready")].status + name: Ready + type: string + - jsonPath: .status.conditions[?(@.type=="Ready")].message + name: Status + type: string + deprecated: true + deprecationWarning: v1beta2 HelmChart is deprecated, upgrade to v1 + name: v1beta2 + schema: + openAPIV3Schema: + description: HelmChart is the Schema for the helmcharts API. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: HelmChartSpec specifies the desired state of a Helm chart. + properties: + accessFrom: + description: |- + AccessFrom specifies an Access Control List for allowing cross-namespace + references to this object. + NOTE: Not implemented, provisional as of https://github.com/fluxcd/flux2/pull/2092 + properties: + namespaceSelectors: + description: |- + NamespaceSelectors is the list of namespace selectors to which this ACL applies. + Items in this list are evaluated using a logical OR operation. + items: + description: |- + NamespaceSelector selects the namespaces to which this ACL applies. + An empty map of MatchLabels matches all namespaces in a cluster. + properties: + matchLabels: + additionalProperties: + type: string + description: |- + MatchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + type: array + required: + - namespaceSelectors + type: object + chart: + description: |- + Chart is the name or path the Helm chart is available at in the + SourceRef. + type: string + ignoreMissingValuesFiles: + description: |- + IgnoreMissingValuesFiles controls whether to silently ignore missing values + files rather than failing. + type: boolean + interval: + description: |- + Interval at which the HelmChart SourceRef is checked for updates. + This interval is approximate and may be subject to jitter to ensure + efficient use of resources. + pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ + type: string + reconcileStrategy: + default: ChartVersion + description: |- + ReconcileStrategy determines what enables the creation of a new artifact. + Valid values are ('ChartVersion', 'Revision'). + See the documentation of the values for an explanation on their behavior. + Defaults to ChartVersion when omitted. + enum: + - ChartVersion + - Revision + type: string + sourceRef: + description: SourceRef is the reference to the Source the chart is + available at. + properties: + apiVersion: + description: APIVersion of the referent. + type: string + kind: + description: |- + Kind of the referent, valid values are ('HelmRepository', 'GitRepository', + 'Bucket'). + enum: + - HelmRepository + - GitRepository + - Bucket + type: string + name: + description: Name of the referent. + type: string + required: + - kind + - name + type: object + suspend: + description: |- + Suspend tells the controller to suspend the reconciliation of this + source. + type: boolean + valuesFile: + description: |- + ValuesFile is an alternative values file to use as the default chart + values, expected to be a relative path in the SourceRef. Deprecated in + favor of ValuesFiles, for backwards compatibility the file specified here + is merged before the ValuesFiles items. Ignored when omitted. + type: string + valuesFiles: + description: |- + ValuesFiles is an alternative list of values files to use as the chart + values (values.yaml is not included by default), expected to be a + relative path in the SourceRef. + Values files are merged in the order of this list with the last file + overriding the first. Ignored when omitted. + items: + type: string + type: array + verify: + description: |- + Verify contains the secret name containing the trusted public keys + used to verify the signature and specifies which provider to use to check + whether OCI image is authentic. + This field is only supported when using HelmRepository source with spec.type 'oci'. + Chart dependencies, which are not bundled in the umbrella chart artifact, are not verified. + properties: + matchOIDCIdentity: + description: |- + MatchOIDCIdentity specifies the identity matching criteria to use + while verifying an OCI artifact which was signed using Cosign keyless + signing. The artifact's identity is deemed to be verified if any of the + specified matchers match against the identity. + items: + description: |- + OIDCIdentityMatch specifies options for verifying the certificate identity, + i.e. the issuer and the subject of the certificate. + properties: + issuer: + description: |- + Issuer specifies the regex pattern to match against to verify + the OIDC issuer in the Fulcio certificate. The pattern must be a + valid Go regular expression. + type: string + subject: + description: |- + Subject specifies the regex pattern to match against to verify + the identity subject in the Fulcio certificate. The pattern must + be a valid Go regular expression. + type: string + required: + - issuer + - subject + type: object + type: array + provider: + default: cosign + description: Provider specifies the technology used to sign the + OCI Artifact. + enum: + - cosign + - notation + type: string + secretRef: + description: |- + SecretRef specifies the Kubernetes Secret containing the + trusted public keys. + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + required: + - provider + type: object + version: + default: '*' + description: |- + Version is the chart version semver expression, ignored for charts from + GitRepository and Bucket sources. Defaults to latest when omitted. + type: string + required: + - chart + - interval + - sourceRef + type: object + status: + default: + observedGeneration: -1 + description: HelmChartStatus records the observed state of the HelmChart. + properties: + artifact: + description: Artifact represents the output of the last successful + reconciliation. + properties: + digest: + description: Digest is the digest of the file in the form of '<algorithm>:<checksum>'. + pattern: ^[a-z0-9]+(?:[.+_-][a-z0-9]+)*:[a-zA-Z0-9=_-]+$ + type: string + lastUpdateTime: + description: |- + LastUpdateTime is the timestamp corresponding to the last update of the + Artifact. + format: date-time + type: string + metadata: + additionalProperties: + type: string + description: Metadata holds upstream information such as OCI annotations. + type: object + path: + description: |- + Path is the relative file path of the Artifact. It can be used to locate + the file in the root of the Artifact storage on the local file system of + the controller managing the Source. + type: string + revision: + description: |- + Revision is a human-readable identifier traceable in the origin source + system. It can be a Git commit SHA, Git tag, a Helm chart version, etc. + type: string + size: + description: Size is the number of bytes in the file. + format: int64 + type: integer + url: + description: |- + URL is the HTTP address of the Artifact as exposed by the controller + managing the Source. It can be used to retrieve the Artifact for + consumption, e.g. by another controller applying the Artifact contents. + type: string + required: + - lastUpdateTime + - path + - revision + - url + type: object + conditions: + description: Conditions holds the conditions for the HelmChart. + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + lastHandledReconcileAt: + description: |- + LastHandledReconcileAt holds the value of the most recent + reconcile request value, so a change of the annotation value + can be detected. + type: string + observedChartName: + description: |- + ObservedChartName is the last observed chart name as specified by the + resolved chart reference. + type: string + observedGeneration: + description: |- + ObservedGeneration is the last observed generation of the HelmChart + object. + format: int64 + type: integer + observedSourceArtifactRevision: + description: |- + ObservedSourceArtifactRevision is the last observed Artifact.Revision + of the HelmChartSpec.SourceRef. + type: string + observedValuesFiles: + description: |- + ObservedValuesFiles are the observed value files of the last successful + reconciliation. + It matches the chart in the last successfully reconciled artifact. + items: + type: string + type: array + url: + description: |- + URL is the dynamic fetch link for the latest Artifact. + It is provided on a "best effort" basis, and using the precise + BucketStatus.Artifact data is recommended. + type: string + type: object + type: object + served: true + storage: false + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.16.1 + labels: + app.kubernetes.io/component: source-controller + app.kubernetes.io/instance: flux-system + app.kubernetes.io/part-of: flux + app.kubernetes.io/version: v2.4.0 + name: helmrepositories.source.toolkit.fluxcd.io +spec: + group: source.toolkit.fluxcd.io + names: + kind: HelmRepository + listKind: HelmRepositoryList + plural: helmrepositories + shortNames: + - helmrepo + singular: helmrepository + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .spec.url + name: URL + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + - jsonPath: .status.conditions[?(@.type=="Ready")].status + name: Ready + type: string + - jsonPath: .status.conditions[?(@.type=="Ready")].message + name: Status + type: string + name: v1 + schema: + openAPIV3Schema: + description: HelmRepository is the Schema for the helmrepositories API. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: |- + HelmRepositorySpec specifies the required configuration to produce an + Artifact for a Helm repository index YAML. + properties: + accessFrom: + description: |- + AccessFrom specifies an Access Control List for allowing cross-namespace + references to this object. + NOTE: Not implemented, provisional as of https://github.com/fluxcd/flux2/pull/2092 + properties: + namespaceSelectors: + description: |- + NamespaceSelectors is the list of namespace selectors to which this ACL applies. + Items in this list are evaluated using a logical OR operation. + items: + description: |- + NamespaceSelector selects the namespaces to which this ACL applies. + An empty map of MatchLabels matches all namespaces in a cluster. + properties: + matchLabels: + additionalProperties: + type: string + description: |- + MatchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + type: array + required: + - namespaceSelectors + type: object + certSecretRef: + description: |- + CertSecretRef can be given the name of a Secret containing + either or both of + + - a PEM-encoded client certificate (`tls.crt`) and private + key (`tls.key`); + - a PEM-encoded CA certificate (`ca.crt`) + + and whichever are supplied, will be used for connecting to the + registry. The client cert and key are useful if you are + authenticating with a certificate; the CA cert is useful if + you are using a self-signed server certificate. The Secret must + be of type `Opaque` or `kubernetes.io/tls`. + + It takes precedence over the values specified in the Secret referred + to by `.spec.secretRef`. + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + insecure: + description: |- + Insecure allows connecting to a non-TLS HTTP container registry. + This field is only taken into account if the .spec.type field is set to 'oci'. + type: boolean + interval: + description: |- + Interval at which the HelmRepository URL is checked for updates. + This interval is approximate and may be subject to jitter to ensure + efficient use of resources. + pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ + type: string + passCredentials: + description: |- + PassCredentials allows the credentials from the SecretRef to be passed + on to a host that does not match the host as defined in URL. + This may be required if the host of the advertised chart URLs in the + index differ from the defined URL. + Enabling this should be done with caution, as it can potentially result + in credentials getting stolen in a MITM-attack. + type: boolean + provider: + default: generic + description: |- + Provider used for authentication, can be 'aws', 'azure', 'gcp' or 'generic'. + This field is optional, and only taken into account if the .spec.type field is set to 'oci'. + When not specified, defaults to 'generic'. + enum: + - generic + - aws + - azure + - gcp + type: string + secretRef: + description: |- + SecretRef specifies the Secret containing authentication credentials + for the HelmRepository. + For HTTP/S basic auth the secret must contain 'username' and 'password' + fields. + Support for TLS auth using the 'certFile' and 'keyFile', and/or 'caFile' + keys is deprecated. Please use `.spec.certSecretRef` instead. + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + suspend: + description: |- + Suspend tells the controller to suspend the reconciliation of this + HelmRepository. + type: boolean + timeout: + description: |- + Timeout is used for the index fetch operation for an HTTPS helm repository, + and for remote OCI Repository operations like pulling for an OCI helm + chart by the associated HelmChart. + Its default value is 60s. + pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m))+$ + type: string + type: + description: |- + Type of the HelmRepository. + When this field is set to "oci", the URL field value must be prefixed with "oci://". + enum: + - default + - oci + type: string + url: + description: |- + URL of the Helm repository, a valid URL contains at least a protocol and + host. + pattern: ^(http|https|oci)://.*$ + type: string + required: + - url + type: object + status: + default: + observedGeneration: -1 + description: HelmRepositoryStatus records the observed state of the HelmRepository. + properties: + artifact: + description: Artifact represents the last successful HelmRepository + reconciliation. + properties: + digest: + description: Digest is the digest of the file in the form of '<algorithm>:<checksum>'. + pattern: ^[a-z0-9]+(?:[.+_-][a-z0-9]+)*:[a-zA-Z0-9=_-]+$ + type: string + lastUpdateTime: + description: |- + LastUpdateTime is the timestamp corresponding to the last update of the + Artifact. + format: date-time + type: string + metadata: + additionalProperties: + type: string + description: Metadata holds upstream information such as OCI annotations. + type: object + path: + description: |- + Path is the relative file path of the Artifact. It can be used to locate + the file in the root of the Artifact storage on the local file system of + the controller managing the Source. + type: string + revision: + description: |- + Revision is a human-readable identifier traceable in the origin source + system. It can be a Git commit SHA, Git tag, a Helm chart version, etc. + type: string + size: + description: Size is the number of bytes in the file. + format: int64 + type: integer + url: + description: |- + URL is the HTTP address of the Artifact as exposed by the controller + managing the Source. It can be used to retrieve the Artifact for + consumption, e.g. by another controller applying the Artifact contents. + type: string + required: + - lastUpdateTime + - path + - revision + - url + type: object + conditions: + description: Conditions holds the conditions for the HelmRepository. + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + lastHandledReconcileAt: + description: |- + LastHandledReconcileAt holds the value of the most recent + reconcile request value, so a change of the annotation value + can be detected. + type: string + observedGeneration: + description: |- + ObservedGeneration is the last observed generation of the HelmRepository + object. + format: int64 + type: integer + url: + description: |- + URL is the dynamic fetch link for the latest Artifact. + It is provided on a "best effort" basis, and using the precise + HelmRepositoryStatus.Artifact data is recommended. + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} + - additionalPrinterColumns: + - jsonPath: .spec.url + name: URL + type: string + - jsonPath: .status.conditions[?(@.type=="Ready")].status + name: Ready + type: string + - jsonPath: .status.conditions[?(@.type=="Ready")].message + name: Status + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + deprecated: true + deprecationWarning: v1beta1 HelmRepository is deprecated, upgrade to v1 + name: v1beta1 + schema: + openAPIV3Schema: + description: HelmRepository is the Schema for the helmrepositories API + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: HelmRepositorySpec defines the reference to a Helm repository. + properties: + accessFrom: + description: AccessFrom defines an Access Control List for allowing + cross-namespace references to this object. + properties: + namespaceSelectors: + description: |- + NamespaceSelectors is the list of namespace selectors to which this ACL applies. + Items in this list are evaluated using a logical OR operation. + items: + description: |- + NamespaceSelector selects the namespaces to which this ACL applies. + An empty map of MatchLabels matches all namespaces in a cluster. + properties: + matchLabels: + additionalProperties: + type: string + description: |- + MatchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + type: array + required: + - namespaceSelectors + type: object + interval: + description: The interval at which to check the upstream for updates. + type: string + passCredentials: + description: |- + PassCredentials allows the credentials from the SecretRef to be passed on to + a host that does not match the host as defined in URL. + This may be required if the host of the advertised chart URLs in the index + differ from the defined URL. + Enabling this should be done with caution, as it can potentially result in + credentials getting stolen in a MITM-attack. + type: boolean + secretRef: + description: |- + The name of the secret containing authentication credentials for the Helm + repository. + For HTTP/S basic auth the secret must contain username and + password fields. + For TLS the secret must contain a certFile and keyFile, and/or + caFile fields. + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + suspend: + description: This flag tells the controller to suspend the reconciliation + of this source. + type: boolean + timeout: + default: 60s + description: The timeout of index downloading, defaults to 60s. + type: string + url: + description: The Helm repository URL, a valid URL contains at least + a protocol and host. + type: string + required: + - interval + - url + type: object + status: + default: + observedGeneration: -1 + description: HelmRepositoryStatus defines the observed state of the HelmRepository. + properties: + artifact: + description: Artifact represents the output of the last successful + repository sync. + properties: + checksum: + description: Checksum is the SHA256 checksum of the artifact. + type: string + lastUpdateTime: + description: |- + LastUpdateTime is the timestamp corresponding to the last update of this + artifact. + format: date-time + type: string + path: + description: Path is the relative file path of this artifact. + type: string + revision: + description: |- + Revision is a human readable identifier traceable in the origin source + system. It can be a Git commit SHA, Git tag, a Helm index timestamp, a Helm + chart version, etc. + type: string + url: + description: URL is the HTTP address of this artifact. + type: string + required: + - lastUpdateTime + - path + - url + type: object + conditions: + description: Conditions holds the conditions for the HelmRepository. + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + lastHandledReconcileAt: + description: |- + LastHandledReconcileAt holds the value of the most recent + reconcile request value, so a change of the annotation value + can be detected. + type: string + observedGeneration: + description: ObservedGeneration is the last observed generation. + format: int64 + type: integer + url: + description: URL is the download link for the last index fetched. + type: string + type: object + type: object + served: true + storage: false + subresources: + status: {} + - additionalPrinterColumns: + - jsonPath: .spec.url + name: URL + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + - jsonPath: .status.conditions[?(@.type=="Ready")].status + name: Ready + type: string + - jsonPath: .status.conditions[?(@.type=="Ready")].message + name: Status + type: string + deprecated: true + deprecationWarning: v1beta2 HelmRepository is deprecated, upgrade to v1 + name: v1beta2 + schema: + openAPIV3Schema: + description: HelmRepository is the Schema for the helmrepositories API. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: |- + HelmRepositorySpec specifies the required configuration to produce an + Artifact for a Helm repository index YAML. + properties: + accessFrom: + description: |- + AccessFrom specifies an Access Control List for allowing cross-namespace + references to this object. + NOTE: Not implemented, provisional as of https://github.com/fluxcd/flux2/pull/2092 + properties: + namespaceSelectors: + description: |- + NamespaceSelectors is the list of namespace selectors to which this ACL applies. + Items in this list are evaluated using a logical OR operation. + items: + description: |- + NamespaceSelector selects the namespaces to which this ACL applies. + An empty map of MatchLabels matches all namespaces in a cluster. + properties: + matchLabels: + additionalProperties: + type: string + description: |- + MatchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + type: array + required: + - namespaceSelectors + type: object + certSecretRef: + description: |- + CertSecretRef can be given the name of a Secret containing + either or both of + + - a PEM-encoded client certificate (`tls.crt`) and private + key (`tls.key`); + - a PEM-encoded CA certificate (`ca.crt`) + + and whichever are supplied, will be used for connecting to the + registry. The client cert and key are useful if you are + authenticating with a certificate; the CA cert is useful if + you are using a self-signed server certificate. The Secret must + be of type `Opaque` or `kubernetes.io/tls`. + + It takes precedence over the values specified in the Secret referred + to by `.spec.secretRef`. + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + insecure: + description: |- + Insecure allows connecting to a non-TLS HTTP container registry. + This field is only taken into account if the .spec.type field is set to 'oci'. + type: boolean + interval: + description: |- + Interval at which the HelmRepository URL is checked for updates. + This interval is approximate and may be subject to jitter to ensure + efficient use of resources. + pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ + type: string + passCredentials: + description: |- + PassCredentials allows the credentials from the SecretRef to be passed + on to a host that does not match the host as defined in URL. + This may be required if the host of the advertised chart URLs in the + index differ from the defined URL. + Enabling this should be done with caution, as it can potentially result + in credentials getting stolen in a MITM-attack. + type: boolean + provider: + default: generic + description: |- + Provider used for authentication, can be 'aws', 'azure', 'gcp' or 'generic'. + This field is optional, and only taken into account if the .spec.type field is set to 'oci'. + When not specified, defaults to 'generic'. + enum: + - generic + - aws + - azure + - gcp + type: string + secretRef: + description: |- + SecretRef specifies the Secret containing authentication credentials + for the HelmRepository. + For HTTP/S basic auth the secret must contain 'username' and 'password' + fields. + Support for TLS auth using the 'certFile' and 'keyFile', and/or 'caFile' + keys is deprecated. Please use `.spec.certSecretRef` instead. + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + suspend: + description: |- + Suspend tells the controller to suspend the reconciliation of this + HelmRepository. + type: boolean + timeout: + description: |- + Timeout is used for the index fetch operation for an HTTPS helm repository, + and for remote OCI Repository operations like pulling for an OCI helm + chart by the associated HelmChart. + Its default value is 60s. + pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m))+$ + type: string + type: + description: |- + Type of the HelmRepository. + When this field is set to "oci", the URL field value must be prefixed with "oci://". + enum: + - default + - oci + type: string + url: + description: |- + URL of the Helm repository, a valid URL contains at least a protocol and + host. + pattern: ^(http|https|oci)://.*$ + type: string + required: + - url + type: object + status: + default: + observedGeneration: -1 + description: HelmRepositoryStatus records the observed state of the HelmRepository. + properties: + artifact: + description: Artifact represents the last successful HelmRepository + reconciliation. + properties: + digest: + description: Digest is the digest of the file in the form of '<algorithm>:<checksum>'. + pattern: ^[a-z0-9]+(?:[.+_-][a-z0-9]+)*:[a-zA-Z0-9=_-]+$ + type: string + lastUpdateTime: + description: |- + LastUpdateTime is the timestamp corresponding to the last update of the + Artifact. + format: date-time + type: string + metadata: + additionalProperties: + type: string + description: Metadata holds upstream information such as OCI annotations. + type: object + path: + description: |- + Path is the relative file path of the Artifact. It can be used to locate + the file in the root of the Artifact storage on the local file system of + the controller managing the Source. + type: string + revision: + description: |- + Revision is a human-readable identifier traceable in the origin source + system. It can be a Git commit SHA, Git tag, a Helm chart version, etc. + type: string + size: + description: Size is the number of bytes in the file. + format: int64 + type: integer + url: + description: |- + URL is the HTTP address of the Artifact as exposed by the controller + managing the Source. It can be used to retrieve the Artifact for + consumption, e.g. by another controller applying the Artifact contents. + type: string + required: + - lastUpdateTime + - path + - revision + - url + type: object + conditions: + description: Conditions holds the conditions for the HelmRepository. + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + lastHandledReconcileAt: + description: |- + LastHandledReconcileAt holds the value of the most recent + reconcile request value, so a change of the annotation value + can be detected. + type: string + observedGeneration: + description: |- + ObservedGeneration is the last observed generation of the HelmRepository + object. + format: int64 + type: integer + url: + description: |- + URL is the dynamic fetch link for the latest Artifact. + It is provided on a "best effort" basis, and using the precise + HelmRepositoryStatus.Artifact data is recommended. + type: string + type: object + type: object + served: true + storage: false + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.16.1 + labels: + app.kubernetes.io/component: source-controller + app.kubernetes.io/instance: flux-system + app.kubernetes.io/part-of: flux + app.kubernetes.io/version: v2.4.0 + name: ocirepositories.source.toolkit.fluxcd.io +spec: + group: source.toolkit.fluxcd.io + names: + kind: OCIRepository + listKind: OCIRepositoryList + plural: ocirepositories + shortNames: + - ocirepo + singular: ocirepository + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .spec.url + name: URL + type: string + - jsonPath: .status.conditions[?(@.type=="Ready")].status + name: Ready + type: string + - jsonPath: .status.conditions[?(@.type=="Ready")].message + name: Status + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1beta2 + schema: + openAPIV3Schema: + description: OCIRepository is the Schema for the ocirepositories API + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: OCIRepositorySpec defines the desired state of OCIRepository + properties: + certSecretRef: + description: |- + CertSecretRef can be given the name of a Secret containing + either or both of + + - a PEM-encoded client certificate (`tls.crt`) and private + key (`tls.key`); + - a PEM-encoded CA certificate (`ca.crt`) + + and whichever are supplied, will be used for connecting to the + registry. The client cert and key are useful if you are + authenticating with a certificate; the CA cert is useful if + you are using a self-signed server certificate. The Secret must + be of type `Opaque` or `kubernetes.io/tls`. + + Note: Support for the `caFile`, `certFile` and `keyFile` keys have + been deprecated. + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + ignore: + description: |- + Ignore overrides the set of excluded patterns in the .sourceignore format + (which is the same as .gitignore). If not provided, a default will be used, + consult the documentation for your version to find out what those are. + type: string + insecure: + description: Insecure allows connecting to a non-TLS HTTP container + registry. + type: boolean + interval: + description: |- + Interval at which the OCIRepository URL is checked for updates. + This interval is approximate and may be subject to jitter to ensure + efficient use of resources. + pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ + type: string + layerSelector: + description: |- + LayerSelector specifies which layer should be extracted from the OCI artifact. + When not specified, the first layer found in the artifact is selected. + properties: + mediaType: + description: |- + MediaType specifies the OCI media type of the layer + which should be extracted from the OCI Artifact. The + first layer matching this type is selected. + type: string + operation: + description: |- + Operation specifies how the selected layer should be processed. + By default, the layer compressed content is extracted to storage. + When the operation is set to 'copy', the layer compressed content + is persisted to storage as it is. + enum: + - extract + - copy + type: string + type: object + provider: + default: generic + description: |- + The provider used for authentication, can be 'aws', 'azure', 'gcp' or 'generic'. + When not specified, defaults to 'generic'. + enum: + - generic + - aws + - azure + - gcp + type: string + proxySecretRef: + description: |- + ProxySecretRef specifies the Secret containing the proxy configuration + to use while communicating with the container registry. + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + ref: + description: |- + The OCI reference to pull and monitor for changes, + defaults to the latest tag. + properties: + digest: + description: |- + Digest is the image digest to pull, takes precedence over SemVer. + The value should be in the format 'sha256:<HASH>'. + type: string + semver: + description: |- + SemVer is the range of tags to pull selecting the latest within + the range, takes precedence over Tag. + type: string + semverFilter: + description: SemverFilter is a regex pattern to filter the tags + within the SemVer range. + type: string + tag: + description: Tag is the image tag to pull, defaults to latest. + type: string + type: object + secretRef: + description: |- + SecretRef contains the secret name containing the registry login + credentials to resolve image metadata. + The secret must be of type kubernetes.io/dockerconfigjson. + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + serviceAccountName: + description: |- + ServiceAccountName is the name of the Kubernetes ServiceAccount used to authenticate + the image pull if the service account has attached pull secrets. For more information: + https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/#add-imagepullsecrets-to-a-service-account + type: string + suspend: + description: This flag tells the controller to suspend the reconciliation + of this source. + type: boolean + timeout: + default: 60s + description: The timeout for remote OCI Repository operations like + pulling, defaults to 60s. + pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m))+$ + type: string + url: + description: |- + URL is a reference to an OCI artifact repository hosted + on a remote container registry. + pattern: ^oci://.*$ + type: string + verify: + description: |- + Verify contains the secret name containing the trusted public keys + used to verify the signature and specifies which provider to use to check + whether OCI image is authentic. + properties: + matchOIDCIdentity: + description: |- + MatchOIDCIdentity specifies the identity matching criteria to use + while verifying an OCI artifact which was signed using Cosign keyless + signing. The artifact's identity is deemed to be verified if any of the + specified matchers match against the identity. + items: + description: |- + OIDCIdentityMatch specifies options for verifying the certificate identity, + i.e. the issuer and the subject of the certificate. + properties: + issuer: + description: |- + Issuer specifies the regex pattern to match against to verify + the OIDC issuer in the Fulcio certificate. The pattern must be a + valid Go regular expression. + type: string + subject: + description: |- + Subject specifies the regex pattern to match against to verify + the identity subject in the Fulcio certificate. The pattern must + be a valid Go regular expression. + type: string + required: + - issuer + - subject + type: object + type: array + provider: + default: cosign + description: Provider specifies the technology used to sign the + OCI Artifact. + enum: + - cosign + - notation + type: string + secretRef: + description: |- + SecretRef specifies the Kubernetes Secret containing the + trusted public keys. + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + required: + - provider + type: object + required: + - interval + - url + type: object + status: + default: + observedGeneration: -1 + description: OCIRepositoryStatus defines the observed state of OCIRepository + properties: + artifact: + description: Artifact represents the output of the last successful + OCI Repository sync. + properties: + digest: + description: Digest is the digest of the file in the form of '<algorithm>:<checksum>'. + pattern: ^[a-z0-9]+(?:[.+_-][a-z0-9]+)*:[a-zA-Z0-9=_-]+$ + type: string + lastUpdateTime: + description: |- + LastUpdateTime is the timestamp corresponding to the last update of the + Artifact. + format: date-time + type: string + metadata: + additionalProperties: + type: string + description: Metadata holds upstream information such as OCI annotations. + type: object + path: + description: |- + Path is the relative file path of the Artifact. It can be used to locate + the file in the root of the Artifact storage on the local file system of + the controller managing the Source. + type: string + revision: + description: |- + Revision is a human-readable identifier traceable in the origin source + system. It can be a Git commit SHA, Git tag, a Helm chart version, etc. + type: string + size: + description: Size is the number of bytes in the file. + format: int64 + type: integer + url: + description: |- + URL is the HTTP address of the Artifact as exposed by the controller + managing the Source. It can be used to retrieve the Artifact for + consumption, e.g. by another controller applying the Artifact contents. + type: string + required: + - lastUpdateTime + - path + - revision + - url + type: object + conditions: + description: Conditions holds the conditions for the OCIRepository. + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + contentConfigChecksum: + description: |- + ContentConfigChecksum is a checksum of all the configurations related to + the content of the source artifact: + - .spec.ignore + - .spec.layerSelector + observed in .status.observedGeneration version of the object. This can + be used to determine if the content configuration has changed and the + artifact needs to be rebuilt. + It has the format of `<algo>:<checksum>`, for example: `sha256:<checksum>`. + + Deprecated: Replaced with explicit fields for observed artifact content + config in the status. + type: string + lastHandledReconcileAt: + description: |- + LastHandledReconcileAt holds the value of the most recent + reconcile request value, so a change of the annotation value + can be detected. + type: string + observedGeneration: + description: ObservedGeneration is the last observed generation. + format: int64 + type: integer + observedIgnore: + description: |- + ObservedIgnore is the observed exclusion patterns used for constructing + the source artifact. + type: string + observedLayerSelector: + description: |- + ObservedLayerSelector is the observed layer selector used for constructing + the source artifact. + properties: + mediaType: + description: |- + MediaType specifies the OCI media type of the layer + which should be extracted from the OCI Artifact. The + first layer matching this type is selected. + type: string + operation: + description: |- + Operation specifies how the selected layer should be processed. + By default, the layer compressed content is extracted to storage. + When the operation is set to 'copy', the layer compressed content + is persisted to storage as it is. + enum: + - extract + - copy + type: string + type: object + url: + description: URL is the download link for the artifact output of the + last OCI Repository sync. + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app.kubernetes.io/component: source-controller + app.kubernetes.io/instance: flux-system + app.kubernetes.io/part-of: flux + app.kubernetes.io/version: v2.4.0 + name: source-controller + namespace: flux-system +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/component: source-controller + app.kubernetes.io/instance: flux-system + app.kubernetes.io/part-of: flux + app.kubernetes.io/version: v2.4.0 + control-plane: controller + name: source-controller + namespace: flux-system +spec: + ports: + - name: http + port: 80 + protocol: TCP + targetPort: http + selector: + app: source-controller + type: ClusterIP +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app.kubernetes.io/component: source-controller + app.kubernetes.io/instance: flux-system + app.kubernetes.io/part-of: flux + app.kubernetes.io/version: v2.4.0 + control-plane: controller + name: source-controller + namespace: flux-system +spec: + replicas: 1 + selector: + matchLabels: + app: source-controller + strategy: + type: Recreate + template: + metadata: + annotations: + prometheus.io/port: "8080" + prometheus.io/scrape: "true" + labels: + app: source-controller + spec: + containers: + - args: + - --events-addr=http://notification-controller.flux-system.svc.cluster.local./ + - --watch-all-namespaces=true + - --log-level=info + - --log-encoding=json + - --enable-leader-election + - --storage-path=/data + - --storage-adv-addr=source-controller.$(RUNTIME_NAMESPACE).svc.cluster.local. + env: + - name: RUNTIME_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: TUF_ROOT + value: /tmp/.sigstore + - name: GOMAXPROCS + valueFrom: + resourceFieldRef: + containerName: manager + resource: limits.cpu + - name: GOMEMLIMIT + valueFrom: + resourceFieldRef: + containerName: manager + resource: limits.memory + image: ghcr.io/fluxcd/source-controller:v1.4.1 + imagePullPolicy: IfNotPresent + livenessProbe: + httpGet: + path: /healthz + port: healthz + name: manager + ports: + - containerPort: 9090 + name: http + protocol: TCP + - containerPort: 8080 + name: http-prom + protocol: TCP + - containerPort: 9440 + name: healthz + protocol: TCP + readinessProbe: + httpGet: + path: / + port: http + resources: + limits: + cpu: 1000m + memory: 1Gi + requests: + cpu: 50m + memory: 64Mi + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + volumeMounts: + - mountPath: /data + name: data + - mountPath: /tmp + name: tmp + nodeSelector: + kubernetes.io/os: linux + priorityClassName: system-cluster-critical + securityContext: + fsGroup: 1337 + serviceAccountName: source-controller + terminationGracePeriodSeconds: 10 + volumes: + - emptyDir: {} + name: data + - emptyDir: {} + name: tmp +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.16.1 + labels: + app.kubernetes.io/component: kustomize-controller + app.kubernetes.io/instance: flux-system + app.kubernetes.io/part-of: flux + app.kubernetes.io/version: v2.4.0 + name: kustomizations.kustomize.toolkit.fluxcd.io +spec: + group: kustomize.toolkit.fluxcd.io + names: + kind: Kustomization + listKind: KustomizationList + plural: kustomizations + shortNames: + - ks + singular: kustomization + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + - jsonPath: .status.conditions[?(@.type=="Ready")].status + name: Ready + type: string + - jsonPath: .status.conditions[?(@.type=="Ready")].message + name: Status + type: string + name: v1 + schema: + openAPIV3Schema: + description: Kustomization is the Schema for the kustomizations API. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: |- + KustomizationSpec defines the configuration to calculate the desired state + from a Source using Kustomize. + properties: + commonMetadata: + description: |- + CommonMetadata specifies the common labels and annotations that are + applied to all resources. Any existing label or annotation will be + overridden if its key matches a common one. + properties: + annotations: + additionalProperties: + type: string + description: Annotations to be added to the object's metadata. + type: object + labels: + additionalProperties: + type: string + description: Labels to be added to the object's metadata. + type: object + type: object + components: + description: Components specifies relative paths to specifications + of other Components. + items: + type: string + type: array + decryption: + description: Decrypt Kubernetes secrets before applying them on the + cluster. + properties: + provider: + description: Provider is the name of the decryption engine. + enum: + - sops + type: string + secretRef: + description: The secret name containing the private OpenPGP keys + used for decryption. + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + required: + - provider + type: object + dependsOn: + description: |- + DependsOn may contain a meta.NamespacedObjectReference slice + with references to Kustomization resources that must be ready before this + Kustomization can be reconciled. + items: + description: |- + NamespacedObjectReference contains enough information to locate the referenced Kubernetes resource object in any + namespace. + properties: + name: + description: Name of the referent. + type: string + namespace: + description: Namespace of the referent, when not specified it + acts as LocalObjectReference. + type: string + required: + - name + type: object + type: array + force: + default: false + description: |- + Force instructs the controller to recreate resources + when patching fails due to an immutable field change. + type: boolean + healthChecks: + description: A list of resources to be included in the health assessment. + items: + description: |- + NamespacedObjectKindReference contains enough information to locate the typed referenced Kubernetes resource object + in any namespace. + properties: + apiVersion: + description: API version of the referent, if not specified the + Kubernetes preferred version will be used. + type: string + kind: + description: Kind of the referent. + type: string + name: + description: Name of the referent. + type: string + namespace: + description: Namespace of the referent, when not specified it + acts as LocalObjectReference. + type: string + required: + - kind + - name + type: object + type: array + images: + description: |- + Images is a list of (image name, new name, new tag or digest) + for changing image names, tags or digests. This can also be achieved with a + patch, but this operator is simpler to specify. + items: + description: Image contains an image name, a new name, a new tag + or digest, which will replace the original name and tag. + properties: + digest: + description: |- + Digest is the value used to replace the original image tag. + If digest is present NewTag value is ignored. + type: string + name: + description: Name is a tag-less image name. + type: string + newName: + description: NewName is the value used to replace the original + name. + type: string + newTag: + description: NewTag is the value used to replace the original + tag. + type: string + required: + - name + type: object + type: array + interval: + description: |- + The interval at which to reconcile the Kustomization. + This interval is approximate and may be subject to jitter to ensure + efficient use of resources. + pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ + type: string + kubeConfig: + description: |- + The KubeConfig for reconciling the Kustomization on a remote cluster. + When used in combination with KustomizationSpec.ServiceAccountName, + forces the controller to act on behalf of that Service Account at the + target cluster. + If the --default-service-account flag is set, its value will be used as + a controller level fallback for when KustomizationSpec.ServiceAccountName + is empty. + properties: + secretRef: + description: |- + SecretRef holds the name of a secret that contains a key with + the kubeconfig file as the value. If no key is set, the key will default + to 'value'. + It is recommended that the kubeconfig is self-contained, and the secret + is regularly updated if credentials such as a cloud-access-token expire. + Cloud specific `cmd-path` auth helpers will not function without adding + binaries and credentials to the Pod that is responsible for reconciling + Kubernetes resources. + properties: + key: + description: Key in the Secret, when not specified an implementation-specific + default key is used. + type: string + name: + description: Name of the Secret. + type: string + required: + - name + type: object + required: + - secretRef + type: object + namePrefix: + description: NamePrefix will prefix the names of all managed resources. + maxLength: 200 + minLength: 1 + type: string + nameSuffix: + description: NameSuffix will suffix the names of all managed resources. + maxLength: 200 + minLength: 1 + type: string + patches: + description: |- + Strategic merge and JSON patches, defined as inline YAML objects, + capable of targeting objects based on kind, label and annotation selectors. + items: + description: |- + Patch contains an inline StrategicMerge or JSON6902 patch, and the target the patch should + be applied to. + properties: + patch: + description: |- + Patch contains an inline StrategicMerge patch or an inline JSON6902 patch with + an array of operation objects. + type: string + target: + description: Target points to the resources that the patch document + should be applied to. + properties: + annotationSelector: + description: |- + AnnotationSelector is a string that follows the label selection expression + https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#api + It matches with the resource annotations. + type: string + group: + description: |- + Group is the API group to select resources from. + Together with Version and Kind it is capable of unambiguously identifying and/or selecting resources. + https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md + type: string + kind: + description: |- + Kind of the API Group to select resources from. + Together with Group and Version it is capable of unambiguously + identifying and/or selecting resources. + https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md + type: string + labelSelector: + description: |- + LabelSelector is a string that follows the label selection expression + https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#api + It matches with the resource labels. + type: string + name: + description: Name to match resources with. + type: string + namespace: + description: Namespace to select resources from. + type: string + version: + description: |- + Version of the API Group to select resources from. + Together with Group and Kind it is capable of unambiguously identifying and/or selecting resources. + https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md + type: string + type: object + required: + - patch + type: object + type: array + path: + description: |- + Path to the directory containing the kustomization.yaml file, or the + set of plain YAMLs a kustomization.yaml should be generated for. + Defaults to 'None', which translates to the root path of the SourceRef. + type: string + postBuild: + description: |- + PostBuild describes which actions to perform on the YAML manifest + generated by building the kustomize overlay. + properties: + substitute: + additionalProperties: + type: string + description: |- + Substitute holds a map of key/value pairs. + The variables defined in your YAML manifests that match any of the keys + defined in the map will be substituted with the set value. + Includes support for bash string replacement functions + e.g. ${var:=default}, ${var:position} and ${var/substring/replacement}. + type: object + substituteFrom: + description: |- + SubstituteFrom holds references to ConfigMaps and Secrets containing + the variables and their values to be substituted in the YAML manifests. + The ConfigMap and the Secret data keys represent the var names, and they + must match the vars declared in the manifests for the substitution to + happen. + items: + description: |- + SubstituteReference contains a reference to a resource containing + the variables name and value. + properties: + kind: + description: Kind of the values referent, valid values are + ('Secret', 'ConfigMap'). + enum: + - Secret + - ConfigMap + type: string + name: + description: |- + Name of the values referent. Should reside in the same namespace as the + referring resource. + maxLength: 253 + minLength: 1 + type: string + optional: + default: false + description: |- + Optional indicates whether the referenced resource must exist, or whether to + tolerate its absence. If true and the referenced resource is absent, proceed + as if the resource was present but empty, without any variables defined. + type: boolean + required: + - kind + - name + type: object + type: array + type: object + prune: + description: Prune enables garbage collection. + type: boolean + retryInterval: + description: |- + The interval at which to retry a previously failed reconciliation. + When not specified, the controller uses the KustomizationSpec.Interval + value to retry failures. + pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ + type: string + serviceAccountName: + description: |- + The name of the Kubernetes service account to impersonate + when reconciling this Kustomization. + type: string + sourceRef: + description: Reference of the source where the kustomization file + is. + properties: + apiVersion: + description: API version of the referent. + type: string + kind: + description: Kind of the referent. + enum: + - OCIRepository + - GitRepository + - Bucket + type: string + name: + description: Name of the referent. + type: string + namespace: + description: |- + Namespace of the referent, defaults to the namespace of the Kubernetes + resource object that contains the reference. + type: string + required: + - kind + - name + type: object + suspend: + description: |- + This flag tells the controller to suspend subsequent kustomize executions, + it does not apply to already started executions. Defaults to false. + type: boolean + targetNamespace: + description: |- + TargetNamespace sets or overrides the namespace in the + kustomization.yaml file. + maxLength: 63 + minLength: 1 + type: string + timeout: + description: |- + Timeout for validation, apply and health checking operations. + Defaults to 'Interval' duration. + pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ + type: string + wait: + description: |- + Wait instructs the controller to check the health of all the reconciled + resources. When enabled, the HealthChecks are ignored. Defaults to false. + type: boolean + required: + - interval + - prune + - sourceRef + type: object + status: + default: + observedGeneration: -1 + description: KustomizationStatus defines the observed state of a kustomization. + properties: + conditions: + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + inventory: + description: |- + Inventory contains the list of Kubernetes resource object references that + have been successfully applied. + properties: + entries: + description: Entries of Kubernetes resource object references. + items: + description: ResourceRef contains the information necessary + to locate a resource within a cluster. + properties: + id: + description: |- + ID is the string representation of the Kubernetes resource object's metadata, + in the format '<namespace>_<name>_<group>_<kind>'. + type: string + v: + description: Version is the API version of the Kubernetes + resource object's kind. + type: string + required: + - id + - v + type: object + type: array + required: + - entries + type: object + lastAppliedRevision: + description: |- + The last successfully applied revision. + Equals the Revision of the applied Artifact from the referenced Source. + type: string + lastAttemptedRevision: + description: LastAttemptedRevision is the revision of the last reconciliation + attempt. + type: string + lastHandledReconcileAt: + description: |- + LastHandledReconcileAt holds the value of the most recent + reconcile request value, so a change of the annotation value + can be detected. + type: string + observedGeneration: + description: ObservedGeneration is the last reconciled generation. + format: int64 + type: integer + type: object + type: object + served: true + storage: true + subresources: + status: {} + - additionalPrinterColumns: + - jsonPath: .status.conditions[?(@.type=="Ready")].status + name: Ready + type: string + - jsonPath: .status.conditions[?(@.type=="Ready")].message + name: Status + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + deprecated: true + deprecationWarning: v1beta1 Kustomization is deprecated, upgrade to v1 + name: v1beta1 + schema: + openAPIV3Schema: + description: Kustomization is the Schema for the kustomizations API. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: KustomizationSpec defines the desired state of a kustomization. + properties: + decryption: + description: Decrypt Kubernetes secrets before applying them on the + cluster. + properties: + provider: + description: Provider is the name of the decryption engine. + enum: + - sops + type: string + secretRef: + description: The secret name containing the private OpenPGP keys + used for decryption. + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + required: + - provider + type: object + dependsOn: + description: |- + DependsOn may contain a meta.NamespacedObjectReference slice + with references to Kustomization resources that must be ready before this + Kustomization can be reconciled. + items: + description: |- + NamespacedObjectReference contains enough information to locate the referenced Kubernetes resource object in any + namespace. + properties: + name: + description: Name of the referent. + type: string + namespace: + description: Namespace of the referent, when not specified it + acts as LocalObjectReference. + type: string + required: + - name + type: object + type: array + force: + default: false + description: |- + Force instructs the controller to recreate resources + when patching fails due to an immutable field change. + type: boolean + healthChecks: + description: A list of resources to be included in the health assessment. + items: + description: |- + NamespacedObjectKindReference contains enough information to locate the typed referenced Kubernetes resource object + in any namespace. + properties: + apiVersion: + description: API version of the referent, if not specified the + Kubernetes preferred version will be used. + type: string + kind: + description: Kind of the referent. + type: string + name: + description: Name of the referent. + type: string + namespace: + description: Namespace of the referent, when not specified it + acts as LocalObjectReference. + type: string + required: + - kind + - name + type: object + type: array + images: + description: |- + Images is a list of (image name, new name, new tag or digest) + for changing image names, tags or digests. This can also be achieved with a + patch, but this operator is simpler to specify. + items: + description: Image contains an image name, a new name, a new tag + or digest, which will replace the original name and tag. + properties: + digest: + description: |- + Digest is the value used to replace the original image tag. + If digest is present NewTag value is ignored. + type: string + name: + description: Name is a tag-less image name. + type: string + newName: + description: NewName is the value used to replace the original + name. + type: string + newTag: + description: NewTag is the value used to replace the original + tag. + type: string + required: + - name + type: object + type: array + interval: + description: The interval at which to reconcile the Kustomization. + type: string + kubeConfig: + description: |- + The KubeConfig for reconciling the Kustomization on a remote cluster. + When specified, KubeConfig takes precedence over ServiceAccountName. + properties: + secretRef: + description: |- + SecretRef holds the name to a secret that contains a 'value' key with + the kubeconfig file as the value. It must be in the same namespace as + the Kustomization. + It is recommended that the kubeconfig is self-contained, and the secret + is regularly updated if credentials such as a cloud-access-token expire. + Cloud specific `cmd-path` auth helpers will not function without adding + binaries and credentials to the Pod that is responsible for reconciling + the Kustomization. + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + required: + - secretRef + type: object + patches: + description: |- + Strategic merge and JSON patches, defined as inline YAML objects, + capable of targeting objects based on kind, label and annotation selectors. + items: + description: |- + Patch contains an inline StrategicMerge or JSON6902 patch, and the target the patch should + be applied to. + properties: + patch: + description: |- + Patch contains an inline StrategicMerge patch or an inline JSON6902 patch with + an array of operation objects. + type: string + target: + description: Target points to the resources that the patch document + should be applied to. + properties: + annotationSelector: + description: |- + AnnotationSelector is a string that follows the label selection expression + https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#api + It matches with the resource annotations. + type: string + group: + description: |- + Group is the API group to select resources from. + Together with Version and Kind it is capable of unambiguously identifying and/or selecting resources. + https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md + type: string + kind: + description: |- + Kind of the API Group to select resources from. + Together with Group and Version it is capable of unambiguously + identifying and/or selecting resources. + https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md + type: string + labelSelector: + description: |- + LabelSelector is a string that follows the label selection expression + https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#api + It matches with the resource labels. + type: string + name: + description: Name to match resources with. + type: string + namespace: + description: Namespace to select resources from. + type: string + version: + description: |- + Version of the API Group to select resources from. + Together with Group and Kind it is capable of unambiguously identifying and/or selecting resources. + https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md + type: string + type: object + required: + - patch + type: object + type: array + patchesJson6902: + description: JSON 6902 patches, defined as inline YAML objects. + items: + description: JSON6902Patch contains a JSON6902 patch and the target + the patch should be applied to. + properties: + patch: + description: Patch contains the JSON6902 patch document with + an array of operation objects. + items: + description: |- + JSON6902 is a JSON6902 operation object. + https://datatracker.ietf.org/doc/html/rfc6902#section-4 + properties: + from: + description: |- + From contains a JSON-pointer value that references a location within the target document where the operation is + performed. The meaning of the value depends on the value of Op, and is NOT taken into account by all operations. + type: string + op: + description: |- + Op indicates the operation to perform. Its value MUST be one of "add", "remove", "replace", "move", "copy", or + "test". + https://datatracker.ietf.org/doc/html/rfc6902#section-4 + enum: + - test + - remove + - add + - replace + - move + - copy + type: string + path: + description: |- + Path contains the JSON-pointer value that references a location within the target document where the operation + is performed. The meaning of the value depends on the value of Op. + type: string + value: + description: |- + Value contains a valid JSON structure. The meaning of the value depends on the value of Op, and is NOT taken into + account by all operations. + x-kubernetes-preserve-unknown-fields: true + required: + - op + - path + type: object + type: array + target: + description: Target points to the resources that the patch document + should be applied to. + properties: + annotationSelector: + description: |- + AnnotationSelector is a string that follows the label selection expression + https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#api + It matches with the resource annotations. + type: string + group: + description: |- + Group is the API group to select resources from. + Together with Version and Kind it is capable of unambiguously identifying and/or selecting resources. + https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md + type: string + kind: + description: |- + Kind of the API Group to select resources from. + Together with Group and Version it is capable of unambiguously + identifying and/or selecting resources. + https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md + type: string + labelSelector: + description: |- + LabelSelector is a string that follows the label selection expression + https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#api + It matches with the resource labels. + type: string + name: + description: Name to match resources with. + type: string + namespace: + description: Namespace to select resources from. + type: string + version: + description: |- + Version of the API Group to select resources from. + Together with Group and Kind it is capable of unambiguously identifying and/or selecting resources. + https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md + type: string + type: object + required: + - patch + - target + type: object + type: array + patchesStrategicMerge: + description: Strategic merge patches, defined as inline YAML objects. + items: + x-kubernetes-preserve-unknown-fields: true + type: array + path: + description: |- + Path to the directory containing the kustomization.yaml file, or the + set of plain YAMLs a kustomization.yaml should be generated for. + Defaults to 'None', which translates to the root path of the SourceRef. + type: string + postBuild: + description: |- + PostBuild describes which actions to perform on the YAML manifest + generated by building the kustomize overlay. + properties: + substitute: + additionalProperties: + type: string + description: |- + Substitute holds a map of key/value pairs. + The variables defined in your YAML manifests + that match any of the keys defined in the map + will be substituted with the set value. + Includes support for bash string replacement functions + e.g. ${var:=default}, ${var:position} and ${var/substring/replacement}. + type: object + substituteFrom: + description: |- + SubstituteFrom holds references to ConfigMaps and Secrets containing + the variables and their values to be substituted in the YAML manifests. + The ConfigMap and the Secret data keys represent the var names and they + must match the vars declared in the manifests for the substitution to happen. + items: + description: |- + SubstituteReference contains a reference to a resource containing + the variables name and value. + properties: + kind: + description: Kind of the values referent, valid values are + ('Secret', 'ConfigMap'). + enum: + - Secret + - ConfigMap + type: string + name: + description: |- + Name of the values referent. Should reside in the same namespace as the + referring resource. + maxLength: 253 + minLength: 1 + type: string + required: + - kind + - name + type: object + type: array + type: object + prune: + description: Prune enables garbage collection. + type: boolean + retryInterval: + description: |- + The interval at which to retry a previously failed reconciliation. + When not specified, the controller uses the KustomizationSpec.Interval + value to retry failures. + type: string + serviceAccountName: + description: |- + The name of the Kubernetes service account to impersonate + when reconciling this Kustomization. + type: string + sourceRef: + description: Reference of the source where the kustomization file + is. + properties: + apiVersion: + description: API version of the referent + type: string + kind: + description: Kind of the referent + enum: + - GitRepository + - Bucket + type: string + name: + description: Name of the referent + type: string + namespace: + description: Namespace of the referent, defaults to the Kustomization + namespace + type: string + required: + - kind + - name + type: object + suspend: + description: |- + This flag tells the controller to suspend subsequent kustomize executions, + it does not apply to already started executions. Defaults to false. + type: boolean + targetNamespace: + description: |- + TargetNamespace sets or overrides the namespace in the + kustomization.yaml file. + maxLength: 63 + minLength: 1 + type: string + timeout: + description: |- + Timeout for validation, apply and health checking operations. + Defaults to 'Interval' duration. + type: string + validation: + description: |- + Validate the Kubernetes objects before applying them on the cluster. + The validation strategy can be 'client' (local dry-run), 'server' + (APIServer dry-run) or 'none'. + When 'Force' is 'true', validation will fallback to 'client' if set to + 'server' because server-side validation is not supported in this scenario. + enum: + - none + - client + - server + type: string + required: + - interval + - prune + - sourceRef + type: object + status: + default: + observedGeneration: -1 + description: KustomizationStatus defines the observed state of a kustomization. + properties: + conditions: + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + lastAppliedRevision: + description: |- + The last successfully applied revision. + The revision format for Git sources is <branch|tag>/<commit-sha>. + type: string + lastAttemptedRevision: + description: LastAttemptedRevision is the revision of the last reconciliation + attempt. + type: string + lastHandledReconcileAt: + description: |- + LastHandledReconcileAt holds the value of the most recent + reconcile request value, so a change of the annotation value + can be detected. + type: string + observedGeneration: + description: ObservedGeneration is the last reconciled generation. + format: int64 + type: integer + snapshot: + description: The last successfully applied revision metadata. + properties: + checksum: + description: The manifests sha1 checksum. + type: string + entries: + description: A list of Kubernetes kinds grouped by namespace. + items: + description: |- + Snapshot holds the metadata of namespaced + Kubernetes objects + properties: + kinds: + additionalProperties: + type: string + description: The list of Kubernetes kinds. + type: object + namespace: + description: The namespace of this entry. + type: string + required: + - kinds + type: object + type: array + required: + - checksum + - entries + type: object + type: object + type: object + served: true + storage: false + subresources: + status: {} + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + - jsonPath: .status.conditions[?(@.type=="Ready")].status + name: Ready + type: string + - jsonPath: .status.conditions[?(@.type=="Ready")].message + name: Status + type: string + deprecated: true + deprecationWarning: v1beta2 Kustomization is deprecated, upgrade to v1 + name: v1beta2 + schema: + openAPIV3Schema: + description: Kustomization is the Schema for the kustomizations API. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: KustomizationSpec defines the configuration to calculate + the desired state from a Source using Kustomize. + properties: + commonMetadata: + description: |- + CommonMetadata specifies the common labels and annotations that are applied to all resources. + Any existing label or annotation will be overridden if its key matches a common one. + properties: + annotations: + additionalProperties: + type: string + description: Annotations to be added to the object's metadata. + type: object + labels: + additionalProperties: + type: string + description: Labels to be added to the object's metadata. + type: object + type: object + components: + description: Components specifies relative paths to specifications + of other Components. + items: + type: string + type: array + decryption: + description: Decrypt Kubernetes secrets before applying them on the + cluster. + properties: + provider: + description: Provider is the name of the decryption engine. + enum: + - sops + type: string + secretRef: + description: The secret name containing the private OpenPGP keys + used for decryption. + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + required: + - provider + type: object + dependsOn: + description: |- + DependsOn may contain a meta.NamespacedObjectReference slice + with references to Kustomization resources that must be ready before this + Kustomization can be reconciled. + items: + description: |- + NamespacedObjectReference contains enough information to locate the referenced Kubernetes resource object in any + namespace. + properties: + name: + description: Name of the referent. + type: string + namespace: + description: Namespace of the referent, when not specified it + acts as LocalObjectReference. + type: string + required: + - name + type: object + type: array + force: + default: false + description: |- + Force instructs the controller to recreate resources + when patching fails due to an immutable field change. + type: boolean + healthChecks: + description: A list of resources to be included in the health assessment. + items: + description: |- + NamespacedObjectKindReference contains enough information to locate the typed referenced Kubernetes resource object + in any namespace. + properties: + apiVersion: + description: API version of the referent, if not specified the + Kubernetes preferred version will be used. + type: string + kind: + description: Kind of the referent. + type: string + name: + description: Name of the referent. + type: string + namespace: + description: Namespace of the referent, when not specified it + acts as LocalObjectReference. + type: string + required: + - kind + - name + type: object + type: array + images: + description: |- + Images is a list of (image name, new name, new tag or digest) + for changing image names, tags or digests. This can also be achieved with a + patch, but this operator is simpler to specify. + items: + description: Image contains an image name, a new name, a new tag + or digest, which will replace the original name and tag. + properties: + digest: + description: |- + Digest is the value used to replace the original image tag. + If digest is present NewTag value is ignored. + type: string + name: + description: Name is a tag-less image name. + type: string + newName: + description: NewName is the value used to replace the original + name. + type: string + newTag: + description: NewTag is the value used to replace the original + tag. + type: string + required: + - name + type: object + type: array + interval: + description: The interval at which to reconcile the Kustomization. + pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ + type: string + kubeConfig: + description: |- + The KubeConfig for reconciling the Kustomization on a remote cluster. + When used in combination with KustomizationSpec.ServiceAccountName, + forces the controller to act on behalf of that Service Account at the + target cluster. + If the --default-service-account flag is set, its value will be used as + a controller level fallback for when KustomizationSpec.ServiceAccountName + is empty. + properties: + secretRef: + description: |- + SecretRef holds the name of a secret that contains a key with + the kubeconfig file as the value. If no key is set, the key will default + to 'value'. + It is recommended that the kubeconfig is self-contained, and the secret + is regularly updated if credentials such as a cloud-access-token expire. + Cloud specific `cmd-path` auth helpers will not function without adding + binaries and credentials to the Pod that is responsible for reconciling + Kubernetes resources. + properties: + key: + description: Key in the Secret, when not specified an implementation-specific + default key is used. + type: string + name: + description: Name of the Secret. + type: string + required: + - name + type: object + required: + - secretRef + type: object + patches: + description: |- + Strategic merge and JSON patches, defined as inline YAML objects, + capable of targeting objects based on kind, label and annotation selectors. + items: + description: |- + Patch contains an inline StrategicMerge or JSON6902 patch, and the target the patch should + be applied to. + properties: + patch: + description: |- + Patch contains an inline StrategicMerge patch or an inline JSON6902 patch with + an array of operation objects. + type: string + target: + description: Target points to the resources that the patch document + should be applied to. + properties: + annotationSelector: + description: |- + AnnotationSelector is a string that follows the label selection expression + https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#api + It matches with the resource annotations. + type: string + group: + description: |- + Group is the API group to select resources from. + Together with Version and Kind it is capable of unambiguously identifying and/or selecting resources. + https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md + type: string + kind: + description: |- + Kind of the API Group to select resources from. + Together with Group and Version it is capable of unambiguously + identifying and/or selecting resources. + https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md + type: string + labelSelector: + description: |- + LabelSelector is a string that follows the label selection expression + https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#api + It matches with the resource labels. + type: string + name: + description: Name to match resources with. + type: string + namespace: + description: Namespace to select resources from. + type: string + version: + description: |- + Version of the API Group to select resources from. + Together with Group and Kind it is capable of unambiguously identifying and/or selecting resources. + https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md + type: string + type: object + required: + - patch + type: object + type: array + patchesJson6902: + description: |- + JSON 6902 patches, defined as inline YAML objects. + Deprecated: Use Patches instead. + items: + description: JSON6902Patch contains a JSON6902 patch and the target + the patch should be applied to. + properties: + patch: + description: Patch contains the JSON6902 patch document with + an array of operation objects. + items: + description: |- + JSON6902 is a JSON6902 operation object. + https://datatracker.ietf.org/doc/html/rfc6902#section-4 + properties: + from: + description: |- + From contains a JSON-pointer value that references a location within the target document where the operation is + performed. The meaning of the value depends on the value of Op, and is NOT taken into account by all operations. + type: string + op: + description: |- + Op indicates the operation to perform. Its value MUST be one of "add", "remove", "replace", "move", "copy", or + "test". + https://datatracker.ietf.org/doc/html/rfc6902#section-4 + enum: + - test + - remove + - add + - replace + - move + - copy + type: string + path: + description: |- + Path contains the JSON-pointer value that references a location within the target document where the operation + is performed. The meaning of the value depends on the value of Op. + type: string + value: + description: |- + Value contains a valid JSON structure. The meaning of the value depends on the value of Op, and is NOT taken into + account by all operations. + x-kubernetes-preserve-unknown-fields: true + required: + - op + - path + type: object + type: array + target: + description: Target points to the resources that the patch document + should be applied to. + properties: + annotationSelector: + description: |- + AnnotationSelector is a string that follows the label selection expression + https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#api + It matches with the resource annotations. + type: string + group: + description: |- + Group is the API group to select resources from. + Together with Version and Kind it is capable of unambiguously identifying and/or selecting resources. + https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md + type: string + kind: + description: |- + Kind of the API Group to select resources from. + Together with Group and Version it is capable of unambiguously + identifying and/or selecting resources. + https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md + type: string + labelSelector: + description: |- + LabelSelector is a string that follows the label selection expression + https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#api + It matches with the resource labels. + type: string + name: + description: Name to match resources with. + type: string + namespace: + description: Namespace to select resources from. + type: string + version: + description: |- + Version of the API Group to select resources from. + Together with Group and Kind it is capable of unambiguously identifying and/or selecting resources. + https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md + type: string + type: object + required: + - patch + - target + type: object + type: array + patchesStrategicMerge: + description: |- + Strategic merge patches, defined as inline YAML objects. + Deprecated: Use Patches instead. + items: + x-kubernetes-preserve-unknown-fields: true + type: array + path: + description: |- + Path to the directory containing the kustomization.yaml file, or the + set of plain YAMLs a kustomization.yaml should be generated for. + Defaults to 'None', which translates to the root path of the SourceRef. + type: string + postBuild: + description: |- + PostBuild describes which actions to perform on the YAML manifest + generated by building the kustomize overlay. + properties: + substitute: + additionalProperties: + type: string + description: |- + Substitute holds a map of key/value pairs. + The variables defined in your YAML manifests + that match any of the keys defined in the map + will be substituted with the set value. + Includes support for bash string replacement functions + e.g. ${var:=default}, ${var:position} and ${var/substring/replacement}. + type: object + substituteFrom: + description: |- + SubstituteFrom holds references to ConfigMaps and Secrets containing + the variables and their values to be substituted in the YAML manifests. + The ConfigMap and the Secret data keys represent the var names and they + must match the vars declared in the manifests for the substitution to happen. + items: + description: |- + SubstituteReference contains a reference to a resource containing + the variables name and value. + properties: + kind: + description: Kind of the values referent, valid values are + ('Secret', 'ConfigMap'). + enum: + - Secret + - ConfigMap + type: string + name: + description: |- + Name of the values referent. Should reside in the same namespace as the + referring resource. + maxLength: 253 + minLength: 1 + type: string + optional: + default: false + description: |- + Optional indicates whether the referenced resource must exist, or whether to + tolerate its absence. If true and the referenced resource is absent, proceed + as if the resource was present but empty, without any variables defined. + type: boolean + required: + - kind + - name + type: object + type: array + type: object + prune: + description: Prune enables garbage collection. + type: boolean + retryInterval: + description: |- + The interval at which to retry a previously failed reconciliation. + When not specified, the controller uses the KustomizationSpec.Interval + value to retry failures. + pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ + type: string + serviceAccountName: + description: |- + The name of the Kubernetes service account to impersonate + when reconciling this Kustomization. + type: string + sourceRef: + description: Reference of the source where the kustomization file + is. + properties: + apiVersion: + description: API version of the referent. + type: string + kind: + description: Kind of the referent. + enum: + - OCIRepository + - GitRepository + - Bucket + type: string + name: + description: Name of the referent. + type: string + namespace: + description: Namespace of the referent, defaults to the namespace + of the Kubernetes resource object that contains the reference. + type: string + required: + - kind + - name + type: object + suspend: + description: |- + This flag tells the controller to suspend subsequent kustomize executions, + it does not apply to already started executions. Defaults to false. + type: boolean + targetNamespace: + description: |- + TargetNamespace sets or overrides the namespace in the + kustomization.yaml file. + maxLength: 63 + minLength: 1 + type: string + timeout: + description: |- + Timeout for validation, apply and health checking operations. + Defaults to 'Interval' duration. + pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ + type: string + validation: + description: 'Deprecated: Not used in v1beta2.' + enum: + - none + - client + - server + type: string + wait: + description: |- + Wait instructs the controller to check the health of all the reconciled resources. + When enabled, the HealthChecks are ignored. Defaults to false. + type: boolean + required: + - interval + - prune + - sourceRef + type: object + status: + default: + observedGeneration: -1 + description: KustomizationStatus defines the observed state of a kustomization. + properties: + conditions: + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + inventory: + description: Inventory contains the list of Kubernetes resource object + references that have been successfully applied. + properties: + entries: + description: Entries of Kubernetes resource object references. + items: + description: ResourceRef contains the information necessary + to locate a resource within a cluster. + properties: + id: + description: |- + ID is the string representation of the Kubernetes resource object's metadata, + in the format '<namespace>_<name>_<group>_<kind>'. + type: string + v: + description: Version is the API version of the Kubernetes + resource object's kind. + type: string + required: + - id + - v + type: object + type: array + required: + - entries + type: object + lastAppliedRevision: + description: |- + The last successfully applied revision. + Equals the Revision of the applied Artifact from the referenced Source. + type: string + lastAttemptedRevision: + description: LastAttemptedRevision is the revision of the last reconciliation + attempt. + type: string + lastHandledReconcileAt: + description: |- + LastHandledReconcileAt holds the value of the most recent + reconcile request value, so a change of the annotation value + can be detected. + type: string + observedGeneration: + description: ObservedGeneration is the last reconciled generation. + format: int64 + type: integer + type: object + type: object + served: true + storage: false + subresources: + status: {} +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app.kubernetes.io/component: kustomize-controller + app.kubernetes.io/instance: flux-system + app.kubernetes.io/part-of: flux + app.kubernetes.io/version: v2.4.0 + name: kustomize-controller + namespace: flux-system +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app.kubernetes.io/component: kustomize-controller + app.kubernetes.io/instance: flux-system + app.kubernetes.io/part-of: flux + app.kubernetes.io/version: v2.4.0 + control-plane: controller + name: kustomize-controller + namespace: flux-system +spec: + replicas: 1 + selector: + matchLabels: + app: kustomize-controller + template: + metadata: + annotations: + prometheus.io/port: "8080" + prometheus.io/scrape: "true" + labels: + app: kustomize-controller + spec: + containers: + - args: + - --events-addr=http://notification-controller.flux-system.svc.cluster.local./ + - --watch-all-namespaces=true + - --log-level=info + - --log-encoding=json + - --enable-leader-election + env: + - name: RUNTIME_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: GOMAXPROCS + valueFrom: + resourceFieldRef: + containerName: manager + resource: limits.cpu + - name: GOMEMLIMIT + valueFrom: + resourceFieldRef: + containerName: manager + resource: limits.memory + image: ghcr.io/fluxcd/kustomize-controller:v1.4.0 + imagePullPolicy: IfNotPresent + livenessProbe: + httpGet: + path: /healthz + port: healthz + name: manager + ports: + - containerPort: 8080 + name: http-prom + protocol: TCP + - containerPort: 9440 + name: healthz + protocol: TCP + readinessProbe: + httpGet: + path: /readyz + port: healthz + resources: + limits: + cpu: 1000m + memory: 1Gi + requests: + cpu: 100m + memory: 64Mi + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + volumeMounts: + - mountPath: /tmp + name: temp + nodeSelector: + kubernetes.io/os: linux + priorityClassName: system-cluster-critical + securityContext: + fsGroup: 1337 + serviceAccountName: kustomize-controller + terminationGracePeriodSeconds: 60 + volumes: + - emptyDir: {} + name: temp +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.16.1 + labels: + app.kubernetes.io/component: helm-controller + app.kubernetes.io/instance: flux-system + app.kubernetes.io/part-of: flux + app.kubernetes.io/version: v2.4.0 + name: helmreleases.helm.toolkit.fluxcd.io +spec: + group: helm.toolkit.fluxcd.io + names: + kind: HelmRelease + listKind: HelmReleaseList + plural: helmreleases + shortNames: + - hr + singular: helmrelease + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + - jsonPath: .status.conditions[?(@.type=="Ready")].status + name: Ready + type: string + - jsonPath: .status.conditions[?(@.type=="Ready")].message + name: Status + type: string + name: v2 + schema: + openAPIV3Schema: + description: HelmRelease is the Schema for the helmreleases API + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: HelmReleaseSpec defines the desired state of a Helm release. + properties: + chart: + description: |- + Chart defines the template of the v1.HelmChart that should be created + for this HelmRelease. + properties: + metadata: + description: ObjectMeta holds the template for metadata like labels + and annotations. + properties: + annotations: + additionalProperties: + type: string + description: |- + Annotations is an unstructured key value map stored with a resource that may be + set by external tools to store and retrieve arbitrary metadata. They are not + queryable and should be preserved when modifying objects. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/ + type: object + labels: + additionalProperties: + type: string + description: |- + Map of string keys and values that can be used to organize and categorize + (scope and select) objects. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ + type: object + type: object + spec: + description: Spec holds the template for the v1.HelmChartSpec + for this HelmRelease. + properties: + chart: + description: The name or path the Helm chart is available + at in the SourceRef. + maxLength: 2048 + minLength: 1 + type: string + ignoreMissingValuesFiles: + description: IgnoreMissingValuesFiles controls whether to + silently ignore missing values files rather than failing. + type: boolean + interval: + description: |- + Interval at which to check the v1.Source for updates. Defaults to + 'HelmReleaseSpec.Interval'. + pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ + type: string + reconcileStrategy: + default: ChartVersion + description: |- + Determines what enables the creation of a new artifact. Valid values are + ('ChartVersion', 'Revision'). + See the documentation of the values for an explanation on their behavior. + Defaults to ChartVersion when omitted. + enum: + - ChartVersion + - Revision + type: string + sourceRef: + description: The name and namespace of the v1.Source the chart + is available at. + properties: + apiVersion: + description: APIVersion of the referent. + type: string + kind: + description: Kind of the referent. + enum: + - HelmRepository + - GitRepository + - Bucket + type: string + name: + description: Name of the referent. + maxLength: 253 + minLength: 1 + type: string + namespace: + description: Namespace of the referent. + maxLength: 63 + minLength: 1 + type: string + required: + - kind + - name + type: object + valuesFiles: + description: |- + Alternative list of values files to use as the chart values (values.yaml + is not included by default), expected to be a relative path in the SourceRef. + Values files are merged in the order of this list with the last file overriding + the first. Ignored when omitted. + items: + type: string + type: array + verify: + description: |- + Verify contains the secret name containing the trusted public keys + used to verify the signature and specifies which provider to use to check + whether OCI image is authentic. + This field is only supported for OCI sources. + Chart dependencies, which are not bundled in the umbrella chart artifact, + are not verified. + properties: + provider: + default: cosign + description: Provider specifies the technology used to + sign the OCI Helm chart. + enum: + - cosign + - notation + type: string + secretRef: + description: |- + SecretRef specifies the Kubernetes Secret containing the + trusted public keys. + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + required: + - provider + type: object + version: + default: '*' + description: |- + Version semver expression, ignored for charts from v1.GitRepository and + v1beta2.Bucket sources. Defaults to latest when omitted. + type: string + required: + - chart + - sourceRef + type: object + required: + - spec + type: object + chartRef: + description: |- + ChartRef holds a reference to a source controller resource containing the + Helm chart artifact. + properties: + apiVersion: + description: APIVersion of the referent. + type: string + kind: + description: Kind of the referent. + enum: + - OCIRepository + - HelmChart + type: string + name: + description: Name of the referent. + maxLength: 253 + minLength: 1 + type: string + namespace: + description: |- + Namespace of the referent, defaults to the namespace of the Kubernetes + resource object that contains the reference. + maxLength: 63 + minLength: 1 + type: string + required: + - kind + - name + type: object + dependsOn: + description: |- + DependsOn may contain a meta.NamespacedObjectReference slice with + references to HelmRelease resources that must be ready before this HelmRelease + can be reconciled. + items: + description: |- + NamespacedObjectReference contains enough information to locate the referenced Kubernetes resource object in any + namespace. + properties: + name: + description: Name of the referent. + type: string + namespace: + description: Namespace of the referent, when not specified it + acts as LocalObjectReference. + type: string + required: + - name + type: object + type: array + driftDetection: + description: |- + DriftDetection holds the configuration for detecting and handling + differences between the manifest in the Helm storage and the resources + currently existing in the cluster. + properties: + ignore: + description: |- + Ignore contains a list of rules for specifying which changes to ignore + during diffing. + items: + description: |- + IgnoreRule defines a rule to selectively disregard specific changes during + the drift detection process. + properties: + paths: + description: |- + Paths is a list of JSON Pointer (RFC 6901) paths to be excluded from + consideration in a Kubernetes object. + items: + type: string + type: array + target: + description: |- + Target is a selector for specifying Kubernetes objects to which this + rule applies. + If Target is not set, the Paths will be ignored for all Kubernetes + objects within the manifest of the Helm release. + properties: + annotationSelector: + description: |- + AnnotationSelector is a string that follows the label selection expression + https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#api + It matches with the resource annotations. + type: string + group: + description: |- + Group is the API group to select resources from. + Together with Version and Kind it is capable of unambiguously identifying and/or selecting resources. + https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md + type: string + kind: + description: |- + Kind of the API Group to select resources from. + Together with Group and Version it is capable of unambiguously + identifying and/or selecting resources. + https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md + type: string + labelSelector: + description: |- + LabelSelector is a string that follows the label selection expression + https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#api + It matches with the resource labels. + type: string + name: + description: Name to match resources with. + type: string + namespace: + description: Namespace to select resources from. + type: string + version: + description: |- + Version of the API Group to select resources from. + Together with Group and Kind it is capable of unambiguously identifying and/or selecting resources. + https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md + type: string + type: object + required: + - paths + type: object + type: array + mode: + description: |- + Mode defines how differences should be handled between the Helm manifest + and the manifest currently applied to the cluster. + If not explicitly set, it defaults to DiffModeDisabled. + enum: + - enabled + - warn + - disabled + type: string + type: object + install: + description: Install holds the configuration for Helm install actions + for this HelmRelease. + properties: + crds: + description: |- + CRDs upgrade CRDs from the Helm Chart's crds directory according + to the CRD upgrade policy provided here. Valid values are `Skip`, + `Create` or `CreateReplace`. Default is `Create` and if omitted + CRDs are installed but not updated. + + Skip: do neither install nor replace (update) any CRDs. + + Create: new CRDs are created, existing CRDs are neither updated nor deleted. + + CreateReplace: new CRDs are created, existing CRDs are updated (replaced) + but not deleted. + + By default, CRDs are applied (installed) during Helm install action. + With this option users can opt in to CRD replace existing CRDs on Helm + install actions, which is not (yet) natively supported by Helm. + https://helm.sh/docs/chart_best_practices/custom_resource_definitions. + enum: + - Skip + - Create + - CreateReplace + type: string + createNamespace: + description: |- + CreateNamespace tells the Helm install action to create the + HelmReleaseSpec.TargetNamespace if it does not exist yet. + On uninstall, the namespace will not be garbage collected. + type: boolean + disableHooks: + description: DisableHooks prevents hooks from running during the + Helm install action. + type: boolean + disableOpenAPIValidation: + description: |- + DisableOpenAPIValidation prevents the Helm install action from validating + rendered templates against the Kubernetes OpenAPI Schema. + type: boolean + disableSchemaValidation: + description: |- + DisableSchemaValidation prevents the Helm install action from validating + the values against the JSON Schema. + type: boolean + disableWait: + description: |- + DisableWait disables the waiting for resources to be ready after a Helm + install has been performed. + type: boolean + disableWaitForJobs: + description: |- + DisableWaitForJobs disables waiting for jobs to complete after a Helm + install has been performed. + type: boolean + remediation: + description: |- + Remediation holds the remediation configuration for when the Helm install + action for the HelmRelease fails. The default is to not perform any action. + properties: + ignoreTestFailures: + description: |- + IgnoreTestFailures tells the controller to skip remediation when the Helm + tests are run after an install action but fail. Defaults to + 'Test.IgnoreFailures'. + type: boolean + remediateLastFailure: + description: |- + RemediateLastFailure tells the controller to remediate the last failure, when + no retries remain. Defaults to 'false'. + type: boolean + retries: + description: |- + Retries is the number of retries that should be attempted on failures before + bailing. Remediation, using an uninstall, is performed between each attempt. + Defaults to '0', a negative integer equals to unlimited retries. + type: integer + type: object + replace: + description: |- + Replace tells the Helm install action to re-use the 'ReleaseName', but only + if that name is a deleted release which remains in the history. + type: boolean + skipCRDs: + description: |- + SkipCRDs tells the Helm install action to not install any CRDs. By default, + CRDs are installed if not already present. + + Deprecated use CRD policy (`crds`) attribute with value `Skip` instead. + type: boolean + timeout: + description: |- + Timeout is the time to wait for any individual Kubernetes operation (like + Jobs for hooks) during the performance of a Helm install action. Defaults to + 'HelmReleaseSpec.Timeout'. + pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ + type: string + type: object + interval: + description: Interval at which to reconcile the Helm release. + pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ + type: string + kubeConfig: + description: |- + KubeConfig for reconciling the HelmRelease on a remote cluster. + When used in combination with HelmReleaseSpec.ServiceAccountName, + forces the controller to act on behalf of that Service Account at the + target cluster. + If the --default-service-account flag is set, its value will be used as + a controller level fallback for when HelmReleaseSpec.ServiceAccountName + is empty. + properties: + secretRef: + description: |- + SecretRef holds the name of a secret that contains a key with + the kubeconfig file as the value. If no key is set, the key will default + to 'value'. + It is recommended that the kubeconfig is self-contained, and the secret + is regularly updated if credentials such as a cloud-access-token expire. + Cloud specific `cmd-path` auth helpers will not function without adding + binaries and credentials to the Pod that is responsible for reconciling + Kubernetes resources. + properties: + key: + description: Key in the Secret, when not specified an implementation-specific + default key is used. + type: string + name: + description: Name of the Secret. + type: string + required: + - name + type: object + required: + - secretRef + type: object + maxHistory: + description: |- + MaxHistory is the number of revisions saved by Helm for this HelmRelease. + Use '0' for an unlimited number of revisions; defaults to '5'. + type: integer + persistentClient: + description: |- + PersistentClient tells the controller to use a persistent Kubernetes + client for this release. When enabled, the client will be reused for the + duration of the reconciliation, instead of being created and destroyed + for each (step of a) Helm action. + + This can improve performance, but may cause issues with some Helm charts + that for example do create Custom Resource Definitions during installation + outside Helm's CRD lifecycle hooks, which are then not observed to be + available by e.g. post-install hooks. + + If not set, it defaults to true. + type: boolean + postRenderers: + description: |- + PostRenderers holds an array of Helm PostRenderers, which will be applied in order + of their definition. + items: + description: PostRenderer contains a Helm PostRenderer specification. + properties: + kustomize: + description: Kustomization to apply as PostRenderer. + properties: + images: + description: |- + Images is a list of (image name, new name, new tag or digest) + for changing image names, tags or digests. This can also be achieved with a + patch, but this operator is simpler to specify. + items: + description: Image contains an image name, a new name, + a new tag or digest, which will replace the original + name and tag. + properties: + digest: + description: |- + Digest is the value used to replace the original image tag. + If digest is present NewTag value is ignored. + type: string + name: + description: Name is a tag-less image name. + type: string + newName: + description: NewName is the value used to replace + the original name. + type: string + newTag: + description: NewTag is the value used to replace the + original tag. + type: string + required: + - name + type: object + type: array + patches: + description: |- + Strategic merge and JSON patches, defined as inline YAML objects, + capable of targeting objects based on kind, label and annotation selectors. + items: + description: |- + Patch contains an inline StrategicMerge or JSON6902 patch, and the target the patch should + be applied to. + properties: + patch: + description: |- + Patch contains an inline StrategicMerge patch or an inline JSON6902 patch with + an array of operation objects. + type: string + target: + description: Target points to the resources that the + patch document should be applied to. + properties: + annotationSelector: + description: |- + AnnotationSelector is a string that follows the label selection expression + https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#api + It matches with the resource annotations. + type: string + group: + description: |- + Group is the API group to select resources from. + Together with Version and Kind it is capable of unambiguously identifying and/or selecting resources. + https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md + type: string + kind: + description: |- + Kind of the API Group to select resources from. + Together with Group and Version it is capable of unambiguously + identifying and/or selecting resources. + https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md + type: string + labelSelector: + description: |- + LabelSelector is a string that follows the label selection expression + https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#api + It matches with the resource labels. + type: string + name: + description: Name to match resources with. + type: string + namespace: + description: Namespace to select resources from. + type: string + version: + description: |- + Version of the API Group to select resources from. + Together with Group and Kind it is capable of unambiguously identifying and/or selecting resources. + https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md + type: string + type: object + required: + - patch + type: object + type: array + type: object + type: object + type: array + releaseName: + description: |- + ReleaseName used for the Helm release. Defaults to a composition of + '[TargetNamespace-]Name'. + maxLength: 53 + minLength: 1 + type: string + rollback: + description: Rollback holds the configuration for Helm rollback actions + for this HelmRelease. + properties: + cleanupOnFail: + description: |- + CleanupOnFail allows deletion of new resources created during the Helm + rollback action when it fails. + type: boolean + disableHooks: + description: DisableHooks prevents hooks from running during the + Helm rollback action. + type: boolean + disableWait: + description: |- + DisableWait disables the waiting for resources to be ready after a Helm + rollback has been performed. + type: boolean + disableWaitForJobs: + description: |- + DisableWaitForJobs disables waiting for jobs to complete after a Helm + rollback has been performed. + type: boolean + force: + description: Force forces resource updates through a replacement + strategy. + type: boolean + recreate: + description: Recreate performs pod restarts for the resource if + applicable. + type: boolean + timeout: + description: |- + Timeout is the time to wait for any individual Kubernetes operation (like + Jobs for hooks) during the performance of a Helm rollback action. Defaults to + 'HelmReleaseSpec.Timeout'. + pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ + type: string + type: object + serviceAccountName: + description: |- + The name of the Kubernetes service account to impersonate + when reconciling this HelmRelease. + maxLength: 253 + minLength: 1 + type: string + storageNamespace: + description: |- + StorageNamespace used for the Helm storage. + Defaults to the namespace of the HelmRelease. + maxLength: 63 + minLength: 1 + type: string + suspend: + description: |- + Suspend tells the controller to suspend reconciliation for this HelmRelease, + it does not apply to already started reconciliations. Defaults to false. + type: boolean + targetNamespace: + description: |- + TargetNamespace to target when performing operations for the HelmRelease. + Defaults to the namespace of the HelmRelease. + maxLength: 63 + minLength: 1 + type: string + test: + description: Test holds the configuration for Helm test actions for + this HelmRelease. + properties: + enable: + description: |- + Enable enables Helm test actions for this HelmRelease after an Helm install + or upgrade action has been performed. + type: boolean + filters: + description: Filters is a list of tests to run or exclude from + running. + items: + description: Filter holds the configuration for individual Helm + test filters. + properties: + exclude: + description: Exclude specifies whether the named test should + be excluded. + type: boolean + name: + description: Name is the name of the test. + maxLength: 253 + minLength: 1 + type: string + required: + - name + type: object + type: array + ignoreFailures: + description: |- + IgnoreFailures tells the controller to skip remediation when the Helm tests + are run but fail. Can be overwritten for tests run after install or upgrade + actions in 'Install.IgnoreTestFailures' and 'Upgrade.IgnoreTestFailures'. + type: boolean + timeout: + description: |- + Timeout is the time to wait for any individual Kubernetes operation during + the performance of a Helm test action. Defaults to 'HelmReleaseSpec.Timeout'. + pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ + type: string + type: object + timeout: + description: |- + Timeout is the time to wait for any individual Kubernetes operation (like Jobs + for hooks) during the performance of a Helm action. Defaults to '5m0s'. + pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ + type: string + uninstall: + description: Uninstall holds the configuration for Helm uninstall + actions for this HelmRelease. + properties: + deletionPropagation: + default: background + description: |- + DeletionPropagation specifies the deletion propagation policy when + a Helm uninstall is performed. + enum: + - background + - foreground + - orphan + type: string + disableHooks: + description: DisableHooks prevents hooks from running during the + Helm rollback action. + type: boolean + disableWait: + description: |- + DisableWait disables waiting for all the resources to be deleted after + a Helm uninstall is performed. + type: boolean + keepHistory: + description: |- + KeepHistory tells Helm to remove all associated resources and mark the + release as deleted, but retain the release history. + type: boolean + timeout: + description: |- + Timeout is the time to wait for any individual Kubernetes operation (like + Jobs for hooks) during the performance of a Helm uninstall action. Defaults + to 'HelmReleaseSpec.Timeout'. + pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ + type: string + type: object + upgrade: + description: Upgrade holds the configuration for Helm upgrade actions + for this HelmRelease. + properties: + cleanupOnFail: + description: |- + CleanupOnFail allows deletion of new resources created during the Helm + upgrade action when it fails. + type: boolean + crds: + description: |- + CRDs upgrade CRDs from the Helm Chart's crds directory according + to the CRD upgrade policy provided here. Valid values are `Skip`, + `Create` or `CreateReplace`. Default is `Skip` and if omitted + CRDs are neither installed nor upgraded. + + Skip: do neither install nor replace (update) any CRDs. + + Create: new CRDs are created, existing CRDs are neither updated nor deleted. + + CreateReplace: new CRDs are created, existing CRDs are updated (replaced) + but not deleted. + + By default, CRDs are not applied during Helm upgrade action. With this + option users can opt-in to CRD upgrade, which is not (yet) natively supported by Helm. + https://helm.sh/docs/chart_best_practices/custom_resource_definitions. + enum: + - Skip + - Create + - CreateReplace + type: string + disableHooks: + description: DisableHooks prevents hooks from running during the + Helm upgrade action. + type: boolean + disableOpenAPIValidation: + description: |- + DisableOpenAPIValidation prevents the Helm upgrade action from validating + rendered templates against the Kubernetes OpenAPI Schema. + type: boolean + disableSchemaValidation: + description: |- + DisableSchemaValidation prevents the Helm upgrade action from validating + the values against the JSON Schema. + type: boolean + disableWait: + description: |- + DisableWait disables the waiting for resources to be ready after a Helm + upgrade has been performed. + type: boolean + disableWaitForJobs: + description: |- + DisableWaitForJobs disables waiting for jobs to complete after a Helm + upgrade has been performed. + type: boolean + force: + description: Force forces resource updates through a replacement + strategy. + type: boolean + preserveValues: + description: |- + PreserveValues will make Helm reuse the last release's values and merge in + overrides from 'Values'. Setting this flag makes the HelmRelease + non-declarative. + type: boolean + remediation: + description: |- + Remediation holds the remediation configuration for when the Helm upgrade + action for the HelmRelease fails. The default is to not perform any action. + properties: + ignoreTestFailures: + description: |- + IgnoreTestFailures tells the controller to skip remediation when the Helm + tests are run after an upgrade action but fail. + Defaults to 'Test.IgnoreFailures'. + type: boolean + remediateLastFailure: + description: |- + RemediateLastFailure tells the controller to remediate the last failure, when + no retries remain. Defaults to 'false' unless 'Retries' is greater than 0. + type: boolean + retries: + description: |- + Retries is the number of retries that should be attempted on failures before + bailing. Remediation, using 'Strategy', is performed between each attempt. + Defaults to '0', a negative integer equals to unlimited retries. + type: integer + strategy: + description: Strategy to use for failure remediation. Defaults + to 'rollback'. + enum: + - rollback + - uninstall + type: string + type: object + timeout: + description: |- + Timeout is the time to wait for any individual Kubernetes operation (like + Jobs for hooks) during the performance of a Helm upgrade action. Defaults to + 'HelmReleaseSpec.Timeout'. + pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ + type: string + type: object + values: + description: Values holds the values for this Helm release. + x-kubernetes-preserve-unknown-fields: true + valuesFrom: + description: |- + ValuesFrom holds references to resources containing Helm values for this HelmRelease, + and information about how they should be merged. + items: + description: |- + ValuesReference contains a reference to a resource containing Helm values, + and optionally the key they can be found at. + properties: + kind: + description: Kind of the values referent, valid values are ('Secret', + 'ConfigMap'). + enum: + - Secret + - ConfigMap + type: string + name: + description: |- + Name of the values referent. Should reside in the same namespace as the + referring resource. + maxLength: 253 + minLength: 1 + type: string + optional: + description: |- + Optional marks this ValuesReference as optional. When set, a not found error + for the values reference is ignored, but any ValuesKey, TargetPath or + transient error will still result in a reconciliation failure. + type: boolean + targetPath: + description: |- + TargetPath is the YAML dot notation path the value should be merged at. When + set, the ValuesKey is expected to be a single flat value. Defaults to 'None', + which results in the values getting merged at the root. + maxLength: 250 + pattern: ^([a-zA-Z0-9_\-.\\\/]|\[[0-9]{1,5}\])+$ + type: string + valuesKey: + description: |- + ValuesKey is the data key where the values.yaml or a specific value can be + found at. Defaults to 'values.yaml'. + maxLength: 253 + pattern: ^[\-._a-zA-Z0-9]+$ + type: string + required: + - kind + - name + type: object + type: array + required: + - interval + type: object + x-kubernetes-validations: + - message: either chart or chartRef must be set + rule: (has(self.chart) && !has(self.chartRef)) || (!has(self.chart) + && has(self.chartRef)) + status: + default: + observedGeneration: -1 + description: HelmReleaseStatus defines the observed state of a HelmRelease. + properties: + conditions: + description: Conditions holds the conditions for the HelmRelease. + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + failures: + description: |- + Failures is the reconciliation failure count against the latest desired + state. It is reset after a successful reconciliation. + format: int64 + type: integer + helmChart: + description: |- + HelmChart is the namespaced name of the HelmChart resource created by + the controller for the HelmRelease. + type: string + history: + description: |- + History holds the history of Helm releases performed for this HelmRelease + up to the last successfully completed release. + items: + description: |- + Snapshot captures a point-in-time copy of the status information for a Helm release, + as managed by the controller. + properties: + apiVersion: + description: |- + APIVersion is the API version of the Snapshot. + Provisional: when the calculation method of the Digest field is changed, + this field will be used to distinguish between the old and new methods. + type: string + appVersion: + description: AppVersion is the chart app version of the release + object in storage. + type: string + chartName: + description: ChartName is the chart name of the release object + in storage. + type: string + chartVersion: + description: |- + ChartVersion is the chart version of the release object in + storage. + type: string + configDigest: + description: |- + ConfigDigest is the checksum of the config (better known as + "values") of the release object in storage. + It has the format of `<algo>:<checksum>`. + type: string + deleted: + description: Deleted is when the release was deleted. + format: date-time + type: string + digest: + description: |- + Digest is the checksum of the release object in storage. + It has the format of `<algo>:<checksum>`. + type: string + firstDeployed: + description: FirstDeployed is when the release was first deployed. + format: date-time + type: string + lastDeployed: + description: LastDeployed is when the release was last deployed. + format: date-time + type: string + name: + description: Name is the name of the release. + type: string + namespace: + description: Namespace is the namespace the release is deployed + to. + type: string + ociDigest: + description: OCIDigest is the digest of the OCI artifact associated + with the release. + type: string + status: + description: Status is the current state of the release. + type: string + testHooks: + additionalProperties: + description: |- + TestHookStatus holds the status information for a test hook as observed + to be run by the controller. + properties: + lastCompleted: + description: LastCompleted is the time the test hook last + completed. + format: date-time + type: string + lastStarted: + description: LastStarted is the time the test hook was + last started. + format: date-time + type: string + phase: + description: Phase the test hook was observed to be in. + type: string + type: object + description: |- + TestHooks is the list of test hooks for the release as observed to be + run by the controller. + type: object + version: + description: Version is the version of the release object in + storage. + type: integer + required: + - chartName + - chartVersion + - configDigest + - digest + - firstDeployed + - lastDeployed + - name + - namespace + - status + - version + type: object + type: array + installFailures: + description: |- + InstallFailures is the install failure count against the latest desired + state. It is reset after a successful reconciliation. + format: int64 + type: integer + lastAttemptedConfigDigest: + description: |- + LastAttemptedConfigDigest is the digest for the config (better known as + "values") of the last reconciliation attempt. + type: string + lastAttemptedGeneration: + description: |- + LastAttemptedGeneration is the last generation the controller attempted + to reconcile. + format: int64 + type: integer + lastAttemptedReleaseAction: + description: |- + LastAttemptedReleaseAction is the last release action performed for this + HelmRelease. It is used to determine the active remediation strategy. + enum: + - install + - upgrade + type: string + lastAttemptedRevision: + description: |- + LastAttemptedRevision is the Source revision of the last reconciliation + attempt. For OCIRepository sources, the 12 first characters of the digest are + appended to the chart version e.g. "1.2.3+1234567890ab". + type: string + lastAttemptedRevisionDigest: + description: |- + LastAttemptedRevisionDigest is the digest of the last reconciliation attempt. + This is only set for OCIRepository sources. + type: string + lastAttemptedValuesChecksum: + description: |- + LastAttemptedValuesChecksum is the SHA1 checksum for the values of the last + reconciliation attempt. + Deprecated: Use LastAttemptedConfigDigest instead. + type: string + lastHandledForceAt: + description: |- + LastHandledForceAt holds the value of the most recent force request + value, so a change of the annotation value can be detected. + type: string + lastHandledReconcileAt: + description: |- + LastHandledReconcileAt holds the value of the most recent + reconcile request value, so a change of the annotation value + can be detected. + type: string + lastHandledResetAt: + description: |- + LastHandledResetAt holds the value of the most recent reset request + value, so a change of the annotation value can be detected. + type: string + lastReleaseRevision: + description: |- + LastReleaseRevision is the revision of the last successful Helm release. + Deprecated: Use History instead. + type: integer + observedGeneration: + description: ObservedGeneration is the last observed generation. + format: int64 + type: integer + observedPostRenderersDigest: + description: |- + ObservedPostRenderersDigest is the digest for the post-renderers of + the last successful reconciliation attempt. + type: string + storageNamespace: + description: |- + StorageNamespace is the namespace of the Helm release storage for the + current release. + maxLength: 63 + minLength: 1 + type: string + upgradeFailures: + description: |- + UpgradeFailures is the upgrade failure count against the latest desired + state. It is reset after a successful reconciliation. + format: int64 + type: integer + type: object + type: object + served: true + storage: true + subresources: + status: {} + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + - jsonPath: .status.conditions[?(@.type=="Ready")].status + name: Ready + type: string + - jsonPath: .status.conditions[?(@.type=="Ready")].message + name: Status + type: string + deprecated: true + deprecationWarning: v2beta1 HelmRelease is deprecated, upgrade to v2 + name: v2beta1 + schema: + openAPIV3Schema: + description: HelmRelease is the Schema for the helmreleases API + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: HelmReleaseSpec defines the desired state of a Helm release. + properties: + chart: + description: |- + Chart defines the template of the v1beta2.HelmChart that should be created + for this HelmRelease. + properties: + metadata: + description: ObjectMeta holds the template for metadata like labels + and annotations. + properties: + annotations: + additionalProperties: + type: string + description: |- + Annotations is an unstructured key value map stored with a resource that may be + set by external tools to store and retrieve arbitrary metadata. They are not + queryable and should be preserved when modifying objects. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/ + type: object + labels: + additionalProperties: + type: string + description: |- + Map of string keys and values that can be used to organize and categorize + (scope and select) objects. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ + type: object + type: object + spec: + description: Spec holds the template for the v1beta2.HelmChartSpec + for this HelmRelease. + properties: + chart: + description: The name or path the Helm chart is available + at in the SourceRef. + type: string + interval: + description: |- + Interval at which to check the v1beta2.Source for updates. Defaults to + 'HelmReleaseSpec.Interval'. + pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ + type: string + reconcileStrategy: + default: ChartVersion + description: |- + Determines what enables the creation of a new artifact. Valid values are + ('ChartVersion', 'Revision'). + See the documentation of the values for an explanation on their behavior. + Defaults to ChartVersion when omitted. + enum: + - ChartVersion + - Revision + type: string + sourceRef: + description: The name and namespace of the v1beta2.Source + the chart is available at. + properties: + apiVersion: + description: APIVersion of the referent. + type: string + kind: + description: Kind of the referent. + enum: + - HelmRepository + - GitRepository + - Bucket + type: string + name: + description: Name of the referent. + maxLength: 253 + minLength: 1 + type: string + namespace: + description: Namespace of the referent. + maxLength: 63 + minLength: 1 + type: string + required: + - kind + - name + type: object + valuesFile: + description: |- + Alternative values file to use as the default chart values, expected to + be a relative path in the SourceRef. Deprecated in favor of ValuesFiles, + for backwards compatibility the file defined here is merged before the + ValuesFiles items. Ignored when omitted. + type: string + valuesFiles: + description: |- + Alternative list of values files to use as the chart values (values.yaml + is not included by default), expected to be a relative path in the SourceRef. + Values files are merged in the order of this list with the last file overriding + the first. Ignored when omitted. + items: + type: string + type: array + verify: + description: |- + Verify contains the secret name containing the trusted public keys + used to verify the signature and specifies which provider to use to check + whether OCI image is authentic. + This field is only supported for OCI sources. + Chart dependencies, which are not bundled in the umbrella chart artifact, are not verified. + properties: + provider: + default: cosign + description: Provider specifies the technology used to + sign the OCI Helm chart. + enum: + - cosign + type: string + secretRef: + description: |- + SecretRef specifies the Kubernetes Secret containing the + trusted public keys. + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + required: + - provider + type: object + version: + default: '*' + description: |- + Version semver expression, ignored for charts from v1beta2.GitRepository and + v1beta2.Bucket sources. Defaults to latest when omitted. + type: string + required: + - chart + - sourceRef + type: object + required: + - spec + type: object + chartRef: + description: |- + ChartRef holds a reference to a source controller resource containing the + Helm chart artifact. + + Note: this field is provisional to the v2 API, and not actively used + by v2beta1 HelmReleases. + properties: + apiVersion: + description: APIVersion of the referent. + type: string + kind: + description: Kind of the referent. + enum: + - OCIRepository + - HelmChart + type: string + name: + description: Name of the referent. + maxLength: 253 + minLength: 1 + type: string + namespace: + description: |- + Namespace of the referent, defaults to the namespace of the Kubernetes + resource object that contains the reference. + maxLength: 63 + minLength: 1 + type: string + required: + - kind + - name + type: object + dependsOn: + description: |- + DependsOn may contain a meta.NamespacedObjectReference slice with + references to HelmRelease resources that must be ready before this HelmRelease + can be reconciled. + items: + description: |- + NamespacedObjectReference contains enough information to locate the referenced Kubernetes resource object in any + namespace. + properties: + name: + description: Name of the referent. + type: string + namespace: + description: Namespace of the referent, when not specified it + acts as LocalObjectReference. + type: string + required: + - name + type: object + type: array + driftDetection: + description: |- + DriftDetection holds the configuration for detecting and handling + differences between the manifest in the Helm storage and the resources + currently existing in the cluster. + + Note: this field is provisional to the v2beta2 API, and not actively used + by v2beta1 HelmReleases. + properties: + ignore: + description: |- + Ignore contains a list of rules for specifying which changes to ignore + during diffing. + items: + description: |- + IgnoreRule defines a rule to selectively disregard specific changes during + the drift detection process. + properties: + paths: + description: |- + Paths is a list of JSON Pointer (RFC 6901) paths to be excluded from + consideration in a Kubernetes object. + items: + type: string + type: array + target: + description: |- + Target is a selector for specifying Kubernetes objects to which this + rule applies. + If Target is not set, the Paths will be ignored for all Kubernetes + objects within the manifest of the Helm release. + properties: + annotationSelector: + description: |- + AnnotationSelector is a string that follows the label selection expression + https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#api + It matches with the resource annotations. + type: string + group: + description: |- + Group is the API group to select resources from. + Together with Version and Kind it is capable of unambiguously identifying and/or selecting resources. + https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md + type: string + kind: + description: |- + Kind of the API Group to select resources from. + Together with Group and Version it is capable of unambiguously + identifying and/or selecting resources. + https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md + type: string + labelSelector: + description: |- + LabelSelector is a string that follows the label selection expression + https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#api + It matches with the resource labels. + type: string + name: + description: Name to match resources with. + type: string + namespace: + description: Namespace to select resources from. + type: string + version: + description: |- + Version of the API Group to select resources from. + Together with Group and Kind it is capable of unambiguously identifying and/or selecting resources. + https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md + type: string + type: object + required: + - paths + type: object + type: array + mode: + description: |- + Mode defines how differences should be handled between the Helm manifest + and the manifest currently applied to the cluster. + If not explicitly set, it defaults to DiffModeDisabled. + enum: + - enabled + - warn + - disabled + type: string + type: object + install: + description: Install holds the configuration for Helm install actions + for this HelmRelease. + properties: + crds: + description: |- + CRDs upgrade CRDs from the Helm Chart's crds directory according + to the CRD upgrade policy provided here. Valid values are `Skip`, + `Create` or `CreateReplace`. Default is `Create` and if omitted + CRDs are installed but not updated. + + Skip: do neither install nor replace (update) any CRDs. + + Create: new CRDs are created, existing CRDs are neither updated nor deleted. + + CreateReplace: new CRDs are created, existing CRDs are updated (replaced) + but not deleted. + + By default, CRDs are applied (installed) during Helm install action. + With this option users can opt-in to CRD replace existing CRDs on Helm + install actions, which is not (yet) natively supported by Helm. + https://helm.sh/docs/chart_best_practices/custom_resource_definitions. + enum: + - Skip + - Create + - CreateReplace + type: string + createNamespace: + description: |- + CreateNamespace tells the Helm install action to create the + HelmReleaseSpec.TargetNamespace if it does not exist yet. + On uninstall, the namespace will not be garbage collected. + type: boolean + disableHooks: + description: DisableHooks prevents hooks from running during the + Helm install action. + type: boolean + disableOpenAPIValidation: + description: |- + DisableOpenAPIValidation prevents the Helm install action from validating + rendered templates against the Kubernetes OpenAPI Schema. + type: boolean + disableWait: + description: |- + DisableWait disables the waiting for resources to be ready after a Helm + install has been performed. + type: boolean + disableWaitForJobs: + description: |- + DisableWaitForJobs disables waiting for jobs to complete after a Helm + install has been performed. + type: boolean + remediation: + description: |- + Remediation holds the remediation configuration for when the Helm install + action for the HelmRelease fails. The default is to not perform any action. + properties: + ignoreTestFailures: + description: |- + IgnoreTestFailures tells the controller to skip remediation when the Helm + tests are run after an install action but fail. Defaults to + 'Test.IgnoreFailures'. + type: boolean + remediateLastFailure: + description: |- + RemediateLastFailure tells the controller to remediate the last failure, when + no retries remain. Defaults to 'false'. + type: boolean + retries: + description: |- + Retries is the number of retries that should be attempted on failures before + bailing. Remediation, using an uninstall, is performed between each attempt. + Defaults to '0', a negative integer equals to unlimited retries. + type: integer + type: object + replace: + description: |- + Replace tells the Helm install action to re-use the 'ReleaseName', but only + if that name is a deleted release which remains in the history. + type: boolean + skipCRDs: + description: |- + SkipCRDs tells the Helm install action to not install any CRDs. By default, + CRDs are installed if not already present. + + Deprecated use CRD policy (`crds`) attribute with value `Skip` instead. + type: boolean + timeout: + description: |- + Timeout is the time to wait for any individual Kubernetes operation (like + Jobs for hooks) during the performance of a Helm install action. Defaults to + 'HelmReleaseSpec.Timeout'. + pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ + type: string + type: object + interval: + description: |- + Interval at which to reconcile the Helm release. + This interval is approximate and may be subject to jitter to ensure + efficient use of resources. + pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ + type: string + kubeConfig: + description: |- + KubeConfig for reconciling the HelmRelease on a remote cluster. + When used in combination with HelmReleaseSpec.ServiceAccountName, + forces the controller to act on behalf of that Service Account at the + target cluster. + If the --default-service-account flag is set, its value will be used as + a controller level fallback for when HelmReleaseSpec.ServiceAccountName + is empty. + properties: + secretRef: + description: |- + SecretRef holds the name of a secret that contains a key with + the kubeconfig file as the value. If no key is set, the key will default + to 'value'. + It is recommended that the kubeconfig is self-contained, and the secret + is regularly updated if credentials such as a cloud-access-token expire. + Cloud specific `cmd-path` auth helpers will not function without adding + binaries and credentials to the Pod that is responsible for reconciling + Kubernetes resources. + properties: + key: + description: Key in the Secret, when not specified an implementation-specific + default key is used. + type: string + name: + description: Name of the Secret. + type: string + required: + - name + type: object + required: + - secretRef + type: object + maxHistory: + description: |- + MaxHistory is the number of revisions saved by Helm for this HelmRelease. + Use '0' for an unlimited number of revisions; defaults to '10'. + type: integer + persistentClient: + description: |- + PersistentClient tells the controller to use a persistent Kubernetes + client for this release. When enabled, the client will be reused for the + duration of the reconciliation, instead of being created and destroyed + for each (step of a) Helm action. + + This can improve performance, but may cause issues with some Helm charts + that for example do create Custom Resource Definitions during installation + outside Helm's CRD lifecycle hooks, which are then not observed to be + available by e.g. post-install hooks. + + If not set, it defaults to true. + type: boolean + postRenderers: + description: |- + PostRenderers holds an array of Helm PostRenderers, which will be applied in order + of their definition. + items: + description: PostRenderer contains a Helm PostRenderer specification. + properties: + kustomize: + description: Kustomization to apply as PostRenderer. + properties: + images: + description: |- + Images is a list of (image name, new name, new tag or digest) + for changing image names, tags or digests. This can also be achieved with a + patch, but this operator is simpler to specify. + items: + description: Image contains an image name, a new name, + a new tag or digest, which will replace the original + name and tag. + properties: + digest: + description: |- + Digest is the value used to replace the original image tag. + If digest is present NewTag value is ignored. + type: string + name: + description: Name is a tag-less image name. + type: string + newName: + description: NewName is the value used to replace + the original name. + type: string + newTag: + description: NewTag is the value used to replace the + original tag. + type: string + required: + - name + type: object + type: array + patches: + description: |- + Strategic merge and JSON patches, defined as inline YAML objects, + capable of targeting objects based on kind, label and annotation selectors. + items: + description: |- + Patch contains an inline StrategicMerge or JSON6902 patch, and the target the patch should + be applied to. + properties: + patch: + description: |- + Patch contains an inline StrategicMerge patch or an inline JSON6902 patch with + an array of operation objects. + type: string + target: + description: Target points to the resources that the + patch document should be applied to. + properties: + annotationSelector: + description: |- + AnnotationSelector is a string that follows the label selection expression + https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#api + It matches with the resource annotations. + type: string + group: + description: |- + Group is the API group to select resources from. + Together with Version and Kind it is capable of unambiguously identifying and/or selecting resources. + https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md + type: string + kind: + description: |- + Kind of the API Group to select resources from. + Together with Group and Version it is capable of unambiguously + identifying and/or selecting resources. + https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md + type: string + labelSelector: + description: |- + LabelSelector is a string that follows the label selection expression + https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#api + It matches with the resource labels. + type: string + name: + description: Name to match resources with. + type: string + namespace: + description: Namespace to select resources from. + type: string + version: + description: |- + Version of the API Group to select resources from. + Together with Group and Kind it is capable of unambiguously identifying and/or selecting resources. + https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md + type: string + type: object + required: + - patch + type: object + type: array + patchesJson6902: + description: JSON 6902 patches, defined as inline YAML objects. + items: + description: JSON6902Patch contains a JSON6902 patch and + the target the patch should be applied to. + properties: + patch: + description: Patch contains the JSON6902 patch document + with an array of operation objects. + items: + description: |- + JSON6902 is a JSON6902 operation object. + https://datatracker.ietf.org/doc/html/rfc6902#section-4 + properties: + from: + description: |- + From contains a JSON-pointer value that references a location within the target document where the operation is + performed. The meaning of the value depends on the value of Op, and is NOT taken into account by all operations. + type: string + op: + description: |- + Op indicates the operation to perform. Its value MUST be one of "add", "remove", "replace", "move", "copy", or + "test". + https://datatracker.ietf.org/doc/html/rfc6902#section-4 + enum: + - test + - remove + - add + - replace + - move + - copy + type: string + path: + description: |- + Path contains the JSON-pointer value that references a location within the target document where the operation + is performed. The meaning of the value depends on the value of Op. + type: string + value: + description: |- + Value contains a valid JSON structure. The meaning of the value depends on the value of Op, and is NOT taken into + account by all operations. + x-kubernetes-preserve-unknown-fields: true + required: + - op + - path + type: object + type: array + target: + description: Target points to the resources that the + patch document should be applied to. + properties: + annotationSelector: + description: |- + AnnotationSelector is a string that follows the label selection expression + https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#api + It matches with the resource annotations. + type: string + group: + description: |- + Group is the API group to select resources from. + Together with Version and Kind it is capable of unambiguously identifying and/or selecting resources. + https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md + type: string + kind: + description: |- + Kind of the API Group to select resources from. + Together with Group and Version it is capable of unambiguously + identifying and/or selecting resources. + https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md + type: string + labelSelector: + description: |- + LabelSelector is a string that follows the label selection expression + https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#api + It matches with the resource labels. + type: string + name: + description: Name to match resources with. + type: string + namespace: + description: Namespace to select resources from. + type: string + version: + description: |- + Version of the API Group to select resources from. + Together with Group and Kind it is capable of unambiguously identifying and/or selecting resources. + https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md + type: string + type: object + required: + - patch + - target + type: object + type: array + patchesStrategicMerge: + description: Strategic merge patches, defined as inline + YAML objects. + items: + x-kubernetes-preserve-unknown-fields: true + type: array + type: object + type: object + type: array + releaseName: + description: |- + ReleaseName used for the Helm release. Defaults to a composition of + '[TargetNamespace-]Name'. + maxLength: 53 + minLength: 1 + type: string + rollback: + description: Rollback holds the configuration for Helm rollback actions + for this HelmRelease. + properties: + cleanupOnFail: + description: |- + CleanupOnFail allows deletion of new resources created during the Helm + rollback action when it fails. + type: boolean + disableHooks: + description: DisableHooks prevents hooks from running during the + Helm rollback action. + type: boolean + disableWait: + description: |- + DisableWait disables the waiting for resources to be ready after a Helm + rollback has been performed. + type: boolean + disableWaitForJobs: + description: |- + DisableWaitForJobs disables waiting for jobs to complete after a Helm + rollback has been performed. + type: boolean + force: + description: Force forces resource updates through a replacement + strategy. + type: boolean + recreate: + description: Recreate performs pod restarts for the resource if + applicable. + type: boolean + timeout: + description: |- + Timeout is the time to wait for any individual Kubernetes operation (like + Jobs for hooks) during the performance of a Helm rollback action. Defaults to + 'HelmReleaseSpec.Timeout'. + pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ + type: string + type: object + serviceAccountName: + description: |- + The name of the Kubernetes service account to impersonate + when reconciling this HelmRelease. + type: string + storageNamespace: + description: |- + StorageNamespace used for the Helm storage. + Defaults to the namespace of the HelmRelease. + maxLength: 63 + minLength: 1 + type: string + suspend: + description: |- + Suspend tells the controller to suspend reconciliation for this HelmRelease, + it does not apply to already started reconciliations. Defaults to false. + type: boolean + targetNamespace: + description: |- + TargetNamespace to target when performing operations for the HelmRelease. + Defaults to the namespace of the HelmRelease. + maxLength: 63 + minLength: 1 + type: string + test: + description: Test holds the configuration for Helm test actions for + this HelmRelease. + properties: + enable: + description: |- + Enable enables Helm test actions for this HelmRelease after an Helm install + or upgrade action has been performed. + type: boolean + ignoreFailures: + description: |- + IgnoreFailures tells the controller to skip remediation when the Helm tests + are run but fail. Can be overwritten for tests run after install or upgrade + actions in 'Install.IgnoreTestFailures' and 'Upgrade.IgnoreTestFailures'. + type: boolean + timeout: + description: |- + Timeout is the time to wait for any individual Kubernetes operation during + the performance of a Helm test action. Defaults to 'HelmReleaseSpec.Timeout'. + pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ + type: string + type: object + timeout: + description: |- + Timeout is the time to wait for any individual Kubernetes operation (like Jobs + for hooks) during the performance of a Helm action. Defaults to '5m0s'. + pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ + type: string + uninstall: + description: Uninstall holds the configuration for Helm uninstall + actions for this HelmRelease. + properties: + deletionPropagation: + default: background + description: |- + DeletionPropagation specifies the deletion propagation policy when + a Helm uninstall is performed. + enum: + - background + - foreground + - orphan + type: string + disableHooks: + description: DisableHooks prevents hooks from running during the + Helm rollback action. + type: boolean + disableWait: + description: |- + DisableWait disables waiting for all the resources to be deleted after + a Helm uninstall is performed. + type: boolean + keepHistory: + description: |- + KeepHistory tells Helm to remove all associated resources and mark the + release as deleted, but retain the release history. + type: boolean + timeout: + description: |- + Timeout is the time to wait for any individual Kubernetes operation (like + Jobs for hooks) during the performance of a Helm uninstall action. Defaults + to 'HelmReleaseSpec.Timeout'. + pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ + type: string + type: object + upgrade: + description: Upgrade holds the configuration for Helm upgrade actions + for this HelmRelease. + properties: + cleanupOnFail: + description: |- + CleanupOnFail allows deletion of new resources created during the Helm + upgrade action when it fails. + type: boolean + crds: + description: |- + CRDs upgrade CRDs from the Helm Chart's crds directory according + to the CRD upgrade policy provided here. Valid values are `Skip`, + `Create` or `CreateReplace`. Default is `Skip` and if omitted + CRDs are neither installed nor upgraded. + + Skip: do neither install nor replace (update) any CRDs. + + Create: new CRDs are created, existing CRDs are neither updated nor deleted. + + CreateReplace: new CRDs are created, existing CRDs are updated (replaced) + but not deleted. + + By default, CRDs are not applied during Helm upgrade action. With this + option users can opt-in to CRD upgrade, which is not (yet) natively supported by Helm. + https://helm.sh/docs/chart_best_practices/custom_resource_definitions. + enum: + - Skip + - Create + - CreateReplace + type: string + disableHooks: + description: DisableHooks prevents hooks from running during the + Helm upgrade action. + type: boolean + disableOpenAPIValidation: + description: |- + DisableOpenAPIValidation prevents the Helm upgrade action from validating + rendered templates against the Kubernetes OpenAPI Schema. + type: boolean + disableWait: + description: |- + DisableWait disables the waiting for resources to be ready after a Helm + upgrade has been performed. + type: boolean + disableWaitForJobs: + description: |- + DisableWaitForJobs disables waiting for jobs to complete after a Helm + upgrade has been performed. + type: boolean + force: + description: Force forces resource updates through a replacement + strategy. + type: boolean + preserveValues: + description: |- + PreserveValues will make Helm reuse the last release's values and merge in + overrides from 'Values'. Setting this flag makes the HelmRelease + non-declarative. + type: boolean + remediation: + description: |- + Remediation holds the remediation configuration for when the Helm upgrade + action for the HelmRelease fails. The default is to not perform any action. + properties: + ignoreTestFailures: + description: |- + IgnoreTestFailures tells the controller to skip remediation when the Helm + tests are run after an upgrade action but fail. + Defaults to 'Test.IgnoreFailures'. + type: boolean + remediateLastFailure: + description: |- + RemediateLastFailure tells the controller to remediate the last failure, when + no retries remain. Defaults to 'false' unless 'Retries' is greater than 0. + type: boolean + retries: + description: |- + Retries is the number of retries that should be attempted on failures before + bailing. Remediation, using 'Strategy', is performed between each attempt. + Defaults to '0', a negative integer equals to unlimited retries. + type: integer + strategy: + description: Strategy to use for failure remediation. Defaults + to 'rollback'. + enum: + - rollback + - uninstall + type: string + type: object + timeout: + description: |- + Timeout is the time to wait for any individual Kubernetes operation (like + Jobs for hooks) during the performance of a Helm upgrade action. Defaults to + 'HelmReleaseSpec.Timeout'. + pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ + type: string + type: object + values: + description: Values holds the values for this Helm release. + x-kubernetes-preserve-unknown-fields: true + valuesFrom: + description: |- + ValuesFrom holds references to resources containing Helm values for this HelmRelease, + and information about how they should be merged. + items: + description: |- + ValuesReference contains a reference to a resource containing Helm values, + and optionally the key they can be found at. + properties: + kind: + description: Kind of the values referent, valid values are ('Secret', + 'ConfigMap'). + enum: + - Secret + - ConfigMap + type: string + name: + description: |- + Name of the values referent. Should reside in the same namespace as the + referring resource. + maxLength: 253 + minLength: 1 + type: string + optional: + description: |- + Optional marks this ValuesReference as optional. When set, a not found error + for the values reference is ignored, but any ValuesKey, TargetPath or + transient error will still result in a reconciliation failure. + type: boolean + targetPath: + description: |- + TargetPath is the YAML dot notation path the value should be merged at. When + set, the ValuesKey is expected to be a single flat value. Defaults to 'None', + which results in the values getting merged at the root. + maxLength: 250 + pattern: ^([a-zA-Z0-9_\-.\\\/]|\[[0-9]{1,5}\])+$ + type: string + valuesKey: + description: |- + ValuesKey is the data key where the values.yaml or a specific value can be + found at. Defaults to 'values.yaml'. + When set, must be a valid Data Key, consisting of alphanumeric characters, + '-', '_' or '.'. + maxLength: 253 + pattern: ^[\-._a-zA-Z0-9]+$ + type: string + required: + - kind + - name + type: object + type: array + required: + - chart + - interval + type: object + status: + default: + observedGeneration: -1 + description: HelmReleaseStatus defines the observed state of a HelmRelease. + properties: + conditions: + description: Conditions holds the conditions for the HelmRelease. + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + failures: + description: |- + Failures is the reconciliation failure count against the latest desired + state. It is reset after a successful reconciliation. + format: int64 + type: integer + helmChart: + description: |- + HelmChart is the namespaced name of the HelmChart resource created by + the controller for the HelmRelease. + type: string + history: + description: |- + History holds the history of Helm releases performed for this HelmRelease + up to the last successfully completed release. + + Note: this field is provisional to the v2beta2 API, and not actively used + by v2beta1 HelmReleases. + items: + description: |- + Snapshot captures a point-in-time copy of the status information for a Helm release, + as managed by the controller. + properties: + apiVersion: + description: |- + APIVersion is the API version of the Snapshot. + Provisional: when the calculation method of the Digest field is changed, + this field will be used to distinguish between the old and new methods. + type: string + appVersion: + description: AppVersion is the chart app version of the release + object in storage. + type: string + chartName: + description: ChartName is the chart name of the release object + in storage. + type: string + chartVersion: + description: |- + ChartVersion is the chart version of the release object in + storage. + type: string + configDigest: + description: |- + ConfigDigest is the checksum of the config (better known as + "values") of the release object in storage. + It has the format of `<algo>:<checksum>`. + type: string + deleted: + description: Deleted is when the release was deleted. + format: date-time + type: string + digest: + description: |- + Digest is the checksum of the release object in storage. + It has the format of `<algo>:<checksum>`. + type: string + firstDeployed: + description: FirstDeployed is when the release was first deployed. + format: date-time + type: string + lastDeployed: + description: LastDeployed is when the release was last deployed. + format: date-time + type: string + name: + description: Name is the name of the release. + type: string + namespace: + description: Namespace is the namespace the release is deployed + to. + type: string + ociDigest: + description: OCIDigest is the digest of the OCI artifact associated + with the release. + type: string + status: + description: Status is the current state of the release. + type: string + testHooks: + additionalProperties: + description: |- + TestHookStatus holds the status information for a test hook as observed + to be run by the controller. + properties: + lastCompleted: + description: LastCompleted is the time the test hook last + completed. + format: date-time + type: string + lastStarted: + description: LastStarted is the time the test hook was + last started. + format: date-time + type: string + phase: + description: Phase the test hook was observed to be in. + type: string + type: object + description: |- + TestHooks is the list of test hooks for the release as observed to be + run by the controller. + type: object + version: + description: Version is the version of the release object in + storage. + type: integer + required: + - chartName + - chartVersion + - configDigest + - digest + - firstDeployed + - lastDeployed + - name + - namespace + - status + - version + type: object + type: array + installFailures: + description: |- + InstallFailures is the install failure count against the latest desired + state. It is reset after a successful reconciliation. + format: int64 + type: integer + lastAppliedRevision: + description: LastAppliedRevision is the revision of the last successfully + applied source. + type: string + lastAttemptedConfigDigest: + description: |- + LastAttemptedConfigDigest is the digest for the config (better known as + "values") of the last reconciliation attempt. + + Note: this field is provisional to the v2beta2 API, and not actively used + by v2beta1 HelmReleases. + type: string + lastAttemptedGeneration: + description: |- + LastAttemptedGeneration is the last generation the controller attempted + to reconcile. + + Note: this field is provisional to the v2beta2 API, and not actively used + by v2beta1 HelmReleases. + format: int64 + type: integer + lastAttemptedReleaseAction: + description: |- + LastAttemptedReleaseAction is the last release action performed for this + HelmRelease. It is used to determine the active remediation strategy. + + Note: this field is provisional to the v2beta2 API, and not actively used + by v2beta1 HelmReleases. + type: string + lastAttemptedRevision: + description: LastAttemptedRevision is the revision of the last reconciliation + attempt. + type: string + lastAttemptedValuesChecksum: + description: |- + LastAttemptedValuesChecksum is the SHA1 checksum of the values of the last + reconciliation attempt. + type: string + lastHandledForceAt: + description: |- + LastHandledForceAt holds the value of the most recent force request + value, so a change of the annotation value can be detected. + + Note: this field is provisional to the v2beta2 API, and not actively used + by v2beta1 HelmReleases. + type: string + lastHandledReconcileAt: + description: |- + LastHandledReconcileAt holds the value of the most recent + reconcile request value, so a change of the annotation value + can be detected. + type: string + lastHandledResetAt: + description: |- + LastHandledResetAt holds the value of the most recent reset request + value, so a change of the annotation value can be detected. + + Note: this field is provisional to the v2beta2 API, and not actively used + by v2beta1 HelmReleases. + type: string + lastReleaseRevision: + description: LastReleaseRevision is the revision of the last successful + Helm release. + type: integer + observedGeneration: + description: ObservedGeneration is the last observed generation. + format: int64 + type: integer + observedPostRenderersDigest: + description: |- + ObservedPostRenderersDigest is the digest for the post-renderers of + the last successful reconciliation attempt. + type: string + storageNamespace: + description: |- + StorageNamespace is the namespace of the Helm release storage for the + current release. + + Note: this field is provisional to the v2beta2 API, and not actively used + by v2beta1 HelmReleases. + type: string + upgradeFailures: + description: |- + UpgradeFailures is the upgrade failure count against the latest desired + state. It is reset after a successful reconciliation. + format: int64 + type: integer + type: object + type: object + served: true + storage: false + subresources: + status: {} + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + - jsonPath: .status.conditions[?(@.type=="Ready")].status + name: Ready + type: string + - jsonPath: .status.conditions[?(@.type=="Ready")].message + name: Status + type: string + deprecated: true + deprecationWarning: v2beta2 HelmRelease is deprecated, upgrade to v2 + name: v2beta2 + schema: + openAPIV3Schema: + description: HelmRelease is the Schema for the helmreleases API + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: HelmReleaseSpec defines the desired state of a Helm release. + properties: + chart: + description: |- + Chart defines the template of the v1beta2.HelmChart that should be created + for this HelmRelease. + properties: + metadata: + description: ObjectMeta holds the template for metadata like labels + and annotations. + properties: + annotations: + additionalProperties: + type: string + description: |- + Annotations is an unstructured key value map stored with a resource that may be + set by external tools to store and retrieve arbitrary metadata. They are not + queryable and should be preserved when modifying objects. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/ + type: object + labels: + additionalProperties: + type: string + description: |- + Map of string keys and values that can be used to organize and categorize + (scope and select) objects. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ + type: object + type: object + spec: + description: Spec holds the template for the v1beta2.HelmChartSpec + for this HelmRelease. + properties: + chart: + description: The name or path the Helm chart is available + at in the SourceRef. + maxLength: 2048 + minLength: 1 + type: string + ignoreMissingValuesFiles: + description: IgnoreMissingValuesFiles controls whether to + silently ignore missing values files rather than failing. + type: boolean + interval: + description: |- + Interval at which to check the v1.Source for updates. Defaults to + 'HelmReleaseSpec.Interval'. + pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ + type: string + reconcileStrategy: + default: ChartVersion + description: |- + Determines what enables the creation of a new artifact. Valid values are + ('ChartVersion', 'Revision'). + See the documentation of the values for an explanation on their behavior. + Defaults to ChartVersion when omitted. + enum: + - ChartVersion + - Revision + type: string + sourceRef: + description: The name and namespace of the v1.Source the chart + is available at. + properties: + apiVersion: + description: APIVersion of the referent. + type: string + kind: + description: Kind of the referent. + enum: + - HelmRepository + - GitRepository + - Bucket + type: string + name: + description: Name of the referent. + maxLength: 253 + minLength: 1 + type: string + namespace: + description: Namespace of the referent. + maxLength: 63 + minLength: 1 + type: string + required: + - kind + - name + type: object + valuesFile: + description: |- + Alternative values file to use as the default chart values, expected to + be a relative path in the SourceRef. Deprecated in favor of ValuesFiles, + for backwards compatibility the file defined here is merged before the + ValuesFiles items. Ignored when omitted. + type: string + valuesFiles: + description: |- + Alternative list of values files to use as the chart values (values.yaml + is not included by default), expected to be a relative path in the SourceRef. + Values files are merged in the order of this list with the last file overriding + the first. Ignored when omitted. + items: + type: string + type: array + verify: + description: |- + Verify contains the secret name containing the trusted public keys + used to verify the signature and specifies which provider to use to check + whether OCI image is authentic. + This field is only supported for OCI sources. + Chart dependencies, which are not bundled in the umbrella chart artifact, + are not verified. + properties: + provider: + default: cosign + description: Provider specifies the technology used to + sign the OCI Helm chart. + enum: + - cosign + - notation + type: string + secretRef: + description: |- + SecretRef specifies the Kubernetes Secret containing the + trusted public keys. + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + required: + - provider + type: object + version: + default: '*' + description: |- + Version semver expression, ignored for charts from v1beta2.GitRepository and + v1beta2.Bucket sources. Defaults to latest when omitted. + type: string + required: + - chart + - sourceRef + type: object + required: + - spec + type: object + chartRef: + description: |- + ChartRef holds a reference to a source controller resource containing the + Helm chart artifact. + + Note: this field is provisional to the v2 API, and not actively used + by v2beta2 HelmReleases. + properties: + apiVersion: + description: APIVersion of the referent. + type: string + kind: + description: Kind of the referent. + enum: + - OCIRepository + - HelmChart + type: string + name: + description: Name of the referent. + maxLength: 253 + minLength: 1 + type: string + namespace: + description: |- + Namespace of the referent, defaults to the namespace of the Kubernetes + resource object that contains the reference. + maxLength: 63 + minLength: 1 + type: string + required: + - kind + - name + type: object + dependsOn: + description: |- + DependsOn may contain a meta.NamespacedObjectReference slice with + references to HelmRelease resources that must be ready before this HelmRelease + can be reconciled. + items: + description: |- + NamespacedObjectReference contains enough information to locate the referenced Kubernetes resource object in any + namespace. + properties: + name: + description: Name of the referent. + type: string + namespace: + description: Namespace of the referent, when not specified it + acts as LocalObjectReference. + type: string + required: + - name + type: object + type: array + driftDetection: + description: |- + DriftDetection holds the configuration for detecting and handling + differences between the manifest in the Helm storage and the resources + currently existing in the cluster. + properties: + ignore: + description: |- + Ignore contains a list of rules for specifying which changes to ignore + during diffing. + items: + description: |- + IgnoreRule defines a rule to selectively disregard specific changes during + the drift detection process. + properties: + paths: + description: |- + Paths is a list of JSON Pointer (RFC 6901) paths to be excluded from + consideration in a Kubernetes object. + items: + type: string + type: array + target: + description: |- + Target is a selector for specifying Kubernetes objects to which this + rule applies. + If Target is not set, the Paths will be ignored for all Kubernetes + objects within the manifest of the Helm release. + properties: + annotationSelector: + description: |- + AnnotationSelector is a string that follows the label selection expression + https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#api + It matches with the resource annotations. + type: string + group: + description: |- + Group is the API group to select resources from. + Together with Version and Kind it is capable of unambiguously identifying and/or selecting resources. + https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md + type: string + kind: + description: |- + Kind of the API Group to select resources from. + Together with Group and Version it is capable of unambiguously + identifying and/or selecting resources. + https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md + type: string + labelSelector: + description: |- + LabelSelector is a string that follows the label selection expression + https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#api + It matches with the resource labels. + type: string + name: + description: Name to match resources with. + type: string + namespace: + description: Namespace to select resources from. + type: string + version: + description: |- + Version of the API Group to select resources from. + Together with Group and Kind it is capable of unambiguously identifying and/or selecting resources. + https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md + type: string + type: object + required: + - paths + type: object + type: array + mode: + description: |- + Mode defines how differences should be handled between the Helm manifest + and the manifest currently applied to the cluster. + If not explicitly set, it defaults to DiffModeDisabled. + enum: + - enabled + - warn + - disabled + type: string + type: object + install: + description: Install holds the configuration for Helm install actions + for this HelmRelease. + properties: + crds: + description: |- + CRDs upgrade CRDs from the Helm Chart's crds directory according + to the CRD upgrade policy provided here. Valid values are `Skip`, + `Create` or `CreateReplace`. Default is `Create` and if omitted + CRDs are installed but not updated. + + Skip: do neither install nor replace (update) any CRDs. + + Create: new CRDs are created, existing CRDs are neither updated nor deleted. + + CreateReplace: new CRDs are created, existing CRDs are updated (replaced) + but not deleted. + + By default, CRDs are applied (installed) during Helm install action. + With this option users can opt in to CRD replace existing CRDs on Helm + install actions, which is not (yet) natively supported by Helm. + https://helm.sh/docs/chart_best_practices/custom_resource_definitions. + enum: + - Skip + - Create + - CreateReplace + type: string + createNamespace: + description: |- + CreateNamespace tells the Helm install action to create the + HelmReleaseSpec.TargetNamespace if it does not exist yet. + On uninstall, the namespace will not be garbage collected. + type: boolean + disableHooks: + description: DisableHooks prevents hooks from running during the + Helm install action. + type: boolean + disableOpenAPIValidation: + description: |- + DisableOpenAPIValidation prevents the Helm install action from validating + rendered templates against the Kubernetes OpenAPI Schema. + type: boolean + disableWait: + description: |- + DisableWait disables the waiting for resources to be ready after a Helm + install has been performed. + type: boolean + disableWaitForJobs: + description: |- + DisableWaitForJobs disables waiting for jobs to complete after a Helm + install has been performed. + type: boolean + remediation: + description: |- + Remediation holds the remediation configuration for when the Helm install + action for the HelmRelease fails. The default is to not perform any action. + properties: + ignoreTestFailures: + description: |- + IgnoreTestFailures tells the controller to skip remediation when the Helm + tests are run after an install action but fail. Defaults to + 'Test.IgnoreFailures'. + type: boolean + remediateLastFailure: + description: |- + RemediateLastFailure tells the controller to remediate the last failure, when + no retries remain. Defaults to 'false'. + type: boolean + retries: + description: |- + Retries is the number of retries that should be attempted on failures before + bailing. Remediation, using an uninstall, is performed between each attempt. + Defaults to '0', a negative integer equals to unlimited retries. + type: integer + type: object + replace: + description: |- + Replace tells the Helm install action to re-use the 'ReleaseName', but only + if that name is a deleted release which remains in the history. + type: boolean + skipCRDs: + description: |- + SkipCRDs tells the Helm install action to not install any CRDs. By default, + CRDs are installed if not already present. + + Deprecated use CRD policy (`crds`) attribute with value `Skip` instead. + type: boolean + timeout: + description: |- + Timeout is the time to wait for any individual Kubernetes operation (like + Jobs for hooks) during the performance of a Helm install action. Defaults to + 'HelmReleaseSpec.Timeout'. + pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ + type: string + type: object + interval: + description: Interval at which to reconcile the Helm release. + pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ + type: string + kubeConfig: + description: |- + KubeConfig for reconciling the HelmRelease on a remote cluster. + When used in combination with HelmReleaseSpec.ServiceAccountName, + forces the controller to act on behalf of that Service Account at the + target cluster. + If the --default-service-account flag is set, its value will be used as + a controller level fallback for when HelmReleaseSpec.ServiceAccountName + is empty. + properties: + secretRef: + description: |- + SecretRef holds the name of a secret that contains a key with + the kubeconfig file as the value. If no key is set, the key will default + to 'value'. + It is recommended that the kubeconfig is self-contained, and the secret + is regularly updated if credentials such as a cloud-access-token expire. + Cloud specific `cmd-path` auth helpers will not function without adding + binaries and credentials to the Pod that is responsible for reconciling + Kubernetes resources. + properties: + key: + description: Key in the Secret, when not specified an implementation-specific + default key is used. + type: string + name: + description: Name of the Secret. + type: string + required: + - name + type: object + required: + - secretRef + type: object + maxHistory: + description: |- + MaxHistory is the number of revisions saved by Helm for this HelmRelease. + Use '0' for an unlimited number of revisions; defaults to '5'. + type: integer + persistentClient: + description: |- + PersistentClient tells the controller to use a persistent Kubernetes + client for this release. When enabled, the client will be reused for the + duration of the reconciliation, instead of being created and destroyed + for each (step of a) Helm action. + + This can improve performance, but may cause issues with some Helm charts + that for example do create Custom Resource Definitions during installation + outside Helm's CRD lifecycle hooks, which are then not observed to be + available by e.g. post-install hooks. + + If not set, it defaults to true. + type: boolean + postRenderers: + description: |- + PostRenderers holds an array of Helm PostRenderers, which will be applied in order + of their definition. + items: + description: PostRenderer contains a Helm PostRenderer specification. + properties: + kustomize: + description: Kustomization to apply as PostRenderer. + properties: + images: + description: |- + Images is a list of (image name, new name, new tag or digest) + for changing image names, tags or digests. This can also be achieved with a + patch, but this operator is simpler to specify. + items: + description: Image contains an image name, a new name, + a new tag or digest, which will replace the original + name and tag. + properties: + digest: + description: |- + Digest is the value used to replace the original image tag. + If digest is present NewTag value is ignored. + type: string + name: + description: Name is a tag-less image name. + type: string + newName: + description: NewName is the value used to replace + the original name. + type: string + newTag: + description: NewTag is the value used to replace the + original tag. + type: string + required: + - name + type: object + type: array + patches: + description: |- + Strategic merge and JSON patches, defined as inline YAML objects, + capable of targeting objects based on kind, label and annotation selectors. + items: + description: |- + Patch contains an inline StrategicMerge or JSON6902 patch, and the target the patch should + be applied to. + properties: + patch: + description: |- + Patch contains an inline StrategicMerge patch or an inline JSON6902 patch with + an array of operation objects. + type: string + target: + description: Target points to the resources that the + patch document should be applied to. + properties: + annotationSelector: + description: |- + AnnotationSelector is a string that follows the label selection expression + https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#api + It matches with the resource annotations. + type: string + group: + description: |- + Group is the API group to select resources from. + Together with Version and Kind it is capable of unambiguously identifying and/or selecting resources. + https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md + type: string + kind: + description: |- + Kind of the API Group to select resources from. + Together with Group and Version it is capable of unambiguously + identifying and/or selecting resources. + https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md + type: string + labelSelector: + description: |- + LabelSelector is a string that follows the label selection expression + https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#api + It matches with the resource labels. + type: string + name: + description: Name to match resources with. + type: string + namespace: + description: Namespace to select resources from. + type: string + version: + description: |- + Version of the API Group to select resources from. + Together with Group and Kind it is capable of unambiguously identifying and/or selecting resources. + https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md + type: string + type: object + required: + - patch + type: object + type: array + patchesJson6902: + description: |- + JSON 6902 patches, defined as inline YAML objects. + Deprecated: use Patches instead. + items: + description: JSON6902Patch contains a JSON6902 patch and + the target the patch should be applied to. + properties: + patch: + description: Patch contains the JSON6902 patch document + with an array of operation objects. + items: + description: |- + JSON6902 is a JSON6902 operation object. + https://datatracker.ietf.org/doc/html/rfc6902#section-4 + properties: + from: + description: |- + From contains a JSON-pointer value that references a location within the target document where the operation is + performed. The meaning of the value depends on the value of Op, and is NOT taken into account by all operations. + type: string + op: + description: |- + Op indicates the operation to perform. Its value MUST be one of "add", "remove", "replace", "move", "copy", or + "test". + https://datatracker.ietf.org/doc/html/rfc6902#section-4 + enum: + - test + - remove + - add + - replace + - move + - copy + type: string + path: + description: |- + Path contains the JSON-pointer value that references a location within the target document where the operation + is performed. The meaning of the value depends on the value of Op. + type: string + value: + description: |- + Value contains a valid JSON structure. The meaning of the value depends on the value of Op, and is NOT taken into + account by all operations. + x-kubernetes-preserve-unknown-fields: true + required: + - op + - path + type: object + type: array + target: + description: Target points to the resources that the + patch document should be applied to. + properties: + annotationSelector: + description: |- + AnnotationSelector is a string that follows the label selection expression + https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#api + It matches with the resource annotations. + type: string + group: + description: |- + Group is the API group to select resources from. + Together with Version and Kind it is capable of unambiguously identifying and/or selecting resources. + https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md + type: string + kind: + description: |- + Kind of the API Group to select resources from. + Together with Group and Version it is capable of unambiguously + identifying and/or selecting resources. + https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md + type: string + labelSelector: + description: |- + LabelSelector is a string that follows the label selection expression + https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#api + It matches with the resource labels. + type: string + name: + description: Name to match resources with. + type: string + namespace: + description: Namespace to select resources from. + type: string + version: + description: |- + Version of the API Group to select resources from. + Together with Group and Kind it is capable of unambiguously identifying and/or selecting resources. + https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md + type: string + type: object + required: + - patch + - target + type: object + type: array + patchesStrategicMerge: + description: |- + Strategic merge patches, defined as inline YAML objects. + Deprecated: use Patches instead. + items: + x-kubernetes-preserve-unknown-fields: true + type: array + type: object + type: object + type: array + releaseName: + description: |- + ReleaseName used for the Helm release. Defaults to a composition of + '[TargetNamespace-]Name'. + maxLength: 53 + minLength: 1 + type: string + rollback: + description: Rollback holds the configuration for Helm rollback actions + for this HelmRelease. + properties: + cleanupOnFail: + description: |- + CleanupOnFail allows deletion of new resources created during the Helm + rollback action when it fails. + type: boolean + disableHooks: + description: DisableHooks prevents hooks from running during the + Helm rollback action. + type: boolean + disableWait: + description: |- + DisableWait disables the waiting for resources to be ready after a Helm + rollback has been performed. + type: boolean + disableWaitForJobs: + description: |- + DisableWaitForJobs disables waiting for jobs to complete after a Helm + rollback has been performed. + type: boolean + force: + description: Force forces resource updates through a replacement + strategy. + type: boolean + recreate: + description: Recreate performs pod restarts for the resource if + applicable. + type: boolean + timeout: + description: |- + Timeout is the time to wait for any individual Kubernetes operation (like + Jobs for hooks) during the performance of a Helm rollback action. Defaults to + 'HelmReleaseSpec.Timeout'. + pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ + type: string + type: object + serviceAccountName: + description: |- + The name of the Kubernetes service account to impersonate + when reconciling this HelmRelease. + maxLength: 253 + minLength: 1 + type: string + storageNamespace: + description: |- + StorageNamespace used for the Helm storage. + Defaults to the namespace of the HelmRelease. + maxLength: 63 + minLength: 1 + type: string + suspend: + description: |- + Suspend tells the controller to suspend reconciliation for this HelmRelease, + it does not apply to already started reconciliations. Defaults to false. + type: boolean + targetNamespace: + description: |- + TargetNamespace to target when performing operations for the HelmRelease. + Defaults to the namespace of the HelmRelease. + maxLength: 63 + minLength: 1 + type: string + test: + description: Test holds the configuration for Helm test actions for + this HelmRelease. + properties: + enable: + description: |- + Enable enables Helm test actions for this HelmRelease after an Helm install + or upgrade action has been performed. + type: boolean + filters: + description: Filters is a list of tests to run or exclude from + running. + items: + description: Filter holds the configuration for individual Helm + test filters. + properties: + exclude: + description: Exclude specifies whether the named test should + be excluded. + type: boolean + name: + description: Name is the name of the test. + maxLength: 253 + minLength: 1 + type: string + required: + - name + type: object + type: array + ignoreFailures: + description: |- + IgnoreFailures tells the controller to skip remediation when the Helm tests + are run but fail. Can be overwritten for tests run after install or upgrade + actions in 'Install.IgnoreTestFailures' and 'Upgrade.IgnoreTestFailures'. + type: boolean + timeout: + description: |- + Timeout is the time to wait for any individual Kubernetes operation during + the performance of a Helm test action. Defaults to 'HelmReleaseSpec.Timeout'. + pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ + type: string + type: object + timeout: + description: |- + Timeout is the time to wait for any individual Kubernetes operation (like Jobs + for hooks) during the performance of a Helm action. Defaults to '5m0s'. + pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ + type: string + uninstall: + description: Uninstall holds the configuration for Helm uninstall + actions for this HelmRelease. + properties: + deletionPropagation: + default: background + description: |- + DeletionPropagation specifies the deletion propagation policy when + a Helm uninstall is performed. + enum: + - background + - foreground + - orphan + type: string + disableHooks: + description: DisableHooks prevents hooks from running during the + Helm rollback action. + type: boolean + disableWait: + description: |- + DisableWait disables waiting for all the resources to be deleted after + a Helm uninstall is performed. + type: boolean + keepHistory: + description: |- + KeepHistory tells Helm to remove all associated resources and mark the + release as deleted, but retain the release history. + type: boolean + timeout: + description: |- + Timeout is the time to wait for any individual Kubernetes operation (like + Jobs for hooks) during the performance of a Helm uninstall action. Defaults + to 'HelmReleaseSpec.Timeout'. + pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ + type: string + type: object + upgrade: + description: Upgrade holds the configuration for Helm upgrade actions + for this HelmRelease. + properties: + cleanupOnFail: + description: |- + CleanupOnFail allows deletion of new resources created during the Helm + upgrade action when it fails. + type: boolean + crds: + description: |- + CRDs upgrade CRDs from the Helm Chart's crds directory according + to the CRD upgrade policy provided here. Valid values are `Skip`, + `Create` or `CreateReplace`. Default is `Skip` and if omitted + CRDs are neither installed nor upgraded. + + Skip: do neither install nor replace (update) any CRDs. + + Create: new CRDs are created, existing CRDs are neither updated nor deleted. + + CreateReplace: new CRDs are created, existing CRDs are updated (replaced) + but not deleted. + + By default, CRDs are not applied during Helm upgrade action. With this + option users can opt-in to CRD upgrade, which is not (yet) natively supported by Helm. + https://helm.sh/docs/chart_best_practices/custom_resource_definitions. + enum: + - Skip + - Create + - CreateReplace + type: string + disableHooks: + description: DisableHooks prevents hooks from running during the + Helm upgrade action. + type: boolean + disableOpenAPIValidation: + description: |- + DisableOpenAPIValidation prevents the Helm upgrade action from validating + rendered templates against the Kubernetes OpenAPI Schema. + type: boolean + disableWait: + description: |- + DisableWait disables the waiting for resources to be ready after a Helm + upgrade has been performed. + type: boolean + disableWaitForJobs: + description: |- + DisableWaitForJobs disables waiting for jobs to complete after a Helm + upgrade has been performed. + type: boolean + force: + description: Force forces resource updates through a replacement + strategy. + type: boolean + preserveValues: + description: |- + PreserveValues will make Helm reuse the last release's values and merge in + overrides from 'Values'. Setting this flag makes the HelmRelease + non-declarative. + type: boolean + remediation: + description: |- + Remediation holds the remediation configuration for when the Helm upgrade + action for the HelmRelease fails. The default is to not perform any action. + properties: + ignoreTestFailures: + description: |- + IgnoreTestFailures tells the controller to skip remediation when the Helm + tests are run after an upgrade action but fail. + Defaults to 'Test.IgnoreFailures'. + type: boolean + remediateLastFailure: + description: |- + RemediateLastFailure tells the controller to remediate the last failure, when + no retries remain. Defaults to 'false' unless 'Retries' is greater than 0. + type: boolean + retries: + description: |- + Retries is the number of retries that should be attempted on failures before + bailing. Remediation, using 'Strategy', is performed between each attempt. + Defaults to '0', a negative integer equals to unlimited retries. + type: integer + strategy: + description: Strategy to use for failure remediation. Defaults + to 'rollback'. + enum: + - rollback + - uninstall + type: string + type: object + timeout: + description: |- + Timeout is the time to wait for any individual Kubernetes operation (like + Jobs for hooks) during the performance of a Helm upgrade action. Defaults to + 'HelmReleaseSpec.Timeout'. + pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ + type: string + type: object + values: + description: Values holds the values for this Helm release. + x-kubernetes-preserve-unknown-fields: true + valuesFrom: + description: |- + ValuesFrom holds references to resources containing Helm values for this HelmRelease, + and information about how they should be merged. + items: + description: |- + ValuesReference contains a reference to a resource containing Helm values, + and optionally the key they can be found at. + properties: + kind: + description: Kind of the values referent, valid values are ('Secret', + 'ConfigMap'). + enum: + - Secret + - ConfigMap + type: string + name: + description: |- + Name of the values referent. Should reside in the same namespace as the + referring resource. + maxLength: 253 + minLength: 1 + type: string + optional: + description: |- + Optional marks this ValuesReference as optional. When set, a not found error + for the values reference is ignored, but any ValuesKey, TargetPath or + transient error will still result in a reconciliation failure. + type: boolean + targetPath: + description: |- + TargetPath is the YAML dot notation path the value should be merged at. When + set, the ValuesKey is expected to be a single flat value. Defaults to 'None', + which results in the values getting merged at the root. + maxLength: 250 + pattern: ^([a-zA-Z0-9_\-.\\\/]|\[[0-9]{1,5}\])+$ + type: string + valuesKey: + description: |- + ValuesKey is the data key where the values.yaml or a specific value can be + found at. Defaults to 'values.yaml'. + maxLength: 253 + pattern: ^[\-._a-zA-Z0-9]+$ + type: string + required: + - kind + - name + type: object + type: array + required: + - interval + type: object + x-kubernetes-validations: + - message: either chart or chartRef must be set + rule: (has(self.chart) && !has(self.chartRef)) || (!has(self.chart) + && has(self.chartRef)) + status: + default: + observedGeneration: -1 + description: HelmReleaseStatus defines the observed state of a HelmRelease. + properties: + conditions: + description: Conditions holds the conditions for the HelmRelease. + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + failures: + description: |- + Failures is the reconciliation failure count against the latest desired + state. It is reset after a successful reconciliation. + format: int64 + type: integer + helmChart: + description: |- + HelmChart is the namespaced name of the HelmChart resource created by + the controller for the HelmRelease. + type: string + history: + description: |- + History holds the history of Helm releases performed for this HelmRelease + up to the last successfully completed release. + items: + description: |- + Snapshot captures a point-in-time copy of the status information for a Helm release, + as managed by the controller. + properties: + apiVersion: + description: |- + APIVersion is the API version of the Snapshot. + Provisional: when the calculation method of the Digest field is changed, + this field will be used to distinguish between the old and new methods. + type: string + appVersion: + description: AppVersion is the chart app version of the release + object in storage. + type: string + chartName: + description: ChartName is the chart name of the release object + in storage. + type: string + chartVersion: + description: |- + ChartVersion is the chart version of the release object in + storage. + type: string + configDigest: + description: |- + ConfigDigest is the checksum of the config (better known as + "values") of the release object in storage. + It has the format of `<algo>:<checksum>`. + type: string + deleted: + description: Deleted is when the release was deleted. + format: date-time + type: string + digest: + description: |- + Digest is the checksum of the release object in storage. + It has the format of `<algo>:<checksum>`. + type: string + firstDeployed: + description: FirstDeployed is when the release was first deployed. + format: date-time + type: string + lastDeployed: + description: LastDeployed is when the release was last deployed. + format: date-time + type: string + name: + description: Name is the name of the release. + type: string + namespace: + description: Namespace is the namespace the release is deployed + to. + type: string + ociDigest: + description: OCIDigest is the digest of the OCI artifact associated + with the release. + type: string + status: + description: Status is the current state of the release. + type: string + testHooks: + additionalProperties: + description: |- + TestHookStatus holds the status information for a test hook as observed + to be run by the controller. + properties: + lastCompleted: + description: LastCompleted is the time the test hook last + completed. + format: date-time + type: string + lastStarted: + description: LastStarted is the time the test hook was + last started. + format: date-time + type: string + phase: + description: Phase the test hook was observed to be in. + type: string + type: object + description: |- + TestHooks is the list of test hooks for the release as observed to be + run by the controller. + type: object + version: + description: Version is the version of the release object in + storage. + type: integer + required: + - chartName + - chartVersion + - configDigest + - digest + - firstDeployed + - lastDeployed + - name + - namespace + - status + - version + type: object + type: array + installFailures: + description: |- + InstallFailures is the install failure count against the latest desired + state. It is reset after a successful reconciliation. + format: int64 + type: integer + lastAppliedRevision: + description: |- + LastAppliedRevision is the revision of the last successfully applied + source. + Deprecated: the revision can now be found in the History. + type: string + lastAttemptedConfigDigest: + description: |- + LastAttemptedConfigDigest is the digest for the config (better known as + "values") of the last reconciliation attempt. + type: string + lastAttemptedGeneration: + description: |- + LastAttemptedGeneration is the last generation the controller attempted + to reconcile. + format: int64 + type: integer + lastAttemptedReleaseAction: + description: |- + LastAttemptedReleaseAction is the last release action performed for this + HelmRelease. It is used to determine the active remediation strategy. + enum: + - install + - upgrade + type: string + lastAttemptedRevision: + description: |- + LastAttemptedRevision is the Source revision of the last reconciliation + attempt. For OCIRepository sources, the 12 first characters of the digest are + appended to the chart version e.g. "1.2.3+1234567890ab". + type: string + lastAttemptedRevisionDigest: + description: |- + LastAttemptedRevisionDigest is the digest of the last reconciliation attempt. + This is only set for OCIRepository sources. + type: string + lastAttemptedValuesChecksum: + description: |- + LastAttemptedValuesChecksum is the SHA1 checksum for the values of the last + reconciliation attempt. + Deprecated: Use LastAttemptedConfigDigest instead. + type: string + lastHandledForceAt: + description: |- + LastHandledForceAt holds the value of the most recent force request + value, so a change of the annotation value can be detected. + type: string + lastHandledReconcileAt: + description: |- + LastHandledReconcileAt holds the value of the most recent + reconcile request value, so a change of the annotation value + can be detected. + type: string + lastHandledResetAt: + description: |- + LastHandledResetAt holds the value of the most recent reset request + value, so a change of the annotation value can be detected. + type: string + lastReleaseRevision: + description: |- + LastReleaseRevision is the revision of the last successful Helm release. + Deprecated: Use History instead. + type: integer + observedGeneration: + description: ObservedGeneration is the last observed generation. + format: int64 + type: integer + observedPostRenderersDigest: + description: |- + ObservedPostRenderersDigest is the digest for the post-renderers of + the last successful reconciliation attempt. + type: string + storageNamespace: + description: |- + StorageNamespace is the namespace of the Helm release storage for the + current release. + maxLength: 63 + minLength: 1 + type: string + upgradeFailures: + description: |- + UpgradeFailures is the upgrade failure count against the latest desired + state. It is reset after a successful reconciliation. + format: int64 + type: integer + type: object + type: object + served: true + storage: false + subresources: + status: {} +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app.kubernetes.io/component: helm-controller + app.kubernetes.io/instance: flux-system + app.kubernetes.io/part-of: flux + app.kubernetes.io/version: v2.4.0 + name: helm-controller + namespace: flux-system +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app.kubernetes.io/component: helm-controller + app.kubernetes.io/instance: flux-system + app.kubernetes.io/part-of: flux + app.kubernetes.io/version: v2.4.0 + control-plane: controller + name: helm-controller + namespace: flux-system +spec: + replicas: 1 + selector: + matchLabels: + app: helm-controller + template: + metadata: + annotations: + prometheus.io/port: "8080" + prometheus.io/scrape: "true" + labels: + app: helm-controller + spec: + containers: + - args: + - --events-addr=http://notification-controller.flux-system.svc.cluster.local./ + - --watch-all-namespaces=true + - --log-level=info + - --log-encoding=json + - --enable-leader-election + env: + - name: RUNTIME_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: GOMAXPROCS + valueFrom: + resourceFieldRef: + containerName: manager + resource: limits.cpu + - name: GOMEMLIMIT + valueFrom: + resourceFieldRef: + containerName: manager + resource: limits.memory + image: ghcr.io/fluxcd/helm-controller:v1.1.0 + imagePullPolicy: IfNotPresent + livenessProbe: + httpGet: + path: /healthz + port: healthz + name: manager + ports: + - containerPort: 8080 + name: http-prom + protocol: TCP + - containerPort: 9440 + name: healthz + protocol: TCP + readinessProbe: + httpGet: + path: /readyz + port: healthz + resources: + limits: + cpu: 1000m + memory: 1Gi + requests: + cpu: 100m + memory: 64Mi + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + volumeMounts: + - mountPath: /tmp + name: temp + nodeSelector: + kubernetes.io/os: linux + priorityClassName: system-cluster-critical + securityContext: + fsGroup: 1337 + serviceAccountName: helm-controller + terminationGracePeriodSeconds: 600 + volumes: + - emptyDir: {} + name: temp +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.16.1 + labels: + app.kubernetes.io/component: notification-controller + app.kubernetes.io/instance: flux-system + app.kubernetes.io/part-of: flux + app.kubernetes.io/version: v2.4.0 + name: alerts.notification.toolkit.fluxcd.io +spec: + group: notification.toolkit.fluxcd.io + names: + kind: Alert + listKind: AlertList + plural: alerts + singular: alert + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + - jsonPath: .status.conditions[?(@.type=="Ready")].status + name: Ready + type: string + - jsonPath: .status.conditions[?(@.type=="Ready")].message + name: Status + type: string + deprecated: true + deprecationWarning: v1beta1 Alert is deprecated, upgrade to v1beta3 + name: v1beta1 + schema: + openAPIV3Schema: + description: Alert is the Schema for the alerts API + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: AlertSpec defines an alerting rule for events involving a + list of objects + properties: + eventSeverity: + default: info + description: |- + Filter events based on severity, defaults to ('info'). + If set to 'info' no events will be filtered. + enum: + - info + - error + type: string + eventSources: + description: Filter events based on the involved objects. + items: + description: |- + CrossNamespaceObjectReference contains enough information to let you locate the + typed referenced object at cluster level + properties: + apiVersion: + description: API version of the referent + type: string + kind: + description: Kind of the referent + enum: + - Bucket + - GitRepository + - Kustomization + - HelmRelease + - HelmChart + - HelmRepository + - ImageRepository + - ImagePolicy + - ImageUpdateAutomation + - OCIRepository + type: string + matchLabels: + additionalProperties: + type: string + description: |- + MatchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + name: + description: Name of the referent + maxLength: 53 + minLength: 1 + type: string + namespace: + description: Namespace of the referent + maxLength: 53 + minLength: 1 + type: string + required: + - kind + - name + type: object + type: array + exclusionList: + description: A list of Golang regular expressions to be used for excluding + messages. + items: + type: string + type: array + providerRef: + description: Send events using this provider. + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + summary: + description: Short description of the impact and affected cluster. + type: string + suspend: + description: |- + This flag tells the controller to suspend subsequent events dispatching. + Defaults to false. + type: boolean + required: + - eventSources + - providerRef + type: object + status: + default: + observedGeneration: -1 + description: AlertStatus defines the observed state of Alert + properties: + conditions: + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + observedGeneration: + description: ObservedGeneration is the last observed generation. + format: int64 + type: integer + type: object + type: object + served: true + storage: false + subresources: + status: {} + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + - jsonPath: .status.conditions[?(@.type=="Ready")].status + name: Ready + type: string + - jsonPath: .status.conditions[?(@.type=="Ready")].message + name: Status + type: string + deprecated: true + deprecationWarning: v1beta2 Alert is deprecated, upgrade to v1beta3 + name: v1beta2 + schema: + openAPIV3Schema: + description: Alert is the Schema for the alerts API + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: AlertSpec defines an alerting rule for events involving a + list of objects. + properties: + eventMetadata: + additionalProperties: + type: string + description: |- + EventMetadata is an optional field for adding metadata to events dispatched by the + controller. This can be used for enhancing the context of the event. If a field + would override one already present on the original event as generated by the emitter, + then the override doesn't happen, i.e. the original value is preserved, and an info + log is printed. + type: object + eventSeverity: + default: info + description: |- + EventSeverity specifies how to filter events based on severity. + If set to 'info' no events will be filtered. + enum: + - info + - error + type: string + eventSources: + description: |- + EventSources specifies how to filter events based + on the involved object kind, name and namespace. + items: + description: |- + CrossNamespaceObjectReference contains enough information to let you locate the + typed referenced object at cluster level + properties: + apiVersion: + description: API version of the referent + type: string + kind: + description: Kind of the referent + enum: + - Bucket + - GitRepository + - Kustomization + - HelmRelease + - HelmChart + - HelmRepository + - ImageRepository + - ImagePolicy + - ImageUpdateAutomation + - OCIRepository + type: string + matchLabels: + additionalProperties: + type: string + description: |- + MatchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + MatchLabels requires the name to be set to `*`. + type: object + name: + description: |- + Name of the referent + If multiple resources are targeted `*` may be set. + maxLength: 53 + minLength: 1 + type: string + namespace: + description: Namespace of the referent + maxLength: 53 + minLength: 1 + type: string + required: + - kind + - name + type: object + type: array + exclusionList: + description: |- + ExclusionList specifies a list of Golang regular expressions + to be used for excluding messages. + items: + type: string + type: array + inclusionList: + description: |- + InclusionList specifies a list of Golang regular expressions + to be used for including messages. + items: + type: string + type: array + providerRef: + description: ProviderRef specifies which Provider this Alert should + use. + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + summary: + description: Summary holds a short description of the impact and affected + cluster. + maxLength: 255 + type: string + suspend: + description: |- + Suspend tells the controller to suspend subsequent + events handling for this Alert. + type: boolean + required: + - eventSources + - providerRef + type: object + status: + default: + observedGeneration: -1 + description: AlertStatus defines the observed state of the Alert. + properties: + conditions: + description: Conditions holds the conditions for the Alert. + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + lastHandledReconcileAt: + description: |- + LastHandledReconcileAt holds the value of the most recent + reconcile request value, so a change of the annotation value + can be detected. + type: string + observedGeneration: + description: ObservedGeneration is the last observed generation. + format: int64 + type: integer + type: object + type: object + served: true + storage: false + subresources: + status: {} + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1beta3 + schema: + openAPIV3Schema: + description: Alert is the Schema for the alerts API + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: AlertSpec defines an alerting rule for events involving a + list of objects. + properties: + eventMetadata: + additionalProperties: + type: string + description: |- + EventMetadata is an optional field for adding metadata to events dispatched by the + controller. This can be used for enhancing the context of the event. If a field + would override one already present on the original event as generated by the emitter, + then the override doesn't happen, i.e. the original value is preserved, and an info + log is printed. + type: object + eventSeverity: + default: info + description: |- + EventSeverity specifies how to filter events based on severity. + If set to 'info' no events will be filtered. + enum: + - info + - error + type: string + eventSources: + description: |- + EventSources specifies how to filter events based + on the involved object kind, name and namespace. + items: + description: |- + CrossNamespaceObjectReference contains enough information to let you locate the + typed referenced object at cluster level + properties: + apiVersion: + description: API version of the referent + type: string + kind: + description: Kind of the referent + enum: + - Bucket + - GitRepository + - Kustomization + - HelmRelease + - HelmChart + - HelmRepository + - ImageRepository + - ImagePolicy + - ImageUpdateAutomation + - OCIRepository + type: string + matchLabels: + additionalProperties: + type: string + description: |- + MatchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + MatchLabels requires the name to be set to `*`. + type: object + name: + description: |- + Name of the referent + If multiple resources are targeted `*` may be set. + maxLength: 53 + minLength: 1 + type: string + namespace: + description: Namespace of the referent + maxLength: 53 + minLength: 1 + type: string + required: + - kind + - name + type: object + type: array + exclusionList: + description: |- + ExclusionList specifies a list of Golang regular expressions + to be used for excluding messages. + items: + type: string + type: array + inclusionList: + description: |- + InclusionList specifies a list of Golang regular expressions + to be used for including messages. + items: + type: string + type: array + providerRef: + description: ProviderRef specifies which Provider this Alert should + use. + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + summary: + description: Summary holds a short description of the impact and affected + cluster. + maxLength: 255 + type: string + suspend: + description: |- + Suspend tells the controller to suspend subsequent + events handling for this Alert. + type: boolean + required: + - eventSources + - providerRef + type: object + type: object + served: true + storage: true + subresources: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.16.1 + labels: + app.kubernetes.io/component: notification-controller + app.kubernetes.io/instance: flux-system + app.kubernetes.io/part-of: flux + app.kubernetes.io/version: v2.4.0 + name: providers.notification.toolkit.fluxcd.io +spec: + group: notification.toolkit.fluxcd.io + names: + kind: Provider + listKind: ProviderList + plural: providers + singular: provider + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + - jsonPath: .status.conditions[?(@.type=="Ready")].status + name: Ready + type: string + - jsonPath: .status.conditions[?(@.type=="Ready")].message + name: Status + type: string + deprecated: true + deprecationWarning: v1beta1 Provider is deprecated, upgrade to v1beta3 + name: v1beta1 + schema: + openAPIV3Schema: + description: Provider is the Schema for the providers API + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: ProviderSpec defines the desired state of Provider + properties: + address: + description: HTTP/S webhook address of this provider + pattern: ^(http|https):// + type: string + certSecretRef: + description: |- + CertSecretRef can be given the name of a secret containing + a PEM-encoded CA certificate (`caFile`) + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + channel: + description: Alert channel for this provider + type: string + proxy: + description: HTTP/S address of the proxy + pattern: ^(http|https):// + type: string + secretRef: + description: |- + Secret reference containing the provider webhook URL + using "address" as data key + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + suspend: + description: |- + This flag tells the controller to suspend subsequent events handling. + Defaults to false. + type: boolean + timeout: + description: Timeout for sending alerts to the provider. + pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m))+$ + type: string + type: + description: Type of provider + enum: + - slack + - discord + - msteams + - rocket + - generic + - generic-hmac + - github + - gitlab + - bitbucket + - azuredevops + - googlechat + - webex + - sentry + - azureeventhub + - telegram + - lark + - matrix + - opsgenie + - alertmanager + - grafana + - githubdispatch + type: string + username: + description: Bot username for this provider + type: string + required: + - type + type: object + status: + default: + observedGeneration: -1 + description: ProviderStatus defines the observed state of Provider + properties: + conditions: + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + observedGeneration: + description: ObservedGeneration is the last reconciled generation. + format: int64 + type: integer + type: object + type: object + served: true + storage: false + subresources: + status: {} + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + - jsonPath: .status.conditions[?(@.type=="Ready")].status + name: Ready + type: string + - jsonPath: .status.conditions[?(@.type=="Ready")].message + name: Status + type: string + deprecated: true + deprecationWarning: v1beta2 Provider is deprecated, upgrade to v1beta3 + name: v1beta2 + schema: + openAPIV3Schema: + description: Provider is the Schema for the providers API. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: ProviderSpec defines the desired state of the Provider. + properties: + address: + description: |- + Address specifies the endpoint, in a generic sense, to where alerts are sent. + What kind of endpoint depends on the specific Provider type being used. + For the generic Provider, for example, this is an HTTP/S address. + For other Provider types this could be a project ID or a namespace. + maxLength: 2048 + type: string + certSecretRef: + description: |- + CertSecretRef specifies the Secret containing + a PEM-encoded CA certificate (in the `ca.crt` key). + + Note: Support for the `caFile` key has + been deprecated. + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + channel: + description: Channel specifies the destination channel where events + should be posted. + maxLength: 2048 + type: string + interval: + description: Interval at which to reconcile the Provider with its + Secret references. + pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ + type: string + proxy: + description: Proxy the HTTP/S address of the proxy server. + maxLength: 2048 + pattern: ^(http|https)://.*$ + type: string + secretRef: + description: |- + SecretRef specifies the Secret containing the authentication + credentials for this Provider. + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + suspend: + description: |- + Suspend tells the controller to suspend subsequent + events handling for this Provider. + type: boolean + timeout: + description: Timeout for sending alerts to the Provider. + pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m))+$ + type: string + type: + description: Type specifies which Provider implementation to use. + enum: + - slack + - discord + - msteams + - rocket + - generic + - generic-hmac + - github + - gitlab + - gitea + - bitbucketserver + - bitbucket + - azuredevops + - googlechat + - googlepubsub + - webex + - sentry + - azureeventhub + - telegram + - lark + - matrix + - opsgenie + - alertmanager + - grafana + - githubdispatch + - pagerduty + - datadog + type: string + username: + description: Username specifies the name under which events are posted. + maxLength: 2048 + type: string + required: + - type + type: object + status: + default: + observedGeneration: -1 + description: ProviderStatus defines the observed state of the Provider. + properties: + conditions: + description: Conditions holds the conditions for the Provider. + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + lastHandledReconcileAt: + description: |- + LastHandledReconcileAt holds the value of the most recent + reconcile request value, so a change of the annotation value + can be detected. + type: string + observedGeneration: + description: ObservedGeneration is the last reconciled generation. + format: int64 + type: integer + type: object + type: object + served: true + storage: false + subresources: + status: {} + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1beta3 + schema: + openAPIV3Schema: + description: Provider is the Schema for the providers API + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: ProviderSpec defines the desired state of the Provider. + properties: + address: + description: |- + Address specifies the endpoint, in a generic sense, to where alerts are sent. + What kind of endpoint depends on the specific Provider type being used. + For the generic Provider, for example, this is an HTTP/S address. + For other Provider types this could be a project ID or a namespace. + maxLength: 2048 + type: string + certSecretRef: + description: |- + CertSecretRef specifies the Secret containing + a PEM-encoded CA certificate (in the `ca.crt` key). + + Note: Support for the `caFile` key has + been deprecated. + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + channel: + description: Channel specifies the destination channel where events + should be posted. + maxLength: 2048 + type: string + interval: + description: |- + Interval at which to reconcile the Provider with its Secret references. + Deprecated and not used in v1beta3. + pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ + type: string + proxy: + description: Proxy the HTTP/S address of the proxy server. + maxLength: 2048 + pattern: ^(http|https)://.*$ + type: string + secretRef: + description: |- + SecretRef specifies the Secret containing the authentication + credentials for this Provider. + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + suspend: + description: |- + Suspend tells the controller to suspend subsequent + events handling for this Provider. + type: boolean + timeout: + description: Timeout for sending alerts to the Provider. + pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m))+$ + type: string + type: + description: Type specifies which Provider implementation to use. + enum: + - slack + - discord + - msteams + - rocket + - generic + - generic-hmac + - github + - gitlab + - gitea + - bitbucketserver + - bitbucket + - azuredevops + - googlechat + - googlepubsub + - webex + - sentry + - azureeventhub + - telegram + - lark + - matrix + - opsgenie + - alertmanager + - grafana + - githubdispatch + - pagerduty + - datadog + - nats + type: string + username: + description: Username specifies the name under which events are posted. + maxLength: 2048 + type: string + required: + - type + type: object + type: object + served: true + storage: true + subresources: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.16.1 + labels: + app.kubernetes.io/component: notification-controller + app.kubernetes.io/instance: flux-system + app.kubernetes.io/part-of: flux + app.kubernetes.io/version: v2.4.0 + name: receivers.notification.toolkit.fluxcd.io +spec: + group: notification.toolkit.fluxcd.io + names: + kind: Receiver + listKind: ReceiverList + plural: receivers + singular: receiver + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + - jsonPath: .status.conditions[?(@.type=="Ready")].status + name: Ready + type: string + - jsonPath: .status.conditions[?(@.type=="Ready")].message + name: Status + type: string + name: v1 + schema: + openAPIV3Schema: + description: Receiver is the Schema for the receivers API. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: ReceiverSpec defines the desired state of the Receiver. + properties: + events: + description: |- + Events specifies the list of event types to handle, + e.g. 'push' for GitHub or 'Push Hook' for GitLab. + items: + type: string + type: array + interval: + default: 10m + description: Interval at which to reconcile the Receiver with its + Secret references. + pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ + type: string + resources: + description: A list of resources to be notified about changes. + items: + description: |- + CrossNamespaceObjectReference contains enough information to let you locate the + typed referenced object at cluster level + properties: + apiVersion: + description: API version of the referent + type: string + kind: + description: Kind of the referent + enum: + - Bucket + - GitRepository + - Kustomization + - HelmRelease + - HelmChart + - HelmRepository + - ImageRepository + - ImagePolicy + - ImageUpdateAutomation + - OCIRepository + type: string + matchLabels: + additionalProperties: + type: string + description: |- + MatchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + MatchLabels requires the name to be set to `*`. + type: object + name: + description: |- + Name of the referent + If multiple resources are targeted `*` may be set. + maxLength: 53 + minLength: 1 + type: string + namespace: + description: Namespace of the referent + maxLength: 53 + minLength: 1 + type: string + required: + - kind + - name + type: object + type: array + secretRef: + description: |- + SecretRef specifies the Secret containing the token used + to validate the payload authenticity. + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + suspend: + description: |- + Suspend tells the controller to suspend subsequent + events handling for this receiver. + type: boolean + type: + description: |- + Type of webhook sender, used to determine + the validation procedure and payload deserialization. + enum: + - generic + - generic-hmac + - github + - gitlab + - bitbucket + - harbor + - dockerhub + - quay + - gcr + - nexus + - acr + - cdevents + type: string + required: + - resources + - secretRef + - type + type: object + status: + default: + observedGeneration: -1 + description: ReceiverStatus defines the observed state of the Receiver. + properties: + conditions: + description: Conditions holds the conditions for the Receiver. + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + lastHandledReconcileAt: + description: |- + LastHandledReconcileAt holds the value of the most recent + reconcile request value, so a change of the annotation value + can be detected. + type: string + observedGeneration: + description: ObservedGeneration is the last observed generation of + the Receiver object. + format: int64 + type: integer + webhookPath: + description: |- + WebhookPath is the generated incoming webhook address in the format + of '/hook/sha256sum(token+name+namespace)'. + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + - jsonPath: .status.conditions[?(@.type=="Ready")].status + name: Ready + type: string + - jsonPath: .status.conditions[?(@.type=="Ready")].message + name: Status + type: string + deprecated: true + deprecationWarning: v1beta1 Receiver is deprecated, upgrade to v1 + name: v1beta1 + schema: + openAPIV3Schema: + description: Receiver is the Schema for the receivers API + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: ReceiverSpec defines the desired state of Receiver + properties: + events: + description: |- + A list of events to handle, + e.g. 'push' for GitHub or 'Push Hook' for GitLab. + items: + type: string + type: array + resources: + description: A list of resources to be notified about changes. + items: + description: |- + CrossNamespaceObjectReference contains enough information to let you locate the + typed referenced object at cluster level + properties: + apiVersion: + description: API version of the referent + type: string + kind: + description: Kind of the referent + enum: + - Bucket + - GitRepository + - Kustomization + - HelmRelease + - HelmChart + - HelmRepository + - ImageRepository + - ImagePolicy + - ImageUpdateAutomation + - OCIRepository + type: string + matchLabels: + additionalProperties: + type: string + description: |- + MatchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + name: + description: Name of the referent + maxLength: 53 + minLength: 1 + type: string + namespace: + description: Namespace of the referent + maxLength: 53 + minLength: 1 + type: string + required: + - kind + - name + type: object + type: array + secretRef: + description: |- + Secret reference containing the token used + to validate the payload authenticity + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + suspend: + description: |- + This flag tells the controller to suspend subsequent events handling. + Defaults to false. + type: boolean + type: + description: |- + Type of webhook sender, used to determine + the validation procedure and payload deserialization. + enum: + - generic + - generic-hmac + - github + - gitlab + - bitbucket + - harbor + - dockerhub + - quay + - gcr + - nexus + - acr + type: string + required: + - resources + - secretRef + - type + type: object + status: + default: + observedGeneration: -1 + description: ReceiverStatus defines the observed state of Receiver + properties: + conditions: + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + observedGeneration: + description: ObservedGeneration is the last observed generation. + format: int64 + type: integer + url: + description: |- + Generated webhook URL in the format + of '/hook/sha256sum(token+name+namespace)'. + type: string + type: object + type: object + served: true + storage: false + subresources: + status: {} + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + - jsonPath: .status.conditions[?(@.type=="Ready")].status + name: Ready + type: string + - jsonPath: .status.conditions[?(@.type=="Ready")].message + name: Status + type: string + deprecated: true + deprecationWarning: v1beta2 Receiver is deprecated, upgrade to v1 + name: v1beta2 + schema: + openAPIV3Schema: + description: Receiver is the Schema for the receivers API. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: ReceiverSpec defines the desired state of the Receiver. + properties: + events: + description: |- + Events specifies the list of event types to handle, + e.g. 'push' for GitHub or 'Push Hook' for GitLab. + items: + type: string + type: array + interval: + description: Interval at which to reconcile the Receiver with its + Secret references. + pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ + type: string + resources: + description: A list of resources to be notified about changes. + items: + description: |- + CrossNamespaceObjectReference contains enough information to let you locate the + typed referenced object at cluster level + properties: + apiVersion: + description: API version of the referent + type: string + kind: + description: Kind of the referent + enum: + - Bucket + - GitRepository + - Kustomization + - HelmRelease + - HelmChart + - HelmRepository + - ImageRepository + - ImagePolicy + - ImageUpdateAutomation + - OCIRepository + type: string + matchLabels: + additionalProperties: + type: string + description: |- + MatchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + MatchLabels requires the name to be set to `*`. + type: object + name: + description: |- + Name of the referent + If multiple resources are targeted `*` may be set. + maxLength: 53 + minLength: 1 + type: string + namespace: + description: Namespace of the referent + maxLength: 53 + minLength: 1 + type: string + required: + - kind + - name + type: object + type: array + secretRef: + description: |- + SecretRef specifies the Secret containing the token used + to validate the payload authenticity. + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + suspend: + description: |- + Suspend tells the controller to suspend subsequent + events handling for this receiver. + type: boolean + type: + description: |- + Type of webhook sender, used to determine + the validation procedure and payload deserialization. + enum: + - generic + - generic-hmac + - github + - gitlab + - bitbucket + - harbor + - dockerhub + - quay + - gcr + - nexus + - acr + type: string + required: + - resources + - secretRef + - type + type: object + status: + default: + observedGeneration: -1 + description: ReceiverStatus defines the observed state of the Receiver. + properties: + conditions: + description: Conditions holds the conditions for the Receiver. + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + lastHandledReconcileAt: + description: |- + LastHandledReconcileAt holds the value of the most recent + reconcile request value, so a change of the annotation value + can be detected. + type: string + observedGeneration: + description: ObservedGeneration is the last observed generation of + the Receiver object. + format: int64 + type: integer + url: + description: |- + URL is the generated incoming webhook address in the format + of '/hook/sha256sum(token+name+namespace)'. + Deprecated: Replaced by WebhookPath. + type: string + webhookPath: + description: |- + WebhookPath is the generated incoming webhook address in the format + of '/hook/sha256sum(token+name+namespace)'. + type: string + type: object + type: object + served: true + storage: false + subresources: + status: {} +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app.kubernetes.io/component: notification-controller + app.kubernetes.io/instance: flux-system + app.kubernetes.io/part-of: flux + app.kubernetes.io/version: v2.4.0 + name: notification-controller + namespace: flux-system +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/component: notification-controller + app.kubernetes.io/instance: flux-system + app.kubernetes.io/part-of: flux + app.kubernetes.io/version: v2.4.0 + control-plane: controller + name: notification-controller + namespace: flux-system +spec: + ports: + - name: http + port: 80 + protocol: TCP + targetPort: http + selector: + app: notification-controller + type: ClusterIP +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/component: notification-controller + app.kubernetes.io/instance: flux-system + app.kubernetes.io/part-of: flux + app.kubernetes.io/version: v2.4.0 + control-plane: controller + name: webhook-receiver + namespace: flux-system +spec: + ports: + - name: http + port: 80 + protocol: TCP + targetPort: http-webhook + selector: + app: notification-controller + type: ClusterIP +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app.kubernetes.io/component: notification-controller + app.kubernetes.io/instance: flux-system + app.kubernetes.io/part-of: flux + app.kubernetes.io/version: v2.4.0 + control-plane: controller + name: notification-controller + namespace: flux-system +spec: + replicas: 1 + selector: + matchLabels: + app: notification-controller + template: + metadata: + annotations: + prometheus.io/port: "8080" + prometheus.io/scrape: "true" + labels: + app: notification-controller + spec: + containers: + - args: + - --watch-all-namespaces=true + - --log-level=info + - --log-encoding=json + - --enable-leader-election + env: + - name: RUNTIME_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: GOMAXPROCS + valueFrom: + resourceFieldRef: + containerName: manager + resource: limits.cpu + - name: GOMEMLIMIT + valueFrom: + resourceFieldRef: + containerName: manager + resource: limits.memory + image: ghcr.io/fluxcd/notification-controller:v1.4.0 + imagePullPolicy: IfNotPresent + livenessProbe: + httpGet: + path: /healthz + port: healthz + name: manager + ports: + - containerPort: 9090 + name: http + protocol: TCP + - containerPort: 9292 + name: http-webhook + protocol: TCP + - containerPort: 8080 + name: http-prom + protocol: TCP + - containerPort: 9440 + name: healthz + protocol: TCP + readinessProbe: + httpGet: + path: /readyz + port: healthz + resources: + limits: + cpu: 1000m + memory: 1Gi + requests: + cpu: 100m + memory: 64Mi + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + volumeMounts: + - mountPath: /tmp + name: temp + nodeSelector: + kubernetes.io/os: linux + securityContext: + fsGroup: 1337 + serviceAccountName: notification-controller + terminationGracePeriodSeconds: 10 + volumes: + - emptyDir: {} + name: temp diff --git a/base/flux/kustomization.yaml b/base/flux/kustomization.yaml new file mode 100644 index 0000000000000000000000000000000000000000..f88cf2d5a9d9f4316d441bf6282e97df6089b165 --- /dev/null +++ b/base/flux/kustomization.yaml @@ -0,0 +1,175 @@ +# start with a default flux deployment +resources: +- gotk-components.yaml + +# update flux components to use ironbank images +images: +- name: ghcr.io/fluxcd/helm-controller + newName: registry1.dso.mil/ironbank/fluxcd/helm-controller + newTag: v1.1.0 +- name: ghcr.io/fluxcd/kustomize-controller + newName: registry1.dso.mil/ironbank/fluxcd/kustomize-controller + newTag: v1.4.0 +- name: ghcr.io/fluxcd/notification-controller + newName: registry1.dso.mil/ironbank/fluxcd/notification-controller + newTag: v1.4.0 +- name: ghcr.io/fluxcd/source-controller + newName: registry1.dso.mil/ironbank/fluxcd/source-controller + newTag: v1.4.1 + +patches: + - target: + kind: Deployment + patch: |- + apiVersion: apps/v1 + kind: Deployment + metadata: + name: whatever + spec: + template: + metadata: + annotations: + # Required by Kubernetes node autoscaler + cluster-autoscaler.kubernetes.io/safe-to-evict: "true" + spec: + imagePullSecrets: + - name: private-registry + terminationGracePeriodSeconds: 60 + # Required by Pod Security Policy + securityContext: + runAsUser: 1000 + fsGroup: 1000 + containers: + - name: manager + # Required by Pod Security Policy + securityContext: + runAsUser: 1000 + runAsGroup: 1000 + privileged: false + readOnlyRootFilesystem: true + allowPrivilegeEscalation: false + runAsNonRoot: true + capabilities: + drop: + - ALL + $patch: replace + - target: + kind: ServiceAccount + name: helm-controller + patch: |- + apiVersion: v1 + kind: ServiceAccount + metadata: + name: helm-controller + automountServiceAccountToken: false + - target: + kind: Deployment + name: helm-controller + patch: |- + apiVersion: apps/v1 + kind: Deployment + metadata: + name: helm-controller + spec: + template: + spec: + automountServiceAccountToken: true + containers: + - name: manager + resources: + limits: + cpu: 1800m + memory: 2Gi + requests: + cpu: 900m + memory: 1Gi + - target: + kind: ServiceAccount + name: kustomize-controller + patch: |- + apiVersion: v1 + kind: ServiceAccount + metadata: + name: kustomize-controller + automountServiceAccountToken: false + - target: + kind: Deployment + name: kustomize-controller + patch: |- + apiVersion: apps/v1 + kind: Deployment + metadata: + name: kustomize-controller + spec: + template: + spec: + automountServiceAccountToken: true + containers: + - name: manager + resources: + limits: + cpu: 600m + memory: 1200Mi + requests: + cpu: 300m + memory: 600Mi + - target: + kind: ServiceAccount + name: notification-controller + patch: |- + apiVersion: v1 + kind: ServiceAccount + metadata: + name: notification-controller + automountServiceAccountToken: false + - target: + kind: Deployment + name: notification-controller + patch: |- + apiVersion: apps/v1 + kind: Deployment + metadata: + name: notification-controller + spec: + template: + spec: + automountServiceAccountToken: true + containers: + - name: manager + resources: + limits: + cpu: 200m + memory: 400Mi + requests: + cpu: 100m + memory: 200Mi + - target: + kind: ServiceAccount + name: source-controller + patch: |- + apiVersion: v1 + kind: ServiceAccount + metadata: + name: source-controller + automountServiceAccountToken: false + - target: + kind: Deployment + name: source-controller + patch: |- + apiVersion: apps/v1 + kind: Deployment + metadata: + name: source-controller + spec: + template: + spec: + automountServiceAccountToken: true + containers: + - name: manager + resources: + limits: + cpu: 600m + memory: 800Mi + requests: + cpu: 300m + memory: 384Mi diff --git a/base/gitrepository.yaml b/base/gitrepository.yaml new file mode 100644 index 0000000000000000000000000000000000000000..5fdaa02793e638e50d12aeb77feec3479f84115a --- /dev/null +++ b/base/gitrepository.yaml @@ -0,0 +1,14 @@ +apiVersion: source.toolkit.fluxcd.io/v1 +kind: GitRepository +metadata: + name: bigbang +spec: + ignore: | + # exclude file extensions + /**/*.md + /**/*.txt + /**/*.sh + interval: 10m + url: https://repo1.dso.mil/big-bang/bigbang.git + ref: + tag: 2.44.0 diff --git a/base/helmrelease.yaml b/base/helmrelease.yaml new file mode 100644 index 0000000000000000000000000000000000000000..7a64ecf9f76d5009f5aa96b542c313f8cad73b0c --- /dev/null +++ b/base/helmrelease.yaml @@ -0,0 +1,40 @@ +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + name: bigbang +spec: + targetNamespace: bigbang + releaseName: bigbang + interval: 10m + chart: + spec: + chart: chart + sourceRef: + kind: GitRepository + name: bigbang + test: + enable: false + install: + remediation: + retries: -1 + upgrade: + remediation: + retries: 5 + remediateLastFailure: true + cleanupOnFail: true + rollback: + timeout: 10m + cleanupOnFail: false + valuesFrom: + # Optional secret injected with https://repo1.dso.mil/big-bang/infrastructure/big-bang-terraform-launcher + - kind: Secret + name: terraform + optional: true + - kind: Secret + name: common-bb + - kind: ConfigMap + name: common + - kind: Secret + name: environment-bb + - kind: ConfigMap + name: environment diff --git a/base/kustomization.yaml b/base/kustomization.yaml new file mode 100644 index 0000000000000000000000000000000000000000..f5f387ed85a8b1656f9bc34f4bd5625b5eecb1da --- /dev/null +++ b/base/kustomization.yaml @@ -0,0 +1,37 @@ +configurations: +- transformer.yaml + +namespace: bigbang + +commonLabels: + owner: bigbang + +resources: + - namespace.yaml + - gitrepository.yaml + - helmrelease.yaml + +configMapGenerator: + - name: common + behavior: create + literals: + - values.yaml= + - name: environment + behavior: create + literals: + - values.yaml= + +# Flux combines secrets and configmaps in `valuesFrom`. Kustomize +# cannot distinguish between them when applying suffixes. Therefore, +# the secrets must have different names than the configmaps +# While capital letters or dashes could be used, '-bb' was chosen +# to make the difference obvious at a glance +secretGenerator: + - name: common-bb + behavior: create + literals: + - values.yaml= + - name: environment-bb + behavior: create + literals: + - values.yaml= diff --git a/base/namespace.yaml b/base/namespace.yaml new file mode 100644 index 0000000000000000000000000000000000000000..147e8f392058987edbfaf5d84721ebf8f1c569eb --- /dev/null +++ b/base/namespace.yaml @@ -0,0 +1,4 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: bigbang \ No newline at end of file diff --git a/base/transformer.yaml b/base/transformer.yaml new file mode 100644 index 0000000000000000000000000000000000000000..f55683c3a57fff932ef2c185c19fa9446df8652a --- /dev/null +++ b/base/transformer.yaml @@ -0,0 +1,9 @@ +nameReference: +- kind: ConfigMap + fieldSpecs: + - path: spec/valuesFrom/name + kind: HelmRelease +- kind: Secret + fieldSpecs: + - path: spec/valuesFrom/name + kind: HelmRelease \ No newline at end of file diff --git a/blog/.pages b/blog/.pages new file mode 100644 index 0000000000000000000000000000000000000000..dc8c057167c0198fd8074be19b7ac7d256182ca9 --- /dev/null +++ b/blog/.pages @@ -0,0 +1,9 @@ +nav: + - Big Bang 2.42 Release and Team Updates: 2-42-Release.md + - Big Bang 2.41 Release and Team Updates: 2-41-Release.md + - Introducing Headlamp a UI for your k8s Cluster management: UI-for-your-K8s-Cluster.md + - Cypress Testing In Depth: cypress-testing.md + - BigBang.mil Domain & dev Certificate: dev-bigbang-mil-certificate.md + - 2.0 New Features: 2-0-new-features.md + - 2.0 Breaking Changes: 2-0-breaking-changes.md + - Big Bang 2.0: big-bang-2-0.md diff --git a/blog/2-0-breaking-changes.md b/blog/2-0-breaking-changes.md new file mode 100644 index 0000000000000000000000000000000000000000..69822a0dbb5058e789fc3a86db20654e18dc2132 --- /dev/null +++ b/blog/2-0-breaking-changes.md @@ -0,0 +1,65 @@ +--- +revision_date: Last edited April 14, 2023 +tags: + - blog +--- + +# Breaking Changes in Big Bang 2.0 + +This is part 2 in a series of Big Bang 2.0 blog posts. If you haven't already, read through part 1 [here](./big-bang-2-0.md) which provides some backstory on why the team thought 2.0 was necessary and what changes are included. This post will dive more into the specific breaking changes and how these will affect you as a user. + +## Values Key Changes + +As mentioned in the first post, a number of values keys will be changing in order to standardize naming. Some of these keys already changed in BB 1.x, but had backwards compatibility previously. In 2.0 usage of the new keys will be required. When evaluating the upgrade for your own deployment, these are the specific key translations/changes you will need to make if you were using them in 1.x: +- `istiooperator` -> `istioOperator` +- `kyvernopolicies` -> `kyvernoPolicies` +- `kyvernoreporter` -> `kyvernoReporter` +- `logging` -> `elasticsearchKibana` +- `eckoperator` -> `eckOperator` +- `mattermostoperator` -> `mattermostOperator` +- `nexus` -> `nexusRepositoryManager` + +Note that your upgrade to 2.0 will fail if you do not modify your values as seen above. Big Bang is now maintaining a [values schema](https://helm.sh/docs/topics/charts/#schema-files) to enforce strict adherence to the allowed/required keys within Big Bang. For reference Big Bang's values schema is located [here](https://repo1.dso.mil/big-bang/bigbang/-/blob/master/chart/values.schema.json). You can also leverage the script in `/scripts/values-translate-2-0.sh <values file path>` to perform these translations for you (note that this is a relatively simple script and may not work for your use case). + +## Namespace Changes + +Connected with name standardization as well as package isolation, several packages will be moving to different namespaces in 2.0. These packages are all "state-less" with no persistent storage, so there is no requirement to backup anything from the previous version before upgrading. Specific packages moving: +- Fluentbit: Moving from `logging` namespace to `fluentbit` namespace +- Promtail: Moving from `logging` namespace to `promtail` namespace +- Gitlab Runner: Moving from `gitlab` namespace to `gitlab-runner` namespace + +Also note that Fluentbit (if connecting to Elasticsearch) and Gitlab Runner now have a dependency on Kyverno if relying on the "auto" authentication/token setup. In both cases Kyverno is leveraged to copy secrets between namespaces. This does not mean that you need to use `kyvernoPolicies` as well - you could continue to use Gatekeeper for policy enforcement and deploy Kyverno exclusively for this use case (although we do encourage Kyverno adoption). If you do not want to deploy Kyverno there are several alternative options listed below. + +Gitlab Runner Alternatives: +- Get a token from your Gitlab instance and add it via values (`addons.gitlabRunner.values.runnerRegistrationToken`) +- Manually copy the secret from the `gitlab` namespace to the `gitlab-runner` namespace + +Fluentbit Alternatives: +- Leverage `fluentbit.values.additionalOutputs.elasticsearch` and `fluentbit.values.additionalOutputs.disableDefault`=`true` to setup a connection with Elastic, rather than using the auto-connection +- Manually copy secrets from the `logging` namespace to the `fluentbit` namespace. You will need to copy both the certs secret (`logging-ek-es-http-certs-public`) as well as the auth secret (`logging-ek-es-elastic-user`) + +Beyond the new requirement for Kyverno, changes to a namespace can affect labels and pod/svc names in some cases, so be aware of this if you are leveraging these packages in connection with anything on top of Big Bang. All components within Big Bang have been adjusted to account for these changes already. + +## Default Package Changes + +As mentioned in the previous post - Big Bang will deploy by default with a new opensource set of core packages in 2.0. If you are using any of the below packages and want to continue using them in 2.0, make note of the changes you will need to perform: +- Twistlock: Set `twistlock.enabled` to true; set `neuvector.enabled` to false +- Fluentbit: Set `fluentbit.enabled` to true; set `promtail.enabled` to false +- Elasticsearch/Kibana: Set `elasticsearchKibana.enabled` to true; set `loki.enabled` to false +- Gatekeeper: Set `gatekeeper.enabled` and `clusterAuditor.enabled` to true; set `kyverno.enabled`, `kyvernoReporter.enabled`, and `kyvernoPolicies.enabled` to false +- Jaeger: Set `jaeger.enabled` to true; set `tempo.enabled` to false + +Provided you make the above adjustments you will be able to deploy with the same set of packages you were using in 1.x. Example values for each of the above are provided in a reference file [here](../docs/assets/configs/example/core-packages-1-x.yaml). + +## HelmRelease / GitRepository Name Changes + +Beyond the above mentioned name changes you may also notice some `HelmRelease` and `GitRepository` names change in 2.0. For the most part these should have no effect on anything directly in Big Bang, but they are important to be aware of if you maintain automation/applications on top of what is provided by Big Bang. Changes to the `HelmRelease` name specifically could affect pod/svc names and labels, so these are enumerated below: +- Fluentbit: `fluent-bit` -> `fluentbit` +- Kyverno Policies: `kyvernopolicies` -> `kyverno-policies` +- Kyverno Reporter: `kyvernoreporter` -> `kyverno-reporter` + +## Is that it? + +That's it! This blog post lays out all of the breaking changes in 2.0, and hopefully also provides you with a clear path forward for what you need to change before upgrading. + +Continue reading about Big Bang 2.0 in [part 3 of this series](./2-0-new-features.md), which is focused specifically on the new features included in 2.0. diff --git a/blog/2-0-new-features.md b/blog/2-0-new-features.md new file mode 100644 index 0000000000000000000000000000000000000000..53e66f1d6bb48029e9e73e6ec007169046d47a37 --- /dev/null +++ b/blog/2-0-new-features.md @@ -0,0 +1,55 @@ +--- +revision_date: Last edited April 13, 2023 +tags: + - blog +--- + +# New Features in Big Bang 2.0 + +This is part 3 in a series of Big Bang 2.0 blog posts. If you haven't already, read through part 1 [here](./big-bang-2-0.md) which provides some backstory on 2.0 and part 2 [here](./2-0-breaking-changes.md) which will get you prepared for the breaking changes in 2.0. This post will dive more into some of the new features releasing with 2.0. + +## Package Extensibility + +As mentioned in the first post in this series, 2.0 will provide new extensibility for deploying additional packages (beyond what is providing in Big Bang core/addons). The ["extra package deployment guide"](../docs/guides/deployment-scenarios/extra-package-deployment.md) provides a lot of details on what is included and how to use it, so we won't reproduce all of that here. As a teaser for that more extensive document, 2.0 provides a new way to deploy extra packages, as seen in the example below which deploys podinfo directly from the GitHub source: + +```yaml +packages: + podinfo: + git: + repo: https://github.com/stefanprodan/podinfo.git + tag: 6.3.4 + path: charts/podinfo +``` + +We strongly encourage you look at using this for deploying any extra packages, whether they are from the Big Bang Community or directly from GitHub and other sources. + +## OCI HelmRepositories + +As mentioned previously Helm repositories will now be an option for deployment in 2.0. While we do encourage users to test and adopt this, Git repository sources will remain the default for 2.0 so you will not see any immediate changes unless you choose to test it out as laid out in the brief guide below. + +To setup a `HelmRepository` source you will want to add a `helmRepositories` config to your values: + +```yaml +helmRepositories: + - name: "registry1" + repository: "oci://registry1.dso.mil/bigbang" + existingSecret: "private-registry" + type: "oci" +``` + +By using the `existingSecret: "private-registry"` you will be re-using your `registryCredentials` for authentication. If using a robot account you may need to get a new one issued with a broader scope since previous robot accounts only provided access to `registry1.dso.mil/ironbank`. + +In order to start using the `HelmRepository`, you'll need to switch the `sourceType` for a package. The below example switches it for `istio`: + +```yaml +istio: + sourceType: "helmRepo" +``` + +Currently you would need to set the `sourceType` individually for each package, but once making that change your `HelmRelease` will be setup to pull from the `HelmRepository` instead of the `GitRepository`. As a side-note, you can also pull from other Helm repositories (even non-OCI type ones) and leverage this alongside the new `packages` functionality to deploy from any imaginable Helm repo. + +Why should you be interested in switching? Big Bang is currently publishing all package Helm charts (including community packages) to our OCI Helm Repository (`registry1.dso.mil/bigbang`). This means that you can pull all of your charts from a single source object in cluster, rather than having a `GitRepository` per package. In the future we also plan to sign these charts and have Flux validate the signatures in cluster. If you're an airgap user this also has some future benefits depending on tooling, you may no longer need a Git server running to spin up Big Bang. + +## Renovate for Upgrades + +The last feature we want to highlight in this post is the new inclusion of Renovate for upgrades. This again is pretty well laid out in existing documentation [here](../docs/guides/renovate/deployment.md) so we won't dive too deep into configurations and how to use it in this post. We encourage you to take a look at that deployment document and explore the [package itself](https://repo1.dso.mil/big-bang/product/packages/renovate) to see how it might help you with updates. We've also updated the [customer template repo](https://repo1.dso.mil/big-bang/customers/template) with a sample Renovate config to show how it could be used directly in a config repo. diff --git a/blog/2-41-Release.md b/blog/2-41-Release.md new file mode 100644 index 0000000000000000000000000000000000000000..9a6846c3554e5c3bee04378c9c7d0754cf996474 --- /dev/null +++ b/blog/2-41-Release.md @@ -0,0 +1,65 @@ +--- +revision_date: Last edited December 09, 2024 +tags: + - blog +--- + +# Big Bang Release 2.41.0: A Milestone in Enterprise Platform Development + +We are thrilled to announce the release of Big Bang 2.41.0, marking another significant step forward in our enterprise platform development journey. This incremental release brings substantial improvements to stability, security, and core functionality across our component ecosystem. + +## Release Highlights + +The latest release includes comprehensive updates to critical components including GitLab, Istio, Kiali, and Kyverno. Our development teams have worked diligently to ensure these updates enhance both performance and security while maintaining seamless integration within the Big Bang ecosystem. + +## Release Notes +We always encourage consumers to view the [Release notes](https://repo1.dso.mil/big-bang/bigbang/-/releases/2.41.0) for additional information. + +## Team Achievements and Progress + +### Storage and Collaboration Enhancements + +- Comprehensive updates to Minio, Vault, Confluence, and External Secrets +- Implementation of ESO cluster secret functionality to allow for centralized secret management, dynamic secret injection, and cloud native integration. + +### Security and Compliance Advancement + +- Completed renovate updates for Anchore Enterprise and Neuvector +- Internal testing of KubeScape project +- Refined Kyverno policy implementation +- Progress toward multi-cluster Twistlock deployment support + +### Observability Improvements + +- Successfully implemented Prometheus remote-write metrics to Mimir over Istio +- Completed updates to core monitoring tools including Loki, Grafana, and Fluentbit +- Advanced CI tracing tools integration with Alloy, Tempo, and Loki + +### Service Mesh Developments + +- Resolution of Tetrate image enabling in Sandbox Istio Gateway +- Advanced templating for public and passthrough gateway implementation +- Near completion of the Kiali labeling epic with only 13 remaining issues + +### Repo Sync + +- Updates and improvements to the Repo Sync utility which enables us to receive and accept community contributions [Further information on the current status can be found within the epic ](https://repo1.dso.mil/groups/big-bang/-/epics/400) + +### Edge Computing Innovation + +- Advancement of initiatives toward the anticipated 1.0 release + +## Community Engagement + +We extend our gratitude to Daniel Dides and the entire Big Bang team for their valued contributions to this release. The success of Big Bang relies heavily on the engagement of our community, and we request feedback through the following methods: +- [Issue](https://repo1.dso.mil/big-bang/bigbang/-/issues/new) reporting on our platform +- Consulting our [comprehensive documentation](https://docs-bigbang.dso.mil/latest/) for implementation guidance +- Providing [feedback](https://join.slack.com/t/bigbanguniver-ft39451/shared_invite/zt-2mrtefxg6-5WJr85JD3NPbreMuAcQR0A) on new features and improvements + +## Looking Forward + +As we continue to evolve Big Bang, our focus remains on delivering robust, secure, and scalable solutions for enterprise deployment. The progress demonstrated in this release reflects our commitment to excellence and continuous improvement across all aspects of the platform. + +For detailed information about the upgrade process and known issues, please consult the release notes in our documentation. We look forward to your feedback and continued collaboration in making Big Bang even better. + +*Stay tuned for more updates as we continue to enhance and expand the capabilities of Big Bang.* diff --git a/blog/2-42-Release.md b/blog/2-42-Release.md new file mode 100644 index 0000000000000000000000000000000000000000..eacf4cd6c2febbf09c2123dee1d3157f445817d0 --- /dev/null +++ b/blog/2-42-Release.md @@ -0,0 +1,71 @@ +--- +revision_date: Last edited December 19, 2024 +tags: + - blog +--- + +# Big Bang Release 2.42.0: Engineering Progress and Strategic Innovations + +We are thrilled to announce the release of Big Bang 2.42.0, marking another significant step forward in our enterprise platform development journey. This incremental release brings substantial improvements to stability, security, and core functionality across our component ecosystem. + +## Release Highlights + +The latest release includes comprehensive updates to critical components including GitLab, Istio, and Kyverno. Our development teams have worked diligently to ensure these updates enhance both performance and security while maintaining seamless integration within the Big Bang ecosystem. + +## Release Notes +We always encourage consumers to view the [Release notes](https://repo1.dso.mil/big-bang/bigbang/-/releases/2.42.0) for additional information. + +## Team Achievements and Progress + +### Security and Compliance Enhancement + +- Successfully completed renovations for Kyverno and associated policies +- Enhanced Anchore Enterprise configurations +- Strengthened security measures for Fluentbit and Gitlab Runner +- Upgraded Tetragon chart to version 1.2.1 +- Launched the initial phase of our Compliance Dashboard + +### Observability Platform Evolution + +- Near completion of Mimir integration with comprehensive network security implementation +- Successful collaboration with IronBank for enterprise container optimization +- Implementation of community contributions for elasticsearch-kibana package +- Completion of Alloy and Loki renovations + +### Storage and Collaboration Improvements + +- Successful renovation of Confluence, Vault, and Jira systems +- Resolution of critical Confluence installation issues +- Implementation of external secrets key versioning in ESO + +### Development and Operations Progress + +- Gitlab-CI-Pipelines-Exporter is in a stable and maintained status. +- Resolution of ArgoCD CI stability issues +- Successful implementation of various renovations including Nexus, Fortify, and Gitlab +- Enhancement of Harbor OIDC SSO configuration + +### Edge Computing and Strategic Partnerships + +- Substantial progress on Release 1.0, with particular emphasis on Crossplane integration and comprehensive testing frameworks + +### Tooling and Automation Achievements + +- Enhancement of bbctl pipeline functionality +- Improvements to Repo-sync capabilities +- Implementation of comprehensive testing frameworks + +## Community Engagement + +We extend our gratitude to Darrien Lee and the entire Big Bang team for their valued contributions to this release. The success of Big Bang relies heavily on the engagement of our community, and we request feedback through the following methods: +- [Issue](https://repo1.dso.mil/big-bang/bigbang/-/issues/new) reporting on our platform +- Consulting our [comprehensive documentation](https://docs-bigbang.dso.mil/latest/) for implementation guidance +- Providing [feedback](https://join.slack.com/t/bigbanguniver-ft39451/shared_invite/zt-2mrtefxg6-5WJr85JD3NPbreMuAcQR0A) on new features and improvements + +## Looking Forward + +As we continue to evolve Big Bang, our focus remains on delivering robust, secure, and scalable solutions for enterprise deployment. The progress demonstrated in this release reflects our commitment to excellence and continuous improvement across all aspects of the platform. + +For detailed information about the upgrade process and known issues, please consult the release notes in our documentation. We look forward to your feedback and continued collaboration in making Big Bang even better. + +*Stay tuned for more updates as we continue to enhance and expand the capabilities of Big Bang.* \ No newline at end of file diff --git a/blog/UI-for-your-K8s-Cluster.md b/blog/UI-for-your-K8s-Cluster.md new file mode 100644 index 0000000000000000000000000000000000000000..5e4efdf3ca808ca27ef6b06d12460f5d1a82a450 --- /dev/null +++ b/blog/UI-for-your-K8s-Cluster.md @@ -0,0 +1,49 @@ +--- +revision_date: Last edited November 20, 2024 +tags: + - blog +--- +We at BigBang are excited to share some great news! We're working on adding **Headlamp**, a modern, user-friendly Kubernetes management UI, as an installable add-on in BigBang. But you don’t have to wait—Headlamp is already available as a desktop client for macOS, Windows, and Linux. You can download it now at [headlamp.dev](https://headlamp.dev/#download-platforms). + +## Benefits of Headlamp + +### 1. **Easy to Use** +Headlamp provides a clean, intuitive interface that simplifies Kubernetes cluster management. It’s accessible for both beginners and experienced users, reducing the steep learning curve often associated with Kubernetes. + +### 2. **Lightweight and Fast** +Designed to be lightweight, Headlamp ensures fast performance and minimal resource usage, making it a great tool for responsive cluster management. + +### 3. **Real-Time Insights** +Get live updates on resource statuses, metrics, and logs. This ensures you always have the most accurate information to monitor cluster health and troubleshoot issues effectively. + +![Alt text](assets/images/UI-for-your-K8s-Cluster/pods_snapshot.png) + +### 4. **Customizable and Extensible** +- **Plugin Support:** Add or modify functionality to tailor the UI to your needs such as the easily implemented Flux plugin. +- **Open Source:** Adapt Headlamp for specific requirements or contribute to its development. + +![Alt text](assets/images/UI-for-your-K8s-Cluster/flux_hr_snapshot.png) +![Alt text](assets/images/UI-for-your-K8s-Cluster/Flux_actions.png) + + +### 5. **Multi-Cluster Management** +Easily manage multiple Kubernetes clusters from a single interface, streamlining operations across environments. + +### 6. **RBAC Visualization** +Understand and manage Role-Based Access Control (RBAC) with clear visualizations, simplifying permission management. +![Alt text](assets/images/UI-for-your-K8s-Cluster/rbac.png) + +### 7. **Native Kubernetes API Integration** +Headlamp connects directly with Kubernetes APIs, ensuring accurate, real-time cluster management without relying on additional tools or agents. + +### 8. **Real-Time Visualization of resources** +Headlamp is capable of mapping out your real-time resources such as Workloads(pods, deployments, etc), Storage(PVCs), Network (Services, Endpoints, Ingress), Security(Service Accounts, Roles, Role Bindings), Configuration(Config Maps, Secrets, etc) and can be grouped by Namespace, Instance, or node. + +![Alt text](assets/images/UI-for-your-K8s-Cluster/visualization.png) + + +--- + +Start exploring Headlamp today to simplify and enhance your Kubernetes management experience! + +Progress of headlamp being implemented into Big Bang as an add-on can be found [here](https://repo1.dso.mil/big-bang/product/bbtoc/-/issues/144) \ No newline at end of file diff --git a/blog/assets/images/UI-for-your-K8s-Cluster/Flux_actions.png b/blog/assets/images/UI-for-your-K8s-Cluster/Flux_actions.png new file mode 100644 index 0000000000000000000000000000000000000000..8a5e6ee2429ff3d28771e702e1d08be91790af4c Binary files /dev/null and b/blog/assets/images/UI-for-your-K8s-Cluster/Flux_actions.png differ diff --git a/blog/assets/images/UI-for-your-K8s-Cluster/flux_hr_snapshot.png b/blog/assets/images/UI-for-your-K8s-Cluster/flux_hr_snapshot.png new file mode 100644 index 0000000000000000000000000000000000000000..c86716279b99be2e60ad73d2b658c3f12841e42e Binary files /dev/null and b/blog/assets/images/UI-for-your-K8s-Cluster/flux_hr_snapshot.png differ diff --git a/blog/assets/images/UI-for-your-K8s-Cluster/pods_snapshot.png b/blog/assets/images/UI-for-your-K8s-Cluster/pods_snapshot.png new file mode 100644 index 0000000000000000000000000000000000000000..c559434fe006633998407badaad52796f7068100 Binary files /dev/null and b/blog/assets/images/UI-for-your-K8s-Cluster/pods_snapshot.png differ diff --git a/blog/assets/images/UI-for-your-K8s-Cluster/rbac.png b/blog/assets/images/UI-for-your-K8s-Cluster/rbac.png new file mode 100644 index 0000000000000000000000000000000000000000..93cf09d0d72380a7d84fe0268ce314978f1b2d78 Binary files /dev/null and b/blog/assets/images/UI-for-your-K8s-Cluster/rbac.png differ diff --git a/blog/assets/images/UI-for-your-K8s-Cluster/visualization.png b/blog/assets/images/UI-for-your-K8s-Cluster/visualization.png new file mode 100644 index 0000000000000000000000000000000000000000..de5f0caf210a385f07a8d9028931ca6d5c80b20f Binary files /dev/null and b/blog/assets/images/UI-for-your-K8s-Cluster/visualization.png differ diff --git a/blog/big-bang-2-0.md b/blog/big-bang-2-0.md new file mode 100644 index 0000000000000000000000000000000000000000..aab4d784eeb8605df2acafbb31f9019413cd554f --- /dev/null +++ b/blog/big-bang-2-0.md @@ -0,0 +1,62 @@ +--- +revision_date: Last edited April 13, 2023 +tags: + - blog +--- + +# Big Bang 2.0 + +What is Big Bang 2.0? Why are we doing it? 2.0 is the second major release since Big Bang 1.0 released in December 2020. This blog post should provide you with both the why behind what we're doing, as well as what the changes involved are, and what that means for you as a user. + +## Why Change Things? + +The majority of the why behind 2.0 comes down to customer pain points. A few of the top ones that tie into specific things changing in 2.0 are listed in the following: +1. The barrier to entry for users is too high, both from a technical/knowledge standpoint and from a cost perspective. +2. Upgrades of Big Bang are difficult, partially due to the large amount of changes in each release. +3. Adding on community packages/mission apps is too hard; there's no easy (or even documented) way to add a new community package to your deployment. + +Beyond these pain points, there are also changes we are making to enable future platform improvements that necessitate a major release. + +## What is Changing? + +### Free and OpenSource Core by Default + +The default core packages in 1.x releases come with both licensing and closed source concerns, as well as some usability concerns in some cases. Several of the default packages will be changing in 2.0 as a result. These changes are listed in the following: +* **Runtime Security:** NeuVector will replace Twistlock as the default. NeuVector is opensourced and does not come with a license cost. +* **Logging:** The Promtail/Loki/Grafana (PLG) stack will become the new default stack, replacing Elasticsearch/Fluentbit/Kibana (EFK). PLG has lower resource costs for users, and does not have a license requirement for core features. +* **Policy Enforcement:** Kyverno will replace Gatekeeper as the default. Kyverno provides a better user experience for policy writing, and is more directly focused on the Kubernetes experience. +* **Tracing:** Tempo will replace Jaeger as the default. Jaeger has a dependency on Elasticsearch for persistence, and Tempo is better integrated with the PLG stack to tie traces to specific logs. + +These will be *small* breaking changes to user values. If you want to continue to deploy Twistlock, for example, you will need to adjust your values to disable NeuVector and enable Twistlock before upgrading. It's also important to note that we will continue to support the alternative packages in all of these cases, we do not intend to lock users in to a single option. + +### Standardization of Naming + +Within Big Bang, packages have a wide variety of naming conventions and mis-matches between different locations. Some packages may have a values key that doesn't match the namespace or `HelmRelease` name. In order to improve the user experience, we are standardizing the names in these areas. Package values keys will line up with the namespace and `HelmRelease`/`GitRepository` name 1:1 with case translations to accommodate different usages (`camelCase` for Helm values, `kebab-case` for Kubernetes resources). In addition, Big Bang will provide a documented style guide with any exceptions to the guide. + +Once again - these will be *small* breaking changes to user values and potentially has effects on any extra user scripts/tooling on top of Big Bang. Exact changes will be provided as part of a follow on blog post and in the release notes for 2.0. + +### Improved Package Extensibility + +With 2.0 we will be providing a way to deploy community/arbitrary packages as part of Big Bang and as a "first-class" experience. This will provide a way for users to effectively extend Big Bang, and still have the lifecycle of additional packages tied to the Big Bang deployment directly. Beyond this, there will also be a new `wrapper` provided that offers some features for integration of an application inside of Big Bang, strictly via Big Bang values. This includes things like configuring `VirtualService`, `ServiceMonitor`, and `NetworkPolicy` resources. + +For additional details on what this looks like from a user/values perspective, read the [extra package deployment guide](../docs/guides/deployment-scenarios/extra-package-deployment.md). This will be provided as a new feature, and not change any existing architecture/functionality. + +### Upgrade Process Improvements + +As mentioned in our "Why" section, upgrades for Big Bang are hard. A big piece of this is a lack of documentation surrounding what a Big Bang upgrade should look like, and how to complete one. In 2.0, we will be providing clear documentation around updates for both single packages and the entire stack as a whole. + +One of the challenges we are balancing is keeping end users up to date with the latest security patches as quick as they release, while avoiding the danger of updating 10, 20, or 30+ packages in a single upgrade. Part of our approach to resolving this pain is releasing/encouraging smaller upgrades at a more frequent rate. A piece of our solution for this is providing the Renovate tool as a Big Bang package, along with providing guidance around usage and templates for configuration. Renovate is a tool that provides automation of dependency updates. Within the context of Big Bang, this would alert end users of new package releases and provide automatic changes to the user's GitOps config repo in the form of merge/pull requests. The ultimate goal is for customers to be able to update packages asynchronously from the Big Bang releases (i.e., smaller updates, more often). + +This again will largely look more like a new feature, although it may have implications to the current release process/cadence. We will continue to release Big Bang versions, but again, we hope for these to be smaller updates due to package updates happening differently. As a result the requirements for a major/minor/patch version will be different and will be documented in the near future. + +### OCI HelmRepositories + +OCI `HelmRepository` will be offered as a deployment option instead of `GitRepository` in 2.0. Big Bang charts are currently being published as Helm OCI artifacts in `registry1.dso.mil/bigbang` and will be published for all Big Bang core, addon, and community packages. It is important to call out that there is no inherent extra scanning/security going into these artifacts today; this is largely just a "storage format" change for the way Flux sources the Helm charts. In the future, Big Bang will be signing our OCI Helm charts and providing for verification of these signatures by end users, increasing confidence in our supply chain security. We also hope this will enable future improvements to the airgap process. All artifacts needed for Big Bang will be "OCI shaped," both the images and the Helm charts. + +This is a change in the underlying architecture of Big Bang, but it will be offered as an option in 2.0 to start with, and `GitRepository` will remain the default. We anticipate changing the default in the future but `GitRepository` will remain an option long-term to enable a variety of deployment needs. + +## Where can I Learn More? + +Big Bang's 2.0 epic is a great place to start [here](https://repo1.dso.mil/groups/big-bang/-/epics/217). Beyond this, we encourage users to get involved via the [BBTOC](https://repo1.dso.mil/platform-one/bbtoc). + +Continue reading about Big Bang 2.0 in [part 2 of this series](./2-0-breaking-changes.md), which is focused specifically on the breaking changes included in 2.0. diff --git a/blog/cypress-testing.md b/blog/cypress-testing.md new file mode 100644 index 0000000000000000000000000000000000000000..058859f00f6364cc4369f3f4424e49816d7f9d5e --- /dev/null +++ b/blog/cypress-testing.md @@ -0,0 +1,248 @@ +--- +revision_date: Last edited April 2, 2024 +tags: + - blog +--- + +# Cypress Testing In-Depth + +## Introduction + +The intent of this post is to build off the existing Cypress Testing documentation [here](../docs/guides/using-bigbang/testing-deployments.md) and go a bit deeper into how it can be leveraged in a real-world environment. We will also go a bit deeper into Cypress specific configuration settings, running/debugging tests, and cover some of the basics of Cypress. + +## Environment Overview + +Before we get started, let's go over the environment we'll be using. This environment was setup using the umbrella strategy described in our [Customer Template](https://repo1.dso.mil/big-bang/customers/template) and has the following layout: + +``` +|-- bb-demo +| |-- base +| | |-- cypress-tests +| | | |-- sonarqube +| | | | -- 10-sonarqube-health.cy.js +| | | | -- 11-sonarqube-delay.cy.js +| | -- configmap.yaml +| | -- kustomization.yaml +| | -- secrets.enc.yaml +| |-- demo +| | -- bigbang.yaml +| | -- configmap.yaml +| | -- kustomization.yaml +| | -- secrets.enc.yaml +``` + +As this is only a demo, there is only one environment named demo, but in a real-world situation you would likely have additional folders for staging and production. The custom Cypress tests are located under the base folder as these would remain the same regardless of the environment to which they are being deployed. The configuration of the environment itself is pretty straight forward and primarily contained in the configmap.yaml under the demo folder: + +``` +domain: dev.bigbang.mil +networkPolicies: + enabled: true +neuvector: + enabled: false +kyvernoPolicies: + values: + validationFailureAction: Audit +addons: + sonarqube: + enabled: true + values: + bbtests: + enabled: true + cypress: + artifacts: false + disableDefaultTests: true + customTest: "sonarqube-tests" + resources: + requests: + cpu: 2 + memory: "4Gi" + limits: + cpu: 4 + memory: "8Gi" + envs: + cypress_user: "admin" + cypress_url: "https://sonarqube.dev.bigbang.mil" + cypress_url_setup: "https://sonarqube.dev.bigbang.mil/setup" + secretEnvs: + - name: cypress_password + valueFrom: + secretKeyRef: + name: sonarqube-secrets + key: password +``` + +We'll go over the more specific configuration settings for Cypress later, but for now let's continue to the rest of the configuration. The kustomization.yaml under the demo folder holds an additional reference to a kubernetes secret created to hold the password for the sonarqube user: + +``` +generatorOptions: + disableNameSuffixHash: true +bases: +- ../base +configMapGenerator: + - name: environment + behavior: merge + files: + - values.yaml=configmap.yaml +secretGenerator: + - name: sonarqube-secrets + namespace: sonarqube + files: + - password=secrets.enc.yaml +``` + +The kustomization.yaml file under the base folder has also been modified to reference the Cypress test files we want to use: + +``` +generatorOptions: + disableNameSuffixHash: true +bases: +- https://repo1.dso.mil/platform-one/big-bang/bigbang.git//base?ref=2.23.0 +configMapGenerator: + - name: common + behavior: merge + files: + - values.yaml=configmap.yaml + - name: sonarqube-tests + namespace: sonarqube + files: + - cypress-tests/sonarqube/10-sonarqube-health.cy.js + - cypress-tests/sonarqube/11-sonarqube-delay.cy.js +patchesStrategicMerge: +- secrets.enc.yaml +``` + +Both kustomization.yaml files have an additional option at the top to disable the name suffix hash to ensure we can reference it correctly. The assumption of this environment is that Sonarqube has been enabled and configured. + +## Cypress Specific Settings + +Aside from enabling the tests themselves, there are a few settings that deserve more attention: + +* artifacts - This setting is typically set to true when running tests from a pipeline. However, since we are running this in a local dev environment we have set the value to false. It's worth noting that when this value is true a host path mount called Cypress will need to be created and available within your Kubernetes cluster. This allows the pod to upload any of the resulting screenshots and videos from the cypress tests before the pod completes. + +* resources - Cypress recommends 2 CPU's and 4 GB of RAM at an absolute minimum with more given depending on the complexity and length of the tests themselves. At the time of this writing, the default values for both requests and limits for CPU and Memory are 1 and 2 GB respectively as many of the default tests are very basic. The settings used in the configmap.yaml previously shown are just there for demo purposes and are likely much more than what is needed for our tests. However, if you ever find yourself running into odd issues that only seem to come up in your tests, it may be a good idea to tweak those values first to make sure its not the cause. This is especially true if you find that the logs indicate the browser crashed during a test as that is the most common sign of not having enough resources. + +* envs - This is where you would specify any environment variables that will be used by your Cypress tests. You'll want to check each package where tests are enabled to see what variables are required if you're using the default provided tests. You can also add in any additional variables you need for any custom tests you've written. Any variable prefixed with "cypress_" will become a variable you can use in your tests. For example, the existing variable of "cypress_user" shown above, can be used within your Cypress test by referencing the "user" variable which you'll see a bit later. + +* secretEnvs - The same rules apply to this setting, but these values are pulled from Kubernetes secret files so they'd likely be used for any passwords or tokens you may need to use throughout any tests. + +We won't go over the customTest and disableDefaultTests settings as this has already been explained in the documentation link referenced in the Introduction section. + +## Cypress Tests + +Now that we've covered the environment and settings, let's take a look at the Cypress tests themselves. In this specific scenario, we've come to the realization that the default tests don't quite offer all we need to be satisfied. As a result, we've decided to disable the default tests and create a very basic health check: + +``` +Cypress.on('uncaught:exception', (err, runnable) => { + // returning false here prevents Cypress from failing the test + return false +}) + +describe('Sonarqube Health Checks', () => { + + it('Perform Login', () => { + //Login and wait for authentication call to complete before moving on + cy.visit(`${Cypress.env('url')}/sessions/new?return_to=%2F`) + cy.get('input[name="login"]').type(Cypress.env('user')) + cy.get('input[name="password"]').type(Cypress.env('password')) + cy.intercept('POST', '**/api/authentication/login').as('validSession') + cy.get('button[type="submit"]').contains("Log in").click() + cy.wait('@validSession').then((interception) => { + expect(interception.response.statusCode).to.equal(200) + }) + }) + + it('Validate Health', () => { + //Use API Response to validate system is up + cy.intercept('GET', '**/info').as('apiCall') + cy.visit(`${Cypress.env('url')}/admin/system`) + cy.wait('@apiCall').then(({ response }) => { + expect(response.statusCode).to.equal(200) + expect(response.body).to.have.property('Health', 'GREEN') + }) + //Use UI to validate system is up + cy.get('.system-info-health-info').contains('Status is up') + }) +}) +``` + +The first few lines of the test allow Cypress to continue to run in the event we encounter any errors while browsing to the site. In this situation, we are seeing some 401's from a couple of API calls that occur when browsing to the system section of this application even after successfully authenticating. Typically, you would want to dig a little deeper into the underlying issue for that, however, I wanted to illustrate how you can bypass those errors as there are some applications that may exhibit behaviors that you cannot control. Additionally, Cypress will still fail if the actual tests themselves fail even with this setting. + +The next snippet browses directly to the login URL, inputs the username/password, and clicks submit. If we were to browse to the base URL, https://sonarqube.dev.bigbang.mil, we would be met with several 401 statuses causing Cypress to fail without that first snippet. This is one way you can avoid the behavior previously mentioned as browsing directly to the login URL prevents those 401's from occurring. You may also notice that we are using "(Cypress.env('user'))" as opposed to "(Cypress.env('cypress_user'))" when we are referencing a variable we have provided. This is because the "cypress_" portion is removed when referenced from within the test so keep that in mind when creating custom tests. Prior to clicking the "Log in" button on the test, we've created an intercept to listen for an underlying API call that will signal a successful authentication. Without the intercept in place, it is entirely possible to go through the motions of logging in only to fail to authenticate which will cause our subsequent test to fail. + +The final snippet performs a basic health check of the application by browsing to the sytem page within Sonarqube. In a real world scenario, you would only use one of the two methods to validate health, but I wanted to provide another look at how intercepts can be used to validate information within API calls that occur throughout the process of browsing. Since we don't own the applications, some things may be quite difficult to test using only the browser itself. Furthermore, if you have several properties of the response you need to validate, you can typically do that more easily using intercepts and often with less code. + +The additional test file used in this scenario, 11-sonarqube-delay.cy.js, isn't really doing anything as you can see below: + +``` +describe('Sonarqube Delay', () => { + it('Do Nothing', () => { + cy.wait(30000) + }) +}) +``` + +It was added primarily to illustrate the fact that you can add as many custom tests as you need (although it does serve one other purpose which we'll see later 🙂). Every test specified in our kustomization.yaml file will be consolidated into the same configmap which we have specified in our Cypress settings. + +## Running and Debugging the Tests + +Now that we've covered all the boring details of the tests and configuration settings, let's run our test by executing the following command: + +``` +helm test sonarqube -n bigbang +``` + +Open up your favorite Kubernetes IDE and you should see a new pod in the Sonarqube namespace. Every Cypress test pod name takes the form of HelmReleaseName-cypress-test so in this case we should be seeing a pod called sonarqube-cypress-test. The first time the test is run it may take a bit longer as it needs to pull the image down. If everything ran as expected, you should see no failures output once the "helm test" command completes. + +If you'd like to view the logs from the Cypress test pod as the test is executing you can issue the following command: + +``` +kubectl logs -f sonarqube-cypress-test -n sonarqube +``` + +> **Note:** You may notice the following errors/warnings occur during the initialization process, but they can be ignored as they have no impact on the test's behavior: + +``` +Fontconfig error: No writable cache directories +Failed to create /home/node/.cache for shader cache (Read-only file system)---disabling. +[353:0401/180059.881693:ERROR:zygote_host_impl_linux.cc(273)] Failed to adjust OOM score of renderer with pid 570: Permission denied (13) +``` + +It can also be very useful to view the resulting video from the test run which is where that additional Cypress test comes in. That test will sit and wait for 30 seconds allowing enough time to download the video from the pod by using the following command: + +``` +kubectl cp -n sonarqube sonarqube-cypress-test:'/test/cypress/videos/10-sonarqube-health.cy.js.mp4' ~/Downloads/sonarqube.mp4 +``` + +Of course, if you have access to the underlying Kubernetes cluster and you have an existing hostPath created for "/Cypress", you can simply download the video that way. Just keep in mind, you'll need to set the artifacts value to true within the cypress section under bbtests, otherwise, the videos/screenshots won't be uploaded there. + +Since the tests are coming from the configmap, you can easily modify the code within it using the Kubernetes IDE of your choice to quickly and easily test the changes. Once the configmap has been updated, you can simply run the "helm test" command once more to verify the changes work. You'll obviously want to make sure you make the same changes within your Cypress test files once you've found what works. + +## Tips, Tricks, & Gotchya's + +The easiest way to start on writing a Cypress test is to simply browse around with the developer tools open to get a feel of what a site looks like during normal operation. Once that's been established the process of creating the test becomes fairly straight forward, but here are some additional tips to help get you started: + +* Try to use css selectors designated for QA in your tests. Since we don't have control over the underlying application this can be a bit difficult, but you'll notice several applications seem to have css selectors prefixed with data, qa, or test. You can reasonably assume these selectors are used by that application's QA process and therefore they are least likely to change. + +* Avoid Explicit waits at all costs and use Implicit waits instead. You may be tempted to force your test to wait prior to taking an action by using something like this: + + ``` + cy.wait(25000) + cy.get('button[type="submit"]').contains("Log in").click() + ``` + + However, a better way to handle this is to use a timeout value instead like this: + + ``` + cy.get('button[type="submit"]', { timeout: 25000 }).contains("Log in").click() + ``` + + In the first example, the test will **always** wait for 25 seconds before continuing while the second example will wait **up to** 25 seconds before failing or moving on. If it's able to take that action before the 25 second mark it will and the tests will complete sooner. You will also want to remember that the amount of time it takes to run a test may also necessitate more resources to be given to that pod. As a result, explicit waits (cy.wait()) should be avoided at all costs. The only exception to this rule is when its used for waiting on an API call which behaves as an implicit wait. + +* Try to avoid using Cypress tests to perform configuration of the application itself and make sure your tests clean up after themselves. Your Cypress tests can quickly become over-complicated if you try to account for something already existing from a previous run of your test. Additionally, the results of your tests may give other developers misleading information. + + For example, let's say you have a test that creates a project within Sonarqube, but the test does not delete that project afterwards. All subsequent tests may tell the user it was able to successfully create a project when in reality it just found one created from a previous test run. + +* Finally, be aware that Cypress is asynchronous which means things may not execute exactly as you think they will. This can result in tests seemingly failing intermittently even when they execute just fine locally. To avoid this use chained commands within Cypress to ensure the order will remain intact every time. This is a bit of a loaded topic so I won't go into further detail about here, but if you'd like more information [this article](https://learn.cypress.io/cypress-fundamentals/understanding-the-asynchronous-nature-of-cypress) is a great place to start. + +## Wrap Up +Cypress can be a powerful testing tool for your arsenal when used properly and now that users can now add in their own tests, it can easily be tailored to fit more specific situations. Getting everything deployed in Big Bang is nice, but having confidence that it's all working as expected is even better! 🙂 \ No newline at end of file diff --git a/blog/dev-bigbang-mil-certificate.md b/blog/dev-bigbang-mil-certificate.md new file mode 100644 index 0000000000000000000000000000000000000000..a932f9502766073478a35392c8ad9b53d2c20492 --- /dev/null +++ b/blog/dev-bigbang-mil-certificate.md @@ -0,0 +1,11 @@ +--- +revision_date: Last edited March 26, 2024 +tags: + - blog +--- + +# Big Bang Mil Domain & Certificate + +In late March 2024, Big Bang migrated to a Platform One (P1) owned and operated domain `bigbang.mil` and updated the DEVELOPMENT ONLY certificate we ship with BigBang which makes the process of doing dev setup and quickstart items easier via using a valid and pre-configured certificate. + +This `*.dev.bigbang.mil` certificate is for our team's internal Continuous Integration (CI) pipelines and Development ONLY. No artifacts, articles, pages or downloads will be available behind this domain. If there is anything pointing to or referencing this domain that is publicly available it is NOT owned or operated by P1. Our method of publishing and hosting releases only on `repo1.dso.mil`, `registry1.dso.mil` and `github.com/DoD-Platform-One` will continue to be our method where you can find our artifacts and releases. diff --git a/chart/Chart.yaml b/chart/Chart.yaml new file mode 100644 index 0000000000000000000000000000000000000000..861d205ece3b2978a0535cdbe4c5af78035dfa3b --- /dev/null +++ b/chart/Chart.yaml @@ -0,0 +1,20 @@ +apiVersion: v2 +name: bigbang +version: 2.44.0 +kubeVersion: '>=1.29.0-0' +description: Big Bang is a declarative, continuous delivery tool for core DoD hardened and approved packages into a Kubernetes cluster. +type: application +keywords: + - platform1 + - bigbang +home: https://p1.dso.mil/products/big-bang +sources: + - https://repo1.dso.mil/big-bang/bigbang +maintainers: + - name: Michael Martin + email: michaelmartin@seed-innovations.com + - name: Chris O'Connell + email: coconnell@bridgephase.com + - name: Andrew Shoell + email: a.shoell@wearemetronome.com +icon: https://p1.dso.mil/img/Big_Bang_Color_Logo_White_text.b04263b1.png diff --git a/chart/dashboards/flux/Kptfile b/chart/dashboards/flux/Kptfile new file mode 100644 index 0000000000000000000000000000000000000000..4dcb07b56e4eb97463fa5c4800d7910562fef75c --- /dev/null +++ b/chart/dashboards/flux/Kptfile @@ -0,0 +1,11 @@ +apiVersion: kpt.dev/v1alpha1 +kind: Kptfile +metadata: + name: flux +upstream: + type: git + git: + commit: 22cf986a79a6da2dd1bcd91b5eef763400f0104b + repo: https://github.com/fluxcd/flux2 + directory: /manifests/monitoring/monitoring-config/dashboards + ref: v2.1.0 diff --git a/chart/dashboards/flux/cluster.json b/chart/dashboards/flux/cluster.json new file mode 100644 index 0000000000000000000000000000000000000000..1ef0fed50e4a4ade8ea77d7856e2451723342940 --- /dev/null +++ b/chart/dashboards/flux/cluster.json @@ -0,0 +1,1006 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": "-- Grafana --", + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + }, + { + "datasource": { + "type": "datasource", + "uid": "grafana" + }, + "enable": true, + "iconColor": "red", + "name": "flux events", + "target": { + "limit": 100, + "matchAny": false, + "tags": [ + "flux" + ], + "type": "tags" + } + } + ] + }, + "editable": true, + "gnetId": null, + "graphTooltip": 0, + "iteration": 1652337714814, + "links": [], + "panels": [ + { + "datasource": "${DS_PROMETHEUS}", + "description": "", + "fieldConfig": { + "defaults": { + "decimals": 0, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "blue", + "value": null + }, + { + "color": "red", + "value": 100 + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "gridPos": { + "h": 5, + "w": 6, + "x": 0, + "y": 0 + }, + "id": 24, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "last" + ], + "fields": "", + "values": false + }, + "text": {}, + "textMode": "value" + }, + "pluginVersion": "7.5.5", + "targets": [ + { + "exemplar": true, + "expr": "count(gotk_reconcile_condition{namespace=~\"$operator_namespace\",exported_namespace=~\"$namespace\",type=\"Ready\",status=\"True\",kind=~\"Kustomization|HelmRelease\"})\n-\nsum(gotk_reconcile_condition{namespace=~\"$operator_namespace\",exported_namespace=~\"$namespace\",type=\"Ready\",status=\"Deleted\",kind=~\"Kustomization|HelmRelease\"})", + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Cluster Reconcilers", + "type": "stat" + }, + { + "datasource": "${DS_PROMETHEUS}", + "description": "", + "fieldConfig": { + "defaults": { + "decimals": 0, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "red", + "value": null + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "gridPos": { + "h": 5, + "w": 6, + "x": 6, + "y": 0 + }, + "id": 28, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "last" + ], + "fields": "", + "values": false + }, + "text": {}, + "textMode": "value" + }, + "pluginVersion": "7.5.5", + "targets": [ + { + "exemplar": true, + "expr": "sum(gotk_reconcile_condition{namespace=~\"$operator_namespace\",exported_namespace=~\"$namespace\",type=\"Ready\",status=\"False\",kind=~\"Kustomization|HelmRelease\"})", + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Failing Reconcilers", + "type": "stat" + }, + { + "datasource": "${DS_PROMETHEUS}", + "description": "", + "fieldConfig": { + "defaults": { + "decimals": 0, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "blue", + "value": null + }, + { + "color": "red", + "value": 100 + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "gridPos": { + "h": 5, + "w": 6, + "x": 12, + "y": 0 + }, + "id": 29, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "last" + ], + "fields": "", + "values": false + }, + "text": {}, + "textMode": "value" + }, + "pluginVersion": "7.5.5", + "targets": [ + { + "exemplar": true, + "expr": "count(gotk_reconcile_condition{namespace=~\"$operator_namespace\",exported_namespace=~\"$namespace\",type=\"Ready\",status=\"True\",kind=~\"GitRepository|OCIRepository|HelmRepository|Bucket\"})\n-\nsum(gotk_reconcile_condition{namespace=~\"$operator_namespace\",exported_namespace=~\"$namespace\",type=\"Ready\",status=\"Deleted\",kind=~\"GitRepository|OCIRepository|HelmRepository|Bucket\"})", + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Kubernetes Manifests Sources", + "type": "stat" + }, + { + "datasource": "${DS_PROMETHEUS}", + "description": "", + "fieldConfig": { + "defaults": { + "decimals": 0, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "red", + "value": null + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "gridPos": { + "h": 5, + "w": 6, + "x": 18, + "y": 0 + }, + "id": 30, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "last" + ], + "fields": "", + "values": false + }, + "text": {}, + "textMode": "value" + }, + "pluginVersion": "7.5.5", + "targets": [ + { + "exemplar": true, + "expr": "sum(gotk_reconcile_condition{namespace=~\"$operator_namespace\",exported_namespace=~\"$namespace\",type=\"Ready\",status=\"False\",kind=~\"GitRepository|OCIRepository|HelmRepository|Bucket\"})", + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Failing Sources", + "type": "stat" + }, + { + "datasource": "${DS_PROMETHEUS}", + "description": "", + "fieldConfig": { + "defaults": { + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "#EAB839", + "value": 1 + }, + { + "color": "red", + "value": 61 + } + ] + }, + "unit": "s" + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 12, + "x": 0, + "y": 5 + }, + "id": 8, + "options": { + "displayMode": "gradient", + "minVizHeight": 10, + "minVizWidth": 0, + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "mean" + ], + "fields": "", + "values": false + }, + "showUnfilled": true, + "text": {} + }, + "pluginVersion": "7.5.5", + "targets": [ + { + "exemplar": true, + "expr": "sum(rate(gotk_reconcile_duration_seconds_sum{namespace=~\"$operator_namespace\",exported_namespace=~\"$namespace\",kind=~\"Kustomization|HelmRelease\"}[5m])) by (kind)\n/\n sum(rate(gotk_reconcile_duration_seconds_count{namespace=~\"$operator_namespace\",exported_namespace=~\"$namespace\",kind=~\"Kustomization|HelmRelease\"}[5m])) by (kind)", + "interval": "", + "legendFormat": "{{kind}}", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Reconciler ops avg. duration", + "type": "bargauge" + }, + { + "datasource": "${DS_PROMETHEUS}", + "description": "", + "fieldConfig": { + "defaults": { + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "#EAB839", + "value": 1 + }, + { + "color": "red", + "value": 61 + } + ] + }, + "unit": "s" + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 12, + "x": 12, + "y": 5 + }, + "id": 31, + "options": { + "displayMode": "gradient", + "minVizHeight": 10, + "minVizWidth": 0, + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "mean" + ], + "fields": "", + "values": false + }, + "showUnfilled": true, + "text": {} + }, + "pluginVersion": "7.5.5", + "targets": [ + { + "exemplar": true, + "expr": "sum(rate(gotk_reconcile_duration_seconds_sum{namespace=~\"$operator_namespace\",exported_namespace=~\"$namespace\",kind=~\"GitRepository|OCIRepository|HelmRepository|Bucket\"}[5m])) by (kind)\n/\n sum(rate(gotk_reconcile_duration_seconds_count{namespace=~\"$operator_namespace\",exported_namespace=~\"$namespace\",kind=~\"GitRepository|OCIRepository|HelmRepository|Bucket\"}[5m])) by (kind)", + "interval": "", + "legendFormat": "{{kind}}", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Source ops avg. duration", + "type": "bargauge" + }, + { + "collapsed": false, + "datasource": "${DS_PROMETHEUS}", + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 9 + }, + "id": 15, + "panels": [], + "title": "Status", + "type": "row" + }, + { + "datasource": "${DS_PROMETHEUS}", + "description": "", + "fieldConfig": { + "defaults": { + "custom": { + "displayMode": "auto", + "filterable": true, + "inspect": false + }, + "mappings": [ + { + "options": { + "0": { + "text": "Ready" + }, + "1": { + "text": "Not Ready" + } + }, + "type": "value" + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "blue", + "value": null + }, + { + "color": "blue", + "value": 0 + }, + { + "color": "red", + "value": 1 + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "Status" + }, + "properties": [ + { + "id": "custom.displayMode", + "value": "color-background" + } + ] + } + ] + }, + "gridPos": { + "h": 11, + "w": 12, + "x": 0, + "y": 10 + }, + "id": 33, + "options": { + "footer": { + "fields": "", + "reducer": [ + "sum" + ], + "show": false + }, + "showHeader": true, + "sortBy": [ + { + "desc": true, + "displayName": "Status" + } + ] + }, + "pluginVersion": "7.5.5", + "targets": [ + { + "exemplar": true, + "expr": "gotk_reconcile_condition{namespace=~\"$operator_namespace\",exported_namespace=~\"$namespace\",type=\"Ready\",status=\"False\",kind=~\"Kustomization|HelmRelease\"}", + "format": "table", + "instant": true, + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Cluster reconciliation readiness ", + "transformations": [ + { + "id": "organize", + "options": { + "excludeByName": { + "Time": true, + "__name__": true, + "app": true, + "container": true, + "endpoint": true, + "exported_namespace": false, + "instance": true, + "job": true, + "kubernetes_namespace": true, + "kubernetes_pod_name": true, + "namespace": true, + "pod": true, + "pod_template_hash": true, + "status": true, + "type": true + }, + "indexByName": {}, + "renameByName": { + "Value": "Status", + "exported_namespace": "Namespace", + "kind": "Kind", + "name": "Name", + "namespace": "Operator Namespace" + } + } + } + ], + "type": "table" + }, + { + "datasource": "${DS_PROMETHEUS}", + "description": "", + "fieldConfig": { + "defaults": { + "custom": { + "displayMode": "auto", + "filterable": true, + "inspect": false + }, + "mappings": [ + { + "options": { + "0": { + "text": "Ready" + }, + "1": { + "text": "Not Ready" + } + }, + "type": "value" + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "blue", + "value": null + }, + { + "color": "blue", + "value": 0 + }, + { + "color": "red", + "value": 1 + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "Status" + }, + "properties": [ + { + "id": "custom.displayMode", + "value": "color-background" + } + ] + } + ] + }, + "gridPos": { + "h": 11, + "w": 12, + "x": 12, + "y": 10 + }, + "id": 34, + "options": { + "footer": { + "fields": "", + "reducer": [ + "sum" + ], + "show": false + }, + "showHeader": true, + "sortBy": [ + { + "desc": true, + "displayName": "Status" + } + ] + }, + "pluginVersion": "7.5.5", + "targets": [ + { + "exemplar": true, + "expr": "gotk_reconcile_condition{namespace=~\"$operator_namespace\",exported_namespace=~\"$namespace\",type=\"Ready\",status=\"False\",kind=~\"GitRepository|OCIRepository|HelmRepository|Bucket\"}", + "format": "table", + "instant": true, + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Source acquisition readiness ", + "transformations": [ + { + "id": "organize", + "options": { + "excludeByName": { + "Time": true, + "__name__": true, + "app": true, + "container": true, + "endpoint": true, + "exported_namespace": false, + "instance": true, + "job": true, + "kubernetes_namespace": true, + "kubernetes_pod_name": true, + "namespace": true, + "pod": true, + "pod_template_hash": true, + "status": true, + "type": true + }, + "indexByName": {}, + "renameByName": { + "Value": "Status", + "exported_namespace": "Namespace", + "kind": "Kind", + "name": "Name", + "namespace": "Operator Namespace" + } + } + } + ], + "type": "table" + }, + { + "collapsed": false, + "datasource": "${DS_PROMETHEUS}", + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 21 + }, + "id": 17, + "panels": [], + "title": "Timing", + "type": "row" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_PROMETHEUS}", + "description": "", + "fieldConfig": { + "defaults": {}, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 24, + "x": 0, + "y": 22 + }, + "hiddenSeries": false, + "id": 27, + "legend": { + "alignAsTable": true, + "avg": true, + "current": false, + "hideEmpty": true, + "hideZero": true, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "7.5.5", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "exemplar": true, + "expr": "sum(rate(gotk_reconcile_duration_seconds_sum{namespace=~\"$operator_namespace\",exported_namespace=~\"$namespace\",kind=~\"Kustomization|HelmRelease\"}[5m])) by (kind, name)\n/\n sum(rate(gotk_reconcile_duration_seconds_count{namespace=~\"$operator_namespace\",exported_namespace=~\"$namespace\",kind=~\"Kustomization|HelmRelease\"}[5m])) by (kind, name)", + "hide": false, + "interval": "", + "legendFormat": "{{kind}}/{{name}}", + "refId": "B" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Cluster reconciliation duration", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "s", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_PROMETHEUS}", + "description": "", + "fieldConfig": { + "defaults": {}, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 24, + "x": 0, + "y": 30 + }, + "hiddenSeries": false, + "id": 35, + "legend": { + "alignAsTable": true, + "avg": true, + "current": false, + "hideEmpty": true, + "hideZero": true, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "7.5.5", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "exemplar": true, + "expr": "sum(rate(gotk_reconcile_duration_seconds_sum{namespace=~\"$operator_namespace\",exported_namespace=~\"$namespace\",kind=~\"GitRepository|OCIRepository|HelmRepository|Bucket\"}[5m])) by (kind, name)\n/\n sum(rate(gotk_reconcile_duration_seconds_count{namespace=~\"$operator_namespace\",exported_namespace=~\"$namespace\",kind=~\"GitRepository|OCIRepository|HelmRepository|Bucket\"}[5m])) by (kind, name)", + "hide": false, + "interval": "", + "legendFormat": "{{kind}}/{{name}}", + "refId": "B" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Source acquisition duration", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "s", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + } + ], + "refresh": "30s", + "schemaVersion": 36, + "style": "light", + "tags": [ + "flux" + ], + "templating": { + "list": [ + { + "allValue": "", + "current": { + "selected": true, + "text": [ + "All" + ], + "value": [ + "$__all" + ] + }, + "datasource": "$DS_PROMETHEUS", + "definition": "label_values(gotk_reconcile_condition, namespace)", + "description": null, + "error": null, + "hide": 0, + "includeAll": true, + "label": null, + "multi": true, + "name": "operator_namespace", + "options": [], + "query": { + "query": "label_values(gotk_reconcile_condition, namespace)", + "refId": "StandardVariableQuery" + }, + "refresh": 2, + "regex": "", + "skipUrlSync": false, + "sort": 5, + "tagValuesQuery": "", + "tags": [], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": null, + "current": { + "selected": true, + "tags": [], + "text": [ + "All" + ], + "value": [ + "$__all" + ] + }, + "datasource": "$DS_PROMETHEUS", + "definition": "label_values(gotk_reconcile_condition, exported_namespace)", + "description": null, + "error": null, + "hide": 0, + "includeAll": true, + "label": null, + "multi": true, + "name": "namespace", + "options": [], + "query": { + "query": "label_values(gotk_reconcile_condition, exported_namespace)", + "refId": "StandardVariableQuery" + }, + "refresh": 2, + "regex": "", + "skipUrlSync": false, + "sort": 0, + "tagValuesQuery": "", + "tags": [], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "current": { + "selected": false, + "text": "Prometheus", + "value": "Prometheus" + }, + "hide": 0, + "includeAll": false, + "label": "Datasource", + "multi": false, + "name": "DS_PROMETHEUS", + "options": [], + "query": "prometheus", + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "type": "datasource" + } + ] + }, + "time": { + "from": "now-15m", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ] + }, + "title": "Flux Cluster Stats", + "uid": "flux-cluster", + "version": 3 +} diff --git a/chart/dashboards/flux/control-plane.json b/chart/dashboards/flux/control-plane.json new file mode 100644 index 0000000000000000000000000000000000000000..a4ad008d28ee23a68ae5bc0becdef18ce7b69fdc --- /dev/null +++ b/chart/dashboards/flux/control-plane.json @@ -0,0 +1,1637 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": "-- Grafana --", + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "target": { + "limit": 100, + "matchAny": false, + "tags": [], + "type": "dashboard" + }, + "type": "dashboard" + }, + { + "datasource": { + "type": "datasource", + "uid": "grafana" + }, + "enable": true, + "iconColor": "red", + "name": "flux events", + "target": { + "limit": 100, + "matchAny": false, + "tags": [ + "flux" + ], + "type": "tags" + } + } + ] + }, + "editable": true, + "fiscalYearStartMonth": 0, + "gnetId": null, + "graphTooltip": 0, + "id": 29, + "iteration": 1639041352219, + "links": [], + "liveNow": false, + "panels": [ + { + "datasource": "${DS_PROMETHEUS}", + "description": "", + "fieldConfig": { + "defaults": { + "decimals": 0, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "blue", + "value": null + }, + { + "color": "red", + "value": 100 + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "gridPos": { + "h": 5, + "w": 6, + "x": 0, + "y": 0 + }, + "id": 24, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "last" + ], + "fields": "", + "values": false + }, + "text": {}, + "textMode": "value" + }, + "pluginVersion": "8.2.3", + "targets": [ + { + "expr": "sum(go_info{namespace=\"$namespace\",pod=~\".*-controller-.*\"})", + "interval": "", + "legendFormat": "pods", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Controllers", + "type": "stat" + }, + { + "datasource": "${DS_PROMETHEUS}", + "description": "", + "fieldConfig": { + "defaults": { + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "blue", + "value": null + }, + { + "color": "#EAB839", + "value": 50 + }, + { + "color": "red", + "value": 100 + } + ] + }, + "unit": "s" + }, + "overrides": [] + }, + "gridPos": { + "h": 5, + "w": 6, + "x": 6, + "y": 0 + }, + "id": 23, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "text": {}, + "textMode": "auto" + }, + "pluginVersion": "8.2.3", + "targets": [ + { + "expr": "max(workqueue_longest_running_processor_seconds{namespace=\"$namespace\",pod=~\".*-controller-.*\"})", + "hide": false, + "interval": "", + "legendFormat": "seconds", + "refId": "B" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Max Work Queue", + "type": "stat" + }, + { + "datasource": "${DS_PROMETHEUS}", + "description": "", + "fieldConfig": { + "defaults": { + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "blue", + "value": null + }, + { + "color": "#EAB839", + "value": 500000000 + }, + { + "color": "red", + "value": 900000000 + } + ] + }, + "unit": "decbits" + }, + "overrides": [] + }, + "gridPos": { + "h": 5, + "w": 6, + "x": 12, + "y": 0 + }, + "id": 25, + "options": { + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showThresholdLabels": false, + "showThresholdMarkers": true, + "text": {} + }, + "pluginVersion": "8.2.3", + "targets": [ + { + "expr": "sum(go_memstats_alloc_bytes{namespace=\"$namespace\",pod=~\".*-controller-.*\"})", + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Memory", + "type": "gauge" + }, + { + "datasource": "${DS_PROMETHEUS}", + "description": "", + "fieldConfig": { + "defaults": { + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "blue", + "value": null + }, + { + "color": "#EAB839", + "value": 50 + }, + { + "color": "red", + "value": 100 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 5, + "w": 6, + "x": 18, + "y": 0 + }, + "id": 26, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "mean" + ], + "fields": "", + "values": false + }, + "text": {}, + "textMode": "auto" + }, + "pluginVersion": "8.2.3", + "targets": [ + { + "expr": "sum(rate(rest_client_requests_total{namespace=\"$namespace\",pod=~\".*-controller-.*\"}[1m]))", + "interval": "", + "legendFormat": "requests", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "API Requests", + "type": "stat" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_PROMETHEUS}", + "decimals": null, + "description": "", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 24, + "x": 0, + "y": 5 + }, + "hiddenSeries": false, + "id": 21, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.2.3", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(rest_client_requests_total{namespace=\"$namespace\"}[1m]))", + "hide": false, + "interval": "", + "legendFormat": "total", + "refId": "A" + }, + { + "expr": "sum(rate(rest_client_requests_total{namespace=\"$namespace\",code!~\"2..\"}[1m]))", + "hide": false, + "interval": "", + "legendFormat": "errors", + "refId": "B" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Kubernetes API Requests", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:912", + "decimals": null, + "format": "short", + "label": "", + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "$$hashKey": "object:913", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "collapsed": false, + "datasource": "${DS_PROMETHEUS}", + "fieldConfig": { + "defaults": {}, + "overrides": [] + }, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 13 + }, + "id": 15, + "panels": [], + "title": "Resource Usage", + "type": "row" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_PROMETHEUS}", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 11, + "w": 12, + "x": 0, + "y": 14 + }, + "hiddenSeries": false, + "id": 11, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": false, + "min": false, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.2.3", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "rate(process_cpu_seconds_total{namespace=\"$namespace\",pod=~\".*-controller-.*\"}[1m])", + "interval": "", + "legendFormat": "{{pod}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "CPU Usage", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:93", + "format": "s", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "$$hashKey": "object:94", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_PROMETHEUS}", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 11, + "w": 12, + "x": 12, + "y": 14 + }, + "hiddenSeries": false, + "id": 13, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": false, + "min": false, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.2.3", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sum(container_memory_working_set_bytes{namespace=\"$namespace\",container!=\"POD\",container!=\"\",pod=~\".*-controller-.*\"}) by (pod)", + "hide": false, + "interval": "", + "legendFormat": "{{pod}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Memory Usage", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:93", + "decimals": 0, + "format": "bytes", + "label": "", + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "$$hashKey": "object:94", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "collapsed": false, + "datasource": "${DS_PROMETHEUS}", + "fieldConfig": { + "defaults": {}, + "overrides": [] + }, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 25 + }, + "id": 17, + "panels": [], + "title": "Reconciliation Stats", + "type": "row" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_PROMETHEUS}", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 24, + "x": 0, + "y": 26 + }, + "hiddenSeries": false, + "id": 27, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.2.3", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "workqueue_longest_running_processor_seconds{name=\"kustomization\"}", + "hide": false, + "interval": "", + "legendFormat": "kustomizations", + "refId": "B" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Cluster Reconciliation Duration", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:912", + "format": "s", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "$$hashKey": "object:913", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_PROMETHEUS}", + "decimals": 2, + "description": "", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 24, + "x": 0, + "y": 34 + }, + "hiddenSeries": false, + "id": 2, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "total": false, + "values": true + }, + "lines": false, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "8.2.3", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": true, + "targets": [ + { + "expr": "sum(increase(controller_runtime_reconcile_total{controller=\"kustomization\",result!=\"error\"}[1m])) by (controller)", + "format": "time_series", + "interval": "", + "legendFormat": "successful reconciliations ", + "refId": "A" + }, + { + "expr": "sum(increase(controller_runtime_reconcile_total{controller=\"kustomization\",result=\"error\"}[1m])) by (controller)", + "format": "time_series", + "interval": "", + "legendFormat": "failed reconciliations ", + "refId": "B" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Cluster Reconciliations ops/min", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:1171", + "format": "opm", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "$$hashKey": "object:1172", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "collapsed": false, + "datasource": "${DS_PROMETHEUS}", + "fieldConfig": { + "defaults": {}, + "overrides": [] + }, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 42 + }, + "id": 29, + "panels": [], + "title": "Sources Stats", + "type": "row" + }, + { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_PROMETHEUS}", + "decimals": 2, + "description": "", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 43 + }, + "hiddenSeries": false, + "id": 4, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "total": false, + "values": true + }, + "lines": false, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "8.2.3", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": true, + "targets": [ + { + "expr": "sum(increase(controller_runtime_reconcile_total{controller=\"gitrepository\",result!=\"error\"}[1m]))", + "format": "time_series", + "interval": "", + "legendFormat": "successful git pulls", + "refId": "A" + }, + { + "expr": "sum(increase(controller_runtime_reconcile_total{controller=\"gitrepository\",result=\"error\"}[1m]))", + "format": "time_series", + "interval": "", + "legendFormat": "failed git pulls", + "refId": "B" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Git Repos ops/min", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:285", + "format": "opm", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "$$hashKey": "object:286", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_PROMETHEUS}", + "decimals": 2, + "description": "", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 9, + "w": 12, + "x": 12, + "y": 43 + }, + "hiddenSeries": false, + "id": 4, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "total": false, + "values": true + }, + "lines": false, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "8.2.3", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": true, + "targets": [ + { + "expr": "sum(increase(controller_runtime_reconcile_total{controller=\"ocirepository\",result!=\"error\"}[1m]))", + "format": "time_series", + "interval": "", + "legendFormat": "successful oci pulls", + "refId": "A" + }, + { + "expr": "sum(increase(controller_runtime_reconcile_total{controller=\"ocirepository\",result=\"error\"}[1m]))", + "format": "time_series", + "interval": "", + "legendFormat": "failed oci pulls", + "refId": "B" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "OCI Repos ops/min", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:285", + "format": "opm", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "$$hashKey": "object:286", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_PROMETHEUS}", + "decimals": 2, + "description": "", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 52 + }, + "hiddenSeries": false, + "id": 4, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "total": false, + "values": true + }, + "lines": false, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "8.2.3", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": true, + "targets": [ + { + "expr": "sum(increase(controller_runtime_reconcile_total{controller=\"helmrepository\",result!=\"error\"}[1m]))", + "format": "time_series", + "interval": "", + "legendFormat": "successful helm pulls", + "refId": "A" + }, + { + "expr": "sum(increase(controller_runtime_reconcile_total{controller=\"helmrepository\",result=\"error\"}[1m]))", + "format": "time_series", + "interval": "", + "legendFormat": "failed helm pulls", + "refId": "B" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Helm Repos ops/min", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:285", + "format": "opm", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "$$hashKey": "object:286", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_PROMETHEUS}", + "decimals": 2, + "description": "", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 9, + "w": 12, + "x": 12, + "y": 52 + }, + "hiddenSeries": false, + "id": 4, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "total": false, + "values": true + }, + "lines": false, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "8.2.3", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": true, + "targets": [ + { + "expr": "sum(increase(controller_runtime_reconcile_total{controller=\"bucket\",result!=\"error\"}[1m]))", + "format": "time_series", + "interval": "", + "legendFormat": "successful bucket pulls", + "refId": "A" + }, + { + "expr": "sum(increase(controller_runtime_reconcile_total{controller=\"bucket\",result=\"error\"}[1m]))", + "format": "time_series", + "interval": "", + "legendFormat": "failed bucket pulls", + "refId": "B" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Buckets ops/min", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:285", + "format": "opm", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "$$hashKey": "object:286", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "collapsed": false, + "datasource": "${DS_PROMETHEUS}", + "fieldConfig": { + "defaults": {}, + "overrides": [] + }, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 61 + }, + "id": 19, + "panels": [], + "title": "Helm Stats", + "type": "row" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_PROMETHEUS}", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 24, + "x": 0, + "y": 62 + }, + "hiddenSeries": false, + "id": 9, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": false, + "min": false, + "rightSide": true, + "show": false, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null as zero", + "percentage": false, + "pluginVersion": "8.2.3", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(0.50, sum(rate(controller_runtime_reconcile_time_seconds_bucket{controller=\"helmrelease\"}[5m])) by (le))", + "hide": true, + "interval": "", + "legendFormat": "P50", + "refId": "A" + }, + { + "expr": "histogram_quantile(0.90, sum(rate(controller_runtime_reconcile_time_seconds_bucket{controller=\"helmrelease\"}[5m])) by (le))", + "hide": true, + "interval": "", + "legendFormat": "P90", + "refId": "B" + }, + { + "expr": "histogram_quantile(0.99, sum(rate(controller_runtime_reconcile_time_seconds_bucket{controller=\"helmrelease\"}[5m])) by (le))", + "hide": false, + "interval": "", + "legendFormat": "P99", + "refId": "C" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Helm Release Duration", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:1612", + "format": "s", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "$$hashKey": "object:1613", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_PROMETHEUS}", + "decimals": 2, + "description": "", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 70 + }, + "hiddenSeries": false, + "id": 5, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "total": false, + "values": true + }, + "lines": false, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "8.2.3", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": true, + "targets": [ + { + "expr": "sum(increase(controller_runtime_reconcile_total{controller=\"helmrelease\",result!=\"error\"}[1m])) by (controller)", + "format": "time_series", + "interval": "", + "legendFormat": "successful reconciliations ", + "refId": "A" + }, + { + "expr": "sum(increase(controller_runtime_reconcile_total{controller=\"helmrelease\",result=\"error\"}[1m])) by (controller)", + "format": "time_series", + "interval": "", + "legendFormat": "failed reconciliations ", + "refId": "B" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Helm Releases ops/min", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:1102", + "format": "opm", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "$$hashKey": "object:1103", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_PROMETHEUS}", + "decimals": 2, + "description": "", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 9, + "w": 12, + "x": 12, + "y": 70 + }, + "hiddenSeries": false, + "id": 6, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "total": false, + "values": true + }, + "lines": false, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "8.2.3", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": true, + "targets": [ + { + "expr": "sum(increase(controller_runtime_reconcile_total{controller=\"helmchart\",result!=\"error\"}[1m])) by (controller)", + "format": "time_series", + "interval": "", + "legendFormat": "successful chart pulls", + "refId": "A" + }, + { + "expr": "sum(increase(controller_runtime_reconcile_total{controller=\"helmchart\",result=\"error\"}[1m])) by (controller)", + "format": "time_series", + "interval": "", + "legendFormat": "failed chart pulls", + "refId": "B" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Helm Charts ops/min", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:1892", + "format": "opm", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "$$hashKey": "object:1893", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + } + ], + "refresh": "10s", + "schemaVersion": 31, + "style": "light", + "tags": [ + "flux" + ], + "templating": { + "list": [ + { + "current": { + "selected": false, + "text": "Prometheus", + "value": "Prometheus" + }, + "description": null, + "error": null, + "hide": 2, + "includeAll": false, + "label": null, + "multi": false, + "name": "DS_PROMETHEUS", + "options": [], + "query": "prometheus", + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "type": "datasource" + }, + { + "allValue": null, + "current": { + "selected": false, + "text": "flux-system", + "value": "flux-system" + }, + "datasource": "${DS_PROMETHEUS}", + "definition": "workqueue_work_duration_seconds_count", + "description": null, + "error": null, + "hide": 0, + "includeAll": false, + "label": null, + "multi": false, + "name": "namespace", + "options": [], + "query": { + "query": "workqueue_work_duration_seconds_count", + "refId": "Prometheus-namespace-Variable-Query" + }, + "refresh": 2, + "regex": "/.*namespace=\"([^\"]*).*/", + "skipUrlSync": false, + "sort": 0, + "tagValuesQuery": "", + "tagsQuery": "", + "type": "query", + "useTags": false + } + ] + }, + "time": { + "from": "now-15m", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ] + }, + "timezone": "", + "title": "Flux Control Plane", + "uid": "flux-control-plane", + "version": 2 +} \ No newline at end of file diff --git a/chart/dashboards/flux/logs.json b/chart/dashboards/flux/logs.json new file mode 100644 index 0000000000000000000000000000000000000000..4d9f58daccd1be71ee844353c5b9a3c90c1b152f --- /dev/null +++ b/chart/dashboards/flux/logs.json @@ -0,0 +1,332 @@ +{ + "__inputs": [ + { + "name": "DS_LOKI", + "label": "Loki", + "description": "", + "type": "datasource", + "pluginId": "loki", + "pluginName": "Loki" + } + ], + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": "-- Grafana --", + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "target": { + "limit": 100, + "matchAny": false, + "tags": [], + "type": "dashboard" + }, + "type": "dashboard" + }, + { + "datasource": { + "type": "datasource", + "uid": "grafana" + }, + "enable": true, + "iconColor": "red", + "name": "flux events", + "target": { + "limit": 100, + "matchAny": false, + "tags": [ + "flux" + ], + "type": "tags" + } + } + ] + }, + "description": "Flux logs collected from Kubernetes, stored in Loki", + "editable": true, + "gnetId": null, + "graphTooltip": 0, + "id": 29, + "iteration": 1653748775696, + "links": [], + "liveNow": false, + "panels": [ + { + "datasource": "${DS_LOKI}", + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "bars", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 4, + "options": { + "legend": { + "calcs": [], + "displayMode": "hidden", + "placement": "bottom" + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": "${DS_LOKI}", + "expr": "sum(count_over_time({namespace=~\"$namespace\", stream=~\"$stream\", app =~\"$controller\"} | json | __error__!=\"JSONParserErr\" | level=~\"$level\" |= \"$query\" [$__interval]))", + "instant": false, + "legendFormat": "Log count", + "range": true, + "refId": "A" + } + ], + "type": "timeseries" + }, + { + "datasource": "${DS_LOKI}", + "description": "Logs from services running in Kubernetes", + "gridPos": { + "h": 25, + "w": 24, + "x": 0, + "y": 4 + }, + "id": 2, + "options": { + "dedupStrategy": "numbers", + "enableLogDetails": false, + "prettifyLogMessage": true, + "showCommonLabels": false, + "showLabels": false, + "showTime": false, + "sortOrder": "Descending", + "wrapLogMessage": false + }, + "targets": [ + { + "datasource": "${DS_LOKI}", + "expr": "{namespace=~\"$namespace\", stream=~\"$stream\", app =~\"$controller\"} | json | __error__!=\"JSONParserErr\" | level=~\"$level\" |= \"$query\"", + "refId": "A" + } + ], + "type": "logs" + } + ], + "refresh": "10s", + "schemaVersion": 36, + "style": "light", + "tags": [ + "flux" + ], + "templating": { + "list": [ + { + "current": { + "selected": false, + "text": "", + "value": "" + }, + "description": "String to search for", + "hide": 0, + "label": "Search Query", + "name": "query", + "options": [ + { + "selected": true, + "text": "", + "value": "" + } + ], + "query": "", + "skipUrlSync": false, + "type": "textbox" + }, + { + "allValue": "info|error", + "current": { + "selected": false, + "text": "All", + "value": "$__all" + }, + "hide": 0, + "includeAll": true, + "multi": false, + "name": "level", + "options": [ + { + "selected": true, + "text": "All", + "value": "$__all" + }, + { + "selected": false, + "text": "info", + "value": "info" + }, + { + "selected": false, + "text": "error", + "value": "error" + } + ], + "query": "info,error", + "queryValue": "", + "skipUrlSync": false, + "type": "custom" + }, + { + "allValue": ".+", + "current": { + "selected": true, + "text": [ + "All" + ], + "value": [ + "$__all" + ] + }, + "datasource": "${DS_LOKI}", + "definition": "label_values(app)", + "hide": 0, + "includeAll": true, + "multi": true, + "name": "controller", + "options": [], + "query": "label_values(app)", + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "sort": 0, + "type": "query" + }, + { + "allValue": ".+", + "current": { + "selected": true, + "text": [ + "flux-system" + ], + "value": [ + "flux-system" + ] + }, + "datasource": "${DS_LOKI}", + "definition": "label_values(namespace)", + "hide": 0, + "includeAll": true, + "multi": true, + "name": "namespace", + "options": [], + "query": "label_values(namespace)", + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "sort": 0, + "type": "query" + }, + { + "allValue": ".+", + "current": { + "selected": false, + "text": "All", + "value": "$__all" + }, + "datasource": "${DS_LOKI}", + "definition": "label_values(stream)", + "hide": 0, + "includeAll": true, + "multi": true, + "name": "stream", + "options": [], + "query": "label_values(stream)", + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "sort": 0, + "type": "query" + }, + { + "current": { + "selected": false, + "text": "Loki", + "value": "Loki" + }, + "hide": 0, + "includeAll": false, + "label": "Datasource", + "multi": false, + "name": "DS_LOKI", + "options": [], + "query": "loki", + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "type": "datasource" + } + ] + }, + "time": { + "from": "now-6h", + "to": "now" + }, + "timepicker": {}, + "timezone": "", + "title": "Flux Logs", + "uid": "flux-logs", + "version": 2 +} diff --git a/chart/ingress-certs.yaml b/chart/ingress-certs.yaml new file mode 100644 index 0000000000000000000000000000000000000000..1c5ce19faf642de8b0aeec964d27a987d66893ab --- /dev/null +++ b/chart/ingress-certs.yaml @@ -0,0 +1,172 @@ +istio: + gateways: + public: + tls: + key: | + -----BEGIN PRIVATE KEY----- + MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgY8guQ+hcKpHSgrm2 + A+GcFrrUtM8nb4L++naSjVQnogGhRANCAATKBRvdmdwoI2v36FYM8xpY7lI7r5KW + oj1lOKS6OwyAyGQyUYobCm/o7a2WJnhAkGFUFrrV1Z7N1lAGCmQJOOb8 + -----END PRIVATE KEY----- + cert: | + -----BEGIN CERTIFICATE----- + MIIDgzCCAwmgAwIBAgISBFMkWa9lPkFhl087yAiMkoEpMAoGCCqGSM49BAMDMDIx + CzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MQswCQYDVQQDEwJF + NTAeFw0yNDExMTgyMTA0NDRaFw0yNTAyMTYyMTA0NDNaMBwxGjAYBgNVBAMMESou + ZGV2LmJpZ2JhbmcubWlsMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEygUb3Znc + KCNr9+hWDPMaWO5SO6+SlqI9ZTikujsMgMhkMlGKGwpv6O2tliZ4QJBhVBa61dWe + zdZQBgpkCTjm/KOCAhMwggIPMA4GA1UdDwEB/wQEAwIHgDAdBgNVHSUEFjAUBggr + BgEFBQcDAQYIKwYBBQUHAwIwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQUd+z9mMaM + YJEbjoKZOyob74JP7vwwHwYDVR0jBBgwFoAUnytfzzwhT50Et+0rLMTGcIvS1w0w + VQYIKwYBBQUHAQEESTBHMCEGCCsGAQUFBzABhhVodHRwOi8vZTUuby5sZW5jci5v + cmcwIgYIKwYBBQUHMAKGFmh0dHA6Ly9lNS5pLmxlbmNyLm9yZy8wHAYDVR0RBBUw + E4IRKi5kZXYuYmlnYmFuZy5taWwwEwYDVR0gBAwwCjAIBgZngQwBAgEwggEEBgor + BgEEAdZ5AgQCBIH1BIHyAPAAdwCi4wrkRe+9rZt+OO1HZ3dT14JbhJTXK14bLMS5 + UKRH5wAAAZNBTSWpAAAEAwBIMEYCIQDxh3t5GRZRc+RdSV2GXQ7MhPmxNuaOK2K8 + +0G1nhV+oQIhANFeYVYgmPAjCdZeTPbvRX8DdcQXLrencMhjrO+NQcGFAHUAE0rf + GrWYQgl4DG/vTHqRpBa3I0nOWFdq367ap8Kr4CIAAAGTQU0mZAAABAMARjBEAiBd + yXAGHYvhbQaFdrYzQ191u5DoRP5wiiP16/8fYRfRDgIgAJeJwqBTR1+CG/BaIFir + xJHo82Ulcmo+IBLoL+5oJX0wCgYIKoZIzj0EAwMDaAAwZQIxAM0kS16QX1Qc9VtP + DypEln3luAegjWimBEi/45BDBeeOr1ofEL13oyDlKdP/6f+sWQIwLyEYai56gHmN + sSfBmgkdEEdz0M5HowiKAIahom+kg+Mj+0vvJeV3fREqC1joWzRB + -----END CERTIFICATE----- + -----BEGIN CERTIFICATE----- + MIIEVzCCAj+gAwIBAgIRAIOPbGPOsTmMYgZigxXJ/d4wDQYJKoZIhvcNAQELBQAw + TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh + cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMjQwMzEzMDAwMDAw + WhcNMjcwMzEyMjM1OTU5WjAyMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNTGV0J3Mg + RW5jcnlwdDELMAkGA1UEAxMCRTUwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQNCzqK + a2GOtu/cX1jnxkJFVKtj9mZhSAouWXW0gQI3ULc/FnncmOyhKJdyIBwsz9V8UiBO + VHhbhBRrwJCuhezAUUE8Wod/Bk3U/mDR+mwt4X2VEIiiCFQPmRpM5uoKrNijgfgw + gfUwDgYDVR0PAQH/BAQDAgGGMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcD + ATASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBSfK1/PPCFPnQS37SssxMZw + i9LXDTAfBgNVHSMEGDAWgBR5tFnme7bl5AFzgAiIyBpY9umbbjAyBggrBgEFBQcB + AQQmMCQwIgYIKwYBBQUHMAKGFmh0dHA6Ly94MS5pLmxlbmNyLm9yZy8wEwYDVR0g + BAwwCjAIBgZngQwBAgEwJwYDVR0fBCAwHjAcoBqgGIYWaHR0cDovL3gxLmMubGVu + Y3Iub3JnLzANBgkqhkiG9w0BAQsFAAOCAgEAH3KdNEVCQdqk0LKyuNImTKdRJY1C + 2uw2SJajuhqkyGPY8C+zzsufZ+mgnhnq1A2KVQOSykOEnUbx1cy637rBAihx97r+ + bcwbZM6sTDIaEriR/PLk6LKs9Be0uoVxgOKDcpG9svD33J+G9Lcfv1K9luDmSTgG + 6XNFIN5vfI5gs/lMPyojEMdIzK9blcl2/1vKxO8WGCcjvsQ1nJ/Pwt8LQZBfOFyV + XP8ubAp/au3dc4EKWG9MO5zcx1qT9+NXRGdVWxGvmBFRAajciMfXME1ZuGmk3/GO + koAM7ZkjZmleyokP1LGzmfJcUd9s7eeu1/9/eg5XlXd/55GtYjAM+C4DG5i7eaNq + cm2F+yxYIPt6cbbtYVNJCGfHWqHEQ4FYStUyFnv8sjyqU8ypgZaNJ9aVcWSICLOI + E1/Qv/7oKsnZCWJ926wU6RqG1OYPGOi1zuABhLw61cuPVDT28nQS/e6z95cJXq0e + K1BcaJ6fJZsmbjRgD5p3mvEf5vdQM7MCEvU0tHbsx2I5mHHJoABHb8KVBgWp/lcX + GWiWaeOyB7RP+OfDtvi2OsapxXiV7vNVs7fMlrRjY1joKaqmmycnBvAq14AEbtyL + sVfOS66B8apkeFX2NY4XPEYV4ZSCe8VHPrdrERk2wILG3T/EGmSIkCYVUMSnjmJd + VQD9F6Na/+zmXCc= + -----END CERTIFICATE----- + +addons: + keycloak: + ingress: + key: | + -----BEGIN PRIVATE KEY----- + MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgY8guQ+hcKpHSgrm2 + A+GcFrrUtM8nb4L++naSjVQnogGhRANCAATKBRvdmdwoI2v36FYM8xpY7lI7r5KW + oj1lOKS6OwyAyGQyUYobCm/o7a2WJnhAkGFUFrrV1Z7N1lAGCmQJOOb8 + -----END PRIVATE KEY----- + cert: | + -----BEGIN CERTIFICATE----- + MIIDgzCCAwmgAwIBAgISBFMkWa9lPkFhl087yAiMkoEpMAoGCCqGSM49BAMDMDIx + CzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MQswCQYDVQQDEwJF + NTAeFw0yNDExMTgyMTA0NDRaFw0yNTAyMTYyMTA0NDNaMBwxGjAYBgNVBAMMESou + ZGV2LmJpZ2JhbmcubWlsMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEygUb3Znc + KCNr9+hWDPMaWO5SO6+SlqI9ZTikujsMgMhkMlGKGwpv6O2tliZ4QJBhVBa61dWe + zdZQBgpkCTjm/KOCAhMwggIPMA4GA1UdDwEB/wQEAwIHgDAdBgNVHSUEFjAUBggr + BgEFBQcDAQYIKwYBBQUHAwIwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQUd+z9mMaM + YJEbjoKZOyob74JP7vwwHwYDVR0jBBgwFoAUnytfzzwhT50Et+0rLMTGcIvS1w0w + VQYIKwYBBQUHAQEESTBHMCEGCCsGAQUFBzABhhVodHRwOi8vZTUuby5sZW5jci5v + cmcwIgYIKwYBBQUHMAKGFmh0dHA6Ly9lNS5pLmxlbmNyLm9yZy8wHAYDVR0RBBUw + E4IRKi5kZXYuYmlnYmFuZy5taWwwEwYDVR0gBAwwCjAIBgZngQwBAgEwggEEBgor + BgEEAdZ5AgQCBIH1BIHyAPAAdwCi4wrkRe+9rZt+OO1HZ3dT14JbhJTXK14bLMS5 + UKRH5wAAAZNBTSWpAAAEAwBIMEYCIQDxh3t5GRZRc+RdSV2GXQ7MhPmxNuaOK2K8 + +0G1nhV+oQIhANFeYVYgmPAjCdZeTPbvRX8DdcQXLrencMhjrO+NQcGFAHUAE0rf + GrWYQgl4DG/vTHqRpBa3I0nOWFdq367ap8Kr4CIAAAGTQU0mZAAABAMARjBEAiBd + yXAGHYvhbQaFdrYzQ191u5DoRP5wiiP16/8fYRfRDgIgAJeJwqBTR1+CG/BaIFir + xJHo82Ulcmo+IBLoL+5oJX0wCgYIKoZIzj0EAwMDaAAwZQIxAM0kS16QX1Qc9VtP + DypEln3luAegjWimBEi/45BDBeeOr1ofEL13oyDlKdP/6f+sWQIwLyEYai56gHmN + sSfBmgkdEEdz0M5HowiKAIahom+kg+Mj+0vvJeV3fREqC1joWzRB + -----END CERTIFICATE----- + -----BEGIN CERTIFICATE----- + MIIEVzCCAj+gAwIBAgIRAIOPbGPOsTmMYgZigxXJ/d4wDQYJKoZIhvcNAQELBQAw + TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh + cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMjQwMzEzMDAwMDAw + WhcNMjcwMzEyMjM1OTU5WjAyMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNTGV0J3Mg + RW5jcnlwdDELMAkGA1UEAxMCRTUwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQNCzqK + a2GOtu/cX1jnxkJFVKtj9mZhSAouWXW0gQI3ULc/FnncmOyhKJdyIBwsz9V8UiBO + VHhbhBRrwJCuhezAUUE8Wod/Bk3U/mDR+mwt4X2VEIiiCFQPmRpM5uoKrNijgfgw + gfUwDgYDVR0PAQH/BAQDAgGGMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcD + ATASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBSfK1/PPCFPnQS37SssxMZw + i9LXDTAfBgNVHSMEGDAWgBR5tFnme7bl5AFzgAiIyBpY9umbbjAyBggrBgEFBQcB + AQQmMCQwIgYIKwYBBQUHMAKGFmh0dHA6Ly94MS5pLmxlbmNyLm9yZy8wEwYDVR0g + BAwwCjAIBgZngQwBAgEwJwYDVR0fBCAwHjAcoBqgGIYWaHR0cDovL3gxLmMubGVu + Y3Iub3JnLzANBgkqhkiG9w0BAQsFAAOCAgEAH3KdNEVCQdqk0LKyuNImTKdRJY1C + 2uw2SJajuhqkyGPY8C+zzsufZ+mgnhnq1A2KVQOSykOEnUbx1cy637rBAihx97r+ + bcwbZM6sTDIaEriR/PLk6LKs9Be0uoVxgOKDcpG9svD33J+G9Lcfv1K9luDmSTgG + 6XNFIN5vfI5gs/lMPyojEMdIzK9blcl2/1vKxO8WGCcjvsQ1nJ/Pwt8LQZBfOFyV + XP8ubAp/au3dc4EKWG9MO5zcx1qT9+NXRGdVWxGvmBFRAajciMfXME1ZuGmk3/GO + koAM7ZkjZmleyokP1LGzmfJcUd9s7eeu1/9/eg5XlXd/55GtYjAM+C4DG5i7eaNq + cm2F+yxYIPt6cbbtYVNJCGfHWqHEQ4FYStUyFnv8sjyqU8ypgZaNJ9aVcWSICLOI + E1/Qv/7oKsnZCWJ926wU6RqG1OYPGOi1zuABhLw61cuPVDT28nQS/e6z95cJXq0e + K1BcaJ6fJZsmbjRgD5p3mvEf5vdQM7MCEvU0tHbsx2I5mHHJoABHb8KVBgWp/lcX + GWiWaeOyB7RP+OfDtvi2OsapxXiV7vNVs7fMlrRjY1joKaqmmycnBvAq14AEbtyL + sVfOS66B8apkeFX2NY4XPEYV4ZSCe8VHPrdrERk2wILG3T/EGmSIkCYVUMSnjmJd + VQD9F6Na/+zmXCc= + -----END CERTIFICATE----- + vault: + ingress: + key: | + -----BEGIN PRIVATE KEY----- + MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgY8guQ+hcKpHSgrm2 + A+GcFrrUtM8nb4L++naSjVQnogGhRANCAATKBRvdmdwoI2v36FYM8xpY7lI7r5KW + oj1lOKS6OwyAyGQyUYobCm/o7a2WJnhAkGFUFrrV1Z7N1lAGCmQJOOb8 + -----END PRIVATE KEY----- + cert: | + -----BEGIN CERTIFICATE----- + MIIDgzCCAwmgAwIBAgISBFMkWa9lPkFhl087yAiMkoEpMAoGCCqGSM49BAMDMDIx + CzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MQswCQYDVQQDEwJF + NTAeFw0yNDExMTgyMTA0NDRaFw0yNTAyMTYyMTA0NDNaMBwxGjAYBgNVBAMMESou + ZGV2LmJpZ2JhbmcubWlsMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEygUb3Znc + KCNr9+hWDPMaWO5SO6+SlqI9ZTikujsMgMhkMlGKGwpv6O2tliZ4QJBhVBa61dWe + zdZQBgpkCTjm/KOCAhMwggIPMA4GA1UdDwEB/wQEAwIHgDAdBgNVHSUEFjAUBggr + BgEFBQcDAQYIKwYBBQUHAwIwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQUd+z9mMaM + YJEbjoKZOyob74JP7vwwHwYDVR0jBBgwFoAUnytfzzwhT50Et+0rLMTGcIvS1w0w + VQYIKwYBBQUHAQEESTBHMCEGCCsGAQUFBzABhhVodHRwOi8vZTUuby5sZW5jci5v + cmcwIgYIKwYBBQUHMAKGFmh0dHA6Ly9lNS5pLmxlbmNyLm9yZy8wHAYDVR0RBBUw + E4IRKi5kZXYuYmlnYmFuZy5taWwwEwYDVR0gBAwwCjAIBgZngQwBAgEwggEEBgor + BgEEAdZ5AgQCBIH1BIHyAPAAdwCi4wrkRe+9rZt+OO1HZ3dT14JbhJTXK14bLMS5 + UKRH5wAAAZNBTSWpAAAEAwBIMEYCIQDxh3t5GRZRc+RdSV2GXQ7MhPmxNuaOK2K8 + +0G1nhV+oQIhANFeYVYgmPAjCdZeTPbvRX8DdcQXLrencMhjrO+NQcGFAHUAE0rf + GrWYQgl4DG/vTHqRpBa3I0nOWFdq367ap8Kr4CIAAAGTQU0mZAAABAMARjBEAiBd + yXAGHYvhbQaFdrYzQ191u5DoRP5wiiP16/8fYRfRDgIgAJeJwqBTR1+CG/BaIFir + xJHo82Ulcmo+IBLoL+5oJX0wCgYIKoZIzj0EAwMDaAAwZQIxAM0kS16QX1Qc9VtP + DypEln3luAegjWimBEi/45BDBeeOr1ofEL13oyDlKdP/6f+sWQIwLyEYai56gHmN + sSfBmgkdEEdz0M5HowiKAIahom+kg+Mj+0vvJeV3fREqC1joWzRB + -----END CERTIFICATE----- + -----BEGIN CERTIFICATE----- + MIIEVzCCAj+gAwIBAgIRAIOPbGPOsTmMYgZigxXJ/d4wDQYJKoZIhvcNAQELBQAw + TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh + cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMjQwMzEzMDAwMDAw + WhcNMjcwMzEyMjM1OTU5WjAyMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNTGV0J3Mg + RW5jcnlwdDELMAkGA1UEAxMCRTUwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQNCzqK + a2GOtu/cX1jnxkJFVKtj9mZhSAouWXW0gQI3ULc/FnncmOyhKJdyIBwsz9V8UiBO + VHhbhBRrwJCuhezAUUE8Wod/Bk3U/mDR+mwt4X2VEIiiCFQPmRpM5uoKrNijgfgw + gfUwDgYDVR0PAQH/BAQDAgGGMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcD + ATASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBSfK1/PPCFPnQS37SssxMZw + i9LXDTAfBgNVHSMEGDAWgBR5tFnme7bl5AFzgAiIyBpY9umbbjAyBggrBgEFBQcB + AQQmMCQwIgYIKwYBBQUHMAKGFmh0dHA6Ly94MS5pLmxlbmNyLm9yZy8wEwYDVR0g + BAwwCjAIBgZngQwBAgEwJwYDVR0fBCAwHjAcoBqgGIYWaHR0cDovL3gxLmMubGVu + Y3Iub3JnLzANBgkqhkiG9w0BAQsFAAOCAgEAH3KdNEVCQdqk0LKyuNImTKdRJY1C + 2uw2SJajuhqkyGPY8C+zzsufZ+mgnhnq1A2KVQOSykOEnUbx1cy637rBAihx97r+ + bcwbZM6sTDIaEriR/PLk6LKs9Be0uoVxgOKDcpG9svD33J+G9Lcfv1K9luDmSTgG + 6XNFIN5vfI5gs/lMPyojEMdIzK9blcl2/1vKxO8WGCcjvsQ1nJ/Pwt8LQZBfOFyV + XP8ubAp/au3dc4EKWG9MO5zcx1qT9+NXRGdVWxGvmBFRAajciMfXME1ZuGmk3/GO + koAM7ZkjZmleyokP1LGzmfJcUd9s7eeu1/9/eg5XlXd/55GtYjAM+C4DG5i7eaNq + cm2F+yxYIPt6cbbtYVNJCGfHWqHEQ4FYStUyFnv8sjyqU8ypgZaNJ9aVcWSICLOI + E1/Qv/7oKsnZCWJ926wU6RqG1OYPGOi1zuABhLw61cuPVDT28nQS/e6z95cJXq0e + K1BcaJ6fJZsmbjRgD5p3mvEf5vdQM7MCEvU0tHbsx2I5mHHJoABHb8KVBgWp/lcX + GWiWaeOyB7RP+OfDtvi2OsapxXiV7vNVs7fMlrRjY1joKaqmmycnBvAq14AEbtyL + sVfOS66B8apkeFX2NY4XPEYV4ZSCe8VHPrdrERk2wILG3T/EGmSIkCYVUMSnjmJd + VQD9F6Na/+zmXCc= + -----END CERTIFICATE----- diff --git a/chart/templates/NOTES.txt b/chart/templates/NOTES.txt new file mode 100644 index 0000000000000000000000000000000000000000..12db9d817ed29f2ade3a3c823b3bdff0de051fc0 --- /dev/null +++ b/chart/templates/NOTES.txt @@ -0,0 +1,416 @@ +Thank you for supporting PlatformOne! + +{{ if $.Values.addons.gitlab.enabled }} +Gitlab is enabled. +Please follow the Gitlab online documentation for proper configuration. +This BigBang chart provides convenient enhancements to the Gitlab Package helm chart. +If you enable these features certain settings will be defaulted for you and any required secrets will be automatically created. +You should point to your cloud provider's RDS and object storage. +Gitlab will not provision storage for you. You will need to provision the database and the S3 buckets. +Here is an example of how to configure your deployment. + +addons: + gitlab: + enabled: true + hostnames: + gitlab: gitlab.example.mil + registry: registry.example.mil + sso: + enabled: true + label: "Platform One SSO" + client_id: "platform1_a8604cc9-f5e9-4656-802d-d05624370245_bb8-gitlab" + client_secret: "" + database: + host: postgres.example.mil + port: 5432 + username: gitlab + database: gitlab + password: mysecretpassword + objectstorage: + type: s3 + endpoint: https://s3.us-gov-west-1.amazonaws.com + region: us-gov-west-1 + accessKey: myaccesskey + accessSecret: mysecretkey + bucketPrefix: prod + +{{ if $.Values.addons.gitlab.objectStorage.endpoint }} +GITLAB: You have enabled Gitlab external object storage. +Here is the list of buckets that you must provision in your s3 service: +{{- if .Values.addons.gitlab.objectStorage.bucketPrefix }} +{{ .Values.addons.gitlab.objectStorage.bucketPrefix }}-gitlab-registry +{{ .Values.addons.gitlab.objectStorage.bucketPrefix }}-gitlab-lfs +{{ .Values.addons.gitlab.objectStorage.bucketPrefix }}-gitlab-artifacts +{{ .Values.addons.gitlab.objectStorage.bucketPrefix }}-gitlab-uploads +{{ .Values.addons.gitlab.objectStorage.bucketPrefix }}-gitlab-packages +{{ .Values.addons.gitlab.objectStorage.bucketPrefix }}-gitlab-mr-diffs +{{ .Values.addons.gitlab.objectStorage.bucketPrefix }}-gitlab-terraform-state +{{ .Values.addons.gitlab.objectStorage.bucketPrefix }}-gitlab-dependency-proxy +{{ .Values.addons.gitlab.objectStorage.bucketPrefix }}-gitlab-pseudo +{{ .Values.addons.gitlab.objectStorage.bucketPrefix }}-gitlab-backup +{{ .Values.addons.gitlab.objectStorage.bucketPrefix }}-gitlab-backup-tmp +{{- else }} +gitlab-registry +gitlab-lfs +gitlab-artifacts +gitlab-uploads +gitlab-packages +gitlab-mr-diffs +gitlab-terraform-state +gitlab-dependency-proxy +gitlab-pseudo +gitlab-backup +gitlab-backup-tmp +{{- end }} +{{- end }} + +{{ if $.Values.addons.gitlab.database.host }} +{{ else }} +PLATFORM ONE GITLAB WARNING: + You have enabled an internal postgres database in the BigBang configuration. + PlatformOne does not support this option for production deployments because your persistent data can be permanently lost. + This option should only be used for development or CI pipelines. +{{- end -}} + +{{ if $.Values.addons.gitlab.objectStorage.endpoint }} +{{ else }} +PLATFORM ONE GITLAB WARNING: + You have enabled a MinIO internal service in the BigBang configuration. + PlatformOne does not support this option for production deployments because your persistent data can be permanently lost. + This option should only be used for development or CI pipelines. +{{- end }} +{{- end }} + +{{- if $.Values.addons.anchore.enabled }} +Anchore is enabled. +{{- if not (and $.Values.addons.anchore.database.host $.Values.addons.anchore.database.port $.Values.addons.anchore.database.username $.Values.addons.anchore.database.password $.Values.addons.anchore.database.database) }} +PLATFORM ONE ANCHORE WARNING: + You have enabled an internal postgres database (main-db) in the values configuration. + PlatformOne does not support this option for production deployments. + This option should only be used for development or CI pipelines. +{{- end }} +{{- if $.Values.addons.anchore.enterprise.enabled }} +{{- if not (and $.Values.addons.anchore.redis.host $.Values.addons.anchore.redis.port $.Values.addons.anchore.redis.password) }} +PLATFORM ONE ANCHORE WARNING: + You have enabled an internal redis database in the values configuration. + PlatformOne does not support this option for production deployments. + This option should only be used for development or CI pipelines. +{{- end }} +{{- if not (and $.Values.addons.anchore.database.host $.Values.addons.anchore.database.port $.Values.addons.anchore.database.username $.Values.addons.anchore.database.password $.Values.addons.anchore.database.feeds_database) }} +PLATFORM ONE ANCHORE WARNING: + You have enabled an internal postgres database (feeds-db) in the values configuration. + PlatformOne does not support this option for production deployments. + This option should only be used for development or CI pipelines. +{{- end }} +{{- end }} +{{- if and ($.Values.addons.anchore.enterprise.enabled) (not $.Values.addons.anchore.enterprise.licenseYaml) }} +PLATFORM ONE ANCHORE WARNING: + You have enabled an enterprise Anchore in the values configuration, but not provided a license. + Your deployment will fail without a license, please review your configuration and supply a license + or disable the enterprise features. +{{- end }} +{{- if and ($.Values.addons.anchore.sso.enabled) (not $.Values.addons.anchore.enterprise.enabled) }} +PLATFORM ONE ANCHORE WARNING: + You have enabled SSO in the values configuration, but not enabled enterprise Anchore. + Your SSO configuration will be ignored, the Anchore UI is only available for enterprise deployments. +{{- end }} +{{- end }} + +{{- if and $.Values.eckOperator.enabled $.Values.elasticsearchKibana.enabled }} + {{- if $.Values.elasticsearchKibana.sso.enabled }} + {{- if and (not $.Values.elasticsearchKibana.license.trial) (not $.Values.elasticsearchKibana.license.keyJSON) }} +PLATFORM ONE LOGGING WARNING: + You have enabled SSO but not provided an enterprise license configuration to use. SSO is not functional without a license. + Edit the values for the eck-operator to specify a license key JSON or use the trial license for development. + {{- end }} + {{- end }} +{{- end }} + +{{- if and .Values.promtail.enabled .Values.fluentbit.enabled }} +PLATFORM ONE LOGGING WARNING: + You have enabled both Promtail and Fluentbit (log forwarders). This is not a supported configuration and you may see conflicts as a result of both applications attempting to ship logs. +{{- end }} + +{{- if and .Values.loki.enabled .Values.elasticsearchKibana.enabled }} +PLATFORM ONE LOGGING WARNING: + You have enabled both Loki and Elastic (log storage). This is not a supported configuration and you may see issues as a result of running both applications. + If using Elastic for other functionality, deploying both applications is acceptable. +{{- end }} + +{{- if and $.Values.loki.enabled (dig "values" "global" "createGlobalConfig" false $.Values.loki) }} +PLATFORM ONE LOKI WARNING: + You still have Loki global values set but this version of Loki has changed significantly, please review the latest production document within the Loki package repo: https://repo1.dso.mil/big-bang/product/packages/loki/-/blob/main/docs/production.md +{{- end }} + +{{- if and $.Values.loki.enabled (dig "values" "gel" "enabled" false $.Values.loki) }} +PLATFORM ONE LOKI WARNING: + You still have Loki gel values set but this version of Loki has changed significantly, please review the latest grafana enterprise document within the Loki package repo: https://repo1.dso.mil/big-bang/product/packages/loki/-/blob/main/docs/grafana-enterprise.md +{{- end }} + +{{- if and $.Values.jaeger.enabled .Values.tempo.enabled }} +PLATFORM ONE TRACING WARNING: + You have enabled both Jaeger and Tempo Tracing Engines. This is permitted during beta testing of Tempo. + After the beta period, only one Tracing engine will be supported at one time, with Tempo becoming the default supported engine over a direct Jaeger installation. Tempo will deploy with Tempo-Query, a Jaeger frontend with Tempo as the backend. +{{- end }} + +{{- if $.Values.addons.mattermost.enabled }} +Mattermost is enabled. +{{- with .Values.addons.mattermost.database }} +{{- if not (and .username .password .host .port .database .ssl_mode) }} +PLATFORM ONE MATTERMOST WARNING: + You have enabled an internal postgres database in the values configuration. + PlatformOne does not support this option for production deployments. + This option should only be used for development or CI pipelines. +{{- end }} +{{- end }} +{{- with .Values.addons.mattermost.objectStorage }} +{{- if not (and .endpoint .accessKey .accessSecret .bucket) }} +PLATFORM ONE MATTERMOST WARNING: + You have enabled an internal Minio instance in the values configuration. + PlatformOne does not support this option for production deployments. + This option should only be used for development or CI pipelines. +{{- end }} +{{- end }} +{{- if and (.Values.addons.mattermost.enterprise.enabled) (not .Values.addons.mattermost.enterprise.license) }} +PLATFORM ONE MATTERMOST WARNING: + You have enabled enterprise Mattermost in the values configuration, but not provided a license. + Make sure to go back and edit your values or ensure you add the license through the mattermost settings page. +{{- end }} +{{- end }} + +{{- if .Values.hostname }} +DEPRECATION NOTICE: + The top level yaml key "hostname" has been deprecated and replaced with "domain". + Please update your values override to use the "domain" key. +{{- end }} + +{{- if .Values.addons.nexus }} +DEPRECATION NOTICE: + .Values.addons.nexus has been deprecated and will be removed in a future Big Bang release. + Please reconfigure your values overrides to use .Values.addons.nexusRepositoryManager +{{- end }} + +{{- $nexusOldValues := default dict .Values.addons.nexus -}} +{{- $nexusValues := merge $nexusOldValues .Values.addons.nexusRepositoryManager -}} + +{{- with .Values }} +{{- if and .sso.url (coalesce .sso.oidc.host .sso.oidc.realm .sso.certificate_authority .sso.jwks .sso.jwks_uri .sso.client_id .sso.client_secret .sso.token_url .sso.auth_url .sso.secretName .elasticsearchKibana.sso.issuer .elasticsearchKibana.sso.auth_url .elasticsearchKibana.sso.token_url .elasticsearchKibana.sso.userinfo_url .elasticsearchKibana.sso.jwkset_url .elasticsearchKibana.sso.claims_principal .elasticsearchKibana.sso.endsession_url .elasticsearchKibana.sso.claims_group .elasticsearchKibana.sso.claims_mail .grafana.sso.grafana.auth_url .grafana.sso.grafana.token_url .grafana.sso.grafana.api_url .twistlock.sso.provider_name .twistlock.sso.issuer_uri .twistlock.sso.idp_url .twistlock.sso.console_url .twistlock.sso.cert .addons.argocd.sso.provider_name .addons.gitlab.sso.label .addons.gitlab.sso.issuer_uri .addons.gitlab.sso.end_session_uri .addons.gitlab.sso.uid_field .addons.mattermost.sso.auth_endpoint .addons.mattermost.sso.token_endpoint .addons.mattermost.sso.user_api_endpoint $nexusValues.sso.idp_data.idpMetadata .addons.sonarqube.sso.provider_name .addons.sonarqube.sso.certificate) }} +DEPRECATION NOTICE: + The following SSO keys have been deprecated. Deprecated keys will continue to work, but will be removed in a future release. Please update your overrides. + {{- if coalesce .sso.oidc.host .sso.oidc.realm .sso.certificate_authority .sso.jwks .sso.jwks_uri .sso.client_id .sso.client_secret .sso.token_url .sso.auth_url .sso.secretName }} + sso: + {{- if coalesce .sso.oidc.host .sso.oidc.realm }} + oidc: + {{- if .sso.oidc.host }} + # "host" removed. It is now implicitly defined in "sso.url". + host: {{ .sso.oidc.host }} + {{- end }} + {{- if .sso.oidc.realm }} + # "realm" removed. It is now implicitly defined in "sso.url". + realm: {{ .sso.oidc.realm }} + {{- end }} + {{- end }} + {{- if .sso.certificate_authority }} + # "certificate_authority" was moved to "sso.certificateAuthority.cert". + certificate_authority: {{ .sso.certificate_authority | trunc 27 }} + {{- end }} + {{- if .sso.jwks }} + # "jwks" was moved to "sso.oidc.jwks". If possible, switch to using "sso.oidc.jwksUri" to dynamically retrieve metadata instead + jwks: {{ .sso.jwks }} + {{- end }} + {{- if .sso.jwks_uri }} + # "jwks_uri" was moved to "sso.oidc.jwksUri" + jwks_uri: {{ .sso.jwks_uri }} + {{- end }} + {{- if .sso.client_id }} + # "client_id" was moved to "addons.authservice.sso.client_id" + client_id: {{ .sso.client_id }} + {{- end }} + {{- if .sso.client_secret }} + # "client_secret" was moved to "addons.authservice.sso.client_secret" + client_secret: {{ .sso.client_secret }} + {{- end }} + {{- if .sso.token_url }} + # "token_url" was moved to "sso.oidc.token" + token_url: {{ .sso.token_url }} + {{- end }} + {{- if .sso.auth_url }} + # "auth_url" was moved to "sso.oidc.authorization" + auth_url: {{ .sso.auth_url }} + {{- end }} + {{- if .sso.secretName }} + # "secretName" was moved to "sso.certificateAuthority.secretName" + secretName: {{ .sso.secretName }} + {{- end }} + {{- end }} + {{- if coalesce .elasticsearchKibana.sso.issuer .elasticsearchKibana.sso.auth_url .elasticsearchKibana.sso.token_url .elasticsearchKibana.sso.userinfo_url .elasticsearchKibana.sso.jwkset_url .elasticsearchKibana.sso.claims_principal .elasticsearchKibana.sso.endsession_url .elasticsearchKibana.sso.claims_group .elasticsearchKibana.sso.claims_mail }} + elasticsearchKibana: + sso: + {{- if .elasticsearchKibana.sso.issuer }} + # "issuer" was moved to "sso.url" + issuer: {{ .elasticsearchKibana.sso.issuer }} + {{- end }} + {{- if .elasticsearchKibana.sso.auth_url }} + # "auth_url" was moved to "sso.oidc.authorization" + auth_url: {{ .elasticsearchKibana.sso.auth_url }} + {{- end }} + {{- if .elasticsearchKibana.sso.token_url }} + # "token_url" was moved to "sso.oidc.token" + token_url: {{ .elasticsearchKibana.sso.token_url }} + {{- end }} + {{- if .elasticsearchKibana.sso.userinfo_url }} + # "userinfo_url" was moved to "sso.oidc.userinfo" + userinfo_url: {{ .elasticsearchKibana.sso.userinfo_url }} + {{- end }} + {{- if .elasticsearchKibana.sso.jwkset_url }} + # "jwkset_url" was moved to "sso.oidc.jwksUrl" + jwkset_url: {{ .elasticsearchKibana.sso.jwkset_url }} + {{- end }} + {{- if .elasticsearchKibana.sso.claims_principal }} + # "claims_principal" was moved to "sso.oidc.claims.username" + claims_principal: {{ .elasticsearchKibana.sso.claims_principal }} + {{- end }} + {{- if .elasticsearchKibana.sso.endsession_url }} + # "endsession_url" was moved to "sso.oidc.endsession" + endsession_url: {{ .elasticsearchKibana.sso.endsession_url }} + {{- end }} + {{- if .elasticsearchKibana.sso.claims_group }} + # "claims_group" was moved to "sso.oidc.claims.groups" + claims_group: {{ .elasticsearchKibana.sso.claims_group }} + {{- end }} + {{- if .elasticsearchKibana.sso.claims_mail }} + # "claims_mail" was moved to "sso.oidc.claims.email" + claims_mail: {{ .elasticsearchKibana.sso.claims_mail }} + {{- end }} + {{- end }} + {{- if coalesce .grafana.sso.grafana.auth_url .grafana.sso.grafana.token_url .grafana.sso.grafana.api_url }} + grafana: + sso: + grafana: + {{- if .grafana.sso.grafana.auth_url }} + # "auth_url" moved to "sso.oidc.authorization" + auth_url: {{ .grafana.sso.grafana.auth_url }} + {{- end }} + {{- if .grafana.sso.grafana.token_url }} + # "token_url" moved to "sso.oidc.token" + token_url: {{ .grafana.sso.grafana.token_url }} + {{- end }} + {{- if .grafana.sso.grafana.api_url }} + # "api_url" moved to "sso.oidc.userinfo" + api_url: {{ .grafana.sso.grafana.api_url }} + {{- end }} + {{- end }} + {{- if coalesce .twistlock.sso.provider_name .twistlock.sso.issuer_uri .twistlock.sso.idp_url .twistlock.sso.console_url .twistlock.sso.cert }} + twistlock: + sso: + {{- if .twistlock.sso.provider_name }} + # "provider_name" moved to "sso.name" + provider_name: {{ .twistlock.sso.provider_name }} + {{- end }} + {{- if .twistlock.sso.issuer_uri }} + # "issuer_uri" moved to "sso.url" + issuer_uri: {{ .twistlock.sso.issuer_uri }} + {{- end }} + {{- if .twistlock.sso.idp_url }} + # "idp_url" moved to "sso.saml.service" + idp_url: {{ .twistlock.sso.idp_url }} + {{- end }} + {{- if .twistlock.sso.console_url }} + # "console_url" deprecated. It will be created from "twistlock.values.istio.console.hosts" or "twistlock.<domain>" + console_url: {{ .twistlock.sso.console_url }} + {{- end }} + {{- if .twistlock.sso.cert }} + # "cert" is derived from "sso.saml.metadata" + cert: {{ .twistlock.sso.cert | trunc 27 }} + {{- end }} + {{- end }} + {{- if coalesce .addons.argocd.sso.provider_name .addons.gitlab.sso.label .addons.gitlab.sso.issuer_uri .addons.gitlab.sso.end_session_uri .addons.gitlab.sso.uid_field .addons.mattermost.sso.auth_endpoint .addons.mattermost.sso.token_endpoint .addons.mattermost.sso.user_api_endpoint $nexusValues.sso.idp_data.idpMetadata .addons.sonarqube.sso.provider_name .addons.sonarqube.sso.certificate }} + addons: + {{- if .addons.argocd.sso.provider_name }} + argocd: + sso: + # "provider_name" moved to "sso.name" + provider_name: {{ .addons.argocd.sso.provider_name }} + {{- end }} + {{- if coalesce .addons.gitlab.sso.label .addons.gitlab.sso.issuer_uri .addons.gitlab.sso.end_session_uri .addons.gitlab.sso.uid_field -}} + gitlab: + sso: + {{- if .addons.gitlab.sso.label }} + # "label" moved to "sso.name" + label: {{ .addons.gitlab.sso.label }} + {{- end }} + {{- if .addons.gitlab.sso.issuer_uri }} + # "issuer_uri" moved to "sso.url" + issuer_uri: {{ .addons.gitlab.sso.issuer_uri }} + {{- end }} + {{- if .addons.gitlab.sso.end_session_uri }} + # "end_session_uri" moved to "sso.oidc.endSession" + end_session_uri: {{ .addons.gitlab.sso.end_session_uri }} + {{- end }} + {{- if .addons.gitlab.sso.uid_field }} + # "uid_field" moved to "sso.oidc.claims.username" + uid_field: {{ .addons.gitlab.sso.uid_field }} + {{- end }} + {{- end }} + {{- if coalesce .addons.mattermost.sso.auth_endpoint .addons.mattermost.sso.token_endpoint .addons.mattermost.sso.user_api_endpoint }} + mattermost: + sso: + {{- if .addons.mattermost.sso.auth_endpoint }} + # "auth_endpoint" moved to "sso.oidc.authorization" + auth_endpoint: {{ .addons.mattermost.sso.auth_endpoint }} + {{- end }} + {{- if .addons.mattermost.sso.token_endpoint }} + # "token_endpoint" moved "sso.oidc.token" + token_endpoint: {{ .addons.mattermost.sso.token_endpoint }} + {{- end }} + {{- if .addons.mattermost.sso.user_api_endpoint }} + # "user_api_endpoint" moved to "sso.oidc.userinfo" + user_api_endpoint: {{ .addons.mattermost.sso.user_api_endpoint }} + {{- end }} + {{- end }} + {{- if coalesce $nexusValues.sso.idp_data.idpMetadata }} + nexus: + sso: + {{- if $nexusValues.sso.idp_data.idpMetadata }} + # idpMetadata moved to "sso.saml.metadata" + idpMetadata: {{ $nexusValues.sso.idp_data.idpMetadata | trunc 27 }} + {{- end }} + {{- end }} + {{- if coalesce .addons.sonarqube.sso.provider_name .addons.sonarqube.sso.certificate }} + sonarqube: + sso: + {{- if .addons.sonarqube.sso.provider_name }} + # "provider_name" moved to "sso.name" + provider_name: {{ .addons.sonarqube.sso.provider_name }} + {{- end }} + {{- if .addons.sonarqube.sso.certificate }} + # "certificate" derived from "sso.saml.metadata" + certificate: {{ .addons.sonarqube.sso.certificate | trunc 27 }} + {{- end }} + {{- end }} + {{- end }} + {{- end }} +{{- end }} + +{{- if .Values.addons.mattermostoperator }} +DEPRECATION NOTICE: + .Values.addons.mattermostoperator has been deprecated and will be removed in a future Big Bang release. + Please reconfigure your values overrides to use .Values.addons.mattermostOperator +{{- end }} + +{{- if and $.Values.addons.thanos.enabled (not (dig "values" "prometheus" "prometheusSpec" "replicas" "" $.Values.monitoring)) }} +PLATFORM ONE THANOS WARNING: + You have enabled Thanos with the default Prometheus replicas set to 1. For production deployments, + you can increase the number of replicas by adding: + monitoring: + values: + prometheus: + prometheusSpec: + +{{- end }} + +{{- if (eq .Values.loki.strategy "distributed") }} +PLATFORM ONE LOKI WARNING: + BigBang does not support the Loki Distributed deployment mode. For production deployments, + please set your strategy to "scalable" or "monolithic" +{{- end }} \ No newline at end of file diff --git a/chart/templates/_helpers.tpl b/chart/templates/_helpers.tpl new file mode 100644 index 0000000000000000000000000000000000000000..d2dc916a4e5feea1190d8fb4cdc344844b096531 --- /dev/null +++ b/chart/templates/_helpers.tpl @@ -0,0 +1,441 @@ +{{- define "values-bigbang" -}} +{{- /* + * bigbang.values-bigbang: Produce a stripped version of the bigbang variables + * in the root namespace suitable for inclusion in wrapper or package variables definitions + */ -}} +{{ toYaml (pick $ "domain" "openshift") }} +{{- /* For every top level map, if it has the enable key, pass it through. */ -}} +{{- range $bbpkg, $bbvals := $ -}} + {{- if kindIs "map" $bbvals -}} + {{- if hasKey $bbvals "enabled" }} +{{ $bbpkg }}: + {{- /* For network policies, we need all of its values. */ -}} + {{- if eq $bbpkg "networkPolicies" -}} + {{- toYaml $bbvals | nindent 2}} + {{- else }} + enabled: {{ $bbvals.enabled }} + {{- end -}} + {{- /* For addons, pass through the enable key. */ -}} + {{- else if eq $bbpkg "addons" }} +{{ $bbpkg }}: + {{- range $addpkg, $addvals := $bbvals -}} + {{- if hasKey $addvals "enabled" }} + {{ $addpkg }}: + enabled: {{ $addvals.enabled }} + {{- /* For authservice, the selector values are needed. */ -}} + {{- if and (eq $addpkg "authservice") (or (dig "values" "selector" "key" false $addvals) (dig "values" "selector" "value" false $addvals)) }} + values: + selector: + {{- if (dig "values" "selector" "key" false $addvals) }} + key: {{ $addvals.values.selector.key }} + {{- end -}} + {{- if (dig "values" "selector" "value" false $addvals) }} + value: {{ $addvals.values.selector.key }} + {{- end -}} + {{- end -}} + {{- end -}} + {{- end -}} + {{- end -}} + {{- end -}} +{{- end -}} +{{- end }} + +{{- define "imagePullSecret" }} + {{- if .Values.registryCredentials -}} + {{- $credType := typeOf .Values.registryCredentials -}} + {{- /* If we have a list, embed that here directly. This allows for complex configuration from configmap, downward API, etc. */ -}} + {{- if eq $credType "[]interface {}" -}} + {{- include "multipleCreds" . | b64enc }} + {{- else if eq $credType "map[string]interface {}" }} + {{- /* If we have a map, treat those as key-value pairs. */ -}} + {{- if and .Values.registryCredentials.username .Values.registryCredentials.password }} + {{- with .Values.registryCredentials }} + {{- printf "{\"auths\":{\"%s\":{\"username\":\"%s\",\"password\":\"%s\",\"email\":\"%s\",\"auth\":\"%s\"}}}" .registry .username .password .email (printf "%s:%s" .username .password | b64enc) | b64enc }} + {{- end }} + {{- end }} + {{- end -}} + {{- end }} +{{- end }} + +{{- define "multipleCreds" -}} +{ + "auths": { + {{- range $i, $m := .Values.registryCredentials }} + {{- /* Only create entry if resulting entry is valid */}} + {{- if and $m.registry $m.username $m.password }} + {{- if $i }},{{ end }} + "{{ $m.registry }}": { + "username": "{{ $m.username }}", + "password": "{{ $m.password }}", + "email": "{{ $m.email | default "" }}", + "auth": "{{ printf "%s:%s" $m.username $m.password | b64enc }}" + } + {{- end }} + {{- end }} + } +} +{{- end }} + +{{/* +Build the appropriate spec.ref.{} given git branch, commit values +*/}} +{{- define "validRef" -}} +{{- if .commit -}} +{{- if not .branch -}} +{{- fail "A valid branch is required when a commit is specified!" -}} +{{- end -}} +branch: {{ .branch | quote }} +commit: {{ .commit }} +{{- else if .semver -}} +semver: {{ .semver | quote }} +{{- else if .tag -}} +tag: {{ .tag }} +{{- else -}} +branch: {{ .branch | quote }} +{{- end -}} +{{- end -}} + +{{/* +Build the appropriate git credentials secret for BB wide git repositories +*/}} +{{- define "gitCredsGlobal" -}} +{{- if .Values.git.existingSecret -}} +secretRef: + name: {{ .Values.git.existingSecret }} +{{- else if coalesce .Values.git.credentials.username .Values.git.credentials.password .Values.git.credentials.caFile .Values.git.credentials.privateKey .Values.git.credentials.publicKey .Values.git.credentials.knownHosts "" -}} +{{- /* Input validation happens in git-credentials.yaml template */ -}} +secretRef: + name: {{ $.Release.Name }}-git-credentials +{{- end -}} +{{- end -}} + +{{/* +Build the appropriate git credentials secret for individual package and BB wide private git repositories +*/}} +{{- define "gitCredsExtended" -}} +{{- if .packageGitScope.existingSecret -}} +secretRef: + name: {{ .packageGitScope.existingSecret }} +{{- else if and (.packageGitScope.credentials) (coalesce .packageGitScope.credentials.username .packageGitScope.credentials.password .packageGitScope.credentials.caFile .packageGitScope.credentials.privateKey .packageGitScope.credentials.publicKey .packageGitScope.credentials.knownHosts "") -}} +{{- /* Input validation happens in git-credentials.yaml template */ -}} +secretRef: + name: {{ .releaseName }}-{{ .name }}-git-credentials +{{- else -}} +{{/* If no credentials are specified, use the global credentials in the rootScope */}} +{{- include "gitCredsGlobal" .rootScope }} +{{- end -}} +{{- end -}} + +{{/* +Pointer to the appropriate git credentials template +*/}} +{{- define "gitCreds" -}} +{{- include "gitCredsGlobal" . }} +{{- end -}} + +{{/* +Build common set of file extensions to include/exclude +*/}} +{{- define "gitIgnore" -}} + ignore: | + # exclude file extensions + /**/*.md + /**/*.txt + /**/*.sh + !/chart/tests/scripts/*.sh + !/chart/wait/*.sh +{{- end -}} + +{{/* +Common labels for all objects +*/}} +{{- define "commonLabels" -}} +app.kubernetes.io/instance: {{ .Release.Name }} +app.kubernetes.io/version: {{ default .Chart.Version .Chart.AppVersion | replace "+" "_" }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +app.kubernetes.io/part-of: "bigbang" +helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} +{{- end -}} + +{{- define "values-secret" -}} +apiVersion: v1 +kind: Secret +metadata: + name: {{ .root.Release.Name }}-{{ .name }}-values + namespace: {{ .root.Release.Namespace }} +type: generic +stringData: + common: "" + defaults: {{- toYaml .defaults | nindent 4 }} + overlays: | + {{- toYaml .package.values | nindent 4 }} +{{- end -}} + +{{/* +bigbang.addValueIfSet can be used to nil check parameters before adding them to the values. + Expects a list with the following params: + * [0] - (string) <yaml_key_to_add> + * [1] - (interface{}) <value_to_check> + + No output is generated if <value> is undefined, however, explicitly set empty values + (i.e. `username=""`) will be passed along. All string fields will be quoted. + + Example command: + - `{{ (list "name" .username) | include "bigbang.addValueIfSet" }}` + * When `username: Aniken` + -> `name: "Aniken"` + * When `username: ""` + -> `name: ""` + * When username is not defined + -> no output +*/}} +{{- define "bigbang.addValueIfSet" -}} + {{- $key := (index . 0) }} + {{- $value := (index . 1) }} + {{- /*If the value is explicitly set (even if it's empty)*/}} + {{- if not (kindIs "invalid" $value) }} + {{- /*Handle strings*/}} + {{- if kindIs "string" $value }} + {{- printf "\n%s" $key }}: {{ $value | quote }} + {{- /*Hanldle slices*/}} + {{- else if kindIs "slice" $value }} + {{- printf "\n%s" $key }}: + {{- range $value }} + {{- if kindIs "string" . }} + {{- printf "\n - %s" (. | quote) }} + {{- else }} + {{- printf "\n - %v" . }} + {{- end }} + {{- end }} + {{- /*Handle other types (no quotes)*/}} + {{- else }} + {{- printf "\n%s" $key }}: {{ $value }} + {{- end }} + {{- end }} +{{- end -}} + +{{/* +Annotation for Istio version +*/}} +{{- define "istioAnnotation" -}} +{{- if (eq .Values.istio.sourceType "git") -}} +{{- if .Values.istio.git.semver -}} +bigbang.dev/istioVersion: {{ .Values.istio.git.semver | trimSuffix (regexFind "-bb.*" .Values.istio.git.semver) }}{{ if .Values.istio.enterprise }}-enterprise{{ end }} +{{- else if .Values.istio.git.tag -}} +bigbang.dev/istioVersion: {{ .Values.istio.git.tag | trimSuffix (regexFind "-bb.*" .Values.istio.git.tag) }}{{ if .Values.istio.enterprise }}-enterprise{{ end }} +{{- else if .Values.istio.git.branch -}} +bigbang.dev/istioVersion: {{ .Values.istio.git.branch }}{{ if .Values.istio.enterprise }}-enterprise{{ end }} +{{- end -}} +{{- else -}} +bigbang.dev/istioVersion: {{ .Values.istio.helmRepo.tag }}{{ if .Values.istio.enterprise }}-enterprise{{ end }} +{{- end -}} +{{- end -}} + +{{- /* Helpers below this line are in support of the Big Bang extensibility feature */ -}} + +{{- /* Converts the string in . to a legal Kubernetes resource name */ -}} +{{- define "resourceName" -}} + {{- regexReplaceAll "\\W+" . "-" | trimPrefix "-" | trunc 63 | trimSuffix "-" | kebabcase -}} +{{- end -}} + +{{- /* Returns a space separated string of unique namespaces where `<package>.enabled` and key held in `.constraint` are true */ -}} +{{- /* [Optional] Set `.constraint` to the key under <package> holding a boolean that must be true to be enabled */ -}} +{{- /* [Optional] Set `.default` to `true` to enable a `true` result when the `constraint` key is not found */ -}} +{{- /* To use: $ns := compact (splitList " " (include "uniqueNamespaces" (merge (dict "constraint" "some.boolean" "default" true) .))) */ -}} +{{- define "uniqueNamespaces" -}} + {{- $namespaces := list -}} + {{- range $pkg, $vals := .Values.packages -}} + {{- if (dig "enabled" true $vals) -}} + {{- $constraint := $vals -}} + {{- range $key := split "." (default "" $.constraint) -}} + {{- $constraint = (dig $key dict $constraint) -}} + {{- end -}} + {{- if (ternary $constraint (default false $.default) (kindIs "bool" $constraint)) -}} + {{- $namespaces = append $namespaces (dig "namespace" "name" (include "resourceName" $pkg) $vals) -}} + {{- end -}} + {{- end -}} + {{- end -}} + {{- join " " (uniq $namespaces) | trim -}} +{{- end -}} + +{{- /* Prints istio version */ -}} +{{- define "istioVersion" -}} + {{- regexReplaceAll "-bb.+$" (coalesce .Values.istio.git.semver .Values.istio.git.tag .Values.istio.git.branch) "" -}} +{{- end -}} + +{{- /* Returns an SSO host */ -}} +{{- define "sso.host" -}} + {{- coalesce .Values.sso.oidc.host (regexReplaceAll ".*//([^/]*)/?.*" .Values.sso.url "${1}") -}} +{{- end -}} + +{{- /* Returns an SSO realm */ -}} +{{- define "sso.realm" -}} + {{- coalesce .Values.sso.oidc.realm (regexReplaceAll ".*/realms/([^/]*)" .Values.sso.url "${1}") (regexReplaceAll "\\W+" .Values.sso.name "") -}} +{{- end -}} + +{{- /* Returns the SSO base URL */ -}} +{{- define "sso.url" -}} + {{- if and .Values.sso.oidc.host .Values.sso.oidc.realm -}} + {{- printf "https://%s/auth/realms/%s" .Values.sso.oidc.host .Values.sso.oidc.realm -}} + {{- else -}} + {{- tpl (default "" .Values.sso.url) . -}} + {{- end -}} +{{- end -}} + +{{- /* Returns the SSO auth url (OIDC) */ -}} +{{- define "sso.oidc.auth" -}} + {{- if .Values.sso.auth_url -}} + {{- tpl (default "" .Values.sso.auth_url) . -}} + {{- else if and .Values.sso.oidc.host .Values.sso.oidc.realm -}} + {{- printf "%s/protocol/openid-connect/auth" (include "sso.url" .) -}} + {{- else -}} + {{- tpl (dig "oidc" "authorization" (printf "%s/protocol/openid-connect/auth" (include "sso.url" .)) .Values.sso) . -}} + {{- end -}} +{{- end -}} + +{{- /* Returns the SSO token url (OIDC) */ -}} +{{- define "sso.oidc.token" -}} + {{- if .Values.sso.token_url -}} + {{- tpl (default "" .Values.sso.token_url) . -}} + {{- else if and .Values.sso.oidc.host .Values.sso.oidc.realm -}} + {{- printf "%s/protocol/openid-connect/token" (include "sso.url" .) -}} + {{- else -}} + {{- tpl (dig "oidc" "token" (printf "%s/protocol/openid-connect/token" (include "sso.url" .)) .Values.sso) . -}} + {{- end -}} +{{- end -}} + +{{- /* Returns the SSO userinfo url (OIDC) */ -}} +{{- define "sso.oidc.userinfo" -}} + {{- if and .Values.sso.oidc.host .Values.sso.oidc.realm -}} + {{- printf "%s/protocol/openid-connect/userinfo" (include "sso.url" .) -}} + {{- else -}} + {{- tpl (dig "oidc" "userinfo" (printf "%s/protocol/openid-connect/userinfo" (include "sso.url" .)) .Values.sso) . -}} + {{- end -}} +{{- end -}} + +{{- /* Returns the SSO jwks url (OIDC) */ -}} +{{- define "sso.oidc.jwksuri" -}} + {{- if .Values.sso.jwks_uri -}} + {{- tpl (default "" .Values.sso.jwks_uri) . -}} + {{- else if and .Values.sso.oidc.host .Values.sso.oidc.realm -}} + {{- printf "%s/protocol/openid-connect/certs" (include "sso.url" .) -}} + {{- else -}} + {{- tpl (dig "oidc" "jwksUri" (printf "%s/protocol/openid-connect/certs" (include "sso.url" .)) .Values.sso) . -}} + {{- end -}} +{{- end -}} + +{{- /* Returns the SSO end session url (OIDC) */ -}} +{{- define "sso.oidc.endsession" -}} + {{- if and .Values.sso.oidc.host .Values.sso.oidc.realm -}} + {{- printf "%s/protocol/openid-connect/logout" (include "sso.url" .) -}} + {{- else -}} + {{- tpl (dig "oidc" "endSession" (printf "%s/protocol/openid-connect/logout" (include "sso.url" .)) .Values.sso) . -}} + {{- end -}} +{{- end -}} + +{{- /* Returns the single sign on service (SAML) */ -}} +{{- define "sso.saml.service" -}} + {{- if and .Values.sso.oidc.host .Values.sso.oidc.realm -}} + {{- printf "%s/protocol/saml" (include "sso.url" .) -}} + {{- else -}} + {{- tpl (dig "saml" "service" (printf "%s/protocol/saml" (include "sso.url" .)) .Values.sso) . -}} + {{- end -}} +{{- end -}} + +{{- /* Returns the single sign on entity descriptor (SAML) */ -}} +{{- define "sso.saml.descriptor" -}} + {{- if and .Values.sso.oidc.host .Values.sso.oidc.realm -}} + {{- printf "%s/descriptor" (include "sso.saml.service" .) -}} + {{- else -}} + {{- tpl (dig "saml" "entityDescriptor" (printf "%s/descriptor" (include "sso.saml.service" .)) .Values.sso) . -}} + {{- end -}} +{{- end -}} + +{{- /* Returns the signing cert (no headers) from the SAML metadata */ -}} +{{- define "sso.saml.cert" -}} + {{- $cert := dig "saml" "metadata" "" .Values.sso -}} + {{- if $cert -}} + {{- $cert := regexFind "<md:IDPSSODescriptor[\\s>][\\s\\S]*?</md:IDPSSODescriptor[\\s>]" $cert -}} + {{- $cert = regexFind "<md:KeyDescriptor[\\s>][^>]*?use=\"signing\"[\\s\\S]*?</md:KeyDescriptor[\\s>]" $cert -}} + {{- $cert = regexFind "<ds:KeyInfo[\\s>][\\s\\S]*?</ds:KeyInfo[\\s>]" $cert -}} + {{- $cert = regexFind "<ds:X509Data[\\s>][\\s\\S]*?</ds:X509Data[\\s>]" $cert -}} + {{- $cert = regexFind "<ds:X509Certificate[\\s>][\\s\\S]*?</ds:X509Certificate[\\s>]" $cert -}} + {{- $cert = regexReplaceAll "<ds:X509Certificate[^>]*?>\\s*([\\s\\S]*?)</ds:X509Certificate[\\s>]" $cert "${1}" -}} + {{- $cert = regexReplaceAll "\\s*" $cert "" -}} + {{- required "X.509 signing certificate could not be found in sso.saml.metadata!" $cert -}} + {{- end -}} +{{- end -}} + +{{- /* Returns the signing cert with headers from the SAML metadata */ -}} +{{- define "sso.saml.cert.withheaders" -}} + {{- $cert := include "sso.saml.cert" . -}} + {{- if $cert -}} + {{- printf "-----BEGIN CERTIFICATE-----\n%s\n-----END CERTIFICATE-----" $cert -}} + {{- end -}} +{{- end -}} + +{{- /* +Returns the git credentails secret for the given scope and name +*/ -}} +{{- define "gitCredsSecret" -}} +{{- $name := .name }} +{{- $releaseName := .releaseName }} +{{- $releaseNamespace := .releaseNamespace }} +{{- with .targetScope -}} +{{- if and (eq .sourceType "git") .enabled }} +{{- if .git }} +{{- with .git -}} +{{- if not .existingSecret }} +{{- if .credentials }} +{{- if coalesce .credentials.username .credentials.password .credentials.caFile .credentials.privateKey .credentials.publicKey .credentials.knownHosts -}} +{{- $http := coalesce .credentials.username .credentials.password .credentials.caFile "" }} +{{- $ssh := coalesce .credentials.privateKey .credentials.publicKey .credentials.knownHosts "" }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ $releaseName }}-{{ $name }}-git-credentials + namespace: {{ $releaseNamespace }} +type: Opaque +data: + {{- if $http }} + {{- if .credentials.caFile }} + caFile: {{ .credentials.caFile | b64enc }} + {{- end }} + {{- if and .credentials.username (not .credentials.password ) }} + {{- printf "%s - When using http git username, password must be specified" $name | fail }} + {{- end }} + {{- if and .credentials.password (not .credentials.username ) }} + {{- printf "%s - When using http git password, username must be specified" $name | fail }} + {{- end }} + {{- if and .credentials.username .credentials.password }} + username: {{ .credentials.username | b64enc }} + password: {{ .credentials.password | b64enc }} + {{- end }} + {{- else }} + {{- if not (and (and .credentials.privateKey .credentials.publicKey) .credentials.knownHosts) }} + {{- printf "%s - When using ssh git credentials, privateKey, publicKey, and knownHosts must all be specified" $name | fail }} + {{- end }} + identity: {{ .credentials.privateKey | b64enc }} + identity.pub: {{ .credentials.publicKey | b64enc }} + known_hosts: {{ .credentials.knownHosts | b64enc }} + {{- end }} +{{- end }} +{{- end }} +{{- end }} +{{- end }} +{{- end }} +{{- end }} +{{- end }} +{{- end }} + +{{- /* Returns type of Helm Repository */ -}} +{{- define "getRepoType" -}} + {{- $repoName := .repoName -}} + {{- range .allRepos -}} + {{- if eq .name $repoName -}} + {{- print .type -}} + {{- end -}} + {{- end -}} +{{- end -}} + + diff --git a/chart/templates/alloy/git-credentials.yaml b/chart/templates/alloy/git-credentials.yaml new file mode 100644 index 0000000000000000000000000000000000000000..ef7d50ce33819bbd28d8a394e95cd914f186a75e --- /dev/null +++ b/chart/templates/alloy/git-credentials.yaml @@ -0,0 +1,7 @@ +{{- $gitCredsSecretDict := dict + "name" "alloy" + "targetScope" .Values.addons.alloy + "releaseName" .Release.Name + "releaseNamespace" .Release.Namespace +}} +{{- include "gitCredsSecret" $gitCredsSecretDict | nindent 0 -}} diff --git a/chart/templates/alloy/gitrepository.yaml b/chart/templates/alloy/gitrepository.yaml new file mode 100644 index 0000000000000000000000000000000000000000..2d5a4cad14896210d94aa01ca8a13a36480a3cad --- /dev/null +++ b/chart/templates/alloy/gitrepository.yaml @@ -0,0 +1,23 @@ +{{- if and (eq .Values.addons.alloy.sourceType "git") (not .Values.offline) .Values.addons.alloy.enabled }} +{{- $gitCredsDict := dict + "name" "alloy" + "packageGitScope" .Values.addons.alloy.git + "rootScope" . + "releaseName" .Release.Name +}} +apiVersion: source.toolkit.fluxcd.io/v1 +kind: GitRepository +metadata: + name: alloy + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: alloy + {{- include "commonLabels" . | nindent 4}} +spec: + interval: {{ .Values.flux.interval }} + url: {{ .Values.addons.alloy.git.repo }} + ref: + {{- include "validRef" .Values.addons.alloy.git | nindent 4 }} + {{ include "gitIgnore" . }} + {{- include "gitCredsExtended" $gitCredsDict | nindent 2 }} +{{- end }} diff --git a/chart/templates/alloy/helmrelease.yaml b/chart/templates/alloy/helmrelease.yaml new file mode 100644 index 0000000000000000000000000000000000000000..5591edfda9b304fcaa0a17470c40de5f9d751e2a --- /dev/null +++ b/chart/templates/alloy/helmrelease.yaml @@ -0,0 +1,74 @@ +{{- $fluxSettingsMonitoring := merge .Values.addons.alloy.flux .Values.flux -}} +{{- if .Values.addons.alloy.enabled }} +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + name: alloy + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: alloy + {{- include "commonLabels" . | nindent 4}} + annotations: + checksum/bigbang-values: {{ include (print $.Template.BasePath "/alloy/values.yaml") . | sha256sum }} +spec: + targetNamespace: monitoring + chart: + spec: + {{- if eq .Values.addons.alloy.sourceType "git" }} + chart: {{ .Values.addons.alloy.git.path }} + sourceRef: + kind: GitRepository + name: alloy + namespace: {{ .Release.Namespace }} + {{- else }} + chart: {{ .Values.addons.alloy.helmRepo.chartName }} + version: {{ .Values.addons.alloy.helmRepo.tag }} + sourceRef: + kind: HelmRepository + name: {{ .Values.addons.alloy.helmRepo.repoName }} + namespace: {{ .Release.Namespace }} + {{- $repoType := include "getRepoType" (dict "repoName" .Values.addons.alloy.helmRepo.repoName "allRepos" $.Values.helmRepositories) -}} + {{- if (and .Values.addons.alloy.helmRepo.cosignVerify (eq $repoType "oci")) }} # Needs to be an OCI repo + verify: + provider: cosign + secretRef: + name: {{ printf "%s-cosign-pub" .Values.addons.alloy.helmRepo.repoName }} + {{- end }} + {{- end }} + interval: 5m + + {{- toYaml $fluxSettingsMonitoring | nindent 2 }} + + {{- if .Values.addons.alloy.postRenderers }} + postRenderers: + {{ toYaml .Values.addons.alloy.postRenderers | nindent 4 }} + {{- end }} + valuesFrom: + - name: {{ .Release.Name }}-alloy-values + kind: Secret + valuesKey: "common" + - name: {{ .Release.Name }}-alloy-values + kind: Secret + valuesKey: "defaults" + - name: {{ .Release.Name }}-alloy-values + kind: Secret + valuesKey: "overlays" + + # TODO: DRY this up + {{- if or .Values.gatekeeper.enabled .Values.istio.enabled .Values.kyvernoPolicies.enabled .Values.monitoring.enabled }} + dependsOn: + {{- if .Values.istio.enabled }} + - name: istio + namespace: {{ .Release.Namespace }} + {{- end }} + {{- if .Values.gatekeeper.enabled }} + - name: gatekeeper + namespace: {{ .Release.Namespace }} + {{- end }} + {{- if .Values.kyvernoPolicies.enabled }} + - name: kyverno-policies + namespace: {{ .Release.Namespace }} + {{- end }} + {{- end }} +{{- end }} + diff --git a/chart/templates/alloy/imagepullsecret.yaml b/chart/templates/alloy/imagepullsecret.yaml new file mode 100644 index 0000000000000000000000000000000000000000..8fce1a127f4dac21a9ad5849223a56dbe62f2c07 --- /dev/null +++ b/chart/templates/alloy/imagepullsecret.yaml @@ -0,0 +1,16 @@ +{{- if and (not .Values.monitoring.enabled) (not .Values.grafana.enabled ) .Values.addons.alloy.enabled }} +{{- if ( include "imagePullSecret" . ) }} +apiVersion: v1 +kind: Secret +metadata: + name: private-registry + namespace: monitoring + labels: + app.kubernetes.io/name: alloy + {{- include "commonLabels" . | nindent 4}} +type: kubernetes.io/dockerconfigjson +data: + .dockerconfigjson: {{ template "imagePullSecret" . }} +{{- end }} +{{- end }} + diff --git a/chart/templates/alloy/namespace.yaml b/chart/templates/alloy/namespace.yaml new file mode 100644 index 0000000000000000000000000000000000000000..b8c80daa6032cb02a34c0e18fd358312a5c42bb2 --- /dev/null +++ b/chart/templates/alloy/namespace.yaml @@ -0,0 +1,11 @@ +{{- if and (not .Values.monitoring.enabled) (not .Values.grafana.enabled ) .Values.addons.alloy.enabled }} +apiVersion: v1 +kind: Namespace +metadata: + name: monitoring + labels: + app.kubernetes.io/name: monitoring + app.kubernetes.io/component: "core" + {{- include "commonLabels" . | nindent 4}} + istio-injection: {{ dig "istio" "injection" "enabled" .Values.grafana }} +{{- end }} diff --git a/chart/templates/alloy/values.yaml b/chart/templates/alloy/values.yaml new file mode 100644 index 0000000000000000000000000000000000000000..e2e813ebba2b1a850f3c1a6f488b7e78fa29daf5 --- /dev/null +++ b/chart/templates/alloy/values.yaml @@ -0,0 +1,14 @@ +{{- /* Create secret */ -}} +{{- if .Values.addons.alloy.enabled }} +{{- include "values-secret" (dict "root" $ "package" .Values.addons.alloy "name" "alloy" "defaults" (include "bigbang.defaults.alloy" .)) }} +{{- end }} + +{{- define "bigbang.defaults.alloy" -}} +monitoring: + enabled: {{ .Values.monitoring.enabled }} + +networkPolicies: + enabled: {{ .Values.networkPolicies.enabled }} + controlPlaneCidr: {{ .Values.networkPolicies.controlPlaneCidr }} + +{{- end }} \ No newline at end of file diff --git a/chart/templates/anchore/git-credentials.yaml b/chart/templates/anchore/git-credentials.yaml new file mode 100644 index 0000000000000000000000000000000000000000..0fadae2c24b8f91b73014788d9f317da95e2aa94 --- /dev/null +++ b/chart/templates/anchore/git-credentials.yaml @@ -0,0 +1,7 @@ +{{- $gitCredsSecretDict := dict + "name" "anchore" + "targetScope" .Values.addons.anchore + "releaseName" .Release.Name + "releaseNamespace" .Release.Namespace +}} +{{- include "gitCredsSecret" $gitCredsSecretDict | nindent 0 -}} diff --git a/chart/templates/anchore/gitrepository.yaml b/chart/templates/anchore/gitrepository.yaml new file mode 100644 index 0000000000000000000000000000000000000000..952453afd7f9d6af7e18c50010fa39355cbb6559 --- /dev/null +++ b/chart/templates/anchore/gitrepository.yaml @@ -0,0 +1,20 @@ +{{- if and (eq .Values.addons.anchore.sourceType "git") .Values.addons.anchore.enabled }} +{{- $gitCredsDict := dict + "name" "anchore" + "packageGitScope" .Values.addons.anchore.git + "rootScope" . + "releaseName" .Release.Name +}} +apiVersion: source.toolkit.fluxcd.io/v1 +kind: GitRepository +metadata: + name: anchore + namespace: {{ .Release.Namespace }} +spec: + interval: {{ .Values.flux.interval }} + url: {{ .Values.addons.anchore.git.repo }} + ref: + {{- include "validRef" .Values.addons.anchore.git | nindent 4 }} + {{ include "gitIgnore" . }} + {{- include "gitCredsExtended" $gitCredsDict | nindent 2 }} +{{- end }} diff --git a/chart/templates/anchore/helmrelease.yaml b/chart/templates/anchore/helmrelease.yaml new file mode 100644 index 0000000000000000000000000000000000000000..07aacca2743b9bd5daf64f12a920241d0b9bd976 --- /dev/null +++ b/chart/templates/anchore/helmrelease.yaml @@ -0,0 +1,67 @@ +{{- $fluxSettingsAnchore := merge .Values.addons.anchore.flux .Values.flux -}} +{{- if .Values.addons.anchore.enabled }} +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + name: anchore + namespace: {{ .Release.Namespace }} + annotations: + checksum/bigbang-values: {{ include (print $.Template.BasePath "/anchore/values.yaml") . | sha256sum }} +spec: + releaseName: anchore + targetNamespace: anchore + chart: + spec: + {{- if eq .Values.addons.anchore.sourceType "git" }} + chart: {{ .Values.addons.anchore.git.path }} + sourceRef: + kind: GitRepository + name: anchore + namespace: {{ .Release.Namespace }} + {{- else }} + chart: {{ .Values.addons.anchore.helmRepo.chartName }} + version: {{ .Values.addons.anchore.helmRepo.tag }} + sourceRef: + kind: HelmRepository + name: {{ .Values.addons.anchore.helmRepo.repoName }} + namespace: {{ .Release.Namespace }} + {{- $repoType := include "getRepoType" (dict "repoName" .Values.addons.anchore.helmRepo.repoName "allRepos" $.Values.helmRepositories) -}} + {{- if (and .Values.addons.anchore.helmRepo.cosignVerify (eq $repoType "oci")) }} # Needs to be an OCI repo + verify: + provider: cosign + secretRef: + name: {{ printf "%s-cosign-pub" .Values.addons.anchore.helmRepo.repoName }} + {{- end }} + {{- end }} + interval: 5m + + {{- toYaml $fluxSettingsAnchore | nindent 2 }} + + {{- if .Values.addons.anchore.postRenderers }} + postRenderers: + {{ toYaml .Values.addons.anchore.postRenderers | nindent 4 }} + {{- end }} + + valuesFrom: + - name: {{ .Release.Name }}-anchore-values + kind: Secret + valuesKey: "common" + - name: {{ .Release.Name }}-anchore-values + kind: Secret + valuesKey: "defaults" + - name: {{ .Release.Name }}-anchore-values + kind: Secret + valuesKey: "overlays" + + {{- if or .Values.istio.enabled .Values.monitoring.enabled }} + dependsOn: + {{- if .Values.istio.enabled }} + - name: istio + namespace: {{ .Release.Namespace }} + {{- end }} + {{- if .Values.monitoring.enabled }} + - name: monitoring + namespace: {{ .Release.Namespace }} + {{- end }} + {{- end }} +{{- end }} diff --git a/chart/templates/anchore/imagepullsecret.yaml b/chart/templates/anchore/imagepullsecret.yaml new file mode 100644 index 0000000000000000000000000000000000000000..0493bb0d0adae20360a3351a11df6882399e6cb3 --- /dev/null +++ b/chart/templates/anchore/imagepullsecret.yaml @@ -0,0 +1,12 @@ +{{- if .Values.addons.anchore.enabled }} +{{- if ( include "imagePullSecret" . ) }} +apiVersion: v1 +kind: Secret +metadata: + name: private-registry + namespace: anchore +type: kubernetes.io/dockerconfigjson +data: + .dockerconfigjson: {{ template "imagePullSecret" . }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/chart/templates/anchore/namespace.yaml b/chart/templates/anchore/namespace.yaml new file mode 100644 index 0000000000000000000000000000000000000000..9ccc37a4b8658be69f49e1807db3ba18b5808591 --- /dev/null +++ b/chart/templates/anchore/namespace.yaml @@ -0,0 +1,11 @@ +{{- if .Values.addons.anchore.enabled }} +apiVersion: v1 +kind: Namespace +metadata: + labels: + app.kubernetes.io/name: anchore + app.kubernetes.io/component: "security" + {{- include "commonLabels" . | nindent 4}} + istio-injection: {{ ternary "enabled" "disabled" (and .Values.istio.enabled (eq (dig "istio" "injection" "enabled" .Values.addons.anchore) "enabled")) }} + name: anchore +{{- end }} \ No newline at end of file diff --git a/chart/templates/anchore/secret-ca.yaml b/chart/templates/anchore/secret-ca.yaml new file mode 100644 index 0000000000000000000000000000000000000000..a0c95319acaaee7914a9deb2915e1b62c8e48c56 --- /dev/null +++ b/chart/templates/anchore/secret-ca.yaml @@ -0,0 +1,10 @@ +{{- if and .Values.addons.anchore.enabled .Values.addons.anchore.sso.enabled (or .Values.sso.certificate_authority (dig "certificateAuthority" "cert" false .Values.sso)) }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ default (dig "certificateAuthority" "secretName" "" .Values.sso) .Values.sso.secretName }} + namespace: anchore +type: Opaque +data: + ca.pem: {{ default (dig "certificateAuthority" "cert" "" .Values.sso) .Values.sso.certificate_authority | b64enc }} +{{- end }} \ No newline at end of file diff --git a/chart/templates/anchore/values.yaml b/chart/templates/anchore/values.yaml new file mode 100644 index 0000000000000000000000000000000000000000..e64e0530ff4833f63911e2d7320b451360858f68 --- /dev/null +++ b/chart/templates/anchore/values.yaml @@ -0,0 +1,154 @@ +{{- if .Values.addons.anchore.enabled }} +{{- include "values-secret" (dict "root" $ "package" .Values.addons.anchore "name" "anchore" "defaults" (include "bigbang.defaults.anchore" .)) }} +{{- end }} + +{{- define "bigbang.defaults.anchore" -}} +# hostname is deprecated and replaced with domain. But if hostname exists then use it. +{{- $domainName := default .Values.domain .Values.hostname }} +domain: {{ $domainName }} + +openshift: {{ .Values.openshift }} + +istio: + enabled: {{ .Values.istio.enabled }} + hardened: + enabled: {{ or + (dig "istio" "hardened" "enabled" false .Values.addons.anchore.values) + (dig "hardened" "enabled" false .Values.istio.values) + }} + injection: {{ ternary "enabled" "disabled" (and .Values.istio.enabled (eq (dig "istio" "injection" "enabled" .Values.addons.anchore) "enabled")) }} + ui: + gateways: + - istio-system/{{ default "public" .Values.addons.anchore.ingress.gateway }} + api: + gateways: + - istio-system/{{ default "public" .Values.addons.anchore.ingress.gateway }} + +monitoring: + enabled: {{ .Values.monitoring.enabled }} + {{- if and .Values.istio.enabled (eq (dig "istio" "injection" "enabled" .Values.addons.anchore) "enabled") }} + {{- if (eq (dig "values" "istio" "mtls" "mode" "STRICT" .Values.addons.anchore) "STRICT") }} + serviceMonitor: + scheme: "https" + tlsConfig: + caFile: /etc/prom-certs/root-cert.pem + certFile: /etc/prom-certs/cert-chain.pem + keyFile: /etc/prom-certs/key.pem + insecureSkipVerify: true + {{- end }} + {{- end }} + +networkPolicies: + enabled: {{ .Values.networkPolicies.enabled }} + ingressLabels: + {{- $gateway := default "public" .Values.addons.anchore.ingress.gateway }} + {{- $default := dict "app" (dig "gateways" $gateway "ingressGateway" nil .Values.istio) "istio" nil }} + {{- toYaml (dig "values" "gateways" $gateway "selector" $default .Values.istio) | nindent 4 }} + +{{- if .Values.addons.anchore.enterprise.licenseYaml }} +enterpriseLicenseYaml: | + {{ .Values.addons.anchore.enterprise.licenseYaml | nindent 2 }} +{{- end }} + +sso: + enabled: {{ .Values.addons.anchore.sso.enabled }} + spEntityId: {{ .Values.addons.anchore.sso.client_id }} + {{- $anchoreUrl := first (dig "istio" "ui" "hosts" list .Values.addons.anchore.values) }} + acsUrl: https://{{ tpl ($anchoreUrl | default (printf "%s.%s" "anchore" $domainName)) . }}/service/sso/auth/keycloak + idpMetadataUrl: "{{ include "sso.saml.descriptor" . }}" + roleAttribute: {{ .Values.addons.anchore.sso.role_attribute }} + +global: + imagePullSecretName: private-registry + +imagePullPolicy: {{ .Values.imagePullPolicy }} + +postgresql: + {{- if .Values.istio.enabled }} + podAnnotations: + {{ include "istioAnnotation" . }} + {{- end}} + imagePullSecrets: private-registry + {{- if and .Values.addons.anchore.database.host .Values.addons.anchore.database.port .Values.addons.anchore.database.username .Values.addons.anchore.database.password .Values.addons.anchore.database.database }} + enabled: false + postgresUser: {{ .Values.addons.anchore.database.username }} + postgresPassword: {{ .Values.addons.anchore.database.password }} + postgresDatabase: {{ .Values.addons.anchore.database.database }} + externalEndpoint: "{{ .Values.addons.anchore.database.host }}" + postgresPort: {{ .Values.addons.anchore.database.port }} + {{- end }} +{{- if .Values.addons.anchore.adminPassword }} +anchoreConfig: + default_admin_password: {{ .Values.addons.anchore.adminPassword }} +{{- end }} + +feeds: + istio: + enabled: {{ .Values.istio.enabled }} + injection: {{ ternary "enabled" "disabled" (and .Values.istio.enabled (eq (dig "istio" "injection" "enabled" .Values.addons.anchore) "enabled")) }} + + feeds-db: + {{- if .Values.istio.enabled }} + podAnnotations: + {{ include "istioAnnotation" . }} + {{- end }} + imagePullSecrets: private-registry + {{- if and .Values.addons.anchore.database.host .Values.addons.anchore.database.port .Values.addons.anchore.database.username .Values.addons.anchore.database.password .Values.addons.anchore.database.feeds_database }} + enabled: false + postgresUser: {{ .Values.addons.anchore.database.username }} + postgresPassword: {{ .Values.addons.anchore.database.password }} + postgresDatabase: {{ .Values.addons.anchore.database.feeds_database }} + externalEndpoint: "{{ .Values.addons.anchore.database.host }}" + postgresPort: {{ .Values.addons.anchore.database.port }} + {{- end }} + +ui: + imagePullPolicy: {{ .Values.imagePullPolicy }} + imagePullSecretName: private-registry + +ui-redis: + {{- if and .Values.addons.anchore.redis.host .Values.addons.anchore.redis.port .Values.addons.anchore.redis.password }} + enabled: false + externalEndpoint: "redis://{{ .Values.addons.anchore.redis.username | default "nouser" }}:{{ .Values.addons.anchore.redis.password }}@{{ .Values.addons.anchore.redis.host }}:{{ .Values.addons.anchore.redis.port }}" + auth: + password: {{ .Values.addons.anchore.redis.password }} + {{- end }} + {{- if .Values.istio.enabled }} + master: + podAnnotations: + {{ include "istioAnnotation" . }} + replica: + podAnnotations: + {{ include "istioAnnotation" . }} + {{- end }} + image: + pullSecrets: + - private-registry + {{- if and .Values.monitoring.enabled (not (and .Values.addons.anchore.redis.host .Values.addons.anchore.redis.port .Values.addons.anchore.redis.password)) }} + metrics: + enabled: true + image: + pullSecrets: + - private-registry + serviceMonitor: + enabled: true + namespace: anchore + selector: + app.kubernetes.io/name: anchore-ui-redis + app.kubernetes.io/instance: anchore + {{- if and .Values.istio.enabled (eq (dig "istio" "injection" "enabled" .Values.addons.anchore) "enabled") }} + {{- if (eq (dig "values" "istio" "mtls" "mode" "STRICT" .Values.addons.anchore) "STRICT") }} + scheme: "https" + tlsConfig: + caFile: /etc/prom-certs/root-cert.pem + certFile: /etc/prom-certs/cert-chain.pem + keyFile: /etc/prom-certs/key.pem + insecureSkipVerify: true + {{- end }} + {{- end }} + prometheusRule: + enabled: true + namespace: monitoring + {{- end }} + +{{- end }} diff --git a/chart/templates/argocd/git-credentials.yaml b/chart/templates/argocd/git-credentials.yaml new file mode 100644 index 0000000000000000000000000000000000000000..7ec86325bdb9be1068464f88ed81dc11bc9d2f3e --- /dev/null +++ b/chart/templates/argocd/git-credentials.yaml @@ -0,0 +1,7 @@ +{{- $gitCredsSecretDict := dict + "name" "argocd" + "targetScope" .Values.addons.argocd + "releaseName" .Release.Name + "releaseNamespace" .Release.Namespace +}} +{{- include "gitCredsSecret" $gitCredsSecretDict | nindent 0 -}} diff --git a/chart/templates/argocd/gitrepository.yaml b/chart/templates/argocd/gitrepository.yaml new file mode 100644 index 0000000000000000000000000000000000000000..f447c20ab33a4f220d5f9ffee5ef871ea66f4976 --- /dev/null +++ b/chart/templates/argocd/gitrepository.yaml @@ -0,0 +1,24 @@ +{{- if and (eq .Values.addons.argocd.sourceType "git") .Values.addons.argocd.enabled }} +{{- $gitCredsDict := dict + "name" "argocd" + "packageGitScope" .Values.addons.argocd.git + "rootScope" . + "releaseName" .Release.Name +}} +apiVersion: source.toolkit.fluxcd.io/v1 +kind: GitRepository +metadata: + name: argocd + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: argocd + app.kubernetes.io/component: "core" + {{- include "commonLabels" . | nindent 4}} +spec: + interval: {{ .Values.flux.interval }} + url: {{ .Values.addons.argocd.git.repo }} + ref: + {{- include "validRef" .Values.addons.argocd.git | nindent 4 }} + {{ include "gitIgnore" . }} + {{- include "gitCredsExtended" $gitCredsDict | nindent 2 }} +{{- end }} diff --git a/chart/templates/argocd/helmrelease.yaml b/chart/templates/argocd/helmrelease.yaml new file mode 100644 index 0000000000000000000000000000000000000000..b099fc0d5b1f684c726d7093bdbf606c287850bf --- /dev/null +++ b/chart/templates/argocd/helmrelease.yaml @@ -0,0 +1,70 @@ +{{- $fluxSettingsArgo := merge .Values.addons.argocd.flux .Values.flux -}} +{{- if .Values.addons.argocd.enabled }} +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + name: argocd + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: argocd + app.kubernetes.io/component: "core" + {{- include "commonLabels" . | nindent 4}} + annotations: + checksum/bigbang-values: {{ include (print $.Template.BasePath "/argocd/values.yaml") . | sha256sum }} +spec: + targetNamespace: argocd + chart: + spec: + {{- if eq .Values.addons.argocd.sourceType "git" }} + chart: {{ .Values.addons.argocd.git.path }} + sourceRef: + kind: GitRepository + name: argocd + namespace: {{ .Release.Namespace }} + {{- else }} + chart: {{ .Values.addons.argocd.helmRepo.chartName }} + version: {{ .Values.addons.argocd.helmRepo.tag }} + sourceRef: + kind: HelmRepository + name: {{ .Values.addons.argocd.helmRepo.repoName }} + namespace: {{ .Release.Namespace }} + {{- $repoType := include "getRepoType" (dict "repoName" .Values.addons.argocd.helmRepo.repoName "allRepos" $.Values.helmRepositories) -}} + {{- if (and .Values.addons.argocd.helmRepo.cosignVerify (eq $repoType "oci")) }} # Needs to be an OCI repo + verify: + provider: cosign + secretRef: + name: {{ printf "%s-cosign-pub" .Values.addons.argocd.helmRepo.repoName }} + {{- end }} + {{- end }} + interval: 5m + + {{- toYaml $fluxSettingsArgo | nindent 2 }} + + {{- if .Values.addons.argocd.postRenderers }} + postRenderers: + {{ toYaml .Values.addons.argocd.postRenderers | nindent 4 }} + {{- end }} + + valuesFrom: + - name: {{ .Release.Name }}-argocd-values + kind: Secret + valuesKey: "common" + - name: {{ .Release.Name }}-argocd-values + kind: Secret + valuesKey: "defaults" + - name: {{ .Release.Name }}-argocd-values + kind: Secret + valuesKey: "overlays" + + {{- if or .Values.monitoring.enabled .Values.istio.enabled }} + dependsOn: + {{- if .Values.istio.enabled }} + - name: istio + namespace: {{ .Release.Namespace}} + {{- end}} + {{- if .Values.monitoring.enabled }} + - name: monitoring + namespace: {{ .Release.Namespace }} + {{- end }} + {{- end }} +{{- end }} diff --git a/chart/templates/argocd/imagepullsecret.yaml b/chart/templates/argocd/imagepullsecret.yaml new file mode 100644 index 0000000000000000000000000000000000000000..b1dd59ae3ca69aa935ae583dfe34f7adfe2e35e6 --- /dev/null +++ b/chart/templates/argocd/imagepullsecret.yaml @@ -0,0 +1,12 @@ +{{- if .Values.addons.argocd.enabled }} +{{- if ( include "imagePullSecret" . ) }} +apiVersion: v1 +kind: Secret +metadata: + name: private-registry + namespace: argocd +type: kubernetes.io/dockerconfigjson +data: + .dockerconfigjson: {{ template "imagePullSecret" . }} +{{- end }} +{{- end }} diff --git a/chart/templates/argocd/namespace.yaml b/chart/templates/argocd/namespace.yaml new file mode 100644 index 0000000000000000000000000000000000000000..3897cb98af27930df6e739737ba225a61867c5dc --- /dev/null +++ b/chart/templates/argocd/namespace.yaml @@ -0,0 +1,11 @@ +{{- if .Values.addons.argocd.enabled }} +apiVersion: v1 +kind: Namespace +metadata: + labels: + app.kubernetes.io/name: argocd + app.kubernetes.io/component: "core" + {{- include "commonLabels" . | nindent 4}} + istio-injection: {{ ternary "enabled" "disabled" (and .Values.istio.enabled (eq (dig "istio" "injection" "enabled" .Values.addons.argocd) "enabled")) }} + name: argocd +{{- end }} diff --git a/chart/templates/argocd/secret-ca.yaml b/chart/templates/argocd/secret-ca.yaml new file mode 100644 index 0000000000000000000000000000000000000000..4e667f9d0defd0ddb1b7671c6dcccbe5ef8df14b --- /dev/null +++ b/chart/templates/argocd/secret-ca.yaml @@ -0,0 +1,10 @@ +{{- if and .Values.addons.argocd.enabled .Values.addons.argocd.sso.enabled (or .Values.sso.certificate_authority (dig "certificateAuthority" "cert" false .Values.sso)) }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ default (dig "certificateAuthority" "secretName" "" .Values.sso) .Values.sso.secretName }} + namespace: argocd +type: Opaque +data: + ca.pem: {{ default (dig "certificateAuthority" "cert" "" .Values.sso) .Values.sso.certificate_authority | b64enc }} +{{- end }} \ No newline at end of file diff --git a/chart/templates/argocd/values.yaml b/chart/templates/argocd/values.yaml new file mode 100644 index 0000000000000000000000000000000000000000..d36a93c9ad6dac4db3c3757ff3772e87a9e730e4 --- /dev/null +++ b/chart/templates/argocd/values.yaml @@ -0,0 +1,187 @@ +{{- if .Values.addons.argocd.enabled }} +{{- include "values-secret" (dict "root" $ "package" .Values.addons.argocd "name" "argocd" "defaults" (include "bigbang.defaults.argocd" .)) }} +{{- end }} + +{{- define "bigbang.defaults.argocd" -}} +# hostname is deprecated and replaced with domain. But if hostname exists then use it. +{{- $domainName := default .Values.domain .Values.hostname }} +hostname: {{ $domainName }} +domain: {{ $domainName }} + +openshift: + enabled: {{ .Values.openshift }} + +createNamespace: false + +global: + {{- $argocdHosts := (dig "istio" "argocd" "hosts" dict .Values.addons.argocd.values) }} + {{- if $argocdHosts }} + domain: {{ tpl ($argocdHosts | first) $ }} + {{- else }} + domain: argocd.{{ $domainName }} + {{- end }} + image: + imagePullPolicy: {{ .Values.imagePullPolicy }} + imagePullSecrets: + - name: private-registry +{{- $istioInjection := (and (eq (dig "istio" "injection" "enabled" .Values.addons.argocd) "enabled") .Values.istio.enabled) }} +{{- if $istioInjection }} + podAnnotations: + {{ include "istioAnnotation" . }} +{{- end }} + +controller: + image: + imagePullPolicy: {{ .Values.imagePullPolicy }} + imagePullSecrets: + - name: private-registry + # conditional passes only for default istio: enabled, mTLS: SCRICT, istio injection: enabled + {{- if and $istioInjection (eq (dig "istio" "mtls" "mode" "STRICT" .Values.addons.argocd.values) "STRICT") }} + metrics: + serviceMonitor: + scheme: https + tlsConfig: + caFile: /etc/prom-certs/root-cert.pem + certFile: /etc/prom-certs/cert-chain.pem + keyFile: /etc/prom-certs/key.pem + insecureSkipVerify: true + {{- end }} + +dex: + image: + imagePullPolicy: {{ .Values.imagePullPolicy }} + imagePullSecrets: + - name: private-registry + +{{- if and .Values.addons.argocd.redis.host .Values.addons.argocd.redis.port }} +redis: + externalEndpoint: {{ .Values.addons.argocd.redis.host }}:{{ .Values.addons.argocd.redis.port }} + enabled: false +{{- end }} + +redis-bb: + {{- if and .Values.addons.argocd.redis.host .Values.addons.argocd.redis.port }} + enabled: false + {{- else }} + enabled: true + {{- end }} + image: + pullPolicy: {{ .Values.imagePullPolicy }} + auth: + enabled: false + {{- if .Values.monitoring.enabled }} + metrics: + enabled: true + image: + pullSecrets: + - private-registry + serviceMonitor: + enabled: true + namespace: argocd + selector: + app.kubernetes.io/name: redis-bb + app.kubernetes.io/instance: argocd-argocd + # conditional passes only for default istio: enabled, mTLS: SCRICT, istio injection: enabled + {{- if and $istioInjection (eq (dig "istio" "mtls" "mode" "STRICT" .Values.addons.argocd.values) "STRICT") }} + scheme: https + tlsConfig: + caFile: /etc/prom-certs/root-cert.pem + certFile: /etc/prom-certs/cert-chain.pem + keyFile: /etc/prom-certs/key.pem + insecureSkipVerify: true + {{- end }} + + prometheusRule: + enabled: true + namespace: monitoring + {{- end }} +{{- if $istioInjection }} + master: + podAnnotations: + {{ include "istioAnnotation" . }} + replica: + podAnnotations: + {{ include "istioAnnotation" . }} +{{- end }} + +server: + image: + imagePullPolicy: {{ .Values.imagePullPolicy }} + autoscaling: + enabled: true + config: + # Must be enabled for plugins included in PlatformOne image. + kustomize.buildOptions: "--enable-alpha-plugins" + # conditional passes only for default istio: enabled, mTLS: SCRICT, istio injection: enabled + {{- if and $istioInjection (eq (dig "istio" "mtls" "mode" "STRICT" .Values.addons.argocd.values) "STRICT") }} + metrics: + serviceMonitor: + scheme: https + tlsConfig: + caFile: /etc/prom-certs/root-cert.pem + certFile: /etc/prom-certs/cert-chain.pem + keyFile: /etc/prom-certs/key.pem + insecureSkipVerify: true + {{- end }} + +repoServer: + image: + imagePullPolicy: {{ .Values.imagePullPolicy }} + autoscaling: + enabled: true + # conditional passes only for default istio: enabled, mTLS: SCRICT, istio injection: enabled + {{- if and $istioInjection (eq (dig "istio" "mtls" "mode" "STRICT" .Values.addons.argocd.values) "STRICT") }} + metrics: + serviceMonitor: + scheme: https + tlsConfig: + caFile: /etc/prom-certs/root-cert.pem + certFile: /etc/prom-certs/cert-chain.pem + keyFile: /etc/prom-certs/key.pem + insecureSkipVerify: true + {{- end }} + +istio: + enabled: {{ .Values.istio.enabled }} + hardened: + enabled: {{ or + (dig "istio" "hardened" "enabled" false .Values.addons.argocd.values) + (dig "hardened" "enabled" false .Values.istio.values) + }} + injection: {{ dig "istio" "injection" "enabled" .Values.addons.argocd }} + argocd: + gateways: + - istio-system/{{ default "public" .Values.addons.argocd.ingress.gateway }} + +monitoring: + enabled: {{ .Values.monitoring.enabled }} + +networkPolicies: + enabled: {{ .Values.networkPolicies.enabled }} + controlPlaneCidr: {{ .Values.networkPolicies.controlPlaneCidr }} + ingressLabels: + {{- $gateway := default "public" .Values.addons.argocd.ingress.gateway }} + {{- $default := dict "app" (dig "gateways" $gateway "ingressGateway" nil .Values.istio) "istio" nil }} + {{- toYaml (dig "values" "gateways" $gateway "selector" $default .Values.istio) | nindent 4 }} + +{{- if .Values.addons.argocd.sso.enabled }} +sso: + enabled: {{ .Values.addons.argocd.sso.enabled }} + rbac: + policy.csv: | + {{- .Values.addons.argocd.sso.groups | nindent 6 }} + keycloakClientSecret: {{ .Values.addons.argocd.sso.client_secret }} + config: + oidc.config: | + name: {{ default .Values.sso.name .Values.addons.argocd.sso.provider_name }} + issuer: {{ include "sso.url" . }} + clientID: {{ .Values.addons.argocd.sso.client_id }} + clientSecret: $oidc.keycloak.clientSecret + requestedScopes: ["openid","ArgoCD"] + {{- if (or .Values.sso.certificate_authority (dig "certificateAuthority" "cert" false .Values.sso)) }} + rootCA: | + {{- default (dig "certificateAuthority" "cert" "" .Values.sso) .Values.sso.certificate_authority | nindent 8 }} + {{- end }} +{{- end }} +{{- end -}} + diff --git a/chart/templates/authservice/git-credentials.yaml b/chart/templates/authservice/git-credentials.yaml new file mode 100644 index 0000000000000000000000000000000000000000..830777ca8c4cd74da2a54b7081545eebe618465a --- /dev/null +++ b/chart/templates/authservice/git-credentials.yaml @@ -0,0 +1,7 @@ +{{- $gitCredsSecretDict := dict + "name" "authservice" + "targetScope" .Values.addons.authservice + "releaseName" .Release.Name + "releaseNamespace" .Release.Namespace +}} +{{- include "gitCredsSecret" $gitCredsSecretDict | nindent 0 -}} diff --git a/chart/templates/authservice/gitrepository.yaml b/chart/templates/authservice/gitrepository.yaml new file mode 100644 index 0000000000000000000000000000000000000000..c6665ace28684b1020df720b29b54f9b51e9bf09 --- /dev/null +++ b/chart/templates/authservice/gitrepository.yaml @@ -0,0 +1,24 @@ +{{- if and .Values.istio.enabled (eq .Values.addons.authservice.sourceType "git") (or .Values.addons.authservice.enabled (and .Values.monitoring.enabled .Values.monitoring.sso.enabled) (and .Values.jaeger.enabled .Values.jaeger.sso.enabled) (and .Values.tempo.enabled .Values.tempo.sso.enabled)) }} +{{- $gitCredsDict := dict + "name" "authservice" + "packageGitScope" .Values.addons.authservice.git + "rootScope" . + "releaseName" .Release.Name +}} +apiVersion: source.toolkit.fluxcd.io/v1 +kind: GitRepository +metadata: + name: authservice + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: authservice + app.kubernetes.io/component: "core" + {{- include "commonLabels" . | nindent 4}} +spec: + interval: {{ .Values.flux.interval }} + url: {{ .Values.addons.authservice.git.repo }} + ref: + {{- include "validRef" .Values.addons.authservice.git | nindent 4 }} + {{ include "gitIgnore" . }} + {{- include "gitCredsExtended" $gitCredsDict | nindent 2 }} +{{- end }} diff --git a/chart/templates/authservice/helmrelease.yaml b/chart/templates/authservice/helmrelease.yaml new file mode 100644 index 0000000000000000000000000000000000000000..2032be1475e510d8332078cf23bcea33eed8237b --- /dev/null +++ b/chart/templates/authservice/helmrelease.yaml @@ -0,0 +1,68 @@ +{{- $fluxSettingsAuthservice := merge .Values.addons.authservice.flux .Values.flux -}} +{{- if and .Values.istio.enabled (or .Values.addons.authservice.enabled (and .Values.monitoring.enabled .Values.monitoring.sso.enabled) (and .Values.jaeger.enabled .Values.jaeger.sso.enabled) (and .Values.tempo.enabled .Values.tempo.sso.enabled)) }} +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + name: authservice + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: authservice + app.kubernetes.io/component: "core" + {{- include "commonLabels" . | nindent 4}} + annotations: + checksum/bigbang-values: {{ include (print $.Template.BasePath "/authservice/values.yaml") . | sha256sum }} +spec: + targetNamespace: authservice + chart: + spec: + {{- if eq .Values.addons.authservice.sourceType "git" }} + chart: {{ .Values.addons.authservice.git.path }} + sourceRef: + kind: GitRepository + name: authservice + namespace: {{ .Release.Namespace }} + {{- else }} + chart: {{ .Values.addons.authservice.helmRepo.chartName }} + version: {{ .Values.addons.authservice.helmRepo.tag }} + sourceRef: + kind: HelmRepository + name: {{ .Values.addons.authservice.helmRepo.repoName }} + namespace: {{ .Release.Namespace }} + {{- $repoType := include "getRepoType" (dict "repoName" .Values.addons.authservice.helmRepo.repoName "allRepos" $.Values.helmRepositories) -}} + {{- if (and .Values.addons.authservice.helmRepo.cosignVerify (eq $repoType "oci")) }} # Needs to be an OCI repo + verify: + provider: cosign + secretRef: + name: {{ printf "%s-cosign-pub" .Values.addons.authservice.helmRepo.repoName }} + {{- end }} + {{- end }} + interval: 5m + + {{- toYaml $fluxSettingsAuthservice | nindent 2 }} + + {{- if .Values.addons.authservice.postRenderers }} + postRenderers: + {{ toYaml .Values.addons.authservice.postRenderers | nindent 4 }} + {{- end }} + + valuesFrom: + - name: {{ .Release.Name }}-authservice-values + kind: Secret + valuesKey: "common" + - name: {{ .Release.Name }}-authservice-values + kind: Secret + valuesKey: "defaults" + - name: {{ .Release.Name }}-authservice-values + kind: Secret + valuesKey: "overlays" + + dependsOn: + {{- if .Values.istio.enabled }} + - name: istio + namespace: {{ .Release.Namespace }} + {{- end }} + {{- if .Values.monitoring.enabled }} + - name: monitoring + namespace: {{ .Release.Namespace }} + {{- end }} +{{- end }} diff --git a/chart/templates/authservice/imagepullsecret.yaml b/chart/templates/authservice/imagepullsecret.yaml new file mode 100644 index 0000000000000000000000000000000000000000..c26e456c3015e5dced62b38aad48b707da0301c8 --- /dev/null +++ b/chart/templates/authservice/imagepullsecret.yaml @@ -0,0 +1,12 @@ +{{- if and .Values.istio.enabled (or .Values.addons.authservice.enabled (and .Values.monitoring.enabled .Values.monitoring.sso.enabled) (and .Values.jaeger.enabled .Values.jaeger.sso.enabled) (and .Values.tempo.enabled .Values.tempo.sso.enabled)) }} +{{- if ( include "imagePullSecret" . ) }} +apiVersion: v1 +kind: Secret +metadata: + name: private-registry + namespace: authservice +type: kubernetes.io/dockerconfigjson +data: + .dockerconfigjson: {{ template "imagePullSecret" . }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/chart/templates/authservice/namespace.yaml b/chart/templates/authservice/namespace.yaml new file mode 100644 index 0000000000000000000000000000000000000000..4a29c465de96b35b27d3b9d7762f9273dfb57c20 --- /dev/null +++ b/chart/templates/authservice/namespace.yaml @@ -0,0 +1,12 @@ +{{- if and .Values.istio.enabled (or .Values.addons.authservice.enabled (and .Values.monitoring.enabled .Values.monitoring.sso.enabled) (and .Values.jaeger.enabled .Values.jaeger.sso.enabled) (and .Values.tempo.enabled .Values.tempo.sso.enabled)) }} +apiVersion: v1 +kind: Namespace +metadata: + name: authservice + labels: + istio-injection: {{ ternary "enabled" "disabled" (and .Values.istio.enabled (eq (dig "istio" "injection" "enabled" .Values.addons.authservice) "enabled")) }} + app.kubernetes.io/name: authservice + app.kubernetes.io/component: "core" + {{- include "commonLabels" . | nindent 4}} +{{- end }} + diff --git a/chart/templates/authservice/values.yaml b/chart/templates/authservice/values.yaml new file mode 100644 index 0000000000000000000000000000000000000000..8746e7ece74f933f92870b5875d55d0466605079 --- /dev/null +++ b/chart/templates/authservice/values.yaml @@ -0,0 +1,254 @@ +{{- if and .Values.istio.enabled (or .Values.addons.authservice.enabled (and .Values.monitoring.enabled .Values.monitoring.sso.enabled) (and .Values.jaeger.enabled .Values.jaeger.sso.enabled) (and .Values.tempo.enabled .Values.tempo.sso.enabled) (and .Values.addons.thanos.enabled .Values.addons.thanos.sso.enabled) (and .Values.addons.holocron.enabled .Values.addons.holocron.sso.enabled)) }} +{{- include "values-secret" (dict "root" $ "package" .Values.addons.authservice "name" "authservice" "defaults" (include "bigbang.defaults.authservice" .)) }} +{{- end }} + +{{- define "bigbang.defaults.authservice" -}} +# hostname is deprecated and replaced with domain. But if hostname exists then use it. +{{- $domainName := default .Values.domain .Values.hostname }} +{{- $authServiceHardened := or + (dig "istio" "hardened" "enabled" false .Values.monitoring.values) + (dig "istio" "hardened" "enabled" false .Values.addons.authservice.values) + (dig "hardened" "enabled" false .Values.istio.values) + (dig "istio" "hardened" "enabled" false .Values.grafana.values) + (dig "istio" "hardened" "enabled" false .Values.loki.values) + (dig "istio" "hardened" "enabled" false .Values.eckOperator.values) + (dig "istio" "hardened" "enabled" false .Values.elasticsearchKibana.values) +}} + +istio: + enabled: {{ .Values.istio.enabled | default false }} + hardened: + enabled: {{ $authServiceHardened }} + clusterWideHardenedEnabled: {{ dig "hardened" "enabled" false .Values.istio.values }} + +image: + pullPolicy: {{ .Values.imagePullPolicy | default "IfNotPresent" }} + +imagePullSecrets: + - name: private-registry + +podAnnotations: + {{ include "istioAnnotation" . }} + +openshift: {{ .Values.openshift | default false }} + +monitoring: + enabled: {{ .Values.monitoring.enabled | default false }} + +networkPolicies: + enabled: {{ .Values.networkPolicies.enabled | default false }} + ingressLabels: + {{- $gateway := default "public" .Values.addons.haproxy.ingress.gateway }} + {{- $default := dict "app" (dig "gateways" $gateway "ingressGateway" nil .Values.istio) "istio" nil }} + {{- toYaml (dig "values" "gateways" $gateway "selector" $default .Values.istio) | nindent 4 }} + +{{- if or (dig "redis" "enabled" false .Values.addons.authservice.values) (dig "global" "redis_server_uri" "" .Values.addons.authservice.values) }} +autoscaling: + enabled: true + minReplicas: 2 + maxReplicas: 3 +{{- end }} + +{{- if and (dig "redis" "enabled" false .Values.addons.authservice.values) (or .Values.monitoring.enabled .Values.kiali.enabled) }} +redis-bb: + {{- if .Values.monitoring.enabled }} + metrics: + enabled: true + image: + pullSecrets: + - private-registry + serviceMonitor: + enabled: true + namespace: authservice + selector: + app.kubernetes.io/name: redis-bb + app.kubernetes.io/instance: authservice-authservice + {{- if and .Values.istio.enabled (eq (dig "istio" "mtls" "mode" "STRICT" .Values.addons.authservice.values) "STRICT") }} + scheme: https + tlsConfig: + caFile: /etc/prom-certs/root-cert.pem + certFile: /etc/prom-certs/cert-chain.pem + keyFile: /etc/prom-certs/key.pem + insecureSkipVerify: true + {{- end }} + prometheusRule: + enabled: true + namespace: monitoring + {{- end }} +{{- end }} + +{{- $legacy := and .Values.sso.oidc.realm .Values.sso.oidc.host -}} +{{- if not $legacy }} +issuer_uri: {{ include "sso.url" . }} +{{- end }} + +global: + oidc: + host: {{ default (include "sso.host" .) .Values.sso.oidc.host }} + realm: {{ default (include "sso.realm" .) .Values.sso.oidc.realm }} + + {{- if or .Values.sso.jwks_uri (dig "oidc" "jwksUri" false .Values.sso) }} + jwks_uri: {{ include "sso.oidc.jwksuri" . | quote }} + {{- else if or .Values.sso.jwks (dig "oidc" "jwks" false .Values.sso) }} + jwks: {{ default (dig "oidc" "jwks" "" .Values.sso) .Values.sso.jwks | quote }} + {{- end }} + + {{- if or .Values.sso.client_id (dig "sso" "client_id" false .Values.addons.authservice) }} + client_id: {{ default (dig "sso" "client_id" "" .Values.addons.authservice) .Values.sso.client_id }} + {{- end }} + + {{- if or .Values.sso.client_secret (dig "sso" "client_secret" false .Values.addons.authservice) }} + client_secret: {{ default (dig "sso" "client_secret" "" .Values.addons.authservice) .Values.sso.client_secret }} + {{- end }} + + {{- if (or .Values.sso.certificate_authority (dig "certificateAuthority" "cert" false .Values.sso)) }} + certificate_authority: {{ (default (dig "certificateAuthority" "cert" "" .Values.sso) .Values.sso.certificate_authority) | quote }} + {{- end }} + + {{- if not $legacy }} + authorization_uri: {{ include "sso.oidc.auth" . }} + token_uri: {{ include "sso.oidc.token" . }} + logout_redirect_uri: {{ include "sso.oidc.endsession" . }} + {{- end }} + + {{- $authserviceValues := .Values.addons.authservice.values | default dict }} + {{- $redisValues := $authserviceValues.redis | default dict }} + {{- if hasKey $redisValues "enabled" }} + {{- if $redisValues.enabled }} + redis_server_uri: "tcp://authservice-authservice-redis-bb-master:6379" + {{- end }} + {{- end }} + +chains: + {{- if .Values.addons.authservice.chains }} + {{ .Values.addons.authservice.chains | toYaml | nindent 2 }} + {{- end }} + + {{- if and .Values.jaeger.enabled .Values.jaeger.sso.enabled }} + jaeger: + match: + header: ":authority" + {{- $jaegerHosts := (dig "istio" "jaeger" "hosts" dict .Values.jaeger.values) }} + {{- if $jaegerHosts }} + prefix: {{ tpl ($jaegerHosts | first) $ }} + callback_uri: https://{{ tpl ($jaegerHosts | first) $ }}/login + {{- else }} + prefix: {{ printf "tracing.%s" $domainName }} + callback_uri: https://tracing.{{ $domainName }}/login + {{- end }} + client_id: "{{ .Values.jaeger.sso.client_id }}" + client_secret: "{{ .Values.jaeger.sso.client_secret }}" + {{- if not $legacy }} + authorization_uri: {{ include "sso.oidc.auth" . }} + token_uri: {{ include "sso.oidc.token" . }} + logout_redirect_uri: {{ include "sso.oidc.endsession" . }} + {{- end }} + {{- end }} + + {{- if and .Values.addons.holocron.enabled .Values.addons.holocron.sso.enabled }} + holocron: + match: + header: ":authority" + {{- $holocronHosts := (dig "istio" "holocron" "hosts" dict .Values.addons.holocron.values) }} + {{- if $holocronHosts }} + prefix: {{ tpl ($holocronHosts | first) $ }} + callback_uri: https://{{ tpl ($holocronHosts | first) $ }}/login + {{- else }} + prefix: {{ printf "holocron.%s" $domainName }} + callback_uri: https://holocron.{{ $domainName }}/login + {{- end }} + client_id: "{{ .Values.addons.holocron.sso.client_id }}" + client_secret: "{{ .Values.addons.holocron.sso.client_secret }}" + {{- if not $legacy }} + authorization_uri: {{ include "sso.oidc.auth" . }} + token_uri: {{ include "sso.oidc.token" . }} + logout_redirect_uri: {{ include "sso.oidc.endsession" . }} + {{- end }} + {{- end }} + + {{- if and .Values.addons.thanos.enabled .Values.addons.thanos.sso.enabled }} + thanos: + match: + header: ":authority" + {{- $thanosHosts := (dig "istio" "thanos" "hosts" dict .Values.addons.thanos.values) }} + {{- if $thanosHosts }} + prefix: {{ tpl ($thanosHosts | first) $ }} + callback_uri: https://{{ tpl ($thanosHosts | first) $ }}/login/generic_oauth + {{- else }} + prefix: {{ printf "thanos.%s" $domainName }} + callback_uri: https://thanos.{{ $domainName }}/login/generic_oauth + {{- end }} + client_id: "{{ .Values.addons.thanos.sso.client_id }}" + client_secret: "{{ .Values.addons.thanos.sso.client_secret }}" + {{- if not $legacy }} + authorization_uri: {{ include "sso.oidc.auth" . }} + token_uri: {{ include "sso.oidc.token" . }} + logout_redirect_uri: {{ include "sso.oidc.endsession" . }} + {{- end }} + {{- end }} + + {{- $tempoQueryEnabled := (dig "tempoQuery" "enabled" false .Values.tempo.values) }} + {{- if and $tempoQueryEnabled .Values.tempo.enabled .Values.tempo.sso.enabled }} + tempo: + match: + header: ":authority" + {{- $tempoHosts := (dig "istio" "tempoQuery" "hosts" dict .Values.tempo.values) }} + {{- if $tempoHosts }} + prefix: {{ tpl ($tempoHosts | first) $ }} + callback_uri: https://{{ tpl ($tempoHosts | first) $ }}/login + {{- else if .Values.jaeger.enabled }} + prefix: {{ printf "tempo.%s" $domainName }} + callback_uri: https://tempo.{{ $domainName }}/login + {{- else }} + prefix: {{ printf "tracing.%s" $domainName }} + callback_uri: https://tracing.{{ $domainName }}/login + {{- end }} + client_id: "{{ .Values.tempo.sso.client_id }}" + client_secret: "{{ .Values.tempo.sso.client_secret }}" + {{- if not $legacy }} + authorization_uri: {{ include "sso.oidc.auth" . }} + token_uri: {{ include "sso.oidc.token" . }} + logout_redirect_uri: {{ include "sso.oidc.endsession" . }} + {{- end }} + {{- end }} + + {{- if and .Values.monitoring.enabled .Values.monitoring.sso.enabled }} + prometheus: + match: + header: ":authority" + {{- $prometheusHosts := (dig "istio" "prometheus" "hosts" dict .Values.monitoring.values) }} + {{- if $prometheusHosts }} + prefix: {{ tpl ($prometheusHosts | first) $ }} + callback_uri: https://{{ tpl ($prometheusHosts | first) $ }}/login/generic_oauth + {{- else }} + prefix: {{ printf "prometheus.%s" $domainName }} + callback_uri: https://prometheus.{{ $domainName }}/login/generic_oauth + {{- end }} + client_id: {{ .Values.monitoring.sso.prometheus.client_id }} + client_secret: "{{ .Values.monitoring.sso.prometheus.client_secret }}" + {{- if not $legacy }} + authorization_uri: {{ include "sso.oidc.auth" . }} + token_uri: {{ include "sso.oidc.token" . }} + logout_redirect_uri: {{ include "sso.oidc.endsession" . }} + {{- end }} + + alertmanager: + match: + header: ":authority" + {{- $alertmanagerHosts := (dig "istio" "alertmanager" "hosts" dict .Values.monitoring.values) }} + {{- if $alertmanagerHosts }} + prefix: {{ tpl ($alertmanagerHosts | first) $ }} + callback_uri: https://{{ tpl ($alertmanagerHosts | first) $ }}/login/generic_oauth + {{- else }} + prefix: {{ printf "alertmanager.%s" $domainName }} + callback_uri: https://alertmanager.{{ $domainName }}/login/generic_oauth + {{- end }} + client_id: {{ .Values.monitoring.sso.alertmanager.client_id }} + client_secret: "{{ .Values.monitoring.sso.alertmanager.client_secret }}" + {{- if not $legacy }} + authorization_uri: {{ include "sso.oidc.auth" . }} + token_uri: {{ include "sso.oidc.token" . }} + logout_redirect_uri: {{ include "sso.oidc.endsession" . }} + {{- end }} + {{- end }} +{{- end -}} diff --git a/chart/templates/cluster-auditor/git-credentials.yaml b/chart/templates/cluster-auditor/git-credentials.yaml new file mode 100644 index 0000000000000000000000000000000000000000..5132ce0f28f55e2590a92b5e79bd4db35a2c65f2 --- /dev/null +++ b/chart/templates/cluster-auditor/git-credentials.yaml @@ -0,0 +1,7 @@ +{{- $gitCredsSecretDict := dict + "name" "clusterAuditor" + "targetScope" .Values.clusterAuditor + "releaseName" .Release.Name + "releaseNamespace" .Release.Namespace +}} +{{- include "gitCredsSecret" $gitCredsSecretDict | nindent 0 -}} diff --git a/chart/templates/cluster-auditor/gitrepository.yaml b/chart/templates/cluster-auditor/gitrepository.yaml new file mode 100644 index 0000000000000000000000000000000000000000..dec3272075b578008b34d14a9d7db3dff2bb69ce --- /dev/null +++ b/chart/templates/cluster-auditor/gitrepository.yaml @@ -0,0 +1,24 @@ +{{- if and (eq .Values.clusterAuditor.sourceType "git") (not .Values.offline) .Values.clusterAuditor.enabled }} +{{- $gitCredsDict := dict + "name" "clusterAuditor" + "packageGitScope" .Values.clusterAuditor.git + "rootScope" . + "releaseName" .Release.Name +}} +apiVersion: source.toolkit.fluxcd.io/v1 +kind: GitRepository +metadata: + name: cluster-auditor + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: cluster-auditor + app.kubernetes.io/component: "core" + {{- include "commonLabels" . | nindent 4}} +spec: + interval: {{ .Values.flux.interval }} + url: {{ .Values.clusterAuditor.git.repo }} + ref: + {{- include "validRef" .Values.clusterAuditor.git | nindent 4 }} + {{ include "gitIgnore" . }} + {{- include "gitCredsExtended" $gitCredsDict | nindent 2 }} +{{- end }} diff --git a/chart/templates/cluster-auditor/helmrelease.yaml b/chart/templates/cluster-auditor/helmrelease.yaml new file mode 100644 index 0000000000000000000000000000000000000000..600fd6a36a9ced940492321eade06a7d2e113f9a --- /dev/null +++ b/chart/templates/cluster-auditor/helmrelease.yaml @@ -0,0 +1,66 @@ +{{- $fluxSettingsClusterAuditor := merge .Values.clusterAuditor.flux .Values.flux -}} +{{- if .Values.clusterAuditor.enabled }} +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + name: cluster-auditor + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: cluster-auditor + app.kubernetes.io/component: "core" + {{- include "commonLabels" . | nindent 4}} + annotations: + checksum/bigbang-values: {{ include (print $.Template.BasePath "/cluster-auditor/values.yaml") . | sha256sum }} +spec: + targetNamespace: cluster-auditor + chart: + spec: + {{- if eq .Values.clusterAuditor.sourceType "git" }} + chart: {{ .Values.clusterAuditor.git.path }} + sourceRef: + kind: GitRepository + name: cluster-auditor + namespace: {{ .Release.Namespace }} + {{- else }} + chart: {{ .Values.clusterAuditor.helmRepo.chartName }} + version: {{ .Values.clusterAuditor.helmRepo.tag }} + sourceRef: + kind: HelmRepository + name: {{ .Values.clusterAuditor.helmRepo.repoName }} + namespace: {{ .Release.Namespace }} + {{- $repoType := include "getRepoType" (dict "repoName" .Values.clusterAuditor.helmRepo.repoName "allRepos" $.Values.helmRepositories) -}} + {{- if (and .Values.clusterAuditor.helmRepo.cosignVerify (eq $repoType "oci")) }} # Needs to be an OCI repo + verify: + provider: cosign + secretRef: + name: {{ printf "%s-cosign-pub" .Values.clusterAuditor.helmRepo.repoName }} + {{- end }} + {{- end }} + interval: 5m + + {{- toYaml $fluxSettingsClusterAuditor | nindent 2 }} + + {{- if .Values.clusterAuditor.postRenderers }} + postRenderers: + {{ toYaml .Values.clusterAuditor.postRenderers | nindent 4 }} + {{- end }} + valuesFrom: + - name: {{ .Release.Name }}-cluster-auditor-values + kind: Secret + valuesKey: "common" + - name: {{ .Release.Name }}-cluster-auditor-values + kind: Secret + valuesKey: "defaults" + - name: {{ .Release.Name }}-cluster-auditor-values + kind: Secret + valuesKey: "overlays" + + # CA always depends on Gatekeeper so we can assume it exists here + dependsOn: + - name: gatekeeper + namespace: {{ .Release.Namespace }} + {{- if .Values.monitoring.enabled }} + - name: monitoring + namespace: {{ .Release.Namespace }} + {{- end }} +{{- end }} diff --git a/chart/templates/cluster-auditor/imagepullsecret.yaml b/chart/templates/cluster-auditor/imagepullsecret.yaml new file mode 100644 index 0000000000000000000000000000000000000000..ba95baa529cc0efd959baf0c9116ac9c2447a6b5 --- /dev/null +++ b/chart/templates/cluster-auditor/imagepullsecret.yaml @@ -0,0 +1,12 @@ +{{- if .Values.clusterAuditor.enabled }} +{{- if ( include "imagePullSecret" . ) }} +apiVersion: v1 +kind: Secret +metadata: + name: private-registry + namespace: cluster-auditor +type: kubernetes.io/dockerconfigjson +data: + .dockerconfigjson: {{ template "imagePullSecret" . }} +{{- end }} +{{- end }} diff --git a/chart/templates/cluster-auditor/namespace.yaml b/chart/templates/cluster-auditor/namespace.yaml new file mode 100644 index 0000000000000000000000000000000000000000..c2efe3189f94c372234f4a254c9ff660994f9159 --- /dev/null +++ b/chart/templates/cluster-auditor/namespace.yaml @@ -0,0 +1,13 @@ +{{- if .Values.clusterAuditor.enabled }} +apiVersion: v1 +kind: Namespace +metadata: + labels: + meta.helm.sh/release-namespace: bigbang + meta.helm.sh/release-name: bigbang + app.kubernetes.io/name: cluster-auditor + app.kubernetes.io/component: "core" + {{- include "commonLabels" . | nindent 4}} + istio-injection: {{ ternary "enabled" "disabled" (and .Values.istio.enabled (eq (dig "istio" "injection" "enabled" .Values.clusterAuditor) "enabled")) }} + name: cluster-auditor +{{- end }} diff --git a/chart/templates/cluster-auditor/values.yaml b/chart/templates/cluster-auditor/values.yaml new file mode 100644 index 0000000000000000000000000000000000000000..031080cbcaf454323f5142d08ad07388102164ef --- /dev/null +++ b/chart/templates/cluster-auditor/values.yaml @@ -0,0 +1,35 @@ +{{- if .Values.clusterAuditor.enabled }} +{{- include "values-secret" (dict "root" $ "package" .Values.clusterAuditor "name" "cluster-auditor" "defaults" (include "bigbang.defaults.clusterauditor" .)) }} +{{- end }} + +{{- define "bigbang.defaults.clusterauditor" -}} +elasticsearch: + imagePullSecrets: + - name: private-registry + +image: + imagePullPolicy: {{ .Values.imagePullPolicy }} + +monitoring: + enabled: {{ .Values.monitoring.enabled }} + +networkPolicies: + enabled: {{ .Values.networkPolicies.enabled }} + controlPlaneCidr: {{ .Values.networkPolicies.controlPlaneCidr }} + +{{- if .Values.istio.enabled }} +annotations: + {{ include "istioAnnotation" . }} +{{- end }} + +istio: + enabled: {{ .Values.istio.enabled }} + hardened: + enabled: {{ or + (dig "istio" "hardened" "enabled" false .Values.clusterAuditor.values) + (dig "hardened" "enabled" false .Values.istio.values) + }} + +openshift: {{ .Values.openshift }} + +{{- end -}} diff --git a/chart/templates/eck-operator/git-credentials.yaml b/chart/templates/eck-operator/git-credentials.yaml new file mode 100644 index 0000000000000000000000000000000000000000..80f4afd4ebc0e5dc09099c3357373a1d1850639c --- /dev/null +++ b/chart/templates/eck-operator/git-credentials.yaml @@ -0,0 +1,7 @@ +{{- $gitCredsSecretDict := dict + "name" "eckOperator" + "targetScope" .Values.eckOperator + "releaseName" .Release.Name + "releaseNamespace" .Release.Namespace +}} +{{- include "gitCredsSecret" $gitCredsSecretDict | nindent 0 -}} diff --git a/chart/templates/eck-operator/gitrepository.yaml b/chart/templates/eck-operator/gitrepository.yaml new file mode 100644 index 0000000000000000000000000000000000000000..5a4297bed0e1c2b55fa834c3bdc504499d79d99e --- /dev/null +++ b/chart/templates/eck-operator/gitrepository.yaml @@ -0,0 +1,24 @@ +{{- if and (eq .Values.eckOperator.sourceType "git") (not .Values.offline) (or .Values.eckOperator.enabled .Values.elasticsearchKibana.enabled) }} +{{- $gitCredsDict := dict + "name" "eckOperator" + "packageGitScope" .Values.eckOperator.git + "rootScope" . + "releaseName" .Release.Name +}} +apiVersion: source.toolkit.fluxcd.io/v1 +kind: GitRepository +metadata: + name: eck-operator + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: eck-operator + app.kubernetes.io/component: "core" + {{- include "commonLabels" . | nindent 4}} +spec: + interval: {{ .Values.flux.interval }} + url: {{ .Values.eckOperator.git.repo }} + ref: + {{- include "validRef" .Values.eckOperator.git | nindent 4 }} + {{ include "gitIgnore" . }} + {{- include "gitCredsExtended" $gitCredsDict | nindent 2 }} +{{- end }} diff --git a/chart/templates/eck-operator/helmrelease.yaml b/chart/templates/eck-operator/helmrelease.yaml new file mode 100644 index 0000000000000000000000000000000000000000..2a3a1d276639dd39db20d1b9c4119acd6eb247ef --- /dev/null +++ b/chart/templates/eck-operator/helmrelease.yaml @@ -0,0 +1,75 @@ +{{- $fluxSettingsEckOperator := merge .Values.eckOperator.flux .Values.flux -}} +{{- if or .Values.eckOperator.enabled .Values.elasticsearchKibana.enabled }} +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + name: eck-operator + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: eck-operator + app.kubernetes.io/component: "core" + {{- include "commonLabels" . | nindent 4}} + annotations: + checksum/bigbang-values: {{ include (print $.Template.BasePath "/eck-operator/values.yaml") . | sha256sum }} +spec: + driftDetection: + mode: warn + targetNamespace: eck-operator + chart: + spec: + {{- if eq .Values.eckOperator.sourceType "git" }} + chart: {{ .Values.eckOperator.git.path }} + sourceRef: + kind: GitRepository + name: eck-operator + namespace: {{ .Release.Namespace }} + {{- else }} + chart: {{ .Values.eckOperator.helmRepo.chartName }} + version: {{ .Values.eckOperator.helmRepo.tag }} + sourceRef: + kind: HelmRepository + name: {{ .Values.eckOperator.helmRepo.repoName }} + namespace: {{ .Release.Namespace }} + {{- $repoType := include "getRepoType" (dict "repoName" .Values.eckOperator.helmRepo.repoName "allRepos" $.Values.helmRepositories) -}} + {{- if (and .Values.eckOperator.helmRepo.cosignVerify (eq $repoType "oci")) }} # Needs to be an OCI repo + verify: + provider: cosign + secretRef: + name: {{ printf "%s-cosign-pub" .Values.eckOperator.helmRepo.repoName }} + {{- end }} + {{- end }} + interval: 5m + + {{- toYaml $fluxSettingsEckOperator | nindent 2 }} + + {{- if .Values.eckOperator.postRenderers }} + postRenderers: + {{ toYaml .Values.eckOperator.postRenderers | nindent 4 }} + {{- end }} + valuesFrom: + - name: {{ .Release.Name }}-eck-operator-values + kind: Secret + valuesKey: "common" + - name: {{ .Release.Name }}-eck-operator-values + kind: Secret + valuesKey: "defaults" + - name: {{ .Release.Name }}-eck-operator-values + kind: Secret + valuesKey: "overlays" + + {{- if or .Values.gatekeeper.enabled .Values.istio.enabled .Values.kyvernoPolicies.enabled }} + dependsOn: + {{- if .Values.gatekeeper.enabled }} + - name: gatekeeper + namespace: {{ .Release.Namespace }} + {{- end }} + {{- if .Values.istio.enabled }} + - name: istio + namespace: {{ .Release.Namespace }} + {{- end }} + {{- if .Values.kyvernoPolicies.enabled }} + - name: kyverno-policies + namespace: {{ .Release.Namespace }} + {{- end }} + {{- end }} +{{- end }} diff --git a/chart/templates/eck-operator/imagepullsecret.yaml b/chart/templates/eck-operator/imagepullsecret.yaml new file mode 100644 index 0000000000000000000000000000000000000000..5383d0249eded42d7dec95c9bbbdc460ec256123 --- /dev/null +++ b/chart/templates/eck-operator/imagepullsecret.yaml @@ -0,0 +1,16 @@ +{{- if or .Values.eckOperator.enabled .Values.elasticsearchKibana.enabled }} +{{- if ( include "imagePullSecret" . ) }} +apiVersion: v1 +kind: Secret +metadata: + name: private-registry + namespace: eck-operator + labels: + app.kubernetes.io/name: eck-operator + app.kubernetes.io/component: "core" + {{- include "commonLabels" . | nindent 4}} +type: kubernetes.io/dockerconfigjson +data: + .dockerconfigjson: {{ template "imagePullSecret" . }} +{{- end }} +{{- end }} diff --git a/chart/templates/eck-operator/namespace.yaml b/chart/templates/eck-operator/namespace.yaml new file mode 100644 index 0000000000000000000000000000000000000000..75e894f3af5d8b2d59c5a95ee36b29770a85b3ff --- /dev/null +++ b/chart/templates/eck-operator/namespace.yaml @@ -0,0 +1,11 @@ +{{- if or .Values.eckOperator.enabled .Values.elasticsearchKibana.enabled }} +apiVersion: v1 +kind: Namespace +metadata: + name: eck-operator + labels: + app.kubernetes.io/name: eck-operator + app.kubernetes.io/component: "core" + {{- include "commonLabels" . | nindent 4}} + istio-injection: {{ ternary "enabled" "disabled" (and .Values.istio.enabled (eq (dig "istio" "injection" "enabled" .Values.eckOperator) "enabled")) }} +{{- end }} diff --git a/chart/templates/eck-operator/values.yaml b/chart/templates/eck-operator/values.yaml new file mode 100644 index 0000000000000000000000000000000000000000..832b7e4360dc82733620336c7738c4783d08c2b1 --- /dev/null +++ b/chart/templates/eck-operator/values.yaml @@ -0,0 +1,45 @@ +{{- if or .Values.eckOperator.enabled .Values.elasticsearchKibana.enabled }} +{{- include "values-secret" (dict "root" $ "package" .Values.eckOperator "name" "eck-operator" "defaults" (include "bigbang.defaults.eck-operator" .)) }} +{{- end }} + +{{- define "bigbang.defaults.eck-operator" -}} +license: + trial: {{ .Values.elasticsearchKibana.license.trial }} + keyJSON: | + {{ .Values.elasticsearchKibana.license.keyJSON | nindent 4 }} + +image: + pullPolicy: {{ .Values.imagePullPolicy }} + +{{- if .Values.istio.enabled }} +podAnnotations: + traffic.sidecar.istio.io/includeInboundPorts: "*" + traffic.sidecar.istio.io/excludeInboundPorts: "9443" + {{ include "istioAnnotation" . }} +{{- end }} + +openshift: {{ .Values.openshift }} + +istio: + enabled: {{ .Values.istio.enabled }} + hardened: + enabled: {{ or + (dig "istio" "hardened" "enabled" false .Values.monitoring.values) + (dig "istio" "hardened" "enabled" false .Values.addons.authservice.values) + (dig "hardened" "enabled" false .Values.istio.values) + (dig "istio" "hardened" "enabled" false .Values.grafana.values) + (dig "istio" "hardened" "enabled" false .Values.loki.values) + (dig "istio" "hardened" "enabled" false .Values.eckOperator.values) + (dig "istio" "hardened" "enabled" false .Values.elasticsearchKibana.values) + }} + +monitoring: + enabled: {{ .Values.monitoring.enabled }} + +networkPolicies: + enabled: {{ .Values.networkPolicies.enabled }} + controlPlaneCidr: {{ .Values.networkPolicies.controlPlaneCidr }} + +imagePullSecrets: + - name: private-registry +{{- end -}} diff --git a/chart/templates/elasticsearch-kibana/git-credentials.yaml b/chart/templates/elasticsearch-kibana/git-credentials.yaml new file mode 100644 index 0000000000000000000000000000000000000000..d6da7ae5ecbe27f490d3b3d58cf5c3bf139f8f7b --- /dev/null +++ b/chart/templates/elasticsearch-kibana/git-credentials.yaml @@ -0,0 +1,7 @@ +{{- $gitCredsSecretDict := dict + "name" "elasticsearchKibana" + "targetScope" .Values.elasticsearchKibana + "releaseName" .Release.Name + "releaseNamespace" .Release.Namespace +}} +{{- include "gitCredsSecret" $gitCredsSecretDict | nindent 0 -}} diff --git a/chart/templates/elasticsearch-kibana/gitrepository.yaml b/chart/templates/elasticsearch-kibana/gitrepository.yaml new file mode 100644 index 0000000000000000000000000000000000000000..b9524d1ac965fc8059dbe2f0e928b2d61ce0bec6 --- /dev/null +++ b/chart/templates/elasticsearch-kibana/gitrepository.yaml @@ -0,0 +1,24 @@ +{{- if and (eq .Values.elasticsearchKibana.sourceType "git") (not .Values.offline) ( .Values.elasticsearchKibana.enabled ) }} +{{- $gitCredsDict := dict + "name" "elasticsearchKibana" + "packageGitScope" .Values.elasticsearchKibana.git + "rootScope" . + "releaseName" .Release.Name +}} +apiVersion: source.toolkit.fluxcd.io/v1 +kind: GitRepository +metadata: + name: elasticsearch-kibana + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: elasticsearch-kibana + app.kubernetes.io/component: "core" + {{- include "commonLabels" . | nindent 4}} +spec: + interval: {{ .Values.flux.interval }} + url: {{ .Values.elasticsearchKibana.git.repo }} + ref: + {{- include "validRef" .Values.elasticsearchKibana.git | nindent 4 }} + {{ include "gitIgnore" . }} + {{- include "gitCredsExtended" $gitCredsDict | nindent 2 }} +{{- end }} diff --git a/chart/templates/elasticsearch-kibana/helmrelease.yaml b/chart/templates/elasticsearch-kibana/helmrelease.yaml new file mode 100644 index 0000000000000000000000000000000000000000..66399cf222fdce22ebc561a2e77ec5707eb8fdd5 --- /dev/null +++ b/chart/templates/elasticsearch-kibana/helmrelease.yaml @@ -0,0 +1,76 @@ +{{- $fluxSettingsEk := merge .Values.elasticsearchKibana.flux .Values.flux -}} +{{- if .Values.elasticsearchKibana.enabled }} +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + name: ek + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: elasticsearch-kibana + app.kubernetes.io/component: "core" + {{- include "commonLabels" . | nindent 4}} + annotations: + checksum/bigbang-values: {{ include (print $.Template.BasePath "/elasticsearch-kibana/values.yaml") . | sha256sum }} +spec: + driftDetection: + mode: warn + targetNamespace: logging + chart: + spec: + {{- if eq .Values.elasticsearchKibana.sourceType "git" }} + chart: {{ .Values.elasticsearchKibana.git.path }} + sourceRef: + kind: GitRepository + name: elasticsearch-kibana + namespace: {{ .Release.Namespace }} + {{- else }} + chart: {{ .Values.elasticsearchKibana.helmRepo.chartName }} + version: {{ .Values.elasticsearchKibana.helmRepo.tag }} + sourceRef: + kind: HelmRepository + name: {{ .Values.elasticsearchKibana.helmRepo.repoName }} + namespace: {{ .Release.Namespace }} + {{- $repoType := include "getRepoType" (dict "repoName" .Values.elasticsearchKibana.helmRepo.repoName "allRepos" $.Values.helmRepositories) -}} + {{- if (and .Values.elasticsearchKibana.helmRepo.cosignVerify (eq $repoType "oci")) }} # Needs to be an OCI repo + verify: + provider: cosign + secretRef: + name: {{ printf "%s-cosign-pub" .Values.elasticsearchKibana.helmRepo.repoName }} + {{- end }} + {{- end }} + interval: 5m + + {{- toYaml $fluxSettingsEk | nindent 2 }} + + {{- if .Values.elasticsearchKibana.postRenderers }} + postRenderers: + {{ toYaml .Values.elasticsearchKibana.postRenderers | nindent 4 }} + {{- end }} + valuesFrom: + - name: {{ .Release.Name }}-ek-values + kind: Secret + valuesKey: "common" + - name: {{ .Release.Name }}-ek-values + kind: Secret + valuesKey: "defaults" + - name: {{ .Release.Name }}-ek-values + kind: Secret + valuesKey: "overlays" + + {{/* ECK and Logging _always_ depend on .Values.elasticsearchKibana being enabled, so can assume they exist here */}} + dependsOn: + - name: eck-operator + namespace: {{ .Release.Namespace }} + {{- if .Values.monitoring.enabled }} + - name: monitoring + namespace: {{ .Release.Namespace }} + {{- end }} + {{- if .Values.gatekeeper.enabled }} + - name: gatekeeper + namespace: {{ .Release.Namespace }} + {{- end }} + {{- if .Values.kyvernoPolicies.enabled }} + - name: kyverno-policies + namespace: {{ .Release.Namespace }} + {{- end }} +{{- end }} diff --git a/chart/templates/elasticsearch-kibana/imagepullsecret.yaml b/chart/templates/elasticsearch-kibana/imagepullsecret.yaml new file mode 100644 index 0000000000000000000000000000000000000000..193a9ad6f4884029fbee6978ee0fa3cba4ac4a51 --- /dev/null +++ b/chart/templates/elasticsearch-kibana/imagepullsecret.yaml @@ -0,0 +1,16 @@ +{{- if .Values.elasticsearchKibana.enabled }} +{{- if ( include "imagePullSecret" . ) }} +apiVersion: v1 +kind: Secret +metadata: + name: private-registry + namespace: logging + labels: + app.kubernetes.io/name: elasticsearch-kibana + app.kubernetes.io/component: "core" + {{- include "commonLabels" . | nindent 4}} +type: kubernetes.io/dockerconfigjson +data: + .dockerconfigjson: {{ template "imagePullSecret" . }} +{{- end }} +{{- end }} diff --git a/chart/templates/elasticsearch-kibana/namespace.yaml b/chart/templates/elasticsearch-kibana/namespace.yaml new file mode 100644 index 0000000000000000000000000000000000000000..4a8112676e579e405ebdd42c57289039b9bf48a7 --- /dev/null +++ b/chart/templates/elasticsearch-kibana/namespace.yaml @@ -0,0 +1,12 @@ +{{- if .Values.elasticsearchKibana.enabled }} +--- +apiVersion: v1 +kind: Namespace +metadata: + name: logging + labels: + app.kubernetes.io/name: logging + app.kubernetes.io/component: "core" + {{- include "commonLabels" . | nindent 4}} + istio-injection: {{ ternary "enabled" "disabled" (and .Values.istio.enabled (eq (dig "istio" "injection" "enabled" .Values.elasticsearchKibana) "enabled")) }} +{{- end }} diff --git a/chart/templates/elasticsearch-kibana/secret-ca.yaml b/chart/templates/elasticsearch-kibana/secret-ca.yaml new file mode 100644 index 0000000000000000000000000000000000000000..f5c1950245780fb89f591eba8c5f04245b6efc75 --- /dev/null +++ b/chart/templates/elasticsearch-kibana/secret-ca.yaml @@ -0,0 +1,10 @@ +{{- if and .Values.elasticsearchKibana.enabled .Values.elasticsearchKibana.sso.enabled (or .Values.sso.certificate_authority (dig "certificateAuthority" "cert" false .Values.sso)) }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ default (dig "certificateAuthority" "secretName" "" .Values.sso) .Values.sso.secretName }} + namespace: logging +type: Opaque +data: + ca.pem: {{ default (dig "certificateAuthority" "cert" "" .Values.sso) .Values.sso.certificate_authority | b64enc }} +{{- end }} diff --git a/chart/templates/elasticsearch-kibana/values.yaml b/chart/templates/elasticsearch-kibana/values.yaml new file mode 100644 index 0000000000000000000000000000000000000000..dc96bc58c15b03b83fff4b3e1fabb1b0d82b9ea8 --- /dev/null +++ b/chart/templates/elasticsearch-kibana/values.yaml @@ -0,0 +1,246 @@ +{{- if .Values.elasticsearchKibana.enabled }} +{{- include "values-secret" (dict "root" $ "package" .Values.elasticsearchKibana "name" "ek" "defaults" (include "bigbang.defaults.logging" .)) }} +{{- end }} + +{{- define "bigbang.defaults.logging" -}} +# hostname is deprecated and replaced with domain. But if hostname exists then use it. +{{- $domainName := default .Values.domain .Values.hostname }} +hostname: {{ $domainName }} +domain: {{ $domainName }} + +openshift: {{ .Values.openshift }} + +imagePullPolicy: {{ .Values.imagePullPolicy }} + +istio: + enabled: {{ .Values.istio.enabled }} + hardened: + enabled: {{ or + (dig "istio" "hardened" "enabled" false .Values.monitoring.values) + (dig "istio" "hardened" "enabled" false .Values.addons.authservice.values) + (dig "hardened" "enabled" false .Values.istio.values) + (dig "istio" "hardened" "enabled" false .Values.grafana.values) + (dig "istio" "hardened" "enabled" false .Values.loki.values) + (dig "istio" "hardened" "enabled" false .Values.eckOperator.values) + (dig "istio" "hardened" "enabled" false .Values.elasticsearchKibana.values) + }} + kibana: + gateways: + - istio-system/{{ default "public" .Values.elasticsearchKibana.ingress.gateway }} + elasticsearch: + gateways: + - istio-system/{{ default "public" .Values.elasticsearchKibana.ingress.gateway }} + +networkPolicies: + enabled: {{ .Values.networkPolicies.enabled }} + ingressLabels: + {{- $gateway := default "public" .Values.elasticsearchKibana.ingress.gateway }} + {{- $default := dict "app" (dig "gateways" $gateway "ingressGateway" nil .Values.istio) "istio" nil }} + {{- toYaml (dig "values" "gateways" $gateway "selector" $default .Values.istio) | nindent 4 }} + +{{- if and .Values.addons.mattermost.elasticsearch.enabled .Values.addons.mattermost.enabled }} +mattermost: + enabled: true +{{- end }} + +{{- $disableDefaultFLB := dig "additionalOutputs" "disableDefault" false .Values.fluentbit.values }} +{{- if and .Values.fluentbit.enabled (not $disableDefaultFLB) }} +fluentbit: + enabled: true +{{- end }} + +{{- with .Values.elasticsearchKibana.sso }} +{{- if .enabled }} +sso: + enabled: {{ .enabled }} + client_id: {{ .client_id | quote }} + client_secret: {{ .client_secret | default "no-secret" }} + oidc: + host: {{ default (include "sso.host" $) (dig "oidc" "host" "" .) | quote }} + realm: {{ default (include "sso.realm" $) (dig "oidc" "realm" "" .) | quote }} + {{- /* Optional fields should be nil checked */ -}} + {{- $legacy := and (not (empty $.Values.sso.oidc.realm)) (not (empty $.Values.sso.oidc.host)) -}} + {{- list "issuer" (default (ternary nil (include "sso.url" $) $legacy) .issuer) | include "bigbang.addValueIfSet" | indent 2 }} + {{- list "auth_url" (default (ternary nil (include "sso.oidc.auth" $) $legacy) .auth_url) | include "bigbang.addValueIfSet" | indent 2 }} + {{- list "token_url" (default (ternary nil (include "sso.oidc.token" $) $legacy) .token_url) | include "bigbang.addValueIfSet" | indent 2 }} + {{- list "userinfo_url" (default (ternary nil (include "sso.oidc.userinfo" $) $legacy) .userinfo_url) | include "bigbang.addValueIfSet" | indent 2 }} + {{- list "jwkset_url" (default (ternary nil (include "sso.oidc.jwksuri" $) $legacy) .jwkset_url) | include "bigbang.addValueIfSet" | indent 2 }} + {{- list "claims_principal" (default (ternary nil (dig "oidc" "claims" "username" nil $.Values.sso) $legacy) .claims_principal) | include "bigbang.addValueIfSet" | indent 2 }} + {{- list "claims_principal_pattern" .claims_principal_pattern | include "bigbang.addValueIfSet" | indent 2 }} + {{- list "requested_scopes" .requested_scopes | include "bigbang.addValueIfSet" | indent 2 }} + {{- list "signature_algorithm" .signature_algorithm | include "bigbang.addValueIfSet" | indent 2 }} + {{- list "endsession_url" (default (ternary nil (include "sso.oidc.endsession" $) $legacy) .endsession_url) | include "bigbang.addValueIfSet" | indent 2 }} + {{- list "claims_group" (default (ternary nil (dig "oidc" "claims" "groups" nil $.Values.sso) $legacy) .claims_group) | include "bigbang.addValueIfSet" | indent 2 }} + {{- list "claims_mail" (default (ternary nil (dig "oidc" "claims" "email" nil $.Values.sso) $legacy) .claims_mail) | include "bigbang.addValueIfSet" | indent 2 }} + {{- list "cert_authorities" .cert_authorities | include "bigbang.addValueIfSet" | indent 2 }} +{{- end }} +{{- end }} + +kibana: + imagePullSecrets: + - name: private-registry +{{- if .Values.istio.enabled }} + podAnnotations: + {{ include "istioAnnotation" . }} +{{- end }} + +{{- if not .Values.elasticsearchKibana.serviceAccountAnnotations.kibana }} + serviceAccountAnnotations: {} +{{- else }} + serviceAccountAnnotations: {{ toYaml .Values.elasticsearchKibana.serviceAccountAnnotations.kibana | nindent 4 }} +{{- end }} +monitoring: + enabled: {{ .Values.monitoring.enabled }} + +metrics: + enabled: {{ .Values.monitoring.enabled }} + {{- $istioInjection := (and (eq (dig "istio" "injection" "enabled" .Values.elasticsearchKibana) "enabled") .Values.istio.enabled) }} + {{- if and (eq (dig "istio" "mtls" "mode" "STRICT" .Values.elasticsearchKibana.values) "STRICT") $istioInjection }} + serviceMonitor: + scheme: https + tlsConfig: + caFile: /etc/prom-certs/root-cert.pem + certFile: /etc/prom-certs/cert-chain.pem + keyFile: /etc/prom-certs/key.pem + insecureSkipVerify: true + {{- end }} + +elasticsearch: + imagePullSecrets: + - name: private-registry + master: + initContainers: + - name: elastic-internal-init-filesystem + securityContext: + privileged: false + capabilities: + drop: + - ALL + - name: elastic-internal-suspend + securityContext: + privileged: false + capabilities: + drop: + - ALL + {{- if .Values.elasticsearchKibana.sso.enabled }} + - name: elastic-internal-init-keystore + securityContext: + privileged: false + capabilities: + drop: + - ALL + {{- end }} + {{- if .Values.istio.enabled }} + podAnnotations: + {{ include "istioAnnotation" . }} + {{- end }} + data: + initContainers: + - name: elastic-internal-init-filesystem + securityContext: + privileged: false + capabilities: + drop: + - ALL + - name: elastic-internal-suspend + securityContext: + privileged: false + capabilities: + drop: + - ALL + {{- if .Values.elasticsearchKibana.sso.enabled }} + - name: elastic-internal-init-keystore + securityContext: + privileged: false + capabilities: + drop: + - ALL + {{- end }} + {{- if .Values.istio.enabled }} + podAnnotations: + {{ include "istioAnnotation" . }} + {{- end }} + ingest: + initContainers: + - name: elastic-internal-init-filesystem + securityContext: + privileged: false + capabilities: + drop: + - ALL + - name: elastic-internal-suspend + securityContext: + privileged: false + capabilities: + drop: + - ALL + {{- if .Values.elasticsearchKibana.sso.enabled }} + - name: elastic-internal-init-keystore + securityContext: + privileged: false + capabilities: + drop: + - ALL + {{- end }} + {{- if .Values.istio.enabled }} + podAnnotations: + {{ include "istioAnnotation" . }} + {{- end }} + ml: + initContainers: + - name: elastic-internal-init-filesystem + securityContext: + privileged: false + capabilities: + drop: + - ALL + - name: elastic-internal-suspend + securityContext: + privileged: false + capabilities: + drop: + - ALL + {{- if .Values.elasticsearchKibana.sso.enabled }} + - name: elastic-internal-init-keystore + securityContext: + privileged: false + capabilities: + drop: + - ALL + {{- end }} + {{- if .Values.istio.enabled }} + podAnnotations: + {{ include "istioAnnotation" . }} + {{- end }} + coord: + initContainers: + - name: elastic-internal-init-filesystem + securityContext: + privileged: false + capabilities: + drop: + - ALL + - name: elastic-internal-suspend + securityContext: + privileged: false + capabilities: + drop: + - ALL + {{- if .Values.elasticsearchKibana.sso.enabled }} + - name: elastic-internal-init-keystore + securityContext: + privileged: false + capabilities: + drop: + - ALL + {{- end }} + {{- if .Values.istio.enabled }} + podAnnotations: + {{ include "istioAnnotation" . }} + {{- end }} + {{- if not .Values.elasticsearchKibana.serviceAccountAnnotations.elasticsearch }} + serviceAccountAnnotations: {} + {{- else }} + serviceAccountAnnotations: {{ toYaml .Values.elasticsearchKibana.serviceAccountAnnotations.elasticsearch | nindent 4 }} + {{- end }} +{{- end -}} diff --git a/chart/templates/external-secrets/git-credentials.yaml b/chart/templates/external-secrets/git-credentials.yaml new file mode 100644 index 0000000000000000000000000000000000000000..1d97643d654fe41f7b80cb753755ec29ec21593c --- /dev/null +++ b/chart/templates/external-secrets/git-credentials.yaml @@ -0,0 +1,7 @@ +{{- $gitCredsSecretDict := dict + "name" "externalSecrets" + "targetScope" .Values.addons.externalSecrets + "releaseName" .Release.Name + "releaseNamespace" .Release.Namespace +}} +{{- include "gitCredsSecret" $gitCredsSecretDict | nindent 0 -}} diff --git a/chart/templates/external-secrets/gitrepository.yaml b/chart/templates/external-secrets/gitrepository.yaml new file mode 100644 index 0000000000000000000000000000000000000000..82014b9d8504c661c34ea46ab3e8e076c0964b9c --- /dev/null +++ b/chart/templates/external-secrets/gitrepository.yaml @@ -0,0 +1,24 @@ +{{- if and (eq .Values.addons.externalSecrets.sourceType "git") .Values.addons.externalSecrets.enabled }} +{{- $gitCredsDict := dict + "name" "externalSecrets" + "packageGitScope" .Values.addons.externalSecrets.git + "rootScope" . + "releaseName" .Release.Name +}} +apiVersion: source.toolkit.fluxcd.io/v1 +kind: GitRepository +metadata: + name: external-secrets + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: external-secrets + app.kubernetes.io/component: "core" + {{- include "commonLabels" . | nindent 4}} +spec: + interval: {{ .Values.flux.interval }} + url: {{ .Values.addons.externalSecrets.git.repo }} + ref: + {{- include "validRef" .Values.addons.externalSecrets.git | nindent 4 }} + {{ include "gitIgnore" . }} + {{- include "gitCredsExtended" $gitCredsDict | nindent 2 }} +{{- end }} diff --git a/chart/templates/external-secrets/helmrelease.yaml b/chart/templates/external-secrets/helmrelease.yaml new file mode 100644 index 0000000000000000000000000000000000000000..1ff84d188e27bb2a4669df83766f25fc6a76c44c --- /dev/null +++ b/chart/templates/external-secrets/helmrelease.yaml @@ -0,0 +1,73 @@ +{{- $fluxSettings := merge .Values.addons.externalSecrets.flux .Values.flux -}} +{{- if .Values.addons.externalSecrets.enabled }} +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + name: external-secrets + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: external-secrets + app.kubernetes.io/component: "core" + {{- include "commonLabels" . | nindent 4}} + annotations: + checksum/bigbang-values: {{ include (print $.Template.BasePath "/external-secrets/values.yaml") . | sha256sum }} +spec: + targetNamespace: external-secrets + chart: + spec: + {{- if eq .Values.addons.externalSecrets.sourceType "git" }} + chart: {{ .Values.addons.externalSecrets.git.path }} + sourceRef: + kind: GitRepository + name: external-secrets + namespace: {{ .Release.Namespace }} + {{- else }} + chart: {{ .Values.addons.externalSecrets.helmRepo.chartName }} + version: {{ .Values.addons.externalSecrets.helmRepo.tag }} + sourceRef: + kind: HelmRepository + name: {{ .Values.addons.externalSecrets.helmRepo.repoName }} + namespace: {{ .Release.Namespace }} + {{- $repoType := include "getRepoType" (dict "repoName" .Values.addons.externalSecrets.helmRepo.repoName "allRepos" .Values.helmRepositories) -}} + {{- if (and .Values.addons.externalSecrets.helmRepo.cosignVerify (eq $repoType "oci")) }} # Needs to be an OCI repo + verify: + provider: cosign + secretRef: + name: {{ printf "%s-cosign-pub" .Values.addons.externalSecrets.helmRepo.repoName }} + {{- end }} + {{- end }} + interval: 5m + + {{- toYaml $fluxSettings | nindent 2 }} + + {{- if .Values.addons.externalSecrets.postRenderers }} + postRenderers: + {{- toYaml .Values.addons.externalSecrets.postRenderers | nindent 2 }} + {{- end }} + valuesFrom: + - name: {{ .Release.Name }}-external-secrets-values + kind: Secret + valuesKey: "common" + - name: {{ .Release.Name }}-external-secrets-values + kind: Secret + valuesKey: "defaults" + - name: {{ .Release.Name }}-external-secrets-values + kind: Secret + valuesKey: "overlays" + + {{- if or .Values.istio.enabled .Values.kyvernoPolicies.enabled .Values.monitoring.enabled }} + dependsOn: + {{- if .Values.istio.enabled }} + - name: istio + namespace: {{ .Release.Namespace }} + {{- end }} + {{- if .Values.kyvernoPolicies.enabled }} + - name: kyverno-policies + namespace: {{ .Release.Namespace }} + {{- end }} + {{- if .Values.monitoring.enabled }} + - name: monitoring + namespace: {{ .Release.Namespace }} + {{- end }} + {{- end }} +{{- end }} \ No newline at end of file diff --git a/chart/templates/external-secrets/imagepullsecret.yaml b/chart/templates/external-secrets/imagepullsecret.yaml new file mode 100644 index 0000000000000000000000000000000000000000..8c01b2b78d1728d828fd42c71241dcf3f5437311 --- /dev/null +++ b/chart/templates/external-secrets/imagepullsecret.yaml @@ -0,0 +1,12 @@ +{{- if .Values.addons.externalSecrets.enabled }} +{{- if ( include "imagePullSecret" . ) }} +apiVersion: v1 +kind: Secret +metadata: + name: private-registry + namespace: external-secrets +type: kubernetes.io/dockerconfigjson +data: + .dockerconfigjson: {{ template "imagePullSecret" . }} +{{- end }} +{{- end }} diff --git a/chart/templates/external-secrets/namespace.yaml b/chart/templates/external-secrets/namespace.yaml new file mode 100644 index 0000000000000000000000000000000000000000..2dc63e1d6aba92b5204ca48cf3c39381fb872081 --- /dev/null +++ b/chart/templates/external-secrets/namespace.yaml @@ -0,0 +1,13 @@ +{{- if .Values.addons.externalSecrets.enabled }} +apiVersion: v1 +kind: Namespace +metadata: + labels: + meta.helm.sh/release-namespace: bigbang + meta.helm.sh/release-name: bigbang + app.kubernetes.io/name: external-secrets + app.kubernetes.io/component: "core" + {{- include "commonLabels" . | nindent 4}} + istio-injection: {{ ternary "enabled" "disabled" (and .Values.istio.enabled (eq (dig "istio" "injection" "enabled" .Values.addons.externalSecrets) "enabled")) }} + name: external-secrets +{{- end }} diff --git a/chart/templates/external-secrets/values.yaml b/chart/templates/external-secrets/values.yaml new file mode 100644 index 0000000000000000000000000000000000000000..9de2abcf26486180a28330fdf5d37c4a06f8ef82 --- /dev/null +++ b/chart/templates/external-secrets/values.yaml @@ -0,0 +1,31 @@ +{{- if .Values.addons.externalSecrets.enabled }} +{{- include "values-secret" (dict "root" $ "package" .Values.addons.externalSecrets "name" "external-secrets" "defaults" (include "bigbang.defaults.external-secrets" .)) }} +{{- end }} + +{{- define "bigbang.defaults.external-secrets" -}} + +image: + imagePullPolicy: {{ .Values.imagePullPolicy }} + +monitoring: + enabled: {{ .Values.monitoring.enabled }} + +networkPolicies: + enabled: {{ .Values.networkPolicies.enabled }} + controlPlaneCidr: {{ .Values.networkPolicies.controlPlaneCidr }} + +{{- if .Values.istio.enabled }} +annotations: + {{ include "istioAnnotation" . }} +{{- end }} + +istio: + enabled: {{ .Values.istio.enabled }} + hardened: + enabled: {{ or + (dig "istio" "hardened" "enabled" false .Values.addons.externalSecrets.values) + (dig "hardened" "enabled" false .Values.istio.values) + }} + +openshift: {{ .Values.openshift }} +{{- end -}} diff --git a/chart/templates/fluentbit/git-credentials.yaml b/chart/templates/fluentbit/git-credentials.yaml new file mode 100644 index 0000000000000000000000000000000000000000..98a6882c6de337b5c7bd03383704fb24b4cc2563 --- /dev/null +++ b/chart/templates/fluentbit/git-credentials.yaml @@ -0,0 +1,7 @@ +{{- $gitCredsSecretDict := dict + "name" "fluentbit" + "targetScope" .Values.fluentbit + "releaseName" .Release.Name + "releaseNamespace" .Release.Namespace +}} +{{- include "gitCredsSecret" $gitCredsSecretDict | nindent 0 -}} diff --git a/chart/templates/fluentbit/gitrepository.yaml b/chart/templates/fluentbit/gitrepository.yaml new file mode 100644 index 0000000000000000000000000000000000000000..092ee90cdbb1c6975cbdd7f2f3f4234b50287595 --- /dev/null +++ b/chart/templates/fluentbit/gitrepository.yaml @@ -0,0 +1,24 @@ +{{- if and (eq .Values.fluentbit.sourceType "git") (not .Values.offline) (.Values.fluentbit.enabled) }} +{{- $gitCredsDict := dict + "name" "fluentbit" + "packageGitScope" .Values.fluentbit.git + "rootScope" . + "releaseName" .Release.Name +}} +apiVersion: source.toolkit.fluxcd.io/v1 +kind: GitRepository +metadata: + name: fluentbit + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: fluentbit + app.kubernetes.io/component: "core" + {{- include "commonLabels" . | nindent 4}} +spec: + interval: {{ .Values.flux.interval }} + url: {{ .Values.fluentbit.git.repo }} + ref: + {{- include "validRef" .Values.fluentbit.git | nindent 4 }} + {{ include "gitIgnore" . }} + {{- include "gitCredsExtended" $gitCredsDict | nindent 2 }} +{{- end }} diff --git a/chart/templates/fluentbit/helmrelease.yaml b/chart/templates/fluentbit/helmrelease.yaml new file mode 100644 index 0000000000000000000000000000000000000000..3317b9dad8d0deab0b43cae9a9a081f41f5f8453 --- /dev/null +++ b/chart/templates/fluentbit/helmrelease.yaml @@ -0,0 +1,93 @@ +{{- $fluxSettingsFluentbit := merge .Values.fluentbit.flux .Values.flux -}} +{{- if .Values.fluentbit.enabled }} +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + name: fluentbit + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: fluentbit + app.kubernetes.io/component: "core" + {{- include "commonLabels" . | nindent 4}} + annotations: + checksum/bigbang-values: {{ include (print $.Template.BasePath "/fluentbit/values.yaml") . | sha256sum }} +spec: + driftDetection: + mode: warn + targetNamespace: fluentbit + releaseName: fluentbit + chart: + spec: + {{- if eq .Values.fluentbit.sourceType "git" }} + chart: {{ .Values.fluentbit.git.path }} + sourceRef: + kind: GitRepository + name: fluentbit + namespace: {{ .Release.Namespace }} + {{- else }} + chart: {{ .Values.fluentbit.helmRepo.chartName }} + version: {{ .Values.fluentbit.helmRepo.tag }} + sourceRef: + kind: HelmRepository + name: {{ .Values.fluentbit.helmRepo.repoName }} + namespace: {{ .Release.Namespace }} + {{- $repoType := include "getRepoType" (dict "repoName" .Values.fluentbit.helmRepo.repoName "allRepos" $.Values.helmRepositories) -}} + {{- if (and .Values.fluentbit.helmRepo.cosignVerify (eq $repoType "oci")) }} # Needs to be an OCI repo + verify: + provider: cosign + secretRef: + name: {{ printf "%s-cosign-pub" .Values.fluentbit.helmRepo.repoName }} + {{- end }} + {{- end }} + interval: 5m + + {{- toYaml $fluxSettingsFluentbit | nindent 2 }} + + {{- if .Values.fluentbit.postRenderers }} + postRenderers: + {{ toYaml .Values.fluentbit.postRenderers | nindent 4 }} + {{- end }} + valuesFrom: + - name: {{ .Release.Name }}-fluentbit-values + kind: Secret + valuesKey: "common" + - name: {{ .Release.Name }}-fluentbit-values + kind: Secret + valuesKey: "defaults" + - name: {{ .Release.Name }}-fluentbit-values + kind: Secret + valuesKey: "overlays" + + {{/* To support a "standalone" fluentbit for shipping to central location we conditionally depend on logging enabled */}} + {{- if or .Values.elasticsearchKibana.enabled .Values.gatekeeper.enabled .Values.istio.enabled .Values.kyvernoPolicies.enabled .Values.kyverno.enabled .Values.monitoring.enabled }} + dependsOn: + {{- if .Values.elasticsearchKibana.enabled }} + - name: ek + namespace: {{ .Release.Namespace }} + {{- end }} + {{- if .Values.loki.enabled }} + - name: loki + namespace: {{ .Release.Namespace }} + {{- end }} + {{- if .Values.gatekeeper.enabled }} + - name: gatekeeper + namespace: {{ .Release.Namespace }} + {{- end }} + {{- if .Values.istio.enabled }} + - name: istio + namespace: {{ .Release.Namespace }} + {{- end }} + {{- if .Values.kyverno.enabled }} + - name: kyverno + namespace: {{ .Release.Namespace }} + {{- end }} + {{- if .Values.kyvernoPolicies.enabled }} + - name: kyverno-policies + namespace: {{ .Release.Namespace }} + {{- end }} + {{- if .Values.monitoring.enabled }} + - name: monitoring + namespace: {{ .Release.Namespace }} + {{- end }} + {{- end }} +{{- end }} diff --git a/chart/templates/fluentbit/imagepullsecret.yaml b/chart/templates/fluentbit/imagepullsecret.yaml new file mode 100644 index 0000000000000000000000000000000000000000..d7d1681926b46bc1c50d6c66982457b0e7404534 --- /dev/null +++ b/chart/templates/fluentbit/imagepullsecret.yaml @@ -0,0 +1,16 @@ +{{- if .Values.fluentbit.enabled }} +{{- if ( include "imagePullSecret" . ) }} +apiVersion: v1 +kind: Secret +metadata: + name: private-registry + namespace: fluentbit + labels: + app.kubernetes.io/name: fluentbit + app.kubernetes.io/component: "core" + {{- include "commonLabels" . | nindent 4}} +type: kubernetes.io/dockerconfigjson +data: + .dockerconfigjson: {{ template "imagePullSecret" . }} +{{- end }} +{{- end }} diff --git a/chart/templates/fluentbit/namespace.yaml b/chart/templates/fluentbit/namespace.yaml new file mode 100644 index 0000000000000000000000000000000000000000..a0eba36a8835e5196f1fd87276516834adcffc25 --- /dev/null +++ b/chart/templates/fluentbit/namespace.yaml @@ -0,0 +1,11 @@ +{{- if .Values.fluentbit.enabled }} +apiVersion: v1 +kind: Namespace +metadata: + name: fluentbit + labels: + app.kubernetes.io/name: fluentbit + app.kubernetes.io/component: "core" + {{- include "commonLabels" . | nindent 4}} + istio-injection: {{ ternary "enabled" "disabled" (and .Values.istio.enabled (eq (dig "istio" "injection" "enabled" .Values.fluentbit) "enabled")) }} +{{- end }} diff --git a/chart/templates/fluentbit/values.yaml b/chart/templates/fluentbit/values.yaml new file mode 100644 index 0000000000000000000000000000000000000000..e1cf1d7a2fa2dde1d2232f8fc659e4fd9e2e4817 --- /dev/null +++ b/chart/templates/fluentbit/values.yaml @@ -0,0 +1,255 @@ +{{- if .Values.fluentbit.enabled }} +{{- include "values-secret" (dict "root" $ "package" .Values.fluentbit "name" "fluentbit" "defaults" (include "bigbang.defaults.fluentbit" .)) }} +{{- end }} + +{{- define "bigbang.defaults.fluentbit" -}} +{{- $disableDefault := dig "additionalOutputs" "disableDefault" false .Values.fluentbit.values }} +{{- $clusterName := ( default "logging-loki" .Values.loki.clusterName ) }} + +{{- if (not $disableDefault) }} +loki: + enabled: {{ .Values.loki.enabled }} + +elasticsearchKibana: + enabled: {{.Values.elasticsearchKibana.enabled }} + +{{- if .Values.elasticsearchKibana.enabled }} +env: + - name: FLUENT_ELASTICSEARCH_PASSWORD + valueFrom: + secretKeyRef: + name: logging-ek-es-elastic-user + key: elastic + +extraVolumes: + - hostPath: + path: /var/log/flb-storage/ + type: DirectoryOrCreate + name: flb-storage + - secret: + secretName: logging-ek-es-http-certs-public + name: elasticsearch-certs + +extraVolumeMounts: + - mountPath: /var/log/flb-storage/ + name: flb-storage + readOnly: false + - mountPath: /etc/elasticsearch/certs/ + name: elasticsearch-certs +{{- end }} +{{- if or .Values.elasticsearchKibana.enabled .Values.loki.enabled }} +config: + outputs: | + {{- if .Values.elasticsearchKibana.enabled }} + [OUTPUT] + Name es + Match kube.* + Host {{ dig "elasticsearch" "name" "logging-ek" .Values.fluentbit.values }}-es-http.logging + HTTP_User elastic + HTTP_Passwd ${FLUENT_ELASTICSEARCH_PASSWORD} + Logstash_Format On + Suppress_Type_Name On + Retry_Limit False + Replace_Dots On + {{- if and .Values.istio.enabled (dig "istio" "elasticsearch" "enabled" false .Values.elasticsearchKibana.values) }} + tls Off + {{- else }} + tls On + tls.verify On + tls.ca_file /etc/elasticsearch/certs/ca.crt + {{- end }} + storage.total_limit_size {{ dig "storage" "total_limit_size" "10G" .Values.fluentbit.values }} + [OUTPUT] + Name es + Match host.* + Host {{ dig "elasticsearch" "name" "logging-ek" .Values.fluentbit.values }}-es-http.logging + HTTP_User elastic + HTTP_Passwd ${FLUENT_ELASTICSEARCH_PASSWORD} + Logstash_Format On + Suppress_Type_Name On + Logstash_Prefix node + Retry_Limit False + tls On + tls.verify On + tls.ca_file /etc/elasticsearch/certs/ca.crt + storage.total_limit_size {{ dig "storage" "total_limit_size" "10G" .Values.fluentbit.values }} + {{- end }} + + {{- if .Values.loki.enabled }} + [OUTPUT] + name loki + match kube.* + labels job=fluentbit, container=$kubernetes['container_name'], pod=$kubernetes['pod_name'], namespace=$kubernetes['namespace_name'], node_name=$kubernetes['host'] + {{- if eq .Values.loki.strategy "monolith" }} + host logging-loki.logging + {{- else }} + host logging-loki-write.logging + {{- end }} + port 3100 + auto_kubernetes_labels on + Retry_Limit False + tls Off + storage.total_limit_size {{ dig "storage" "total_limit_size" "10G" .Values.fluentbit.values }} + [OUTPUT] + name loki + match host.* + labels job=fluentbit, container=$kubernetes['container_name'], pod=$kubernetes['pod_name'], namespace=$kubernetes['namespace_name'], node_name=$kubernetes['host'] + {{- if eq .Values.loki.strategy "monolith" }} + host logging-loki.logging + {{- else }} + host logging-loki-write.logging + {{- end }} + port 3100 + auto_kubernetes_labels on + Retry_Limit False + tls Off + storage.total_limit_size {{ dig "storage" "total_limit_size" "10G" .Values.fluentbit.values }} + {{- end }} + + filters: | + {{- if .Values.loki.enabled }} + [FILTER] + Name kubernetes + Match kube.* + Kube_CA_File /var/run/secrets/kubernetes.io/serviceaccount/ca.crt + Kube_Token_File /var/run/secrets/kubernetes.io/serviceaccount/token + Merge_Log On + Merge_Log_Key log_processed + K8S-Logging.Parser On + K8S-Logging.Exclude Off + Buffer_Size 1M + [FILTER] + Name lua + Match kube.* + script /fluent-bit/scripts/remove_labels.lua + call remove_labels + [FILTER] + Alias lua.add + Name lua + Match kube.* + script /fluent-bit/scripts/add_labels.lua + call add_labels + {{- end }} + +{{- end }} +{{- end }} + +imagePullSecrets: + - name: private-registry + +image: + pullPolicy: {{ .Values.imagePullPolicy }} + +networkPolicies: + enabled: {{ .Values.networkPolicies.enabled }} + controlPlaneCidr: {{ .Values.networkPolicies.controlPlaneCidr }} + +istio: + enabled: {{ .Values.istio.enabled }} + hardened: + enabled: {{ or + (dig "istio" "hardened" "enabled" false .Values.fluentbit.values) + (dig "hardened" "enabled" false .Values.istio.values) + }} + +openShift: + enabled: {{ .Values.openshift }} + +{{- if .Values.monitoring.enabled }} +serviceMonitor: + enabled: true + namespace: monitoring + interval: 10s + scrapeTimeout: 10s + selector: + prometheus: monitoring-monitoring-kube-prometheus + # conditional passes only if all conditionals are true: + # - istio: enabled + # - mTLS: SCRICT + # - istio injection: enabled (for logging ns) + {{- if and .Values.istio.enabled (eq (dig "istio" "mtls" "mode" "STRICT" .Values.fluentbit.values) "STRICT") (eq (dig "istio" "injection" "enabled" .Values.elasticsearchKibana.values) "enabled") }} + scheme: https + tlsConfig: + caFile: /etc/prom-certs/root-cert.pem + certFile: /etc/prom-certs/cert-chain.pem + keyFile: /etc/prom-certs/key.pem + insecureSkipVerify: true # Prometheus does not support Istio security naming, thus skip verifying target pod certificate + {{- end }} + +dashboards: + enabled: true + labelKey: grafana_dashboard + namespace: monitoring +{{- end }} + +{{- if .Values.istio.enabled }} +podAnnotations: + {{ include "istioAnnotation" . }} +{{- end }} + +openshift: {{ .Values.openshift }} + +{{- if .Values.openshift }} +podSecurityContext: + seLinuxOptions: + type: "spc_t" +{{- end }} + +# Those are BB custom lua scripts so they are taken out from package values file and placed here. +# https://docs.fluentbit.io/manual/pipeline/filters/lua +luaScripts: + add_labels.lua: | + function add_labels(tag, timestamp, record) + record["kubernetes"]["labels"]["cluster"] = "{{ $clusterName }}" + return 1, timestamp, record + end + remove_labels.lua: | + function remove_labels(tag, timestamp, record) + + local patterns = { + "service.istio.-", + "security.istio.-", + "helm.-", + "istio.-", + "statefulset.kubernetes.io/pod%-name", + "prometheus", + "operator.prometheus.io/name", + "app.kubernetes.io/managed%-by", + "app.kubernetes.io/part%-of", + "apps.kuberentes.io/version", + "apps.kubernetes.io/pod%-index", + "heritage", + "release", + "elasticsearch.k8s.elastic.co.node.-" + } + + if record["kubernetes"] ~= nil then + if record["kubernetes"]["labels"] ~= nil then + + for key, value in pairs(record["kubernetes"]["labels"]) do + -- Uncomment for debugging + -- print("Checking - Label " .. key .. "=" .. value) + + local remove_key = false + local i = 1 + while not remove_key and i <= #patterns do + if string.match(key, patterns[i]) then + remove_key = true + end + i = i + 1 + end + + -- Key matched a pattern, remove it + if remove_key then + -- Uncomment for debugging + -- print("Removing - Label " .. key .. "=" .. value) + record["kubernetes"]["labels"][key] = nil + end + end + + end + end + + return 1, timestamp, record + end +{{- end -}} diff --git a/chart/templates/fortify/git-credentials.yaml b/chart/templates/fortify/git-credentials.yaml new file mode 100644 index 0000000000000000000000000000000000000000..492fc5bb4946514ea46c402cfee93be1da493a62 --- /dev/null +++ b/chart/templates/fortify/git-credentials.yaml @@ -0,0 +1,8 @@ +{{- $pkg := "fortify" }} +{{- $gitCredsSecretDict := dict + "name" $pkg + "targetScope" (get .Values.addons $pkg) + "releaseName" .Release.Name + "releaseNamespace" .Release.Namespace +}} +{{- include "gitCredsSecret" $gitCredsSecretDict | nindent 0 -}} diff --git a/chart/templates/fortify/gitrepository.yaml b/chart/templates/fortify/gitrepository.yaml new file mode 100644 index 0000000000000000000000000000000000000000..8d196c851135e79443f2df22cadfa51165b16e01 --- /dev/null +++ b/chart/templates/fortify/gitrepository.yaml @@ -0,0 +1,21 @@ +{{- $pkg := "fortify" }} +{{- if and (eq (get .Values.addons $pkg).sourceType "git") (not .Values.offline) (get .Values.addons $pkg).enabled }} +{{- $gitCredsDict := dict + "name" $pkg + "packageGitScope" (get .Values.addons $pkg).git + "rootScope" . + "releaseName" .Release.Name +}} +apiVersion: source.toolkit.fluxcd.io/v1 +kind: GitRepository +metadata: + name: {{ $pkg }} + namespace: {{ .Release.Namespace }} +spec: + interval: {{ .Values.flux.interval }} + url: {{ (get .Values.addons $pkg).git.repo }} + ref: + {{- include "validRef" (get .Values.addons $pkg).git | nindent 4 }} + {{ include "gitIgnore" . }} + {{- include "gitCredsExtended" $gitCredsDict | nindent 2 }} +{{- end }} diff --git a/chart/templates/fortify/helmrelease.yaml b/chart/templates/fortify/helmrelease.yaml new file mode 100644 index 0000000000000000000000000000000000000000..4d3cd1a9e08783e7b45b7394132d1f9cb200b305 --- /dev/null +++ b/chart/templates/fortify/helmrelease.yaml @@ -0,0 +1,74 @@ +{{- $pkg := "fortify" }} +{{- $fluxSettingsFortify := merge .Values.addons.fortify.flux .Values.flux -}} +{{- if (get .Values.addons $pkg).enabled }} +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + name: {{ $pkg }} + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ $pkg }} + {{- include "commonLabels" . | nindent 4}} + annotations: + checksum/bigbang-values: {{ include (print $.Template.BasePath "/fortify/values.yaml") . | sha256sum }} +spec: + releaseName: {{ $pkg }} + targetNamespace: {{ $pkg }} + chart: + spec: + {{- if eq (get .Values.addons $pkg).sourceType "git" }} + chart: {{ (get .Values.addons $pkg).git.path }} + sourceRef: + kind: GitRepository + name: fortify + namespace: {{ .Release.Namespace }} + {{- else }} + chart: {{ (get .Values.addons $pkg).helmRepo.chartName }} + version: {{ (get .Values.addons $pkg).helmRepo.tag }} + sourceRef: + kind: HelmRepository + name: {{ (get .Values.addons $pkg).helmRepo.repoName }} + namespace: {{ .Release.Namespace }} + {{- $repoType := include "getRepoType" (dict "repoName" (get .Values.addons $pkg).helmRepo.repoName "allRepos" $.Values.helmRepositories) -}} + {{- if (and (get .Values.addons $pkg).helmRepo.cosignVerify (eq $repoType "oci")) }} # Needs to be an OCI repo + verify: + provider: cosign + secretRef: + name: {{ printf "%s-cosign-pub" (get .Values.addons $pkg).helmRepo.repoName }} + {{- end }} + {{- end }} + interval: 5m + + {{- toYaml $fluxSettingsFortify | nindent 2 }} + + {{- if (get .Values.addons $pkg).postRenderers }} + postRenderers: + {{ toYaml (get .Values.addons $pkg).postRenderers | nindent 4 }} + {{- end }} + valuesFrom: + - name: {{ .Release.Name }}-{{ $pkg }}-values + kind: Secret + valuesKey: "common" + - name: {{ .Release.Name }}-{{ $pkg }}-values + kind: Secret + valuesKey: "defaults" + - name: {{ .Release.Name }}-{{ $pkg }}-values + kind: Secret + valuesKey: "overlays" + + {{- if or .Values.istio.enabled .Values.kyvernoPolicies.enabled .Values.monitoring.enabled }} + dependsOn: + {{- if .Values.istio.enabled }} + - name: istio + namespace: {{ .Release.Namespace }} + {{- end }} + {{- if .Values.kyvernoPolicies.enabled }} + - name: kyverno-policies + namespace: {{ .Release.Namespace }} + {{- end }} + {{- if .Values.monitoring.enabled }} + - name: monitoring + namespace: {{ .Release.Namespace }} + {{- end }} + {{- end }} +{{- end }} diff --git a/chart/templates/fortify/imagepullsecret.yaml b/chart/templates/fortify/imagepullsecret.yaml new file mode 100644 index 0000000000000000000000000000000000000000..7122078d76f1852f19e09f354b355107ad017324 --- /dev/null +++ b/chart/templates/fortify/imagepullsecret.yaml @@ -0,0 +1,14 @@ +{{- $pkg := "fortify" }} +{{- if and (get .Values.addons $pkg).enabled ( include "imagePullSecret" . ) }} +apiVersion: v1 +kind: Secret +metadata: + name: private-registry + namespace: {{ $pkg }} + labels: + app.kubernetes.io/name: {{ $pkg }} + {{- include "commonLabels" . | nindent 4}} +type: kubernetes.io/dockerconfigjson +data: + .dockerconfigjson: {{ template "imagePullSecret" . }} +{{- end }} diff --git a/chart/templates/fortify/namespace.yaml b/chart/templates/fortify/namespace.yaml new file mode 100644 index 0000000000000000000000000000000000000000..2e138b54e18c8746231cafc2a060aed84965dffb --- /dev/null +++ b/chart/templates/fortify/namespace.yaml @@ -0,0 +1,12 @@ +{{- $pkg := "fortify" }} +{{- if (get .Values.addons $pkg).enabled }} +apiVersion: v1 +kind: Namespace +metadata: + name: {{ $pkg }} + labels: + istio-injection: {{ ternary "enabled" "disabled" (and .Values.istio.enabled (eq (dig "istio" "injection" "enabled" (get .Values.addons $pkg)) "enabled")) }} + app.kubernetes.io/name: {{ $pkg }} + app.kubernetes.io/component: "core" + {{- include "commonLabels" . | nindent 4}} +{{- end }} \ No newline at end of file diff --git a/chart/templates/fortify/values.yaml b/chart/templates/fortify/values.yaml new file mode 100644 index 0000000000000000000000000000000000000000..4a3f73eba10b0a62ba36dbdad8364d32998e4f6a --- /dev/null +++ b/chart/templates/fortify/values.yaml @@ -0,0 +1,45 @@ +{{- $pkg := "fortify" }} + +{{- /* Create secret */ -}} +{{- if (get .Values.addons $pkg).enabled }} +{{- include "values-secret" (dict "root" $ "package" (get .Values.addons $pkg) "name" $pkg "defaults" (include (printf "bigbang.defaults.%s" $pkg) .)) }} +{{- end }} + +{{- define "bigbang.defaults.fortify" -}} + +imagePullSecrets: +- name: private-registry +imagePullPolicy: {{ .Values.imagePullPolicy }} + +externalURL: https://fortify.{{ .Values.domain }} + +domain: {{ .Values.domain }} + +istio: + enabled: {{ .Values.istio.enabled }} + hardened: + enabled: {{ or + (dig "istio" "hardened" "enabled" false .Values.addons.fortify.values) + (dig "hardened" "enabled" false .Values.istio.values) + }} + fortify: + gateways: + - istio-system/{{ default "public" .Values.addons.fortify.ingress.gateway }} + +networkPolicies: + enabled: {{ .Values.networkPolicies.enabled }} + controlPlaneCidr: {{ .Values.networkPolicies.controlPlaneCidr }} + ingressLabels: + {{- $gateway := default "public" .Values.addons.fortify.ingress.gateway }} + {{- $default := dict "app" (dig "gateways" $gateway "ingressGateway" nil .Values.istio) "istio" nil }} + {{- toYaml (dig "values" "gateways" $gateway "selector" $default .Values.istio) | nindent 4 }} + +openshift: {{ .Values.openshift }} + +monitoring: + enabled: {{ .Values.monitoring.enabled }} + +sso: + enabled: {{ default "false" .Values.addons.fortify.sso.enabled }} + +{{- end }} diff --git a/chart/templates/gatekeeper/git-credentials.yaml b/chart/templates/gatekeeper/git-credentials.yaml new file mode 100644 index 0000000000000000000000000000000000000000..50cfaf54736584db955b484ca2f2c3bccb1ee7f1 --- /dev/null +++ b/chart/templates/gatekeeper/git-credentials.yaml @@ -0,0 +1,7 @@ +{{- $gitCredsSecretDict := dict + "name" "gatekeeper" + "targetScope" .Values.gatekeeper + "releaseName" .Release.Name + "releaseNamespace" .Release.Namespace +}} +{{- include "gitCredsSecret" $gitCredsSecretDict | nindent 0 -}} diff --git a/chart/templates/gatekeeper/gitrepository.yaml b/chart/templates/gatekeeper/gitrepository.yaml new file mode 100644 index 0000000000000000000000000000000000000000..6d1cd71ffe00dfc1c76f010500401388e10b3914 --- /dev/null +++ b/chart/templates/gatekeeper/gitrepository.yaml @@ -0,0 +1,24 @@ +{{- if and (eq .Values.gatekeeper.sourceType "git") (not .Values.offline) (or .Values.gatekeeper.enabled .Values.clusterAuditor.enabled) }} +{{- $gitCredsDict := dict + "name" "gatekeeper" + "packageGitScope" .Values.gatekeeper.git + "rootScope" . + "releaseName" .Release.Name +}} +apiVersion: source.toolkit.fluxcd.io/v1 +kind: GitRepository +metadata: + name: gatekeeper + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: gatekeeper + app.kubernetes.io/component: "core" + {{- include "commonLabels" . | nindent 4}} +spec: + interval: {{ .Values.flux.interval }} + url: {{ .Values.gatekeeper.git.repo }} + ref: + {{- include "validRef" .Values.gatekeeper.git | nindent 4 }} + {{ include "gitIgnore" . }} + {{- include "gitCredsExtended" $gitCredsDict | nindent 2 }} +{{- end }} diff --git a/chart/templates/gatekeeper/helmrelease.yaml b/chart/templates/gatekeeper/helmrelease.yaml new file mode 100644 index 0000000000000000000000000000000000000000..e09a1f3ff828fe88e802aa0e609b0b7749377074 --- /dev/null +++ b/chart/templates/gatekeeper/helmrelease.yaml @@ -0,0 +1,59 @@ +{{- $fluxSettingsGatekeeper := merge .Values.gatekeeper.flux .Values.flux -}} +{{- if or .Values.gatekeeper.enabled .Values.clusterAuditor.enabled }} +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + name: gatekeeper + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: gatekeeper + app.kubernetes.io/component: "core" + {{- include "commonLabels" . | nindent 4}} + annotations: + checksum/bigbang-values: {{ include (print $.Template.BasePath "/gatekeeper/values.yaml") . | sha256sum }} +spec: + # Use a non-persistent client to allow for Gatekeeper CRD *magic* + persistentClient: false + targetNamespace: gatekeeper-system + chart: + spec: + {{- if eq .Values.gatekeeper.sourceType "git" }} + chart: {{ .Values.gatekeeper.git.path }} + sourceRef: + kind: GitRepository + name: gatekeeper + namespace: {{ .Release.Namespace }} + {{- else }} + chart: {{ .Values.gatekeeper.helmRepo.chartName }} + version: {{ .Values.gatekeeper.helmRepo.tag }} + sourceRef: + kind: HelmRepository + name: {{ .Values.gatekeeper.helmRepo.repoName }} + namespace: {{ .Release.Namespace }} + {{- $repoType := include "getRepoType" (dict "repoName" .Values.gatekeeper.helmRepo.repoName "allRepos" $.Values.helmRepositories) -}} + {{- if (and .Values.gatekeeper.helmRepo.cosignVerify (eq $repoType "oci")) }} # Needs to be an OCI repo + verify: + provider: cosign + secretRef: + name: {{ printf "%s-cosign-pub" .Values.gatekeeper.helmRepo.repoName }} + {{- end }} + {{- end }} + interval: 5m + + {{- toYaml $fluxSettingsGatekeeper | nindent 2 }} + + {{- if .Values.gatekeeper.postRenderers }} + postRenderers: + {{ toYaml .Values.gatekeeper.postRenderers | nindent 4 }} + {{- end }} + valuesFrom: + - name: {{ .Release.Name }}-gatekeeper-values + kind: Secret + valuesKey: "common" + - name: {{ .Release.Name }}-gatekeeper-values + kind: Secret + valuesKey: "defaults" + - name: {{ .Release.Name }}-gatekeeper-values + kind: Secret + valuesKey: "overlays" +{{- end }} diff --git a/chart/templates/gatekeeper/imagepullsecret.yaml b/chart/templates/gatekeeper/imagepullsecret.yaml new file mode 100644 index 0000000000000000000000000000000000000000..e85dccbe33285a5a2b059234c287f4ad46f140ff --- /dev/null +++ b/chart/templates/gatekeeper/imagepullsecret.yaml @@ -0,0 +1,16 @@ +{{- if or .Values.gatekeeper.enabled .Values.clusterAuditor.enabled }} +{{- if ( include "imagePullSecret" . ) }} +apiVersion: v1 +kind: Secret +metadata: + name: private-registry + namespace: gatekeeper-system + labels: + app.kubernetes.io/name: gatekeeper + app.kubernetes.io/component: "core" + {{- include "commonLabels" . | nindent 4}} +type: kubernetes.io/dockerconfigjson +data: + .dockerconfigjson: {{ template "imagePullSecret" . }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/chart/templates/gatekeeper/namespace.yaml b/chart/templates/gatekeeper/namespace.yaml new file mode 100644 index 0000000000000000000000000000000000000000..6f78f366d1d6b474d293624ec70ce37f9b0f1cb4 --- /dev/null +++ b/chart/templates/gatekeeper/namespace.yaml @@ -0,0 +1,13 @@ +{{- if or .Values.gatekeeper.enabled .Values.clusterAuditor.enabled }} +apiVersion: v1 +kind: Namespace +metadata: + labels: + admission.gatekeeper.sh/ignore: no-self-managing + gatekeeper.sh/system: "yes" + app.kubernetes.io/name: gatekeeper + app.kubernetes.io/component: "core" + {{- include "commonLabels" . | nindent 4}} + istio-injection: disabled + name: gatekeeper-system +{{- end }} diff --git a/chart/templates/gatekeeper/values.yaml b/chart/templates/gatekeeper/values.yaml new file mode 100644 index 0000000000000000000000000000000000000000..fedff2d2e5a913aa478c7490815869bbf28e5717 --- /dev/null +++ b/chart/templates/gatekeeper/values.yaml @@ -0,0 +1,245 @@ +{{- if or .Values.gatekeeper.enabled .Values.clusterAuditor.enabled }} +{{- include "values-secret" (dict "root" $ "package" (dict "values" (fromYaml (include "bigbang.overlays.gatekeeper" .))) "name" "gatekeeper" "defaults" (include "bigbang.defaults.gatekeeper" .)) }} +{{- end }} + +{{- define "bigbang.defaults.gatekeeper" -}} +image: + pullPolicy: {{ .Values.imagePullPolicy }} + pullSecrets: + - name: private-registry +postInstall: + labelNamespace: + enabled: false + image: + pullPolicy: {{ .Values.imagePullPolicy }} + pullSecrets: + - name: private-registry + probeWebhook: + image: + pullPolicy: {{ .Values.imagePullPolicy }} + pullSecrets: + - name: private-registry +postUpgrade: + cleanupCRD: + image: + pullPolicy: {{ .Values.imagePullPolicy }} + pullSecrets: + - name: private-registry +preUninstall: + deleteWebhookConfigurations: + image: + pullPolicy: {{ .Values.imagePullPolicy }} + pullSecrets: + - name: private-registry + +networkPolicies: + enabled: {{ .Values.networkPolicies.enabled }} + controlPlaneCidr: {{ .Values.networkPolicies.controlPlaneCidr }} +violations: # Try to keep this in alpha order to make it easier to find keys + + allowedDockerRegistries: + parameters: + repos: + - registry1.dso.mil + - registry.dso.mil + + {{- if or .Values.monitoring.enabled .Values.fluentbit.enabled .Values.twistlock.enabled .Values.promtail.enabled .Values.neuvector.enabled (and .Values.addons.velero.enabled .Values.addons.velero.values.deployNodeAgent)}} + allowedHostFilesystem: + parameters: + excludedResources: + {{- if .Values.monitoring.enabled }} + # Prometheus-node-exporter needs access to host to get node metrics + - monitoring/monitoring-monitoring-prometheus-node-exporter-.* + {{- end }} + {{- if .Values.fluentbit.enabled }} + # Fluentbit pods need access to host to get log files + - fluentbit/fluentbit-fluent-bit-.* + {{- end }} + {{- if .Values.neuvector.enabled }} + # Neuvector needs access to host to inspect network traffic + - neuvector/neuvector-enforcer-pod.* + - neuvector/neuvector-controller-pod.* + {{- end }} + {{- if .Values.twistlock.enabled }} + - twistlock/twistlock-defender-ds-.* + {{- end }} + {{- if .Values.promtail.enabled }} + # promtail requires hostpath volume mounts + # https://github.com/grafana/helm-charts/blob/main/charts/promtail/templates/daemonset.yaml#L120 + - promtail/promtail-promtail-.* + {{- end }} + {{- if and .Values.addons.velero.enabled .Values.addons.velero.values.deployNodeAgent }} + # NodeAgent requires hostpath volume mount access in order to facilitate backing up cluster PV/C resources + - velero/node-agent-.* + {{- end }} + {{- end }} + + {{- if .Values.twistlock.enabled }} + hostNetworking: + parameters: + excludedResources: + # Twistlock, by default, does its own network monitoring. hostNetworking is enabled by default for this purpose + # With hostNetworking enabled, Istio sidecar injection is disabled. If this function is disabled, Twistlock wil + # not be able to self monitor. If both Istio sidecar injection and TL monitoring are disabled, a security gap will + # be created for network monitoring in Twistlock, so it is important to make sure at least one is enabled. + - twistlock/twistlock-defender-ds-.* + {{- end }} + + {{- if or .Values.twistlock.enabled .Values.neuvector.enabled }} + noHostNamespace: + parameters: + excludedResources: + {{- if .Values.twistlock.enabled }} + - twistlock/twistlock-defender-ds-.* + {{- end }} + {{- if .Values.neuvector.enabled }} + # Neuvector needs access to host to inspect network traffic + - neuvector/neuvector-enforcer-pod.* + {{- end }} + {{- end }} + + imageDigest: + enabled: false + + namespacesHaveIstio: + enabled: {{ .Values.istio.enabled }} + parameters: + excludedResources: + # Kuberentes control plane does not use Istio + - kube-node-lease + - kube-public + - kube-system + # No pods in bigbang / default + - bigbang + - default + # Flux is installed prior to Istio + - flux-system + # Istio does not inject itself + - istio-operator + - istio-system + # Kyverno is installed prior to Istio + - kyverno + + {{- if or .Values.fluentbit.enabled .Values.neuvector.enabled }} + noPrivilegedContainers: + parameters: + excludedResources: + # Fluentbit needs privileged to read and store the buffer for tailing logs from the nodes + - fluentbit/fluent-bit + {{- if .Values.neuvector.enabled }} + # Neuvector needs privileged access for realtime scanning of files from the node / access to the container runtime + - neuvector/neuvector-enforcer-pod.* + - neuvector/neuvector-controller-pod.* + {{- end }} + {{- end }} + + podsHaveIstio: + enabled: {{ .Values.istio.enabled }} + match: + excludedNamespaces: + # Istio does not inject sidecars in itself + - istio-operator + - istio-system + + {{- if or .Values.monitoring.enabled .Values.twistlock.enabled }} + restrictedTaint: + parameters: + excludedResources: + {{- if .Values.monitoring.enabled }} + # Prometheus Node Exporter needs to be able to run on all nodes, regardless of taint, to gather node metrics + - monitoring/monitoring-monitoring-prometheus-node-exporter-.* + {{- end }} + {{- if .Values.twistlock.enabled }} + - twistlock/twistlock-defender-ds-.* + {{- end }} + {{- end }} + + {{- if or .Values.fluentbit.enabled .Values.twistlock.enabled .Values.promtail.enabled }} + selinuxPolicy: + parameters: + excludedResources: + {{- if .Values.fluentbit.enabled }} + # FluentBit needs selinux option type spc_t + - fluentbit/fluent-bit + {{- end }} + {{- if .Values.twistlock.enabled }} + # Twistlock Defenders need selinux option type spc_t + - twistlock/twistlock-defender + {{- end }} + {{- if .Values.promtail.enabled }} + # Promtail needs selinux option type spc_t + - promtail/promtail + {{- end }} + {{- end }} + + {{- if or .Values.fluentbit.enabled .Values.twistlock.enabled .Values.monitoring.enabled .Values.promtail.enabled .Values.neuvector.enabled (and .Values.addons.velero.enabled .Values.addons.velero.values.deployNodeAgent) }} + volumeTypes: + parameters: + excludedResources: + {{- if .Values.fluentbit.enabled }} + # fluent-bit container requires certain host level access to ship logs and for keep track of state + # https://docs.fluentbit.io/manual/pipeline/filters/kubernetes#workflow-of-tail-kubernetes-filter + - fluentbit/fluentbit-fluent-bit-.* + {{- end }} + {{- if .Values.twistlock.enabled }} + # Twistlock requires /dev/log for its syslog daemon. + # https://docs.paloaltonetworks.com/prisma/prisma-cloud/prisma-cloud-admin-compute/audit/logging.html# + - twistlock/twistlock-defender-ds-.* + {{- end }} + {{- if .Values.monitoring.enabled }} + # Prometheus node exported requires hostpath hardcoded in upstream chart on which monitoring pkg has a direct dependency + # https://github.com/prometheus-community/helm-charts/blob/main/charts/prometheus-node-exporter/templates/daemonset.yaml#L150 + - monitoring/monitoring-monitoring-prometheus-node-exporter-.* + {{- end }} + {{- if .Values.promtail.enabled }} + # Promtail requires hostpath volume types + # https://github.com/grafana/helm-charts/blob/main/charts/promtail/templates/daemonset.yaml#L120 + - promtail/promtail-promtail-.* + {{- end }} + {{- if .Values.neuvector.enabled }} + # Neuvector requires hostpath volume types + # Neuvector mounts the following hostPaths: + # `/var/neuvector`: (as writable) for Neuvector's buffering and persistent state + # `/var/run`: communication to docker daemon + # `/proc`: monitoring of proccesses for malicious activity + # `/sys/fs/cgroup`: important files the controller wants to monitor for malicious content + # https://github.com/neuvector/neuvector-helm/blob/master/charts/core/templates/enforcer-daemonset.yaml#L108 + - neuvector/neuvector-enforcer-pod.* + - neuvector/neuvector-controller-pod.* + {{- end }} + {{- if and .Values.addons.velero.enabled .Values.addons.velero.values.deployNodeAgent }} + # NodeAgent requires hostpath volume mounts in order to facilitate backing up cluster PV/C resources + - velero/node-agent-.* + {{- end }} + {{- end }} + +openshift: {{ .Values.openshift }} +{{- end -}} + + +{{- /* This function merges defaults in lists from above into overlays */ -}} +{{- /* The end user will not have to replicate exclusions/repos from above when providing an overlay */ -}} +{{- /* There is a hidden flag `skipOverlayMerge` that can be added to any constraint to ignore the defaults */ -}} +{{- define "bigbang.overlays.gatekeeper" }} + {{- $defaults := fromYaml (include "bigbang.defaults.gatekeeper" .) }} + {{- $overlays := dig "values" dict .Values.gatekeeper }} + {{- range $constraint, $default := $defaults.violations }} + {{- $overlay := (dig "violations" $constraint dict $overlays) }} + # Only continue if an overlay matches a default constriant and hidden "skipOverlayMerge" is not set + {{- if and $overlay (not $overlay.skipOverlayMerge) }} + # Add any default excludedNamespaces to overlay + {{- if and (dig "match" "excludedNamespaces" list $default) (dig "match" "excludedNamespaces" list $overlay) }} + {{ $_ := set $overlay.match "excludedNamespaces" (concat $default.match.excludedNamespaces $overlay.match.excludedNamespaces) }} + {{- end }} + # Add any default excludedResources to overlay + {{- if and (dig "parameters" "excludedResources" list $default) (dig "parameters" "excludedResources" list $overlay) }} + {{ $_ := set $overlay.parameters "excludedResources" (concat $default.parameters.excludedResources $overlay.parameters.excludedResources) }} + {{- end }} + # Special case to add registries for allowed registries to overlay + {{- if and (dig "parameters" "repos" list $default) (dig "parameters" "repos" list $overlay) }} + {{ $_ := set $overlay.parameters "repos" (concat $default.parameters.repos $overlay.parameters.repos) }} + {{- end }} + {{- end }} + {{- end }} +{{ toYaml $overlays }} +{{- end }} diff --git a/chart/templates/git-credentials.yaml b/chart/templates/git-credentials.yaml new file mode 100644 index 0000000000000000000000000000000000000000..54a08ade06c52faac83a49c36b48c3f518ebe6b5 --- /dev/null +++ b/chart/templates/git-credentials.yaml @@ -0,0 +1,39 @@ +{{- if .Values.git }} +{{- if not .Values.git.existingSecret }} +{{- with .Values.git -}} +{{- if coalesce .credentials.username .credentials.password .credentials.caFile .credentials.privateKey .credentials.publicKey .credentials.knownHosts -}} +{{- $http := coalesce .credentials.username .credentials.password .credentials.caFile "" }} +{{- $ssh := coalesce .credentials.privateKey .credentials.publicKey .credentials.knownHosts "" }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ $.Release.Name }}-git-credentials + namespace: {{ $.Release.Namespace }} +type: Opaque +data: + {{- if $http }} + {{- if .credentials.caFile }} + caFile: {{ .credentials.caFile | b64enc }} + {{- end }} + {{- if and .credentials.username (not .credentials.password ) }} + {{- fail "When using http git username, password must be specified" }} + {{- end }} + {{- if and .credentials.password (not .credentials.username ) }} + {{- fail "When using http git password, username must be specified" }} + {{- end }} + {{- if and .credentials.username .credentials.password }} + username: {{ .credentials.username | b64enc }} + password: {{ .credentials.password | b64enc }} + {{- end }} + {{- else }} + {{- if not (and (and .credentials.privateKey .credentials.publicKey) .credentials.knownHosts) }} + {{- fail "When using ssh git credentials, privateKey, publicKey, and knownHosts must all be specified" }} + {{- end }} + identity: {{ .credentials.privateKey | b64enc }} + identity.pub: {{ .credentials.publicKey | b64enc }} + known_hosts: {{ .credentials.knownHosts | b64enc }} + {{- end }} +{{- end }} +{{- end }} +{{- end }} +{{- end }} diff --git a/chart/templates/gitlab-runner/git-credentials.yaml b/chart/templates/gitlab-runner/git-credentials.yaml new file mode 100644 index 0000000000000000000000000000000000000000..c1544b6ac2921cdd50879feb946448be24b1d4d6 --- /dev/null +++ b/chart/templates/gitlab-runner/git-credentials.yaml @@ -0,0 +1,7 @@ +{{- $gitCredsSecretDict := dict + "name" "gitlabRunner" + "targetScope" .Values.addons.gitlabRunner + "releaseName" .Release.Name + "releaseNamespace" .Release.Namespace +}} +{{- include "gitCredsSecret" $gitCredsSecretDict | nindent 0 -}} diff --git a/chart/templates/gitlab-runner/gitrepository.yaml b/chart/templates/gitlab-runner/gitrepository.yaml new file mode 100644 index 0000000000000000000000000000000000000000..b4d82bc832a407a39b7a7e38e0bc4c5f9a96aebb --- /dev/null +++ b/chart/templates/gitlab-runner/gitrepository.yaml @@ -0,0 +1,20 @@ +{{- if and (eq .Values.addons.gitlabRunner.sourceType "git") (not .Values.offline) .Values.addons.gitlabRunner.enabled }} +{{- $gitCredsDict := dict + "name" "gitlabRunner" + "packageGitScope" .Values.addons.gitlabRunner.git + "rootScope" . + "releaseName" .Release.Name +}} +apiVersion: source.toolkit.fluxcd.io/v1 +kind: GitRepository +metadata: + name: gitlab-runner + namespace: {{ .Release.Namespace }} +spec: + interval: {{ .Values.flux.interval }} + url: {{ .Values.addons.gitlabRunner.git.repo }} + ref: + {{- include "validRef" .Values.addons.gitlabRunner.git | nindent 4 }} + {{ include "gitIgnore" . }} + {{- include "gitCredsExtended" $gitCredsDict | nindent 2 }} +{{- end }} \ No newline at end of file diff --git a/chart/templates/gitlab-runner/helmrelease.yaml b/chart/templates/gitlab-runner/helmrelease.yaml new file mode 100644 index 0000000000000000000000000000000000000000..352d068698ee0234f0324a9618cc207b49808690 --- /dev/null +++ b/chart/templates/gitlab-runner/helmrelease.yaml @@ -0,0 +1,78 @@ +{{- $fluxSettingsGitlabRunner := merge .Values.addons.gitlabRunner.flux .Values.flux -}} +{{- if .Values.addons.gitlabRunner.enabled }} +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + name: gitlab-runner + namespace: {{ .Release.Namespace }} + annotations: + checksum/bigbang-values: {{ include (print $.Template.BasePath "/gitlab-runner/values.yaml") . | sha256sum }} +spec: + targetNamespace: gitlab-runner + releaseName: gitlab-runner + chart: + spec: + {{- if eq .Values.addons.gitlabRunner.sourceType "git" }} + chart: {{ .Values.addons.gitlabRunner.git.path }} + sourceRef: + kind: GitRepository + name: gitlab-runner + namespace: {{ .Release.Namespace }} + {{- else }} + chart: {{ .Values.addons.gitlabRunner.helmRepo.chartName }} + version: {{ .Values.addons.gitlabRunner.helmRepo.tag }} + sourceRef: + kind: HelmRepository + name: {{ .Values.addons.gitlabRunner.helmRepo.repoName }} + namespace: {{ .Release.Namespace }} + {{- $repoType := include "getRepoType" (dict "repoName" .Values.addons.gitlabRunner.helmRepo.repoName "allRepos" $.Values.helmRepositories) -}} + {{- if (and .Values.addons.gitlabRunner.helmRepo.cosignVerify (eq $repoType "oci")) }} # Needs to be an OCI repo + verify: + provider: cosign + secretRef: + name: {{ printf "%s-cosign-pub" .Values.addons.gitlabRunner.helmRepo.repoName }} + {{- end }} + {{- end }} + interval: 5m + + {{- toYaml $fluxSettingsGitlabRunner | nindent 2 }} + + {{- if .Values.addons.gitlabRunner.postRenderers }} + postRenderers: + {{ toYaml .Values.addons.gitlabRunner.postRenderers | nindent 4 }} + {{- end }} + valuesFrom: + - name: {{ .Release.Name }}-gitlab-runner-values + kind: Secret + valuesKey: "common" + - name: {{ .Release.Name }}-gitlab-runner-values + kind: Secret + valuesKey: "defaults" + - name: {{ .Release.Name }}-gitlab-runner-values + kind: Secret + valuesKey: "overlays" + + {{- if or .Values.gatekeeper.enabled .Values.kyvernoPolicies.enabled .Values.monitoring.enabled .Values.addons.gitlab.enabled }} + dependsOn: + {{- if .Values.gatekeeper.enabled }} + - name: gatekeeper + namespace: {{ .Release.Namespace }} + {{- end }} + {{- if .Values.kyverno.enabled }} + - name: kyverno + namespace: {{ .Release.Namespace }} + {{- end }} + {{- if .Values.kyvernoPolicies.enabled }} + - name: kyverno-policies + namespace: {{ .Release.Namespace }} + {{- end }} + {{- if .Values.monitoring.enabled }} + - name: monitoring + namespace: {{ .Release.Namespace }} + {{- end }} + {{- if .Values.addons.gitlab.enabled }} + - name: gitlab + namespace: {{ .Release.Namespace }} + {{- end }} + {{- end }} +{{- end }} diff --git a/chart/templates/gitlab-runner/imagepullsecret.yaml b/chart/templates/gitlab-runner/imagepullsecret.yaml new file mode 100644 index 0000000000000000000000000000000000000000..0e957d2101183d03bd0ec172a85bc21e3ca95de1 --- /dev/null +++ b/chart/templates/gitlab-runner/imagepullsecret.yaml @@ -0,0 +1,16 @@ +{{- if .Values.addons.gitlabRunner.enabled }} +{{- if ( include "imagePullSecret" . ) }} +apiVersion: v1 +kind: Secret +metadata: + name: private-registry + namespace: gitlab-runner + labels: + app.kubernetes.io/name: gitlab-runner + app.kubernetes.io/component: "developer-tools" + {{- include "commonLabels" . | nindent 4}} +type: kubernetes.io/dockerconfigjson +data: + .dockerconfigjson: {{ template "imagePullSecret" . }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/chart/templates/gitlab-runner/namespace.yaml b/chart/templates/gitlab-runner/namespace.yaml new file mode 100644 index 0000000000000000000000000000000000000000..22e58320ddf25491d6868629a713009a5fc8f5e5 --- /dev/null +++ b/chart/templates/gitlab-runner/namespace.yaml @@ -0,0 +1,11 @@ +{{- if .Values.addons.gitlabRunner.enabled }} +apiVersion: v1 +kind: Namespace +metadata: + labels: + app.kubernetes.io/name: gitlab-runner + app.kubernetes.io/component: "developer-tools" + {{- include "commonLabels" . | nindent 4}} + istio-injection: {{ ternary "enabled" "disabled" (and .Values.istio.enabled (eq (dig "istio" "injection" "enabled" .Values.addons.gitlabRunner) "enabled")) }} + name: gitlab-runner +{{- end }} diff --git a/chart/templates/gitlab-runner/values.yaml b/chart/templates/gitlab-runner/values.yaml new file mode 100644 index 0000000000000000000000000000000000000000..5201a470d2c9609b2ddec921e34a7a89b1e41d81 --- /dev/null +++ b/chart/templates/gitlab-runner/values.yaml @@ -0,0 +1,49 @@ +{{- if .Values.addons.gitlabRunner.enabled }} +{{- include "values-secret" (dict "root" $ "package" .Values.addons.gitlabRunner "name" "gitlab-runner" "defaults" (include "bigbang.defaults.gitlab-runner" .)) }} +{{- end }} + +{{- define "bigbang.defaults.gitlab-runner" -}} + +imagePullPolicy: {{ .Values.imagePullPolicy }} + +imagePullSecrets: +- name: private-registry + +istio: + enabled: {{ .Values.istio.enabled }} + hardened: + enabled: {{ or + (dig "istio" "hardened" "enabled" false .Values.addons.gitlab.values) + (dig "istio" "hardened" "enabled" false .Values.addons.gitlabRunner.values) + (dig "hardened" "enabled" false .Values.istio.values) + }} + injection: {{ dig "istio" "injection" "enabled" .Values.addons.gitlabRunner }} + + +networkPolicies: + enabled: {{ .Values.networkPolicies.enabled }} + controlPlaneCidr: {{ .Values.networkPolicies.controlPlaneCidr }} + +# no longer necessary to directly pass through .Values.monitoring.enabled +# the package chart uses: .Capabilities.APIVersions.Has "monitoring.coreos.com/v1" to toggle monitoring +metrics: + enabled: {{ .Values.monitoring.enabled }} + serviceMonitor: + enabled: {{ .Values.monitoring.enabled }} + +# When istio injected, add an annotation with the istio version to the manager pods only +{{- if (and (eq (dig "istio" "injection" "enabled" .Values.addons.gitlab) "enabled") .Values.istio.enabled) }} +podAnnotations: + {{ include "istioAnnotation" . }} +{{- end }} + +monitoring: + enabled: {{ .Values.monitoring.enabled }} + +# autoRegister requires kyverno +{{- if and .Values.kyverno.enabled .Values.addons.gitlab.enabled }} +autoRegister: + enabled: {{ dig "autoRegister" "enabled" "true" .Values.addons.gitlabRunner }} +{{- end }} + +{{- end -}} diff --git a/chart/templates/gitlab/git-credentials.yaml b/chart/templates/gitlab/git-credentials.yaml new file mode 100644 index 0000000000000000000000000000000000000000..31d031d66271b07fc2cb2cfe0ff86e6921bc3c6f --- /dev/null +++ b/chart/templates/gitlab/git-credentials.yaml @@ -0,0 +1,7 @@ +{{- $gitCredsSecretDict := dict + "name" "gitlab" + "targetScope" .Values.addons.gitlab + "releaseName" .Release.Name + "releaseNamespace" .Release.Namespace +}} +{{- include "gitCredsSecret" $gitCredsSecretDict | nindent 0 -}} diff --git a/chart/templates/gitlab/gitrepository.yaml b/chart/templates/gitlab/gitrepository.yaml new file mode 100644 index 0000000000000000000000000000000000000000..d25655d98035f41e57d62b6ca5d489653a2ba883 --- /dev/null +++ b/chart/templates/gitlab/gitrepository.yaml @@ -0,0 +1,23 @@ +{{- if and (eq .Values.addons.gitlab.sourceType "git") (not .Values.offline) .Values.addons.gitlab.enabled }} +{{- $gitCredsDict := dict + "name" "gitlab" + "packageGitScope" .Values.addons.gitlab.git + "rootScope" . + "releaseName" .Release.Name +}} +apiVersion: source.toolkit.fluxcd.io/v1 +kind: GitRepository +metadata: + name: gitlab + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: gitlab + app.kubernetes.io/component: "developer-tools" + {{- include "commonLabels" . | nindent 4}} +spec: + interval: {{ .Values.flux.interval }} + url: {{ .Values.addons.gitlab.git.repo }} + ref: + {{- include "validRef" .Values.addons.gitlab.git | nindent 4 }} + {{- include "gitCredsExtended" $gitCredsDict | nindent 2 }} +{{- end }} diff --git a/chart/templates/gitlab/helmrelease.yaml b/chart/templates/gitlab/helmrelease.yaml new file mode 100644 index 0000000000000000000000000000000000000000..08f2769fa263a32886a0020c17301fb59c1253be --- /dev/null +++ b/chart/templates/gitlab/helmrelease.yaml @@ -0,0 +1,78 @@ +{{- $fluxSettingsGitlab := merge .Values.addons.gitlab.flux .Values.flux -}} +{{- if .Values.addons.gitlab.enabled }} +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + name: gitlab + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: gitlab + app.kubernetes.io/component: "developer-tools" + {{- include "commonLabels" . | nindent 4}} + annotations: + checksum/bigbang-values: {{ include (print $.Template.BasePath "/gitlab/values.yaml") . | sha256sum }} +spec: + releaseName: gitlab + targetNamespace: gitlab + chart: + spec: + {{- if eq .Values.addons.gitlab.sourceType "git" }} + chart: {{ .Values.addons.gitlab.git.path }} + sourceRef: + kind: GitRepository + name: gitlab + namespace: {{ .Release.Namespace }} + {{- else }} + chart: {{ .Values.addons.gitlab.helmRepo.chartName }} + version: {{ .Values.addons.gitlab.helmRepo.tag }} + sourceRef: + kind: HelmRepository + name: {{ .Values.addons.gitlab.helmRepo.repoName }} + namespace: {{ .Release.Namespace }} + {{- $repoType := include "getRepoType" (dict "repoName" .Values.addons.gitlab.helmRepo.repoName "allRepos" $.Values.helmRepositories) -}} + {{- if (and .Values.addons.gitlab.helmRepo.cosignVerify (eq $repoType "oci")) }} # Needs to be an OCI repo + verify: + provider: cosign + secretRef: + name: {{ printf "%s-cosign-pub" .Values.addons.gitlab.helmRepo.repoName }} + {{- end }} + {{- end }} + interval: 5m + + + {{- toYaml $fluxSettingsGitlab | nindent 2 }} + {{- if .Values.addons.gitlab.postRenderers }} + postRenderers: + {{ toYaml .Values.addons.gitlab.postRenderers | nindent 4 }} + {{- end }} + valuesFrom: + - name: {{ .Release.Name }}-gitlab-values + kind: Secret + valuesKey: "common" + - name: {{ .Release.Name }}-gitlab-values + kind: Secret + valuesKey: "defaults" + - name: {{ .Release.Name }}-gitlab-values + kind: Secret + valuesKey: "overlays" + + {{- if or .Values.gatekeeper.enabled .Values.istio.enabled .Values.kyvernoPolicies.enabled .Values.monitoring.enabled }} + dependsOn: + {{- if .Values.gatekeeper.enabled }} + - name: gatekeeper + namespace: {{ .Release.Namespace }} + {{- end }} + {{- if .Values.istio.enabled }} + - name: istio + namespace: {{ .Release.Namespace }} + {{- end }} + {{- if .Values.kyvernoPolicies.enabled }} + - name: kyverno-policies + namespace: {{ .Release.Namespace }} + {{- end }} + {{- if .Values.monitoring.enabled }} + - name: monitoring + namespace: {{ .Release.Namespace }} + {{- end }} + {{- end }} +{{- end }} diff --git a/chart/templates/gitlab/imagepullsecret.yaml b/chart/templates/gitlab/imagepullsecret.yaml new file mode 100644 index 0000000000000000000000000000000000000000..3cff8183fdbd7f0053a5204d6d3fbaf4df60009e --- /dev/null +++ b/chart/templates/gitlab/imagepullsecret.yaml @@ -0,0 +1,16 @@ +{{- if .Values.addons.gitlab.enabled }} +{{- if ( include "imagePullSecret" . ) }} +apiVersion: v1 +kind: Secret +metadata: + name: private-registry + namespace: gitlab + labels: + app.kubernetes.io/name: gitlab + app.kubernetes.io/component: "developer-tools" + {{- include "commonLabels" . | nindent 4}} +type: kubernetes.io/dockerconfigjson +data: + .dockerconfigjson: {{ template "imagePullSecret" . }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/chart/templates/gitlab/namespace.yaml b/chart/templates/gitlab/namespace.yaml new file mode 100644 index 0000000000000000000000000000000000000000..cb21bb382a0ba914b426ff61cac674d12fd5919d --- /dev/null +++ b/chart/templates/gitlab/namespace.yaml @@ -0,0 +1,11 @@ +{{- if or .Values.addons.gitlab.enabled }} +apiVersion: v1 +kind: Namespace +metadata: + labels: + app.kubernetes.io/name: gitlab + app.kubernetes.io/component: "developer-tools" + {{- include "commonLabels" . | nindent 4}} + istio-injection: {{ ternary "enabled" "disabled" (and .Values.istio.enabled (eq (dig "istio" "injection" "enabled" .Values.addons.gitlab) "enabled")) }} + name: gitlab +{{- end }} diff --git a/chart/templates/gitlab/secret-ca.yaml b/chart/templates/gitlab/secret-ca.yaml new file mode 100644 index 0000000000000000000000000000000000000000..5ba3a98a5f43be8431a7d3c34fe3275eacc6ae49 --- /dev/null +++ b/chart/templates/gitlab/secret-ca.yaml @@ -0,0 +1,10 @@ +{{- if and .Values.addons.gitlab.enabled .Values.addons.gitlab.sso.enabled (or .Values.sso.certificate_authority (dig "certificateAuthority" "cert" false .Values.sso))}} +apiVersion: v1 +kind: Secret +metadata: + name: {{ default (dig "certificateAuthority" "secretName" "" .Values.sso) .Values.sso.secretName }} + namespace: gitlab +type: Opaque +data: + ca.pem: {{ default (dig "certificateAuthority" "cert" "" .Values.sso) .Values.sso.certificate_authority | b64enc }} +{{- end }} diff --git a/chart/templates/gitlab/secret-database.yaml b/chart/templates/gitlab/secret-database.yaml new file mode 100644 index 0000000000000000000000000000000000000000..421cdd23fc7186a6e2725e0b43eea826ccfc934e --- /dev/null +++ b/chart/templates/gitlab/secret-database.yaml @@ -0,0 +1,12 @@ +{{- if .Values.addons.gitlab.enabled }} +{{- if .Values.addons.gitlab.database.host }} +apiVersion: v1 +kind: Secret +metadata: + name: gitlab-database + namespace: gitlab +type: kubernetes.io/opaque +stringData: + PGPASSWORD: {{ .Values.addons.gitlab.database.password | quote }} +{{- end }} +{{- end }} diff --git a/chart/templates/gitlab/secret-objectstore.yaml b/chart/templates/gitlab/secret-objectstore.yaml new file mode 100644 index 0000000000000000000000000000000000000000..0478bbc332e91bf8af3d841d75a15479fca452b7 --- /dev/null +++ b/chart/templates/gitlab/secret-objectstore.yaml @@ -0,0 +1,59 @@ +{{- if .Values.addons.gitlab.enabled }} +{{- if or .Values.addons.gitlab.objectStorage.region .Values.addons.gitlab.objectStorage.endpoint }} +{{- if and (ne .Values.addons.gitlab.objectStorage.iamProfile "") (ne .Values.addons.gitlab.objectStorage.accessKey "") }}{{- fail "Must choose to use an IAM profile OR an AWS accessKey/accessSecret at .Values.addons.gitlab.objectStorage" }}{{- end }} +apiVersion: v1 +kind: Secret +metadata: + name: gitlab-object-storage + namespace: gitlab +type: kubernetes.io/opaque +stringData: + rails: |- + provider: AWS + region: {{ .Values.addons.gitlab.objectStorage.region }} + {{- if ne .Values.addons.gitlab.objectStorage.iamProfile "" }} + use_iam_profile: true + {{- else if eq .Values.addons.gitlab.objectStorage.iamProfile "" }} + aws_access_key_id: {{ .Values.addons.gitlab.objectStorage.accessKey }} + aws_secret_access_key: {{ .Values.addons.gitlab.objectStorage.accessSecret }} + endpoint: "{{ .Values.addons.gitlab.objectStorage.endpoint }}" + {{- end }} + {{- if eq .Values.addons.gitlab.objectStorage.type "minio" }} + aws_signature_version: 4 + path_style: true + {{- end }} + registry: |- + s3: + {{- $global := .Values.addons.gitlab.values.global | default dict }} + {{- $registryConfig := $global.registry | default dict }} + {{- if .Values.addons.gitlab.objectStorage.bucketPrefix }} + bucket: {{ .Values.addons.gitlab.objectStorage.bucketPrefix }}-gitlab-registry + {{- else if hasKey $registryConfig "bucket" }} + bucket: {{ .Values.addons.gitlab.values.global.registry.bucket }} + {{- else }} + bucket: gitlab-registry + {{- end }} + {{- if eq .Values.addons.gitlab.objectStorage.iamProfile "" }} + accesskey: {{ .Values.addons.gitlab.objectStorage.accessKey }} + secretkey: {{ .Values.addons.gitlab.objectStorage.accessSecret }} + regionendpoint: "{{ .Values.addons.gitlab.objectStorage.endpoint }}" + {{- end }} + region: {{ .Values.addons.gitlab.objectStorage.region }} + {{- if eq .Values.addons.gitlab.objectStorage.type "s3" }} + v4auth: true + {{- end }} + {{- if eq .Values.addons.gitlab.objectStorage.type "minio" }} + aws_signature_version: 4 + path_style: true + {{- end }} + backups: |- + [default] + {{- if eq .Values.addons.gitlab.objectStorage.iamProfile "" }} + access_key = {{ .Values.addons.gitlab.objectStorage.accessKey }} + secret_key = {{ .Values.addons.gitlab.objectStorage.accessSecret }} + host_bucket = %(bucket)s.{{ regexReplaceAll "http(s*)://" .Values.addons.gitlab.objectStorage.endpoint "" }} + {{- end }} + bucket_location = {{ .Values.addons.gitlab.objectStorage.region }} + multipart_chunk_size_mb = 128 +{{- end }} +{{- end }} diff --git a/chart/templates/gitlab/secret-rails.yaml b/chart/templates/gitlab/secret-rails.yaml new file mode 100644 index 0000000000000000000000000000000000000000..ba40b15c0e475c06abb1da99d6e47f5c58b5ab1e --- /dev/null +++ b/chart/templates/gitlab/secret-rails.yaml @@ -0,0 +1,11 @@ +{{- if and (ne .Values.addons.gitlab.railsSecret "") .Values.addons.gitlab.enabled }} +apiVersion: v1 +kind: Secret +metadata: + name: gitlab-rails-secret-bb + namespace: gitlab +type: Opaque +data: + secrets.yml: | + {{ .Values.addons.gitlab.railsSecret | nindent 4 | b64enc }} +{{- end }} diff --git a/chart/templates/gitlab/secret-redis-bb.yaml b/chart/templates/gitlab/secret-redis-bb.yaml new file mode 100644 index 0000000000000000000000000000000000000000..5aaffcc5048fc906d084bdf14a1ba4b28470d784 --- /dev/null +++ b/chart/templates/gitlab/secret-redis-bb.yaml @@ -0,0 +1,10 @@ +{{- if and (ne .Values.addons.gitlab.redis.password "") .Values.addons.gitlab.enabled }} +apiVersion: v1 +kind: Secret +metadata: + name: gitlab-redis-secret-bb + namespace: gitlab +type: Opaque +data: + secret: {{ .Values.addons.gitlab.redis.password | b64enc }} +{{- end }} diff --git a/chart/templates/gitlab/secret-smtp.yaml b/chart/templates/gitlab/secret-smtp.yaml new file mode 100644 index 0000000000000000000000000000000000000000..26c10d59c098fc8a2def8a54aacedb3cbd23347a --- /dev/null +++ b/chart/templates/gitlab/secret-smtp.yaml @@ -0,0 +1,10 @@ +{{- if and .Values.addons.gitlab.smtp.password .Values.addons.gitlab.enabled }} +apiVersion: v1 +kind: Secret +metadata: + name: gitlab-smtp-password + namespace: gitlab +type: Opaque +data: + password: {{ .Values.addons.gitlab.smtp.password | b64enc }} +{{- end }} diff --git a/chart/templates/gitlab/secret-sso.yaml b/chart/templates/gitlab/secret-sso.yaml new file mode 100644 index 0000000000000000000000000000000000000000..0ff409094bb5c5d1efbfec263df61346407ef204 --- /dev/null +++ b/chart/templates/gitlab/secret-sso.yaml @@ -0,0 +1,64 @@ +{{- if .Values.addons.gitlab.enabled }} +{{- if .Values.addons.gitlab.sso.enabled }} +# hostname is deprecated and replaced with domain. But if hostname exists then use it. +{{- $domainName := default .Values.domain .Values.hostname }} +apiVersion: v1 +kind: Secret +metadata: + name: gitlab-sso-provider + namespace: gitlab +type: kubernetes.io/opaque +stringData: + gitlab-sso.json: |- + { + "name": "openid_connect", + "label": "{{ default .Values.sso.name .Values.addons.gitlab.sso.label }}", + "args": { + "name": "openid_connect", + "scope": [ + {{- $scopes := .Values.addons.gitlab.sso.scopes | default (list "Gitlab") | uniq }} + {{- range $index, $scopes }} + {{ $index | quote }}{{if ne $index (last $scopes)}},{{end}} + {{- end }} + ], + "response_type": "code", + {{- if .Values.addons.gitlab.sso.issuer_uri }} + "issuer": "{{ .Values.addons.gitlab.sso.issuer_uri }}", + {{- else }} + "issuer": "{{ include "sso.url" . }}", + {{- end }} + "client_auth_method": "query", + "discovery": true, + "uid_field": {{ default (dig "oidc" "claims" "username" "" .Values.sso) .Values.addons.gitlab.sso.uid_field | default "preferred_username" | quote }}, + "client_options": { + "identifier": "{{ .Values.addons.gitlab.sso.client_id }}", + "secret": "{{ .Values.addons.gitlab.sso.client_secret }}", + "redirect_uri": "https://{{ .Values.addons.gitlab.hostnames.gitlab }}.{{ $domainName }}/users/auth/openid_connect/callback", + {{- if .Values.addons.gitlab.sso.end_session_uri }} + "end_session_endpoint": "{{ .Values.addons.gitlab.sso.end_session_uri }}"{{if .Values.addons.gitlab.sso.groups }}{{printf "%s" ","}}{{end}} + {{- else }} + "end_session_endpoint": "{{ include "sso.oidc.endsession" . }}"{{if .Values.addons.gitlab.sso.groups }}{{printf "%s" ","}}{{end}} + {{- end }} + {{- if .Values.addons.gitlab.sso.groups }} + {{- $groups := .Values.addons.gitlab.sso.groups }} + "gitlab": { + "groups_attribute": {{- printf " %s%s" (.Values.addons.gitlab.sso.groups.groupsAttribute | default "groups" | quote) "," }} + {{- $numKeys := len (keys $groups) }} + {{- $counter := 1 }} + {{- $comma := "," }} + {{- range $key, $val := $groups }} + {{- if eq $counter $numKeys }}{{ $comma = "" }}{{end}} + {{- if eq $key "requiredGroups" }}{{- printf "%s%s" (trimSuffix "\n" (trimAll "{}" (dict "required_groups" $val | toPrettyJson))) $comma | indent 10 }}{{end}} + {{- if eq $key "externalGroups" }}{{- printf "%s%s" (trimSuffix "\n" (trimAll "{}" (dict "external_groups" $val | toPrettyJson))) $comma | indent 10 }}{{end}} + {{- if eq $key "auditorGroups" }}{{- printf "%s%s" (trimSuffix "\n" (trimAll "{}" (dict "auditor_groups" $val | toPrettyJson))) $comma | indent 10 }}{{end}} + {{- if eq $key "adminGroups" }}{{- printf "%s%s" (trimSuffix "\n" (trimAll "{}" (dict "admin_groups" $val | toPrettyJson))) $comma | indent 10 }}{{end}} + {{- $counter = add1 $counter -}} + {{- end -}} + } + {{- end }} + } + } + } + +{{- end }} +{{- end }} diff --git a/chart/templates/gitlab/values.yaml b/chart/templates/gitlab/values.yaml new file mode 100644 index 0000000000000000000000000000000000000000..843811ab6285ae1bcb22c57d53fb2ce96754265e --- /dev/null +++ b/chart/templates/gitlab/values.yaml @@ -0,0 +1,501 @@ +{{- if .Values.addons.gitlab.enabled }} +{{- include "values-secret" (dict "root" $ "package" (dict "values" (fromYaml (include "bigbang.overlays.gitlab" .))) "name" "gitlab" "defaults" (include "bigbang.defaults.gitlab" .)) }} +{{- end }} +{{- if and (ne .Values.addons.gitlab.objectStorage.iamProfile "") (ne .Values.addons.gitlab.objectStorage.accessKey "") }}{{- fail "Must choose to use an IAM profile OR an AWS accessKey/accessSecret at .Values.addons.gitlab.objectStorage" }}{{- end }} +{{- define "bigbang.defaults.gitlab" -}} +# hostname is deprecated and replaced with domain. But if hostname exists then use it. +{{- $domainName := default .Values.domain .Values.hostname }} +hostname: {{ $domainName }} +domain: {{ $domainName }} + +# Define variables to help with conditionals later +{{- $istioInjection := (and (eq (dig "istio" "injection" "enabled" .Values.addons.gitlab) "enabled") .Values.istio.enabled) }} +{{- $extObjStorageIsConfigured := (or .Values.addons.gitlab.objectStorage.region .Values.addons.gitlab.objectStorage.endpoint) }} +{{- $iamProfile := (and (ne .Values.addons.gitlab.objectStorage.iamProfile "") $extObjStorageIsConfigured) }} + +openshift: {{ .Values.openshift }} + +istio: + enabled: {{ .Values.istio.enabled }} + hardened: + enabled: {{ or + (dig "istio" "hardened" "enabled" false .Values.addons.gitlab.values) + (dig "istio" "hardened" "enabled" false .Values.addons.gitlabRunner.values) + (dig "hardened" "enabled" false .Values.istio.values) + }} + injection: {{ dig "istio" "injection" "enabled" .Values.addons.gitlab }} + gitlab: + gateways: + - istio-system/{{ default "public" .Values.addons.gitlab.ingress.gateway }} + registry: + gateways: + - istio-system/{{ default "public" .Values.addons.gitlab.ingress.gateway }} + +# Used for istio SSO serviceEntry +sso: + enabled: {{ .Values.addons.gitlab.sso.enabled }} + host: {{ include "sso.host" . }} + +monitoring: + enabled: {{ .Values.monitoring.enabled }} + +networkPolicies: + enabled: {{ .Values.networkPolicies.enabled }} + ingressLabels: + {{- $gateway := default "public" .Values.addons.gitlab.ingress.gateway }} + {{- $default := dict "app" (dig "gateways" $gateway "ingressGateway" nil .Values.istio) "istio" nil }} + {{- toYaml (dig "values" "gateways" $gateway "selector" $default .Values.istio) | nindent 4 }} + controlPlaneCidr: {{ .Values.networkPolicies.controlPlaneCidr }} + +{{- if and (or $istioInjection .Values.monitoring.enabled) (dig "redis" "install" true .Values.addons.gitlab.values) }} +redis: + {{- if .Values.monitoring.enabled }} + metrics: + serviceMonitor: + enabled: true + namespace: gitlab + {{- end }} + {{- if $istioInjection }} + master: + podAnnotations: + {{ include "istioAnnotation" . }} + slave: + podAnnotations: + {{ include "istioAnnotation" . }} + {{- end }} +{{- end }} + +{{- if or .Values.addons.gitlab.database.host $istioInjection }} +postgresql: + {{- if .Values.addons.gitlab.database.host }} + install: false + {{- end }} + {{- if $istioInjection }} + master: + podAnnotations: + {{ include "istioAnnotation" . }} + slave: + podAnnotations: + {{ include "istioAnnotation" . }} + {{- end }} +{{- end }} + +{{- if or $extObjStorageIsConfigured $istioInjection }} +registry: + {{- if $extObjStorageIsConfigured }} + storage: + secret: gitlab-object-storage + key: registry + {{- end }} + {{- if or $iamProfile $istioInjection }} + annotations: + {{- if $iamProfile }} + iam.amazonaws.com/role: {{ .Values.addons.gitlab.objectStorage.iamProfile }} + {{- end }} + {{- if $istioInjection }} + {{ include "istioAnnotation" . }} + {{- end }} + {{- end }} + {{- if and (eq (dig "istio" "mtls" "mode" "STRICT" .Values.addons.gitlab.values) "STRICT") $istioInjection }} + metrics: + serviceMonitor: + endpointConfig: + scheme: https + tlsConfig: + caFile: /etc/prom-certs/root-cert.pem + certFile: /etc/prom-certs/cert-chain.pem + keyFile: /etc/prom-certs/key.pem + insecureSkipVerify: true # Prometheus does not support Istio security naming, thus skip verifying target pod certificate + {{- end }} +{{- end }} + +gitlab: + {{- if or $extObjStorageIsConfigured $istioInjection }} + toolbox: + {{- if $extObjStorageIsConfigured }} + backups: + objectStorage: + config: + secret: gitlab-object-storage + key: backups + {{- end }} + {{- if or $iamProfile $istioInjection }} + annotations: + {{- if $iamProfile }} + iam.amazonaws.com/role: {{ .Values.addons.gitlab.objectStorage.iamProfile }} + {{- end }} + {{- if $istioInjection }} + {{ include "istioAnnotation" . }} + {{- end }} + {{- end }} + {{- end }} + gitlab-exporter: + enabled: {{ .Values.monitoring.enabled }} + {{- if $istioInjection }} + metrics: + annotations: + {{ include "istioAnnotation" . }} + {{- end }} + {{- if and (eq (dig "istio" "mtls" "mode" "STRICT" .Values.addons.gitlab.values) "STRICT") $istioInjection }} + metrics: + serviceMonitor: + endpointConfig: + scheme: https + tlsConfig: + caFile: /etc/prom-certs/root-cert.pem + certFile: /etc/prom-certs/cert-chain.pem + keyFile: /etc/prom-certs/key.pem + insecureSkipVerify: true # Prometheus does not support Istio security naming, thus skip verifying target pod certificate + {{- end }} + + {{- if or $iamProfile $istioInjection }} + webservice: + {{- if and (eq (dig "istio" "mtls" "mode" "STRICT" .Values.addons.gitlab.values) "STRICT") $istioInjection }} + metrics: + serviceMonitor: + endpointConfig: + scheme: https + tlsConfig: + caFile: /etc/prom-certs/root-cert.pem + certFile: /etc/prom-certs/cert-chain.pem + keyFile: /etc/prom-certs/key.pem + insecureSkipVerify: true # Prometheus does not support Istio security naming, thus skip verifying target pod certificate + workhorse: + metrics: + serviceMonitor: + endpointConfig: + scheme: https + tlsConfig: + caFile: /etc/prom-certs/root-cert.pem + certFile: /etc/prom-certs/cert-chain.pem + keyFile: /etc/prom-certs/key.pem + insecureSkipVerify: true # Prometheus does not support Istio security naming, thus skip verifying target pod certificate + {{- end }} + {{- if or $iamProfile $istioInjection }} + annotations: + {{- if $iamProfile }} + iam.amazonaws.com/role: {{ .Values.addons.gitlab.objectStorage.iamProfile }} + {{- end }} + {{- if $istioInjection }} + {{ include "istioAnnotation" . }} + {{- end }} + sidekiq: + annotations: + {{- if $iamProfile }} + iam.amazonaws.com/role: {{ .Values.addons.gitlab.objectStorage.iamProfile }} + {{- end }} + {{- if $istioInjection }} + {{ include "istioAnnotation" . }} + {{- end }} + {{- end }} + {{- end }} +{{- if $istioInjection }} + migrations: + annotations: + {{ include "istioAnnotation" . }} + gitaly: + annotations: + {{ include "istioAnnotation" . }} + {{- if and (eq (dig "istio" "mtls" "mode" "STRICT" .Values.addons.gitlab.values) "STRICT") $istioInjection }} + metrics: + serviceMonitor: + endpointConfig: + scheme: https + tlsConfig: + caFile: /etc/prom-certs/root-cert.pem + certFile: /etc/prom-certs/cert-chain.pem + keyFile: /etc/prom-certs/key.pem + insecureSkipVerify: true # Prometheus does not support Istio security naming, thus skip verifying target pod certificate + {{- end }} + gitlab-shell: + annotations: + {{ include "istioAnnotation" . }} + {{- if and (eq (dig "istio" "mtls" "mode" "STRICT" .Values.addons.gitlab.values) "STRICT") $istioInjection }} + metrics: + serviceMonitor: + endpointConfig: + scheme: https + tlsConfig: + caFile: /etc/prom-certs/root-cert.pem + certFile: /etc/prom-certs/cert-chain.pem + keyFile: /etc/prom-certs/key.pem + insecureSkipVerify: true # Prometheus does not support Istio security naming, thus skip verifying target pod certificate + {{- end }} + + praefect: + annotations: + {{ include "istioAnnotation" . }} + gitlab-grafana: + annotations: + {{ include "istioAnnotation" . }} +shared-secrets: + annotations: + {{ include "istioAnnotation" . }} +minio: + podAnnotations: + {{ include "istioAnnotation" . }} +{{- end }} + +global: + {{- if and .Values.addons.gitlab.sso.enabled (or (dig "certificateAuthority" "secretName" false .Values.sso) .Values.sso.secretName) }} + certificates: + customCAs: + {{- if and .Values.addons.gitlab.sso.enabled (or .Values.sso.certificate_authority (dig "certificateAuthority" "cert" false .Values.sso)) }} + - secret: {{ default (dig "certificateAuthority" "secretName" "" .Values.sso) .Values.sso.secretName }} + {{- end }} + - secret: ca-certs-australian-defence-organisation-cross-cert-chain + - secret: ca-certs-australian-defence-organisation-direct-trust-chain + - secret: ca-certs-boeing + - secret: ca-certs-carillon-federal-services-trust-chain-1 + - secret: ca-certs-carillon-federal-services-trust-chain-2 + - secret: ca-certs-department-of-state-trust-chain-1 + - secret: ca-certs-department-of-state-trust-chain-2 + - secret: ca-certs-digicert-federal-ssp-trust-chain-1 + - secret: ca-certs-digicert-federal-ssp-trust-chain-2 + - secret: ca-certs-digicert-nfi-trust-chain-1 + - secret: ca-certs-digicert-nfi-trust-chain-2 + - secret: ca-certs-entrust-federal-ssp-trust-chain-1 + - secret: ca-certs-entrust-federal-ssp-trust-chain-2 + - secret: ca-certs-entrust-managed-service-nfi + - secret: ca-certs-exostar-llc + - secret: ca-certs-identrust-nfi + - secret: ca-certs-lockheed-martin + - secret: ca-certs-netherlands-ministry-of-defence + - secret: ca-certs-northrop-grumman + - secret: ca-certs-raytheon-trust-chain-1 + - secret: ca-certs-raytheon-trust-chain-2 + - secret: ca-certs-us-treasury-ssp-trust-chain-1 + - secret: ca-certs-us-treasury-ssp-trust-chain-2 + - secret: ca-certs-verizon-cybertrust-federal-ssp + - secret: ca-certs-widepoint-federal-ssp-trust-chain-1 + - secret: ca-certs-widepoint-federal-ssp-trust-chain-2 + - secret: ca-certs-widepoint-nfi + - secret: ca-certs-dod-intermediate-and-issuing-ca-certs + - secret: ca-certs-dod-trust-anchors-self-signed + - secret: ca-certs-eca + {{end}} + + # added to help with Gitlab sub-chart configuration + image: + pullPolicy: {{ .Values.imagePullPolicy }} + + istio: + enabled: {{ .Values.istio.enabled }} + injection: {{ dig "istio" "injection" "enabled" .Values.addons.gitlab }} + + hosts: + domain: {{ $domainName }} + + gitlab: + name: {{ .Values.addons.gitlab.hostnames.gitlab }}.{{ $domainName }} + + registry: + name: {{ .Values.addons.gitlab.hostnames.registry }}.{{ $domainName }} + + {{- if or (ne .Values.addons.gitlab.objectStorage.iamProfile "") $extObjStorageIsConfigured }} + minio: + enabled: false + {{- end }} + + {{- if .Values.addons.gitlab.database.host }} + psql: + host: {{ .Values.addons.gitlab.database.host }} + port: {{ .Values.addons.gitlab.database.port }} + username: {{ .Values.addons.gitlab.database.username }} + database: {{ .Values.addons.gitlab.database.database }} + password: + secret: gitlab-database + key: PGPASSWORD + {{- end }} + + {{- if $extObjStorageIsConfigured }} + registry: + {{- if .Values.addons.gitlab.objectStorage.bucketPrefix }} + bucket: {{ .Values.addons.gitlab.objectStorage.bucketPrefix }}-gitlab-registry + {{- else }} + bucket: gitlab-registry + {{- end }} + {{- end }} + + {{- if or .Values.addons.gitlab.sso.enabled $extObjStorageIsConfigured }} + appConfig: + {{- end }} + + {{- if .Values.addons.gitlab.sso.enabled }} + omniauth: + enabled: true + {{- $global := .Values.addons.gitlab.values.global | default dict }} + {{- $appConfig := $global.appConfig | default dict }} + {{- $omniauth := $appConfig.omniauth | default dict }} + {{- if hasKey $omniauth "allowSingleSignOn" }} + allowSingleSignOn: {{ .Values.addons.gitlab.values.global.appConfig.omniauth.allowSingleSignOn }} + {{- else }} + allowSingleSignOn: ['openid_connect'] + {{- end }} + {{- if hasKey $omniauth "blockAutoCreatedUsers" }} + blockAutoCreatedUsers: {{ .Values.addons.gitlab.values.global.appConfig.omniauth.blockAutoCreatedUsers }} + {{- else }} + blockAutoCreatedUsers: false + {{- end }} + + providers: + - secret: gitlab-sso-provider + key: gitlab-sso.json + {{- end }} + + {{- if $extObjStorageIsConfigured }} + lfs: + {{- if .Values.addons.gitlab.objectStorage.bucketPrefix }} + bucket: {{ .Values.addons.gitlab.objectStorage.bucketPrefix }}-gitlab-lfs + {{- else }} + bucket: gitlab-lfs + {{- end }} + {{- if not (dig "global" "appConfig" "object_store" "enabled" false .Values.addons.gitlab.values)}} + connection: + secret: gitlab-object-storage + key: rails + {{- end }} + + artifacts: + {{- if .Values.addons.gitlab.objectStorage.bucketPrefix }} + bucket: {{ .Values.addons.gitlab.objectStorage.bucketPrefix }}-gitlab-artifacts + {{- else }} + bucket: gitlab-artifacts + {{- end }} + {{- if not (dig "global" "appConfig" "object_store" "enabled" false .Values.addons.gitlab.values)}} + connection: + secret: gitlab-object-storage + key: rails + {{- end }} + + uploads: + {{- if .Values.addons.gitlab.objectStorage.bucketPrefix }} + bucket: {{ .Values.addons.gitlab.objectStorage.bucketPrefix }}-gitlab-uploads + {{- else }} + bucket: gitlab-uploads + {{- end }} + {{- if not (dig "global" "appConfig" "object_store" "enabled" false .Values.addons.gitlab.values)}} + connection: + secret: gitlab-object-storage + key: rails + {{- end }} + + packages: + {{- if .Values.addons.gitlab.objectStorage.bucketPrefix }} + bucket: {{ .Values.addons.gitlab.objectStorage.bucketPrefix }}-gitlab-packages + {{- else }} + bucket: gitlab-packages + {{- end }} + {{- if not (dig "global" "appConfig" "object_store" "enabled" false .Values.addons.gitlab.values)}} + connection: + secret: gitlab-object-storage + key: rails + {{- end }} + + externalDiffs: + {{- if .Values.addons.gitlab.objectStorage.bucketPrefix }} + bucket: {{ .Values.addons.gitlab.objectStorage.bucketPrefix }}-gitlab-mr-diffs + {{- else }} + bucket: gitlab-mr-diffs + {{- end }} + {{- if not (dig "global" "appConfig" "object_store" "enabled" false .Values.addons.gitlab.values)}} + connection: + secret: gitlab-object-storage + key: rails + {{- end }} + + terraformState: + {{- if .Values.addons.gitlab.objectStorage.bucketPrefix }} + bucket: {{ .Values.addons.gitlab.objectStorage.bucketPrefix }}-gitlab-terraform-state + {{- else }} + bucket: gitlab-terraform-state + {{- end }} + {{- if not (dig "global" "appConfig" "object_store" "enabled" false .Values.addons.gitlab.values)}} + connection: + secret: gitlab-object-storage + key: rails + {{- end }} + + dependencyProxy: + {{- if .Values.addons.gitlab.objectStorage.bucketPrefix }} + bucket: {{ .Values.addons.gitlab.objectStorage.bucketPrefix }}-gitlab-dependency-proxy + {{- else }} + bucket: gitlab-dependency-proxy + {{- end }} + {{- if not (dig "global" "appConfig" "object_store" "enabled" false .Values.addons.gitlab.values)}} + connection: + secret: gitlab-object-storage + key: rails + {{- end }} + + pseudonymizer: + {{- if .Values.addons.gitlab.objectStorage.bucketPrefix }} + bucket: {{ .Values.addons.gitlab.objectStorage.bucketPrefix }}-gitlab-pseudo + {{- else }} + bucket: gitlab-pseudo + {{- end }} + connection: + secret: gitlab-object-storage + key: rails + + backups: + {{- if .Values.addons.gitlab.objectStorage.bucketPrefix }} + bucket: {{ .Values.addons.gitlab.objectStorage.bucketPrefix }}-gitlab-backup + {{- else }} + bucket: gitlab-backup + {{- end }} + {{- if .Values.addons.gitlab.objectStorage.bucketPrefix }} + tmpBucket: {{ .Values.addons.gitlab.objectStorage.bucketPrefix }}-gitlab-backup-tmp + {{- else }} + tmpBucket: gitlab-backup-tmp + {{- end }} + {{- end }} + + {{- if and (ne .Values.addons.gitlab.redis.password "") (or .Values.addons.gitlab.enabled .Values.addons.gitlabRunner.enabled) }} + redis: + password: + secret: "gitlab-redis-secret-bb" + {{- end }} + + {{- if .Values.addons.gitlab.smtp.password }} + smtp: + password: + secret: "gitlab-smtp-password" + {{- end }} + + {{- if .Values.addons.gitlab.railsSecret }} + railsSecrets: + secret: "gitlab-rails-secret-bb" + {{- end }} + + +{{- if ne .Values.addons.gitlab.objectStorage.iamProfile "" }} +use_iam_profile: true +{{- end }} +{{- end -}} + + + +{{- /* This function merges defaults in lists from above into overlays */ -}} +{{- /* The end user will not have to replicate exclusions/repos from above when providing an overlay */ -}} +{{- /* There is a hidden flag `skipOverlayMerge` that can be added to any certificates to ignore the defaults */ -}} +{{- define "bigbang.overlays.gitlab" }} + + {{- $defaults := fromYaml (include "bigbang.defaults.gitlab" .) }} + + {{- $overlays := dig "values" dict .Values.addons.gitlab }} + {{- range $certificates, $default := $defaults.global }} + {{- $overlay := (dig "global" $certificates dict $overlays) }} + # Only continue if an overlay matches a default constriant and hidden "skipOverlayMerge" is not set + {{- if and $overlay (not $overlay.skipOverlayMerge) }} + + # Add any default excludedNamespaces to overlay + {{- if and (dig "customCAs" list $default) (dig "customCAs" list $overlay) }} + + {{ $_ := set $overlay "customCAs" (concat $default.customCAs $overlay.customCAs) }} + + {{- end }} + {{- end }} + {{- end }} +{{ toYaml $overlays }} +{{- end }} diff --git a/chart/templates/grafana/flux-dashboards.yaml b/chart/templates/grafana/flux-dashboards.yaml new file mode 100644 index 0000000000000000000000000000000000000000..5499e4578120ebdb42e4830bf3f44f3fd7f62768 --- /dev/null +++ b/chart/templates/grafana/flux-dashboards.yaml @@ -0,0 +1,19 @@ +{{- if and .Values.monitoring.enabled .Values.grafana.enabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: flux-grafana-dashboards + namespace: monitoring + labels: + grafana_dashboard: "1" +data: + flux-cluster-dashboard.json: | + {{ .Files.Get "dashboards/flux/cluster.json" | nindent 4 }} + flux-control-plane-dashboard.json: | + {{ .Files.Get "dashboards/flux/control-plane.json" | nindent 4 }} + {{- if .Values.loki.enabled }} + flux-logs-dashboard.json: | + {{ .Files.Get "dashboards/flux/logs.json" | nindent 4 }} + {{- end }} +{{- end }} + diff --git a/chart/templates/grafana/flux/alert.yaml b/chart/templates/grafana/flux/alert.yaml new file mode 100644 index 0000000000000000000000000000000000000000..3e12776325cc27ce400749962c8cdb04aff2ef49 --- /dev/null +++ b/chart/templates/grafana/flux/alert.yaml @@ -0,0 +1,19 @@ +{{- if and .Values.monitoring.enabled (dig "grafana" "enabled" true .Values.monitoring.values) }} +apiVersion: notification.toolkit.fluxcd.io/v1beta3 +kind: Alert +metadata: + name: grafana + namespace: monitoring + labels: + app.kubernetes.io/name: monitoring + app.kubernetes.io/component: "core" + {{- include "commonLabels" . | nindent 4}} +spec: + providerRef: + name: grafana + eventSeverity: info + eventSources: + - kind: GitRepository + name: '*' + namespace: bigbang +{{- end }} diff --git a/chart/templates/grafana/flux/grafana-auth-secret.yaml b/chart/templates/grafana/flux/grafana-auth-secret.yaml new file mode 100644 index 0000000000000000000000000000000000000000..e1db7d94d5601f75ea3549922351dade18017e9e --- /dev/null +++ b/chart/templates/grafana/flux/grafana-auth-secret.yaml @@ -0,0 +1,24 @@ +{{- if and .Values.monitoring.enabled (dig "grafana" "enabled" true .Values.monitoring.values) }} +apiVersion: v1 +kind: Secret +metadata: + name: grafana-flux-auth + namespace: monitoring + labels: + app.kubernetes.io/name: monitoring + app.kubernetes.io/component: "core" + {{- include "commonLabels" . | nindent 4}} +type: kubernetes.io/opaque +stringData: +{{- if (dig "grafana" "admin" "existingSecret" "" .Values.monitoring.values) }} + {{- $passwordKey := (dig "grafana" "admin" "passwordKey" "admin-password" .Values.monitoring.values) }} + {{- $userKey := (dig "grafana" "admin" "userKey" "admin-user" .Values.monitoring.values) }} + {{- with lookup "v1" "Secret" "monitoring" .Values.monitoring.values.grafana.admin.existingSecret }} + username: {{ (get .data $userKey | b64dec) | default "admin" }} + password: {{ (get .data $passwordKey | b64dec) | default "prom-operator" }} + {{- end }} +{{- else }} + username: {{ dig "grafana" "adminUser" "admin" .Values.monitoring.values }} + password: {{ dig "grafana" "adminPassword" "prom-operator" .Values.monitoring.values }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/chart/templates/grafana/flux/ingress-flux.yaml b/chart/templates/grafana/flux/ingress-flux.yaml new file mode 100644 index 0000000000000000000000000000000000000000..34ce94ef8f1edd68a579d21a52b140d1958bbc51 --- /dev/null +++ b/chart/templates/grafana/flux/ingress-flux.yaml @@ -0,0 +1,26 @@ +{{- if and .Values.monitoring.enabled (dig "grafana" "enabled" true .Values.monitoring.values) }} +{{- if or (and .Values.networkPolicies.enabled (dig "networkPolicies" "enabled" true .Values.monitoring.values)) (and (not .Values.networkPolicies.enabled) (dig "networkPolicies" "enabled" false .Values.monitoring.values)) }} +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: allow-from-flux + namespace: monitoring +spec: + podSelector: + matchLabels: + app.kubernetes.io/name: grafana + policyTypes: + - Ingress + ingress: + - from: + - podSelector: + matchLabels: + app: notification-controller + namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: flux-system + ports: + - port: 3000 + protocol: TCP +{{- end }} +{{- end }} diff --git a/chart/templates/grafana/flux/provider.yaml b/chart/templates/grafana/flux/provider.yaml new file mode 100644 index 0000000000000000000000000000000000000000..43a8513ea70572fadc08e41cd328f5a4d6310115 --- /dev/null +++ b/chart/templates/grafana/flux/provider.yaml @@ -0,0 +1,16 @@ +{{- if and .Values.monitoring.enabled (dig "grafana" "enabled" true .Values.monitoring.values) }} +apiVersion: notification.toolkit.fluxcd.io/v1beta3 +kind: Provider +metadata: + name: grafana + namespace: monitoring + labels: + app.kubernetes.io/name: monitoring + app.kubernetes.io/component: "core" + {{- include "commonLabels" . | nindent 4}} +spec: + type: grafana + address: "http://monitoring-monitoring-grafana.monitoring/api/annotations" + secretRef: + name: grafana-flux-auth +{{- end }} diff --git a/chart/templates/grafana/git-credentials.yaml b/chart/templates/grafana/git-credentials.yaml new file mode 100644 index 0000000000000000000000000000000000000000..79b0f68385194cbba6268381e6cf9fd60cb08e96 --- /dev/null +++ b/chart/templates/grafana/git-credentials.yaml @@ -0,0 +1,7 @@ +{{- $gitCredsSecretDict := dict + "name" "grafana" + "targetScope" .Values.grafana + "releaseName" .Release.Name + "releaseNamespace" .Release.Namespace +}} +{{- include "gitCredsSecret" $gitCredsSecretDict | nindent 0 -}} diff --git a/chart/templates/grafana/gitrepository.yaml b/chart/templates/grafana/gitrepository.yaml new file mode 100644 index 0000000000000000000000000000000000000000..0b3851108cfe9de9e45dd0350061b76283e632dd --- /dev/null +++ b/chart/templates/grafana/gitrepository.yaml @@ -0,0 +1,25 @@ +{{- if and (eq .Values.grafana.sourceType "git") (not .Values.offline) .Values.grafana.enabled }} +{{- $gitCredsDict := dict + "name" "grafana" + "packageGitScope" .Values.grafana.git + "rootScope" . + "releaseName" .Release.Name +}} +apiVersion: source.toolkit.fluxcd.io/v1 +kind: GitRepository +metadata: + name: grafana + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: grafana + app.kubernetes.io/component: "core" + {{- include "commonLabels" . | nindent 4}} +spec: + interval: {{ .Values.flux.interval }} + url: {{ .Values.grafana.git.repo }} + ref: + {{- include "validRef" .Values.grafana.git | nindent 4 }} + {{ include "gitIgnore" . }} + {{- include "gitCredsExtended" $gitCredsDict | nindent 2 }} +{{- end }} + diff --git a/chart/templates/grafana/grafana-env-secret.yaml b/chart/templates/grafana/grafana-env-secret.yaml new file mode 100644 index 0000000000000000000000000000000000000000..d6a743fd838f843107450e5c95c4170d80b84799 --- /dev/null +++ b/chart/templates/grafana/grafana-env-secret.yaml @@ -0,0 +1,13 @@ +{{- if and .Values.grafana.enabled (ne .Values.addons.gitlab.redis.password "") }} +apiVersion: v1 +kind: Secret +metadata: + name: grafana-env-secret + namespace: monitoring + labels: + grafana_datasource: "1" +type: Opaque +stringData: + GITLAB_REDIS_PASSWORD: {{ .Values.addons.gitlab.redis.password }} +{{- end }} + diff --git a/chart/templates/grafana/helmrelease.yaml b/chart/templates/grafana/helmrelease.yaml new file mode 100644 index 0000000000000000000000000000000000000000..99d7af88035bf56827eb95219a9963810b83e4c3 --- /dev/null +++ b/chart/templates/grafana/helmrelease.yaml @@ -0,0 +1,81 @@ +{{- $fluxSettingsMonitoring := merge .Values.grafana.flux .Values.flux -}} +{{- if .Values.grafana.enabled }} +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + name: grafana + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: grafana + app.kubernetes.io/component: "core" + {{- include "commonLabels" . | nindent 4}} + annotations: + checksum/bigbang-values: {{ include (print $.Template.BasePath "/grafana/values.yaml") . | sha256sum }} +spec: + driftDetection: + mode: warn + targetNamespace: monitoring + chart: + spec: + {{- if eq .Values.grafana.sourceType "git" }} + chart: {{ .Values.grafana.git.path }} + sourceRef: + kind: GitRepository + name: grafana + namespace: {{ .Release.Namespace }} + {{- else }} + chart: {{ .Values.grafana.helmRepo.chartName }} + version: {{ .Values.grafana.helmRepo.tag }} + sourceRef: + kind: HelmRepository + name: {{ .Values.grafana.helmRepo.repoName }} + namespace: {{ .Release.Namespace }} + {{- $repoType := include "getRepoType" (dict "repoName" .Values.grafana.helmRepo.repoName "allRepos" $.Values.helmRepositories) -}} + {{- if (and .Values.grafana.helmRepo.cosignVerify (eq $repoType "oci")) }} # Needs to be an OCI repo + verify: + provider: cosign + secretRef: + name: {{ printf "%s-cosign-pub" .Values.grafana.helmRepo.repoName }} + {{- end }} + {{- end }} + interval: 5m + + {{- toYaml $fluxSettingsMonitoring | nindent 2 }} + + {{- if .Values.grafana.postRenderers }} + postRenderers: + {{ toYaml .Values.grafana.postRenderers | nindent 4 }} + {{- end }} + valuesFrom: + - name: {{ .Release.Name }}-grafana-values + kind: Secret + valuesKey: "common" + - name: {{ .Release.Name }}-grafana-values + kind: Secret + valuesKey: "defaults" + - name: {{ .Release.Name }}-grafana-values + kind: Secret + valuesKey: "overlays" + + # TODO: DRY this up + {{- if or .Values.gatekeeper.enabled .Values.istio.enabled .Values.kyvernoPolicies.enabled .Values.monitoring.enabled }} + dependsOn: + {{- if .Values.istio.enabled }} + - name: istio + namespace: {{ .Release.Namespace }} + {{- end }} + {{- if .Values.gatekeeper.enabled }} + - name: gatekeeper + namespace: {{ .Release.Namespace }} + {{- end }} + {{- if .Values.kyvernoPolicies.enabled }} + - name: kyverno-policies + namespace: {{ .Release.Namespace }} + {{- end }} + {{- if .Values.monitoring.enabled }} + - name: monitoring + namespace: {{ .Release.Namespace }} + {{- end }} + {{- end }} +{{- end }} + diff --git a/chart/templates/grafana/imagepullsecret.yaml b/chart/templates/grafana/imagepullsecret.yaml new file mode 100644 index 0000000000000000000000000000000000000000..b9a9f0c0adaa6efaa1fd26a7db2da3b7b93ef9c9 --- /dev/null +++ b/chart/templates/grafana/imagepullsecret.yaml @@ -0,0 +1,17 @@ +{{- if and (not .Values.monitoring.enabled) .Values.grafana.enabled }} +{{- if ( include "imagePullSecret" . ) }} +apiVersion: v1 +kind: Secret +metadata: + name: private-registry + namespace: monitoring + labels: + app.kubernetes.io/name: monitoring + app.kubernetes.io/component: "core" + {{- include "commonLabels" . | nindent 4}} +type: kubernetes.io/dockerconfigjson +data: + .dockerconfigjson: {{ template "imagePullSecret" . }} +{{- end }} +{{- end }} + diff --git a/chart/templates/grafana/namespace.yaml b/chart/templates/grafana/namespace.yaml new file mode 100644 index 0000000000000000000000000000000000000000..2b60cf2695b7f40a7884f5a45879f787663bca18 --- /dev/null +++ b/chart/templates/grafana/namespace.yaml @@ -0,0 +1,12 @@ +{{- if and (not .Values.monitoring.enabled) .Values.grafana.enabled }} +apiVersion: v1 +kind: Namespace +metadata: + name: monitoring + labels: + app.kubernetes.io/name: monitoring + app.kubernetes.io/component: "core" + {{- include "commonLabels" . | nindent 4}} + istio-injection: {{ ternary "enabled" "disabled" (and .Values.istio.enabled (eq (dig "istio" "injection" "enabled" .Values.grafana) "enabled")) }} +{{- end }} + diff --git a/chart/templates/grafana/secret-ca.yaml b/chart/templates/grafana/secret-ca.yaml new file mode 100644 index 0000000000000000000000000000000000000000..56261ada92250097785a26d60851c3455e8ad994 --- /dev/null +++ b/chart/templates/grafana/secret-ca.yaml @@ -0,0 +1,11 @@ +{{- if and (or (and .Values.grafana.enabled .Values.grafana.sso.enabled) (and .Values.monitoring.sso.enabled (dig "grafana" "client_id" false .Values.monitoring.sso))) (or .Values.sso.certificate_authority (dig "certificateAuthority" "cert" false .Values.sso)) }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ default (dig "certificateAuthority" "secretName" "" .Values.sso) .Values.sso.secretName }}-grafana + namespace: monitoring +type: Opaque +data: + ca.pem: {{ default (dig "certificateAuthority" "cert" "" .Values.sso) .Values.sso.certificate_authority | b64enc }} +{{- end }} + diff --git a/chart/templates/grafana/secret-sso.yaml b/chart/templates/grafana/secret-sso.yaml new file mode 100644 index 0000000000000000000000000000000000000000..2b5218c0dcc7a6befdce6b6a0c326430325509f1 --- /dev/null +++ b/chart/templates/grafana/secret-sso.yaml @@ -0,0 +1,20 @@ +{{- if or (and .Values.grafana.enabled .Values.grafana.sso.enabled .Values.grafana.sso.grafana.client_id) (and .Values.monitoring.sso.enabled (dig "grafana" "client_id" false .Values.monitoring.sso)) }} +apiVersion: v1 +kind: Secret +metadata: + name: grafana-sso + namespace: monitoring +type: kubernetes.io/opaque +stringData: + {{- if (dig "grafana" "client_id" false .Values.monitoring.sso) }} + client_id: {{ (dig "grafana" "client_id" false .Values.monitoring.sso) }} + {{- else if .Values.grafana.sso.grafana.client_id }} + client_id: {{ .Values.grafana.sso.grafana.client_id }} + {{- end }} + {{- if (dig "grafana" "client_secret" false .Values.monitoring.sso) }} + client_secret: {{ (dig "grafana" "client_secret" false .Values.monitoring.sso) }} + {{- else if .Values.grafana.sso.grafana.client_secret }} + client_secret: {{ .Values.grafana.sso.grafana.client_secret }} + {{- end }} +{{- end }} + diff --git a/chart/templates/grafana/values.yaml b/chart/templates/grafana/values.yaml new file mode 100644 index 0000000000000000000000000000000000000000..89bb3553a5c29b0fe458bc03e5a5be2edb8a2d36 --- /dev/null +++ b/chart/templates/grafana/values.yaml @@ -0,0 +1,335 @@ +{{- if .Values.grafana.enabled }} +{{- include "values-secret" (dict "root" $ "package" (dict "values" (fromYaml (include "bigbang.overlays.grafana" .))) "name" "grafana" "defaults" (include "bigbang.defaults.grafana" .)) }} +{{- end }} + +{{- define "bigbang.defaults.grafana" -}} +# hostname is deprecated and replaced with domain. But if hostname exists then use it. +{{- $domainName := default .Values.domain .Values.hostname }} +hostname: {{ $domainName }} +domain: {{ $domainName }} + +{{- $istioInjection := (and (eq (dig "istio" "injection" "enabled" .Values.grafana) "enabled") .Values.istio.enabled) }} +{{- $gitlabRedis := (and (ne .Values.addons.gitlab.redis.password "" ) (or .Values.addons.gitlab.enabled .Values.addons.gitlabRunner.enabled)) }} +{{- $authserviceRedisEnabled := (and (dig "values" "redis" "enabled" false .Values.addons.authservice) .Values.addons.authservice.enabled) }} +{{- $redisDatasource := (or $gitlabRedis .Values.addons.argocd.enabled $authserviceRedisEnabled) }} + +flux: + enabled: true + +networkPolicies: + enabled: {{ .Values.networkPolicies.enabled }} + controlPlaneCidr: {{ .Values.networkPolicies.controlPlaneCidr }} + ingressLabels: + {{- $gateway := default "public" .Values.grafana.ingress.gateway }} + {{- $default := dict "app" (dig "gateways" $gateway "ingressGateway" nil .Values.istio) "istio" nil }} + {{- toYaml (dig "values" "gateways" $gateway "selector" $default .Values.istio) | nindent 4 }} + +openshift: {{ .Values.openshift }} + +minioOperator: + enabled: {{ .Values.addons.minioOperator.enabled }} + +gitlabRunner: + enabled: {{ .Values.addons.gitlabRunner.enabled }} + +istio: + {{- $grafanaInjection := dig "istio" "injection" "enabled" .Values.grafana }} + enabled: {{ .Values.istio.enabled }} + hardened: + enabled: {{ or + (dig "istio" "hardened" "enabled" false .Values.monitoring.values) + (dig "istio" "hardened" "enabled" false .Values.addons.authservice.values) + (dig "hardened" "enabled" false .Values.istio.values) + (dig "istio" "hardened" "enabled" false .Values.grafana.values) + (dig "istio" "hardened" "enabled" false .Values.loki.values) + (dig "istio" "hardened" "enabled" false .Values.eckOperator.values) + (dig "istio" "hardened" "enabled" false .Values.elasticsearchKibana.values) + }} + grafana: + enabled: true + gateways: + - istio-system/{{ default "public" .Values.grafana.ingress.gateway }} + injection: {{ dig "istio" "injection" "enabled" .Values.grafana }} + +anchore: + enabled: {{ .Values.addons.anchore.enabled }} + +kiali: + enabled: {{ .Values.kiali.enabled }} + +loki: + enabled: {{ .Values.loki.enabled }} + +tempo: + enabled: {{ .Values.tempo.enabled }} + +{{- if or $gitlabRedis $authserviceRedisEnabled $redisDatasource }} +redis: + enabled: true +{{- end }} + +vault: + enabled: {{ .Values.addons.vault.enabled }} + tlsDisable: {{ dig "global" "tlsDisable" true .Values.addons.vault.values }} + +sso: + enabled: {{ or .Values.grafana.sso.enabled .Values.grafana.sso.enabled }} + +{{- if $gitlabRedis }} +envFromSecret: grafana-env-secret +{{- end }} + +{{- if .Values.tempo.enabled }} +env: + GF_FEATURE_TOGGLES_ENABLE: "traceqlEditor tempoSearch tempoServiceGraph" +{{- end }} + +image: + pullPolicy: {{ .Values.imagePullPolicy }} + pullSecrets: + - private-registry +sidecar: + imagePullPolicy: {{ .Values.imagePullPolicy }} + +{{- if $istioInjection }} +podAnnotations: + {{ include "istioAnnotation" . }} + {{- if $gitlabRedis }} + checksum/gitlabRedisPassword: {{ sha256sum .Values.addons.gitlab.redis.password }} + {{- end }} +{{- end }} + +{{- if or .Values.monitoring.enabled .Values.loki.enabled .Values.tempo.enabled $gitlabRedis $authserviceRedisEnabled .Values.addons.argocd.enabled }} +datasources: + datasourcesbb.yaml: + apiVersion: 1 + datasources: + {{- if .Values.monitoring.enabled }} + {{- if .Values.addons.thanos.enabled }} + - name: Thanos + type: prometheus + uid: prometheus + access: proxy + url: http://thanos-query.thanos.svc:9090 + editable: true + {{- else }} + - name: Prometheus + type: prometheus + uid: prometheus + access: proxy + url: http://monitoring-monitoring-kube-prometheus.monitoring.svc:9090 + editable: true + {{- end }} + {{- end }} + {{- if .Values.addons.argocd.enabled }} + - name: Argo Master + type: redis-datasource + access: proxy + url: argocd-argocd-redis-bb-master.argocd.svc.cluster.local:6379 + jsonData: + client: standalone + - name: Argo Headless + type: redis-datasource + access: proxy + url: argocd-argocd-redis-bb-headless.argocd.svc.cluster.local:6379 + jsonData: + client: standalone + - name: Argo Replicas + type: redis-datasource + access: proxy + url: argocd-argocd-redis-bb-replicas.argocd.svc.cluster.local:6379 + jsonData: + client: standalone + {{- end }} + {{- if $authserviceRedisEnabled }} + - name: AuthService Master + type: redis-datasource + access: proxy + url: authservice-authservice-redis-bb-master.authservice.svc.cluster.local:6379 + jsonData: + client: standalone + - name: AuthService Headless + type: redis-datasource + access: proxy + url: authservice-authservice-redis-bb-headless.authservice.svc.cluster.local:6379 + jsonData: + client: standalone + - name: AuthService Replicas + type: redis-datasource + access: proxy + url: authservice-authservice-redis-bb-replicas.authservice.svc.cluster.local:6379 + jsonData: + client: standalone + {{- end }} + {{- if $gitlabRedis }} + - name: GitLab + type: redis-datasource + access: proxy + url: gitlab-redis-master.gitlab.svc.cluster.local:6379 + jsonData: + client: standalone + secureJsonData: + password: $GITLAB_REDIS_PASSWORD + {{- end }} + {{- if .Values.loki.enabled }} + - name: Loki + type: loki + {{- if eq .Values.loki.strategy "monolith" }} + url: http://logging-loki.logging.svc.cluster.local:3100 + {{- else }} + url: http://logging-loki-gateway.logging.svc.cluster.local + {{- end }} + access: proxy + editable: true + {{- end }} + {{- if and .Values.loki.enabled .Values.tempo.enabled }} + jsonData: + derivedFields: + - datasourceName: Tempo + matcherRegex: "traceID=(\\w+)" + name: TraceID + url: "$${__value.raw}" + datasourceUid: tempo + {{- end }} + {{- if .Values.tempo.enabled }} + - name: Tempo + type: tempo + access: proxy + orgId: 1 + uid: tempo + url: http://tempo-tempo.tempo.svc:3100 + isDefault: false + editable: true + jsonData: + httpMethod: GET + serviceMap: + datasourceUid: 'prometheus' + {{- end }} + {{- if and .Values.loki.enabled .Values.tempo.enabled }} + jsonData: + httpMethod: GET + tracesToLogs: + datasourceUid: 'Loki' + tags: ['job', 'instance', 'pod', 'namespace'] + mappedTags: [{ key: 'service.name', value: 'service' }] + mapTagNamesEnabled: false + spanStartTimeShift: '1h' + spanEndTimeShift: '1h' + filterByTraceID: false + filterBySpanID: false + serviceMap: + datasourceUid: 'prometheus' + search: + hide: false + nodeGraph: + enabled: true + lokiSearch: + datasourceUid: 'Loki' + {{- end }} +{{- end }} + +grafana.ini: + {{- if .Values.istio.enabled }} + server: + root_url: https://grafana.{{ $domainName }}/ + {{- end }} + + auth.generic_oauth: + enabled: {{ or .Values.grafana.sso.enabled (and (dig "grafana" "client_id" false .Values.monitoring.sso) .Values.monitoring.sso.enabled) }} + {{- if .Values.sso.name }} + name: {{ .Values.sso.name }} + {{- end }} + {{- if or (and .Values.grafana.sso.enabled .Values.grafana.sso.grafana.client_id) (and (dig "grafana" "client_id" false .Values.monitoring.sso) .Values.monitoring.sso.enabled) }} + client_id: $__file{/etc/secrets/auth_generic_oauth/client_id} + {{- end }} + {{- if or (and .Values.grafana.sso.enabled .Values.grafana.sso.grafana.client_secret) (and (dig "grafana" "client_secret" false .Values.monitoring.sso) .Values.monitoring.sso.enabled) }} + client_secret: $__file{/etc/secrets/auth_generic_oauth/client_secret} + {{- end }} + {{- if (and (dig "grafana" "client_id" false .Values.monitoring.sso) .Values.monitoring.sso.enabled) }} + scopes: {{ ( dig "grafana" "scopes" false .Values.monitoring.sso) | default "openid profile email" }} + auth_url: {{ default (include "sso.oidc.auth" .) (dig "grafana" "auth_url" false .Values.monitoring.sso) }} + token_url: {{ default (include "sso.oidc.token" .) (dig "grafana" "token_url" false .Values.monitoring.sso) }} + api_url: {{ default (include "sso.oidc.userinfo" .) (dig "grafana" "api_url" false .Values.monitoring.sso) }} + allow_sign_up: {{ (dig "grafana" "allow_sign_up" false .Values.monitoring.sso) | default "True" }} + role_attribute_path: {{ (dig "grafana" "role_attribute_path" false .Values.monitoring.sso) | default "Viewer" }} + {{- else if .Values.grafana.sso.enabled }} + scopes: {{ .Values.grafana.sso.grafana.scopes | default "openid profile email" }} + auth_url: {{ default (include "sso.oidc.auth" .) .Values.grafana.sso.grafana.auth_url }} + token_url: {{ default (include "sso.oidc.token" .) .Values.grafana.sso.grafana.token_url }} + api_url: {{ default (include "sso.oidc.userinfo" .) .Values.grafana.sso.grafana.api_url }} + allow_sign_up: {{ .Values.grafana.sso.grafana.allow_sign_up | default "True" }} + role_attribute_path: {{ .Values.grafana.sso.grafana.role_attribute_path | default "Viewer" }} + {{- end }} + {{- with .Values.grafana.sso.grafana }} + {{- list "allowed_domains" .allowed_domains | include "bigbang.addValueIfSet" | indent 4 }} + {{- list "tls_client_ca" .tls_client_ca | include "bigbang.addValueIfSet" | indent 4 }} + {{- list "tls_skip_verify_insecure" .tls_skip_verify_insecure | include "bigbang.addValueIfSet" | indent 4 }} + {{- list "tls_client_cert" .tls_client_cert | include "bigbang.addValueIfSet" | indent 4 }} + {{- list "tls_client_key" .tls_client_key | include "bigbang.addValueIfSet" | indent 4 }} + {{- end }} + {{- with .Values.monitoring.sso.grafana }} + {{- list "allowed_domains" .allowed_domains | include "bigbang.addValueIfSet" | indent 4 }} + {{- list "tls_client_ca" .tls_client_ca | include "bigbang.addValueIfSet" | indent 4 }} + {{- list "tls_skip_verify_insecure" .tls_skip_verify_insecure | include "bigbang.addValueIfSet" | indent 4 }} + {{- list "tls_client_cert" .tls_client_cert | include "bigbang.addValueIfSet" | indent 4 }} + {{- list "tls_client_key" .tls_client_key | include "bigbang.addValueIfSet" | indent 4 }} + {{- end }} + +{{- if or (or .Values.grafana.sso.grafana.client_id (dig "grafana" "client_id" false .Values.monitoring.sso)) (or .Values.sso.certificate_authority (dig "certificateAuthority" "cert" false .Values.sso)) }} +extraSecretMounts: + {{- if or (and .Values.grafana.sso.enabled .Values.grafana.sso.grafana.client_id) (and (dig "grafana" "client_id" false .Values.monitoring.sso) .Values.monitoring.sso.enabled) }} + - name: auth-generic-oauth-secret + mountPath: /etc/secrets/auth_generic_oauth + secretName: grafana-sso + defaultMode: 0440 + readOnly: true + {{- end }} + {{- if and (or .Values.grafana.sso.enabled .Values.monitoring.sso.enabled) (or .Values.sso.certificate_authority (dig "certificateAuthority" "cert" false .Values.sso)) }} + - name: "oidc-ca-certificate" + mountPath: "/etc/oidc/ca.pem" + secretName: "tls-ca-sso-grafana" + readOnly: true + subPath: "ca.pem" + {{- end }} +{{- end }} +{{- if .Values.monitoring.enabled }} +serviceMonitor: + enabled: true +{{- end }} +{{- if $istioInjection }} + scheme: https + tlsConfig: + caFile: /etc/prom-certs/root-cert.pem + certFile: /etc/prom-certs/cert-chain.pem + keyFile: /etc/prom-certs/key.pem + insecureSkipVerify: true # Prometheus does not support Istio security naming, thus skip verifying target pod certificate +{{- end }} +{{- end }} + +{{- /* This function merges defaults in lists from above into overlays */ -}} +{{- /* The end user will not have to replicate `prometheus.prometheusSpec.additionalScrapeConfigs` or `grafana.extraSecretMounts` from above when providing an overlay */ -}} +{{- /* There is a hidden flag `skipOverlayMerge` that can be added to `prometheus.prometheusSpec` or `grafana` overlays to ignore the defaults */ -}} +{{- define "bigbang.overlays.grafana" }} + + {{- $defaults := fromYaml (include "bigbang.defaults.grafana" .) }} + + {{- $overlays := dig "values" dict .Values.grafana }} + {{- range $grafanaConfig, $default := $defaults }} + {{- $overlay := (dig $grafanaConfig dict $overlays) }} + # Only continue if an overlay matches a default constriant and hidden "skipOverlayMerge" is not set + {{- if and $overlay (kindIs "map" $overlay) (not $overlay.skipOverlayMerge) }} + + # Add any default extraSecretMounts to overlay + {{- if and (dig "extraSecretMounts" list $default) (dig "extraSecretMounts" list $overlay) }} + {{ $_ := set $overlay "extraSecretMounts" (concat $default.extraSecretMounts $overlay.extraSecretMounts) }} + {{- end }} + + # Add any default additionalDataSources to overlay + {{- if and (dig "additionalDataSources" list $default) (dig "additionalDataSources" list $overlay) }} + {{ $_ := set $overlay "additionalDataSources" (concat $default.additionalDataSources $overlay.additionalDataSources) }} + {{- end }} + {{- end }} + {{- end }} +{{ toYaml $overlays }} +{{- end }} + diff --git a/chart/templates/haproxy/git-credentials.yaml b/chart/templates/haproxy/git-credentials.yaml new file mode 100644 index 0000000000000000000000000000000000000000..68862d042d22b960014ceee43656bc08387f9142 --- /dev/null +++ b/chart/templates/haproxy/git-credentials.yaml @@ -0,0 +1,7 @@ +{{- $gitCredsSecretDict := dict + "name" "haproxy" + "targetScope" .Values.addons.haproxy + "releaseName" .Release.Name + "releaseNamespace" .Release.Namespace +}} +{{- include "gitCredsSecret" $gitCredsSecretDict | nindent 0 -}} diff --git a/chart/templates/haproxy/gitrepository.yaml b/chart/templates/haproxy/gitrepository.yaml new file mode 100644 index 0000000000000000000000000000000000000000..3d035098790c22807553f208bff104afe945f417 --- /dev/null +++ b/chart/templates/haproxy/gitrepository.yaml @@ -0,0 +1,25 @@ +{{- $monitoringInjection := dig "istio" "injection" "enabled" .Values.monitoring }} +{{- if and .Values.istio.enabled .Values.monitoring.enabled .Values.monitoring.sso.enabled (eq $monitoringInjection "disabled") }} +{{- $gitCredsDict := dict + "name" "haproxy" + "packageGitScope" .Values.addons.haproxy.git + "rootScope" . + "releaseName" .Release.Name +}} +apiVersion: source.toolkit.fluxcd.io/v1 +kind: GitRepository +metadata: + name: haproxy + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: haproxy + app.kubernetes.io/component: "developer-tools" + {{- include "commonLabels" . | nindent 4}} +spec: + interval: {{ .Values.flux.interval }} + url: {{ .Values.addons.haproxy.git.repo }} + ref: + {{- include "validRef" .Values.addons.haproxy.git | nindent 4 }} + {{ include "gitIgnore" . }} + {{- include "gitCredsExtended" $gitCredsDict | nindent 2 }} +{{- end }} diff --git a/chart/templates/haproxy/helmrelease.yaml b/chart/templates/haproxy/helmrelease.yaml new file mode 100644 index 0000000000000000000000000000000000000000..9d3b7777249cfe1f49d1558dbaee7a2c71f80500 --- /dev/null +++ b/chart/templates/haproxy/helmrelease.yaml @@ -0,0 +1,68 @@ +{{- $fluxSettingsHaProxy := merge .Values.addons.haproxy.flux .Values.flux -}} +{{- $monitoringInjection := dig "istio" "injection" "enabled" .Values.monitoring }} +{{- if and .Values.istio.enabled .Values.monitoring.enabled .Values.monitoring.sso.enabled (eq $monitoringInjection "disabled") }} +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + name: haproxy-sso + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: haproxy + app.kubernetes.io/component: "developer-tools" + {{- include "commonLabels" . | nindent 4}} + annotations: + checksum/bigbang-values: {{ include (print $.Template.BasePath "/haproxy/values.yaml") . | sha256sum }} +spec: + targetNamespace: authservice + chart: + spec: + {{- if eq .Values.addons.haproxy.sourceType "git" }} + chart: {{ .Values.addons.haproxy.git.path }} + sourceRef: + kind: GitRepository + name: haproxy + namespace: {{ .Release.Namespace }} + {{- else }} + chart: {{ .Values.addons.haproxy.helmRepo.chartName }} + version: {{ .Values.addons.haproxy.helmRepo.tag }} + sourceRef: + kind: HelmRepository + name: {{ .Values.addons.haproxy.helmRepo.repoName }} + namespace: {{ .Release.Namespace }} + {{- $repoType := include "getRepoType" (dict "repoName" .Values.addons.haproxy.helmRepo.repoName "allRepos" $.Values.helmRepositories) -}} + {{- if (and .Values.addons.haproxy.helmRepo.cosignVerify (eq $repoType "oci")) }} # Needs to be an OCI repo + verify: + provider: cosign + secretRef: + name: {{ printf "%s-cosign-pub" .Values.addons.haproxy.helmRepo.repoName }} + {{- end }} + {{- end }} + interval: 5m + {{- if .Values.addons.haproxy.postRenderers }} + postRenderers: + {{ toYaml .Values.addons.haproxy.postRenderers | nindent 4 }} + {{- end }} + valuesFrom: + - name: {{ .Release.Name }}-haproxy-sso-values + kind: Secret + valuesKey: "common" + - name: {{ .Release.Name }}-haproxy-sso-values + kind: Secret + valuesKey: "defaults" + - name: {{ .Release.Name }}-haproxy-sso-values + kind: Secret + valuesKey: "overlays" + + {{- toYaml $fluxSettingsHaProxy | nindent 2 }} + + dependsOn: + {{- if .Values.istio.enabled }} + - name: istio + namespace: {{ .Release.Namespace }} + {{- end }} + {{- if .Values.monitoring.enabled }} + - name: monitoring + namespace: {{ .Release.Namespace }} + {{- end }} + +{{- end }} diff --git a/chart/templates/haproxy/values.yaml b/chart/templates/haproxy/values.yaml new file mode 100644 index 0000000000000000000000000000000000000000..ab958a4b3bbb9162d0d5313b89d29b48d13b9de0 --- /dev/null +++ b/chart/templates/haproxy/values.yaml @@ -0,0 +1,117 @@ +{{- $monitoringInjection := dig "istio" "injection" "enabled" .Values.monitoring }} +{{- if and .Values.istio.enabled .Values.monitoring.enabled .Values.monitoring.sso.enabled (eq $monitoringInjection "disabled") }} +{{- include "values-secret" (dict "root" $ "package" .Values.addons.haproxy "name" "haproxy-sso" "defaults" (include "bigbang.defaults.haproxy-sso" .)) }} +{{- end }} + +{{- define "bigbang.defaults.haproxy-sso" -}} +# hostname is deprecated and replaced with domain. But if hostname exists then use it. +{{- $domainName := default .Values.domain .Values.hostname }} +{{- $haproxyAuthserviceKey := (dig "selector" "key" "protect" .Values.addons.authservice.values) }} +{{- $haproxyAuthserviceValue := (dig "selector" "value" "keycloak" .Values.addons.authservice.values) }} +podLabels: + {{ $haproxyAuthserviceKey }}: {{ $haproxyAuthserviceValue }} +config: | + global + maxconn 1024 + daemon + log stdout format raw local0 info + defaults + log global + mode http + option httplog + timeout client 60s + timeout connect 60s + timeout server 60s + frontend fe_main + # Create custom headers as temporary holding places for info + http-request set-header X-Scheme http if !{ ssl_fc } + http-request set-header X-Scheme https if { ssl_fc } + http-request set-header X-TraceId %[rand,hex,bytes(8,8),lower]%[rand,hex,bytes(8,8),lower]%[rand,hex,bytes(8,8),lower] + http-request set-header X-SegmentId0 %[rand,hex,bytes(8,8),lower]%[rand,hex,bytes(8,8),lower] + http-request set-header X-SegmentId1 %[rand,hex,bytes(8,8),lower]%[rand,hex,bytes(8,8),lower] + http-request set-header X-SegmentId2 %[rand,hex,bytes(8,8),lower]%[rand,hex,bytes(8,8),lower] + http-request set-header X-SegmentId3 %[rand,hex,bytes(8,8),lower]%[rand,hex,bytes(8,8),lower] + http-request set-header X-SegmentId4 %[rand,hex,bytes(8,8),lower]%[rand,hex,bytes(8,8),lower] + + # Declare capture slots for logging headers + declare capture request len 512 + http-request capture req.fhdr(User-Agent) id 0 + + declare capture request len 5 + http-request capture req.hdr(X-Scheme) id 1 + + declare capture request len 512 + http-request capture req.hdr(Host) id 2 + + declare capture request len 24 + http-request capture req.hdr(X-TraceId) id 3 + + declare capture request len 16 + http-request capture req.hdr(X-SegmentId0) id 4 + + declare capture request len 16 + http-request capture req.hdr(X-SegmentId1) id 5 + + declare capture request len 16 + http-request capture req.hdr(X-SegmentId2) id 6 + + declare capture request len 16 + http-request capture req.hdr(X-SegmentId3) id 7 + + declare capture request len 16 + http-request capture req.hdr(X-SegmentId4) id 8 + + declare capture response len 8 + http-response capture res.hdr(Content-Length) id 0 + + # Generate a unique Trace ID + unique-id-format %{+X}o\ 1-%[date,hex,bytes(8,8),lower]-%[capture.req.hdr(3)] + http-request set-header X-Amzn-Trace-Id Root=%[unique-id,lower] + bind :8080 + {{- $monitoringValues := .Values.monitoring.values | default dict }} + {{- $monitoringIstioValues := $monitoringValues.istio | default dict }} + {{- $prometheusHostValues := $monitoringIstioValues.prometheus | default dict}} + {{- $alertmanagerHostValues := $monitoringIstioValues.alertmanager | default dict}} + {{- if hasKey $alertmanagerHostValues "hosts" }} + acl host_alertmanager hdr(host) -i {{ range .Values.monitoring.values.istio.alertmanager.hosts }}{{ tpl . $}}{{ end }} + {{- else }} + acl host_alertmanager hdr(host) -i alertmanager.{{ $domainName }} + {{- end }} + {{- if hasKey $prometheusHostValues "hosts" }} + acl host_prometheus hdr(host) -i {{ range .Values.monitoring.values.istio.prometheus.hosts }}{{ tpl . $}}{{ end }} + {{- else }} + acl host_prometheus hdr(host) -i prometheus.{{ $domainName }} + {{- end }} + + option forwardfor + use_backend alertmanager_main if host_alertmanager + use_backend prometheus_main if host_prometheus + backend alertmanager_main + mode http + option forwardfor + http-request replace-header Host .* monitoring-monitoring-kube-alertmanager.monitoring.svc.cluster.local + server alertmanager monitoring-monitoring-kube-alertmanager.monitoring.svc.cluster.local:9093 + backend prometheus_main + mode http + option forwardfor + http-request replace-header Host .* monitoring-monitoring-kube-prometheus.monitoring.svc.cluster.local + server prometheus monitoring-monitoring-kube-prometheus.monitoring.svc.cluster.local:9090 +image: + repository: registry1.dso.mil/ironbank/opensource/haproxy/haproxy22 +containerPorts: + http: 8080 +istio: + enabled: {{ .Values.istio.enabled }} + hardened: + enabled: {{ or + (dig "istio" "hardened" "enabled" false .Values.addons.haproxy.values) + (dig "istio" "hardened" "enabled" false .Values.monitoring.values) + (dig "istio" "hardened" "enabled" false .Values.addons.authservice.values) + (dig "hardened" "enabled" false .Values.istio.values) + (dig "istio" "hardened" "enabled" false .Values.grafana.values) + (dig "istio" "hardened" "enabled" false .Values.loki.values) + (dig "istio" "hardened" "enabled" false .Values.eckOperator.values) + (dig "istio" "hardened" "enabled" false .Values.elasticsearchKibana.values) + }} +openshift: {{ .Values.openshift }} +{{- end -}} diff --git a/chart/templates/harbor/git-credentials.yaml b/chart/templates/harbor/git-credentials.yaml new file mode 100644 index 0000000000000000000000000000000000000000..02b4f08fa0d2630478a873fc47cd69fcab54b182 --- /dev/null +++ b/chart/templates/harbor/git-credentials.yaml @@ -0,0 +1,7 @@ +{{- $gitCredsSecretDict := dict + "name" "harbor" + "targetScope" .Values.addons.harbor + "releaseName" .Release.Name + "releaseNamespace" .Release.Namespace +}} +{{- include "gitCredsSecret" $gitCredsSecretDict | nindent 0 -}} diff --git a/chart/templates/harbor/gitrepository.yaml b/chart/templates/harbor/gitrepository.yaml new file mode 100644 index 0000000000000000000000000000000000000000..c950b3724121f559628d1c5bb2979fa135b609be --- /dev/null +++ b/chart/templates/harbor/gitrepository.yaml @@ -0,0 +1,21 @@ +{{- $pkg := "harbor" }} +{{- if and (eq (get .Values.addons $pkg).sourceType "git") (not .Values.offline) (get .Values.addons $pkg).enabled }} +{{- $gitCredsDict := dict + "name" $pkg + "packageGitScope" (get .Values.addons $pkg).git + "rootScope" . + "releaseName" .Release.Name +}} +apiVersion: source.toolkit.fluxcd.io/v1 +kind: GitRepository +metadata: + name: {{ $pkg }} + namespace: {{ .Release.Namespace }} +spec: + interval: {{ .Values.flux.interval }} + url: {{ (get .Values.addons $pkg).git.repo }} + ref: + {{- include "validRef" (get .Values.addons $pkg).git | nindent 4 }} + {{ include "gitIgnore" . }} + {{- include "gitCredsExtended" $gitCredsDict | nindent 2 }} +{{- end }} diff --git a/chart/templates/harbor/helmrelease.yaml b/chart/templates/harbor/helmrelease.yaml new file mode 100644 index 0000000000000000000000000000000000000000..c648462032aec73453e50e0c3be402e6becf7726 --- /dev/null +++ b/chart/templates/harbor/helmrelease.yaml @@ -0,0 +1,74 @@ +{{- $pkg := "harbor" }} +{{- $fluxSettingsHarbor := merge .Values.addons.harbor.flux .Values.flux -}} +{{- if (get .Values.addons $pkg).enabled }} +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + name: {{ $pkg }} + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ $pkg }} + {{- include "commonLabels" . | nindent 4}} + annotations: + checksum/bigbang-values: {{ include (print $.Template.BasePath "/harbor/values.yaml") . | sha256sum }} +spec: + releaseName: {{ $pkg }} + targetNamespace: {{ $pkg }} + chart: + spec: + {{- if eq (get .Values.addons $pkg).sourceType "git" }} + chart: {{ (get .Values.addons $pkg).git.path }} + sourceRef: + kind: GitRepository + name: harbor + namespace: {{ .Release.Namespace }} + {{- else }} + chart: {{ (get .Values.addons $pkg).helmRepo.chartName }} + version: {{ (get .Values.addons $pkg).helmRepo.tag }} + sourceRef: + kind: HelmRepository + name: {{ (get .Values.addons $pkg).helmRepo.repoName }} + namespace: {{ .Release.Namespace }} + {{- $repoType := include "getRepoType" (dict "repoName" (get .Values.addons $pkg).helmRepo.repoName "allRepos" $.Values.helmRepositories) -}} + {{- if (and (get .Values.addons $pkg).helmRepo.cosignVerify (eq $repoType "oci")) }} # Needs to be an OCI repo + verify: + provider: cosign + secretRef: + name: {{ printf "%s-cosign-pub" (get .Values.addons $pkg).helmRepo.repoName }} + {{- end }} + {{- end }} + interval: 5m + + {{- toYaml $fluxSettingsHarbor | nindent 2 }} + + {{- if (get .Values.addons $pkg).postRenderers }} + postRenderers: + {{ toYaml (get .Values.addons $pkg).postRenderers | nindent 4 }} + {{- end }} + valuesFrom: + - name: {{ .Release.Name }}-{{ $pkg }}-values + kind: Secret + valuesKey: "common" + - name: {{ .Release.Name }}-{{ $pkg }}-values + kind: Secret + valuesKey: "defaults" + - name: {{ .Release.Name }}-{{ $pkg }}-values + kind: Secret + valuesKey: "overlays" + + {{- if or .Values.istio.enabled .Values.kyvernoPolicies.enabled .Values.monitoring.enabled }} + dependsOn: + {{- if .Values.istio.enabled }} + - name: istio + namespace: {{ .Release.Namespace }} + {{- end }} + {{- if .Values.kyvernoPolicies.enabled }} + - name: kyverno-policies + namespace: {{ .Release.Namespace }} + {{- end }} + {{- if .Values.monitoring.enabled }} + - name: monitoring + namespace: {{ .Release.Namespace }} + {{- end }} + {{- end }} +{{- end }} diff --git a/chart/templates/harbor/imagepullsecret.yaml b/chart/templates/harbor/imagepullsecret.yaml new file mode 100644 index 0000000000000000000000000000000000000000..0cf06bf36652e7f67f8195b5d9e6c57bbce57daf --- /dev/null +++ b/chart/templates/harbor/imagepullsecret.yaml @@ -0,0 +1,14 @@ +{{- $pkg := "harbor" }} +{{- if and (get .Values.addons $pkg).enabled ( include "imagePullSecret" . ) }} +apiVersion: v1 +kind: Secret +metadata: + name: private-registry + namespace: {{ $pkg }} + labels: + app.kubernetes.io/name: {{ $pkg }} + {{- include "commonLabels" . | nindent 4}} +type: kubernetes.io/dockerconfigjson +data: + .dockerconfigjson: {{ template "imagePullSecret" . }} +{{- end }} diff --git a/chart/templates/harbor/namespace.yaml b/chart/templates/harbor/namespace.yaml new file mode 100644 index 0000000000000000000000000000000000000000..7094f5a49f028cdee479db868062a9dffb6f23f5 --- /dev/null +++ b/chart/templates/harbor/namespace.yaml @@ -0,0 +1,12 @@ +{{- $pkg := "harbor" }} +{{- if (get .Values.addons $pkg).enabled }} +apiVersion: v1 +kind: Namespace +metadata: + name: {{ $pkg }} + labels: + istio-injection: {{ ternary "enabled" "disabled" (and .Values.istio.enabled (eq (dig "istio" "injection" "enabled" (get .Values.addons $pkg)) "enabled")) }} + app.kubernetes.io/name: {{ $pkg }} + app.kubernetes.io/component: "core" + {{- include "commonLabels" . | nindent 4}} +{{- end }} \ No newline at end of file diff --git a/chart/templates/harbor/values.yaml b/chart/templates/harbor/values.yaml new file mode 100644 index 0000000000000000000000000000000000000000..f414717eae2d951ebcef5e9ccbaed543ef69f41b --- /dev/null +++ b/chart/templates/harbor/values.yaml @@ -0,0 +1,57 @@ +{{- $pkg := "harbor" }} + +{{- /* Create secret */ -}} +{{- if (get .Values.addons $pkg).enabled }} +{{- include "values-secret" (dict "root" $ "package" (get .Values.addons $pkg) "name" $pkg "defaults" (include (printf "bigbang.defaults.%s" $pkg) .)) }} +{{- end }} + +{{- define "bigbang.defaults.harbor" -}} + +imagePullSecrets: +- name: private-registry +imagePullPolicy: {{ .Values.imagePullPolicy }} + +externalURL: https://harbor.{{ .Values.domain }} + +domain: {{ .Values.domain }} + +istio: + enabled: {{ .Values.istio.enabled }} + hardened: + enabled: {{ or + (dig "istio" "hardened" "enabled" false .Values.addons.harbor.values) + (dig "hardened" "enabled" false .Values.istio.values) + }} + injection: {{ dig "istio" "injection" "enabled" .Values.addons.harbor }} + harbor: + gateways: + - istio-system/{{ default "public" .Values.addons.harbor.ingress.gateway }} + +networkPolicies: + enabled: {{ .Values.networkPolicies.enabled }} + controlPlaneCidr: {{ .Values.networkPolicies.controlPlaneCidr }} + ingressLabels: + {{- $gateway := default "public" .Values.addons.harbor.ingress.gateway }} + {{- $default := dict "app" (dig "gateways" $gateway "ingressGateway" nil .Values.istio) "istio" nil }} + {{- toYaml (dig "values" "gateways" $gateway "selector" $default .Values.istio) | nindent 4 }} + +monitoring: + enabled: {{ .Values.monitoring.enabled }} + +serviceMonitor: + enabled: {{ .Values.monitoring.enabled }} + # conditional passes only if all conditionals are true: + # - istio: enabled + # - mTLS: SCRICT + {{- if and .Values.istio.enabled (eq (dig "istio" "mtls" "mode" "STRICT" .Values.tempo.values) "STRICT") }} + scheme: https + tlsConfig: + caFile: /etc/prom-certs/root-cert.pem + certFile: /etc/prom-certs/cert-chain.pem + keyFile: /etc/prom-certs/key.pem + insecureSkipVerify: true # Prometheus does not support Istio security naming, thus skip verifying target pod certificate + {{- end }} + +openshift: {{ .Values.openshift }} + +{{- end }} diff --git a/chart/templates/helm-repository/cosignsecret.yaml b/chart/templates/helm-repository/cosignsecret.yaml new file mode 100644 index 0000000000000000000000000000000000000000..cae15bb5ad47d5aa500e652247bd15b60cbd1db0 --- /dev/null +++ b/chart/templates/helm-repository/cosignsecret.yaml @@ -0,0 +1,17 @@ +{{- range .Values.helmRepositories }} +{{- if .cosignPublicKeys }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ .name }}-cosign-pub + namespace: {{ $.Release.Namespace }} + labels: + {{- include "commonLabels" $ | nindent 4 }} +type: Opaque +data: + {{- range $key, $value := .cosignPublicKeys }} + {{ $key }}.pub: {{ $value | b64enc }} + {{- end }} +{{- end }} +--- +{{- end }} diff --git a/chart/templates/helm-repository/helmrepo.yaml b/chart/templates/helm-repository/helmrepo.yaml new file mode 100644 index 0000000000000000000000000000000000000000..5a8e9804ed00984a3ff724907b46f0864f558a32 --- /dev/null +++ b/chart/templates/helm-repository/helmrepo.yaml @@ -0,0 +1,17 @@ +{{- range .Values.helmRepositories }} +apiVersion: source.toolkit.fluxcd.io/v1 +kind: HelmRepository +metadata: + name: {{ .name }} + namespace: {{ $.Release.Namespace }} +spec: + provider: {{ .provider | default "generic" }} + interval: {{ $.Values.flux.interval }} + type: {{ .type | default "default" }} + url: {{ .repository }} + {{- if or .existingSecret (and .username .password) }} + secretRef: + name: {{ .existingSecret | default (printf "%s-secret" .name) }} + {{- end }} +--- +{{- end }} diff --git a/chart/templates/helm-repository/helmreposecret.yaml b/chart/templates/helm-repository/helmreposecret.yaml new file mode 100644 index 0000000000000000000000000000000000000000..49d5b626f8a9c91e00a5565421d08f2b743da78b --- /dev/null +++ b/chart/templates/helm-repository/helmreposecret.yaml @@ -0,0 +1,15 @@ +{{- range .Values.helmRepositories }} +{{- if and (not .existingSecret) .username .password }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ .name }}-secret + namespace: {{ $.Release.Namespace }} + labels: + {{- include "commonLabels" $ | nindent 4 }} +type: kubernetes.io/dockerconfigjson +data: + .dockerconfigjson: {{ printf "{\"auths\":{\"%s\":{\"username\":\"%s\",\"password\":\"%s\",\"email\":\"%s\",\"auth\":\"%s\"}}}" (trimPrefix "oci://" .repository) .username .password .email (printf "%s:%s" .username .password | b64enc) | b64enc }} +{{- end }} +--- +{{- end }} diff --git a/chart/templates/helm-repository/imagepullsecret.yaml b/chart/templates/helm-repository/imagepullsecret.yaml new file mode 100644 index 0000000000000000000000000000000000000000..06ac6933f062e71911542c334dc9f57fd7284286 --- /dev/null +++ b/chart/templates/helm-repository/imagepullsecret.yaml @@ -0,0 +1,12 @@ +{{- if and ( include "imagePullSecret" . ) .Values.helmRepositories }} +apiVersion: v1 +kind: Secret +metadata: + name: private-registry + namespace: {{ .Release.Namespace }} + labels: + {{- include "commonLabels" . | nindent 4}} +type: kubernetes.io/dockerconfigjson +data: + .dockerconfigjson: {{ template "imagePullSecret" . }} +{{- end }} diff --git a/chart/templates/holocron/gitlab-ingress.yaml b/chart/templates/holocron/gitlab-ingress.yaml new file mode 100644 index 0000000000000000000000000000000000000000..9656926323b342bb1a8a4a1495045a0c91afc06f --- /dev/null +++ b/chart/templates/holocron/gitlab-ingress.yaml @@ -0,0 +1,22 @@ +{{- $pkg := "holocron" }} +{{- if and .Values.networkPolicies.enabled .Values.addons.gitlab.enabled (get .Values.addons $pkg).enabled }} +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ $pkg }}-allow-ingress + namespace: gitlab +spec: + podSelector: + matchLabels: + app: webservice + policyTypes: + - Ingress + ingress: + - from: + - namespaceSelector: + matchLabels: + app.kubernetes.io/name: holocron + podSelector: + matchLabels: + role: collector +{{- end }} diff --git a/chart/templates/holocron/gitrepository.yaml b/chart/templates/holocron/gitrepository.yaml new file mode 100644 index 0000000000000000000000000000000000000000..616274f5c3665696fa04b7821ade82d43207330a --- /dev/null +++ b/chart/templates/holocron/gitrepository.yaml @@ -0,0 +1,15 @@ +{{- $pkg := "holocron" }} +{{- if and (eq (get .Values.addons $pkg).sourceType "git") (not .Values.offline) (get .Values.addons $pkg).enabled }} +apiVersion: source.toolkit.fluxcd.io/v1 +kind: GitRepository +metadata: + name: {{ $pkg }} + namespace: {{ .Release.Namespace }} +spec: + interval: {{ .Values.flux.interval }} + url: {{ (get .Values.addons $pkg).git.repo }} + ref: + {{- include "validRef" (get .Values.addons $pkg).git | nindent 4 }} + {{ include "gitIgnore" . }} + {{- include "gitCreds" . | nindent 2 }} +{{- end }} diff --git a/chart/templates/holocron/helmrelease.yaml b/chart/templates/holocron/helmrelease.yaml new file mode 100644 index 0000000000000000000000000000000000000000..1a40d653fab279ee7a6b6db08f4aac03fd98187f --- /dev/null +++ b/chart/templates/holocron/helmrelease.yaml @@ -0,0 +1,71 @@ +{{- $pkg := "holocron" }} +{{- $fluxSettingsHolocron := merge .Values.addons.holocron.flux .Values.flux -}} +{{- if (get .Values.addons $pkg).enabled }} +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + name: {{ $pkg }} + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ $pkg }} + {{- include "commonLabels" . | nindent 4}} + annotations: + checksum/bigbang-values: {{ include (print $.Template.BasePath "/holocron/values.yaml") . | sha256sum }} +spec: + releaseName: {{ $pkg }} + targetNamespace: {{ $pkg }} + chart: + spec: + {{- if eq (get .Values.addons $pkg).sourceType "git" }} + chart: {{ (get .Values.addons $pkg).git.path }} + sourceRef: + kind: GitRepository + name: holocron + namespace: {{ .Release.Namespace }} + {{- else }} + chart: {{ (get .Values.addons $pkg).helmRepo.chartName }} + version: {{ (get .Values.addons $pkg).helmRepo.tag }} + sourceRef: + kind: HelmRepository + name: {{ (get .Values.addons $pkg).helmRepo.repoName }} + namespace: {{ .Release.Namespace }} + {{- end }} + interval: 5m + + {{- toYaml $fluxSettingsHolocron | nindent 2 }} + + {{- if (get .Values.addons $pkg).postRenderers }} + postRenderers: + {{ toYaml (get .Values.addons $pkg).postRenderers | nindent 4 }} + {{- end }} + valuesFrom: + - name: {{ .Release.Name }}-{{ $pkg }}-values + kind: Secret + valuesKey: "common" + - name: {{ .Release.Name }}-{{ $pkg }}-values + kind: Secret + valuesKey: "defaults" + - name: {{ .Release.Name }}-{{ $pkg }}-values + kind: Secret + valuesKey: "overlays" + + {{- if or .Values.istio.enabled .Values.kyvernoPolicies.enabled .Values.monitoring.enabled .Values.addons.gitlab.enabled}} + dependsOn: + {{- if .Values.istio.enabled }} + - name: istio + namespace: {{ .Release.Namespace }} + {{- end }} + {{- if .Values.kyvernoPolicies.enabled }} + - name: kyverno-policies + namespace: {{ .Release.Namespace }} + {{- end }} + {{- if .Values.monitoring.enabled }} + - name: monitoring + namespace: {{ .Release.Namespace }} + {{- end }} + {{- if .Values.addons.gitlab.enabled }} + - name: gitlab + namespace: {{ .Release.Namespace }} + {{- end }} + {{- end }} +{{- end }} diff --git a/chart/templates/holocron/imagepullsecret.yaml b/chart/templates/holocron/imagepullsecret.yaml new file mode 100644 index 0000000000000000000000000000000000000000..8b4fae63f9f75ca30a4c6f6107717800126526f6 --- /dev/null +++ b/chart/templates/holocron/imagepullsecret.yaml @@ -0,0 +1,14 @@ +{{- $pkg := "holocron" }} +{{- if and (get .Values.addons $pkg).enabled ( include "imagePullSecret" . ) }} +apiVersion: v1 +kind: Secret +metadata: + name: private-registry + namespace: {{ $pkg }} + labels: + app.kubernetes.io/name: {{ $pkg }} + {{- include "commonLabels" . | nindent 4 }} +type: kubernetes.io/dockerconfigjson +data: + .dockerconfigjson: {{ template "imagePullSecret" . }} +{{- end }} diff --git a/chart/templates/holocron/jira-ingress.yaml b/chart/templates/holocron/jira-ingress.yaml new file mode 100644 index 0000000000000000000000000000000000000000..84e5b7052a40a1a816068335472d2d3c2a3d0fba --- /dev/null +++ b/chart/templates/holocron/jira-ingress.yaml @@ -0,0 +1,22 @@ +{{- $pkg := "holocron" }} +{{- if and .Values.networkPolicies.enabled (get .Values.addons $pkg).jira.enabled (get .Values.addons $pkg).enabled }} +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ $pkg }}-allow-ingress + namespace: jira +spec: + podSelector: + matchLabels: + app: jira + policyTypes: + - Ingress + ingress: + - from: + - namespaceSelector: + matchLabels: + app.kubernetes.io/name: holocron + podSelector: + matchLabels: + role: collector +{{- end }} \ No newline at end of file diff --git a/chart/templates/holocron/namespace.yaml b/chart/templates/holocron/namespace.yaml new file mode 100644 index 0000000000000000000000000000000000000000..ac4d210d930988062e6f9d8028033992b015f7a0 --- /dev/null +++ b/chart/templates/holocron/namespace.yaml @@ -0,0 +1,12 @@ +{{- $pkg := "holocron" }} +{{- if and (get .Values.addons $pkg).enabled (not (get .Values.addons $pkg).collectorAuth.existingSecret) }} +apiVersion: v1 +kind: Namespace +metadata: + name: {{ $pkg }} + labels: + istio-injection: {{ ternary "enabled" "disabled" (and .Values.istio.enabled (eq (dig "istio" "injection" "enabled" (get .Values.addons $pkg)) "enabled")) }} + app.kubernetes.io/name: {{ $pkg }} + app.kubernetes.io/component: "core" + {{- include "commonLabels" . | nindent 4}} +{{- end }} diff --git a/chart/templates/holocron/sonarqube-ingress.yaml b/chart/templates/holocron/sonarqube-ingress.yaml new file mode 100644 index 0000000000000000000000000000000000000000..5787f7fa721cbf80ef820589a9d3647f2574b826 --- /dev/null +++ b/chart/templates/holocron/sonarqube-ingress.yaml @@ -0,0 +1,22 @@ +{{- $pkg := "holocron" }} +{{- if and .Values.networkPolicies.enabled .Values.addons.sonarqube.enabled (get .Values.addons $pkg).enabled }} +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ $pkg }}-allow-ingress + namespace: sonarqube +spec: + podSelector: + matchLabels: + app: sonarqube + policyTypes: + - Ingress + ingress: + - from: + - namespaceSelector: + matchLabels: + app.kubernetes.io/name: holocron + podSelector: + matchLabels: + role: collector +{{- end }} diff --git a/chart/templates/holocron/values.yaml b/chart/templates/holocron/values.yaml new file mode 100644 index 0000000000000000000000000000000000000000..7c1075e04969203a4062c904dd57fa64c3bda27a --- /dev/null +++ b/chart/templates/holocron/values.yaml @@ -0,0 +1,207 @@ +{{- $pkg := "holocron" }} + +{{- /* Create secret */ -}} +{{- if (get .Values.addons $pkg).enabled }} +{{- include "values-secret" (dict "root" $ "package" (get .Values.addons $pkg) "name" $pkg "defaults" (include (printf "bigbang.defaults.%s" $pkg) .)) }} +{{- end }} + +{{- define "bigbang.defaults.holocron" -}} + +imagePullSecrets: +- name: private-registry +imagePullPolicy: {{ .Values.imagePullPolicy }} + +externalURL: https://holocron.{{ .Values.domain }} + +domain: {{ .Values.domain }} + +{{- $holocronAuthserviceKey := (dig "selector" "key" "protect" .Values.addons.authservice.values) }} +{{- $holocronAuthServiceValue := (dig "selector" "value" "keycloak" .Values.addons.authservice.values) }} + +{{- if .Values.addons.holocron.sso.enabled }} +frontend: + labels: + {{ $holocronAuthserviceKey }}: {{ $holocronAuthServiceValue }} +{{- end }} +api: +{{- if .Values.addons.holocron.sso.enabled }} + labels: + {{ $holocronAuthserviceKey }}: {{ $holocronAuthServiceValue }} +{{- end }} + env: + REQUEST_IP_HEADER: Host + SSO_ENABLED: {{ .Values.addons.holocron.sso.enabled }} + SSO_ADMIN_GROUP: {{ .Values.addons.holocron.sso.groups.admin }} + SSO_LEADERSHIP_GROUP: {{ .Values.addons.holocron.sso.groups.leadership }} + SSO_GROUPS_KEY: {{ .Values.sso.oidc.claims.groups }} + SSO_USERNAME_KEY: {{ .Values.sso.oidc.claims.username }} + +{{- if .Values.addons.gitlab.enabled }} +{{- $gitlabURL := "http://gitlab-webservice-default.gitlab.svc.cluster.local:8080" }} +collectorGitlabSCM: + replicas: 1 + image: + repository: registry1.dso.mil/ironbank/holocron/collector-gitlab-scm + tag: "3.1.1" + pullPolicy: IfNotPresent + instances: + - accessTokenSecretKey: gitlab-scm-0 + accessToken: {{ .Values.addons.holocron.collectorAuth.gitlabToken }} + env: + COLLECTOR_NAME: gitlab-scm-0 + COLLECTOR_INTERVAL_SECONDS: 600 + LOOK_BACK_DAYS: 365 + TARGET_URL: {{ $gitlabURL }} + COLLECTOR_TARGETS_INTRVL_SECS: 86400 + MAX_REQUESTS_PER_MINUTE: 500 +collectorGitlabBuild: + replicas: 1 + image: + repository: registry1.dso.mil/ironbank/holocron/collector-gitlab-build + tag: "3.0.4" + pullPolicy: IfNotPresent + instances: + - accessTokenSecretKey: gitlab-build-0 + accessToken: {{ .Values.addons.holocron.collectorAuth.gitlabToken }} + env: + COLLECTOR_NAME: gitlab-build-0 + COLLECTOR_INTERVAL_SECONDS: 600 + LOOK_BACK_DAYS: 365 + TARGET_URL: {{ $gitlabURL }} + COLLECTOR_TARGETS_INTRVL_SECS: 86400 + MAX_REQUESTS_PER_MINUTE: 500 +collectorGitlabWorkflow: + replicas: 1 + image: + repository: registry1.dso.mil/ironbank/holocron/collector-gitlab-workflow + tag: "3.0.4" + pullPolicy: IfNotPresent + instances: + - accessTokenSecretKey: gitlab-workflow-0 + accessToken: {{ .Values.addons.holocron.collectorAuth.gitlabToken }} + env: + COLLECTOR_NAME: gitlab-workflow-0 + COLLECTOR_INTERVAL_SECONDS: 600 + LOOK_BACK_DAYS: 365 + TARGET_URL: {{ $gitlabURL }} + COLLECTOR_TARGETS_INTRVL_SECS: 86400 + MAX_REQUESTS_PER_MINUTE: 500 + HIGHEST_PRIORITY_LABELS: priority::1,highest + HIGH_PRIORITY_LABELS: priority::2,high + MEDIUM_PRIORITY_LABELS: priority::3,medium + LOW_PRIORITY_LABELS: priority::4,low + LOWEST_PRIORITY_LABELS: priority::5,lowest + DEFAULT_TICKET_PRIORITY: lowest + FEATURE_LABELS: kind::feature,feature + DEFECT_LABELS: kind::bug,kind::defect,bug,defect + MAINTENANCE_LABELS: kind::maintenance,kind::docs,maintenance,docs,documentation + UNPLANNED_LABELS: kind::unplanned + DEFAULT_TICKET_TYPE: feature +{{- else }} +collectorGitlabSCM: + instances: [] +collectorGitlabBuild: + instances: [] +collectorGitlabWorkflow: + instances: [] +{{- end }} +{{- if .Values.addons.holocron.jira.enabled }} +collectorJiraWorkflow: + replicas: 1 + image: + repository: registry1.dso.mil/ironbank/holocron/collector-jira-workflow + tag: "3.0.4" + pullPolicy: IfNotPresent + instances: + - accessTokenSecretKey: jira-workflow-0 + accessToken: {{ .Values.addons.holocron.collectorAuth.jiraToken }} + env: + COLLECTOR_NAME: jira-workflow-0 + COLLECTOR_INTERVAL_SECONDS: 600 + LOOK_BACK_DAYS: 365 + TARGET_URL: {{ .Values.addons.holocron.jira.service }} + COLLECTOR_TARGETS_INTRVL_SECS: 86400 + MAX_REQUESTS_PER_MINUTE: 500 +{{- else }} +collectorJiraWorkflow: + instances: [] +{{- end }} +{{- if .Values.addons.sonarqube.enabled }} +collectorSonarQubeProjectAnalysis: + replicas: 1 + image: + repository: registry1.dso.mil/ironbank/holocron/collector-sonarqube-project-analysis + tag: "3.0.5" + pullPolicy: IfNotPresent + instances: + - accessTokenSecretKey: sonarqube-project-analysis-0 + accessToken: {{ .Values.addons.holocron.collectorAuth.sonarToken }} + env: + COLLECTOR_NAME: sonarqube-project-analysis-0 + COLLECTOR_INTERVAL_SECONDS: 600 + LOOK_BACK_DAYS: 365 + TARGET_URL: "http://sonarqube-sonarqube.gitlab.svc.cluster.local:9000" + COLLECTOR_TARGETS_INTRVL_SECS: 86400 + MAX_REQUESTS_PER_MINUTE: 500 +{{- else }} +collectorSonarQubeProjectAnalysis: + instances: [] +{{- end }} + +postgresql: + {{- if .Values.addons.holocron.database.host }} + enabled: false + service: + name: {{ .Values.addons.holocron.database.host }} + ports: + postgresql: {{ .Values.addons.holocron.database.port }} + {{- else }} + enabled: true + service: + ports: + postgresql: {{ .Values.addons.holocron.database.port }} + {{- end }} + + image: + repository: ironbank/opensource/postgres/postgresql + tag: "15.5" + auth: + secretKey: password + username: {{ .Values.addons.holocron.database.username }} + password: {{ .Values.addons.holocron.database.password }} + database: {{ .Values.addons.holocron.database.database }} + tls: + enabled: true + autoGenerated: true + +istio: + enabled: {{ .Values.istio.enabled }} + hardened: + enabled: {{ or + (dig "istio" "hardened" "enabled" false .Values.addons.holocron.values) + (dig "hardened" "enabled" false .Values.istio.values) + }} + injection: enabled + holocron: + gateways: + - istio-system/{{ default "public" .Values.addons.holocron.ingress.gateway }} + hosts: + - holocron.{{ .Values.domain }} + +networkPolicies: + enabled: {{ .Values.networkPolicies.enabled }} + egressHostLabels: + {{- if .Values.addons.gitlab.enabled }} + app.kubernetes.io/name: gitlab + {{- end }} + {{- if .Values.addons.holocron.jira.enabled }} + {{ toYaml .Values.addons.holocron.jira.service.label | nindent 4 }} + {{- end }} + {{- if .Values.addons.sonarqube.enabled }} + app: sonarqube + {{- end }} + +monitoring: + enabled: {{ .Values.monitoring.enabled }} + +{{- end }} diff --git a/chart/templates/istio-operator/git-credentials.yaml b/chart/templates/istio-operator/git-credentials.yaml new file mode 100644 index 0000000000000000000000000000000000000000..aa53d5788a3126c671559c5e4cd396f1c664599a --- /dev/null +++ b/chart/templates/istio-operator/git-credentials.yaml @@ -0,0 +1,7 @@ +{{- $gitCredsSecretDict := dict + "name" "istioOperator" + "targetScope" .Values.istioOperator + "releaseName" .Release.Name + "releaseNamespace" .Release.Namespace +}} +{{- include "gitCredsSecret" $gitCredsSecretDict | nindent 0 -}} diff --git a/chart/templates/istio-operator/gitrepository.yaml b/chart/templates/istio-operator/gitrepository.yaml new file mode 100644 index 0000000000000000000000000000000000000000..94713ad47d51f7f08a011487020bce12f66d3cd2 --- /dev/null +++ b/chart/templates/istio-operator/gitrepository.yaml @@ -0,0 +1,24 @@ +{{- if and (eq .Values.istioOperator.sourceType "git") (not .Values.offline) .Values.istioOperator.enabled }} +{{- $gitCredsDict := dict + "name" "istioOperator" + "packageGitScope" .Values.istioOperator.git + "rootScope" . + "releaseName" .Release.Name +}} +apiVersion: source.toolkit.fluxcd.io/v1 +kind: GitRepository +metadata: + name: istio-operator + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: istio-operator + app.kubernetes.io/component: "core" + {{- include "commonLabels" . | nindent 4}} +spec: + interval: {{ .Values.flux.interval }} + url: {{ .Values.istioOperator.git.repo }} + ref: + {{- include "validRef" .Values.istioOperator.git | nindent 4 }} + {{ include "gitIgnore" . }} + {{- include "gitCredsExtended" $gitCredsDict | nindent 2 }} +{{- end }} \ No newline at end of file diff --git a/chart/templates/istio-operator/helmrelease.yaml b/chart/templates/istio-operator/helmrelease.yaml new file mode 100644 index 0000000000000000000000000000000000000000..60df7802f5af6a6770d240c346b7d2ea14320c48 --- /dev/null +++ b/chart/templates/istio-operator/helmrelease.yaml @@ -0,0 +1,69 @@ +{{- $fluxSettingsIstioOperator := merge .Values.istioOperator.flux .Values.flux -}} +{{- if .Values.istioOperator.enabled }} +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + name: istio-operator + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: istio-operator + app.kubernetes.io/component: "core" + {{- include "commonLabels" . | nindent 4}} + annotations: + checksum/bigbang-values: {{ include (print $.Template.BasePath "/istio-operator/values.yaml") . | sha256sum }} +spec: + targetNamespace: istio-operator + chart: + spec: + {{- if eq .Values.istioOperator.sourceType "git" }} + chart: {{ .Values.istioOperator.git.path }} + sourceRef: + kind: GitRepository + name: istio-operator + namespace: {{ .Release.Namespace }} + {{- else }} + chart: {{ .Values.istioOperator.helmRepo.chartName }} + version: {{ .Values.istioOperator.helmRepo.tag }} + sourceRef: + kind: HelmRepository + name: {{ .Values.istioOperator.helmRepo.repoName }} + namespace: {{ .Release.Namespace }} + {{- $repoType := include "getRepoType" (dict "repoName" .Values.istioOperator.helmRepo.repoName "allRepos" $.Values.helmRepositories) -}} + {{- if (and .Values.istioOperator.helmRepo.cosignVerify (eq $repoType "oci")) }} # Needs to be an OCI repo + verify: + provider: cosign + secretRef: + name: {{ printf "%s-cosign-pub" .Values.istioOperator.helmRepo.repoName }} + {{- end }} + {{- end }} + interval: 5m + + {{- toYaml $fluxSettingsIstioOperator | nindent 2 }} + + {{- if .Values.istioOperator.postRenderers }} + postRenderers: + {{ toYaml .Values.istioOperator.postRenderers | nindent 4 }} + {{- end }} + valuesFrom: + - name: {{ .Release.Name }}-istio-operator-values + kind: Secret + valuesKey: "common" + - name: {{ .Release.Name }}-istio-operator-values + kind: Secret + valuesKey: "defaults" + - name: {{ .Release.Name }}-istio-operator-values + kind: Secret + valuesKey: "overlays" + + {{- if or .Values.gatekeeper.enabled .Values.kyvernoPolicies.enabled }} + dependsOn: + {{- if .Values.gatekeeper.enabled }} + - name: gatekeeper + namespace: {{ .Release.Namespace }} + {{- end }} + {{- if .Values.kyvernoPolicies.enabled }} + - name: kyverno-policies + namespace: {{ .Release.Namespace }} + {{- end }} + {{- end }} +{{- end }} diff --git a/chart/templates/istio-operator/imagepullsecret.yaml b/chart/templates/istio-operator/imagepullsecret.yaml new file mode 100644 index 0000000000000000000000000000000000000000..292750f8587d89c6516be22d22db752ce7dc5d39 --- /dev/null +++ b/chart/templates/istio-operator/imagepullsecret.yaml @@ -0,0 +1,14 @@ +{{- if and .Values.istioOperator.enabled ( include "imagePullSecret" . ) }} +apiVersion: v1 +kind: Secret +metadata: + name: private-registry + namespace: istio-operator + labels: + app.kubernetes.io/name: istio-operator + app.kubernetes.io/component: "core" + {{- include "commonLabels" . | nindent 4}} +type: kubernetes.io/dockerconfigjson +data: + .dockerconfigjson: {{ template "imagePullSecret" . }} +{{- end }} \ No newline at end of file diff --git a/chart/templates/istio-operator/namespace.yaml b/chart/templates/istio-operator/namespace.yaml new file mode 100644 index 0000000000000000000000000000000000000000..82730ad0f9cc80e8f09bbcf7983c25b605fdc692 --- /dev/null +++ b/chart/templates/istio-operator/namespace.yaml @@ -0,0 +1,12 @@ +{{- if .Values.istioOperator.enabled }} +apiVersion: v1 +kind: Namespace +metadata: + name: istio-operator + labels: + istio-operator-managed: Reconcile + istio-injection: disabled + app.kubernetes.io/name: istio-operator + app.kubernetes.io/component: "core" + {{- include "commonLabels" . | nindent 4}} +{{- end }} \ No newline at end of file diff --git a/chart/templates/istio-operator/values.yaml b/chart/templates/istio-operator/values.yaml new file mode 100644 index 0000000000000000000000000000000000000000..9b4b40492df7494077b347aecb61c8ebf661749e --- /dev/null +++ b/chart/templates/istio-operator/values.yaml @@ -0,0 +1,19 @@ +{{- if .Values.istioOperator.enabled }} +{{- include "values-secret" (dict "root" $ "package" .Values.istioOperator "name" "istio-operator" "defaults" (include "bigbang.defaults.istioOperator" .)) }} +{{- end }} + +{{- define "bigbang.defaults.istioOperator" -}} +createNamespace: false + +enterprise: {{ .Values.istio.enterprise }} +imagePullPolicy: {{ .Values.imagePullPolicy }} + +imagePullSecrets: + - private-registry + +networkPolicies: + enabled: {{ .Values.networkPolicies.enabled }} + controlPlaneCidr: {{ .Values.networkPolicies.controlPlaneCidr }} +monitoring: + enabled: {{ .Values.monitoring.enabled }} +{{- end -}} diff --git a/chart/templates/istio/git-credentials.yaml b/chart/templates/istio/git-credentials.yaml new file mode 100644 index 0000000000000000000000000000000000000000..c3fe2dd9a78414841a2ed7b98d14785877424c84 --- /dev/null +++ b/chart/templates/istio/git-credentials.yaml @@ -0,0 +1,7 @@ +{{- $gitCredsSecretDict := dict + "name" "istio" + "targetScope" .Values.istio + "releaseName" .Release.Name + "releaseNamespace" .Release.Namespace +}} +{{- include "gitCredsSecret" $gitCredsSecretDict | nindent 0 -}} diff --git a/chart/templates/istio/gitrepository.yaml b/chart/templates/istio/gitrepository.yaml new file mode 100644 index 0000000000000000000000000000000000000000..7f61c8c3cf240ac629459f301ca8e3e96e436ecd --- /dev/null +++ b/chart/templates/istio/gitrepository.yaml @@ -0,0 +1,24 @@ +{{- if and (eq .Values.istio.sourceType "git") (not .Values.offline) .Values.istio.enabled }} +{{- $gitCredsDict := dict + "name" "istio" + "packageGitScope" .Values.istio.git + "rootScope" . + "releaseName" .Release.Name +}} +apiVersion: source.toolkit.fluxcd.io/v1 +kind: GitRepository +metadata: + name: istio + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: istio-controlplane + app.kubernetes.io/component: "core" + {{- include "commonLabels" . | nindent 4}} +spec: + interval: {{ .Values.flux.interval }} + url: {{ .Values.istio.git.repo }} + ref: + {{- include "validRef" .Values.istio.git | nindent 4 }} + {{ include "gitIgnore" . }} + {{- include "gitCredsExtended" $gitCredsDict | nindent 2 }} +{{- end }} \ No newline at end of file diff --git a/chart/templates/istio/helmrelease.yaml b/chart/templates/istio/helmrelease.yaml new file mode 100644 index 0000000000000000000000000000000000000000..46c00bfbe9eacf5506253de448fabd6953aa9ce5 --- /dev/null +++ b/chart/templates/istio/helmrelease.yaml @@ -0,0 +1,69 @@ +{{- $fluxSettingsIstioCp := merge .Values.istio.flux .Values.flux -}} +{{- if .Values.istio.enabled }} +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + name: istio + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: istio-controlplane + app.kubernetes.io/component: "core" + {{- include "commonLabels" . | nindent 4}} + annotations: + checksum/bigbang-values: {{ include (print $.Template.BasePath "/istio/values.yaml") . | sha256sum }} +spec: + targetNamespace: istio-system + chart: + spec: + {{- if eq .Values.istio.sourceType "git" }} + chart: {{ .Values.istio.git.path }} + sourceRef: + kind: GitRepository + name: istio + namespace: {{ .Release.Namespace }} + {{- else }} + chart: {{ .Values.istio.helmRepo.chartName }} + version: {{ .Values.istio.helmRepo.tag }} + sourceRef: + kind: HelmRepository + name: {{ .Values.istio.helmRepo.repoName }} + namespace: {{ .Release.Namespace }} + {{- $repoType := include "getRepoType" (dict "repoName" .Values.istio.helmRepo.repoName "allRepos" $.Values.helmRepositories) -}} + {{- if (and .Values.istio.helmRepo.cosignVerify (eq $repoType "oci")) }} # Needs to be an OCI repo + verify: + provider: cosign + secretRef: + name: {{ printf "%s-cosign-pub" .Values.istio.helmRepo.repoName }} + {{- end }} + {{- end }} + interval: 5m + + {{- toYaml $fluxSettingsIstioCp | nindent 2 }} + + {{- if .Values.istio.postRenderers }} + postRenderers: + {{ toYaml .Values.istio.postRenderers | nindent 4 }} + {{- end }} + valuesFrom: + - name: {{ .Release.Name }}-istio-values + kind: Secret + valuesKey: "common" + - name: {{ .Release.Name }}-istio-values + kind: Secret + valuesKey: "defaults" + - name: {{ .Release.Name }}-istio-values + kind: Secret + valuesKey: "overlays" + + dependsOn: + - name: istio-operator + namespace: {{ .Release.Namespace }} + {{- if .Values.gatekeeper.enabled }} + - name: gatekeeper + namespace: {{ .Release.Namespace }} + {{- end }} + {{- if .Values.kyvernoPolicies.enabled }} + - name: kyverno-policies + namespace: {{ .Release.Namespace }} + {{- end }} +{{- end }} diff --git a/chart/templates/istio/imagepullsecret-kubesystem.yaml b/chart/templates/istio/imagepullsecret-kubesystem.yaml new file mode 100644 index 0000000000000000000000000000000000000000..20ba0d712d39ba92920b0d1f1dd537706c9ea4b8 --- /dev/null +++ b/chart/templates/istio/imagepullsecret-kubesystem.yaml @@ -0,0 +1,12 @@ +{{- if .Values.istio.enabled }} +{{- if and .Values.openshift ( include "imagePullSecret" . ) }} +apiVersion: v1 +kind: Secret +metadata: + name: private-registry + namespace: kube-system +type: kubernetes.io/dockerconfigjson +data: + .dockerconfigjson: {{ template "imagePullSecret" . }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/chart/templates/istio/imagepullsecret.yaml b/chart/templates/istio/imagepullsecret.yaml new file mode 100644 index 0000000000000000000000000000000000000000..350ef47e68a85a9a2112e763ef7ca06b5e4ef053 --- /dev/null +++ b/chart/templates/istio/imagepullsecret.yaml @@ -0,0 +1,16 @@ +{{- if .Values.istio.enabled }} +{{- if ( include "imagePullSecret" . ) }} +apiVersion: v1 +kind: Secret +metadata: + name: private-registry + namespace: istio-system + labels: + app.kubernetes.io/name: istio-controlplane + app.kubernetes.io/component: "core" + {{- include "commonLabels" . | nindent 4}} +type: kubernetes.io/dockerconfigjson +data: + .dockerconfigjson: {{ template "imagePullSecret" . }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/chart/templates/istio/namespace.yaml b/chart/templates/istio/namespace.yaml new file mode 100644 index 0000000000000000000000000000000000000000..e4d9e747fd893213683958a557e98d7b52b9c77e --- /dev/null +++ b/chart/templates/istio/namespace.yaml @@ -0,0 +1,11 @@ +{{- if .Values.istio.enabled }} +apiVersion: v1 +kind: Namespace +metadata: + name: istio-system + labels: + app.kubernetes.io/name: istio-controlplane + app.kubernetes.io/component: "core" + {{- include "commonLabels" . | nindent 4}} + istio-injection: disabled +{{- end }} \ No newline at end of file diff --git a/chart/templates/istio/secret-tls.yaml b/chart/templates/istio/secret-tls.yaml new file mode 100644 index 0000000000000000000000000000000000000000..423b4827372420ba2c9d5b9464c3e9bb5bd68eb9 --- /dev/null +++ b/chart/templates/istio/secret-tls.yaml @@ -0,0 +1,49 @@ +{{- if .Values.istio.enabled }} +{{- range $name, $values := .Values.istio.gateways }} +{{- if $values.servers }} +{{- range $index, $servervalues := $values.servers }} +{{- if and (dig "tls" "cert" "" $servervalues) (dig "tls" "key" "" $servervalues) }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ printf "%d-%s-cert" $index $name }} + namespace: istio-system + labels: + app.kubernetes.io/name: istio-controlplane + app.kubernetes.io/component: "core" + {{- include "commonLabels" $ | nindent 4}} +type: kubernetes.io/tls +data: + tls.crt: {{ $servervalues.tls.cert | b64enc }} + tls.key: {{ $servervalues.tls.key | b64enc }} + {{- if $servervalues.tls.ca }} + ca.crt: {{ $servervalues.tls.ca | b64enc }} + {{- end }} +--- +{{- end }} +{{- end }} +{{/* +For backwards compatibility, get certificate and key from .Values.istio.gateways.<gateway>.tls +*/}} +{{- else if and (dig "tls" "cert" "" $values) (dig "tls" "key" "" $values) }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ printf "%s-cert" $name }} + namespace: istio-system + labels: + app.kubernetes.io/name: istio-controlplane + app.kubernetes.io/component: "core" + {{- include "commonLabels" $ | nindent 4}} +type: kubernetes.io/tls +data: + tls.crt: {{ $values.tls.cert | b64enc }} + tls.key: {{ $values.tls.key | b64enc }} + {{- if $values.tls.ca }} + ca.crt: {{ $values.tls.ca | b64enc }} + {{- end }} +--- +{{- end }} +{{- end }} + +{{- end }} \ No newline at end of file diff --git a/chart/templates/istio/values.yaml b/chart/templates/istio/values.yaml new file mode 100644 index 0000000000000000000000000000000000000000..4da481e9d3126f027d8a087606f7b66f74984629 --- /dev/null +++ b/chart/templates/istio/values.yaml @@ -0,0 +1,210 @@ +{{- if .Values.istio.enabled }} +{{- include "values-secret" (dict "root" $ "package" .Values.istio "name" "istio" "defaults" (include "bigbang.defaults.istio" .)) }} +{{- end }} + +{{- define "bigbang.defaults.istio" -}} +# hostname is deprecated and replaced with domain. But if hostname exists then use it. +{{- $domainName := default .Values.domain .Values.hostname }} +domain: {{ $domainName }} + +mtls: + mode: {{ .Values.istio.mtls.mode }} + +enterprise: {{ .Values.istio.enterprise }} + +istiod: +{{- if not (semverCompare "<1.19" .Capabilities.KubeVersion.GitVersion) }} + env: + - name: ENABLE_LEGACY_FSGROUP_INJECTION + value: "false" +{{- end }} +# Change default hpaSpec to ensure generated HPA uses autoscaling/v2 +{{- if .Capabilities.APIVersions.Has "autoscaling/v2" }} + hpaSpec: + metrics: + - type: Resource + resource: + name: cpu + target: + type: Utilization + averageUtilization: 60 +{{- else }} + hpaSpec: + metrics: + - type: Resource + resource: + name: cpu + targetAverageUtilization: 60 +{{- end }} + +{{- if or .Values.jaeger.enabled .Values.tempo.enabled }} +tracing: +{{- if .Values.jaeger.enabled }} + enabled: {{ .Values.jaeger.enabled }} +{{- else if .Values.tempo.enabled }} + enabled: {{ .Values.tempo.enabled }} + address: 'tempo-tempo.tempo.svc' + sampling: 100 + max_path_tag_length: 99999 +{{- end }} +{{- end }} + +{{- if .Values.tempo.enabled }} +meshConfig: + accessLogFormat: | + [%START_TIME%] "%REQ(:METHOD)% %REQ(X-ENVOY-ORIGINAL-PATH?:PATH)% %PROTOCOL%" %RESPONSE_CODE% %RESPONSE_FLAGS% %RESPONSE_CODE_DETAILS% %CONNECTION_TERMINATION_DETAILS% "%UPSTREAM_TRANSPORT_FAILURE_REASON%" %BYTES_RECEIVED% %BYTES_SENT% %DURATION% %RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)% "%REQ(X-FORWARDED-FOR)%" "%REQ(USER-AGENT)%" "%REQ(X-REQUEST-ID)%" "%REQ(:AUTHORITY)%" "%UPSTREAM_HOST%" %UPSTREAM_CLUSTER% %UPSTREAM_LOCAL_ADDRESS% %DOWNSTREAM_LOCAL_ADDRESS% %DOWNSTREAM_REMOTE_ADDRESS% %REQUESTED_SERVER_NAME% %ROUTE_NAME% traceID=%REQ(x-b3-traceid)% +{{- end }} + +imagePullSecrets: + - private-registry + +openshift: {{ .Values.openshift }} + +authservice: + enabled: {{ or .Values.addons.authservice.enabled (and .Values.monitoring.enabled .Values.monitoring.sso.enabled) (and .Values.jaeger.enabled .Values.jaeger.sso.enabled) (and .Values.tempo.enabled .Values.tempo.sso.enabled) }} + +monitoring: + enabled: {{ .Values.monitoring.enabled }} + +kiali: + enabled: {{ .Values.kiali.enabled }} + +networkPolicies: + enabled: {{ .Values.networkPolicies.enabled }} + controlPlaneCidr: {{ .Values.networkPolicies.controlPlaneCidr }} + +imagePullPolicy: {{ .Values.imagePullPolicy }} + +{{- if or .Values.sso.certificate_authority (dig "certificateAuthority" "cert" false .Values.sso)}} +values: + pilot: + jwksResolverExtraRootCA: {{ default (dig "certificateAuthority" "cert" "" .Values.sso) .Values.sso.certificate_authority | quote }} +{{- end }} + +{{- if .Values.istio.ingressGateways }} +ingressGateways: + istio-ingressgateway: + enabled: false +{{- end }} + +{{- range $name, $values := .Values.istio.ingressGateways }} + {{ if ne $values.enabled false }} + {{ $name | nindent 2 }}: + {{- toYaml (merge (dict "k8s" $values.kubernetesResourceSpec) (dict "k8s" $values.k8s) (fromYaml (include "istio.ingressgateway.k8s" $values))) | nindent 4 }} + {{- if $values.extraLabels }} + {{- toYaml (dict "extraLabels" $values.extraLabels) | nindent 4 }} + {{- end}} + {{- end }} +{{- end }} + +{{- if .Values.istio.gateways }} +gateways: + main: null +{{- end }} +{{- range $name, $values := .Values.istio.gateways }} + {{ if ne $values.enabled false }} + {{ $name | nindent 2 }}: + selector: + app: {{ $values.ingressGateway }} + autoHttpRedirect: + enabled: {{ dig "autoHttpRedirect" "enabled" "true" $values }} + servers: + {{- if $values.servers }} + {{- range $index, $servervalues := $values.servers}} + - hosts: + {{- tpl ( $servervalues.hosts | default (list) | toYaml) $ | nindent 8 }} + port: + {{- if $servervalues.port }} + {{- tpl ( $servervalues.port | default (dict) | toYaml) $ | nindent 8 }} + {{- else }} + name: https + number: 8443 + protocol: HTTPS + {{- end }} + {{- if or (eq $servervalues.port.protocol "HTTPS") (eq $servervalues.port.protocol "TLS") }} + tls: + {{- $tlsMode := (dig "tls" "mode" "SIMPLE" $servervalues) }} + mode: {{ $tlsMode }} + {{- if or (eq $tlsMode "SIMPLE") (eq $tlsMode "MUTUAL") (eq $tlsMode "OPTIONAL_MUTUAL") }} + credentialName: {{ $index }}-{{ $name }}-cert + {{- end }} + {{- $tlsMinVersion := (dig "tls" "minProtocolVersion" "" $values) }} + {{- if $tlsMinVersion }} + minProtocolVersion: {{ $tlsMinVersion }} + {{- end }} + {{- end }} + {{- if and (eq $servervalues.port.protocol "HTTP") (hasKey $servervalues "tls") (hasKey $servervalues.tls "httpsRedirect") }} + tls: + httpsRedirect: {{ $servervalues.tls.httpsRedirect | default false }} + {{- end }} + {{- end }} + {{- else if ($values.ports) }} + {{- range $values.ports }} + - hosts: + {{- tpl ($values.hosts | default (list) | toYaml) $ | nindent 8 }} + port: + {{- tpl ( . | default (list) | toYaml) $ | nindent 8 }} + {{- if eq $values.ports.protocol "HTTPS" }} + tls: + {{- $tlsMode := (dig "tls" "mode" "SIMPLE" $values) }} + mode: {{ $tlsMode }} + {{- if or (eq $tlsMode "SIMPLE") (eq $tlsMode "MUTUAL") (eq $tlsMode "OPTIONAL_MUTUAL") }} + credentialName: {{ $name }}-cert + {{- end }} + {{- $tlsMinVersion := (dig "tls" "minProtocolVersion" "" $values) }} + {{- if $tlsMinVersion }} + minProtocolVersion: {{ $tlsMinVersion }} + {{- end }} + {{- end }} + {{- if and (eq $values.port.protocol "HTTP") (hasKey $values "tls") (hasKey $values.tls "httpsRedirect") }} + tls: + httpsRedirect: {{ $values.tls.httpsRedirect | default false }} + {{- end }} + {{- end }} + {{- else }} + - hosts: + {{- tpl ($values.hosts | default (list) | toYaml) $ | nindent 8 }} + port: + name: https + number: 8443 + protocol: HTTPS + tls: + {{- $tlsMode := (dig "tls" "mode" "SIMPLE" $values) }} + mode: {{ $tlsMode }} + {{- if or (eq $tlsMode "SIMPLE") (eq $tlsMode "MUTUAL") (eq $tlsMode "OPTIONAL_MUTUAL") }} + credentialName: {{ $name }}-cert + {{- end }} + {{- $tlsMinVersion := (dig "tls" "minProtocolVersion" "" $values) }} + {{- if $tlsMinVersion }} + minProtocolVersion: {{ $tlsMinVersion }} + {{- end }} + {{- end }} + {{- end }} + {{- end }} +{{- end }} + +{{- define "istio.ingressgateway.k8s" -}} +k8s: + service: + type: {{ .type }} + {{- if .nodePortBase }} + ports: # Pulled from Istio gateway defaults (https://github.com/istio/istio/blob/master/manifests/charts/gateways/istio-ingress/values.yaml) + # Ports default to "protocol: TCP" and "targetPort = port" + # AWS ELB will by default perform health checks on the first port on this list. https://github.com/istio/istio/issues/12503 + - port: 15021 + name: status-port + nodePort: {{ add .nodePortBase 0 }} + - port: 80 + targetPort: 8080 + name: http2 + nodePort: {{ add .nodePortBase 1 }} + - port: 443 + targetPort: 8443 + name: https + nodePort: {{ add .nodePortBase 2 }} + # SNI Routing port + - port: 15443 + name: tls + nodePort: {{ add .nodePortBase 3 }} + {{- end }} +{{- end }} diff --git a/chart/templates/jaeger/git-credentials.yaml b/chart/templates/jaeger/git-credentials.yaml new file mode 100644 index 0000000000000000000000000000000000000000..b1f69f0930bd377e1cc0af7af9bad526e69bebd5 --- /dev/null +++ b/chart/templates/jaeger/git-credentials.yaml @@ -0,0 +1,7 @@ +{{- $gitCredsSecretDict := dict + "name" "jaeger" + "targetScope" .Values.jaeger + "releaseName" .Release.Name + "releaseNamespace" .Release.Namespace +}} +{{- include "gitCredsSecret" $gitCredsSecretDict | nindent 0 -}} diff --git a/chart/templates/jaeger/gitrepository.yaml b/chart/templates/jaeger/gitrepository.yaml new file mode 100644 index 0000000000000000000000000000000000000000..5594e8e85ca63e6687f4425b896dcd7340f29745 --- /dev/null +++ b/chart/templates/jaeger/gitrepository.yaml @@ -0,0 +1,24 @@ +{{- if and (eq .Values.jaeger.sourceType "git") (not .Values.offline) .Values.jaeger.enabled }} +{{- $gitCredsDict := dict + "name" "jaeger" + "packageGitScope" .Values.jaeger.git + "rootScope" . + "releaseName" .Release.Name +}} +apiVersion: source.toolkit.fluxcd.io/v1 +kind: GitRepository +metadata: + name: jaeger + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: jaeger + app.kubernetes.io/component: "core" + {{- include "commonLabels" . | nindent 4}} +spec: + interval: {{ .Values.flux.interval }} + url: {{ .Values.jaeger.git.repo }} + ref: + {{- include "validRef" .Values.jaeger.git | nindent 4 }} + {{ include "gitIgnore" . }} + {{- include "gitCredsExtended" $gitCredsDict | nindent 2 }} +{{- end }} diff --git a/chart/templates/jaeger/helmrelease.yaml b/chart/templates/jaeger/helmrelease.yaml new file mode 100644 index 0000000000000000000000000000000000000000..cf9ba28658407ddcd70e7ece29079ff228e3359c --- /dev/null +++ b/chart/templates/jaeger/helmrelease.yaml @@ -0,0 +1,79 @@ +{{- $fluxSettingsJaeger := merge .Values.jaeger.flux .Values.flux -}} +{{- if .Values.jaeger.enabled }} +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + name: jaeger + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: jaeger + app.kubernetes.io/component: "core" + {{- include "commonLabels" . | nindent 4}} + annotations: + checksum/bigbang-values: {{ include (print $.Template.BasePath "/jaeger/values.yaml") . | sha256sum }} +spec: + driftDetection: + mode: warn + targetNamespace: jaeger + chart: + spec: + {{- if eq .Values.jaeger.sourceType "git" }} + chart: {{ .Values.jaeger.git.path }} + sourceRef: + kind: GitRepository + name: jaeger + namespace: {{ .Release.Namespace }} + {{- else }} + chart: {{ .Values.jaeger.helmRepo.chartName }} + version: {{ .Values.jaeger.helmRepo.tag }} + sourceRef: + kind: HelmRepository + name: {{ .Values.jaeger.helmRepo.repoName }} + namespace: {{ .Release.Namespace }} + {{- $repoType := include "getRepoType" (dict "repoName" .Values.jaeger.helmRepo.repoName "allRepos" $.Values.helmRepositories) -}} + {{- if (and .Values.jaeger.helmRepo.cosignVerify (eq $repoType "oci")) }} # Needs to be an OCI repo + verify: + provider: cosign + secretRef: + name: {{ printf "%s-cosign-pub" .Values.jaeger.helmRepo.repoName }} + {{- end }} + {{- end }} + interval: 5m + + {{- toYaml $fluxSettingsJaeger | nindent 2 }} + + {{- if .Values.jaeger.postRenderers }} + postRenderers: + {{ toYaml .Values.jaeger.postRenderers | nindent 4 }} + {{- end }} + valuesFrom: + - name: {{ .Release.Name }}-jaeger-values + kind: Secret + valuesKey: "common" + - name: {{ .Release.Name }}-jaeger-values + kind: Secret + valuesKey: "defaults" + - name: {{ .Release.Name }}-jaeger-values + kind: Secret + valuesKey: "overlays" + + {{ if or .Values.istio.enabled .Values.monitoring.enabled .Values.jaeger.sso.enabled .Values.elasticsearchKibana.enabled }} + dependsOn: + {{- if .Values.istio.enabled }} + - name: istio + namespace: {{ .Release.Namespace }} + {{- end }} + {{- if .Values.monitoring.enabled }} + - name: monitoring + namespace: {{ .Release.Namespace }} + {{- end }} + {{- if .Values.jaeger.sso.enabled }} + - name: authservice + namespace: {{ .Release.Namespace }} + {{- end }} + {{- if .Values.elasticsearchKibana.enabled }} + - name: ek + namespace: {{ .Release.Namespace }} + {{- end }} + {{- end }} +{{- end }} diff --git a/chart/templates/jaeger/imagepullsecret.yaml b/chart/templates/jaeger/imagepullsecret.yaml new file mode 100644 index 0000000000000000000000000000000000000000..b99489350cb7dc508f94169f21cb923dce2ec17a --- /dev/null +++ b/chart/templates/jaeger/imagepullsecret.yaml @@ -0,0 +1,10 @@ +{{- if and .Values.jaeger.enabled ( include "imagePullSecret" . ) }} +apiVersion: v1 +kind: Secret +metadata: + name: private-registry + namespace: jaeger +type: kubernetes.io/dockerconfigjson +data: + .dockerconfigjson: {{ template "imagePullSecret" . }} +{{- end }} \ No newline at end of file diff --git a/chart/templates/jaeger/namespace.yaml b/chart/templates/jaeger/namespace.yaml new file mode 100644 index 0000000000000000000000000000000000000000..dabc0e00f2a292578c969cfe3a6f879c243487b8 --- /dev/null +++ b/chart/templates/jaeger/namespace.yaml @@ -0,0 +1,11 @@ +{{- if .Values.jaeger.enabled }} +apiVersion: v1 +kind: Namespace +metadata: + name: jaeger + labels: + istio-injection: {{ ternary "enabled" "disabled" (and .Values.istio.enabled (eq (dig "istio" "injection" "enabled" .Values.jaeger) "enabled")) }} + app.kubernetes.io/name: jaeger + app.kubernetes.io/component: "core" + {{- include "commonLabels" . | nindent 4}} +{{- end }} \ No newline at end of file diff --git a/chart/templates/jaeger/secret-ca.yaml b/chart/templates/jaeger/secret-ca.yaml new file mode 100644 index 0000000000000000000000000000000000000000..86036a299430cdcf0b06130e6ecd76b546362fbc --- /dev/null +++ b/chart/templates/jaeger/secret-ca.yaml @@ -0,0 +1,10 @@ +{{- if and .Values.jaeger.enabled .Values.jaeger.sso.enabled (or .Values.sso.certificate_authority (dig "certificateAuthority" "cert" false .Values.sso)) }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ default (dig "certificateAuthority" "secretName" "" .Values.sso) .Values.sso.secretName }} + namespace: jaeger +type: Opaque +data: + ca.pem: {{ default (dig "certificateAuthority" "cert" "" .Values.sso) .Values.sso.certificate_authority | b64enc }} +{{- end }} \ No newline at end of file diff --git a/chart/templates/jaeger/values.yaml b/chart/templates/jaeger/values.yaml new file mode 100644 index 0000000000000000000000000000000000000000..e748950a00fa435bfff0f26df43c43253806c51c --- /dev/null +++ b/chart/templates/jaeger/values.yaml @@ -0,0 +1,107 @@ +{{- if .Values.jaeger.enabled }} +{{- include "values-secret" (dict "root" $ "package" .Values.jaeger "name" "jaeger" "defaults" (include "bigbang.defaults.jaeger" .)) }} +{{- end }} + +{{- define "bigbang.defaults.jaeger" -}} +imagePullSecrets: + - name: private-registry + +image: + pullPolicy: {{ .Values.imagePullPolicy }} + +# hostname is deprecated and replaced with domain. But if hostname exists then use it. +{{- $domainName := default .Values.domain .Values.hostname }} +hostname: {{ $domainName }} +domain: {{ $domainName }} + +istio: + enabled: {{ .Values.istio.enabled }} + hardened: + enabled: {{ or + (dig "istio" "hardened" "enabled" false .Values.jaeger.values) + (dig "hardened" "enabled" false .Values.istio.values) + }} + jaeger: + enabled: {{ .Values.istio.enabled }} + gateways: + - istio-system/{{ default "public" .Values.jaeger.ingress.gateway }} + +{{- if .Values.istio.enabled }} +annotations: + {{ include "istioAnnotation" . }} +{{- end }} + +monitoring: + enabled: {{ .Values.monitoring.enabled }} + # conditional passes only for default istio: enabled, mTLS: SCRICT + {{- if and .Values.istio.enabled (eq (dig "istio" "mtls" "mode" "STRICT" .Values.jaeger.values) "STRICT") }} + serviceMonitor: + scheme: https + tlsConfig: + caFile: /etc/prom-certs/root-cert.pem + certFile: /etc/prom-certs/cert-chain.pem + keyFile: /etc/prom-certs/key.pem + insecureSkipVerify: true # Prometheus does not support Istio security naming, thus skip verifying target pod certificate + {{- end }} + +elasticsearch: + enabled: {{ .Values.elasticsearchKibana.enabled }} + +sso: + enabled: {{ .Values.jaeger.sso.enabled }} + + +{{- if or .Values.jaeger.sso.enabled .Values.istio.enabled .Values.kiali.enabled }} +jaeger: + spec: + {{- if or .Values.jaeger.sso.enabled .Values.istio.enabled }} + {{- $jaegerAuthserviceKey := (dig "selector" "key" "protect" .Values.addons.authservice.values) }} + {{- $jaegerAuthserviceValue := (dig "selector" "value" "keycloak" .Values.addons.authservice.values) }} + allInOne: + {{- if .Values.jaeger.sso.enabled }} + labels: + {{ $jaegerAuthserviceKey }}: {{ $jaegerAuthserviceValue }} + {{- end }} + {{- if .Values.istio.enabled }} + annotations: + {{ include "istioAnnotation" . }} + {{- end }} + query: + {{- if .Values.jaeger.sso.enabled }} + labels: + {{ $jaegerAuthserviceKey }}: {{ $jaegerAuthserviceValue }} + {{- end }} + {{- if .Values.istio.enabled }} + annotations: + {{ include "istioAnnotation" . }} + {{- end }} + {{- end }} + {{- if .Values.istio.enabled }} + agent: + annotations: + {{ include "istioAnnotation" . }} + ingester: + annotations: + {{ include "istioAnnotation" . }} + collector: + annotations: + {{ include "istioAnnotation" . }} + {{- end }} +{{- end }} +openshift: + enabled: {{ .Values.openshift }} +networkPolicies: + enabled: {{ .Values.networkPolicies.enabled }} + controlPlaneCidr: {{ .Values.networkPolicies.controlPlaneCidr }} + ingressLabels: + {{- $gateway := default "public" .Values.jaeger.ingress.gateway }} + {{- $default := dict "app" (dig "gateways" $gateway "ingressGateway" nil .Values.istio) "istio" nil }} + {{- toYaml (dig "values" "gateways" $gateway "selector" $default .Values.istio) | nindent 4 }} + +webhookCertGen: + image: + pullPolicy: {{ .Values.imagePullPolicy }} + cleanupProxy: + image: + pullPolicy: {{ .Values.imagePullPolicy }} +{{- end -}} diff --git a/chart/templates/keycloak/git-credentials.yaml b/chart/templates/keycloak/git-credentials.yaml new file mode 100644 index 0000000000000000000000000000000000000000..9f0d87aacb828f02e777e51b668f82e600068a48 --- /dev/null +++ b/chart/templates/keycloak/git-credentials.yaml @@ -0,0 +1,7 @@ +{{- $gitCredsSecretDict := dict + "name" "keycloak" + "targetScope" .Values.addons.keycloak + "releaseName" .Release.Name + "releaseNamespace" .Release.Namespace +}} +{{- include "gitCredsSecret" $gitCredsSecretDict | nindent 0 -}} diff --git a/chart/templates/keycloak/gitrepository.yaml b/chart/templates/keycloak/gitrepository.yaml new file mode 100644 index 0000000000000000000000000000000000000000..cc066c26d63fb948e5379b8682fb75a07c199a2d --- /dev/null +++ b/chart/templates/keycloak/gitrepository.yaml @@ -0,0 +1,24 @@ +{{- if and (eq .Values.addons.keycloak.sourceType "git") (not .Values.offline) .Values.addons.keycloak.enabled }} +{{ $name := "keycloak" }} +{{- $gitCredsDict := dict + "name" $name + "packageGitScope" .Values.addons.keycloak.git + "rootScope" . + "releaseName" .Release.Name +}} +apiVersion: source.toolkit.fluxcd.io/v1 +kind: GitRepository +metadata: + name: {{ $name }} + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ $name }} + app.kubernetes.io/component: "security-tools" + {{- include "commonLabels" . | nindent 4}} +spec: + interval: {{ .Values.flux.interval }} + url: {{ .Values.addons.keycloak.git.repo }} + ref: + {{- include "validRef" .Values.addons.keycloak.git | nindent 4 }} + {{- include "gitCredsExtended" $gitCredsDict | nindent 2 }} +{{- end }} \ No newline at end of file diff --git a/chart/templates/keycloak/helmrelease.yaml b/chart/templates/keycloak/helmrelease.yaml new file mode 100644 index 0000000000000000000000000000000000000000..1390da94ec79ca13604a8c7a6ca9ec214cce7e23 --- /dev/null +++ b/chart/templates/keycloak/helmrelease.yaml @@ -0,0 +1,81 @@ +{{- $fluxSettingsKeycloak := merge .Values.addons.keycloak.flux .Values.flux -}} +{{- if .Values.addons.keycloak.enabled }} +{{ $name := "keycloak" }} +{{ $component := "security-tools" }} +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + name: {{ $name }} + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ $name }} + app.kubernetes.io/component: {{ $component }} + {{- include "commonLabels" . | nindent 4}} + annotations: + checksum/bigbang-values: {{ include (print $.Template.BasePath "/keycloak/values.yaml") . | sha256sum }} +spec: + releaseName: {{ $name }} + targetNamespace: {{ $name }} + chart: + spec: + {{- if eq .Values.addons.keycloak.sourceType "git" }} + chart: {{ .Values.addons.keycloak.git.path }} + sourceRef: + kind: GitRepository + name: {{ $name }} + namespace: {{ .Release.Namespace }} + {{- else }} + chart: {{ .Values.addons.keycloak.helmRepo.chartName }} + version: {{ .Values.addons.keycloak.helmRepo.tag }} + sourceRef: + kind: HelmRepository + name: {{ .Values.addons.keycloak.helmRepo.repoName }} + namespace: {{ .Release.Namespace }} + {{- $repoType := include "getRepoType" (dict "repoName" .Values.addons.keycloak.helmRepo.repoName "allRepos" $.Values.helmRepositories) -}} + {{- if (and .Values.addons.keycloak.helmRepo.cosignVerify (eq $repoType "oci")) }} # Needs to be an OCI repo + verify: + provider: cosign + secretRef: + name: {{ printf "%s-cosign-pub" .Values.addons.keycloak.helmRepo.repoName }} + {{- end }} + {{- end }} + interval: 5m + + {{- if .Values.addons.keycloak.postRenderers }} + postRenderers: + {{ toYaml .Values.addons.keycloak.postRenderers | nindent 4 }} + {{- end }} + + {{- toYaml $fluxSettingsKeycloak | nindent 2 }} + + valuesFrom: + - name: {{ .Release.Name }}-{{ $name }}-values + kind: Secret + valuesKey: "common" + - name: {{ .Release.Name }}-{{ $name }}-values + kind: Secret + valuesKey: "defaults" + - name: {{ .Release.Name }}-{{ $name }}-values + kind: Secret + valuesKey: "overlays" + + {{- if or .Values.gatekeeper.enabled .Values.istio.enabled .Values.kyvernoPolicies.enabled .Values.monitoring.enabled }} + dependsOn: + {{- if .Values.gatekeeper.enabled }} + - name: gatekeeper + namespace: {{ .Release.Namespace }} + {{- end }} + {{- if .Values.istio.enabled }} + - name: istio + namespace: {{ .Release.Namespace }} + {{- end }} + {{- if .Values.kyvernoPolicies.enabled }} + - name: kyverno-policies + namespace: {{ .Release.Namespace }} + {{- end }} + {{- if .Values.monitoring.enabled }} + - name: monitoring + namespace: {{ .Release.Namespace }} + {{- end }} + {{- end }} +{{- end }} diff --git a/chart/templates/keycloak/imagepullsecret.yaml b/chart/templates/keycloak/imagepullsecret.yaml new file mode 100644 index 0000000000000000000000000000000000000000..27ab5d838f65a41115de70a6c2216e48c279b79e --- /dev/null +++ b/chart/templates/keycloak/imagepullsecret.yaml @@ -0,0 +1,18 @@ +{{- if .Values.addons.keycloak.enabled }} +{{ $name := "keycloak" }} +{{ $component := "security-tools" }} +{{- if ( include "imagePullSecret" . ) }} +apiVersion: v1 +kind: Secret +metadata: + name: private-registry + namespace: {{ $name }} + labels: + app.kubernetes.io/name: {{ $name }} + app.kubernetes.io/component: {{ $component }} + {{- include "commonLabels" . | nindent 4}} +type: kubernetes.io/dockerconfigjson +data: + .dockerconfigjson: {{ template "imagePullSecret" . }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/chart/templates/keycloak/namespace.yaml b/chart/templates/keycloak/namespace.yaml new file mode 100644 index 0000000000000000000000000000000000000000..0a37a9e353accd95ad25f6b2fbb9ec0263e89ab3 --- /dev/null +++ b/chart/templates/keycloak/namespace.yaml @@ -0,0 +1,12 @@ +{{- if .Values.addons.keycloak.enabled }} +{{ $name := "keycloak" }} +apiVersion: v1 +kind: Namespace +metadata: + name: {{ $name }} + labels: + istio-injection: {{ ternary "enabled" "disabled" (and .Values.istio.enabled (eq (dig "istio" "injection" "enabled" .Values.addons.keycloak) "enabled")) }} + app.kubernetes.io/name: {{ $name }} + app.kubernetes.io/component: "security-tools" + {{- include "commonLabels" . | nindent 4 }} +{{- end }} diff --git a/chart/templates/keycloak/values.yaml b/chart/templates/keycloak/values.yaml new file mode 100644 index 0000000000000000000000000000000000000000..7f6de7f0b066a42439ba06c00ae392e7ab842516 --- /dev/null +++ b/chart/templates/keycloak/values.yaml @@ -0,0 +1,144 @@ +{{- if .Values.addons.keycloak.enabled }} +{{- include "values-secret" (dict "root" $ "package" .Values.addons.keycloak "name" "keycloak" "defaults" (include "bigbang.defaults.keycloak" .)) }} +{{- end }} + +{{- define "bigbang.defaults.keycloak" -}} +replicas: 2 + +imagePullSecrets: +- name: private-registry + +image: + pullPolicy: {{ .Values.imagePullPolicy }} + +# hostname is deprecated and replaced with domain. But if hostname exists then use it. +{{- $domainName := default .Values.domain .Values.hostname }} +hostname: {{ $domainName }} +domain: {{ $domainName }} + +openshift: {{ .Values.openshift }} + +{{- $istioInjection := (and (eq (dig "istio" "injection" "enabled" .Values.addons.keycloak) "enabled") .Values.istio.enabled) }} + +istio: + enabled: {{ .Values.istio.enabled }} + hardened: + enabled: {{ or + (dig "istio" "hardened" "enabled" false .Values.addons.keycloak.values) + (dig "hardened" "enabled" false .Values.istio.values) + }} + injection: {{ dig "istio" "injection" "enabled" .Values.addons.keycloak }} + keycloak: + enabled: true + gateways: + - istio-system/{{ default "public" .Values.addons.keycloak.ingress.gateway }} + +{{- if $istioInjection }} +podAnnotations: + {{ include "istioAnnotation" . }} +{{- end }} + +networkPolicies: + enabled: {{ .Values.networkPolicies.enabled }} + controlPlaneCidr: {{ .Values.networkPolicies.controlPlaneCidr }} + ingressLabels: + {{- $gateway := default "passthrough" .Values.addons.keycloak.ingress.gateway }} + {{- $default := dict "app" (dig "gateways" $gateway "ingressGateway" nil .Values.istio) "istio" nil }} + {{- toYaml (dig "values" "gateways" $gateway "selector" $default .Values.istio) | nindent 4 }} + +monitoring: + enabled: {{ .Values.monitoring.enabled }} +serviceMonitor: + enabled: {{ .Values.monitoring.enabled }} + # conditional passes only for default istio: enabled, mTLS: SCRICT, istio injection: enabled + {{- if and $istioInjection (eq (dig "istio" "mtls" "mode" "STRICT" .Values.addons.keycloak.values) "STRICT") }} + scheme: https + tlsConfig: + caFile: /etc/prom-certs/root-cert.pem + certFile: /etc/prom-certs/cert-chain.pem + keyFile: /etc/prom-certs/key.pem + # Prometheus does not support Istio security naming, thus skip verifying target pod certificate + insecureSkipVerify: true + {{- end }} + +{{- if .Values.addons.keycloak.database.host }} +postgresql: + enabled: false +{{- else if or $istioInjection .Values.kiali.enabled }} +postgresql: + primary: + {{- if $istioInjection }} + annotations: + {{- include "istioAnnotation" . | nindent 6 }} + {{- end }} + readReplicas: + {{- if $istioInjection }} + annotations: + {{- include "istioAnnotation" . | nindent 6 }} + {{- end }} +{{- end }} + +{{- if or .Values.addons.keycloak.database.host (and .Values.addons.keycloak.ingress.cert .Values.addons.keycloak.ingress.key) }} +secrets: + {{- if and .Values.addons.keycloak.ingress.cert .Values.addons.keycloak.ingress.key }} + tlscert: + stringData: + tls.crt: {{ .Values.addons.keycloak.ingress.cert | quote }} + tlskey: + stringData: + tls.key: {{ .Values.addons.keycloak.ingress.key | quote }} + {{- end }} + + {{- with .Values.addons.keycloak.database }} + {{- if .host }} + env: + stringData: + # keep legacy ENVs for backwards compatibility + DB_USER: {{ .username | quote }} + DB_PASSWORD: {{ .password | quote }} + DB_VENDOR: {{ default "postgres" .type }} + DB_ADDR: {{ .host }} + DB_PORT: {{ .port | quote }} + DB_DATABASE: {{ .database }} + # Quarkus ENVs + KC_DB_USERNAME: {{ .username | quote }} + KC_DB_PASSWORD: {{ .password | quote }} + KC_DB: {{ default "postgres" .type }} + KC_DB_URL_HOST: {{ .host }} + KC_DB_URL_PORT: {{ .port | quote }} + KC_DB_URL_DATABASE: {{ .database }} + {{- end }} + {{- end }} +{{- end }} + +{{- if and .Values.addons.keycloak.ingress.cert .Values.addons.keycloak.ingress.key }} +extraVolumesBigBang: + - name: tlscert + secret: + secretName: keycloak-tlscert + - name: tlskey + secret: + secretName: keycloak-tlskey + +extraVolumeMountsBigBang: + # keep /etc/x509/https/ for legacy backwards compatibility + - name: tlscert + mountPath: /etc/x509/https/tls.crt + subPath: tls.crt + readOnly: true + - name: tlskey + mountPath: /etc/x509/https/tls.key + subPath: tls.key + readOnly: true + # Quarkus cert paths + - name: tlscert + mountPath: /opt/keycloak/conf/tls.crt + subPath: tls.crt + readOnly: true + - name: tlskey + mountPath: /opt/keycloak/conf/tls.key + subPath: tls.key + readOnly: true +{{- end }} + +{{- end }} diff --git a/chart/templates/kiali/git-credentials.yaml b/chart/templates/kiali/git-credentials.yaml new file mode 100644 index 0000000000000000000000000000000000000000..e50e8d3db22067ea2614a7acaee69b54eb6cdb21 --- /dev/null +++ b/chart/templates/kiali/git-credentials.yaml @@ -0,0 +1,7 @@ +{{- $gitCredsSecretDict := dict + "name" "kiali" + "targetScope" .Values.kiali + "releaseName" .Release.Name + "releaseNamespace" .Release.Namespace +}} +{{- include "gitCredsSecret" $gitCredsSecretDict | nindent 0 -}} diff --git a/chart/templates/kiali/gitrepository.yaml b/chart/templates/kiali/gitrepository.yaml new file mode 100644 index 0000000000000000000000000000000000000000..5ec0d1cce967d1fd4093322ae8d35cc33d1db2a6 --- /dev/null +++ b/chart/templates/kiali/gitrepository.yaml @@ -0,0 +1,24 @@ +{{- if and (eq .Values.kiali.sourceType "git") (not .Values.offline) .Values.kiali.enabled }} +{{- $gitCredsDict := dict + "name" "kiali" + "packageGitScope" .Values.kiali.git + "rootScope" . + "releaseName" .Release.Name +}} +apiVersion: source.toolkit.fluxcd.io/v1 +kind: GitRepository +metadata: + name: kiali + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: kiali + app.kubernetes.io/component: "core" + {{- include "commonLabels" . | nindent 4}} +spec: + interval: {{ .Values.flux.interval }} + url: {{ .Values.kiali.git.repo }} + ref: + {{- include "validRef" .Values.kiali.git | nindent 4 }} + {{ include "gitIgnore" . }} + {{- include "gitCredsExtended" $gitCredsDict | nindent 2 }} +{{- end }} diff --git a/chart/templates/kiali/grafana-auth-secret.yaml b/chart/templates/kiali/grafana-auth-secret.yaml new file mode 100644 index 0000000000000000000000000000000000000000..ce41ab8c75a80a230e3f29f6b71e33e0c38b2fc7 --- /dev/null +++ b/chart/templates/kiali/grafana-auth-secret.yaml @@ -0,0 +1,21 @@ +{{- if and .Values.kiali.enabled .Values.grafana.enabled }} +apiVersion: v1 +kind: Secret +metadata: + name: grafana-auth + namespace: kiali + labels: + app.kubernetes.io/name: kiali + app.kubernetes.io/component: "core" + {{- include "commonLabels" . | nindent 4}} +type: kubernetes.io/opaque +stringData: +{{- if (dig "admin" "existingSecret" "" .Values.grafana.values) }} + {{- $passwordKey := (dig "admin" "passwordKey" "admin-password" .Values.grafana.values) }} + {{- with lookup "v1" "Secret" "monitoring" .Values.grafana.values.admin.existingSecret }} + password: {{ (get .data $passwordKey | b64dec) | default "prom-operator" }} + {{- end }} +{{- else }} + password: {{ dig "adminPassword" "prom-operator" .Values.grafana.values }} +{{- end }} +{{- end }} diff --git a/chart/templates/kiali/helmrelease.yaml b/chart/templates/kiali/helmrelease.yaml new file mode 100644 index 0000000000000000000000000000000000000000..800b1a5f74763083af2af46e0f360ea398148a75 --- /dev/null +++ b/chart/templates/kiali/helmrelease.yaml @@ -0,0 +1,69 @@ +{{- $fluxSettingsKiali := merge .Values.kiali.flux .Values.flux -}} +{{- if .Values.kiali.enabled }} +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + name: kiali + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: kiali + app.kubernetes.io/component: "core" + {{- include "commonLabels" . | nindent 4}} + annotations: + checksum/bigbang-values: {{ include (print $.Template.BasePath "/kiali/values.yaml") . | sha256sum }} +spec: + targetNamespace: kiali + chart: + spec: + {{- if eq .Values.kiali.sourceType "git" }} + chart: {{ .Values.kiali.git.path }} + sourceRef: + kind: GitRepository + name: kiali + namespace: {{ .Release.Namespace }} + {{- else }} + chart: {{ .Values.kiali.helmRepo.chartName }} + version: {{ .Values.kiali.helmRepo.tag }} + sourceRef: + kind: HelmRepository + name: {{ .Values.kiali.helmRepo.repoName }} + namespace: {{ .Release.Namespace }} + {{- $repoType := include "getRepoType" (dict "repoName" .Values.kiali.helmRepo.repoName "allRepos" $.Values.helmRepositories) -}} + {{- if (and .Values.kiali.helmRepo.cosignVerify (eq $repoType "oci")) }} # Needs to be an OCI repo + verify: + provider: cosign + secretRef: + name: {{ printf "%s-cosign-pub" .Values.kiali.helmRepo.repoName }} + {{- end }} + {{- end }} + interval: 5m + + {{- toYaml $fluxSettingsKiali | nindent 2 }} + + {{- if .Values.kiali.postRenderers }} + postRenderers: + {{ toYaml .Values.kiali.postRenderers | nindent 4 }} + {{- end }} + valuesFrom: + - name: {{ .Release.Name }}-kiali-values + kind: Secret + valuesKey: "common" + - name: {{ .Release.Name }}-kiali-values + kind: Secret + valuesKey: "defaults" + - name: {{ .Release.Name }}-kiali-values + kind: Secret + valuesKey: "overlays" + + {{ if or .Values.istio.enabled .Values.monitoring.enabled }} + dependsOn: + {{- if .Values.istio.enabled }} + - name: istio + namespace: {{ .Release.Namespace }} + {{- end }} + {{- if .Values.monitoring.enabled }} + - name: monitoring + namespace: {{ .Release.Namespace }} + {{- end }} + {{- end }} +{{- end }} diff --git a/chart/templates/kiali/imagepullsecret.yaml b/chart/templates/kiali/imagepullsecret.yaml new file mode 100644 index 0000000000000000000000000000000000000000..48bcdc80a23355ebfe87b9358d0a8bf6239ee7c7 --- /dev/null +++ b/chart/templates/kiali/imagepullsecret.yaml @@ -0,0 +1,10 @@ +{{- if and .Values.kiali.enabled ( include "imagePullSecret" . ) }} +apiVersion: v1 +kind: Secret +metadata: + name: private-registry + namespace: kiali +type: kubernetes.io/dockerconfigjson +data: + .dockerconfigjson: {{ template "imagePullSecret" . }} +{{- end }} \ No newline at end of file diff --git a/chart/templates/kiali/namespace.yaml b/chart/templates/kiali/namespace.yaml new file mode 100644 index 0000000000000000000000000000000000000000..56ef0e8f10ca2efc315792214726805aa39742c6 --- /dev/null +++ b/chart/templates/kiali/namespace.yaml @@ -0,0 +1,11 @@ +{{- if .Values.kiali.enabled }} +apiVersion: v1 +kind: Namespace +metadata: + name: kiali + labels: + istio-injection: {{ ternary "enabled" "disabled" (and .Values.istio.enabled (eq (dig "istio" "injection" "enabled" .Values.kiali) "enabled")) }} + app.kubernetes.io/name: kiali + app.kubernetes.io/component: "core" + {{- include "commonLabels" . | nindent 4}} +{{- end }} \ No newline at end of file diff --git a/chart/templates/kiali/secret-ca.yaml b/chart/templates/kiali/secret-ca.yaml new file mode 100644 index 0000000000000000000000000000000000000000..6f86830e22ff35ac5c36c7265fdf0d9beba517fb --- /dev/null +++ b/chart/templates/kiali/secret-ca.yaml @@ -0,0 +1,10 @@ +{{- if and .Values.kiali.enabled .Values.kiali.sso.enabled (or .Values.sso.certificate_authority (dig "certificateAuthority" "cert" false .Values.sso)) }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ default (dig "certificateAuthority" "secretName" "" .Values.sso) .Values.sso.secretName }} + namespace: kiali +type: Opaque +data: + ca.pem: {{ default (dig "certificateAuthority" "cert" "" .Values.sso) .Values.sso.certificate_authority | b64enc }} +{{- end }} \ No newline at end of file diff --git a/chart/templates/kiali/sso-client-secret.yaml b/chart/templates/kiali/sso-client-secret.yaml new file mode 100644 index 0000000000000000000000000000000000000000..0f27505e64364a37fc739bdbc6883c072b0375f0 --- /dev/null +++ b/chart/templates/kiali/sso-client-secret.yaml @@ -0,0 +1,10 @@ +{{- if and .Values.kiali.enabled .Values.kiali.sso.client_secret }} +apiVersion: v1 +kind: Secret +metadata: + name: kiali + namespace: kiali +type: kubernetes.io/opaque +stringData: + oidc-secret: {{ .Values.kiali.sso.client_secret }} +{{- end }} diff --git a/chart/templates/kiali/values.yaml b/chart/templates/kiali/values.yaml new file mode 100644 index 0000000000000000000000000000000000000000..2a91f5b7528b47f8dbe3ab650053f93ebfdfac33 --- /dev/null +++ b/chart/templates/kiali/values.yaml @@ -0,0 +1,132 @@ +{{- if .Values.kiali.enabled }} +{{- include "values-secret" (dict "root" $ "package" .Values.kiali "name" "kiali" "defaults" (include "bigbang.defaults.kiali" .)) }} +{{- end }} + +{{- define "bigbang.defaults.kiali" -}} +# hostname is deprecated and replaced with domain. But if hostname exists then use it. +{{- $domainName := default .Values.domain .Values.hostname }} +domain: {{ $domainName }} + +sso: + enabled: {{ .Values.kiali.sso.enabled }} + +openshift: {{ .Values.openshift}} + +image: + pullPolicy: {{ .Values.imagePullPolicy }} + +istio: + enabled: {{ .Values.istio.enabled }} + hardened: + enabled: {{ or + (dig "istio" "hardened" "enabled" false .Values.kiali.values) + (dig "hardened" "enabled" false .Values.istio.values) + }} + monitoring: + enabled: {{ .Values.monitoring.enabled }} + kiali: + gateways: + - istio-system/{{ default "public" .Values.kiali.ingress.gateway }} + +{{- if .Values.istio.enabled }} +podAnnotations: + {{ include "istioAnnotation" . }} +{{- end }} + +{{- if and .Values.kiali.enabled .Values.kiali.sso.enabled (or .Values.sso.certificate_authority (dig "certificateAuthority" "cert" false .Values.sso)) }} +oidcCaCert: {{ default (dig "certificateAuthority" "cert" "" .Values.sso) .Values.sso.certificate_authority | quote }} +{{- end }} + +monitoring: + enabled: {{ .Values.monitoring.enabled }} +elasticsearch: + enabled: {{ .Values.elasticsearchKibana.enabled }} +cr: + spec: + deployment: + image_pull_policy: {{ .Values.imagePullPolicy }} + {{- if .Values.istio.enabled }} + pod_annotations: + {{ include "istioAnnotation" . }} + {{- end }} + hpa: + spec: + maxReplicas: 2 + minReplicas: 1 + targetCPUUtilizationPercentage: 80 + server: + web_port: "443" + auth: + {{- if .Values.kiali.sso.enabled }} + strategy: openid + openid: + client_id: "{{ .Values.kiali.sso.client_id }}" + disable_rbac: true + issuer_uri: "{{ include "sso.url" . }}" + scopes: + - openid + - email + username_claim: {{ dig "oidc" "claims" "email" "email" .Values.sso }} + {{- else }} + strategy: token + {{- end }} + external_services: + grafana: + enabled: {{ .Values.grafana.enabled }} + {{- $grafanaUrl := first (dig "istio" "grafana" "hosts" list .Values.grafana.values) }} + url: https://{{ tpl ($grafanaUrl | default (printf "%s.%s" "grafana" $domainName)) . }} + {{- if .Values.grafana.enabled }} + auth: + {{- if (dig "admin" "existingSecret" "" .Values.grafana.values) }} + {{- $userKey := (dig "admin" "userKey" "admin-user" .Values.grafana.values) }} + {{- with lookup "v1" "Secret" "monitoring" .Values.grafana.values.admin.existingSecret }} + username: {{ (get .data $userKey | b64dec) | default "admin" }} + {{- end }} + {{- else }} + username: {{ dig "adminUser" "admin" .Values.grafana.values }} + {{- end }} + password: "secret:grafana-auth:password" + {{- end }} + tracing: + {{- $tempoQueryEnabled := (dig "tempoQuery" "enabled" false .Values.tempo.values) }} + enabled: {{ or (and .Values.tempo.enabled $tempoQueryEnabled) .Values.jaeger.enabled }} + {{- if and $tempoQueryEnabled (not .Values.jaeger.enabled) }} + in_cluster_url: "http://tempo-tempo.tempo.svc.cluster.local:16686" + {{- $tracingUrl := first (dig "istio" "tempoQuery" "hosts" list .Values.tempo.values) }} + url: https://{{ tpl ($tracingUrl | default (printf "%s.%s" "tracing" $domainName )) . }} + {{- else}} + {{- $tracingUrl := first (dig "istio" "jaeger" "hosts" list .Values.jaeger.values) }} + url: https://{{ tpl ($tracingUrl | default (printf "%s.%s" "tracing" $domainName )) . }} + {{- end }} + istio: + component_status: + components: + - app_label: istiod + is_core: true + is_proxy: false + {{- range $name, $values := .Values.istio.ingressGateways }} + {{ if ne $values.enabled false }} + - app_label: {{ $name }} + is_core: true + is_proxy: true + {{- end }} + {{- end }} + {{- range $name, $values := .Values.istio.values.ingressGateways }} + {{ if ne $values.enabled false }} + - app_label: {{ $name }} + is_core: true + is_proxy: true + {{- end }} + {{- end }} + api: + namespaces: + # bigbang watches all! + exclude: [] +networkPolicies: + enabled: {{ .Values.networkPolicies.enabled }} + controlPlaneCidr: {{ .Values.networkPolicies.controlPlaneCidr }} + ingressLabels: + {{- $gateway := default "public" .Values.kiali.ingress.gateway }} + {{- $default := dict "app" (dig "gateways" $gateway "ingressGateway" nil .Values.istio) "istio" nil }} + {{- toYaml (dig "values" "gateways" $gateway "selector" $default .Values.istio) | nindent 4 }} +{{- end -}} diff --git a/chart/templates/kyverno-policies/git-credentials.yaml b/chart/templates/kyverno-policies/git-credentials.yaml new file mode 100644 index 0000000000000000000000000000000000000000..6819b8f70ee6dee5393e59c1e93aaf876d0f0271 --- /dev/null +++ b/chart/templates/kyverno-policies/git-credentials.yaml @@ -0,0 +1,7 @@ +{{- $gitCredsSecretDict := dict + "name" "kyvernoPolicies" + "targetScope" .Values.kyvernoPolicies + "releaseName" .Release.Name + "releaseNamespace" .Release.Namespace +}} +{{- include "gitCredsSecret" $gitCredsSecretDict | nindent 0 -}} diff --git a/chart/templates/kyverno-policies/gitrepository.yaml b/chart/templates/kyverno-policies/gitrepository.yaml new file mode 100644 index 0000000000000000000000000000000000000000..03daab4357a6adf8772e9b54d1b6ca2bbd17d3f5 --- /dev/null +++ b/chart/templates/kyverno-policies/gitrepository.yaml @@ -0,0 +1,24 @@ +{{- $pkg := "kyvernoPolicies" }} +{{- if and (eq (get .Values $pkg).sourceType "git") (get .Values $pkg).enabled }} +{{- $gitCredsDict := dict + "name" $pkg + "packageGitScope" (get .Values $pkg).git + "rootScope" . + "releaseName" .Release.Name +}} +apiVersion: source.toolkit.fluxcd.io/v1 +kind: GitRepository +metadata: + name: {{ $pkg | kebabcase }} + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ $pkg | kebabcase }} + {{- include "commonLabels" . | nindent 4}} +spec: + interval: {{ .Values.flux.interval }} + url: {{ (get .Values $pkg).git.repo }} + ref: + {{- include "validRef" (get .Values $pkg).git | nindent 4 }} + {{ include "gitIgnore" . }} + {{- include "gitCredsExtended" $gitCredsDict | nindent 2 }} +{{- end }} \ No newline at end of file diff --git a/chart/templates/kyverno-policies/helmrelease.yaml b/chart/templates/kyverno-policies/helmrelease.yaml new file mode 100644 index 0000000000000000000000000000000000000000..271b6c4f8b2616addc0e2a73a362b45968a47182 --- /dev/null +++ b/chart/templates/kyverno-policies/helmrelease.yaml @@ -0,0 +1,60 @@ +{{- $pkg := "kyvernoPolicies" }} +{{- $fluxSettings := merge .Values.kyvernoPolicies.flux .Values.flux -}} +{{- if (get .Values $pkg).enabled }} +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + name: {{ $pkg | kebabcase }} + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ $pkg | kebabcase }} + {{- include "commonLabels" . | nindent 4}} + annotations: + checksum/bigbang-values: {{ include (print $.Template.BasePath "/kyverno-policies/values.yaml") . | sha256sum }} +spec: + targetNamespace: kyverno + chart: + spec: + {{- if (eq (get .Values $pkg).sourceType "git") }} + chart: {{ (get .Values $pkg).git.path }} + sourceRef: + kind: GitRepository + name: {{ $pkg | kebabcase }} + namespace: {{ .Release.Namespace }} + {{- else }} + chart: {{ (get .Values $pkg).helmRepo.chartName }} + version: {{ (get .Values $pkg).helmRepo.tag }} + sourceRef: + kind: HelmRepository + name: {{ (get .Values $pkg).helmRepo.repoName }} + namespace: {{ .Release.Namespace }} + {{- $repoType := include "getRepoType" (dict "repoName" (get .Values $pkg).helmRepo.repoName "allRepos" $.Values.helmRepositories) -}} + {{- if (and (get .Values $pkg).helmRepo.cosignVerify (eq $repoType "oci")) }} # Needs to be an OCI repo + verify: + provider: cosign + secretRef: + name: {{ printf "%s-cosign-pub" (get .Values $pkg).helmRepo.repoName }} + {{- end }} + {{- end }} + interval: 5m + + {{- toYaml $fluxSettings | nindent 2 }} + + {{- if (get .Values $pkg).postRenderers }} + postRenderers: + {{ toYaml (get .Values $pkg).postRenderers | nindent 4 }} + {{- end }} + valuesFrom: + - name: {{ .Release.Name }}-{{ $pkg | kebabcase }}-values + kind: Secret + valuesKey: "common" + - name: {{ .Release.Name }}-{{ $pkg | kebabcase }}-values + kind: Secret + valuesKey: "defaults" + - name: {{ .Release.Name }}-{{ $pkg | kebabcase }}-values + kind: Secret + valuesKey: "overlays" + dependsOn: + - name: kyverno + namespace: {{ .Release.Namespace }} +{{- end }} diff --git a/chart/templates/kyverno-policies/values.yaml b/chart/templates/kyverno-policies/values.yaml new file mode 100644 index 0000000000000000000000000000000000000000..6b609bcfe10bc266f428db7192376f6586fd1d64 --- /dev/null +++ b/chart/templates/kyverno-policies/values.yaml @@ -0,0 +1,1075 @@ +{{- $pkg := "kyvernoPolicies" }} + +{{- if (get .Values $pkg).enabled }} +{{- include "values-secret" (dict "root" $ "package" (dict "values" (fromYaml (include "bigbang.overlays.kyverno-policies" .))) "name" "kyverno-policies" "defaults" (include "bigbang.defaults.kyverno-policies" .)) }} +{{- end }} + +{{- define "bigbang.defaults.kyverno-policies" -}} + +{{- $deployNodeAgent := (and .Values.addons.velero.enabled (dig "deployNodeAgent" false .Values.addons.velero.values)) }} + +waitforready: + imagePullSecrets: + - name: private-registry + +policies: + + {{- if or .Values.twistlock.enabled .Values.neuvector.enabled }} + disallow-host-namespaces: + exclude: + any: + {{- if .Values.twistlock.enabled }} + # Twistlock, by default, does its own network monitoring. hostNetworking is enabled by default for this purpose + # With hostNetworking enabled, Istio sidecar injection is disabled. If this function is disabled, Twistlock will + # not be able to self monitor. If both Istio sidecar injection and TL monitoring are disabled, a security gap will + # be created for network monitoring in Twistlock. So, it is important to make sure at least one is enabled. + - resources: + namespaces: + - twistlock + names: + - twistlock-defender-ds* + {{- end }} + {{- if .Values.neuvector.enabled }} + # Neuvector needs access to host to inspect network traffic + - resources: + namespaces: + - neuvector + names: + - neuvector-enforcer-pod* + {{- end }} + {{- end }} + + {{- $nodePortIngressGateways := list }} + {{- range $name, $values := .Values.istio.ingressGateways }} + {{- if eq $values.type "NodePort" }} + {{- $nodePortIngressGateways = append $nodePortIngressGateways $name }} + {{- end }} + {{- end }} + + {{- range $name, $values := .Values.istio.values.ingressGateways }} + {{- if eq (dig "k8s" "service" "type" "LoadBalancer" $values) "NodePort" }} + {{- $nodePortIngressGateways = append $nodePortIngressGateways $name }} + {{- end }} + {{- end }} + + # Istio services (istio ingress) can create type: NodePort services + disallow-nodeport-services: + validationFailureAction: Enforce + {{- if $nodePortIngressGateways }} + exclude: + any: + - resources: + kinds: + - Service + names: + {{- range $name := $nodePortIngressGateways }} + - {{ $name }} + {{- end }} + namespaces: + - "istio-system" + {{- end }} + + disallow-image-tags: + enabled: true + validationFailureAction: Enforce + + disallow-istio-injection-bypass: + enabled: {{ .Values.istio.enabled }} + exclude: + any: + # Istio does not inject itself + - resources: + namespaces: + - istio-system + + disallow-namespaces: + enabled: true + validationFailureAction: Enforce + parameters: + disallow: + - bigbang + - default + + {{- if or .Values.fluentbit.enabled .Values.neuvector.enabled}} + disallow-privileged-containers: + exclude: + any: + {{- if .Values.fluentbit.enabled }} + # NEEDS FURTHER JUSTIFICATION + # Fluentbit needs privileged to read and store the buffer for tailing logs from the nodes + - resources: + namespaces: + - fluentbit + names: + - fluentbit-fluent-bit* + {{- end }} + {{- if .Values.neuvector.enabled }} + # Neuvector needs privileged access for realtime scanning of files from the node / access to the container runtime + - resources: + namespaces: + - neuvector + names: + - neuvector-enforcer-pod* + - neuvector-controller-pod* + - neuvector-scanner-pod* + {{- end }} + {{- end }} + + # -- Prevent Automounting of Kubernetes API Credentials on Pods and Service Accounts + disallow-auto-mount-service-account-token: + enabled: true + validationFailureAction: Audit + exclude: + any: + {{- if .Values.kyvernoReporter.enabled }} + - resources: + namespaces: + - kyverno-reporter + kinds: + - Pod + - Deployment + names: + - kyverno-reporter* + {{- end }} + {{- if .Values.monitoring.enabled }} + - resources: + namespaces: + - flux-system + kinds: + - Pod + - Deployment + - StatefulSet + names: + - notification-controller* + - helm-controller* + - source-controller* + - kustomize-controller* + {{- end }} + {{- if .Values.addons.thanos.enabled }} + - resources: + namespaces: + - thanos + kinds: + - Pod + - Deployment + - StatefulSet + names: + - thanos-compactor* + {{- end }} + {{- if .Values.addons.externalSecrets.enabled }} + - resources: + namespaces: + - external-secrets + names: + - external-secrets* + {{- end }} + + {{- if or .Values.fluentbit.enabled .Values.monitoring.enabled .Values.twistlock.enabled }} + disallow-tolerations: + exclude: + any: + {{- if .Values.fluentbit.enabled }} + # Fluent bit needs to be able to run on all nodes to gather logs from the host for containers + - resources: + namespaces: + - fluentbit + names: + - fluentbit-fluent-bit* + {{- end }} + {{- if .Values.monitoring.enabled }} + # Prometheus Node Exporter needs to be able to run on all nodes, regardless of taint, to gather node metrics + - resources: + namespaces: + - monitoring + names: + - monitoring-monitoring-prometheus-node-exporter* + {{- end }} + {{- if .Values.twistlock.enabled }} + # In order to provide real-time scanning of all nodes, Twistlock must ignore taints + - resources: + namespaces: + - twistlock + names: + - twistlock-defender-ds* + {{- end }} + {{- end }} + + require-drop-all-capabilities: + validationFailureAction: Enforce + exclude: + any: + {{- if .Values.neuvector.enabled }} + # Neuvector needs access to host to inspect network traffic + - resources: + namespaces: + - neuvector + names: + - neuvector-enforcer-pod* + - neuvector-cert-upgrader-job-* + - neuvector-controller-pod* + - neuvector-scanner-pod* + - neuvector-prometheus-exporter-pod* + {{- end }} + {{- if .Values.addons.holocron.enabled }} + - resources: + namespaces: + - holocron + names: + - holocron-postgresql-0 + {{- end }} + {{- if .Values.addons.velero.enabled }} + - resources: + namespaces: + - velero + names: + - velero-backup-restore-test* + {{- end }} + {{- if .Values.addons.gitlabRunner.enabled }} + - resources: + namespaces: + - gitlab-runner + names: + - runner-* + {{- end }} + {{- if .Values.addons.gitlab.enabled }} + - resources: + namespaces: + - gitlab + names: + - webservice-test-runner-* + {{- end }} + {{- if .Values.twistlock.enabled }} + - resources: + namespaces: + - twistlock + names: + - twistlock-defender-ds* + - volume-upgrade* + {{- end }} + + # Kyverno Beta feature - https://kyverno.io/docs/writing-policies/verify-images/ + require-image-signature: + enabled: false + validationFailureAction: Audit + + require-labels: + enabled: true + validationFailureAction: Audit + parameters: + require: + - app.kubernetes.io/name + - app.kubernetes.io/version + + require-istio-on-namespaces: + enabled: {{ .Values.istio.enabled }} + exclude: + any: + - resources: + namespaces: + # Kuberentes control plane does not use Istio + - kube-node-lease + - kube-public + - kube-system + # No pods in bigbang / default + - bigbang + - default + # Flux is installed prior to Istio + - flux-system + # Istio does not inject itself + - istio-operator + - istio-system + + require-non-root-group: + validationFailureAction: Enforce + {{ if .Values.istio.enabled }} + parameters: + excludeContainers: + - istio-init + {{ if not .Values.addons.holocron.database.host }} + - init-chmod-data + {{- end }} + {{ else if not .Values.addons.holocron.database.host }} + parameters: + excludeContainers: + - init-chmod-data + {{- end }} + {{- if or $deployNodeAgent .Values.twistlock.enabled .Values.fluentbit.enabled .Values.promtail.enabled .Values.neuvector.enabled }} + exclude: + any: + - resources: + namespaces: + - kube-system + {{- if $deployNodeAgent }} + # Velero. The node agent backup tool requires root group access to see the host's runtime pod directory which is + # mounted inside velero/node agent pods. + - resources: + namespaces: + - velero + names: + - node-agent* + {{- end }} + {{- if .Values.twistlock.enabled }} + # Twistlock Defenders run as root to perform real time scanning on the nodes/cluster, including: + # - read logs from `/var/log` to watch for malicious processes + # - audit modifications to `/etc/passwd` (watching for suspicious changes) + # - access the container runtime socket (observing all running containers on a node) + - resources: + namespaces: + - twistlock + names: + - twistlock-defender-ds* + - volume-upgrade-job* + {{- end }} + # For GitLab runner CI jobs that require root access + {{- if .Values.addons.gitlabRunner.enabled }} + - resources: + namespaces: + - gitlab-runner + names: + - runner-* + {{- end }} + {{- if .Values.fluentbit.enabled }} + # Fluentbit requires access to journalctl as well as /var/log. This would require modifications + # to the host operating system, creating a user, adding that user to the systemd-journal user group + # and then granting permissions recursively on /var/log. + - resources: + namespaces: + - fluentbit + names: + - fluentbit-fluent-bit* + {{- end }} + {{- if .Values.promtail.enabled }} + # promtail requires access to journalctl as well as /var/log. This would require modifications + # to the host operating system, creating a user, adding that user to the systemd-journal user group + # and then granting permissions recursively on /var/log. + # promtail requires access to /run/promtail for its buffering and persistent state. + - resources: + namespaces: + - promtail + names: + - promtail-promtail* + {{- end }} + {{- if .Values.neuvector.enabled }} + # neuvector enforcers run as root to perform real time scanning on the nodes/cluster + - resources: + namespaces: + - neuvector + names: + - neuvector-enforcer-pod-* + - neuvector-controller-pod-* + - neuvector-cert-upgrader-job-* + {{- end }} + {{- end }} + + require-non-root-user: + validationFailureAction: Enforce + {{ if .Values.istio.enabled }} + parameters: + excludeContainers: + - istio-init + {{ if not .Values.addons.holocron.database.host }} + - init-chmod-data + {{- end }} + {{ else if not .Values.addons.holocron.database.host }} + parameters: + excludeContainers: + - init-chmod-data + {{- end }} + exclude: + any: + - resources: + namespaces: + - kube-system + {{- if or $deployNodeAgent .Values.twistlock.enabled .Values.fluentbit.enabled .Values.promtail.enabled .Values.kiali.enabled .Values.neuvector.enabled}} + {{- if .Values.kiali.enabled }} + # Kiali needs exception for operator to deploy Kiali server + - resources: + namespaces: + - kiali + names: + - kiali-* + {{- end }} + {{- if .Values.neuvector.enabled }} + # Neuvector needs privileged access for realtime scanning of files from the node / access to the container runtime + - resources: + namespaces: + - neuvector + names: + - neuvector* + {{- end }} + {{- if $deployNodeAgent }} + # Velero. The node agent backup tool requires root user access to the host's runtime pod directory which is + # mounted inside velero/node agent pods. + - resources: + namespaces: + - velero + names: + - node-agent* + {{- end }} + # For GitLab runner CI jobs that require root access + {{- if .Values.addons.gitlabRunner.enabled }} + - resources: + namespaces: + - gitlab-runner + names: + - runner-* + {{- end }} + {{- if .Values.twistlock.enabled }} + # Twistlock Defenders run as root to perform real time scanning on the nodes/cluster, including: + # - read logs from `/var/log` to watch for malicious processes + # - audit modifications to `/etc/passwd` (watching for suspicious changes) + # - access the container runtime socket (observing all running containers on a node) + - resources: + namespaces: + - twistlock + names: + - twistlock-defender-ds* + - volume-upgrade-job* + {{- end }} + {{- if .Values.fluentbit.enabled }} + # Fluentbit requires access to journalctl as well as /var/log. This would require modifications + # to the host operating system, creating a user, adding that user to the systemd-journal user group + # and then granting permissions recursively on /var/log. + - resources: + namespaces: + - fluentbit + names: + - fluentbit-fluent-bit* + {{- end }} + {{- if .Values.promtail.enabled }} + # promtail requires access to journalctl as well as /var/log. This would require modifications + # to the host operating system, creating a user, adding that user to the systemd-journal user group + # and then granting permissions recursively on /var/log. + # promtail requires access to /run/promtail for its buffering and persistent state. + - resources: + namespaces: + - promtail + names: + - promtail-promtail* + {{- end }} + {{- end }} + + {{- if .Values.twistlock.enabled }} + restrict-apparmor: + exclude: + any: + # NEEDS FURTHER JUSTIFICATION + # Twistlock Defenders use an `unconfined` appArmor profile. + - resources: + namespaces: + - twistlock + names: + - twistlock-defender-ds* + {{- end }} + + restrict-capabilities: + validationFailureAction: Enforce + # NEEDS FURTHER JUSTIFICATION + # Twistlock Defenders require the following capabilities + # - NET_ADMIN - Process monitoring and Iptables + # - NET_RAW - Iptables (CNNF, runtime DNS, WAAS) See https://bugzilla.redhat.com/show_bug.cgi?id=1895032 + # - SYS_ADMIN - filesystem monitoring + # - SYS_PTRACE - local audit monitoring + # - SYS_CHROOT - changing mount namespace using setns + # - MKNOD - Create special files using mknod, used by docker-less registry scanning + # - SETFCAP - Set file capabilties, used by docker-less registry scanning + # - IPC_LOCK + # {{- if .Values.twistlock.enabled }} + # exclude: + # any: + # - resources: + # namespaces: + # - twistlock + # names: + # - twistlock-defender-ds* + # {{- end }} + parameters: + allow: + # Defaults from https://kubernetes.io/docs/concepts/security/pod-security-standards/#restricted + - NET_BIND_SERVICE + {{- if .Values.istio.enabled }} + # Istio requires NET_ADMIN and NET_RAW for sidecar init: https://istio.io/latest/docs/ops/deployment/requirements/#pod-requirements + # It uses these permissions to setup iptables for network routing + # Cannot create exclusion since sidecar is injected in most containers, so allow the capabilities globally + - NET_ADMIN + - NET_RAW + {{- end }} + {{- if .Values.twistlock.enabled }} + # Twistlock Defenders run as root to perform real time scanning on the nodes/cluster, including: + # - read logs from `/var/log` to watch for malicious processes + # - audit modifications to `/etc/passwd` (watching for suspicious changes) + # - access the container runtime socket (observing all running containers on a node) + exclude: + any: + - resources: + namespaces: + - twistlock + names: + - twistlock-defender-ds* + {{- end }} + + restrict-host-path-mount: + validationFailureAction: Enforce + {{- if or .Values.fluentbit.enabled .Values.monitoring.enabled .Values.promtail.enabled .Values.twistlock.enabled .Values.neuvector.enabled $deployNodeAgent }} + exclude: + any: + {{- if .Values.fluentbit.enabled }} + - resources: + namespaces: + - fluentbit + names: + # Fluent Bit mounts the following hostPaths: + # - `/var/log`: to tail node logs (e.g. journal) and pod logs + # - `/var/lib/docker/containers`: to tail container logs + # - `/etc/machine-id`: to obtain the node's unique machine ID for identifying systemd log folder + # - `/var/log/flb-storage`: for Fluent Bit's buffering and persistent state + # Since logs can have sensitive information, it is better to exclude + # FluentBit from the policy than add the paths as allowable mounts + - fluentbit-fluent-bit* + {{- end }} + {{- if .Values.promtail.enabled }} + # Promtail mounts the following hostPaths: + # - `/var/log/pods`: to tail pod logs + # - `/var/lib/docker/containers`: to tail container logs + # - `/run/promtail`: for Promtail's buffering and persistent state + # Since logs can have sensitive information, it is better to exclude + # Promtail from the policy than add the paths as allowable mounts + - resources: + namespaces: + - promtail + names: + - promtail-promtail* + {{- end }} + {{- if .Values.monitoring.enabled }} + # Prometheus Node Exporter mounts the following hostPaths: + # - `/`: monitor disk usage on filesystem mounts using e2fs call + # - `/proc` and `/sys`: gather node metrics + # Since mounting the root would expose sensitive information, it is better to + # exlcude Prometheus Node Exporter than add the paths as allowable mounts + - resources: + namespaces: + - monitoring + names: + - monitoring-monitoring-prometheus-node-exporter* + {{- end }} + {{- if .Values.twistlock.enabled }} + # NEEDS FURTHER JUSTIFICATION + # Twistlock mounts the following hostPaths: + # - `/dev/log`: writing twistlock logs to syslog socket on node (if enabled) + # - `/var/lib/twistlock`: data folder reserved for twistlock + # - `/etc/passwd`: audits changes to passwd file + # - `/var/run`: communication to docker daemon + # - `/var/lib/containers`: Container images data from CRI + # - `/var/run/docker/netns`: Docker's Network Namespace + # - `/var/log/audit`: Audit logs + # Because the mounts are dynamically created for defenders at runtime, we cannot + # anticipate all of the paths it may mount and must exclude it from the policy + - resources: + namespaces: + - twistlock + names: + - twistlock-defender-ds* + {{- end }} + {{- if .Values.neuvector.enabled }} + # Neuvector mounts the following hostPaths: + # `/var/neuvector`: for Neuvector's buffering and persistent state + # `/var/run`: communication to docker daemon + # `/proc`: monitoring of proccesses for malicious activity + # `/sys/fs/cgroup`: important files the controller wants to monitor for malicious content + - resources: + namespaces: + - neuvector + names: + - neuvector-enforcer-pod* + - neuvector-cert-upgrader-job-* + - neuvector-controller-pod* + {{- end }} + {{- if $deployNodeAgent }} + # Velero. The node agent backup tool requires root user access to the host's runtime pod directory which is + # mounted inside velero/node agent pods. Since the host's pod runtime directory may expose sensitive information, + # it is better to exclude the node agent pods than to add the path as allowable mounts + - resources: + namespaces: + - velero + names: + - node-agent* + {{- end }} + {{- end }} + + # NOTE: This restricts the ability to have PVCs when using a local path provisioner storage class (i.e. k3d default). + # To override either disable this policy (not ideal) or add an allowed wildcard matching where local paths are provisioned. + # See `docs/assets/configs/example/policy-overrides-k3d.yaml` for an example of how to do this for k3d. + restrict-host-path-mount-pv: + validationFailureAction: Enforce + + restrict-host-path-write: + validationFailureAction: Enforce + {{- if or .Values.neuvector.enabled .Values.twistlock.enabled }} + exclude: + any: + # NEEDS FURTHER JUSTIFICATION + # Twistlock mounts the following hostPaths as writable: + # - `/dev/log`: writing twistlock logs to syslog socket on node (if enabled) + # - `/var/lib/twistlock`: data folder reserved for twistlock + # - `/run` or `/var/run`: communication to docker daemon and IP tables + # - `/var/lib/containers`: Container images data from CRI + # - `/var/log/audit`: Audit logs + # Because the mounts are dynamically created for defenders at runtime, we cannot + # anticipate all of the paths it may mount and must exclude it from the policy + {{- if .Values.twistlock.enabled }} + - resources: + namespaces: + - twistlock + names: + - twistlock-defender-ds* + {{- end }} + {{- if .Values.neuvector.enabled }} + # Neuvector mounts the following hostPaths as writeable: + # `/var/neuvector`: for Neuvector's buffering and persistent state + - resources: + namespaces: + - neuvector + names: + - neuvector-controller-pod* + - neuvector-enforcer-pod* + {{- end }} + {{- end }} + {{- if or .Values.fluentbit.enabled .Values.promtail.enabled }} + parameters: + allow: + {{- if .Values.fluentbit.enabled }} + # FluentBit - `/var/log/flb-storage`: fluent bit buffering and persistent state + - /var/log/flb-storage/ + # FluentBit - `/var/log` + # NO JUSTIFICATION - Issue opened at https://repo1.dso.mil/big-bang/product/packages/fluentbit/-/issues/31 + # Temporarily added so policy could be enforced + - /var/log + {{- end }} + {{- if .Values.promtail.enabled }} + # Promtail - `/run/promtail`: promtail buffering and persistent state + - /run/promtail + {{- end }} + {{- end }} + + restrict-image-registries: + validationFailureAction: Enforce + parameters: + allow: + - registry1.dso.mil + - registry.dso.mil + + {{- if or .Values.fluentbit.enabled .Values.promtail.enabled .Values.twistlock.enabled }} + restrict-selinux-type: + exclude: + any: + {{- if .Values.fluentbit.enabled }} + - resources: + namespaces: + - fluentbit + names: + # NEEDS FURTHER JUSTIFICATION + # FluentBit needs selinux option type spc_t + - fluentbit-fluent-bit* + {{- end }} + {{- if .Values.promtail.enabled }} + - resources: + namespaces: + - promtail + names: + # NEEDS FURTHER JUSTIFICATION + # Promtail needs selinux option type spc_t + - promtail-promtail* + {{- end }} + {{- if .Values.twistlock.enabled }} + # NEEDS FURTHER JUSTIFICATION + # Twistlock Defenders need selinux option type spc_t + - resources: + namespaces: + - twistlock + names: + - twistlock-defender-ds* + {{- end }} + {{- end }} + + {{- if $deployNodeAgent }} + restrict-user-id: + exclude: + any: + {{- if $deployNodeAgent }} + # Velero. The node agent backup tool requires root user access to the host's runtime pod directory which is + # mounted inside velero/node agent pods. + - resources: + namespaces: + - velero + names: + - node-agent* + {{- end }} + {{- end }} + + {{- if or .Values.fluentbit.enabled .Values.monitoring.enabled .Values.promtail.enabled .Values.twistlock.enabled .Values.neuvector.enabled $deployNodeAgent }} + restrict-volume-types: + exclude: + any: + {{- if or .Values.fluentbit.enabled }} + - resources: + namespaces: + - fluentbit + names: + # Fluent bit containers requires HostPath volumes, to tail node and container logs. It is also used for buffering + # https://docs.fluentbit.io/manual/pipeline/filters/kubernetes#workflow-of-tail-+-kubernetes-filter + - fluentbit-fluent-bit* + {{- end }} + {{- if .Values.promtail.enabled }} + - resources: + namespaces: + - promtail + names: + # NEEDS FURTHER JUSTIFICATION + # Promtail requires HostPath volume types + # https://github.com/grafana/helm-charts/blob/main/charts/promtail/templates/daemonset.yaml#L120 + - promtail-promtail* + {{- end }} + {{- if .Values.monitoring.enabled }} + # Prometheus node exporter requires a HostPath volume to monitor host metrics in /proc and /sys + - resources: + namespaces: + - monitoring + names: + - monitoring-monitoring-prometheus-node-exporter* + {{- end }} + {{- if .Values.twistlock.enabled }} + # Twistlock requires access to node logs, syslog, and docker daemon for defense monitoring + # https://docs.paloaltonetworks.com/prisma/prisma-cloud/prisma-cloud-admin-compute/audit/logging.html + - resources: + namespaces: + - twistlock + names: + - twistlock-defender-ds* + {{- end }} + {{- if .Values.neuvector.enabled }} + # Neuvector requires HostPath volume types + # Neuvector mounts the following hostPaths: + # `/var/neuvector`: (as writable) for Neuvector's buffering and persistent state + # `/var/run`: communication to docker daemon + # `/proc`: monitoring of proccesses for malicious activity + # `/sys/fs/cgroup`: important files the controller wants to monitor for malicious content + # https://github.com/neuvector/neuvector-helm/blob/master/charts/core/templates/enforcer-daemonset.yaml#L108 + - resources: + namespaces: + - neuvector + names: + - neuvector-enforcer-pod* + - neuvector-controller-pod* + {{- end }} + {{- if $deployNodeAgent }} + # Velero. The node agent backup tool requires root user access to the host's runtime pod directory which is + # mounted inside velero/node agent pods. + - resources: + namespaces: + - velero + names: + - node-agent* + {{- end }} + {{- end }} + + update-automountserviceaccounttokens-default: + enabled: true + namespaces: + - istio-system + - istio-operator + - twistlock + - argocd + - logging + - velero + - minio + - minio-operator + - kyverno-reporter + - kyverno + - velero + - neuvector + - kiali + - harbor + - authservice + - anchore + - fortify + - vault + - promtail + - fluentbit + - eck-operator + - nexus-repository-manager + - thanos + - mattermost + - mattermost-operator + - bigbang + - flux-system + - keycloak + - monitoring + - gitlab + - gitlab-runner + + update-automountserviceaccounttokens: + enabled: true + namespaces: + - namespace: istio-system + pods: + allow: + - istiod-* + - passthrough-ingressgateway-* + - public-ingressgateway-* + - namespace: istio-operator + pods: + allow: + - istiod-* + - istio-operator-* + - namespace: twistlock + pods: + allow: + # twistlock-init pods require get/list/patch/etc to several resources. + # More details in twistlock/chart/templates/init/clusterrole.yaml + - twistlock-init-* + # twistlock-volume-upgrade-job requires patch/get/list/update to deployments and get/list to pods + # More details in twistlock/chart/templates/init/volume-upgrade-role.yaml + - twistlock-volume-upgrade-job + # Twistlock Defender enforces various policies that may involve the K8s cluster itself + # Enforcing said policies requires access to the API to get/list resources + - twistlock-defender-ds-* + # bb-twistlock-upgrade-job requires patch/get/list/update/etc to deployments daemonsets pv's and pvc + # More details in twistlock/chart/templates/bigbang/upgrade-job.yaml + - bb-twistlock-twistlock-upgrade-job-* + - namespace: logging + pods: + allow: + - logging-loki-minio-* + deny: + - logging-ek-es-data* + - logging-ek-es-master* + - logging-ek-kb* + - logging-ek-metrics* + - namespace: minio-operator + pods: + allow: + # console pods require access to several API resources + # More details in minio-operator/chart/templates/console-clusterrole.yaml + - console-* + # operator pods require access to several API resources + # More details in minio-operator/chart/templates/operator-clusterrole.yaml + - minio-operator-* + # tenantPatchJob requires get/list/patch on tenants (minio CRD) + # More details in minio-operator/chart/templates/bigbang/tenant-patch-job.yaml + - bb-minio-operator-minio-operator-tenant-patch + - namespace: minio + pods: + allow: + # tenant pods require get/list/watch on secrets/tenants (CRD), and create/delete/get on services + # More details in role named minio-minio-minio-instance-role + - minio-minio-minio-instance-* + - minio-instance-wait-job-* + - namespace: kyverno + pods: + allow: + - kyverno-reports-controller-* + - kyverno-admission-controller-* + - kyverno-cleanup-controller-* + - kyverno-cleanup-admission-reports-* + - kyverno-admission-controller-* + - kyverno-background-controller-* + - kyverno-admission-controller-* + - kyverno-cleanup-cluster-admission-reports-* + - kyverno-cleanup-cluster-ephemeral-reports-* + - kyverno-cleanup-update-requests-* + - kyverno-clean-reports-* + - namespace: velero + pods: + allow: + - velero-cleanup-crds-* + - velero-velero-* + - node-agent-* + - velero-label-namespace-* + - velero-script-test + - velero-backup-restore-test + - namespace: neuvector + pods: + allow: + - neuvector-manager-pod-* + - neuvector-scanner-pod-* + - neuvector-cert-upgrader-job-* + - neuvector-controller-pod-* + - neuvector-enforcer-pod-* + - neuvector-updater-pod-* + - neuvector-prometheus-exporter-pod-* + - neuvector-registry-adapter-pod-* + - namespace: kiali + pods: + allow: + - kiali-* + - namespace: argocd + pods: + allow: + # application-controller pods interact with secrets, configmaps, events, and Argo CRDs + # More details in argocd/chart/templates/argocd-application-controller/role.yaml + - argocd-argocd-application-controller-* + # dex pods interact with secrets and configmaps + # More details in argocd/chart/templates/dex/role.yaml + - argocd-argocd-dex-server-* + # argocd-upgrade-job interacts with CRDs + # More details in argocd/chart/templates/bigbang/upgrade-job.yaml + - argocd-upgrade-job + # argocd server pods interact with secrets, configmaps, events, and CRDs + # More details in argocd/chart/templates/argocd-server/role.yaml + - argocd-argocd-server-* + # repo server pods require access to the K8s API if using RBAC + # Ref: https://github.com/argoproj/argo-cd/blob/master/docs/operator-manual/rbac.md + - argocd-argocd-repo-server-* + # The applicationSet controller pods interact with many API resources, including CRDs + # More details in argocd/chart/templates/argocd-applicationset/role.yaml + - argocd-argocd-applicationset-controller-* + # notifications controller pods interact with secrets, configmaps, and CRDs + # More details in argocd/chart/templates/argocd-notifications/role.yaml + # Additionally (this wildcard covers both)- + # notifications bot pods interact with secrets, configmaps, and CRDs + # More details in argocd/chart/templates/argocd-notifications/bots/slack/role.yaml + - argocd-argocd-notifications-controller-* + - namespace: harbor + # Omitting the serviceAccount and Pods section forces the policy to apply to + # all of the serviceAccount and Pods in the namespace + - namespace: authservice + pods: + allow: + - authservice-authservice-redis-bb-* + - authservice-haproxy-sso-* + - namespace: monitoring + pods: + allow: + - monitoring-grafana* + - monitoring-monitoring-kube-admission-create-* + - monitoring-monitoring-kube-admission-patch-* + - monitoring-monitoring-kube-state-metrics* + - monitoring-monitoring-kube-operator* + - prometheus-monitoring-monitoring-kube-prometheus* + - monitoring-alloy-* + - namespace: anchore + pods: + allow: + - anchore-ui-redis-* + - namespace: jaeger + pods: + allow: + - jaeger-jaeger-jaeger-operator-* + - jaeger-clean-svc-monitor + - namespace: fortify + # Omitting the serviceAccount and pods section forces the policy to apply to + # all of the serviceAccounts and pods in the namespace + - namespace: vault + pods: + allow: + - vault-vault-* + - vault-vault-agent-injector-* + - vault-vault-job-init-* + - namespace: promtail + pods: + allow: + - promtail-promtail-* + - namespace: fluentbit + pods: + allow: + - fluentbit-fluent-bit-* + - namespace: eck-operator + pods: + allow: + - elastic-operator-* + - namespace: nexus-repository-manager + pods: + allow: + - nexus-repository-manager-* + - namespace: thanos + pods: + allow: + - thanos-minio-* + deny: + - thanos-query-frontend-* + - thanos-storegateway* + - thanos-query* + - namespace: mattermost + pods: + allow: + - default-minio-bucket-creation-* + - mattermost-minio-* + - mattermost-wait-job-* + - namespace: mattermost-operator + pods: + allow: + - mattermost-operator-* + - namespace: keycloak + pods: + allow: + - keycloak-* + - namespace: gitlab + pods: + allow: + - gitlab-shared-secrets* + - namespace: gitlab-runner + pods: + allow: + - gitlab-runner-* + +istio: + enabled: {{ .Values.istio.enabled }} + +{{- end }} + +{{- /* This function merges defaults in lists from above into overlays */ -}} +{{- /* The end user will not have to replicate exclusions/repos from above when providing an overlay */ -}} +{{- /* There is a hidden flag `skipOverlayMerge` that can be added to any policy to ignore the defaults */ -}} +{{- define "bigbang.overlays.kyverno-policies" -}} + {{- $defaults := fromYaml (include "bigbang.defaults.kyverno-policies" .) -}} + {{- $overlays := dig "values" dict .Values.kyvernoPolicies -}} + + {{- /* Global merge for exclude fields */ -}} + {{- if and (dig "exclude" "any" list $defaults) (dig "exclude" "any" list $overlays) -}} + {{ $_ := set $overlays.exclude "any" (concat $defaults.exclude.any $overlays.exclude.any) -}} + {{- end -}} + {{- if and (dig "exclude" "all" list $defaults) (dig "exclude" "all" list $overlays) -}} + {{ $_ := set $overlays.exclude "all" (concat $defaults.exclude.all $overlays.exclude.all) -}} + {{- end -}} + + {{- /* Policy specific merges */ -}} + {{- range $policy, $default := $defaults.policies -}} + {{- $overlay := (dig "policies" $policy dict $overlays) -}} + + {{- /* Only continue if an overlay matches a default constriant and hidden "skipOverlayMerge" is not set */ -}} + {{- if and $overlay (not $overlay.skipOverlayMerge) -}} + + {{- /* Add exclude fields */ -}} + {{- if and (dig "exclude" "any" list $default) (dig "exclude" "any" list $overlay) -}} + {{ $_ := set $overlay.exclude "any" (concat $default.exclude.any $overlay.exclude.any) -}} + {{- end -}} + {{- if and (dig "exclude" "all" list $default) (dig "exclude" "all" list $overlay) -}} + {{ $_ := set $overlay.exclude "all" (concat $default.exclude.all $overlay.exclude.all) -}} + {{- end -}} + + {{- /* Add match fields */ -}} + {{- if and (dig "match" "any" list $default) (dig "match" "any" list $overlay) -}} + {{ $_ := set $overlay.match "any" (concat $default.match.any $overlay.match.any) -}} + {{- end -}} + {{- if and (dig "match" "all" list $default) (dig "match" "all" list $overlay) -}} + {{ $_ := set $overlay.match "all" (concat $default.match.all $overlay.match.all) -}} + {{- end -}} + + {{- /* Add parameters.allow fields */ -}} + {{- if and (dig "parameters" "allow" list $default) (dig "parameters" "allow" list $overlay) -}} + {{ $_ := set $overlay.parameters "allow" (concat $default.parameters.allow $overlay.parameters.allow) -}} + {{- end -}} + + {{- /* Add parameters.disallow fields */ -}} + {{- if and (dig "parameters" "disallow" list $default) (dig "parameters" "disallow" list $overlay) -}} + {{ $_ := set $overlay.parameters "disallow" (concat $default.parameters.disallow $overlay.parameters.disallow) -}} + {{- end -}} + + {{- /* Add parameters.require fields */ -}} + {{- if and (dig "parameters" "require" list $default) (dig "parameters" "require" list $overlay) -}} + {{ $_ := set $overlay.parameters "require" (concat $default.parameters.require $overlay.parameters.require) -}} + {{- end -}} + {{- end -}} + {{- end -}} +{{ toYaml $overlays }} +{{- end }} diff --git a/chart/templates/kyverno-reporter/git-credentials.yaml b/chart/templates/kyverno-reporter/git-credentials.yaml new file mode 100644 index 0000000000000000000000000000000000000000..17078d6d88d76076a192577e5329cda809deac09 --- /dev/null +++ b/chart/templates/kyverno-reporter/git-credentials.yaml @@ -0,0 +1,7 @@ +{{- $gitCredsSecretDict := dict + "name" "kyvernoReporter" + "targetScope" .Values.kyvernoReporter + "releaseName" .Release.Name + "releaseNamespace" .Release.Namespace +}} +{{- include "gitCredsSecret" $gitCredsSecretDict | nindent 0 -}} diff --git a/chart/templates/kyverno-reporter/gitrepository.yaml b/chart/templates/kyverno-reporter/gitrepository.yaml new file mode 100644 index 0000000000000000000000000000000000000000..beb593724c1a86739e211fef9167131bcdad435b --- /dev/null +++ b/chart/templates/kyverno-reporter/gitrepository.yaml @@ -0,0 +1,24 @@ +{{- $pkg := "kyvernoReporter" }} +{{- if and (eq (get .Values $pkg).sourceType "git") (get .Values $pkg).enabled }} +{{- $gitCredsDict := dict + "name" $pkg + "packageGitScope" (get .Values $pkg).git + "rootScope" . + "releaseName" .Release.Name +}} +apiVersion: source.toolkit.fluxcd.io/v1 +kind: GitRepository +metadata: + name: {{ $pkg | kebabcase }} + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ $pkg | kebabcase }} + {{- include "commonLabels" . | nindent 4}} +spec: + interval: {{ .Values.flux.interval }} + url: {{ (get .Values $pkg).git.repo }} + ref: + {{- include "validRef" (get .Values $pkg).git | nindent 4 }} + {{ include "gitIgnore" . }} + {{- include "gitCredsExtended" $gitCredsDict | nindent 2 }} +{{- end }} \ No newline at end of file diff --git a/chart/templates/kyverno-reporter/helmrelease.yaml b/chart/templates/kyverno-reporter/helmrelease.yaml new file mode 100644 index 0000000000000000000000000000000000000000..5e33739c3b3ee1e0bdc9f06dbfc1fad22eb52330 --- /dev/null +++ b/chart/templates/kyverno-reporter/helmrelease.yaml @@ -0,0 +1,72 @@ +{{- $pkg := "kyvernoReporter" }} +{{- $fluxSettings := merge .Values.kyvernoReporter.flux .Values.flux -}} +{{- if (get .Values $pkg).enabled }} +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + name: {{ $pkg | kebabcase }} + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ $pkg | kebabcase }} + {{- include "commonLabels" . | nindent 4}} + annotations: + checksum/bigbang-values: {{ include (print $.Template.BasePath "/kyverno-reporter/values.yaml") . | sha256sum }} +spec: + targetNamespace: kyverno-reporter + chart: + spec: + {{- if (eq (get .Values $pkg).sourceType "git") }} + chart: {{ (get .Values $pkg).git.path }} + sourceRef: + kind: GitRepository + name: {{ $pkg | kebabcase }} + namespace: {{ .Release.Namespace }} + {{- else }} + chart: {{ (get .Values $pkg).helmRepo.chartName }} + version: {{ (get .Values $pkg).helmRepo.tag }} + sourceRef: + kind: HelmRepository + name: {{ (get .Values $pkg).helmRepo.repoName }} + namespace: {{ .Release.Namespace }} + {{- $repoType := include "getRepoType" (dict "repoName" (get .Values $pkg).helmRepo.repoName "allRepos" $.Values.helmRepositories) -}} + {{- if (and (get .Values $pkg).helmRepo.cosignVerify (eq $repoType "oci")) }} # Needs to be an OCI repo + verify: + provider: cosign + secretRef: + name: {{ printf "%s-cosign-pub" (get .Values $pkg).helmRepo.repoName }} + {{- end }} + {{- end }} + interval: 5m + + {{- toYaml $fluxSettings | nindent 2 }} + + {{- if (get .Values $pkg).postRenderers }} + postRenderers: + {{ toYaml (get .Values $pkg).postRenderers | nindent 4 }} + {{- end }} + valuesFrom: + - name: {{ .Release.Name }}-{{ $pkg | kebabcase }}-values + kind: Secret + valuesKey: "common" + - name: {{ .Release.Name }}-{{ $pkg | kebabcase }}-values + kind: Secret + valuesKey: "defaults" + - name: {{ .Release.Name }}-{{ $pkg | kebabcase }}-values + kind: Secret + valuesKey: "overlays" + dependsOn: + - name: kyverno + namespace: {{ .Release.Namespace }} + {{- if .Values.kyvernoPolicies.enabled }} + - name: kyverno-policies + namespace: {{ .Release.Namespace }} + {{- end }} + {{- if .Values.monitoring.enabled }} + - name: monitoring + namespace: {{ .Release.Namespace }} + {{- end }} + {{- if .Values.istio.enabled }} + - name: istio + namespace: {{ .Release.Namespace }} + {{- end }} +{{- end }} diff --git a/chart/templates/kyverno-reporter/imagepullsecret.yaml b/chart/templates/kyverno-reporter/imagepullsecret.yaml new file mode 100644 index 0000000000000000000000000000000000000000..4345c83c77b9b37fb6732c02547f7791bb9b6866 --- /dev/null +++ b/chart/templates/kyverno-reporter/imagepullsecret.yaml @@ -0,0 +1,16 @@ +{{- $pkg := "kyvernoReporter" }} +{{- if (get .Values $pkg).enabled }} +{{- if ( include "imagePullSecret" . ) }} +apiVersion: v1 +kind: Secret +metadata: + name: private-registry + namespace: kyverno-reporter + labels: + app.kubernetes.io/name: {{ $pkg | kebabcase }} + {{- include "commonLabels" . | nindent 4}} +type: kubernetes.io/dockerconfigjson +data: + .dockerconfigjson: {{ template "imagePullSecret" . }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/chart/templates/kyverno-reporter/namespace.yaml b/chart/templates/kyverno-reporter/namespace.yaml new file mode 100644 index 0000000000000000000000000000000000000000..e4dded9b6e67b69769b5cdddc62cf5c7b76a48a0 --- /dev/null +++ b/chart/templates/kyverno-reporter/namespace.yaml @@ -0,0 +1,12 @@ +{{- $pkg := "kyvernoReporter" }} +{{- if (get .Values $pkg).enabled }} +apiVersion: v1 +kind: Namespace +metadata: + labels: + app.kubernetes.io/name: {{ $pkg | kebabcase }} + app.kubernetes.io/component: "core" + {{- include "commonLabels" . | nindent 4}} + istio-injection: {{ ternary "enabled" "disabled" (and .Values.istio.enabled (eq (dig "istio" "injection" "enabled" (get .Values $pkg)) "enabled")) }} + name: kyverno-reporter +{{- end }} \ No newline at end of file diff --git a/chart/templates/kyverno-reporter/values.yaml b/chart/templates/kyverno-reporter/values.yaml new file mode 100644 index 0000000000000000000000000000000000000000..0e01f9ae0dc29b0cdbdeef4b2bdd98b6fd33f5f5 --- /dev/null +++ b/chart/templates/kyverno-reporter/values.yaml @@ -0,0 +1,72 @@ +{{- $pkg := "kyvernoReporter" }} + +{{- if (get .Values $pkg).enabled }} +{{- include "values-secret" (dict "root" $ "package" (get .Values $pkg) "name" ($pkg | kebabcase) "defaults" (include (printf "bigbang.defaults.%s" $pkg | kebabcase) .)) }} +{{- end }} + +{{- define "bigbang.defaults.kyverno-reporter" -}} + +global: + fullnameOverride: kyverno-reporter + +image: + pullPolicy: {{ .Values.imagePullPolicy }} +imagePullSecrets: +- name: private-registry + +{{- if .Values.istio.enabled }} +istio: + enabled: true +podAnnotations: + {{ include "istioAnnotation" . }} +{{- end }} + +kyvernoPlugin: + image: + pullPolicy: {{ .Values.imagePullPolicy }} + imagePullSecrets: + - name: private-registry + {{- if .Values.istio.enabled }} + podAnnotations: + {{ include "istioAnnotation" . }} + {{- end }} + +ui: + image: + pullPolicy: {{ .Values.imagePullPolicy }} + imagePullSecrets: + - name: private-registry + {{- if .Values.istio.enabled }} + podAnnotations: + {{ include "istioAnnotation" . }} + {{- end }} + +monitoring: + enabled: {{ .Values.monitoring.enabled }} + grafana: + namespace: monitoring + {{- if .Values.istio.enabled }} + serviceMonitor: + scheme: https + tlsConfig: + caFile: /etc/prom-certs/root-cert.pem + certFile: /etc/prom-certs/cert-chain.pem + keyFile: /etc/prom-certs/key.pem + insecureSkipVerify: true # Prometheus does not support Istio security naming, thus skip verifying target pod certificate + kyverno: + serviceMonitor: + scheme: https + tlsConfig: + caFile: /etc/prom-certs/root-cert.pem + certFile: /etc/prom-certs/cert-chain.pem + keyFile: /etc/prom-certs/key.pem + insecureSkipVerify: true # Prometheus does not support Istio security naming, thus skip verifying target pod certificate + {{- end }} + +openshift: {{ .Values.openshift }} + +networkPolicies: + enabled: {{ .Values.networkPolicies.enabled }} + controlPlaneCidr: {{ .Values.networkPolicies.controlPlaneCidr }} + +{{- end -}} diff --git a/chart/templates/kyverno/git-credentials.yaml b/chart/templates/kyverno/git-credentials.yaml new file mode 100644 index 0000000000000000000000000000000000000000..94812499245ff4888fe3a5f725e6913b3c0b7466 --- /dev/null +++ b/chart/templates/kyverno/git-credentials.yaml @@ -0,0 +1,7 @@ +{{- $gitCredsSecretDict := dict + "name" "kyverno" + "targetScope" .Values.kyverno + "releaseName" .Release.Name + "releaseNamespace" .Release.Namespace +}} +{{- include "gitCredsSecret" $gitCredsSecretDict | nindent 0 -}} diff --git a/chart/templates/kyverno/gitrepository.yaml b/chart/templates/kyverno/gitrepository.yaml new file mode 100644 index 0000000000000000000000000000000000000000..2f34acd15935f0658b24fd18d7cc5cf87892f53e --- /dev/null +++ b/chart/templates/kyverno/gitrepository.yaml @@ -0,0 +1,24 @@ +{{- if and (eq .Values.kyverno.sourceType "git") (not .Values.offline) (or .Values.kyverno.enabled .Values.kyvernoPolicies.enabled .Values.kyvernoReporter.enabled) }} +{{- $gitCredsDict := dict + "name" "kyverno" + "packageGitScope" .Values.kyverno.git + "rootScope" . + "releaseName" .Release.Name +}} +apiVersion: source.toolkit.fluxcd.io/v1 +kind: GitRepository +metadata: + name: kyverno + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: kyverno + app.kubernetes.io/component: "core" + {{- include "commonLabels" . | nindent 4}} +spec: + interval: {{ .Values.flux.interval }} + url: {{ .Values.kyverno.git.repo }} + ref: + {{- include "validRef" .Values.kyverno.git | nindent 4 }} + {{ include "gitIgnore" . }} + {{- include "gitCredsExtended" $gitCredsDict | nindent 2 }} +{{- end }} diff --git a/chart/templates/kyverno/helmrelease.yaml b/chart/templates/kyverno/helmrelease.yaml new file mode 100644 index 0000000000000000000000000000000000000000..bc85a2f2841ff9f2fd25a3785b25f7908bf89b7b --- /dev/null +++ b/chart/templates/kyverno/helmrelease.yaml @@ -0,0 +1,62 @@ +{{- $fluxSettingskyverno := merge .Values.kyverno.flux .Values.flux -}} +{{- if or .Values.kyverno.enabled .Values.kyvernoPolicies.enabled .Values.kyvernoReporter.enabled }} +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + name: kyverno + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: kyverno + app.kubernetes.io/component: "core" + {{- include "commonLabels" . | nindent 4}} + annotations: + checksum/bigbang-values: {{ include (print $.Template.BasePath "/kyverno/values.yaml") . | sha256sum }} +spec: + targetNamespace: kyverno + chart: + spec: + {{- if eq .Values.kyverno.sourceType "git" }} + chart: {{ .Values.kyverno.git.path }} + sourceRef: + kind: GitRepository + name: kyverno + namespace: {{ .Release.Namespace }} + {{- else }} + chart: {{ .Values.kyverno.helmRepo.chartName }} + version: {{ .Values.kyverno.helmRepo.tag }} + sourceRef: + kind: HelmRepository + name: {{ .Values.kyverno.helmRepo.repoName }} + namespace: {{ .Release.Namespace }} + {{- $repoType := include "getRepoType" (dict "repoName" .Values.kyverno.helmRepo.repoName "allRepos" $.Values.helmRepositories) -}} + {{- if (and .Values.kyverno.helmRepo.cosignVerify (eq $repoType "oci")) }} # Needs to be an OCI repo + verify: + provider: cosign + secretRef: + name: {{ printf "%s-cosign-pub" .Values.kyverno.helmRepo.repoName }} + {{- end }} + {{- end }} + interval: 5m + + {{- toYaml $fluxSettingskyverno | nindent 2 }} + + {{- if .Values.kyverno.postRenderers }} + postRenderers: + {{ toYaml .Values.kyverno.postRenderers | nindent 4 }} + {{- end }} + valuesFrom: + - name: {{ .Release.Name }}-kyverno-values + kind: Secret + valuesKey: "common" + - name: {{ .Release.Name }}-kyverno-values + kind: Secret + valuesKey: "defaults" + - name: {{ .Release.Name }}-kyverno-values + kind: Secret + valuesKey: "overlays" + {{- if .Values.gatekeeper.enabled }} + dependsOn: + - name: gatekeeper + namespace: {{ .Release.Namespace }} + {{- end }} +{{- end }} diff --git a/chart/templates/kyverno/imagepullsecret.yaml b/chart/templates/kyverno/imagepullsecret.yaml new file mode 100644 index 0000000000000000000000000000000000000000..9cfc8793ee1d25fc5a6f33989a1885c8652b6866 --- /dev/null +++ b/chart/templates/kyverno/imagepullsecret.yaml @@ -0,0 +1,16 @@ +{{- if or .Values.kyverno.enabled .Values.kyvernoPolicies.enabled .Values.kyvernoReporter.enabled }} +{{- if ( include "imagePullSecret" . ) }} +apiVersion: v1 +kind: Secret +metadata: + name: private-registry + namespace: kyverno + labels: + app.kubernetes.io/name: kyverno + app.kubernetes.io/component: "core" + {{- include "commonLabels" . | nindent 4}} +type: kubernetes.io/dockerconfigjson +data: + .dockerconfigjson: {{ template "imagePullSecret" . }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/chart/templates/kyverno/namespace.yaml b/chart/templates/kyverno/namespace.yaml new file mode 100644 index 0000000000000000000000000000000000000000..de51adda93e33355ac7969f45b440e08a4a1edae --- /dev/null +++ b/chart/templates/kyverno/namespace.yaml @@ -0,0 +1,11 @@ +{{- if or .Values.kyverno.enabled .Values.kyvernoPolicies.enabled .Values.kyvernoReporter.enabled }} +apiVersion: v1 +kind: Namespace +metadata: + labels: + app.kubernetes.io/name: kyverno + app.kubernetes.io/component: "core" + {{- include "commonLabels" . | nindent 4}} + istio-injection: disabled + name: kyverno +{{- end }} \ No newline at end of file diff --git a/chart/templates/kyverno/values.yaml b/chart/templates/kyverno/values.yaml new file mode 100644 index 0000000000000000000000000000000000000000..de2b9be10b1df5cb25048701844194b32e3319e4 --- /dev/null +++ b/chart/templates/kyverno/values.yaml @@ -0,0 +1,46 @@ +{{- if or .Values.kyverno.enabled .Values.kyvernoPolicies.enabled .Values.kyvernoReporter.enabled }} +{{- include "values-secret" (dict "root" $ "package" .Values.kyverno "name" "kyverno" "defaults" (include "bigbang.defaults.kyverno" .)) }} +{{- end }} + +{{- define "bigbang.defaults.kyverno" -}} +replicaCount: 3 + +image: + pullSecrets: + - name: private-registry + pullPolicy: {{ .Values.imagePullPolicy }} + +openshift: {{ .Values.openshift }} + +networkPolicies: + enabled: {{ .Values.networkPolicies.enabled }} + controlPlaneCidr: {{ .Values.networkPolicies.controlPlaneCidr }} + +serviceMonitor: + enabled: {{ .Values.monitoring.enabled }} + dashboards: + namespace: monitoring + +admissionController: + serviceMonitor: + enabled: {{ .Values.monitoring.enabled }} + +backgroundController: + serviceMonitor: + enabled: {{ .Values.monitoring.enabled }} + +cleanupController: + serviceMonitor: + enabled: {{ .Values.monitoring.enabled }} + +reportsController: + serviceMonitor: + enabled: {{ .Values.monitoring.enabled }} + +grafana: + enabled: {{ .Values.monitoring.enabled }} + namespace: monitoring + +istio: + enabled: {{ .Values.istio.enabled }} +{{- end -}} diff --git a/chart/templates/loki/git-credentials.yaml b/chart/templates/loki/git-credentials.yaml new file mode 100644 index 0000000000000000000000000000000000000000..19988fb425e5ef1764db4d7db640f86de73d7e20 --- /dev/null +++ b/chart/templates/loki/git-credentials.yaml @@ -0,0 +1,7 @@ +{{- $gitCredsSecretDict := dict + "name" "loki" + "targetScope" .Values.loki + "releaseName" .Release.Name + "releaseNamespace" .Release.Namespace +}} +{{- include "gitCredsSecret" $gitCredsSecretDict | nindent 0 -}} diff --git a/chart/templates/loki/gitrepository.yaml b/chart/templates/loki/gitrepository.yaml new file mode 100644 index 0000000000000000000000000000000000000000..c0b176c5a5a9a1d301ac09db1a82cc0fe99836b3 --- /dev/null +++ b/chart/templates/loki/gitrepository.yaml @@ -0,0 +1,24 @@ +{{- if and (eq .Values.loki.sourceType "git") (not .Values.offline) .Values.loki.enabled }} +{{- $gitCredsDict := dict + "name" "loki" + "packageGitScope" .Values.loki.git + "rootScope" . + "releaseName" .Release.Name +}} +apiVersion: source.toolkit.fluxcd.io/v1 +kind: GitRepository +metadata: + name: loki + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: loki + app.kubernetes.io/component: "core" + {{- include "commonLabels" . | nindent 4}} +spec: + interval: {{ .Values.flux.interval }} + url: {{ .Values.loki.git.repo }} + ref: + {{- include "validRef" .Values.loki.git | nindent 4 }} + {{ include "gitIgnore" . }} + {{- include "gitCredsExtended" $gitCredsDict | nindent 2 }} +{{- end }} diff --git a/chart/templates/loki/helmrelease.yaml b/chart/templates/loki/helmrelease.yaml new file mode 100644 index 0000000000000000000000000000000000000000..f8cf82f7a280ffd7e310b2796da7171b683982f0 --- /dev/null +++ b/chart/templates/loki/helmrelease.yaml @@ -0,0 +1,92 @@ +{{- $fluxSettingsLoki := merge .Values.loki.flux .Values.flux -}} +{{- if .Values.loki.enabled }} +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + name: loki + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: loki + app.kubernetes.io/component: "core" + {{- include "commonLabels" . | nindent 4}} + annotations: + checksum/bigbang-values: {{ include (print $.Template.BasePath "/loki/values.yaml") . | sha256sum }} +spec: + driftDetection: + mode: warn + ignore: + - paths: [""] + target: + kind: Tenant + - paths: [""] + target: + kind: Sidecar + releaseName: {{ default "logging-loki" .Values.loki.releaseName }} + targetNamespace: logging + chart: + spec: + {{- if eq .Values.loki.sourceType "git" }} + chart: {{ .Values.loki.git.path }} + sourceRef: + kind: GitRepository + name: loki + namespace: {{ .Release.Namespace }} + {{- else }} + chart: {{ .Values.loki.helmRepo.chartName }} + version: {{ .Values.loki.helmRepo.tag }} + sourceRef: + kind: HelmRepository + name: {{ .Values.loki.helmRepo.repoName }} + namespace: {{ .Release.Namespace }} + {{- $repoType := include "getRepoType" (dict "repoName" .Values.loki.helmRepo.repoName "allRepos" $.Values.helmRepositories) -}} + {{- if (and .Values.loki.helmRepo.cosignVerify (eq $repoType "oci")) }} # Needs to be an OCI repo + verify: + provider: cosign + secretRef: + name: {{ printf "%s-cosign-pub" .Values.loki.helmRepo.repoName }} + {{- end }} + {{- end }} + interval: 5m + + {{- toYaml $fluxSettingsLoki | nindent 2 }} + + {{- if .Values.loki.postRenderers }} + postRenderers: + {{ toYaml .Values.loki.postRenderers | nindent 4 }} + {{- end }} + valuesFrom: + - name: {{ .Release.Name }}-loki-values + kind: Secret + valuesKey: "common" + - name: {{ .Release.Name }}-loki-values + kind: Secret + valuesKey: "defaults" + - name: {{ .Release.Name }}-loki-values + kind: Secret + valuesKey: "overlays" + {{- if or .Values.monitoring.enabled .Values.gatekeeper.enabled .Values.istio.enabled .Values.kyvernoPolicies.enabled }} + dependsOn: + {{- if .Values.monitoring.enabled }} + - name: monitoring + namespace: {{ .Release.Namespace }} + {{- end }} + {{- if .Values.gatekeeper.enabled }} + - name: gatekeeper + namespace: {{ .Release.Namespace }} + {{- end }} + {{- if .Values.istio.enabled }} + - name: istio + namespace: {{ .Release.Namespace }} + {{- end }} + {{- if .Values.kyvernoPolicies.enabled }} + - name: kyverno-policies + namespace: {{ .Release.Namespace }} + {{- end }} + {{- with .Values.loki.objectStorage }} + {{- if and (eq $.Values.loki.strategy "scalable") (not (and .endpoint .bucketNames)) }} + - name: minio-operator + namespace: {{ $.Release.Namespace }} + {{- end }} + {{- end }} + {{- end }} +{{- end }} diff --git a/chart/templates/loki/imagepullsecret.yaml b/chart/templates/loki/imagepullsecret.yaml new file mode 100644 index 0000000000000000000000000000000000000000..095fc277e85cdf4a953bcee58c7ff182a71096c0 --- /dev/null +++ b/chart/templates/loki/imagepullsecret.yaml @@ -0,0 +1,16 @@ +{{- if and .Values.loki.enabled (not .Values.elasticsearchKibana.enabled) }} +{{- if ( include "imagePullSecret" . ) }} +apiVersion: v1 +kind: Secret +metadata: + name: private-registry + namespace: logging + labels: + app.kubernetes.io/name: loki + app.kubernetes.io/component: "core" + {{- include "commonLabels" . | nindent 4}} +type: kubernetes.io/dockerconfigjson +data: + .dockerconfigjson: {{ template "imagePullSecret" . }} +{{- end }} +{{- end }} diff --git a/chart/templates/loki/namespace.yaml b/chart/templates/loki/namespace.yaml new file mode 100644 index 0000000000000000000000000000000000000000..bd0e5687fe0d081ff5e6fc0fa88f856f30eb606a --- /dev/null +++ b/chart/templates/loki/namespace.yaml @@ -0,0 +1,11 @@ +{{- if and .Values.loki.enabled (not .Values.elasticsearchKibana.enabled) }} +apiVersion: v1 +kind: Namespace +metadata: + name: logging + labels: + app.kubernetes.io/name: logging + app.kubernetes.io/component: "core" + {{- include "commonLabels" . | nindent 4}} + istio-injection: {{ ternary "enabled" "disabled" (and .Values.istio.enabled (eq (dig "istio" "injection" "enabled" .Values.loki) "enabled")) }} +{{- end }} diff --git a/chart/templates/loki/values.yaml b/chart/templates/loki/values.yaml new file mode 100644 index 0000000000000000000000000000000000000000..a717f95686183ac03dc6cf01061c8e64130a5620 --- /dev/null +++ b/chart/templates/loki/values.yaml @@ -0,0 +1,168 @@ +{{- if .Values.loki.enabled }} +{{- include "values-secret" (dict "root" $ "package" .Values.loki "name" "loki" "defaults" (include "bigbang.defaults.loki" .)) }} +{{- end }} + +{{- define "bigbang.defaults.loki" -}} +hostname: {{ .Values.hostname }} + +clusterName: "" + +openshift: {{ .Values.openshift }} + +istio: + enabled: {{ .Values.istio.enabled }} + hardened: + enabled: {{ or + (dig "istio" "hardened" "enabled" false .Values.monitoring.values) + (dig "istio" "hardened" "enabled" false .Values.addons.authservice.values) + (dig "hardened" "enabled" false .Values.istio.values) + (dig "istio" "hardened" "enabled" false .Values.grafana.values) + (dig "istio" "hardened" "enabled" false .Values.loki.values) + (dig "istio" "hardened" "enabled" false .Values.eckOperator.values) + (dig "istio" "hardened" "enabled" false .Values.elasticsearchKibana.values) + }} + +imagePullSecrets: + - name: private-registry + +image: + pullPolicy: {{ .Values.imagePullPolicy }} + +networkPolicies: + enabled: {{ .Values.networkPolicies.enabled }} + controlPlaneCidr: {{ .Values.networkPolicies.controlPlaneCidr }} + +monitoring: + enabled: {{ .Values.monitoring.enabled }} + serviceMonitor: + enabled: {{ .Values.monitoring.enabled }} + # conditional passes only for default istio: enabled, mTLS: SCRICT + {{- if and .Values.istio.enabled (eq (dig "istio" "mtls" "mode" "STRICT" .Values.loki.values) "STRICT") }} + scheme: https + tlsConfig: + caFile: /etc/prom-certs/root-cert.pem + certFile: /etc/prom-certs/cert-chain.pem + keyFile: /etc/prom-certs/key.pem + insecureSkipVerify: true # Prometheus does not support Istio security naming, thus skip verifying target pod certificate + {{- end }} + rules: + enabled: true + alerting: true + +{{- $disableDefaultFLB := dig "additionalOutputs" "disableDefault" false .Values.fluentbit.values }} +{{- if and .Values.fluentbit.enabled (not $disableDefaultFLB) }} +fluentbit: + enabled: true +{{- end }} + +{{- if .Values.promtail.enabled }} +promtail: + enabled: true +{{- end }} + +loki: + extraMemberlistConfig: + bind_addr: + - ${MY_POD_IP} + storage: + {{- if (and (eq .Values.loki.strategy "monolith") (not (dig "minio" "enabled" false .Values.loki.values))) }} + type: "filesystem" + {{- else }} + type: "s3" + bucketNames: + {{- toYaml .Values.loki.objectStorage.bucketNames | nindent 6 }} + s3: + endpoint: {{ .Values.loki.objectStorage.endpoint }} + region: {{ .Values.loki.objectStorage.region }} + accessKeyId: {{ .Values.loki.objectStorage.accessKey }} + secretAccessKey: {{ .Values.loki.objectStorage.accessSecret }} + {{- end }} + {{- if (and (eq .Values.loki.strategy "monolith") (not (dig "minio" "enabled" false .Values.loki.values))) }} + rulerConfig: + storage: + type: local + storage_config: + boltdb_shipper: + active_index_directory: /var/loki/boltdb-shipper-active + cache_location: /var/loki/boltdb-shipper-cache + cache_ttl: 24h + filesystem: + directory: /var/loki/chunks + {{- end }} + {{- if .Values.istio.enabled }} + podAnnotations: + {{ include "istioAnnotation" . }} + {{- end }} + +{{- if (eq .Values.loki.strategy "monolith") }} +deploymentMode: SingleBinary +singleBinary: + replicas: 1 + extraArgs: + - -config.expand-env=true + extraEnv: + - name: MY_POD_IP + valueFrom: + fieldRef: + fieldPath: status.podIP +{{- end }} + +{{- if (eq .Values.loki.strategy "scalable") }} +deploymentMode: SimpleScalable +singleBinary: + replicas: 0 +read: + replicas: 3 + extraArgs: + - -config.expand-env=true + extraEnv: + - name: MY_POD_IP + valueFrom: + fieldRef: + fieldPath: status.podIP +write: + replicas: 3 + extraArgs: + - -config.expand-env=true + extraEnv: + - name: MY_POD_IP + valueFrom: + fieldRef: + fieldPath: status.podIP +backend: + replicas: 3 + extraArgs: + - -config.expand-env=true + extraEnv: + - name: MY_POD_IP + valueFrom: + fieldRef: + fieldPath: status.podIP +gateway: + enabled: true + service: + labels: + prometheus.io/service-monitor: "false" + extraArgs: + - -config.expand-env=true + extraEnv: + - name: MY_POD_IP + valueFrom: + fieldRef: + fieldPath: status.podIP +{{- end }} + +{{- with .Values.loki.objectStorage }} +{{- if and (eq $.Values.loki.strategy "scalable") (not (and .endpoint .region)) }} +minio: + enabled: true + +{{- end }} +{{- end }} + +# Allows users to deploy distributed mode but calls out that we do not support it +{{- if (eq .Values.loki.strategy "distributed") }} +deploymentMode: Distributed +{{- end -}} + +{{- end -}} diff --git a/chart/templates/mattermost-operator/git-credentials.yaml b/chart/templates/mattermost-operator/git-credentials.yaml new file mode 100644 index 0000000000000000000000000000000000000000..330f67f74c703bd34375313b67c681591d1e11ea --- /dev/null +++ b/chart/templates/mattermost-operator/git-credentials.yaml @@ -0,0 +1,9 @@ +{{- $mmOpOldValues := default dict .Values.addons.mattermostoperator -}} +{{- $mmOpValues := mergeOverwrite $mmOpOldValues .Values.addons.mattermostOperator -}} +{{- $gitCredsSecretDict := dict + "name" "mattermostOperator" + "targetScope" $mmOpValues + "releaseName" .Release.Name + "releaseNamespace" .Release.Namespace +}} +{{- include "gitCredsSecret" $gitCredsSecretDict | nindent 0 -}} diff --git a/chart/templates/mattermost-operator/gitrepository.yaml b/chart/templates/mattermost-operator/gitrepository.yaml new file mode 100644 index 0000000000000000000000000000000000000000..3a259dfde2d6ce819474b2f7e0bb2ce38f08269b --- /dev/null +++ b/chart/templates/mattermost-operator/gitrepository.yaml @@ -0,0 +1,26 @@ +{{- $mmOpOldValues := default dict .Values.addons.mattermostoperator -}} +{{- $mmOpValues := mergeOverwrite $mmOpOldValues .Values.addons.mattermostOperator -}} +{{- if and (eq $mmOpValues.sourceType "git") (not .Values.offline) (or $mmOpValues.enabled .Values.addons.mattermost.enabled) }} +{{- $gitCredsDict := dict + "name" "mattermostOperator" + "packageGitScope" $mmOpValues.git + "rootScope" . + "releaseName" .Release.Name +}} +apiVersion: source.toolkit.fluxcd.io/v1 +kind: GitRepository +metadata: + name: mattermost-operator + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: mattermost-operator + app.kubernetes.io/component: "collaboration-tools" + {{- include "commonLabels" . | nindent 4}} +spec: + interval: {{ .Values.flux.interval }} + url: {{ $mmOpValues.git.repo }} + ref: + {{- include "validRef" $mmOpValues.git | nindent 4 }} + {{ include "gitIgnore" . }} + {{- include "gitCredsExtended" $gitCredsDict | nindent 2 }} +{{- end }} diff --git a/chart/templates/mattermost-operator/helmrelease.yaml b/chart/templates/mattermost-operator/helmrelease.yaml new file mode 100644 index 0000000000000000000000000000000000000000..a886747b45be61d61d734248a78760f9cca11352 --- /dev/null +++ b/chart/templates/mattermost-operator/helmrelease.yaml @@ -0,0 +1,79 @@ +{{- $mmOpOldValues := default dict .Values.addons.mattermostoperator -}} +{{- $mmOpValues := mergeOverwrite $mmOpOldValues .Values.addons.mattermostOperator -}} +{{- $fluxSettingsMattermostOperator := merge $mmOpValues.flux .Values.flux -}} +{{- if or $mmOpValues.enabled .Values.addons.mattermost.enabled }} +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + name: mattermost-operator + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: mattermost-operator + app.kubernetes.io/component: "collaboration-tools" + {{- include "commonLabels" . | nindent 4}} + annotations: + checksum/bigbang-values: {{ include (print $.Template.BasePath "/mattermost-operator/values.yaml") . | sha256sum }} +spec: + targetNamespace: mattermost-operator + chart: + spec: + {{- if (eq $mmOpValues.sourceType "git") }} + chart: {{ $mmOpValues.git.path }} + sourceRef: + kind: GitRepository + name: mattermost-operator + namespace: {{ .Release.Namespace }} + {{- else }} + chart: {{ $mmOpValues.helmRepo.chartName }} + version: {{ $mmOpValues.helmRepo.tag }} + sourceRef: + kind: HelmRepository + name: {{ $mmOpValues.helmRepo.repoName }} + namespace: {{ .Release.Namespace }} + {{- $repoType := include "getRepoType" (dict "repoName" $mmOpValues.helmRepo.repoName "allRepos" $.Values.helmRepositories) -}} + {{- if (and $mmOpValues.helmRepo.cosignVerify (eq $repoType "oci")) }} # Needs to be an OCI repo + verify: + provider: cosign + secretRef: + name: {{ printf "%s-cosign-pub" $mmOpValues.helmRepo.repoName }} + {{- end }} + {{- end }} + interval: 5m + + {{- toYaml $fluxSettingsMattermostOperator | nindent 2 }} + + {{- if $mmOpValues.postRenderers }} + postRenderers: + {{- toYaml $mmOpValues.postRenderers | nindent 4 }} + {{- end }} + valuesFrom: + - name: {{ .Release.Name }}-mattermost-operator-values + kind: Secret + valuesKey: "common" + - name: {{ .Release.Name }}-mattermost-operator-values + kind: Secret + valuesKey: "defaults" + - name: {{ .Release.Name }}-mattermost-operator-values + kind: Secret + valuesKey: "overlays" + + {{- if or .Values.gatekeeper.enabled .Values.istio.enabled .Values.kyvernoPolicies.enabled .Values.monitoring.enabled }} + dependsOn: + {{- if .Values.gatekeeper.enabled }} + - name: gatekeeper + namespace: {{ .Release.Namespace }} + {{- end }} + {{- if .Values.istio.enabled }} + - name: istio + namespace: {{ .Release.Namespace }} + {{- end }} + {{- if .Values.kyvernoPolicies.enabled }} + - name: kyverno-policies + namespace: {{ .Release.Namespace }} + {{- end }} + {{- if .Values.monitoring.enabled }} + - name: monitoring + namespace: {{ .Release.Namespace }} + {{- end }} + {{- end }} +{{- end }} diff --git a/chart/templates/mattermost-operator/imagepullsecret.yaml b/chart/templates/mattermost-operator/imagepullsecret.yaml new file mode 100644 index 0000000000000000000000000000000000000000..bc3dc82b4460c3bce72567df571e25333e7c21a9 --- /dev/null +++ b/chart/templates/mattermost-operator/imagepullsecret.yaml @@ -0,0 +1,18 @@ +{{- $mmOpOldValues := default dict .Values.addons.mattermostoperator -}} +{{- $mmOpValues := mergeOverwrite $mmOpOldValues .Values.addons.mattermostOperator -}} +{{- if or $mmOpValues.enabled .Values.addons.mattermost.enabled }} +{{- if ( include "imagePullSecret" . ) }} +apiVersion: v1 +kind: Secret +metadata: + name: private-registry + namespace: mattermost-operator + labels: + app.kubernetes.io/name: mattermost-operator + app.kubernetes.io/component: "collaboration-tools" + {{- include "commonLabels" . | nindent 4}} +type: kubernetes.io/dockerconfigjson +data: + .dockerconfigjson: {{ template "imagePullSecret" . }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/chart/templates/mattermost-operator/namespace.yaml b/chart/templates/mattermost-operator/namespace.yaml new file mode 100644 index 0000000000000000000000000000000000000000..21d170cf961f7f2b4523d65494bd06d457ca4da0 --- /dev/null +++ b/chart/templates/mattermost-operator/namespace.yaml @@ -0,0 +1,13 @@ +{{- $mmOpOldValues := default dict .Values.addons.mattermostoperator -}} +{{- $mmOpValues := mergeOverwrite $mmOpOldValues .Values.addons.mattermostOperator -}} +{{- if or $mmOpValues.enabled .Values.addons.mattermost.enabled }} +apiVersion: v1 +kind: Namespace +metadata: + name: mattermost-operator + labels: + istio-injection: {{ ternary "enabled" "disabled" (and .Values.istio.enabled (eq (dig "istio" "injection" "enabled" $mmOpValues) "enabled")) }} + app.kubernetes.io/name: mattermost-operator + app.kubernetes.io/component: "collaboration-tools" + {{- include "commonLabels" . | nindent 4}} +{{- end }} diff --git a/chart/templates/mattermost-operator/values.yaml b/chart/templates/mattermost-operator/values.yaml new file mode 100644 index 0000000000000000000000000000000000000000..0132cabbfcf402efa06b074529b0ba0ca414768a --- /dev/null +++ b/chart/templates/mattermost-operator/values.yaml @@ -0,0 +1,35 @@ +{{- $mmOpOldValues := default dict .Values.addons.mattermostoperator -}} +{{- $mmOpValues := mergeOverwrite $mmOpOldValues .Values.addons.mattermostOperator -}} +{{- if or $mmOpValues.enabled .Values.addons.mattermost.enabled }} +{{- include "values-secret" (dict "root" $ "package" $mmOpValues "name" "mattermost-operator" "defaults" (include "bigbang.defaults.mattermostOperator" .)) }} +{{- end }} + +{{- define "bigbang.defaults.mattermostOperator" -}} +imagePullSecrets: + - name: private-registry + +image: + imagePullPolicy: {{ .Values.imagePullPolicy }} + +{{- if .Values.istio.enabled }} +podAnnotations: + {{ include "istioAnnotation" . }} +{{- end}} + +networkPolicies: + enabled: {{ .Values.networkPolicies.enabled }} + controlPlaneCidr: {{ .Values.networkPolicies.controlPlaneCidr }} + +istio: + enabled: {{ .Values.istio.enabled }} + hardened: + enabled: {{ or + (dig "istio" "hardened" "enabled" false .Values.addons.mattermostOperator.values) + (dig "hardened" "enabled" false .Values.istio.values) + }} + +monitoring: + enabled: {{ .Values.monitoring.enabled }} + +openshift: {{ .Values.openshift }} +{{- end -}} diff --git a/chart/templates/mattermost/git-credentials.yaml b/chart/templates/mattermost/git-credentials.yaml new file mode 100644 index 0000000000000000000000000000000000000000..293e6972292145e2d7ec5cbcd3794162f4eae858 --- /dev/null +++ b/chart/templates/mattermost/git-credentials.yaml @@ -0,0 +1,7 @@ +{{- $gitCredsSecretDict := dict + "name" "mattermost" + "targetScope" .Values.addons.mattermost + "releaseName" .Release.Name + "releaseNamespace" .Release.Namespace +}} +{{- include "gitCredsSecret" $gitCredsSecretDict | nindent 0 -}} diff --git a/chart/templates/mattermost/gitrepository.yaml b/chart/templates/mattermost/gitrepository.yaml new file mode 100644 index 0000000000000000000000000000000000000000..963082c6419f96d9c5476d7b23f72f45b8e07ffc --- /dev/null +++ b/chart/templates/mattermost/gitrepository.yaml @@ -0,0 +1,24 @@ +{{- if and (eq .Values.addons.mattermost.sourceType "git") .Values.addons.mattermost.enabled }} +{{- $gitCredsDict := dict + "name" "mattermost" + "packageGitScope" .Values.addons.mattermost.git + "rootScope" . + "releaseName" .Release.Name +}} +apiVersion: source.toolkit.fluxcd.io/v1 +kind: GitRepository +metadata: + name: mattermost + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: mattermost + app.kubernetes.io/component: "collaboration-tools" + {{- include "commonLabels" . | nindent 4}} +spec: + interval: {{ .Values.flux.interval }} + url: {{ .Values.addons.mattermost.git.repo }} + ref: + {{- include "validRef" .Values.addons.mattermost.git | nindent 4 }} + {{ include "gitIgnore" . }} + {{- include "gitCredsExtended" $gitCredsDict | nindent 2 }} +{{- end }} diff --git a/chart/templates/mattermost/helmrelease.yaml b/chart/templates/mattermost/helmrelease.yaml new file mode 100644 index 0000000000000000000000000000000000000000..407db9c6b3079256ed05a953b4fa1b370d4a1868 --- /dev/null +++ b/chart/templates/mattermost/helmrelease.yaml @@ -0,0 +1,74 @@ +{{- $fluxSettingsMattermost := merge .Values.addons.mattermost.flux .Values.flux -}} +{{- if .Values.addons.mattermost.enabled }} +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + name: mattermost + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: mattermost + app.kubernetes.io/component: "collaboration-tools" + {{- include "commonLabels" . | nindent 4}} + annotations: + checksum/bigbang-values: {{ include (print $.Template.BasePath "/mattermost/values.yaml") . | sha256sum }} +spec: + releaseName: mattermost + targetNamespace: mattermost + chart: + spec: + {{- if eq .Values.addons.mattermost.sourceType "git" }} + chart: {{ .Values.addons.mattermost.git.path }} + sourceRef: + kind: GitRepository + name: mattermost + namespace: {{ .Release.Namespace }} + {{- else }} + chart: {{ .Values.addons.mattermost.helmRepo.chartName }} + version: {{ .Values.addons.mattermost.helmRepo.tag }} + sourceRef: + kind: HelmRepository + name: {{ .Values.addons.mattermost.helmRepo.repoName }} + namespace: {{ .Release.Namespace }} + {{- $repoType := include "getRepoType" (dict "repoName" .Values.addons.mattermost.helmRepo.repoName "allRepos" $.Values.helmRepositories) -}} + {{- if (and .Values.addons.mattermost.helmRepo.cosignVerify (eq $repoType "oci")) }} # Needs to be an OCI repo + verify: + provider: cosign + secretRef: + name: {{ printf "%s-cosign-pub" .Values.addons.mattermost.helmRepo.repoName }} + {{- end }} + {{- end }} + interval: 5m + + {{- toYaml $fluxSettingsMattermost | nindent 2 }} + + {{- if .Values.addons.mattermost.postRenderers }} + postRenderers: + {{ toYaml .Values.addons.mattermost.postRenderers | nindent 4 }} + {{- end }} + valuesFrom: + - name: {{ .Release.Name }}-mattermost-values + kind: Secret + valuesKey: "common" + - name: {{ .Release.Name }}-mattermost-values + kind: Secret + valuesKey: "defaults" + - name: {{ .Release.Name }}-mattermost-values + kind: Secret + valuesKey: "overlays" + + dependsOn: + - name: mattermost-operator + namespace: {{ .Release.Namespace }} + + {{- with .Values.addons.mattermost.objectStorage }} + {{- if not (and .endpoint .accessKey .accessSecret .bucket) }} + - name: minio-operator + namespace: {{ $.Release.Namespace }} + {{- end }} + {{- end }} + + {{- if and .Values.addons.mattermost.elasticsearch.enabled .Values.elasticsearchKibana.enabled }} + - name: ek + namespace: {{ $.Release.Namespace }} + {{- end }} +{{- end }} diff --git a/chart/templates/mattermost/imagepullsecret.yaml b/chart/templates/mattermost/imagepullsecret.yaml new file mode 100644 index 0000000000000000000000000000000000000000..07f038f47419869f29f5ad7e8942844f3713eb69 --- /dev/null +++ b/chart/templates/mattermost/imagepullsecret.yaml @@ -0,0 +1,16 @@ +{{- if .Values.addons.mattermost.enabled }} +{{- if ( include "imagePullSecret" . ) }} +apiVersion: v1 +kind: Secret +metadata: + name: private-registry + namespace: mattermost + labels: + app.kubernetes.io/name: mattermost + app.kubernetes.io/component: "collaboration-tools" + {{- include "commonLabels" . | nindent 4}} +type: kubernetes.io/dockerconfigjson +data: + .dockerconfigjson: {{ template "imagePullSecret" . }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/chart/templates/mattermost/namespace.yaml b/chart/templates/mattermost/namespace.yaml new file mode 100644 index 0000000000000000000000000000000000000000..459cd9d0eebf9097aa6f211d51820ef13e81d6ac --- /dev/null +++ b/chart/templates/mattermost/namespace.yaml @@ -0,0 +1,12 @@ +{{- if .Values.addons.mattermost.enabled }} +apiVersion: v1 +kind: Namespace +metadata: + labels: + app: {{ .Release.Name }}-mattermost + app.kubernetes.io/name: mattermost + app.kubernetes.io/component: "collaboration-tools" + {{- include "commonLabels" . | nindent 4}} + istio-injection: {{ ternary "enabled" "disabled" (and .Values.istio.enabled (eq (dig "istio" "injection" "enabled" .Values.addons.mattermost) "enabled")) }} + name: mattermost +{{- end }} diff --git a/chart/templates/mattermost/secret-ca.yaml b/chart/templates/mattermost/secret-ca.yaml new file mode 100644 index 0000000000000000000000000000000000000000..615f15102aa54649f79df6df530a442f556a8eda --- /dev/null +++ b/chart/templates/mattermost/secret-ca.yaml @@ -0,0 +1,10 @@ +{{- if and .Values.addons.mattermost.enabled .Values.addons.mattermost.sso.enabled (or .Values.sso.certificate_authority (dig "certificateAuthority" "cert" false .Values.sso)) }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ default (dig "certificateAuthority" "secretName" "" .Values.sso) .Values.sso.secretName }} + namespace: mattermost +type: Opaque +data: + ca.pem: {{ default (dig "certificateAuthority" "cert" "" .Values.sso) .Values.sso.certificate_authority | b64enc }} +{{- end }} \ No newline at end of file diff --git a/chart/templates/mattermost/secret-database.yaml b/chart/templates/mattermost/secret-database.yaml new file mode 100644 index 0000000000000000000000000000000000000000..c6271d55b4837ceccfcb5fee37a72a6e0047e4c4 --- /dev/null +++ b/chart/templates/mattermost/secret-database.yaml @@ -0,0 +1,21 @@ +{{- if .Values.addons.mattermost.enabled }} +{{- with .Values.addons.mattermost.database }} +{{- if and .username .password .host .port .database }} +apiVersion: v1 +kind: Secret +type: Opaque +metadata: + name: mattermost-database-secret + namespace: mattermost + labels: + app.kubernetes.io/name: mattermost + app.kubernetes.io/component: "collaboration-tools" + {{- include "commonLabels" $ | nindent 4}} +stringData: + DB_CONNECTION_CHECK_URL: "postgres://{{ .username }}:{{ .password }}@{{ .host }}:{{ .port }}/{{ .database }}?connect_timeout=10&sslmode={{ .ssl_mode | default "disable" }}" + DB_CONNECTION_STRING: "postgres://{{ .username }}:{{ .password }}@{{ .host }}:{{ .port }}/{{ .database }}?connect_timeout=10&sslmode={{ .ssl_mode | default "disable" }}" + username: "{{ .username }}" + password: "{{ .password }}" +{{- end }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/chart/templates/mattermost/secret-objectstore.yaml b/chart/templates/mattermost/secret-objectstore.yaml new file mode 100644 index 0000000000000000000000000000000000000000..4ad85f2255a4ef78e543108f9fbe1952f120735a --- /dev/null +++ b/chart/templates/mattermost/secret-objectstore.yaml @@ -0,0 +1,19 @@ +{{- if .Values.addons.mattermost.enabled }} +{{- with .Values.addons.mattermost.objectStorage }} +{{- if and .endpoint .accessKey .accessSecret .bucket }} +apiVersion: v1 +kind: Secret +type: Opaque +metadata: + name: "mattermost-objectstorage-secret" + namespace: mattermost + labels: + app.kubernetes.io/name: mattermost + app.kubernetes.io/component: "collaboration-tools" + {{- include "commonLabels" $ | nindent 4}} +data: + accesskey: {{ .accessKey | b64enc }} + secretkey: {{ .accessSecret | b64enc }} +{{- end }} +{{- end }} +{{- end }} diff --git a/chart/templates/mattermost/values.yaml b/chart/templates/mattermost/values.yaml new file mode 100644 index 0000000000000000000000000000000000000000..ee7c488af53f68c8b4313028f6a428316624478b --- /dev/null +++ b/chart/templates/mattermost/values.yaml @@ -0,0 +1,167 @@ +{{- if .Values.addons.mattermost.enabled }} +{{- include "values-secret" (dict "root" $ "package" .Values.addons.mattermost "name" "mattermost" "defaults" (include "bigbang.defaults.mattermost" .)) }} +{{- end }} + +{{- define "bigbang.defaults.mattermost" -}} +# hostname is deprecated and replaced with domain. But if hostname exists then use it. +{{- $domainName := default .Values.domain .Values.hostname }} +hostname: {{ $domainName }} +domain: {{ $domainName }} + +openshift: {{ .Values.openshift }} + +image: + imagePullPolicy: {{ .Values.imagePullPolicy }} + +{{ $istioInjection := (and .Values.istio.enabled (eq (dig "istio" "injection" "enabled" .Values.addons.mattermost) "enabled")) }} + +istio: + enabled: {{ .Values.istio.enabled }} + chat: + gateways: + - istio-system/{{ default "public" .Values.addons.mattermost.ingress.gateway }} + injection: {{ ternary "enabled" "disabled" $istioInjection }} + hardened: + enabled: {{ or + (dig "istio" "hardened" "enabled" false .Values.addons.mattermost.values) + (dig "hardened" "enabled" false .Values.istio.values) + }} + clusterAuditor: + enabled: {{ .Values.clusterAuditor.enabled }} + kyvernoReporter: + enabled: {{ .Values.kyvernoReporter.enabled }} + +{{- if $istioInjection }} +podAnnotations: + {{ include "istioAnnotation" . }} +updateJob: + disabled: true +{{- end }} + +monitoring: + enabled: {{ .Values.monitoring.enabled }} + + serviceMonitor: + enabled: {{ .Values.monitoring.enabled }} + # conditional passes only for default istio: enabled, mTLS: STRICT + {{- if and .Values.istio.enabled (eq (dig "istio" "mtls" "mode" "STRICT" .Values.addons.mattermost) "STRICT") }} + scheme: https + tlsConfig: + caFile: /etc/prom-certs/root-cert.pem + certFile: /etc/prom-certs/cert-chain.pem + keyFile: /etc/prom-certs/key.pem + insecureSkipVerify: true # Prometheus does not support Istio security naming, thus skip verifying target pod certificate + {{- end }} + +{{- with .Values.addons.mattermost.sso }} +sso: + enabled: {{ .enabled }} + client_id: {{ .client_id }} + client_secret: {{ .client_secret | default "no-secret" }} + auth_endpoint: {{ default (include "sso.oidc.auth" $) .auth_endpoint }} + token_endpoint: {{ default (include "sso.oidc.token" $) .token_endpoint }} + user_api_endpoint: {{ default (include "sso.oidc.userinfo" $) .user_api_endpoint }} + {{- list "enable_sign_up_with_email" .enable_sign_up_with_email | include "bigbang.addValueIfSet" | indent 2 }} + {{- list "enable_sign_in_with_email" .enable_sign_in_with_email | include "bigbang.addValueIfSet" | indent 2 }} + {{- list "enable_sign_in_with_username" .enable_sign_in_with_username | include "bigbang.addValueIfSet" | indent 2 }} +{{- end }} + +networkPolicies: + enabled: {{ .Values.networkPolicies.enabled }} + controlPlaneCidr: {{ .Values.networkPolicies.controlPlaneCidr }} + ingressLabels: + {{- $gateway := default "public" .Values.addons.mattermost.ingress.gateway }} + {{- $default := dict "app" (dig "gateways" $gateway "ingressGateway" nil .Values.istio) "istio" nil }} + {{- toYaml (dig "values" "gateways" $gateway "selector" $default .Values.istio) | nindent 4 }} + +global: + imagePullSecrets: + - name: private-registry + +{{- with .Values.addons.mattermost.enterprise }} +enterprise: + enabled: {{ .enabled }} + license: {{ .license }} +{{- end }} + +{{- with .Values.addons.mattermost.database }} +{{- if and .username .password .host .port .database }} +database: + secret: "mattermost-database-secret" +postgresql: + secret: "mattermost-database-secret" +{{- else }} +postgresql: + image: + pullSecrets: + - private-registry + {{- if and .username .password .host .port .database }} + secret: "mattermost-database-secret" + {{- else }} + secret: "mattermost-dbcreds" + {{- end }} + install: true + {{- if $istioInjection }} + primary: + podAnnotations: + {{ include "istioAnnotation" $ }} + podSecurityContext: + enabled: true + fsGroup: 1001 + runAsUser: 1001 + runAsGroup: 1001 + containerSecurityContext: + enabled: true + runAsUser: 1001 + runAsGroup: 1001 + runAsNonRoot: true + capabilities: + drop: + - ALL + #permissions for initContainers + volumePermissions: + securityContext: + capabilities: + drop: + - ALL + readReplicas: + podAnnotations: + {{ include "istioAnnotation" $ }} + {{- end }} + +{{- end }} +{{- end }} + +{{- with .Values.addons.mattermost.objectStorage }} +{{- if and .endpoint .accessKey .accessSecret .bucket }} +fileStore: + secret: "mattermost-objectstorage-secret" + url: {{ .endpoint }} + bucket: {{ .bucket }} +{{- else }} +minio: + install: true + accessKey: {{ .accessKey | default "minio" }} + secretKey: {{ .secretKey | default "BigBangDEVONLY" }} + imagePullSecrets: + - name: private-registry + tenants: + metrics: + enabled: {{ $.Values.monitoring.enabled }} + {{- if $istioInjection }} + annotations: + {{ include "istioAnnotation" $ }} + {{- end }} +{{- end }} +{{- end }} + +{{- if .Values.addons.mattermost.elasticsearch.enabled }} +elasticsearch: + enabled: true +{{- end }} + +mattermostEnvs: + # required for Keycloak >= 20.X to work with gitlab auth pointed to Keycloak + MM_GITLABSETTINGS_SCOPE: openid + +{{- end -}} diff --git a/chart/templates/metrics-server/git-credentials.yaml b/chart/templates/metrics-server/git-credentials.yaml new file mode 100644 index 0000000000000000000000000000000000000000..feec59ea9cfb07d54ebd7734f658d561fda11c5f --- /dev/null +++ b/chart/templates/metrics-server/git-credentials.yaml @@ -0,0 +1,7 @@ +{{- $gitCredsSecretDict := dict + "name" "metricsServer" + "targetScope" .Values.addons.metricsServer + "releaseName" .Release.Name + "releaseNamespace" .Release.Namespace +}} +{{- include "gitCredsSecret" $gitCredsSecretDict | nindent 0 -}} diff --git a/chart/templates/metrics-server/gitrepository.yaml b/chart/templates/metrics-server/gitrepository.yaml new file mode 100644 index 0000000000000000000000000000000000000000..fb33f3e725c07490e073fd67c9414fe05d526483 --- /dev/null +++ b/chart/templates/metrics-server/gitrepository.yaml @@ -0,0 +1,29 @@ +{{- if (eq .Values.addons.metricsServer.sourceType "git") }} +{{- $enableFlag := .Values.addons.metricsServer.enabled | toString }} +{{- $existingMetricsApi := (.Capabilities.APIVersions.Has "metrics.k8s.io/v1beta1") }} +{{- $existingMetricsHelmRelease := (lookup "helm.toolkit.fluxcd.io/v2" "HelmRelease" "bigbang" "metrics-server") }} +{{- if or ( eq $enableFlag "true") (and (eq $enableFlag "auto") (or (not $existingMetricsApi) $existingMetricsHelmRelease)) }} +{{- $gitCredsDict := dict + "name" "metricsServer" + "packageGitScope" .Values.addons.metricsServer.git + "rootScope" . + "releaseName" .Release.Name +}} +apiVersion: source.toolkit.fluxcd.io/v1 +kind: GitRepository +metadata: + name: metrics-server + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: metrics-server + app.kubernetes.io/component: "cluster-utilities" + {{- include "commonLabels" . | nindent 4}} +spec: + interval: {{ .Values.flux.interval }} + url: {{ .Values.addons.metricsServer.git.repo }} + ref: + {{- include "validRef" .Values.addons.metricsServer.git | nindent 4 }} + {{ include "gitIgnore" . }} + {{- include "gitCredsExtended" $gitCredsDict | nindent 2 }} +{{- end }} +{{- end }} diff --git a/chart/templates/metrics-server/helmrelease.yaml b/chart/templates/metrics-server/helmrelease.yaml new file mode 100644 index 0000000000000000000000000000000000000000..5102def253944cf3f690abb368cb2e60a134d923 --- /dev/null +++ b/chart/templates/metrics-server/helmrelease.yaml @@ -0,0 +1,76 @@ +{{- $fluxSettingsMetrics := merge .Values.addons.metricsServer.flux .Values.flux -}} +{{- $enableFlag := .Values.addons.metricsServer.enabled | toString }} +{{- $existingMetricsApi := (.Capabilities.APIVersions.Has "metrics.k8s.io/v1beta1") }} +{{- $existingMetricsHelmRelease := (lookup "helm.toolkit.fluxcd.io/v2" "HelmRelease" "bigbang" "metrics-server") }} +{{- if or ( eq $enableFlag "true") (and (eq $enableFlag "auto") (or (not $existingMetricsApi) $existingMetricsHelmRelease)) }} +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + name: metrics-server + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: metrics-server + app.kubernetes.io/component: "cluster-utilities" + {{- include "commonLabels" . | nindent 4}} + annotations: + checksum/bigbang-values: {{ include (print $.Template.BasePath "/metrics-server/values.yaml") . | sha256sum }} +spec: + driftDetection: + mode: warn + releaseName: metrics-server + targetNamespace: metrics-server + chart: + spec: + {{- if eq .Values.addons.metricsServer.sourceType "git" }} + chart: {{ .Values.addons.metricsServer.git.path }} + sourceRef: + kind: GitRepository + name: metrics-server + namespace: {{ .Release.Namespace }} + {{- else }} + chart: {{ .Values.addons.metricsServer.helmRepo.chartName }} + version: {{ .Values.addons.metricsServer.helmRepo.tag }} + sourceRef: + kind: HelmRepository + name: {{ .Values.addons.metricsServer.helmRepo.repoName }} + namespace: {{ .Release.Namespace }} + {{- $repoType := include "getRepoType" (dict "repoName" .Values.addons.metricsServer.helmRepo.repoName "allRepos" $.Values.helmRepositories) -}} + {{- if (and .Values.addons.metricsServer.helmRepo.cosignVerify (eq $repoType "oci")) }} # Needs to be an OCI repo + verify: + provider: cosign + secretRef: + name: {{ printf "%s-cosign-pub" .Values.addons.metricsServer.helmRepo.repoName }} + {{- end }} + {{- end }} + interval: 5m + + {{- toYaml $fluxSettingsMetrics | nindent 2 }} + + {{- if .Values.addons.metricsServer.postRenderers }} + postRenderers: + {{ toYaml .Values.addons.metricsServer.postRenderers | nindent 4 }} + {{- end }} + + valuesFrom: + - name: {{ .Release.Name }}-metrics-values + kind: Secret + valuesKey: "common" + - name: {{ .Release.Name }}-metrics-values + kind: Secret + valuesKey: "defaults" + - name: {{ .Release.Name }}-metrics-values + kind: Secret + valuesKey: "overlays" + + {{- if or .Values.istio.enabled .Values.monitoring.enabled }} + dependsOn: + {{- if .Values.istio.enabled }} + - name: istio + namespace: {{ .Release.Namespace }} + {{- end }} + {{- if .Values.monitoring.enabled }} + - name: monitoring + namespace: {{ .Release.Namespace }} + {{- end }} + {{- end }} +{{- end }} diff --git a/chart/templates/metrics-server/imagepullsecret.yaml b/chart/templates/metrics-server/imagepullsecret.yaml new file mode 100644 index 0000000000000000000000000000000000000000..461a92d7f3267be8a041ba6a163b5a0fca285b40 --- /dev/null +++ b/chart/templates/metrics-server/imagepullsecret.yaml @@ -0,0 +1,19 @@ +{{- $enableFlag := .Values.addons.metricsServer.enabled | toString }} +{{- $existingMetricsApi := (.Capabilities.APIVersions.Has "metrics.k8s.io/v1beta1") }} +{{- $existingMetricsHelmRelease := (lookup "helm.toolkit.fluxcd.io/v2" "HelmRelease" "bigbang" "metrics-server") }} +{{- if or ( eq $enableFlag "true") (and (eq $enableFlag "auto") (or (not $existingMetricsApi) $existingMetricsHelmRelease)) }} +{{- if ( include "imagePullSecret" . ) }} +apiVersion: v1 +kind: Secret +metadata: + name: private-registry + namespace: metrics-server + labels: + app.kubernetes.io/name: metrics-server + app.kubernetes.io/component: "cluster-utilities" + {{- include "commonLabels" . | nindent 4}} +type: kubernetes.io/dockerconfigjson +data: + .dockerconfigjson: {{ template "imagePullSecret" . }} +{{- end }} +{{- end }} diff --git a/chart/templates/metrics-server/namespace.yaml b/chart/templates/metrics-server/namespace.yaml new file mode 100644 index 0000000000000000000000000000000000000000..ac5f12982612cfe3debe827189527e37c69c0248 --- /dev/null +++ b/chart/templates/metrics-server/namespace.yaml @@ -0,0 +1,14 @@ +{{- $enableFlag := .Values.addons.metricsServer.enabled | toString }} +{{- $existingMetricsApi := (.Capabilities.APIVersions.Has "metrics.k8s.io/v1beta1") }} +{{- $existingMetricsHelmRelease := (lookup "helm.toolkit.fluxcd.io/v2" "HelmRelease" "bigbang" "metrics-server") }} +{{- if or ( eq $enableFlag "true") (and (eq $enableFlag "auto") (or (not $existingMetricsApi) $existingMetricsHelmRelease)) }} +apiVersion: v1 +kind: Namespace +metadata: + labels: + app.kubernetes.io/name: metrics-server + app.kubernetes.io/component: "cluster-utilities" + {{- include "commonLabels" . | nindent 4}} + istio-injection: {{ ternary "enabled" "disabled" (and .Values.istio.enabled (eq (dig "istio" "injection" "enabled" .Values.addons.metricsServer) "enabled")) }} + name: metrics-server +{{- end }} diff --git a/chart/templates/metrics-server/values.yaml b/chart/templates/metrics-server/values.yaml new file mode 100644 index 0000000000000000000000000000000000000000..9a16143bc1fdc9b28dcbfb695fce8bfef0d061b6 --- /dev/null +++ b/chart/templates/metrics-server/values.yaml @@ -0,0 +1,43 @@ +{{- $enableFlag := .Values.addons.metricsServer.enabled | toString }} +{{- $existingMetricsApi := (.Capabilities.APIVersions.Has "metrics.k8s.io/v1beta1") }} +{{- $existingMetricsHelmRelease := (lookup "helm.toolkit.fluxcd.io/v2" "HelmRelease" "bigbang" "metrics-server") }} +{{- if or ( eq $enableFlag "true") (and (eq $enableFlag "auto") (or (not $existingMetricsApi) $existingMetricsHelmRelease)) }} +{{- include "values-secret" (dict "root" $ "package" .Values.addons.metricsServer "name" "metrics" "defaults" (include "bigbang.defaults.metrics-server" .)) }} +{{- end }} + +{{- define "bigbang.defaults.metrics-server" -}} +# hostname is deprecated and replaced with domain. But if hostname exists then use it. +{{- $domainName := default .Values.domain .Values.hostname }} +domain: {{ $domainName }} + +istio: + enabled: {{ .Values.istio.enabled }} + hardened: + enabled: {{ or + (dig "istio" "hardened" "enabled" false .Values.addons.metricsServer.values) + (dig "hardened" "enabled" false .Values.istio.values) + }} + injection: {{ ternary "enabled" "disabled" .Values.istio.enabled }} + + +{{- if .Values.istio.enabled }} +podAnnotations: + {{ include "istioAnnotation" . }} +{{- end }} + +metrics: + enabled: {{ .Values.monitoring.enabled }} + +serviceMonitor: + enabled: {{ .Values.monitoring.enabled }} + dashboards: + namespace: monitoring + +# Default to 2 replicas for HA +replicas: 2 + +networkPolicies: + enabled: {{ .Values.networkPolicies.enabled }} + controlPlaneCidr: {{ .Values.networkPolicies.controlPlaneCidr }} + +{{- end }} diff --git a/chart/templates/minio-operator/git-credentials.yaml b/chart/templates/minio-operator/git-credentials.yaml new file mode 100644 index 0000000000000000000000000000000000000000..9dcd16432850b13355bafae5b4bdf2dc446bf67d --- /dev/null +++ b/chart/templates/minio-operator/git-credentials.yaml @@ -0,0 +1,7 @@ +{{- $gitCredsSecretDict := dict + "name" "minioOperator" + "targetScope" .Values.addons.minioOperator + "releaseName" .Release.Name + "releaseNamespace" .Release.Namespace +}} +{{- include "gitCredsSecret" $gitCredsSecretDict | nindent 0 -}} diff --git a/chart/templates/minio-operator/gitrepository.yaml b/chart/templates/minio-operator/gitrepository.yaml new file mode 100644 index 0000000000000000000000000000000000000000..adbd0fd8f645e3fe2966e26b9f39b39e461ab69a --- /dev/null +++ b/chart/templates/minio-operator/gitrepository.yaml @@ -0,0 +1,20 @@ +{{- if and (eq .Values.addons.minioOperator.sourceType "git") (not .Values.offline) (or .Values.addons.minioOperator.enabled .Values.addons.minio.enabled) }} +{{- $gitCredsDict := dict + "name" "minioOperator" + "packageGitScope" .Values.addons.minioOperator.git + "rootScope" . + "releaseName" .Release.Name +}} +apiVersion: source.toolkit.fluxcd.io/v1 +kind: GitRepository +metadata: + name: minio-operator + namespace: {{ .Release.Namespace }} +spec: + interval: {{ .Values.flux.interval }} + url: {{ .Values.addons.minioOperator.git.repo }} + ref: + {{- include "validRef" .Values.addons.minioOperator.git | nindent 4 }} + {{ include "gitIgnore" . }} + {{- include "gitCredsExtended" $gitCredsDict | nindent 2 }} +{{- end }} diff --git a/chart/templates/minio-operator/helmrelease.yaml b/chart/templates/minio-operator/helmrelease.yaml new file mode 100644 index 0000000000000000000000000000000000000000..65d539cdffcf745d48a71b0f90b11378dab49d54 --- /dev/null +++ b/chart/templates/minio-operator/helmrelease.yaml @@ -0,0 +1,77 @@ +{{- $fluxSettingsMinioOperator := merge .Values.addons.minioOperator.flux .Values.flux -}} +{{- if or .Values.addons.minioOperator.enabled .Values.addons.minio.enabled }} +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + name: minio-operator + namespace: {{ .Release.Namespace }} + annotations: + checksum/bigbang-values: {{ include (print $.Template.BasePath "/minio-operator/values.yaml") . | sha256sum }} +spec: + targetNamespace: minio-operator + chart: + spec: + {{- if eq .Values.addons.minioOperator.sourceType "git" }} + chart: {{ .Values.addons.minioOperator.git.path }} + sourceRef: + kind: GitRepository + name: minio-operator + namespace: {{ .Release.Namespace }} + {{- else }} + chart: {{ .Values.addons.minioOperator.helmRepo.chartName }} + version: {{ .Values.addons.minioOperator.helmRepo.tag }} + sourceRef: + kind: HelmRepository + name: {{ .Values.addons.minioOperator.helmRepo.repoName }} + namespace: {{ .Release.Namespace }} + {{- $repoType := include "getRepoType" (dict "repoName" .Values.addons.minioOperator.helmRepo.repoName "allRepos" $.Values.helmRepositories) -}} + {{- if (and .Values.addons.minioOperator.helmRepo.cosignVerify (eq $repoType "oci")) }} # Needs to be an OCI repo + verify: + provider: cosign + secretRef: + name: {{ printf "%s-cosign-pub" .Values.addons.minioOperator.helmRepo.repoName }} + {{- end }} + {{- end }} + interval: 5m + + {{- toYaml $fluxSettingsMinioOperator | nindent 2 }} + + {{- if .Values.addons.minioOperator.postRenderers }} + postRenderers: + {{ toYaml .Values.addons.minioOperator.postRenderers | nindent 4 }} + {{- end }} + valuesFrom: + - name: {{ .Release.Name }}-minio-operator-values + kind: Secret + valuesKey: "common" + - name: {{ .Release.Name }}-minio-operator-values + kind: Secret + valuesKey: "defaults" + - name: {{ .Release.Name }}-minio-operator-values + kind: Secret + valuesKey: "overlays" + + values: + podAnnotations: + sidecar.istio.io/inject: "true" + traffic.sidecar.istio.io/includeInboundPorts: "*" + traffic.sidecar.istio.io/excludeInboundPorts: "9443" + imagePullSecrets: + - name: private-registry + + {{- if or .Values.gatekeeper.enabled .Values.istio.enabled .Values.kyvernoPolicies.enabled }} + dependsOn: + {{- if .Values.gatekeeper.enabled }} + - name: gatekeeper + namespace: {{ .Release.Namespace }} + {{- end }} + {{- if .Values.istio.enabled }} + - name: istio + namespace: {{ .Release.Namespace }} + {{- end }} + {{- if .Values.kyvernoPolicies.enabled }} + - name: kyverno-policies + namespace: {{ .Release.Namespace }} + {{- end }} + {{- end }} +{{- end }} diff --git a/chart/templates/minio-operator/imagepullsecret.yaml b/chart/templates/minio-operator/imagepullsecret.yaml new file mode 100644 index 0000000000000000000000000000000000000000..924ad61d3653d0720b02238972c4bcd9661dd88a --- /dev/null +++ b/chart/templates/minio-operator/imagepullsecret.yaml @@ -0,0 +1,16 @@ +{{- if or .Values.addons.minioOperator.enabled .Values.addons.minio.enabled }} +{{- if ( include "imagePullSecret" . ) }} +apiVersion: v1 +kind: Secret +metadata: + name: private-registry + namespace: minio-operator + labels: + app.kubernetes.io/name: minioOperator + app.kubernetes.io/component: "application-utilities" + {{- include "commonLabels" . | nindent 4}} +type: kubernetes.io/dockerconfigjson +data: + .dockerconfigjson: {{ template "imagePullSecret" . }} +{{- end }} +{{- end }} diff --git a/chart/templates/minio-operator/namespace.yaml b/chart/templates/minio-operator/namespace.yaml new file mode 100644 index 0000000000000000000000000000000000000000..e18fda7f8c846f815a654404db343bf7b25c3033 --- /dev/null +++ b/chart/templates/minio-operator/namespace.yaml @@ -0,0 +1,11 @@ +{{- if or .Values.addons.minioOperator.enabled .Values.addons.minio.enabled }} +apiVersion: v1 +kind: Namespace +metadata: + name: minio-operator + labels: + istio-injection: {{ ternary "enabled" "disabled" (and .Values.istio.enabled (eq (dig "istio" "injection" "enabled" .Values.addons.minioOperator) "enabled")) }} + app.kubernetes.io/name: minioOperator + app.kubernetes.io/component: "application-utilities" + {{- include "commonLabels" . | nindent 4}} +{{- end }} diff --git a/chart/templates/minio-operator/values.yaml b/chart/templates/minio-operator/values.yaml new file mode 100644 index 0000000000000000000000000000000000000000..a3166366fe6d763f864f1b99df3e512944652b93 --- /dev/null +++ b/chart/templates/minio-operator/values.yaml @@ -0,0 +1,65 @@ +{{- if or .Values.addons.minioOperator.enabled .Values.addons.minio.enabled }} +{{- include "values-secret" (dict "root" $ "package" .Values.addons.minioOperator "name" "minio-operator" "defaults" (include "bigbang.defaults.minio-operator" .)) }} +{{- end }} + +{{- define "bigbang.defaults.minio-operator" -}} +# hostname is deprecated and replaced with domain. But if hostname exists then use it. +{{- $domainName := default .Values.domain .Values.hostname }} +hostname: {{ $domainName }} +domain: {{ $domainName }} + +podAnnotations: + sidecar.istio.io/inject: "true" + traffic.sidecar.istio.io/includeInboundPorts: "*" + traffic.sidecar.istio.io/excludeInboundPorts: "9443" + +console: + imagePullSecrets: + - name: private-registry + +operator: + image: + pullPolicy: {{ .Values.imagePullPolicy}} + imagePullSecrets: + - name: private-registry + + {{- if .Values.monitoring.enabled }} + env: + - name: MINIO_OPERATOR_TLS_ENABLE + value: "on" + - name: CLUSTER_DOMAIN + value: "cluster.local" + - name: WATCHED_NAMESPACE + value: "" + - name: PROMETHEUS_NAMESPACE + value: "monitoring" + {{- end }} + +networkPolicies: + enabled: {{ .Values.networkPolicies.enabled }} + controlPlaneCidr: {{ .Values.networkPolicies.controlPlaneCidr }} + ingressLabels: + {{- $gateway := default "public" .Values.addons.minio.ingress.gateway }} + {{- $default := dict "app" (dig "gateways" $gateway "ingressGateway" nil .Values.istio) "istio" nil }} + {{- toYaml (dig "values" "gateways" $gateway "selector" $default .Values.istio) | nindent 4 }} + +istio: + enabled: {{ .Values.istio.enabled }} + hardened: + enabled: {{ or + (dig "istio" "hardened" "enabled" false .Values.addons.minioOperator.values) + (dig "istio" "hardened" "enabled" false .Values.addons.minio.values) + (dig "hardened" "enabled" false .Values.istio.values) + }} + console: + gateways: + - istio-system/{{ default "public" .Values.addons.minio.ingress.gateway }} + +{{- if .Values.istio.enabled }} +annotations: + {{ include "istioAnnotation" . }} +{{- end }} + +monitoring: + enabled: {{ .Values.monitoring.enabled }} +{{- end -}} diff --git a/chart/templates/minio/git-credentials.yaml b/chart/templates/minio/git-credentials.yaml new file mode 100644 index 0000000000000000000000000000000000000000..16e0085e310b15cf5dbf08f29e27e65765a15b5b --- /dev/null +++ b/chart/templates/minio/git-credentials.yaml @@ -0,0 +1,7 @@ +{{- $gitCredsSecretDict := dict + "name" "minio" + "targetScope" .Values.addons.minio + "releaseName" .Release.Name + "releaseNamespace" .Release.Namespace +}} +{{- include "gitCredsSecret" $gitCredsSecretDict | nindent 0 -}} diff --git a/chart/templates/minio/gitrepository.yaml b/chart/templates/minio/gitrepository.yaml new file mode 100644 index 0000000000000000000000000000000000000000..472467cf81fd6d85e05d40e22427e162ee2d206e --- /dev/null +++ b/chart/templates/minio/gitrepository.yaml @@ -0,0 +1,20 @@ +{{- if and (eq .Values.addons.minio.sourceType "git") (not .Values.offline) (or .Values.addons.minioOperator.enabled .Values.addons.minio.enabled) }} +{{- $gitCredsDict := dict + "name" "minio" + "packageGitScope" .Values.addons.minio.git + "rootScope" . + "releaseName" .Release.Name +}} +apiVersion: source.toolkit.fluxcd.io/v1 +kind: GitRepository +metadata: + name: minio + namespace: {{ .Release.Namespace }} +spec: + interval: {{ .Values.flux.interval }} + url: {{ .Values.addons.minio.git.repo }} + ref: + {{- include "validRef" .Values.addons.minio.git | nindent 4 }} + {{ include "gitIgnore" . }} + {{- include "gitCredsExtended" $gitCredsDict | nindent 2 }} +{{- end }} diff --git a/chart/templates/minio/helmrelease.yaml b/chart/templates/minio/helmrelease.yaml new file mode 100644 index 0000000000000000000000000000000000000000..324494b900266a24cef3a181fd19781964cd8c9d --- /dev/null +++ b/chart/templates/minio/helmrelease.yaml @@ -0,0 +1,61 @@ +{{- $fluxSettingsMinio := merge .Values.addons.minio.flux .Values.flux -}} +{{- if .Values.addons.minio.enabled }} +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + name: minio + namespace: {{ .Release.Namespace }} + annotations: + checksum/bigbang-values: {{ include (print $.Template.BasePath "/minio/values.yaml") . | sha256sum }} +spec: + targetNamespace: minio + chart: + spec: + {{- if eq .Values.addons.minio.sourceType "git" }} + chart: {{ .Values.addons.minio.git.path }} + sourceRef: + kind: GitRepository + name: minio + namespace: {{ .Release.Namespace }} + {{- else }} + chart: {{ .Values.addons.minio.helmRepo.chartName }} + version: {{ .Values.addons.minio.helmRepo.tag }} + sourceRef: + kind: HelmRepository + name: {{ .Values.addons.minio.helmRepo.repoName }} + namespace: {{ .Release.Namespace }} + {{- $repoType := include "getRepoType" (dict "repoName" .Values.addons.minio.helmRepo.repoName "allRepos" $.Values.helmRepositories) -}} + {{- if (and .Values.addons.minio.helmRepo.cosignVerify (eq $repoType "oci")) }} # Needs to be an OCI repo + verify: + provider: cosign + secretRef: + name: {{ printf "%s-cosign-pub" .Values.addons.minio.helmRepo.repoName }} + {{- end }} + {{- end }} + interval: 5m + + {{- toYaml $fluxSettingsMinio | nindent 2 }} + + {{- if .Values.addons.minio.postRenderers }} + postRenderers: + {{ toYaml .Values.addons.minio.postRenderers | nindent 4 }} + {{- end }} + valuesFrom: + - name: {{ .Release.Name }}-minio-values + kind: Secret + valuesKey: "common" + - name: {{ .Release.Name }}-minio-values + kind: Secret + valuesKey: "defaults" + - name: {{ .Release.Name }}-minio-values + kind: Secret + valuesKey: "overlays" + + dependsOn: + - name: minio-operator + namespace: {{ .Release.Namespace }} + {{- if .Values.monitoring.enabled }} + - name: monitoring + namespace: {{ .Release.Namespace }} + {{- end }} +{{- end }} diff --git a/chart/templates/minio/imagepullsecret.yaml b/chart/templates/minio/imagepullsecret.yaml new file mode 100644 index 0000000000000000000000000000000000000000..f88a8d4b74b926d994525cc1a6f5e91a4cb3c0cc --- /dev/null +++ b/chart/templates/minio/imagepullsecret.yaml @@ -0,0 +1,12 @@ +{{- if .Values.addons.minio.enabled }} +{{- if ( include "imagePullSecret" . ) }} +apiVersion: v1 +kind: Secret +metadata: + name: private-registry + namespace: minio +type: kubernetes.io/dockerconfigjson +data: + .dockerconfigjson: {{ template "imagePullSecret" . }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/chart/templates/minio/namespace.yaml b/chart/templates/minio/namespace.yaml new file mode 100644 index 0000000000000000000000000000000000000000..5133e83cc2a95d039eda909cab0d730388d69ab0 --- /dev/null +++ b/chart/templates/minio/namespace.yaml @@ -0,0 +1,11 @@ +{{- if .Values.addons.minio.enabled }} +apiVersion: v1 +kind: Namespace +metadata: + name: minio + labels: + istio-injection: {{ ternary "enabled" "disabled" (and .Values.istio.enabled (eq (dig "istio" "injection" "enabled" .Values.addons.minio) "enabled")) }} + app.kubernetes.io/name: minio + app.kubernetes.io/component: "application-utilities" + {{- include "commonLabels" . | nindent 4}} +{{- end }} diff --git a/chart/templates/minio/values.yaml b/chart/templates/minio/values.yaml new file mode 100644 index 0000000000000000000000000000000000000000..e62638202dc039d843cd5bbb89a13c9e5635ec5c --- /dev/null +++ b/chart/templates/minio/values.yaml @@ -0,0 +1,63 @@ +{{- if .Values.addons.minio.enabled }} +{{- include "values-secret" (dict "root" $ "package" .Values.addons.minio "name" "minio" "defaults" (include "bigbang.defaults.minio" .)) }} +{{- end }} + +{{- define "bigbang.defaults.minio" -}} +# hostname is deprecated and replaced with domain. But if hostname exists then use it. +{{- $domainName := default .Values.domain .Values.hostname }} +hostname: {{ $domainName }} +domain: {{ $domainName }} + +istio: + enabled: {{ .Values.istio.enabled }} + console: + gateways: + - istio-system/{{ default "public" .Values.addons.minio.ingress.gateway }} + api: + gateways: + - istio-system/{{ default "public" .Values.addons.minio.ingress.gateway }} + hardened: + enabled: {{ or + (dig "istio" "hardened" "enabled" false .Values.addons.minioOperator.values) + (dig "istio" "hardened" "enabled" false .Values.addons.minio.values) + (dig "hardened" "enabled" false .Values.istio.values) + }} + +{{- if .Values.istio.enabled }} +annotations: + {{ include "istioAnnotation" . }} +{{- end }} + +monitoring: + enabled: {{ .Values.monitoring.enabled }} + +networkPolicies: + enabled: {{ .Values.networkPolicies.enabled }} + controlPlaneCidr: {{ .Values.networkPolicies.controlPlaneCidr }} + ingressLabels: + {{- $gateway := default "public" .Values.addons.minio.ingress.gateway }} + {{- $default := dict "app" (dig "gateways" $gateway "ingressGateway" nil .Values.istio) "istio" nil }} + {{- toYaml (dig "values" "gateways" $gateway "selector" $default .Values.istio) | nindent 4 }} + +podAnnotations: + sidecar.istio.io/inject: "true" + traffic.sidecar.istio.io/includeInboundPorts: "*" + traffic.sidecar.istio.io/excludeInboundPorts: "9443" + +configSecret: + accessKey: {{ .Values.addons.minio.accesskey | default "minio" }} + secretKey: {{ .Values.addons.minio.secretkey | default "minio123" }} + +tenant: + image: + pullPolicy: {{ .Values.imagePullPolicy }} + imagePullSecret: + name: private-registry + metrics: + enabled: {{ .Values.monitoring.enabled }} + {{- if .Values.monitoring.enabled }} + env: + - name: MINIO_PROMETHEUS_AUTH_TYPE + value: "public" + {{- end }} +{{- end -}} diff --git a/chart/templates/monitoring/git-credentials.yaml b/chart/templates/monitoring/git-credentials.yaml new file mode 100644 index 0000000000000000000000000000000000000000..497b3b02c06dd775d53581425bd6e43499af64f6 --- /dev/null +++ b/chart/templates/monitoring/git-credentials.yaml @@ -0,0 +1,7 @@ +{{- $gitCredsSecretDict := dict + "name" "monitoring" + "targetScope" .Values.monitoring + "releaseName" .Release.Name + "releaseNamespace" .Release.Namespace +}} +{{- include "gitCredsSecret" $gitCredsSecretDict | nindent 0 -}} diff --git a/chart/templates/monitoring/gitrepository.yaml b/chart/templates/monitoring/gitrepository.yaml new file mode 100644 index 0000000000000000000000000000000000000000..4ccd10fb00ea5ce125ae167a8080fc4634ef8e33 --- /dev/null +++ b/chart/templates/monitoring/gitrepository.yaml @@ -0,0 +1,24 @@ +{{- if and (eq .Values.monitoring.sourceType "git") (not .Values.offline) .Values.monitoring.enabled }} +{{- $gitCredsDict := dict + "name" "monitoring" + "packageGitScope" .Values.monitoring.git + "rootScope" . + "releaseName" .Release.Name +}} +apiVersion: source.toolkit.fluxcd.io/v1 +kind: GitRepository +metadata: + name: monitoring + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: monitoring + app.kubernetes.io/component: "core" + {{- include "commonLabels" . | nindent 4}} +spec: + interval: {{ .Values.flux.interval }} + url: {{ .Values.monitoring.git.repo }} + ref: + {{- include "validRef" .Values.monitoring.git | nindent 4 }} + {{ include "gitIgnore" . }} + {{- include "gitCredsExtended" $gitCredsDict | nindent 2 }} +{{- end }} diff --git a/chart/templates/monitoring/grafana-env-secret.yaml b/chart/templates/monitoring/grafana-env-secret.yaml new file mode 100644 index 0000000000000000000000000000000000000000..314062529981325323c7cca4e5b6fc1288cdded9 --- /dev/null +++ b/chart/templates/monitoring/grafana-env-secret.yaml @@ -0,0 +1,12 @@ +{{- if and .Values.monitoring.enabled (ne .Values.addons.gitlab.redis.password "") }} +apiVersion: v1 +kind: Secret +metadata: + name: grafana-env-secret + namespace: monitoring + labels: + grafana_datasource: "1" +type: Opaque +stringData: + GITLAB_REDIS_PASSWORD: {{ .Values.addons.gitlab.redis.password }} +{{- end }} \ No newline at end of file diff --git a/chart/templates/monitoring/helmrelease.yaml b/chart/templates/monitoring/helmrelease.yaml new file mode 100644 index 0000000000000000000000000000000000000000..d526e0f19586744f3191fdc38360099f7f9d9100 --- /dev/null +++ b/chart/templates/monitoring/helmrelease.yaml @@ -0,0 +1,78 @@ +{{- $fluxSettingsMonitoring := merge .Values.monitoring.flux .Values.flux -}} +{{- if .Values.monitoring.enabled }} +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + name: monitoring + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: monitoring + app.kubernetes.io/component: "core" + {{- include "commonLabels" . | nindent 4}} + annotations: + checksum/bigbang-values: {{ include (print $.Template.BasePath "/monitoring/values.yaml") . | sha256sum }} +spec: + targetNamespace: monitoring + chart: + spec: + {{- if eq .Values.monitoring.sourceType "git" }} + chart: {{ .Values.monitoring.git.path }} + sourceRef: + kind: GitRepository + name: monitoring + namespace: {{ .Release.Namespace }} + {{- else }} + chart: {{ .Values.monitoring.helmRepo.chartName }} + version: {{ .Values.monitoring.helmRepo.tag }} + sourceRef: + kind: HelmRepository + name: {{ .Values.monitoring.helmRepo.repoName }} + namespace: {{ .Release.Namespace }} + {{- $repoType := include "getRepoType" (dict "repoName" .Values.monitoring.helmRepo.repoName "allRepos" $.Values.helmRepositories) -}} + {{- if (and .Values.monitoring.helmRepo.cosignVerify (eq $repoType "oci")) }} # Needs to be an OCI repo + verify: + provider: cosign + secretRef: + name: {{ printf "%s-cosign-pub" .Values.monitoring.helmRepo.repoName }} + {{- end }} + {{- end }} + interval: 5m + + {{- toYaml $fluxSettingsMonitoring | nindent 2 }} + + {{- if .Values.monitoring.postRenderers }} + postRenderers: + {{ toYaml .Values.monitoring.postRenderers | nindent 4 }} + {{- end }} + valuesFrom: + - name: {{ .Release.Name }}-monitoring-values + kind: Secret + valuesKey: "common" + - name: {{ .Release.Name }}-monitoring-values + kind: Secret + valuesKey: "defaults" + - name: {{ .Release.Name }}-monitoring-values + kind: Secret + valuesKey: "overlays" + + # TODO: DRY this up + {{- if or .Values.gatekeeper.enabled .Values.istio.enabled .Values.kyvernoPolicies.enabled .Values.addons.vault.enabled }} + dependsOn: + {{- if .Values.istio.enabled }} + - name: istio + namespace: {{ .Release.Namespace }} + {{- end }} + {{- if .Values.gatekeeper.enabled }} + - name: gatekeeper + namespace: {{ .Release.Namespace }} + {{- end }} + {{- if .Values.kyvernoPolicies.enabled }} + - name: kyverno-policies + namespace: {{ .Release.Namespace }} + {{- end }} + {{- if .Values.addons.vault.enabled }} + - name: vault + namespace: {{ .Release.Namespace }} + {{- end }} + {{- end }} +{{- end }} diff --git a/chart/templates/monitoring/imagepullsecret.yaml b/chart/templates/monitoring/imagepullsecret.yaml new file mode 100644 index 0000000000000000000000000000000000000000..1d65260b441435474bb9473e12045cf34bd66b25 --- /dev/null +++ b/chart/templates/monitoring/imagepullsecret.yaml @@ -0,0 +1,16 @@ +{{- if .Values.monitoring.enabled }} +{{- if ( include "imagePullSecret" . ) }} +apiVersion: v1 +kind: Secret +metadata: + name: private-registry + namespace: monitoring + labels: + app.kubernetes.io/name: monitoring + app.kubernetes.io/component: "core" + {{- include "commonLabels" . | nindent 4}} +type: kubernetes.io/dockerconfigjson +data: + .dockerconfigjson: {{ template "imagePullSecret" . }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/chart/templates/monitoring/namespace.yaml b/chart/templates/monitoring/namespace.yaml new file mode 100644 index 0000000000000000000000000000000000000000..89b930f4ed47d36fbe464641af965f3431129edc --- /dev/null +++ b/chart/templates/monitoring/namespace.yaml @@ -0,0 +1,11 @@ +{{- if .Values.monitoring.enabled }} +apiVersion: v1 +kind: Namespace +metadata: + name: monitoring + labels: + app.kubernetes.io/name: monitoring + app.kubernetes.io/component: "core" + {{- include "commonLabels" . | nindent 4}} + istio-injection: {{ ternary "enabled" "disabled" (and .Values.istio.enabled (eq (dig "istio" "injection" "enabled" .Values.monitoring) "enabled")) }} +{{- end }} diff --git a/chart/templates/monitoring/secret-ca.yaml b/chart/templates/monitoring/secret-ca.yaml new file mode 100644 index 0000000000000000000000000000000000000000..926896089d547b16c2dc9d406a3a42cbb9b313c5 --- /dev/null +++ b/chart/templates/monitoring/secret-ca.yaml @@ -0,0 +1,11 @@ +{{- if and (or (and .Values.monitoring.enabled .Values.monitoring.sso.enabled) (and .Values.grafana.enabled .Values.grafana.sso.enabled)) (or .Values.sso.certificate_authority (dig "certificateAuthority" "cert" false .Values.sso)) }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ default (dig "certificateAuthority" "secretName" "" .Values.sso) .Values.sso.secretName }} + namespace: monitoring +type: Opaque +data: + ca.pem: {{ default (dig "certificateAuthority" "cert" "" .Values.sso) .Values.sso.certificate_authority | b64enc }} +{{- end }} + diff --git a/chart/templates/monitoring/secret-objectstore.yaml b/chart/templates/monitoring/secret-objectstore.yaml new file mode 100644 index 0000000000000000000000000000000000000000..aa01e89997ccd23d535b2fbae2c639e564876e1c --- /dev/null +++ b/chart/templates/monitoring/secret-objectstore.yaml @@ -0,0 +1,21 @@ +{{- if and .Values.monitoring.enabled (not ( .Values.addons.thanos.objectStorage.endpoint | empty)) }} +apiVersion: v1 +kind: Secret +metadata: + name: monitoring-objstore-secret + namespace: monitoring + labels: + app.kubernetes.io/name: monitoring + app.kubernetes.io/component: "core" + {{- include "commonLabels" . | nindent 4}} +type: kubernetes.io/opaque +stringData: + objstore.yml: | + type: s3 + config: + bucket: {{ .Values.addons.thanos.objectStorage.bucket }} + endpoint: {{ .Values.addons.thanos.objectStorage.endpoint }} + access_key: {{ .Values.addons.thanos.objectStorage.accessKey }} + secret_key: {{ .Values.addons.thanos.objectStorage.accessSecret }} + insecure: {{ .Values.addons.thanos.objectStorage.insecure }} +{{- end }} diff --git a/chart/templates/monitoring/values.yaml b/chart/templates/monitoring/values.yaml new file mode 100644 index 0000000000000000000000000000000000000000..94f09c3356b1a178394e80473ea72b8be6d80dff --- /dev/null +++ b/chart/templates/monitoring/values.yaml @@ -0,0 +1,527 @@ +{{- if .Values.monitoring.enabled }} +{{- include "values-secret" (dict "root" $ "package" (dict "values" (fromYaml (include "bigbang.overlays.monitoring" .))) "name" "monitoring" "defaults" (include "bigbang.defaults.monitoring" .)) }} +{{- end }} + +{{- define "bigbang.defaults.monitoring" -}} +# hostname is deprecated and replaced with domain. But if hostname exists then use it. +{{- $domainName := default .Values.domain .Values.hostname }} +hostname: {{ $domainName }} +domain: {{ $domainName }} + +{{- $istioInjection := (and (eq (dig "istio" "injection" "enabled" .Values.monitoring) "enabled") .Values.istio.enabled) }} +{{- $gitlabRedis := (and (ne .Values.addons.gitlab.redis.password "" ) (or .Values.addons.gitlab.enabled .Values.addons.gitlabRunner.enabled)) }} +{{- $authserviceRedisEnabled := (and (dig "values" "redis" "enabled" false .Values.addons.authservice) .Values.addons.authservice.enabled) }} +{{- $redisDatasource := (or $gitlabRedis .Values.addons.argocd.enabled $authserviceRedisEnabled) }} +{{- $thanosEnabled := (.Values.addons.thanos.enabled) }} +{{- $lokiEnabled := (.Values.loki.enabled) }} +{{- $clusterName := ( default "logging-loki" .Values.loki.clusterName ) }} + +flux: + enabled: true + +networkPolicies: + enabled: {{ .Values.networkPolicies.enabled }} + controlPlaneCidr: {{ .Values.networkPolicies.controlPlaneCidr }} + ingressLabels: + {{- $gateway := default "public" .Values.monitoring.ingress.gateway }} + {{- $default := dict "app" (dig "gateways" $gateway "ingressGateway" nil .Values.istio) "istio" nil }} + {{- toYaml (dig "values" "gateways" $gateway "selector" $default .Values.istio) | nindent 4 }} + +openshift: {{ .Values.openshift }} + +minioOperator: + enabled: {{ .Values.addons.minioOperator.enabled }} + +gitlabRunner: + enabled: {{ .Values.addons.gitlabRunner.enabled }} + +istio: + {{- $monitoringInjection := dig "istio" "injection" "enabled" .Values.monitoring }} + enabled: {{ .Values.istio.enabled }} + hardened: + enabled: {{ or + (dig "istio" "hardened" "enabled" false .Values.monitoring.values) + (dig "istio" "hardened" "enabled" false .Values.addons.authservice.values) + (dig "hardened" "enabled" false .Values.istio.values) + (dig "istio" "hardened" "enabled" false .Values.grafana.values) + (dig "istio" "hardened" "enabled" false .Values.loki.values) + (dig "istio" "hardened" "enabled" false .Values.eckOperator.values) + (dig "istio" "hardened" "enabled" false .Values.elasticsearchKibana.values) + }} + {{- if and (dig "values" "istio" "hardened" "enabled" false .Values.monitoring) (contains "s3" .Values.addons.thanos.objectStorage.endpoint) }} + customServiceEntries: + - name: egress-object-store + enabled: true + spec: + hosts: + - "{{ .Values.addons.thanos.objectStorage.bucket }}.{{ .Values.addons.thanos.objectStorage.endpoint }}" + location: MESH_EXTERNAL + ports: + - number: 443 + protocol: TLS + name: https + resolution: DNS + {{- end }} + clusterWideHardenedEnabled: {{ dig "hardened" "enabled" false .Values.istio.values }} + prometheus: + enabled: true + {{- if and .Values.monitoring.sso.enabled (eq $monitoringInjection "disabled") }} + service: authservice-haproxy-sso + port: 8080 + namespace: authservice + {{- end }} + gateways: + - istio-system/{{ default "public" .Values.monitoring.ingress.gateway }} + alertmanager: + enabled: true + {{- if and .Values.monitoring.sso.enabled (eq $monitoringInjection "disabled") }} + service: authservice-haproxy-sso + port: 8080 + namespace: authservice + {{- end }} + gateways: + - istio-system/{{ default "public" .Values.monitoring.ingress.gateway }} + injection: {{ dig "istio" "injection" "enabled" .Values.monitoring }} + +alertmanager: + alertmanagerSpec: + # The operator performs a strategic merge to add our imagePullPolicy definition to the default containers + # NOTE: This functionality is not actively maintained upstream and may not work in a future monitoring upgrade + containers: + - name: "alertmanager" + imagePullPolicy: {{ .Values.imagePullPolicy }} + - name: "config-reloader" + imagePullPolicy: {{ .Values.imagePullPolicy }} + {{- if or .Values.monitoring.sso.enabled $istioInjection .Values.kiali.enabled }} + podMetadata: + {{- if or .Values.monitoring.sso.enabled .Values.kiali.enabled }} + {{- $alertmanagerAuthserviceKey := (dig "selector" "key" "protect" .Values.addons.authservice.values) }} + {{- $alertmanagerAuthserviceValue := (dig "selector" "value" "keycloak" .Values.addons.authservice.values) }} + labels: + {{- if .Values.monitoring.sso.enabled }} + {{ $alertmanagerAuthserviceKey }}: {{ $alertmanagerAuthserviceValue }} + {{- end }} + {{- end }} + {{- if $istioInjection }} + annotations: + {{ include "istioAnnotation" . }} + {{- end }} + {{- end }} + {{- if and .Values.istio.enabled (eq (dig "istio" "mtls" "mode" "STRICT" .Values.monitoring.values) "STRICT") }} + serviceMonitor: + scheme: https + tlsConfig: + caFile: /etc/prom-certs/root-cert.pem + certFile: /etc/prom-certs/cert-chain.pem + keyFile: /etc/prom-certs/key.pem + insecureSkipVerify: true # Prometheus does not support Istio security naming, thus skip verifying target pod certificate + {{- end }} + +prometheus: + {{- if $lokiEnabled }} + monitor: + relabelings: + - action: replace + replacement: {{ $clusterName }} + targetLabel: cluster + {{- end }} + + {{- if $thanosEnabled }} + thanosService: + enabled: true + + # Note: We need to change the portName in order for istio to correctly detect TCP is being used + # for the headless service + {{- if $istioInjection }} + portName: "tcp-grpc" + {{- end }} + + thanosServiceMonitor: + enabled: true + {{- if and .Values.istio.enabled (eq (dig "istio" "mtls" "mode" "STRICT" .Values.monitoring.values) "STRICT") }} + serviceMonitor: + scheme: https + tlsConfig: + caFile: /etc/prom-certs/root-cert.pem + certFile: /etc/prom-certs/cert-chain.pem + keyFile: /etc/prom-certs/key.pem + insecureSkipVerify: true # Prometheus does not support Istio security naming, thus skip verifying target pod certificate + {{- end }} + {{- end }} + prometheusSpec: + {{- if and .Values.istio.enabled (eq (dig "istio" "mtls" "mode" "STRICT" .Values.monitoring.values) "STRICT") }} + alertingEndpoints: + - name: monitoring-monitoring-kube-alertmanager + namespace: monitoring + apiVersion: v2 + port: http-web + pathPrefix: / + scheme: https + tlsConfig: + caFile: /etc/prom-certs/root-cert.pem + certFile: /etc/prom-certs/cert-chain.pem + keyFile: /etc/prom-certs/key.pem + insecureSkipVerify: true # Prometheus does not support Istio security naming, thus skip verifying target pod certificate + {{- end }} + + {{- if $thanosEnabled }} + thanos: + + {{- if (dig "values" "bbtests" "enabled" false .Values.addons.thanos) }} + objectStorageConfig: + secret: + type: s3 + config: + bucket: "thanos" + endpoint: minio.thanos.svc.cluster.local:80 + access_key: "minio" + secret_key: "minio123" + insecure: false + trace: + enable: true + http_config: + tls_config: + key_file: /etc/prom-certs/key.pem + ca_file: /etc/prom-certs/root-cert.pem + cert_file: /etc/prom-certs/cert-chain.pem + insecure_skip_verify: true + + # by default, the object stores only sync every 2 hours + # increase the frequency so the tests will pass + blockSize: 1m + + {{- else if not ( .Values.addons.thanos.objectStorage.endpoint | empty) }} + objectStorageConfig: + existingSecret: + key: objstore.yml + name: monitoring-objstore-secret + + {{- end }} + + {{- if $istioInjection }} + # Add volume/mount on thanos sidecar for Istio certs for mTLS scraping + volumes: + - emptyDir: + medium: Memory + name: istio-certs + volumeMounts: + - mountPath: /etc/prom-certs/ + name: istio-certs + {{- end }} + {{- end }} + + # The operator performs a strategic merge to add our imagePullPolicy definition to the default containers + # NOTE: This functionality is not actively maintained upstream and may not work in a future monitoring upgrade + containers: + - name: "prometheus" + imagePullPolicy: {{ .Values.imagePullPolicy }} + - name: "config-reloader" + imagePullPolicy: {{ .Values.imagePullPolicy }} + {{- if .Values.tempo.enabled }} + enableRemoteWriteReceiver: true + {{- end }} + podMetadata: + labels: + app: prometheus + {{- if .Values.monitoring.sso.enabled }} + {{- $prometheusAuthserviceKey := (dig "selector" "key" "protect" .Values.addons.authservice.values) }} + {{- $prometheusAuthserviceValue := (dig "selector" "value" "keycloak" .Values.addons.authservice.values) }} + {{ $prometheusAuthserviceKey }}: {{ $prometheusAuthserviceValue }} + {{- end }} + {{- if and .Values.networkPolicies.enabled .Values.addons.vault.enabled }} + vault-ingress: "true" + {{- end }} + {{- if or $istioInjection .Values.addons.vault.enabled }} + annotations: + {{- if $istioInjection }} + {{ include "istioAnnotation" . }} + traffic.sidecar.istio.io/includeOutboundIPRanges: "" + proxy.istio.io/config: | + proxyMetadata: + OUTPUT_CERTS: /etc/istio-output-certs + sidecar.istio.io/userVolumeMount: '[{"name": "istio-certs", "mountPath": "/etc/istio-output-certs"}]' + {{- end }} + {{- if .Values.addons.vault.enabled }} + vault.hashicorp.com/agent-inject: "true" + vault.hashicorp.com/agent-init-first: "true" + vault.hashicorp.com/agent-inject-token: "true" + vault.hashicorp.com/role: "prometheus" + vault.hashicorp.com/agent-run-as-user : "1000" + vault.hashicorp.com/agent-run-as-group : "2000" + {{- end }} + {{- end }} + {{- if .Values.addons.vault.enabled }} + additionalScrapeConfigs: + - job_name: vault + metrics_path: /v1/sys/metrics + params: + format: ['prometheus'] + scheme: https + authorization: + credentials_file: /vault/secrets/token + {{- $vaultHosts := (dig "istio" "vault" "hosts" dict .Values.addons.vault.values) }} + {{- if $vaultHosts }} + static_configs: + - targets: [{{ tpl ($vaultHosts | first) $ }}] + {{- else }} + static_configs: + - targets: [vault.{{ .Values.domain }}] + {{- end }} + {{- end }} + # Scrape config for service endpoints. + # + # The relabeling allows the actual service scrape endpoint to be configured + # via the following annotations: + # + # * `prometheus.io/scrape`: Only scrape services that have a value of `true` + # * `prometheus.io/scheme`: If the metrics endpoint is secured then you will need + # to set this to `https` & most likely set the `tls_config` of the scrape config. + # * `prometheus.io/path`: If the metrics path is not `/metrics` override this. + # * `prometheus.io/port`: If the metrics are exposed on a different port to the + # service then set this appropriately. + {{- if (dig "globalServiceEndpointMetrics" "enabled" false .Values.monitoring) }} + - job_name: 'kubernetes-service-endpoints' + kubernetes_sd_configs: + - role: endpoints + scheme: https + tls_config: + insecure_skip_verify: true + follow_redirects: true + enable_http2: true + relabel_configs: + - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scrape] + action: keep + regex: true + - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scheme] + action: replace + target_label: __scheme__ + regex: (https?) + - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_path] + action: replace + target_label: __metrics_path__ + regex: (.+) + - source_labels: [__address__, __meta_kubernetes_service_annotation_prometheus_io_port] + action: replace + target_label: __address__ + regex: ([^:]+)(?::\d+)?;(\d+) + replacement: $1:$2 + - action: labelmap + regex: __meta_kubernetes_service_label_(.+) + - source_labels: [__meta_kubernetes_namespace] + action: replace + target_label: kubernetes_namespace + - source_labels: [__meta_kubernetes_service_name] + action: replace + target_label: kubernetes_name + - source_labels: [__meta_kubernetes_service_name] + action: drop + regex: '(.+)node-exporter' + - source_labels: [__meta_kubernetes_service_name] + action: drop + regex: '(.+)dns' + - source_labels: [__meta_kubernetes_service_name] + action: drop + regex: '(.+)kube-state-metrics' + {{- end }} + # Example scrape config for pods + # + # The relabeling allows the actual pod scrape endpoint to be configured via the + # following annotations: + # + # * `prometheus.io/scrape`: Only scrape pods that have a value of `true` + # * `prometheus.io/path`: If the metrics path is not `/metrics` override this. + # * `prometheus.io/port`: Scrape the pod on the indicated port instead of the default of `9102`. + {{- if (dig "globalPodEndpointMetrics" "enabled" false .Values.monitoring) }} + - job_name: 'kubernetes-pods' + + + kubernetes_sd_configs: + - role: pod + + relabel_configs: + - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape] + action: keep + regex: true + - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_path] + action: replace + target_label: __metrics_path__ + regex: (.+) + - source_labels: [__address__, __meta_kubernetes_pod_annotation_prometheus_io_port] + action: replace + regex: ([^:]+)(?::\d+)?;(\d+) + replacement: $1:$2 + target_label: __address__ + - action: labelmap + regex: __meta_kubernetes_pod_label_(.+) + - source_labels: [__meta_kubernetes_namespace] + action: replace + target_label: kubernetes_namespace + - source_labels: [__meta_kubernetes_pod_name] + action: replace + target_label: kubernetes_pod_name + {{- end }} + {{- if $istioInjection }} + # Add volume/mount for Istio certs for mTLS scraping + volumes: + - emptyDir: + medium: Memory + name: istio-certs + volumeMounts: + - mountPath: /etc/prom-certs/ + name: istio-certs + {{- end }} + + +anchore: + enabled: {{ .Values.addons.anchore.enabled }} + +kiali: + enabled: {{ .Values.kiali.enabled }} + +loki: + enabled: {{ .Values.loki.enabled }} + +tempo: + enabled: {{ .Values.tempo.enabled }} + +{{- if or $gitlabRedis $authserviceRedisEnabled $redisDatasource }} +redis: + enabled: true +{{- end }} + +vault: + enabled: {{ .Values.addons.vault.enabled }} + tlsDisable: {{ dig "global" "tlsDisable" true .Values.addons.vault.values }} + +global: + imagePullSecrets: + - name: private-registry + +sso: + enabled: {{ .Values.monitoring.sso.enabled }} + +prometheus-node-exporter: + image: + pullPolicy: {{ .Values.imagePullPolicy }} + + + {{- if or (eq $lokiEnabled true) (eq $istioInjection true) }} + prometheus: + monitor: + {{- if $lokiEnabled }} + relabelings: + - action: replace + replacement: {{ $clusterName }} + targetLabel: cluster + - targetLabel: "instance" + sourceLabels: + - "__meta_kubernetes_pod_node_name" + {{- end }} + {{- if $istioInjection }} + scheme: https + tlsConfig: + caFile: /etc/prom-certs/root-cert.pem + certFile: /etc/prom-certs/cert-chain.pem + keyFile: /etc/prom-certs/key.pem + insecureSkipVerify: true # Prometheus does not support Istio security naming, thus skip verifying target pod certificate + {{- end }} + {{- if $istioInjection }} + podAnnotations: + {{ include "istioAnnotation" . }} + {{- end }} + {{- end }} + + {{- if .Values.openshift }} + service: + targetPort: 9102 + port: 9102 + {{- end }} + +{{- if $lokiEnabled }} +kubelet: + serviceMonitor: + cAdvisorRelabelings: + - action: replace + replacement: {{ $clusterName }} + targetLabel: cluster + - targetLabel: metrics_path + sourceLabels: + - "__metrics_path__" + - targetLabel: "instance" + sourceLabels: + - "node" +{{- end }} + +{{- if $lokiEnabled }} +defaultRules: + additionalRuleLabels: + cluster: {{ $clusterName }} +{{- end }} + +kube-state-metrics: + image: + pullPolicy: {{ .Values.imagePullPolicy }} + {{- if or (eq $lokiEnabled true) (eq $istioInjection true) }} + prometheus: + monitor: + {{- if $lokiEnabled }} + relabelings: + - action: replace + replacement: {{ $clusterName }} + targetLabel: cluster + - targetLabel: "instance" + sourceLabels: + - "__meta_kubernetes_pod_node_name" + {{- end }} + {{- if $istioInjection }} + scheme: https + tlsConfig: + caFile: /etc/prom-certs/root-cert.pem + certFile: /etc/prom-certs/cert-chain.pem + keyFile: /etc/prom-certs/key.pem + insecureSkipVerify: true # Prometheus does not support Istio security naming, thus skip verifying target pod certificate + {{- end }} + {{- if $istioInjection }} + podAnnotations: + {{ include "istioAnnotation" . }} + {{- end }} + {{- end }} + +prometheusOperator: + image: + pullPolicy: {{ .Values.imagePullPolicy }} + admissionWebhooks: + cleanupProxy: + image: + pullPolicy: {{ .Values.imagePullPolicy }} + patch: + image: + pullPolicy: {{ .Values.imagePullPolicy }} + {{- if $istioInjection }} + podAnnotations: + {{ include "istioAnnotation" . }} + {{- end }} +{{- end }} + +{{- /* This function merges defaults in lists from above into overlays */ -}} +{{- /* The end user will not have to replicate `prometheus.prometheusSpec.additionalScrapeConfigs` or `grafana.extraSecretMounts` from above when providing an overlay */ -}} +{{- /* There is a hidden flag `skipOverlayMerge` that can be added to `prometheus.prometheusSpec` or `grafana` overlays to ignore the defaults */ -}} +{{- define "bigbang.overlays.monitoring" }} + + {{- $defaults := fromYaml (include "bigbang.defaults.monitoring" .) }} + + {{- $overlays := dig "values" dict .Values.monitoring }} + {{- range $prometheusConfig, $default := $defaults.prometheus }} + {{- $overlay := (dig "prometheus" $prometheusConfig dict $overlays) }} + # Only continue if an overlay matches a default constriant and hidden "skipOverlayMerge" is not set + {{- if and $overlay (kindIs "map" $overlay) (not $overlay.skipOverlayMerge) }} + + # Add any default additionalScrapeConfigs to overlay + {{- if and (dig "additionalScrapeConfigs" list $default) (dig "additionalScrapeConfigs" list $overlay) }} + {{ $_ := set $overlay "additionalScrapeConfigs" (concat $default.additionalScrapeConfigs $overlay.additionalScrapeConfigs) }} + {{- end }} + + {{- end }} + {{- end }} +{{ toYaml $overlays }} +{{- end }} diff --git a/chart/templates/neuvector/git-credentials.yaml b/chart/templates/neuvector/git-credentials.yaml new file mode 100644 index 0000000000000000000000000000000000000000..072632cb909ded5b245260f5f238586968dd0079 --- /dev/null +++ b/chart/templates/neuvector/git-credentials.yaml @@ -0,0 +1,7 @@ +{{- $gitCredsSecretDict := dict + "name" "neuvector" + "targetScope" .Values.neuvector + "releaseName" .Release.Name + "releaseNamespace" .Release.Namespace +}} +{{- include "gitCredsSecret" $gitCredsSecretDict | nindent 0 -}} diff --git a/chart/templates/neuvector/gitrepository.yaml b/chart/templates/neuvector/gitrepository.yaml new file mode 100644 index 0000000000000000000000000000000000000000..edbf07771a8c76c18e6464a756a7f51bb99512bf --- /dev/null +++ b/chart/templates/neuvector/gitrepository.yaml @@ -0,0 +1,24 @@ +{{- if and (not .Values.offline) (eq .Values.neuvector.sourceType "git") .Values.neuvector.enabled }} +{{- $gitCredsDict := dict + "name" "neuvector" + "packageGitScope" .Values.neuvector.git + "rootScope" . + "releaseName" .Release.Name +}} +apiVersion: source.toolkit.fluxcd.io/v1 +kind: GitRepository +metadata: + name: neuvector + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: neuvector + app.kubernetes.io/component: "core" + {{- include "commonLabels" . | nindent 4}} +spec: + interval: {{ .Values.flux.interval }} + url: {{ .Values.neuvector.git.repo }} + ref: + {{- include "validRef" .Values.neuvector.git | nindent 4 }} + {{ include "gitIgnore" . }} + {{- include "gitCredsExtended" $gitCredsDict | nindent 2 }} +{{- end }} \ No newline at end of file diff --git a/chart/templates/neuvector/helmrelease.yaml b/chart/templates/neuvector/helmrelease.yaml new file mode 100644 index 0000000000000000000000000000000000000000..a667f095d66ef8b27135501d6814eb208fd36c9e --- /dev/null +++ b/chart/templates/neuvector/helmrelease.yaml @@ -0,0 +1,77 @@ +{{- $fluxSettingsNeuvector := merge .Values.neuvector.flux .Values.flux -}} +{{- if .Values.neuvector.enabled }} +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + name: neuvector + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: neuvector + app.kubernetes.io/component: "sandbox" + {{- include "commonLabels" . | nindent 4}} + annotations: + checksum/bigbang-values: {{ include (print $.Template.BasePath "/neuvector/values.yaml") . | sha256sum }} +spec: + targetNamespace: neuvector + chart: + spec: + {{- if eq .Values.neuvector.sourceType "git" }} + chart: {{ .Values.neuvector.git.path }} + sourceRef: + kind: GitRepository + name: neuvector + namespace: {{ .Release.Namespace }} + {{- else }} + chart: {{ .Values.neuvector.helmRepo.chartName }} + version: {{ .Values.neuvector.helmRepo.tag }} + sourceRef: + kind: HelmRepository + name: {{ .Values.neuvector.helmRepo.repoName }} + namespace: {{ .Release.Namespace }} + {{- $repoType := include "getRepoType" (dict "repoName" .Values.neuvector.helmRepo.repoName "allRepos" $.Values.helmRepositories) -}} + {{- if (and .Values.neuvector.helmRepo.cosignVerify (eq $repoType "oci")) }} # Needs to be an OCI repo + verify: + provider: cosign + secretRef: + name: {{ printf "%s-cosign-pub" .Values.neuvector.helmRepo.repoName }} + {{- end }} + {{- end }} + interval: 5m + + {{- toYaml $fluxSettingsNeuvector | nindent 2 }} + + {{- if .Values.neuvector.postRenderers }} + postRenderers: + {{ toYaml .Values.neuvector.postRenderers | nindent 4 }} + {{- end }} + valuesFrom: + - name: {{ .Release.Name }}-neuvector-values + kind: Secret + valuesKey: "common" + - name: {{ .Release.Name }}-neuvector-values + kind: Secret + valuesKey: "defaults" + - name: {{ .Release.Name }}-neuvector-values + kind: Secret + valuesKey: "overlays" + + {{- if or .Values.gatekeeper.enabled .Values.istio.enabled .Values.kyvernoPolicies.enabled .Values.monitoring.enabled }} + dependsOn: + {{- if .Values.gatekeeper.enabled }} + - name: gatekeeper + namespace: {{ .Release.Namespace }} + {{- end }} + {{- if .Values.istio.enabled }} + - name: istio + namespace: {{ .Release.Namespace }} + {{- end }} + {{- if .Values.kyvernoPolicies.enabled }} + - name: kyverno-policies + namespace: {{ .Release.Namespace }} + {{- end }} + {{- if .Values.monitoring.enabled }} + - name: monitoring + namespace: {{ .Release.Namespace }} + {{- end }} + {{- end }} +{{- end }} diff --git a/chart/templates/neuvector/imagepullsecret.yaml b/chart/templates/neuvector/imagepullsecret.yaml new file mode 100644 index 0000000000000000000000000000000000000000..415d7a75906318afd5d2777e9f576430e3c41866 --- /dev/null +++ b/chart/templates/neuvector/imagepullsecret.yaml @@ -0,0 +1,16 @@ +{{- if .Values.neuvector.enabled }} +{{- if ( include "imagePullSecret" . ) }} +apiVersion: v1 +kind: Secret +metadata: + name: private-registry + namespace: neuvector + labels: + app.kubernetes.io/name: neuvector + app.kubernetes.io/component: "sandbox" + {{- include "commonLabels" . | nindent 4}} +type: kubernetes.io/dockerconfigjson +data: + .dockerconfigjson: {{ template "imagePullSecret" . }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/chart/templates/neuvector/namespace.yaml b/chart/templates/neuvector/namespace.yaml new file mode 100644 index 0000000000000000000000000000000000000000..a231b71f7c8b281ea1291eca1317aa5489cef545 --- /dev/null +++ b/chart/templates/neuvector/namespace.yaml @@ -0,0 +1,11 @@ +{{- if .Values.neuvector.enabled }} +apiVersion: v1 +kind: Namespace +metadata: + name: neuvector + labels: + app.kubernetes.io/name: neuvector + app.kubernetes.io/component: "sandbox" + {{- include "commonLabels" . | nindent 4}} + istio-injection: {{ ternary "enabled" "disabled" (and .Values.istio.enabled (eq (dig "istio" "injection" "enabled" .Values.neuvector) "enabled")) }} +{{- end }} \ No newline at end of file diff --git a/chart/templates/neuvector/secret-ca.yaml b/chart/templates/neuvector/secret-ca.yaml new file mode 100644 index 0000000000000000000000000000000000000000..871198503736738a7d29b4652de706355f039fa8 --- /dev/null +++ b/chart/templates/neuvector/secret-ca.yaml @@ -0,0 +1,10 @@ +{{- if and .Values.neuvector.enabled .Values.neuvector.sso.enabled (or .Values.sso.certificate_authority (dig "certificateAuthority" "cert" false .Values.sso)) }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ default (dig "certificateAuthority" "secretName" "" .Values.sso) .Values.sso.secretName }} + namespace: neuvector +type: Opaque +data: + ca.pem: {{ default (dig "certificateAuthority" "cert" "" .Values.sso) .Values.sso.certificate_authority | b64enc }} +{{- end }} \ No newline at end of file diff --git a/chart/templates/neuvector/values.yaml b/chart/templates/neuvector/values.yaml new file mode 100644 index 0000000000000000000000000000000000000000..832672c5a46687067a8cbee8f76615e1368f2694 --- /dev/null +++ b/chart/templates/neuvector/values.yaml @@ -0,0 +1,136 @@ +{{- define "bigbang.defaults.neuvector" -}} +# Includes suffix of "A1a" to ensure password always meets default minimum password requirements +{{- $neuvectorMetricsPass := join "" (list (randAlphaNum 12) (randAlpha 2 | upper) (randAlpha 2 | lower) (randNumeric 2))}} + +# hostname is deprecated and replaced with domain. But if hostname exists then use it. +domain: {{ default .Values.domain .Values.hostname }} + +openshift: {{ .Values.openshift }} + +{{ $istioInjection := (and .Values.istio.enabled (eq (dig "istio" "injection" "enabled" .Values.neuvector) "enabled")) }} + +istio: + enabled: {{ .Values.istio.enabled }} + hardened: + enabled: {{ or + (dig "istio" "hardened" "enabled" false .Values.neuvector.values) + (dig "hardened" "enabled" false .Values.istio.values) + }} + neuvector: + gateways: + - istio-system/{{ default "public" .Values.neuvector.ingress.gateway }} + injection: {{ ternary "enabled" "disabled" $istioInjection }} + +monitoring: + enabled: {{ .Values.monitoring.enabled }} + +{{- if or .Values.monitoring.enabled $istioInjection .Values.neuvector.sso.enabled $.Values.kiali.enabled}} +controller: + {{- if $istioInjection }} + podAnnotations: + {{ include "istioAnnotation" . }} + {{- end }} + {{- if or .Values.monitoring.enabled .Values.neuvector.sso.enabled }} + secret: + enabled: true + data: + {{- if .Values.monitoring.enabled }} + userinitcfg.yaml: + always_reload: true + users: + - username: metrics + password: {{ $neuvectorMetricsPass }} + role: reader + fullname: metrics + {{- end }} + {{- if .Values.neuvector.sso.enabled }} + oidcinitcfg.yaml: + always_reload: true + enable: {{ .Values.neuvector.sso.enabled }} + issuer: {{ default (include "sso.url" .) (tpl (default "" .Values.neuvector.sso.issuer) .) }} + client_id: {{ .Values.neuvector.sso.client_id }} + client_secret: {{ .Values.neuvector.sso.client_secret | default "no-secret" }} + default_role: {{ .Values.neuvector.sso.default_role }} + group_claim: {{ .Values.neuvector.sso.group_claim }} + group_mapped_roles: + {{ toYaml .Values.neuvector.sso.group_mapped_roles | nindent 10 }} + {{- end }} + {{- end }} + {{- if and .Values.neuvector.sso.enabled (or .Values.sso.certificate_authority (dig "certificateAuthority" "cert" false .Values.sso)) }} + sso: + certificateAuthority: + secretName: {{ default (dig "certificateAuthority" "secretName" "" .Values.sso) .Values.sso.secretName }} + {{- end }} +{{- end }} + +monitor: + install: {{ .Values.monitoring.enabled }} + exporter: + enabled: {{ .Values.monitoring.enabled }} + {{- if or .Values.monitoring.enabled $istioInjection }} + podAnnotations: + {{- if .Values.monitoring.enabled }} + checksum/metrics-pass: {{ sha256sum $neuvectorMetricsPass }} + {{- end }} + {{- if $istioInjection }} + {{ include "istioAnnotation" . }} + {{- end }} + {{- end }} + serviceMonitor: + enabled: {{ .Values.monitoring.enabled }} + # conditional passes only for default istio: enabled, mTLS: SCRICT + {{- if and $istioInjection (eq (dig "istio" "mtls" "mode" "STRICT" .Values.neuvector.values) "STRICT") .Values.monitoring.enabled }} + scheme: https + tlsConfig: + caFile: /etc/prom-certs/root-cert.pem + certFile: /etc/prom-certs/cert-chain.pem + keyFile: /etc/prom-certs/key.pem + insecureSkipVerify: true # Prometheus does not support Istio security naming, thus skip verifying target pod certificate + {{- end }} + svc: + enabled: {{ .Values.monitoring.enabled }} + type: ClusterIP + CTRL_USERNAME: metrics + CTRL_PASSWORD: {{ $neuvectorMetricsPass }} + + +{{- if or $istioInjection $.Values.kiali.enabled }} +enforcer: + {{- if $istioInjection }} + podAnnotations: + {{ include "istioAnnotation" . }} + {{- end }} +cve: + updater: + {{- if $istioInjection }} + podAnnotations: + {{ include "istioAnnotation" . }} + {{- end }} + scanner: + {{- if $istioInjection }} + podAnnotations: + {{ include "istioAnnotation" . }} + {{- end }} +{{- end }} + +{{- if or .Values.istio.enabled $.Values.kiali.enabled }} +manager: + {{- if $istioInjection }} + podAnnotations: + {{ include "istioAnnotation" . }} + {{- end }} +{{- end }} + +networkPolicies: + enabled: {{ .Values.networkPolicies.enabled }} + controlPlaneCidr: {{ .Values.networkPolicies.controlPlaneCidr }} + ingressLabels: + {{- $gateway := default "public" .Values.neuvector.ingress.gateway }} + {{- $default := dict "app" (dig "gateways" $gateway "ingressGateway" nil .Values.istio) "istio" nil }} + {{- toYaml (dig "values" "gateways" $gateway "selector" $default .Values.istio) | nindent 4 }} +{{- end }} + +{{- /* Create secret */ -}} +{{- if .Values.neuvector.enabled }} +{{- include "values-secret" (dict "root" $ "package" .Values.neuvector "name" "neuvector" "defaults" (include "bigbang.defaults.neuvector" .)) }} +{{- end }} diff --git a/chart/templates/nexus-repository-manager/git-credentials.yaml b/chart/templates/nexus-repository-manager/git-credentials.yaml new file mode 100644 index 0000000000000000000000000000000000000000..e0ff163f82db673245a94d3c329b636d2339af44 --- /dev/null +++ b/chart/templates/nexus-repository-manager/git-credentials.yaml @@ -0,0 +1,9 @@ +{{- $nexusOldValues := default dict .Values.addons.nexus -}} +{{- $nexusValues := mergeOverwrite $nexusOldValues .Values.addons.nexusRepositoryManager -}} +{{- $gitCredsSecretDict := dict + "name" "nexusRepositoryManager" + "targetScope" $nexusValues + "releaseName" .Release.Name + "releaseNamespace" .Release.Namespace +}} +{{- include "gitCredsSecret" $gitCredsSecretDict | nindent 0 -}} diff --git a/chart/templates/nexus-repository-manager/gitrepository.yaml b/chart/templates/nexus-repository-manager/gitrepository.yaml new file mode 100644 index 0000000000000000000000000000000000000000..cba412d1238540f25338b9532282108d824e786f --- /dev/null +++ b/chart/templates/nexus-repository-manager/gitrepository.yaml @@ -0,0 +1,26 @@ +{{- $nexusOldValues := default dict .Values.addons.nexus -}} +{{- $nexusValues := mergeOverwrite $nexusOldValues .Values.addons.nexusRepositoryManager -}} +{{- if and (eq $nexusValues.sourceType "git") $nexusValues.enabled }} +{{- $gitCredsDict := dict + "name" "nexusRepositoryManager" + "packageGitScope" $nexusValues.git + "rootScope" . + "releaseName" .Release.Name +}} +apiVersion: source.toolkit.fluxcd.io/v1 +kind: GitRepository +metadata: + name: nexus-repository-manager + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: nexus-repository-manager + app.kubernetes.io/component: "developer-tools" + {{- include "commonLabels" . | nindent 4}} +spec: + interval: {{ .Values.flux.interval }} + url: {{ $nexusValues.git.repo }} + ref: + {{- include "validRef" $nexusValues.git | nindent 4 }} + {{ include "gitIgnore" . }} + {{- include "gitCredsExtended" $gitCredsDict | nindent 2 }} +{{- end }} diff --git a/chart/templates/nexus-repository-manager/helmrelease.yaml b/chart/templates/nexus-repository-manager/helmrelease.yaml new file mode 100644 index 0000000000000000000000000000000000000000..6e2bad4eaccb904eb943eb0c48fb64de573ea9ab --- /dev/null +++ b/chart/templates/nexus-repository-manager/helmrelease.yaml @@ -0,0 +1,72 @@ +{{- $nexusOldValues := default dict .Values.addons.nexus -}} +{{- $nexusValues := mergeOverwrite $nexusOldValues .Values.addons.nexusRepositoryManager -}} +{{- $fluxSettingsNexus := merge $nexusValues.flux .Values.flux -}} +{{- if $nexusValues.enabled }} +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + name: nexus-repository-manager + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: "nexus-repository-manager" + app.kubernetes.io/component: "developer-tools" + {{- include "commonLabels" . | nindent 4}} + annotations: + checksum/bigbang-values: {{ include (print $.Template.BasePath "/nexus-repository-manager/values.yaml") . | sha256sum }} +spec: + targetNamespace: nexus-repository-manager + releaseName: nexus-repository-manager + chart: + spec: + {{- if (eq $nexusValues.sourceType "git") }} + chart: {{ $nexusValues.git.path }} + sourceRef: + kind: GitRepository + name: nexus-repository-manager + namespace: {{ .Release.Namespace }} + {{- else }} + chart: {{ $nexusValues.helmRepo.chartName }} + version: {{ $nexusValues.helmRepo.tag }} + sourceRef: + kind: HelmRepository + name: {{ $nexusValues.helmRepo.repoName }} + namespace: {{ .Release.Namespace }} + {{- $repoType := include "getRepoType" (dict "repoName" .Values.neuvector.helmRepo.repoName "allRepos" $.Values.helmRepositories) -}} + {{- if (and .Values.neuvector.helmRepo.cosignVerify (eq $repoType "oci")) }} # Needs to be an OCI repo + verify: + provider: cosign + secretRef: + name: {{ printf "%s-cosign-pub" .Values.neuvector.helmRepo.repoName }} + {{- end }} + {{- end }} + interval: 5m + + {{- toYaml $fluxSettingsNexus | nindent 2 }} + + {{- if $nexusValues.postRenderers }} + postRenderers: + {{ toYaml $nexusValues.postRenderers | nindent 4 }} + {{- end }} + valuesFrom: + - name: {{ .Release.Name }}-nexus-repository-manager-values + kind: Secret + valuesKey: "common" + - name: {{ .Release.Name }}-nexus-repository-manager-values + kind: Secret + valuesKey: "defaults" + - name: {{ .Release.Name }}-nexus-repository-manager-values + kind: Secret + valuesKey: "overlays" + + {{ if or .Values.istio.enabled .Values.monitoring.enabled }} + dependsOn: + {{- if .Values.istio.enabled }} + - name: istio + namespace: {{ .Release.Namespace }} + {{- end }} + {{- if .Values.monitoring.enabled }} + - name: monitoring + namespace: {{ .Release.Namespace }} + {{- end }} + {{- end }} +{{- end }} diff --git a/chart/templates/nexus-repository-manager/imagepullsecret.yaml b/chart/templates/nexus-repository-manager/imagepullsecret.yaml new file mode 100644 index 0000000000000000000000000000000000000000..c3d6e1a7281f1d697820cb56e36bd06303c53e31 --- /dev/null +++ b/chart/templates/nexus-repository-manager/imagepullsecret.yaml @@ -0,0 +1,18 @@ +{{- $nexusOldValues := default dict .Values.addons.nexus -}} +{{- $nexusValues := mergeOverwrite $nexusOldValues .Values.addons.nexusRepositoryManager -}} +{{- if $nexusValues.enabled }} +{{- if ( include "imagePullSecret" . ) }} +apiVersion: v1 +kind: Secret +metadata: + name: private-registry + namespace: nexus-repository-manager + labels: + app.kubernetes.io/name: "nexus-repository-manager" + app.kubernetes.io/component: "developer-tools" + {{- include "commonLabels" . | nindent 4}} +type: kubernetes.io/dockerconfigjson +data: + .dockerconfigjson: {{ template "imagePullSecret" . }} +{{- end }} +{{- end }} diff --git a/chart/templates/nexus-repository-manager/namespace.yaml b/chart/templates/nexus-repository-manager/namespace.yaml new file mode 100644 index 0000000000000000000000000000000000000000..ffdb5ac5e7bc809e72126593cafd85ab235a6f15 --- /dev/null +++ b/chart/templates/nexus-repository-manager/namespace.yaml @@ -0,0 +1,13 @@ +{{- $nexusOldValues := default dict .Values.addons.nexus -}} +{{- $nexusValues := mergeOverwrite $nexusOldValues .Values.addons.nexusRepositoryManager -}} +{{- if $nexusValues.enabled }} +apiVersion: v1 +kind: Namespace +metadata: + name: nexus-repository-manager + labels: + istio-injection: {{ ternary "enabled" "disabled" (and .Values.istio.enabled (eq (dig "istio" "injection" "enabled" $nexusValues) "enabled")) }} + app.kubernetes.io/name: "nexus-repository-manager" + app.kubernetes.io/component: "developer-tools" + {{- include "commonLabels" . | nindent 4}} +{{- end }} diff --git a/chart/templates/nexus-repository-manager/secret-ca.yaml b/chart/templates/nexus-repository-manager/secret-ca.yaml new file mode 100644 index 0000000000000000000000000000000000000000..87dfe3a7dfa5292bb9d1877750431ae466291c9d --- /dev/null +++ b/chart/templates/nexus-repository-manager/secret-ca.yaml @@ -0,0 +1,12 @@ +{{- $nexusOldValues := default dict .Values.addons.nexus -}} +{{- $nexusValues := mergeOverwrite $nexusOldValues .Values.addons.nexusRepositoryManager -}} +{{- if and $nexusValues.enabled $nexusValues.sso.enabled (or .Values.sso.certificate_authority (dig "certificateAuthority" "cert" false .Values.sso)) }} +apiVersion: v1 +kind: Secret +metadata: + name: {{default (dig "certificateAuthority" "secretName" "" .Values.sso) .Values.sso.secretName}} + namespace: nexus-repository-manager +type: Opaque +data: + ca.pem: {{ default (dig "certificateAuthority" "cert" "" .Values.sso) .Values.sso.certificate_authority | b64enc }} +{{- end }} diff --git a/chart/templates/nexus-repository-manager/values.yaml b/chart/templates/nexus-repository-manager/values.yaml new file mode 100644 index 0000000000000000000000000000000000000000..a7fcd4e060b2ef92f6364ff2803407d694fdc2cc --- /dev/null +++ b/chart/templates/nexus-repository-manager/values.yaml @@ -0,0 +1,107 @@ +{{- $nexusOldValues := default dict .Values.addons.nexus -}} +{{- $nexusValues := mergeOverwrite $nexusOldValues .Values.addons.nexusRepositoryManager -}} +{{- if $nexusValues.enabled }} +{{- include "values-secret" (dict "root" $ "package" $nexusValues "name" "nexus-repository-manager" "defaults" (include "bigbang.defaults.nexus-repository-manager" .)) }} +{{- end }} + +{{- define "bigbang.defaults.nexus-repository-manager" -}} +{{- $nexusOldValues := default dict .Values.addons.nexus -}} +{{- $nexusValues := mergeOverwrite $nexusOldValues .Values.addons.nexusRepositoryManager -}} +{{- $domainName := default .Values.domain .Values.hostname }} +domain: {{ $domainName }} +hostname: nexus +istio: + enabled: {{ .Values.istio.enabled }} + hardened: + enabled: {{ or + (dig "istio" "hardened" "enabled" false $nexusValues.values) + (dig "hardened" "enabled" false .Values.istio.values) + }} + injection: {{ dig "istio" "injection" "enabled" $nexusValues }} + nexus: + gateways: + - istio-system/{{ default "public" $nexusValues.ingress.gateway }} + +openshift: {{ .Values.openshift }} + +image: + pullPolicy: {{ .Values.imagePullPolicy }} + +job_image: + pullPolicy: {{ .Values.imagePullPolicy }} + +monitoring: + enabled: {{ .Values.monitoring.enabled }} + serviceMonitor: + createMetricsUser: {{ .Values.monitoring.enabled }} + {{- if and .Values.istio.enabled (eq (dig "istio" "mtls" "mode" "STRICT" .Values.addons.velero.values) "STRICT") }} + scheme: https + tlsConfig: + caFile: /etc/prom-certs/root-cert.pem + certFile: /etc/prom-certs/cert-chain.pem + keyFile: /etc/prom-certs/key.pem + insecureSkipVerify: true # Prometheus does not support Istio security naming, thus skip verifying target + {{- end }} + +networkPolicies: + enabled: {{ .Values.networkPolicies.enabled }} + ingressLabels: + {{- $gateway := default "public" $nexusValues.ingress.gateway }} + {{- $default := dict "app" (dig "gateways" $gateway "ingressGateway" nil .Values.istio) "istio" nil }} + {{- toYaml (dig "values" "gateways" $gateway "selector" $default .Values.istio) | nindent 4 }} + +nexus: + imagePullSecrets: + - name: private-registry + {{- if .Values.istio.enabled }} + podAnnotations: + {{ include "istioAnnotation" . }} + {{- end }} + {{- if $nexusValues.license_key }} + properties: + override: true + data: + nexus.licenseFile: /nexus-data/sonatype-license.lic + {{- end }} + +license_key: "{{ $nexusValues.license_key }}" +realms: + - "NexusAuthenticatingRealm" + +{{- if $nexusValues.sso.enabled }} +sso: + enabled: {{ $nexusValues.sso.enabled }} + idp_data: + {{- if $nexusValues.sso.idp_data.entityId }} + entityId: {{ $nexusValues.sso.idp_data.entityId }} + {{- else }} + entityId: "https://nexus.{{ $domainName }}/service/rest/v1/security/saml/metadata" + {{- end }} + usernameAttribute: "{{ default "username" $nexusValues.sso.idp_data.username }}" + firstNameAttribute: "{{ default "firstName" $nexusValues.sso.idp_data.firstName }}" + lastNameAttribute: "{{ default "lastName" $nexusValues.sso.idp_data.lastName }}" + emailAttribute: "{{ default "email" $nexusValues.sso.idp_data.email }}" + groupsAttribute: "{{ default "groups" $nexusValues.sso.idp_data.groups }}" + validateResponseSignature: "true" + validateAssertionSignature: "true" + idpMetadata: '{{ default (dig "saml" "metadata" "" .Values.sso) (dig "sso" "idp_data" "idpMetadata" "" $nexusValues) }}' + + role: + {{- range $nexusValues.sso.role }} + - id: {{ .id | quote }} + name: {{ .name | quote }} + description: {{ .description | quote }} + privileges: + {{- range .privileges }} + - {{ . | quote }} + {{- else }} [] + {{- end }} + roles: + {{- range .roles }} + - {{ . | quote }} + {{- else }} [] + {{- end }} + {{- end }} + +{{- end }} +{{- end -}} diff --git a/chart/templates/package/git-credentials.yaml b/chart/templates/package/git-credentials.yaml new file mode 100644 index 0000000000000000000000000000000000000000..2079d2e67c7f1128aad1636093b2e62a9cf99c24 --- /dev/null +++ b/chart/templates/package/git-credentials.yaml @@ -0,0 +1,19 @@ +{{- /* Used for GitOps on a package's Helm chart */ -}} +{{- range $pkg, $vals := .Values.packages -}} +{{- if and (dig "enabled" true $vals) ($vals.git) -}} +{{- $pkg = include "resourceName" $pkg -}} +{{- $defaults := $.Files.Get (printf "defaults/%s.yaml" $pkg) -}} +{{- if $defaults -}} +{{- $vals := mergeOverwrite $vals ($defaults | fromYaml).package -}} +{{- end -}} +{{- $namespace := dig "namespace" "name" $pkg $vals }} +{{- $gitCredsSecretDict := dict + "name" $pkg + "targetScope" $vals + "releaseName" $pkg + "releaseNamespace" $namespace +}} +{{- include "gitCredsSecret" $gitCredsSecretDict | nindent 0 }} +--- +{{- end -}} +{{- end -}} \ No newline at end of file diff --git a/chart/templates/package/gitrepository.yaml b/chart/templates/package/gitrepository.yaml new file mode 100644 index 0000000000000000000000000000000000000000..d4267b718eb701d7ab3fb7fd34c75032b1576c4e --- /dev/null +++ b/chart/templates/package/gitrepository.yaml @@ -0,0 +1,36 @@ +{{- /* Used for GitOps on a package's Helm chart */ -}} +{{- range $pkg, $vals := .Values.packages -}} +{{- if and (dig "enabled" true $vals) ($vals.git) -}} +{{- $pkg = include "resourceName" $pkg -}} +{{- $defaults := $.Files.Get (printf "defaults/%s.yaml" $pkg) -}} +{{- if $defaults -}} +{{- $vals := mergeOverwrite $vals ($defaults | fromYaml).package -}} +{{- end -}} + +{{- $gitCredsDict := dict + "name" $pkg + "packageGitScope" $vals.git + "rootScope" $ + "releaseName" $pkg +}} +apiVersion: source.toolkit.fluxcd.io/v1 +kind: GitRepository +metadata: + name: {{ $pkg }} + namespace: {{ if dig "helmRelease" "namespace" nil (index $.Values.packages $pkg) }} + {{ dig "helmRelease" "namespace" "" (index $.Values.packages $pkg) }} + {{ else }} + {{ default (dig "namespace" "name" $pkg $vals) "" }} + {{ end }} + labels: + app.kubernetes.io/name: {{ $pkg }} + {{- include "commonLabels" $ | nindent 4 }} +spec: + interval: {{ $.Values.flux.interval }} + url: {{ dig "git" "repo" nil $vals }} + ref: + {{- include "validRef" $vals.git | nindent 4 -}} + {{- include "gitCredsExtended" $gitCredsDict | nindent 2 }} +--- +{{- end -}} +{{- end -}} \ No newline at end of file diff --git a/chart/templates/package/helmrelease.yaml b/chart/templates/package/helmrelease.yaml new file mode 100644 index 0000000000000000000000000000000000000000..8be9427c4919773d54f2931550083489fc5b19ac --- /dev/null +++ b/chart/templates/package/helmrelease.yaml @@ -0,0 +1,94 @@ +{{- /* Used for deploying a package using a Helm chart */ -}} +{{- range $pkg, $vals := .Values.packages -}} +{{- if and (dig "enabled" true $vals) (not $vals.kustomize) -}} +{{- $pkg := include "resourceName" $pkg -}} +{{- $defaults := $.Files.Get (printf "defaults/%s.yaml" $pkg) -}} +{{- if $defaults -}} +{{- $vals := mergeOverwrite $vals ($defaults | fromYaml).package -}} +{{- end -}} + +{{- $fluxSettings := merge (default $vals.flux (dict)) $.Values.flux -}} + +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + name: {{ $pkg }} + namespace: {{ if dig "helmRelease" "namespace" nil (index $.Values.packages $pkg) }} + {{ dig "helmRelease" "namespace" "" (index $.Values.packages $pkg) }} + {{ else }} + {{ default (dig "namespace" "name" $pkg $vals) "" }} + {{ end }} + labels: + app.kubernetes.io/name: {{ $pkg }} + {{- include "commonLabels" $ | nindent 4 }} + annotations: + checksum/bigbang-values: {{ (toJson $vals.values) | sha256sum }} +spec: + releaseName: {{ $pkg }} + targetNamespace: {{ dig "namespace" "name" $pkg $vals }} + chart: + spec: + {{- if $vals.git }} + chart: {{ dig "git" "path" "chart" $vals }} + sourceRef: + kind: GitRepository + name: {{ $pkg }} + namespace: {{ if dig "helmRelease" "namespace" nil (index $.Values.packages $pkg) }} + {{ dig "helmRelease" "namespace" "" (index $.Values.packages $pkg) }} + {{ else }} + {{ default (dig "namespace" "name" $pkg $vals) "" }} + {{ end }} + {{- else if $vals.helmRepo }} + chart: {{ dig "helmRepo" "chartName" $pkg $vals }} + version: {{ dig "helmRepo" "tag" nil $vals }} + sourceRef: + kind: HelmRepository + name: {{ dig "helmRepo" "repoName" "registry1" $vals }} + namespace: {{ $.Release.Namespace }} + {{- $repoType := include "getRepoType" (dict "repoName" $vals.helmRepo.repoName "allRepos" $.Values.helmRepositories) -}} + {{- if (and $vals.helmRepo.cosignVerify (eq $repoType "oci")) }} # Needs to be an OCI repo + verify: + provider: cosign + secretRef: + name: {{ printf "%s-cosign-pub" $vals.helmRepo.repoName }} + {{- end }} + {{- else }} + {{- fail (printf "Values for source (git or helmRepo) are required for package %s" $pkg) }} + {{- end }} + interval: {{ default "5m" $fluxSettings.interval }} + reconcileStrategy: Revision + {{- toYaml $fluxSettings | nindent 2 }} + {{- if $vals.postRenderers }} + postRenderers: + {{- toYaml $vals.postRenderers | nindent 4 }} + {{- end }} + valuesFrom: + - name: {{ $pkg }}-values + kind: Secret + + {{- /* Always wait on policy enforcement */ -}} + {{- $gatekeeperDep := $.Values.gatekeeper.enabled -}} + {{- $kyvernoDep := $.Values.kyvernoPolicies.enabled -}} + {{- /* Wait on istio if sidecar is enabled */ -}} + {{- $istioDep := (and $.Values.istio.enabled (eq "enabled" (dig "istio" "injection" "enabled" $vals))) -}} + {{- if or $gatekeeperDep $kyvernoDep $istioDep $vals.dependsOn }} + dependsOn: + {{- if $gatekeeperDep }} + - name: gatekeeper + namespace: {{ default "bigbang" $.Release.namespace }} + {{- end }} + {{- if $kyvernoDep }} + - name: kyverno-policies + namespace: {{ default "bigbang" $.Release.namespace }} + {{- end }} + {{- if $istioDep }} + - name: istio + namespace: {{ default "bigbang" $.Release.namespace }} + {{- end -}} + {{- if $vals.dependsOn }} + {{- toYaml $vals.dependsOn | nindent 4 }} + {{- end }} + {{- end }} +--- +{{ end -}} +{{- end -}} diff --git a/chart/templates/package/kustomization.yaml b/chart/templates/package/kustomization.yaml new file mode 100644 index 0000000000000000000000000000000000000000..fff3c8da9361c38568fc51671461f4ed9e91253d --- /dev/null +++ b/chart/templates/package/kustomization.yaml @@ -0,0 +1,38 @@ +{{- /* Used for deploying a package using Kustomize */ -}} +{{- range $pkg, $vals := .Values.packages -}} +{{- if and (dig "enabled" true $vals) $vals.kustomize -}} +{{- $pkg := include "resourceName" $pkg -}} +{{- $defaults := $.Files.Get (printf "defaults/%s.yaml" $pkg) -}} +{{- if $defaults -}} +{{- $vals := mergeOverwrite $vals ($defaults | fromYaml).package -}} +{{- end -}} +{{- $fluxSettings := merge (default $vals.flux (dict)) $.Values.flux -}} +apiVersion: kustomize.toolkit.fluxcd.io/v1 +kind: Kustomization +metadata: + name: {{ $pkg }} + namespace: {{ dig "namespace" "name" $pkg $vals }} + labels: + app.kubernetes.io/name: {{ $pkg }} + {{- include "commonLabels" $ | nindent 4 }} +spec: + targetNamespace: {{ dig "namespace" "name" $pkg $vals }} + path: {{ dig "git" "path" "" $vals }} + sourceRef: + kind: GitRepository + name: {{ $pkg }} + namespace: {{ dig "namespace" "name" $pkg $vals }} + interval: {{ dig "interval" "2m" $fluxSettings }} + timeout: {{ dig "timeout" "10m" $fluxSettings }} + force: {{ dig "force" false $fluxSettings }} + wait: {{ dig "wait" true $fluxSettings }} + retryInterval: {{ dig "retryInterval" "2m0s" $fluxSettings }} + prune: {{ dig "prune" true $fluxSettings }} + postBuild: + substituteFrom: + - name: {{ $pkg }}-values + kind: Secret + +--- +{{ end -}} +{{- end -}} diff --git a/chart/templates/package/namespace.yaml b/chart/templates/package/namespace.yaml new file mode 100644 index 0000000000000000000000000000000000000000..6424e4f5794cd89026f38687f03f294c18bef4f8 --- /dev/null +++ b/chart/templates/package/namespace.yaml @@ -0,0 +1,25 @@ +{{- /* Used for creating namespaces that package's use. */ -}} +{{- /* If two packages reside in the same namespace, set namespace.create=false in one of them. */ -}} +{{- range $pkg, $vals := .Values.packages -}} +{{- if and (dig "enabled" true $vals) (dig "namespace" "create" true $vals) -}} +{{- $pkg = include "resourceName" $pkg -}} +apiVersion: v1 +kind: Namespace +metadata: + name: {{ dig "namespace" "name" $pkg $vals }} + labels: + app.kubernetes.io/name: {{ $pkg }} + {{- include "commonLabels" $ | nindent 4 }} + {{- if $.Values.istio.enabled }} + istio-injection: {{ tpl ((dig "istio" "injection" "enabled" $vals)) $ }} + {{- end -}} + {{- if (dig "namespace" "labels" nil $vals) -}} + {{- toYaml $vals.namespace.labels | nindent 4 -}} + {{- end -}} + {{- if (dig "namespace" "annotations" nil $vals) }} + annotations: + {{- toYaml $vals.namespace.annotations | nindent 4 -}} + {{- end }} +--- +{{ end -}} +{{- end -}} \ No newline at end of file diff --git a/chart/templates/package/values.yaml b/chart/templates/package/values.yaml new file mode 100644 index 0000000000000000000000000000000000000000..c06c218d3f3fcfb0bd5c52662be067237ed3fb3f --- /dev/null +++ b/chart/templates/package/values.yaml @@ -0,0 +1,35 @@ +{{- /* Used for creating values for the package's Helm chart */ -}} +{{- range $pkg, $vals := .Values.packages -}} +{{- if (dig "enabled" true $vals) -}} +{{- $pkg = include "resourceName" $pkg -}} +{{- $defaults := $.Files.Get (printf "defaults/%s.yaml" $pkg) -}} +{{- if $defaults -}} +{{- $vals := mergeOverwrite $vals ($defaults | fromYaml).package -}} +{{- end -}} +apiVersion: v1 +kind: Secret +metadata: + name: {{ $pkg }}-values + namespace: {{ if dig "helmRelease" "namespace" nil (index $.Values.packages $pkg) }} + {{ dig "helmRelease" "namespace" "" (index $.Values.packages $pkg) }} + {{ else }} + {{ default (dig "namespace" "name" $pkg $vals) "" }} + {{ end }} + labels: + {{- include "commonLabels" $ | nindent 4 }} +type: Opaque +stringData: + {{ if and (dig "enabled" true $vals) (not $vals.kustomize) -}} + values.yaml: | + bigbang: + {{- include "values-bigbang" $.Values | nindent 6 }} + {{- if $vals.values -}} + {{- tpl (toYaml $vals.values) $ | nindent 4 }} + {{- end }} + {{ else }} + {{- tpl (toYaml $vals.values) $ | nindent 2 }} + {{ end }} + +--- +{{ end -}} +{{- end -}} \ No newline at end of file diff --git a/chart/templates/promtail/git-credentials.yaml b/chart/templates/promtail/git-credentials.yaml new file mode 100644 index 0000000000000000000000000000000000000000..9cdc75e49a79c7317bfc88c5658dd65573df3825 --- /dev/null +++ b/chart/templates/promtail/git-credentials.yaml @@ -0,0 +1,7 @@ +{{- $gitCredsSecretDict := dict + "name" "promtail" + "targetScope" .Values.promtail + "releaseName" .Release.Name + "releaseNamespace" .Release.Namespace +}} +{{- include "gitCredsSecret" $gitCredsSecretDict | nindent 0 -}} diff --git a/chart/templates/promtail/gitrepository.yaml b/chart/templates/promtail/gitrepository.yaml new file mode 100644 index 0000000000000000000000000000000000000000..eac60e10e434f7a1608a582eb403a033ea59db94 --- /dev/null +++ b/chart/templates/promtail/gitrepository.yaml @@ -0,0 +1,24 @@ +{{- if and (eq .Values.promtail.sourceType "git") (not .Values.offline) .Values.promtail.enabled }} +{{- $gitCredsDict := dict + "name" "promtail" + "packageGitScope" .Values.promtail.git + "rootScope" . + "releaseName" .Release.Name +}} +apiVersion: source.toolkit.fluxcd.io/v1 +kind: GitRepository +metadata: + name: promtail + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: promtail + app.kubernetes.io/component: "core" + {{- include "commonLabels" . | nindent 4}} +spec: + interval: {{ .Values.flux.interval }} + url: {{ .Values.promtail.git.repo }} + ref: + {{- include "validRef" .Values.promtail.git | nindent 4 }} + {{ include "gitIgnore" . }} + {{- include "gitCredsExtended" $gitCredsDict | nindent 2 }} +{{- end }} diff --git a/chart/templates/promtail/helmrelease.yaml b/chart/templates/promtail/helmrelease.yaml new file mode 100644 index 0000000000000000000000000000000000000000..921a3acf304ba4e703c11fc6dce4e7fbdebb6e95 --- /dev/null +++ b/chart/templates/promtail/helmrelease.yaml @@ -0,0 +1,77 @@ +{{- $fluxSettingsPromtail := merge .Values.promtail.flux .Values.flux -}} +{{- if .Values.promtail.enabled }} +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + name: promtail + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: promtail + app.kubernetes.io/component: "core" + {{- include "commonLabels" . | nindent 4}} + annotations: + checksum/bigbang-values: {{ include (print $.Template.BasePath "/promtail/values.yaml") . | sha256sum }} +spec: + driftDetection: + mode: warn + targetNamespace: promtail + chart: + spec: + {{- if eq .Values.promtail.sourceType "git" }} + chart: {{ .Values.promtail.git.path }} + sourceRef: + kind: GitRepository + name: promtail + namespace: {{ .Release.Namespace }} + {{- else }} + chart: {{ .Values.promtail.helmRepo.chartName }} + version: {{ .Values.promtail.helmRepo.tag }} + sourceRef: + kind: HelmRepository + name: {{ .Values.promtail.helmRepo.repoName }} + namespace: {{ .Release.Namespace }} + {{- $repoType := include "getRepoType" (dict "repoName" .Values.promtail.helmRepo.repoName "allRepos" $.Values.helmRepositories) -}} + {{- if (and .Values.promtail.helmRepo.cosignVerify (eq $repoType "oci")) }} # Needs to be an OCI repo + verify: + provider: cosign + secretRef: + name: {{ printf "%s-cosign-pub" .Values.promtail.helmRepo.repoName }} + {{- end }} + {{- end }} + interval: 5m + + {{- toYaml $fluxSettingsPromtail | nindent 2 }} + + {{- if .Values.promtail.postRenderers }} + postRenderers: + {{ toYaml .Values.promtail.postRenderers | nindent 4 }} + {{- end }} + valuesFrom: + - name: {{ .Release.Name }}-promtail-values + kind: Secret + valuesKey: "common" + - name: {{ .Release.Name }}-promtail-values + kind: Secret + valuesKey: "defaults" + - name: {{ .Release.Name }}-promtail-values + kind: Secret + valuesKey: "overlays" + + dependsOn: + {{- if .Values.loki.enabled }} + - name: loki + namespace: {{ .Release.Namespace }} + {{- end }} + {{- if .Values.gatekeeper.enabled }} + - name: gatekeeper + namespace: {{ .Release.Namespace }} + {{- end }} + {{- if .Values.istio.enabled }} + - name: istio + namespace: {{ .Release.Namespace }} + {{- end }} + {{- if .Values.kyvernoPolicies.enabled }} + - name: kyverno-policies + namespace: {{ .Release.Namespace }} + {{- end }} +{{- end }} diff --git a/chart/templates/promtail/imagepullsecret.yaml b/chart/templates/promtail/imagepullsecret.yaml new file mode 100644 index 0000000000000000000000000000000000000000..ddd52f717fa757befbf84101d1d617132bbca6e6 --- /dev/null +++ b/chart/templates/promtail/imagepullsecret.yaml @@ -0,0 +1,16 @@ +{{- if .Values.promtail.enabled }} +{{- if ( include "imagePullSecret" . ) }} +apiVersion: v1 +kind: Secret +metadata: + name: private-registry + namespace: promtail + labels: + app.kubernetes.io/name: promtail + app.kubernetes.io/component: "core" + {{- include "commonLabels" . | nindent 4}} +type: kubernetes.io/dockerconfigjson +data: + .dockerconfigjson: {{ template "imagePullSecret" . }} +{{- end }} +{{- end }} diff --git a/chart/templates/promtail/namespace.yaml b/chart/templates/promtail/namespace.yaml new file mode 100644 index 0000000000000000000000000000000000000000..a65c30ac6d647bf6624c73411aa8c3088159133c --- /dev/null +++ b/chart/templates/promtail/namespace.yaml @@ -0,0 +1,11 @@ +{{- if .Values.promtail.enabled }} +apiVersion: v1 +kind: Namespace +metadata: + name: promtail + labels: + app.kubernetes.io/name: promtail + app.kubernetes.io/component: "core" + {{- include "commonLabels" . | nindent 4}} + istio-injection: {{ ternary "enabled" "disabled" (and .Values.istio.enabled (eq (dig "istio" "injection" "enabled" .Values.promtail) "enabled")) }} +{{- end }} diff --git a/chart/templates/promtail/values.yaml b/chart/templates/promtail/values.yaml new file mode 100644 index 0000000000000000000000000000000000000000..30632d2a7d37aecb180561ffca72f3477cf27bba --- /dev/null +++ b/chart/templates/promtail/values.yaml @@ -0,0 +1,71 @@ +{{- if .Values.promtail.enabled }} +{{- include "values-secret" (dict "root" $ "package" .Values.promtail "name" "promtail" "defaults" (include "bigbang.defaults.promtail" .)) }} +{{- end }} + +{{- define "bigbang.defaults.promtail" -}} +{{- $clusterName := ( default "logging-loki" .Values.loki.clusterName ) }} +hostname: {{ .Values.hostname }} + +image: + pullPolicy: {{ .Values.imagePullPolicy }} + +openshift: {{ .Values.openshift }} + +istio: + enabled: {{ .Values.istio.enabled }} + hardened: + enabled: {{ or + (dig "istio" "hardened" "enabled" false .Values.promtail.values) + (dig "hardened" "enabled" false .Values.istio.values) + }} + +loki: + enabled: {{ .Values.loki.enabled }} + +serviceMonitor: + enabled: {{ .Values.monitoring.enabled }} + # conditional passes only for default istio: enabled, mTLS: SCRICT + {{- if and .Values.istio.enabled (eq (dig "istio" "mtls" "mode" "STRICT" .Values.promtail.values) "STRICT") }} + scheme: https + tlsConfig: + caFile: /etc/prom-certs/root-cert.pem + certFile: /etc/prom-certs/cert-chain.pem + keyFile: /etc/prom-certs/key.pem + insecureSkipVerify: true # Prometheus does not support Istio security naming, thus skip verifying target pod certificate + {{- end }} + +monitoring: + enabled: {{ .Values.monitoring.enabled }} + +networkPolicies: + enabled: {{ .Values.networkPolicies.enabled }} + controlPlaneCidr: {{ .Values.networkPolicies.controlPlaneCidr }} + +{{- if .Values.istio.enabled }} +podAnnotations: + {{ include "istioAnnotation" . }} +{{- end }} +imagePullSecrets: + - name: private-registry + +{{- if .Values.loki.enabled }} +config: + clients: + {{- if eq .Values.loki.strategy "monolith" }} + - url: http://logging-loki.logging.svc.cluster.local:3100/loki/api/v1/push + external_labels: + cluster: {{ $clusterName }} + {{- else }} + - url: http://logging-loki-write.logging.svc.cluster.local:3100/loki/api/v1/push + external_labels: + cluster: {{ $clusterName }} + {{- end }} +{{- end }} +# If loki is disabled and promtail is not +{{- if and (not .Values.loki.enabled) (.Values.promtail.enabled) }} +# Promtail must have config.clients provided +{{- if or (empty .Values.promtail.values.config) (empty .Values.promtail.values.config.clients) }} +{{- fail "If Promtail is enabled and Loki is disabled, at least one client must be provided via '.Values.promtail.values.config.clients'"}} +{{- end -}} +{{- end -}} +{{- end -}} diff --git a/chart/templates/secrets/certificateauthority.yaml b/chart/templates/secrets/certificateauthority.yaml new file mode 100644 index 0000000000000000000000000000000000000000..0329b2c92328bdaee77017601993c8113365527c --- /dev/null +++ b/chart/templates/secrets/certificateauthority.yaml @@ -0,0 +1,17 @@ +{{- /* Used for adding a trusted custom CA for SSO. One per namespace. */ -}} +{{- if (or (dig "certificate_authority" false .Values.sso) (dig "certificateAuthority" "cert" false .Values.sso)) -}} +{{- range $ns := compact (splitList " " (include "uniqueNamespaces" (merge (dict "default" false "constraint" "sso.enabled") $))) -}} +apiVersion: v1 +kind: Secret +metadata: + name: {{ default "sso-certificate-authority" $.Values.sso.secretName }} + namespace: {{ $ns }} + labels: + app.kubernetes.io/name: {{ $ns }} + {{- include "commonLabels" $ | nindent 4 }} +type: Opaque +data: + ca.pem: {{ default (dig "certificateAuthority" "cert" "" $.Values.sso) $.Values.sso.certificate_authority | b64enc }} +--- +{{ end -}} +{{- end -}} \ No newline at end of file diff --git a/chart/templates/secrets/imagepullsecret.yaml b/chart/templates/secrets/imagepullsecret.yaml new file mode 100644 index 0000000000000000000000000000000000000000..1079148e3818243e6285b718eead6755cf373b47 --- /dev/null +++ b/chart/templates/secrets/imagepullsecret.yaml @@ -0,0 +1,17 @@ +{{- /* Used for pulling images from custom registries. One per namespace */ -}} +{{- if ( include "imagePullSecret" . ) }} +{{- range $ns := compact (splitList " " (include "uniqueNamespaces" (merge (dict "default" true) .))) -}} +apiVersion: v1 +kind: Secret +metadata: + name: private-registry + namespace: {{ $ns }} + labels: + app.kubernetes.io/name: private-registry + {{- include "commonLabels" $ | nindent 4 }} +type: kubernetes.io/dockerconfigjson +data: + .dockerconfigjson: {{ template "imagePullSecret" $ }} +--- +{{- end -}} +{{- end -}} \ No newline at end of file diff --git a/chart/templates/sonarqube/git-credentials.yaml b/chart/templates/sonarqube/git-credentials.yaml new file mode 100644 index 0000000000000000000000000000000000000000..6f90e1238092b64287d6585a7eb6f5138352c5a6 --- /dev/null +++ b/chart/templates/sonarqube/git-credentials.yaml @@ -0,0 +1,7 @@ +{{- $gitCredsSecretDict := dict + "name" "sonarqube" + "targetScope" .Values.addons.sonarqube + "releaseName" .Release.Name + "releaseNamespace" .Release.Namespace +}} +{{- include "gitCredsSecret" $gitCredsSecretDict | nindent 0 -}} diff --git a/chart/templates/sonarqube/gitrepository.yaml b/chart/templates/sonarqube/gitrepository.yaml new file mode 100644 index 0000000000000000000000000000000000000000..1e870c1b3f03fc7ea521541db1169e427e5afc0f --- /dev/null +++ b/chart/templates/sonarqube/gitrepository.yaml @@ -0,0 +1,20 @@ +{{- if and (eq .Values.addons.sonarqube.sourceType "git") (not .Values.offline) .Values.addons.sonarqube.enabled }} +{{- $gitCredsDict := dict + "name" "sonarqube" + "packageGitScope" .Values.addons.sonarqube.git + "rootScope" . + "releaseName" .Release.Name +}} +apiVersion: source.toolkit.fluxcd.io/v1 +kind: GitRepository +metadata: + name: sonarqube + namespace: {{ .Release.Namespace }} +spec: + interval: {{ .Values.flux.interval }} + url: {{ .Values.addons.sonarqube.git.repo }} + ref: + {{- include "validRef" .Values.addons.sonarqube.git | nindent 4 }} + {{ include "gitIgnore" . }} + {{- include "gitCredsExtended" $gitCredsDict | nindent 2 }} +{{- end }} diff --git a/chart/templates/sonarqube/helmrelease.yaml b/chart/templates/sonarqube/helmrelease.yaml new file mode 100644 index 0000000000000000000000000000000000000000..4d15d95de842c7c02a07b55770af2cc68862ba58 --- /dev/null +++ b/chart/templates/sonarqube/helmrelease.yaml @@ -0,0 +1,80 @@ +{{- $fluxSettingsSonarqube := merge .Values.addons.sonarqube.flux .Values.flux -}} +{{- if .Values.addons.sonarqube.enabled }} +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + name: sonarqube + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: sonarqube + app.kubernetes.io/component: "core" + {{- include "commonLabels" . | nindent 4}} + annotations: + checksum/bigbang-values: {{ include (print $.Template.BasePath "/sonarqube/values.yaml") . | sha256sum }} +spec: + releaseName: sonarqube + targetNamespace: sonarqube + chart: + spec: + {{- if eq .Values.addons.sonarqube.sourceType "git" }} + chart: {{ .Values.addons.sonarqube.git.path }} + sourceRef: + kind: GitRepository + name: sonarqube + namespace: {{ .Release.Namespace }} + {{- else }} + chart: {{ .Values.addons.sonarqube.helmRepo.chartName }} + version: {{ .Values.addons.sonarqube.helmRepo.tag }} + sourceRef: + kind: HelmRepository + name: {{ .Values.addons.sonarqube.helmRepo.repoName }} + namespace: {{ .Release.Namespace }} + {{- $repoType := include "getRepoType" (dict "repoName" .Values.addons.sonarqube.helmRepo.repoName "allRepos" $.Values.helmRepositories) -}} + {{- if (and .Values.addons.sonarqube.helmRepo.cosignVerify (eq $repoType "oci")) }} # Needs to be an OCI repo + verify: + provider: cosign + secretRef: + name: {{ printf "%s-cosign-pub" .Values.addons.sonarqube.helmRepo.repoName }} + {{- end }} + {{- end }} + interval: 5m + + {{- toYaml $fluxSettingsSonarqube | nindent 2 }} + + {{- if .Values.addons.sonarqube.postRenderers }} + postRenderers: + {{ toYaml .Values.addons.sonarqube.postRenderers | nindent 4 }} + {{- end }} + valuesFrom: + - name: {{ .Release.Name }}-sonarqube-values + kind: Secret + valuesKey: "common" + - name: {{ .Release.Name }}-sonarqube-values + kind: Secret + valuesKey: "defaults" + - name: {{ .Release.Name }}-sonarqube-values + kind: Secret + valuesKey: "overlays" + + values: + + {{- if or .Values.gatekeeper.enabled .Values.istio.enabled .Values.kyvernoPolicies.enabled .Values.monitoring.enabled }} + dependsOn: + {{- if .Values.gatekeeper.enabled }} + - name: gatekeeper + namespace: {{ .Release.Namespace }} + {{- end }} + {{- if .Values.istio.enabled }} + - name: istio + namespace: {{ .Release.Namespace }} + {{- end }} + {{- if .Values.kyvernoPolicies.enabled }} + - name: kyverno-policies + namespace: {{ .Release.Namespace }} + {{- end }} + {{- if .Values.monitoring.enabled }} + - name: monitoring + namespace: {{ .Release.Namespace }} + {{- end }} + {{- end }} +{{- end }} diff --git a/chart/templates/sonarqube/imagepullsecret.yaml b/chart/templates/sonarqube/imagepullsecret.yaml new file mode 100644 index 0000000000000000000000000000000000000000..6732ac547442a41bcead6a842b09925c42b4faa3 --- /dev/null +++ b/chart/templates/sonarqube/imagepullsecret.yaml @@ -0,0 +1,12 @@ +{{- if .Values.addons.sonarqube.enabled }} +{{- if ( include "imagePullSecret" . ) }} +apiVersion: v1 +kind: Secret +metadata: + name: private-registry + namespace: sonarqube +type: kubernetes.io/dockerconfigjson +data: + .dockerconfigjson: {{ template "imagePullSecret" . }} +{{- end }} +{{- end }} diff --git a/chart/templates/sonarqube/namespace.yaml b/chart/templates/sonarqube/namespace.yaml new file mode 100644 index 0000000000000000000000000000000000000000..c61b874ed2c6f80c45e839ab03112cf957828fd7 --- /dev/null +++ b/chart/templates/sonarqube/namespace.yaml @@ -0,0 +1,11 @@ +{{- if .Values.addons.sonarqube.enabled }} +apiVersion: v1 +kind: Namespace +metadata: + name: sonarqube + labels: + app.kubernetes.io/name: sonarqube + app.kubernetes.io/component: "developer-tools" + {{- include "commonLabels" . | nindent 4}} + istio-injection: {{ ternary "enabled" "disabled" (and .Values.istio.enabled (eq (dig "istio" "injection" "enabled" .Values.addons.sonarqube) "enabled")) }} +{{- end }} diff --git a/chart/templates/sonarqube/secret-ca.yaml b/chart/templates/sonarqube/secret-ca.yaml new file mode 100644 index 0000000000000000000000000000000000000000..195c97573c2df995a542da6064bc439c0a118747 --- /dev/null +++ b/chart/templates/sonarqube/secret-ca.yaml @@ -0,0 +1,10 @@ +{{- if and .Values.addons.sonarqube.enabled .Values.addons.sonarqube.sso.enabled (or .Values.sso.certificate_authority (dig "certificateAuthority" "cert" false .Values.sso)) }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ default (dig "certificateAuthority" "secretName" "" .Values.sso) .Values.sso.secretName }} + namespace: sonarqube +type: Opaque +data: + ca.pem: {{ default (dig "certificateAuthority" "cert" "" .Values.sso) .Values.sso.certificate_authority | b64enc }} +{{- end }} \ No newline at end of file diff --git a/chart/templates/sonarqube/secret-database.yaml b/chart/templates/sonarqube/secret-database.yaml new file mode 100644 index 0000000000000000000000000000000000000000..d05cf2b0e737b260bc7f405eb7f98988abd2ff8e --- /dev/null +++ b/chart/templates/sonarqube/secret-database.yaml @@ -0,0 +1,13 @@ +{{- if .Values.addons.sonarqube.enabled }} +# create database secret +{{- if and .Values.addons.sonarqube.database.host .Values.addons.sonarqube.database.username .Values.addons.sonarqube.database.password .Values.addons.sonarqube.database.database .Values.addons.sonarqube.database.port }} +apiVersion: v1 +kind: Secret +metadata: + name: sonarqube-db-secret + namespace: sonarqube +type: kubernetes.io/opaque +stringData: + postgresql-password: {{ .Values.addons.sonarqube.database.password }} +{{- end }} +{{- end }} diff --git a/chart/templates/sonarqube/values.yaml b/chart/templates/sonarqube/values.yaml new file mode 100644 index 0000000000000000000000000000000000000000..7b1da3aa418a6457bb14b9a271bef02904f34431 --- /dev/null +++ b/chart/templates/sonarqube/values.yaml @@ -0,0 +1,97 @@ +{{- if .Values.addons.sonarqube.enabled }} +{{- include "values-secret" (dict "root" $ "package" .Values.addons.sonarqube "name" "sonarqube" "defaults" (include "bigbang.defaults.sonarqube" .)) }} +{{- end }} + +{{- define "bigbang.defaults.sonarqube" -}} +# hostname is deprecated and replaced with domain. But if hostname exists then use it. +{{- $domainName := default .Values.domain .Values.hostname }} +domain: {{ $domainName }} + +# Define variables to help with conditionals later +{{- $istioInjection := (and (eq (dig "istio" "injection" "enabled" .Values.addons.sonarqube) "enabled") .Values.istio.enabled) }} + +OpenShift: + enabled: {{ .Values.openshift }} + +istio: + enabled: {{ .Values.istio.enabled }} + hardened: + enabled: {{ or + (dig "istio" "hardened" "enabled" false .Values.addons.sonarqube.values) + (dig "hardened" "enabled" false .Values.istio.values) + }} + sonarqube: + gateways: + - istio-system/{{ default "public" .Values.addons.sonarqube.ingress.gateway }} + injection: {{ dig "istio" "injection" "enabled" .Values.addons.sonarqube }} + +monitoring: + enabled: {{ .Values.monitoring.enabled }} + +networkPolicies: + enabled: {{ .Values.networkPolicies.enabled }} + ingressLabels: + {{- $gateway := default "public" .Values.addons.sonarqube.ingress.gateway }} + {{- $default := dict "app" (dig "gateways" $gateway "ingressGateway" nil .Values.istio) "istio" nil }} + {{- toYaml (dig "values" "gateways" $gateway "selector" $default .Values.istio) | nindent 4 }} + +image: + pullPolicy: {{ .Values.imagePullPolicy }} + pullSecret: private-registry + +{{- if $istioInjection }} +annotations: + {{ include "istioAnnotation" . }} +{{- end }} + +{{- if .Values.addons.sonarqube.sso.enabled }} +sonarProperties: + sonar.auth.saml.enabled: {{ .Values.addons.sonarqube.sso.enabled }} + sonar.core.serverBaseURL: https://sonarqube.{{ $domainName }} + sonar.auth.saml.applicationId: {{ .Values.addons.sonarqube.sso.client_id }} + sonar.auth.saml.providerName: {{ coalesce .Values.addons.sonarqube.sso.provider_name .Values.addons.sonarqube.sso.label .Values.sso.name }} + sonar.auth.saml.providerId: {{ include "sso.url" . }} + sonar.auth.saml.loginUrl: {{ include "sso.saml.service" . }} + sonar.auth.saml.certificate.secured: {{ default (include "sso.saml.cert" .) .Values.addons.sonarqube.sso.certificate }} + sonar.auth.saml.user.login: {{ .Values.addons.sonarqube.sso.login | default "login" }} + sonar.auth.saml.user.name: {{ .Values.addons.sonarqube.sso.name | default "name" }} + sonar.auth.saml.user.email: {{ .Values.addons.sonarqube.sso.email | default "email" }} + {{- if .Values.addons.sonarqube.sso.group }} + sonar.auth.saml.group.name: {{ .Values.addons.sonarqube.sso.group }} + {{- end }} +{{- end }} + +{{- with .Values.addons.sonarqube.database }} + {{- if and .host .username .password .database .port }} +# External Postgres config +jdbcOverwrite: + enable: true + jdbcUrl: "jdbc:postgresql://{{ .host }}:{{ .port }}/{{ .database }}?socketTimeout=1500" + jdbcUsername: {{ .username }} + jdbcSecretName: sonarqube-db-secret + jdbcSecretPasswordKey: postgresql-password +postgresql: + # Use external database + enabled: false + {{- else }} +postgresql: + {{- if or $istioInjection $.Values.kiali.enabled}} + master: + {{- if $istioInjection }} + podAnnotations: + {{ include "istioAnnotation" $ }} + {{- end }} + slave: + {{- if $istioInjection }} + podAnnotations: + {{ include "istioAnnotation" $ }} + {{- end }} + {{- end }} + # Use internal database, defaults are fine + enabled: true + service: + port: {{ .port }} + {{- end }} +{{- end }} +{{- end -}} + diff --git a/chart/templates/tempo/git-credentials.yaml b/chart/templates/tempo/git-credentials.yaml new file mode 100644 index 0000000000000000000000000000000000000000..44f85e5e6299fc7e885d7eba98e27e849e2f5bde --- /dev/null +++ b/chart/templates/tempo/git-credentials.yaml @@ -0,0 +1,7 @@ +{{- $gitCredsSecretDict := dict + "name" "tempo" + "targetScope" .Values.tempo + "releaseName" .Release.Name + "releaseNamespace" .Release.Namespace +}} +{{- include "gitCredsSecret" $gitCredsSecretDict | nindent 0 -}} diff --git a/chart/templates/tempo/gitrepository.yaml b/chart/templates/tempo/gitrepository.yaml new file mode 100644 index 0000000000000000000000000000000000000000..4d246b3bd0c3a5ac71256ea16cf3955bfe1c5529 --- /dev/null +++ b/chart/templates/tempo/gitrepository.yaml @@ -0,0 +1,24 @@ +{{- if and (eq .Values.tempo.sourceType "git") (not .Values.offline) .Values.tempo.enabled }} +{{- $gitCredsDict := dict + "name" "tempo" + "packageGitScope" .Values.tempo.git + "rootScope" . + "releaseName" .Release.Name +}} +apiVersion: source.toolkit.fluxcd.io/v1 +kind: GitRepository +metadata: + name: tempo + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: tempo + app.kubernetes.io/component: "core" + {{- include "commonLabels" . | nindent 4}} +spec: + interval: {{ .Values.flux.interval }} + url: {{ .Values.tempo.git.repo }} + ref: + {{- include "validRef" .Values.tempo.git | nindent 4 }} + {{ include "gitIgnore" . }} + {{- include "gitCredsExtended" $gitCredsDict | nindent 2 }} +{{- end }} diff --git a/chart/templates/tempo/helmrelease.yaml b/chart/templates/tempo/helmrelease.yaml new file mode 100644 index 0000000000000000000000000000000000000000..e7ca5d51436eaa69b0c1a12c300618dbd79d140e --- /dev/null +++ b/chart/templates/tempo/helmrelease.yaml @@ -0,0 +1,74 @@ +{{- $fluxSettingsTempo := merge .Values.tempo.flux .Values.flux -}} +{{- if .Values.tempo.enabled }} +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + name: tempo + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: tempo + app.kubernetes.io/component: "core" + {{- include "commonLabels" . | nindent 4}} + annotations: + checksum/bigbang-values: {{ include (print $.Template.BasePath "/tempo/values.yaml") . | sha256sum }} +spec: + driftDetection: + mode: warn + targetNamespace: tempo + chart: + spec: + {{- if eq .Values.tempo.sourceType "git" }} + chart: {{ .Values.tempo.git.path }} + sourceRef: + kind: GitRepository + name: tempo + namespace: {{ .Release.Namespace }} + {{- else }} + chart: {{ .Values.tempo.helmRepo.chartName }} + version: {{ .Values.tempo.helmRepo.tag }} + sourceRef: + kind: HelmRepository + name: {{ .Values.tempo.helmRepo.repoName }} + namespace: {{ .Release.Namespace }} + {{- $repoType := include "getRepoType" (dict "repoName" .Values.tempo.helmRepo.repoName "allRepos" $.Values.helmRepositories) -}} + {{- if (and .Values.tempo.helmRepo.cosignVerify (eq $repoType "oci")) }} # Needs to be an OCI repo + verify: + provider: cosign + secretRef: + name: {{ printf "%s-cosign-pub" .Values.tempo.helmRepo.repoName }} + {{- end }} + {{- end }} + interval: 5m + + {{- toYaml $fluxSettingsTempo | nindent 2 }} + + {{- if .Values.tempo.postRenderers }} + postRenderers: + {{ toYaml .Values.tempo.postRenderers | nindent 4 }} + {{- end }} + valuesFrom: + - name: {{ .Release.Name }}-tempo-values + kind: Secret + valuesKey: "common" + - name: {{ .Release.Name }}-tempo-values + kind: Secret + valuesKey: "defaults" + - name: {{ .Release.Name }}-tempo-values + kind: Secret + valuesKey: "overlays" + {{- if or .Values.monitoring.enabled .Values.istio.enabled .Values.tempo.sso.enabled }} + dependsOn: + {{- if .Values.monitoring.enabled }} + - name: monitoring + namespace: {{ .Release.Namespace }} + {{- end }} + {{- if .Values.tempo.sso.enabled }} + - name: authservice + namespace: {{ .Release.Namespace }} + {{- end }} + {{- if .Values.istio.enabled }} + - name: istio + namespace: {{ .Release.Namespace }} + {{- end }} + {{- end }} +{{- end }} diff --git a/chart/templates/tempo/imagepullsecret.yaml b/chart/templates/tempo/imagepullsecret.yaml new file mode 100644 index 0000000000000000000000000000000000000000..8ff08f28f3fe69fb6c19d33392d610eb1e78a70a --- /dev/null +++ b/chart/templates/tempo/imagepullsecret.yaml @@ -0,0 +1,16 @@ +{{- if .Values.tempo.enabled }} +{{- if ( include "imagePullSecret" . ) }} +apiVersion: v1 +kind: Secret +metadata: + name: private-registry + namespace: tempo + labels: + app.kubernetes.io/name: tempo + app.kubernetes.io/component: "core" + {{- include "commonLabels" . | nindent 4}} +type: kubernetes.io/dockerconfigjson +data: + .dockerconfigjson: {{ template "imagePullSecret" . }} +{{- end }} +{{- end }} diff --git a/chart/templates/tempo/namespace.yaml b/chart/templates/tempo/namespace.yaml new file mode 100644 index 0000000000000000000000000000000000000000..8ce52cc3a30fcd58538181a130ff80fda5a6e922 --- /dev/null +++ b/chart/templates/tempo/namespace.yaml @@ -0,0 +1,11 @@ +{{- if .Values.tempo.enabled }} +apiVersion: v1 +kind: Namespace +metadata: + name: tempo + labels: + app.kubernetes.io/name: tempo + app.kubernetes.io/component: "core" + {{- include "commonLabels" . | nindent 4}} + istio-injection: {{ ternary "enabled" "disabled" (and .Values.istio.enabled (eq (dig "istio" "injection" "enabled" .Values.tempo) "enabled")) }} +{{- end }} diff --git a/chart/templates/tempo/secret-objectstore.yaml b/chart/templates/tempo/secret-objectstore.yaml new file mode 100644 index 0000000000000000000000000000000000000000..6601ed9f503a88393707a5f665ee96029a826961 --- /dev/null +++ b/chart/templates/tempo/secret-objectstore.yaml @@ -0,0 +1,15 @@ +{{- if and .Values.tempo.enabled .Values.tempo.objectStorage.accessKey .Values.tempo.objectStorage.accessSecret }} +apiVersion: v1 +kind: Secret +metadata: + name: tempo-object-storage + namespace: tempo + labels: + app.kubernetes.io/name: tempo + app.kubernetes.io/component: "core" + {{- include "commonLabels" . | nindent 4}} +type: kubernetes.io/opaque +data: + AWS_ACCESS_KEY_ID: {{ .Values.tempo.objectStorage.accessKey | b64enc }} + AWS_SECRET_ACCESS_KEY: {{ .Values.tempo.objectStorage.accessSecret | b64enc }} +{{- end }} diff --git a/chart/templates/tempo/values.yaml b/chart/templates/tempo/values.yaml new file mode 100644 index 0000000000000000000000000000000000000000..b7aeaa2733d696c5085c0982ae9357244a5d8016 --- /dev/null +++ b/chart/templates/tempo/values.yaml @@ -0,0 +1,105 @@ +{{- if .Values.tempo.enabled }} +{{- include "values-secret" (dict "root" $ "package" .Values.tempo "name" "tempo" "defaults" (include "bigbang.defaults.tempo" .)) }} +{{- end }} + +{{- define "bigbang.defaults.tempo" -}} + +{{- if .Values.istio.enabled }} +podAnnotations: + {{ include "istioAnnotation" . }} +{{- end }} + +objectStorage: + access_key_id: {{ .Values.tempo.objectStorage.accessKey }} + secret_access_key: {{ .Values.tempo.objectStorage.accessSecret }} + +tempo: + pullPolicy: {{ .Values.imagePullPolicy }} + global_overrides: + ingestion_rate_limit_bytes: 30000000 +{{- with .Values.tempo.objectStorage }} +{{- if and .endpoint .region .bucket }} + storage: + trace: + backend: s3 + s3: + endpoint: {{ .endpoint }} + bucket: {{ .bucket }} + region: {{ .region }} + insecure: {{ .insecure }} + forcepathstyle: true +{{- end }} +{{- end }} + +{{- if .Values.monitoring.enabled }} + metricsGenerator: + enabled: true + remoteWriteUrl: "http://monitoring-monitoring-kube-prometheus.monitoring.svc.cluster.local:9090/api/v1/write" +{{- end }} + +# hostname is deprecated and replaced with domain. But if hostname exists then use it. +{{- $domainName := default .Values.domain .Values.hostname }} +hostname: {{ $domainName }} +domain: {{ $domainName }} + +tempoQuery: + pullPolicy: {{ .Values.imagePullPolicy }} + +serviceAccount: + imagePullSecrets: + - name: private-registry + +networkPolicies: + enabled: {{ .Values.networkPolicies.enabled }} + controlPlaneCidr: {{ .Values.networkPolicies.controlPlaneCidr }} + ingressLabels: + {{- $gateway := default "public" .Values.tempo.ingress.gateway }} + {{- $default := dict "app" (dig "gateways" $gateway "ingressGateway" nil .Values.istio) "istio" nil }} + {{- toYaml (dig "values" "gateways" $gateway "selector" $default .Values.istio) | nindent 4 }} + +istio: + enabled: {{ .Values.istio.enabled }} + hardened: + enabled: {{ or + (dig "istio" "hardened" "enabled" false .Values.tempo.values) + (dig "hardened" "enabled" false .Values.istio.values) + }} + tempoQuery: + # Set TempoQuery UI to "tempo." if Jaeger is enabled + {{- if .Values.jaeger.enabled }} + hosts: + - "tempo.{{ .Values.domain }}" + {{- end }} + gateways: + - istio-system/{{ default "public" .Values.tempo.ingress.gateway }} + +monitoring: + enabled: {{ .Values.monitoring.enabled }} + +serviceMonitor: + enabled: {{ .Values.monitoring.enabled }} + # conditional passes only if all conditionals are true: + # - istio: enabled + # - mTLS: SCRICT + {{- if and .Values.istio.enabled (eq (dig "istio" "mtls" "mode" "STRICT" .Values.tempo.values) "STRICT") }} + scheme: https + tlsConfig: + caFile: /etc/prom-certs/root-cert.pem + certFile: /etc/prom-certs/cert-chain.pem + keyFile: /etc/prom-certs/key.pem + insecureSkipVerify: true # Prometheus does not support Istio security naming, thus skip verifying target pod certificate + {{- end }} + +sso: + enabled: {{ .Values.tempo.sso.enabled }} + +{{- if or .Values.kiali.enabled .Values.tempo.sso.enabled }} +{{- $tempoAuthserviceKey := (dig "selector" "key" "protect" .Values.addons.authservice.values) }} +{{- $tempoAuthserviceValue := (dig "selector" "value" "keycloak" .Values.addons.authservice.values) }} +podLabels: + {{- if .Values.tempo.sso.enabled }} + {{ $tempoAuthserviceKey }}: {{ $tempoAuthserviceValue }} + {{- end }} +{{- end }} + +{{- end -}} diff --git a/chart/templates/thanos/git-credentials.yaml b/chart/templates/thanos/git-credentials.yaml new file mode 100644 index 0000000000000000000000000000000000000000..0e1cbc5df8bb179ac613e3c0325901890502a27c --- /dev/null +++ b/chart/templates/thanos/git-credentials.yaml @@ -0,0 +1,7 @@ +{{- $gitCredsSecretDict := dict + "name" "tempo" + "targetScope" .Values.addons.thanos + "releaseName" .Release.Name + "releaseNamespace" .Release.Namespace +}} +{{- include "gitCredsSecret" $gitCredsSecretDict | nindent 0 -}} diff --git a/chart/templates/thanos/gitrepository.yaml b/chart/templates/thanos/gitrepository.yaml new file mode 100644 index 0000000000000000000000000000000000000000..f0672b9670593e9642369dc7144547907cd3d56f --- /dev/null +++ b/chart/templates/thanos/gitrepository.yaml @@ -0,0 +1,21 @@ +{{- $pkg := "thanos" }} +{{- if and (eq (get .Values.addons $pkg).sourceType "git") (not .Values.offline) (get .Values.addons $pkg).enabled }} +{{- $gitCredsDict := dict + "name" "thanos" + "packageGitScope" .Values.addons.thanos.git + "rootScope" . + "releaseName" .Release.Name +}} +apiVersion: source.toolkit.fluxcd.io/v1 +kind: GitRepository +metadata: + name: {{ $pkg }} + namespace: {{ .Release.Namespace }} +spec: + interval: {{ .Values.flux.interval }} + url: {{ (get .Values.addons $pkg).git.repo }} + ref: + {{- include "validRef" (get .Values.addons $pkg).git | nindent 4 }} + {{ include "gitIgnore" . }} + {{- include "gitCredsExtended" $gitCredsDict | nindent 2 }} +{{- end }} \ No newline at end of file diff --git a/chart/templates/thanos/helmrelease.yaml b/chart/templates/thanos/helmrelease.yaml new file mode 100644 index 0000000000000000000000000000000000000000..0f8bae30bbfbb71af09bb44f1d86001e25affa20 --- /dev/null +++ b/chart/templates/thanos/helmrelease.yaml @@ -0,0 +1,80 @@ +{{- $pkg := "thanos" }} +{{- $fluxSettingsThanos := merge .Values.addons.thanos.flux .Values.flux -}} +{{- if (get .Values.addons $pkg).enabled }} +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + name: {{ $pkg }} + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ $pkg }} + {{- include "commonLabels" . | nindent 4}} + annotations: + checksum/bigbang-values: {{ include (print $.Template.BasePath "/thanos/values.yaml") . | sha256sum }} +spec: + driftDetection: + mode: warn + ignore: + - paths: [""] + target: + kind: Tenant + releaseName: {{ $pkg }} + targetNamespace: {{ $pkg }} + chart: + spec: + {{- if eq (get .Values.addons $pkg).sourceType "git" }} + chart: {{ (get .Values.addons $pkg).git.path }} + sourceRef: + kind: GitRepository + name: thanos + namespace: {{ .Release.Namespace }} + {{- else }} + chart: {{ (get .Values.addons $pkg).helmRepo.chartName }} + version: {{ (get .Values.addons $pkg).helmRepo.tag }} + sourceRef: + kind: HelmRepository + name: {{ (get .Values.addons $pkg).helmRepo.repoName }} + namespace: {{ .Release.Namespace }} + {{- $repoType := include "getRepoType" (dict "repoName" (get .Values.addons $pkg).helmRepo.repoName "allRepos" $.Values.helmRepositories) -}} + {{- if (and (get .Values.addons $pkg).helmRepo.cosignVerify (eq $repoType "oci")) }} # Needs to be an OCI repo + verify: + provider: cosign + secretRef: + name: {{ printf "%s-cosign-pub" (get .Values.addons $pkg).helmRepo.repoName }} + {{- end }} + {{- end }} + interval: 5m + + {{- toYaml $fluxSettingsThanos | nindent 2 }} + + {{- if (get .Values.addons $pkg).postRenderers }} + postRenderers: + {{ toYaml (get .Values.addons $pkg).postRenderers | nindent 4 }} + {{- end }} + valuesFrom: + - name: {{ .Release.Name }}-{{ $pkg }}-values + kind: Secret + valuesKey: "common" + - name: {{ .Release.Name }}-{{ $pkg }}-values + kind: Secret + valuesKey: "defaults" + - name: {{ .Release.Name }}-{{ $pkg }}-values + kind: Secret + valuesKey: "overlays" + + {{- if or .Values.istio.enabled .Values.kyvernoPolicies.enabled .Values.monitoring.enabled }} + dependsOn: + {{- if .Values.istio.enabled }} + - name: istio + namespace: {{ .Release.Namespace }} + {{- end }} + {{- if .Values.kyvernoPolicies.enabled }} + - name: kyverno-policies + namespace: {{ .Release.Namespace }} + {{- end }} + {{- if .Values.monitoring.enabled }} + - name: monitoring + namespace: {{ .Release.Namespace }} + {{- end }} + {{- end }} +{{- end }} diff --git a/chart/templates/thanos/imagepullsecret.yaml b/chart/templates/thanos/imagepullsecret.yaml new file mode 100644 index 0000000000000000000000000000000000000000..62cc56fbdc997e1435be941341f62df26413c33d --- /dev/null +++ b/chart/templates/thanos/imagepullsecret.yaml @@ -0,0 +1,14 @@ +{{- $pkg := "thanos" }} +{{- if and (get .Values.addons $pkg).enabled ( include "imagePullSecret" . ) }} +apiVersion: v1 +kind: Secret +metadata: + name: private-registry + namespace: {{ $pkg }} + labels: + app.kubernetes.io/name: {{ $pkg }} + {{- include "commonLabels" . | nindent 4}} +type: kubernetes.io/dockerconfigjson +data: + .dockerconfigjson: {{ template "imagePullSecret" . }} +{{- end }} \ No newline at end of file diff --git a/chart/templates/thanos/namespace.yaml b/chart/templates/thanos/namespace.yaml new file mode 100644 index 0000000000000000000000000000000000000000..eeb9599dc4d3c14f87d78197b91a56d14ea30550 --- /dev/null +++ b/chart/templates/thanos/namespace.yaml @@ -0,0 +1,12 @@ +{{- $pkg := "thanos" }} +{{- if (get .Values.addons $pkg).enabled }} +apiVersion: v1 +kind: Namespace +metadata: + name: {{ $pkg }} + labels: + istio-injection: {{ ternary "enabled" "disabled" (and .Values.istio.enabled (eq (dig "istio" "injection" "enabled" (get .Values.addons $pkg)) "enabled")) }} + app.kubernetes.io/name: {{ $pkg }} + app.kubernetes.io/component: "core" + {{- include "commonLabels" . | nindent 4}} +{{- end }} \ No newline at end of file diff --git a/chart/templates/thanos/values.yaml b/chart/templates/thanos/values.yaml new file mode 100644 index 0000000000000000000000000000000000000000..f50234bff004b34632650981eec46695ef85611b --- /dev/null +++ b/chart/templates/thanos/values.yaml @@ -0,0 +1,115 @@ +{{- $pkg := "thanos" }} + +{{- /* Create secret */ -}} +{{- if (get .Values.addons $pkg).enabled }} +{{- include "values-secret" (dict "root" $ "package" (get .Values.addons $pkg) "name" $pkg "defaults" (include (printf "bigbang.defaults.%s" $pkg) .)) }} +{{- end }} + +{{- define "bigbang.defaults.thanos" -}} +{{- $thanosS3Endpoint := (printf "%s.s3.dualstack.%s.amazonaws.com" .Values.addons.thanos.objectStorage.bucket .Values.addons.thanos.objectStorage.region) }} + +imagePullSecrets: +- name: private-registry +imagePullPolicy: {{ .Values.imagePullPolicy }} + +externalURL: https://thanos.{{ .Values.domain }} + +domain: {{ .Values.domain }} + +istio: + enabled: {{ .Values.istio.enabled }} + hardened: + enabled: {{ or + (dig "istio" "hardened" "enabled" false .Values.addons.thanos.values) + (dig "hardened" "enabled" false .Values.istio.values) + }} + {{- if and (or (dig "values" "istio" "hardened" "enabled" false .Values.addons.thanos) (dig "hardened" "enabled" false .Values.istio.values)) (contains "s3" .Values.addons.thanos.objectStorage.endpoint) }} + customServiceEntries: + - name: egress-object-store + enabled: true + spec: + hosts: + - {{ $thanosS3Endpoint }} + location: MESH_EXTERNAL + ports: + - number: 443 + protocol: TLS + name: https + resolution: DNS + {{- end }} + thanos: + gateways: + - istio-system/{{ default "public" .Values.addons.thanos.ingress.gateway }} + +{{- with .Values.addons.thanos.objectStorage }} +{{- if and (eq $.Values.addons.thanos.strategy "scalable") (not (and .endpoint .region)) }} +minio: + enabled: true +{{- end }} +{{- end }} + +networkPolicies: + enabled: {{ .Values.networkPolicies.enabled }} + controlPlaneCidr: {{ .Values.networkPolicies.controlPlaneCidr }} + ingressLabels: + {{- $gateway := default "public" .Values.addons.thanos.ingress.gateway }} + {{- $default := dict "app" (dig "gateways" $gateway "ingressGateway" nil .Values.istio) "istio" nil }} + {{- toYaml (dig "values" "gateways" $gateway "selector" $default .Values.istio) | nindent 4 }} + +monitoring: + enabled: {{ .Values.monitoring.enabled }} + +storegateway: + enabled: false + +query: + dnsDiscovery: + # to allow lookups to work with and without Istio enabled, we disable k8s dns service + # discovery and manually set stores: below. + # + # With Istio, the combination of headless service + TCP port will create an entry + # for each pod IP:PORT and that makes communication via IP:PORT viable + enabled: false + {{- if or .Values.monitoring.enabled (dig "values" "storegateway" "enabled" false .Values.addons.thanos) }} + stores: + {{- end }} + {{- if .Values.monitoring.enabled }} + - dns+monitoring-monitoring-kube-thanos-discovery.monitoring.svc.cluster.local:10901 + {{- end }} + {{- if (dig "values" "storegateway" "enabled" false .Values.addons.thanos) }} + - dns+thanos-storegateway.thanos.svc.cluster.local:10901 + {{- end }} + {{- if or .Values.addons.thanos.sso.enabled .Values.kiali.enabled }} + podLabels: + {{- if .Values.addons.thanos.sso.enabled }} + {{- $thanosAuthserviceKey := (dig "selector" "key" "protect" .Values.addons.authservice.values) }} + {{- $thanosAuthserviceValue := (dig "selector" "value" "keycloak" .Values.addons.authservice.values) }} + {{ $thanosAuthserviceKey }}: {{ $thanosAuthserviceValue }} + {{- end }} + {{- end }} + +{{- if or (dig "compactor" "enabled" false .Values.addons.thanos.values) (not (.Values.addons.thanos.objectStorage.endpoint | empty)) }} +compactor: + enabled: true +{{- end }} + +{{- if not (.Values.addons.thanos.objectStorage.endpoint | empty) }} +objstoreConfig: |- + type: s3 + config: + bucket: {{ .Values.addons.thanos.objectStorage.bucket }} + endpoint: {{ .Values.addons.thanos.objectStorage.endpoint }} + access_key: {{ .Values.addons.thanos.objectStorage.accessKey }} + secret_key: {{ .Values.addons.thanos.objectStorage.accessSecret }} + insecure: {{ .Values.addons.thanos.objectStorage.insecure }} + +storegateway: + enabled: true + useEndpointGroup: true + endpoint: {{ .Values.addons.thanos.objectStorage.endpoint }} + +query: + extraFlags: + - "--endpoint=dns+monitoring-monitoring-kube-thanos-discovery.monitoring.svc.cluster.local:{{- dig "values" "query" "containerPorts" "grpc" 10901 .Values.addons.thanos }}" +{{- end }} +{{- end }} diff --git a/chart/templates/twistlock/git-credentials.yaml b/chart/templates/twistlock/git-credentials.yaml new file mode 100644 index 0000000000000000000000000000000000000000..d1e3f50cf7294c7d760146724e897bbc664ba69e --- /dev/null +++ b/chart/templates/twistlock/git-credentials.yaml @@ -0,0 +1,7 @@ +{{- $gitCredsSecretDict := dict + "name" "twistlock" + "targetScope" .Values.twistlock + "releaseName" .Release.Name + "releaseNamespace" .Release.Namespace +}} +{{- include "gitCredsSecret" $gitCredsSecretDict | nindent 0 -}} diff --git a/chart/templates/twistlock/gitrepository.yaml b/chart/templates/twistlock/gitrepository.yaml new file mode 100644 index 0000000000000000000000000000000000000000..0844bb76baeb13195d038169f39150998944eb0a --- /dev/null +++ b/chart/templates/twistlock/gitrepository.yaml @@ -0,0 +1,25 @@ +{{- if and (eq .Values.twistlock.sourceType "git") (not .Values.offline) .Values.twistlock.enabled }} +{{- $gitCredsDict := dict + "name" "twistlock" + "packageGitScope" .Values.twistlock.git + "rootScope" . + "releaseName" .Release.Name +}} +apiVersion: source.toolkit.fluxcd.io/v1 +kind: GitRepository +metadata: + name: twistlock + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: twistlock + app.kubernetes.io/component: "security" + {{- include "commonLabels" . | nindent 4}} +spec: + interval: {{ .Values.flux.interval }} + url: {{ .Values.twistlock.git.repo }} + ref: + {{- include "validRef" .Values.twistlock.git | nindent 4 }} + {{ include "gitIgnore" . }} + !/chart/scripts/*.sh + {{- include "gitCredsExtended" $gitCredsDict | nindent 2 }} +{{- end }} diff --git a/chart/templates/twistlock/helmrelease.yaml b/chart/templates/twistlock/helmrelease.yaml new file mode 100644 index 0000000000000000000000000000000000000000..2324ab8449178f5b42fd86e19e08c40c4bd7e04a --- /dev/null +++ b/chart/templates/twistlock/helmrelease.yaml @@ -0,0 +1,78 @@ +{{- $fluxSettingsTwistlock := merge .Values.twistlock.flux .Values.flux -}} +{{- if .Values.twistlock.enabled }} +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + name: twistlock + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: twistlock + app.kubernetes.io/component: "security" + {{- include "commonLabels" . | nindent 4}} + annotations: + checksum/bigbang-values: {{ include (print $.Template.BasePath "/twistlock/values.yaml") . | sha256sum }} +spec: + targetNamespace: twistlock + chart: + spec: + {{- if eq .Values.twistlock.sourceType "git" }} + chart: {{ .Values.twistlock.git.path }} + sourceRef: + kind: GitRepository + name: twistlock + namespace: {{ .Release.Namespace }} + {{- else }} + chart: {{ .Values.twistlock.helmRepo.chartName }} + version: {{ .Values.twistlock.helmRepo.tag }} + sourceRef: + kind: HelmRepository + name: {{ .Values.twistlock.helmRepo.repoName }} + namespace: {{ .Release.Namespace }} + {{- $repoType := include "getRepoType" (dict "repoName" .Values.twistlock.helmRepo.repoName "allRepos" $.Values.helmRepositories) -}} + {{- if (and .Values.twistlock.helmRepo.cosignVerify (eq $repoType "oci")) }} # Needs to be an OCI repo + verify: + provider: cosign + secretRef: + name: {{ printf "%s-cosign-pub" .Values.twistlock.helmRepo.repoName }} + {{- end }} + {{- end }} + interval: 5m + + {{- toYaml $fluxSettingsTwistlock | nindent 2 }} + + {{- if .Values.twistlock.postRenderers }} + postRenderers: + {{ toYaml .Values.twistlock.postRenderers | nindent 4 }} + {{- end }} + valuesFrom: + - name: {{ .Release.Name }}-twistlock-values + kind: Secret + valuesKey: "common" + - name: {{ .Release.Name }}-twistlock-values + kind: Secret + valuesKey: "defaults" + - name: {{ .Release.Name }}-twistlock-values + kind: Secret + valuesKey: "overlays" + + # TODO: DRY this up + {{- if or .Values.gatekeeper.enabled .Values.istio.enabled .Values.kyvernoPolicies.enabled .Values.monitoring.enabled }} + dependsOn: + {{- if .Values.gatekeeper.enabled }} + - name: gatekeeper + namespace: {{ .Release.Namespace }} + {{- end }} + {{- if .Values.istio.enabled }} + - name: istio + namespace: {{ .Release.Namespace }} + {{- end }} + {{- if .Values.kyvernoPolicies.enabled }} + - name: kyverno-policies + namespace: {{ .Release.Namespace }} + {{- end }} + {{- if .Values.monitoring.enabled }} + - name: monitoring + namespace: {{ .Release.Namespace }} + {{- end }} + {{- end }} +{{- end }} diff --git a/chart/templates/twistlock/imagepullsecret.yaml b/chart/templates/twistlock/imagepullsecret.yaml new file mode 100644 index 0000000000000000000000000000000000000000..a35f89bb8593b708d05d0ae91ab1e43fda20738a --- /dev/null +++ b/chart/templates/twistlock/imagepullsecret.yaml @@ -0,0 +1,16 @@ +{{- if .Values.twistlock.enabled }} +{{- if ( include "imagePullSecret" . ) }} +apiVersion: v1 +kind: Secret +metadata: + name: private-registry + namespace: twistlock + labels: + app.kubernetes.io/name: twistlock + app.kubernetes.io/component: "security" + {{- include "commonLabels" . | nindent 4}} +type: kubernetes.io/dockerconfigjson +data: + .dockerconfigjson: {{ template "imagePullSecret" . }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/chart/templates/twistlock/namespace.yaml b/chart/templates/twistlock/namespace.yaml new file mode 100644 index 0000000000000000000000000000000000000000..be18dc68e926566fa1979deb1c6939c655c54654 --- /dev/null +++ b/chart/templates/twistlock/namespace.yaml @@ -0,0 +1,11 @@ +{{- if .Values.twistlock.enabled }} +apiVersion: v1 +kind: Namespace +metadata: + name: twistlock + labels: + app.kubernetes.io/name: twistlock + app.kubernetes.io/component: "security" + {{- include "commonLabels" . | nindent 4}} + istio-injection: {{ ternary "enabled" "disabled" (and .Values.istio.enabled (eq (dig "istio" "injection" "enabled" .Values.twistlock) "enabled")) }} +{{- end }} \ No newline at end of file diff --git a/chart/templates/twistlock/values.yaml b/chart/templates/twistlock/values.yaml new file mode 100644 index 0000000000000000000000000000000000000000..a2a95fb21ed66158247bd976632d56f821f0fb7d --- /dev/null +++ b/chart/templates/twistlock/values.yaml @@ -0,0 +1,69 @@ +{{- if .Values.twistlock.enabled }} +{{- include "values-secret" (dict "root" $ "package" .Values.twistlock "name" "twistlock" "defaults" (include "bigbang.defaults.twistlock" .)) }} +{{- end }} + +{{- define "bigbang.defaults.twistlock" -}} +# hostname is deprecated and replaced with domain. But if hostname exists then use it. +{{- $domainName := default .Values.domain .Values.hostname }} +domain: {{ $domainName }} + +openshift: {{ .Values.openshift }} + +monitoring: + enabled: {{ .Values.monitoring.enabled }} + serviceMonitor: + enabled: {{ .Values.monitoring.enabled }} + # conditional passes only for default istio: enabled, mTLS: SCRICT + {{- if and .Values.istio.enabled (eq (dig "istio" "mtls" "mode" "STRICT" .Values.twistlock.values) "STRICT") }} + scheme: https + tlsConfig: + caFile: /etc/prom-certs/root-cert.pem + certFile: /etc/prom-certs/cert-chain.pem + keyFile: /etc/prom-certs/key.pem + insecureSkipVerify: true # Prometheus does not support Istio security naming, thus skip verifying target pod certificate + {{- end }} + +imagePullSecrets: +- name: private-registry + +networkPolicies: + enabled: {{ .Values.networkPolicies.enabled }} + ingressLabels: + {{- $gateway := default "public" .Values.twistlock.ingress.gateway }} + {{- $default := dict "app" (dig "gateways" $gateway "ingressGateway" nil .Values.istio) "istio" nil }} + {{- toYaml (dig "values" "gateways" $gateway "selector" $default .Values.istio) | nindent 4 }} + controlPlaneCidr: {{ .Values.networkPolicies.controlPlaneCidr }} + nodeCidr: {{ .Values.networkPolicies.nodeCidr }} + +istio: + enabled: {{ .Values.istio.enabled }} + hardened: + enabled: {{ or + (dig "istio" "hardened" "enabled" false .Values.twistlock.values) + (dig "hardened" "enabled" false .Values.istio.values) + }} + console: + gateways: + - istio-system/{{ default "public" .Values.twistlock.ingress.gateway }} + +{{- if .Values.istio.enabled }} +annotations: + {{ include "istioAnnotation" . }} +{{- end }} + +console: + image: + imagePullPolicy: {{ .Values.imagePullPolicy }} + +sso: + enabled: {{ .Values.twistlock.sso.enabled }} + client_id: {{ .Values.twistlock.sso.client_id }} + provider_name: {{ default .Values.sso.name .Values.twistlock.sso.provider_name }} + provider_type: {{ .Values.twistlock.sso.provider_type }} + issuer_uri: {{ default (include "sso.url" .) (tpl (default "" .Values.twistlock.sso.issuer_uri) .) }} + idp_url: {{ default (include "sso.saml.service" .) (tpl (default "" .Values.twistlock.sso.idp_url) .) }} + {{- $console := first (dig "istio" "console" "hosts" (list (printf "twistlock.%s" $domainName)) .Values.twistlock.values) }} + console_url: {{ tpl (default (printf "https://%s" $console) .Values.twistlock.sso.console_url) . }} + groups: {{ .Values.twistlock.sso.groups }} + cert: {{ default (include "sso.saml.cert.withheaders" .) .Values.twistlock.sso.cert | quote }} +{{- end -}} diff --git a/chart/templates/vault/git-credentials.yaml b/chart/templates/vault/git-credentials.yaml new file mode 100644 index 0000000000000000000000000000000000000000..0ea2da4e4cf26da5c536ced19f2675b6a17a9b35 --- /dev/null +++ b/chart/templates/vault/git-credentials.yaml @@ -0,0 +1,7 @@ +{{- $gitCredsSecretDict := dict + "name" "vault" + "targetScope" .Values.addons.vault + "releaseName" .Release.Name + "releaseNamespace" .Release.Namespace +}} +{{- include "gitCredsSecret" $gitCredsSecretDict | nindent 0 -}} diff --git a/chart/templates/vault/gitrepository.yaml b/chart/templates/vault/gitrepository.yaml new file mode 100644 index 0000000000000000000000000000000000000000..1e591c3df7a2924d327b5e013a513893f6f9d247 --- /dev/null +++ b/chart/templates/vault/gitrepository.yaml @@ -0,0 +1,24 @@ +{{- if and (eq .Values.addons.vault.sourceType "git") (not .Values.offline) .Values.addons.vault.enabled }} +{{- $gitCredsDict := dict + "name" "vault" + "packageGitScope" .Values.addons.vault.git + "rootScope" . + "releaseName" .Release.Name +}} +apiVersion: source.toolkit.fluxcd.io/v1 +kind: GitRepository +metadata: + name: vault + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: vault + app.kubernetes.io/component: "security-tools" + {{- include "commonLabels" . | nindent 4}} +spec: + interval: {{ .Values.flux.interval }} + url: {{ .Values.addons.vault.git.repo }} + ref: + {{- include "validRef" .Values.addons.vault.git | nindent 4 }} + {{ include "gitIgnore" . }} + {{- include "gitCredsExtended" $gitCredsDict | nindent 2 }} +{{- end }} diff --git a/chart/templates/vault/helmrelease.yaml b/chart/templates/vault/helmrelease.yaml new file mode 100644 index 0000000000000000000000000000000000000000..4e4258fddcbd5941c26d10eac4b52e92df73f98a --- /dev/null +++ b/chart/templates/vault/helmrelease.yaml @@ -0,0 +1,72 @@ +{{- $fluxSettingsVault := merge .Values.addons.vault.flux .Values.flux -}} + +{{- if .Values.addons.vault.enabled }} +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + name: vault + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: vault + app.kubernetes.io/component: "security-tools" + {{- include "commonLabels" . | nindent 4}} + annotations: + checksum/bigbang-values: {{ include (print $.Template.BasePath "/vault/values.yaml") . | sha256sum }} +spec: + targetNamespace: vault + chart: + spec: + {{- if eq .Values.addons.vault.sourceType "git" }} + chart: {{ .Values.addons.vault.git.path }} + sourceRef: + kind: GitRepository + name: vault + namespace: {{ .Release.Namespace }} + {{- else }} + chart: {{ .Values.addons.vault.helmRepo.chartName }} + version: {{ .Values.addons.vault.helmRepo.tag }} + sourceRef: + kind: HelmRepository + name: {{ .Values.addons.vault.helmRepo.repoName }} + namespace: {{ .Release.Namespace }} + {{- $repoType := include "getRepoType" (dict "repoName" .Values.addons.vault.helmRepo.repoName "allRepos" $.Values.helmRepositories) -}} + {{- if (and .Values.addons.vault.helmRepo.cosignVerify (eq $repoType "oci")) }} # Needs to be an OCI repo + verify: + provider: cosign + secretRef: + name: {{ printf "%s-cosign-pub" .Values.addons.vault.helmRepo.repoName }} + {{- end }} + {{- end }} + interval: 5m + + {{- toYaml $fluxSettingsVault | nindent 2 }} + + {{- if .Values.addons.vault.postRenderers }} + postRenderers: + {{ toYaml .Values.addons.vault.postRenderers | nindent 4 }} + {{- end }} + valuesFrom: + - name: {{ .Release.Name }}-vault-values + kind: Secret + valuesKey: "common" + - name: {{ .Release.Name }}-vault-values + kind: Secret + valuesKey: "defaults" + - name: {{ .Release.Name }}-vault-values + kind: Secret + valuesKey: "overlays" + + # TODO: DRY this up + {{- if or .Values.istio.enabled (dig "values" "minio" "enabled" false .Values.addons.vault ) }} + dependsOn: + {{- if .Values.istio.enabled }} + - name: istio + namespace: {{ .Release.Namespace }} + {{- end }} + + {{- if (dig "values" "minio" "enabled" false .Values.addons.vault) }} + - name: minio-operator + namespace: {{ $.Release.Namespace }} + {{- end }} + {{- end }} +{{- end }} diff --git a/chart/templates/vault/imagepullsecret.yaml b/chart/templates/vault/imagepullsecret.yaml new file mode 100644 index 0000000000000000000000000000000000000000..935c73838d86d5cd597fed17f06247520829e97f --- /dev/null +++ b/chart/templates/vault/imagepullsecret.yaml @@ -0,0 +1,16 @@ +{{- if .Values.addons.vault.enabled }} +{{- if ( include "imagePullSecret" . ) }} +apiVersion: v1 +kind: Secret +metadata: + name: private-registry + namespace: vault + labels: + app.kubernetes.io/name: vault + app.kubernetes.io/component: "security-tools" + {{- include "commonLabels" . | nindent 4}} +type: kubernetes.io/dockerconfigjson +data: + .dockerconfigjson: {{ template "imagePullSecret" . }} +{{- end }} +{{- end }} diff --git a/chart/templates/vault/namespace.yaml b/chart/templates/vault/namespace.yaml new file mode 100644 index 0000000000000000000000000000000000000000..f0d0a8a9d16b165732c5be2dc7e89a1e3e54274a --- /dev/null +++ b/chart/templates/vault/namespace.yaml @@ -0,0 +1,11 @@ +{{- if .Values.addons.vault.enabled }} +apiVersion: v1 +kind: Namespace +metadata: + name: vault + labels: + app.kubernetes.io/name: vault + app.kubernetes.io/component: "security-tools" + {{- include "commonLabels" . | nindent 4}} + istio-injection: {{ ternary "enabled" "disabled" (and .Values.istio.enabled (eq (dig "istio" "injection" "enabled" .Values.addons.vault) "enabled")) }} +{{- end }} diff --git a/chart/templates/vault/values.yaml b/chart/templates/vault/values.yaml new file mode 100644 index 0000000000000000000000000000000000000000..78d408eefab1bef1c84057dee9bf98423466f779 --- /dev/null +++ b/chart/templates/vault/values.yaml @@ -0,0 +1,86 @@ +{{- if .Values.addons.vault.enabled }} +{{- include "values-secret" (dict "root" $ "package" .Values.addons.vault "name" "vault" "defaults" (include "bigbang.defaults.vault" .)) }} +{{- end }} + +{{- define "bigbang.defaults.vault" -}} +# hostname is deprecated and replaced with domain. But if hostname exists then use it. +{{- $domainName := default .Values.domain .Values.hostname }} +domain: {{ $domainName }} + +openshift: {{ .Values.openshift }} + +prometheus: + servicemonitor: + enabled: {{ .Values.monitoring.enabled }} + +monitoring: + enabled: {{ .Values.monitoring.enabled }} + +global: + imagePullSecrets: + - name: private-registry + +injector: + {{- if .Values.istio.enabled }} + annotations: + {{ include "istioAnnotation" . }} + {{- end }} + image: + pullPolicy: {{ .Values.imagePullPolicy }} + +server: + {{- if .Values.istio.enabled }} + annotations: + {{ include "istioAnnotation" . }} + {{- end }} + image: + pullPolicy: {{ .Values.imagePullPolicy }} + {{- if and .Values.addons.vault.ingress.cert .Values.addons.vault.ingress.key }} + {{- if eq .Values.addons.vault.ingress.gateway "passthrough" }} + volumes: + - name: tls + secret: + secretName: vault-tls + volumeMounts: + - name: tls + mountPath: "/vault/tls" + readOnly: true + {{- end }} + {{- end }} + +csi: + image: + pullPolicy: {{ .Values.imagePullPolicy }} + +networkPolicies: + enabled: {{ .Values.networkPolicies.enabled }} + ingressLabels: + {{- $gateway := default "public" .Values.addons.vault.ingress.gateway }} + {{- $default := dict "app" (dig "gateways" $gateway "ingressGateway" nil .Values.istio) "istio" nil }} + {{- toYaml (dig "values" "gateways" $gateway "selector" $default .Values.istio) | nindent 4 }} + controlPlaneCidr: {{ .Values.networkPolicies.controlPlaneCidr }} + nodeCidr: {{ .Values.networkPolicies.nodeCidr }} + vpcCidr: {{ .Values.networkPolicies.vpcCidr }} + +istio: + enabled: {{ .Values.istio.enabled }} + hardened: + enabled: {{ or + (dig "istio" "hardened" "enabled" false .Values.addons.vault.values) + (dig "hardened" "enabled" false .Values.istio.values) + }} + vault: + gateways: + - istio-system/{{ default "public" .Values.addons.vault.ingress.gateway }} + {{- if and .Values.addons.vault.ingress.cert .Values.addons.vault.ingress.key }} + tls: + cert: {{ .Values.addons.vault.ingress.cert | quote }} + key: {{ .Values.addons.vault.ingress.key | quote }} + {{- end }} + +{{- if .Values.istio.enabled }} +minio: + annotations: + {{ include "istioAnnotation" . }} +{{- end }} +{{- end -}} diff --git a/chart/templates/velero/git-credentials.yaml b/chart/templates/velero/git-credentials.yaml new file mode 100644 index 0000000000000000000000000000000000000000..74f09ace83fdbf24071a2effcbf7587876e3dc41 --- /dev/null +++ b/chart/templates/velero/git-credentials.yaml @@ -0,0 +1,7 @@ +{{- $gitCredsSecretDict := dict + "name" "velero" + "targetScope" .Values.addons.velero + "releaseName" .Release.Name + "releaseNamespace" .Release.Namespace +}} +{{- include "gitCredsSecret" $gitCredsSecretDict | nindent 0 -}} diff --git a/chart/templates/velero/gitrepository.yaml b/chart/templates/velero/gitrepository.yaml new file mode 100644 index 0000000000000000000000000000000000000000..1244a5f68a245b5c2e43981063d865f0fc8e73df --- /dev/null +++ b/chart/templates/velero/gitrepository.yaml @@ -0,0 +1,24 @@ +{{- if and (eq .Values.addons.velero.sourceType "git") .Values.addons.velero.enabled }} +{{- $gitCredsDict := dict + "name" "velero" + "packageGitScope" .Values.addons.velero.git + "rootScope" . + "releaseName" .Release.Name +}} +apiVersion: source.toolkit.fluxcd.io/v1 +kind: GitRepository +metadata: + name: velero + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: velero + app.kubernetes.io/component: "cluster-utilities" + {{- include "commonLabels" . | nindent 4}} +spec: + interval: {{ .Values.flux.interval }} + url: {{ .Values.addons.velero.git.repo }} + ref: + {{- include "validRef" .Values.addons.velero.git | nindent 4 }} + {{ include "gitIgnore" . }} + {{- include "gitCredsExtended" $gitCredsDict | nindent 2 }} +{{- end }} diff --git a/chart/templates/velero/helmrelease.yaml b/chart/templates/velero/helmrelease.yaml new file mode 100644 index 0000000000000000000000000000000000000000..e25a49034d0cca3fac6f9c3752e5c9cb28852606 --- /dev/null +++ b/chart/templates/velero/helmrelease.yaml @@ -0,0 +1,72 @@ +{{- $fluxSettingsVelero := merge .Values.addons.velero.flux .Values.flux -}} +{{- if .Values.addons.velero.enabled }} +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + name: velero + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: velero + app.kubernetes.io/component: "cluster-utilities" + {{- include "commonLabels" . | nindent 4}} + annotations: + checksum/bigbang-values: {{ include (print $.Template.BasePath "/velero/values.yaml") . | sha256sum }} +spec: + targetNamespace: velero + chart: + spec: + {{- if eq .Values.addons.velero.sourceType "git" }} + chart: {{ .Values.addons.velero.git.path }} + sourceRef: + kind: GitRepository + name: velero + namespace: {{ .Release.Namespace }} + {{- else }} + chart: {{ .Values.addons.velero.helmRepo.chartName }} + version: {{ .Values.addons.velero.helmRepo.tag }} + sourceRef: + kind: HelmRepository + name: {{ .Values.addons.velero.helmRepo.repoName }} + namespace: {{ .Release.Namespace }} + {{- $repoType := include "getRepoType" (dict "repoName" .Values.addons.velero.helmRepo.repoName "allRepos" $.Values.helmRepositories) -}} + {{- if (and .Values.addons.velero.helmRepo.cosignVerify (eq $repoType "oci")) }} # Needs to be an OCI repo + verify: + provider: cosign + secretRef: + name: {{ printf "%s-cosign-pub" .Values.addons.velero.helmRepo.repoName }} + {{- end }} + {{- end }} + interval: 5m + + {{- toYaml $fluxSettingsVelero | nindent 2 }} + + {{- if .Values.addons.velero.postRenderers }} + postRenderers: + {{ toYaml .Values.addons.velero.postRenderers | nindent 4 }} + {{- end }} + valuesFrom: + - name: {{ .Release.Name }}-velero-values + kind: Secret + valuesKey: "common" + - name: {{ .Release.Name }}-velero-values + kind: Secret + valuesKey: "defaults" + - name: {{ .Release.Name }}-velero-values + kind: Secret + valuesKey: "overlays" + {{- if or .Values.istio.enabled .Values.kyvernoPolicies.enabled .Values.monitoring.enabled }} + dependsOn: + {{- if .Values.istio.enabled }} + - name: istio + namespace: {{ .Release.Namespace }} + {{- end }} + {{- if .Values.kyvernoPolicies.enabled }} + - name: kyverno-policies + namespace: {{ .Release.Namespace }} + {{- end }} + {{- if .Values.monitoring.enabled }} + - name: monitoring + namespace: {{ .Release.Namespace }} + {{- end }} + {{- end }} +{{- end }} diff --git a/chart/templates/velero/imagepullsecret.yaml b/chart/templates/velero/imagepullsecret.yaml new file mode 100644 index 0000000000000000000000000000000000000000..ecf9e14bafa11517e6e8dd596a9f7d34bfa23ffc --- /dev/null +++ b/chart/templates/velero/imagepullsecret.yaml @@ -0,0 +1,16 @@ +{{- if .Values.addons.velero.enabled }} +{{- if ( include "imagePullSecret" . ) }} +apiVersion: v1 +kind: Secret +metadata: + name: private-registry + namespace: velero + labels: + app.kubernetes.io/name: velero + app.kubernetes.io/component: "cluster-utilities" + {{- include "commonLabels" . | nindent 4 }} +type: kubernetes.io/dockerconfigjson +data: + .dockerconfigjson: {{ template "imagePullSecret" . }} +{{- end }} +{{- end }} diff --git a/chart/templates/velero/namespace.yaml b/chart/templates/velero/namespace.yaml new file mode 100644 index 0000000000000000000000000000000000000000..525716a60c3d635f9d075edcf7184ce1bc03d44a --- /dev/null +++ b/chart/templates/velero/namespace.yaml @@ -0,0 +1,11 @@ +{{- if .Values.addons.velero.enabled }} +apiVersion: v1 +kind: Namespace +metadata: + name: velero + labels: + app.kubernetes.io/name: velero + app.kubernetes.io/component: "cluster-utilities" + {{- include "commonLabels" . | nindent 4 }} + istio-injection: {{ ternary "enabled" "disabled" (and .Values.istio.enabled (eq (dig "istio" "injection" "enabled" .Values.addons.velero) "enabled")) }} +{{- end }} diff --git a/chart/templates/velero/values.yaml b/chart/templates/velero/values.yaml new file mode 100644 index 0000000000000000000000000000000000000000..a390861c851c7d0575986e41b79b432f1f4b3447 --- /dev/null +++ b/chart/templates/velero/values.yaml @@ -0,0 +1,83 @@ +{{- if .Values.addons.velero.enabled }} +{{- include "values-secret" (dict "root" $ "package" .Values.addons.velero "name" "velero" "defaults" (include "bigbang.defaults.velero" .)) }} +{{- end }} + +{{- define "bigbang.defaults.velero" -}} + +istio: + enabled: {{ .Values.istio.enabled }} + hardened: + enabled: {{ or + (dig "istio" "hardened" "enabled" false .Values.addons.velero.values) + (dig "hardened" "enabled" false .Values.istio.values) + }} + +domain: {{ .Values.domain }} + +{{- if .Values.istio.enabled }} +podAnnotations: + {{ include "istioAnnotation" . }} +{{- end }} + +monitoring: + enabled: {{ .Values.monitoring.enabled }} + +{{- if .Values.monitoring.enabled }} +metrics: + enabled: true + scrapeInterval: 30s + scrapeTimeout: 10s + service: + annotations: {} + labels: {} + podAnnotations: + prometheus.io/scrape: "true" + prometheus.io/port: "8085" + prometheus.io/path: "/metrics" + serviceMonitor: + enabled: true + additionalLabels: {} + {{- if and .Values.istio.enabled (eq (dig "istio" "mtls" "mode" "STRICT" .Values.addons.velero.values) "STRICT") }} + scheme: https + tlsConfig: + caFile: /etc/prom-certs/root-cert.pem + certFile: /etc/prom-certs/cert-chain.pem + keyFile: /etc/prom-certs/key.pem + insecureSkipVerify: true # Prometheus does not support Istio security naming, thus skip verifying target + {{- end }} + prometheusRule: + enabled: true +{{- end }} + +networkPolicies: + enabled: {{ .Values.networkPolicies.enabled }} + controlPlaneCidr: {{ .Values.networkPolicies.controlPlaneCidr }} + +openshift: {{ .Values.openshift }} + +imagePullSecrets: +- name: private-registry + +image: + pullPolicy: {{ .Values.imagePullPolicy }} + +{{- if eq (len .Values.addons.velero.plugins) 0 }}{{- fail "At least one plugin in '.Values.addons.velero.plugins' required. Supported values: aws, azure, csi" }}{{- end }} +plugins: +{{- range .Values.addons.velero.plugins }} +{{- if eq . "aws" }} + aws: + enabled: true +{{- end }} +{{- if eq . "azure" }} + azure: + enabled: true +{{- end }} +{{- if eq . "csi" }} + csi: + enabled: true +configuration: + features: EnableCSI +{{- end }} +{{- end }} + +{{- end -}} diff --git a/chart/templates/wrapper/git-credentials.yaml b/chart/templates/wrapper/git-credentials.yaml new file mode 100644 index 0000000000000000000000000000000000000000..c549b4cc487f9a880faef81835ab3e4a46dc479c --- /dev/null +++ b/chart/templates/wrapper/git-credentials.yaml @@ -0,0 +1,8 @@ +{{- $pkg := print .Release.Name "-wrapper" -}} +{{- $gitCredsSecretDict := dict + "name" $pkg + "targetScope" .Values.wrapper + "releaseName" .Release.Name + "releaseNamespace" .Release.Namespace +}} +{{- include "gitCredsSecret" $gitCredsSecretDict | nindent 0 -}} diff --git a/chart/templates/wrapper/gitrepository.yaml b/chart/templates/wrapper/gitrepository.yaml new file mode 100644 index 0000000000000000000000000000000000000000..6e7cf3b9c883ad8126fe205c0331c4deff4697ab --- /dev/null +++ b/chart/templates/wrapper/gitrepository.yaml @@ -0,0 +1,24 @@ +{{- /* Used for GitOps of the BigBang package wrapper Helm chart. Shared by all packages */ -}} +{{- if and .Values.wrapper (eq .Values.wrapper.sourceType "git") (omit (default dict .Values.packages) "sample") -}} +{{- $pkg := print .Release.Name "-wrapper" -}} +{{- $gitCredsDict := dict + "name" $pkg + "packageGitScope" .Values.wrapper.git + "rootScope" . + "releaseName" .Release.Name +}} +apiVersion: source.toolkit.fluxcd.io/v1 +kind: GitRepository +metadata: + name: {{ $pkg }} + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ $pkg }} + {{- include "commonLabels" $ | nindent 4 }} +spec: + interval: {{ dig "interval" "5m" .Values.flux }} + url: {{ .Values.wrapper.git.repo }} + ref: + {{- include "validRef" .Values.wrapper.git | nindent 4 -}} + {{- include "gitCredsExtended" $gitCredsDict | nindent 2 }} +{{- end -}} \ No newline at end of file diff --git a/chart/templates/wrapper/helmrelease.yaml b/chart/templates/wrapper/helmrelease.yaml new file mode 100644 index 0000000000000000000000000000000000000000..6c94b4e8bfd4fce99d1e927d31aeef890f5ba00a --- /dev/null +++ b/chart/templates/wrapper/helmrelease.yaml @@ -0,0 +1,90 @@ +{{- /* Used for Helm chart deployment of Big Bang wrapper. One per package. */ -}} +{{- range $pkg, $vals := .Values.packages -}} +{{- if and (dig "enabled" true $vals) (dig "wrapper" "enabled" false $vals) -}} +{{- $pkg = include "resourceName" $pkg -}} +{{- $fluxSettings := merge (dig "flux" dict $vals) $.Values.flux -}} +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + name: {{ $pkg }}-wrapper + namespace: {{ if dig "helmRelease" "namespace" nil (index $.Values.packages $pkg) }} + {{ dig "helmRelease" "namespace" "" (index $.Values.packages $pkg) }} + {{ else }} + {{ default (dig "namespace" "name" $pkg $vals) "" }} + {{ end }} + labels: + app.kubernetes.io/name: {{ $pkg }}-wrapper + {{- include "commonLabels" $ | nindent 4 }} + annotations: + {{- $defaults := ($.Files.Get (printf "defaults/%s.yaml" $pkg) | fromYaml) -}} + {{- $overlays := dict "bigbang" $.Values "package" $vals -}} + {{- $merged := mergeOverwrite $overlays $defaults }} + {{- if (omit $merged.package "git" "helmRepo" "flux" "postRenderers" "dependsOn") }} + checksum/bigbang-values: {{ (toJson (omit $merged.package "git" "helmRepo" "flux" "postRenderers" "dependsOn")) | sha256sum }} + {{- end }} +spec: + releaseName: {{ $pkg }}-wrapper + targetNamespace: {{ dig "namespace" "name" $pkg $vals }} + chart: + spec: + {{- if (eq $.Values.wrapper.sourceType "git") }} + chart: {{ default "chart" $.Values.wrapper.git.path }} + sourceRef: + kind: GitRepository + name: {{ $.Release.Name }}-wrapper + namespace: {{ $.Release.Namespace }} + {{- else }} + chart: {{ $.Values.wrapper.helmRepo.chartName }} + version: {{ $.Values.wrapper.helmRepo.tag }} + sourceRef: + kind: HelmRepository + name: {{ $.Values.wrapper.helmRepo.repoName }} + namespace: {{ $.Release.Namespace }} + {{- $repoType := include "getRepoType" (dict "repoName" $.Values.wrapper.helmRepo.repoName "allRepos" $.Values.helmRepositories) -}} + {{- if (and $.Values.wrapper.helmRepo.cosignVerify (eq $repoType "oci")) }} # Needs to be an OCI repo + verify: + provider: cosign + secretRef: + name: {{ printf "%s-cosign-pub" $.Values.wrapper.helmRepo.repoName }} + {{- end }} + {{- end }} + interval: {{ default "5m" $fluxSettings.interval }} + reconcileStrategy: Revision + {{- toYaml $fluxSettings | nindent 2 }} + {{- if $vals.wrapper.postRenderers }} + postRenderers: + {{- toYaml $vals.wrapper.postRenderers | nindent 4 }} + {{- end }} + valuesFrom: + - name: {{ $pkg }}-wrapper-values + kind: Secret + + {{- /* Always wait on policy enforcement */ -}} + {{- $gatekeeperDep := $.Values.gatekeeper.enabled -}} + {{- $kyvernoDep := $.Values.kyvernoPolicies.enabled -}} + {{- /* Wait on istio operator if creating a Virtual Service */ -}} + {{- $istioOpDep := and $.Values.istio.enabled (dig "istio" "hosts" false $vals) -}} + {{- /* Wait on monitoring if dashboard or metrics are enabled */ -}} + {{- $monitoringDep := $.Values.monitoring.enabled -}} + {{- if or $gatekeeperDep $istioOpDep $kyvernoDep $monitoringDep }} + dependsOn: + {{- if $gatekeeperDep }} + - name: gatekeeper + namespace: {{ $.Release.Namespace }} + {{- end }} + {{- if $kyvernoDep }} + - name: kyverno-policies + namespace: {{ $.Release.Namespace }} + {{- end }} + {{- if $istioOpDep }} + - name: istio-operator + namespace: {{ $.Release.Namespace }} + {{- end }} + {{- if $monitoringDep }} + - name: monitoring + namespace: {{ $.Release.Namespace }} + {{- end -}} + {{- end }} +--- +{{ end -}} +{{- end -}} diff --git a/chart/templates/wrapper/values.yaml b/chart/templates/wrapper/values.yaml new file mode 100644 index 0000000000000000000000000000000000000000..4ebb26ae3fa6087748abf3d3ac4b46fe1c34a568 --- /dev/null +++ b/chart/templates/wrapper/values.yaml @@ -0,0 +1,29 @@ +{{- /* Used for creating values to use for Helm wrapper and package Helm charts. */ -}} +{{- range $pkg, $vals := .Values.packages -}} +{{- if and (dig "enabled" true $vals) (dig "wrapper" "enabled" false $vals) -}} +{{- $pkg = include "resourceName" $pkg -}} +apiVersion: v1 +kind: Secret +metadata: + name: {{ $pkg }}-wrapper-values + namespace: {{ if dig "helmRelease" "namespace" nil (index $.Values.packages $pkg) }} + {{ dig "helmRelease" "namespace" "" (index $.Values.packages $pkg) }} + {{ else }} + {{ default (dig "namespace" "name" $pkg $vals) "" }} + {{ end }} +type: Opaque +stringData: + values.yaml: | + {{- $defaults := ($.Files.Get (printf "defaults/%s.yaml" $pkg) | fromYaml) -}} + {{- $overlays := dict "bigbang" $.Values "package" $vals -}} + {{- $merged := mergeOverwrite $overlays $defaults }} + package: + name: {{ $pkg }} + {{- if (omit $merged.package "git" "helmRepo" "flux" "postRenderers" "dependsOn") }} + {{- tpl (toYaml (omit $merged.package "git" "helmRepo" "flux" "postRenderers" "dependsOn")) $ | nindent 6 }} + {{- end }} + bigbang: + {{- include "values-bigbang" $merged.bigbang | nindent 6 }} +--- +{{ end -}} +{{- end -}} \ No newline at end of file diff --git a/chart/values.schema.json b/chart/values.schema.json new file mode 100644 index 0000000000000000000000000000000000000000..b3a51f10e0fbddf1badc73cad20ca10161790c8f --- /dev/null +++ b/chart/values.schema.json @@ -0,0 +1,2161 @@ +{ + "$id": "http://bigbang.dev/bigbang.json", + "type": "object", + "default": {}, + "title": "Big Bang Root Schema", + "required": [ + "domain", + "offline", + "helmRepositories", + "registryCredentials", + "openshift", + "git", + "sso", + "flux", + "networkPolicies", + "imagePullPolicy", + "istio", + "istioOperator", + "jaeger", + "kiali", + "clusterAuditor", + "gatekeeper", + "kyverno", + "kyvernoPolicies", + "kyvernoReporter", + "elasticsearchKibana", + "eckOperator", + "fluentbit", + "promtail", + "loki", + "neuvector", + "tempo", + "monitoring", + "grafana", + "twistlock", + "addons" + ], + "additionalProperties": false, + "properties": { + "comments": { + "type": "string" + }, + "domain": { + "type": "string" + }, + "offline": { + "type": "boolean" + }, + "registryCredentials": { + "oneOf": [ + { + "$ref": "#/$defs/registryCredential" + }, + { + "type": "array", + "items": { + "$ref": "#/$defs/registryCredential" + }, + "minItems": 1 + } + ] + }, + "helmRepositories": { + "$ref": "#/$defs/helmRepositories" + }, + "openshift": { + "type": "boolean" + }, + "git": { + "type": "object", + "properties": { + "existingSecret": { + "type": "string" + }, + "credentials": { + "type": "object", + "properties": { + "username": { + "type": "string" + }, + "password": { + "type": "string" + }, + "caFile": { + "type": "string" + }, + "privateKey": { + "type": "string" + }, + "publicKey": { + "type": "string" + }, + "knownHosts": { + "type": "string" + } + }, + "required": [], + "anyOf": [ + { + "required": [ + "username", + "password" + ] + }, + { + "required": [ + "privateKey", + "publicKey", + "knownHosts" + ] + } + ], + "additionalProperties": false + } + }, + "anyOf": [ + { + "required": [ + "existingSecret" + ] + }, + { + "required": [ + "credentials" + ] + } + ], + "additionalProperties": false + }, + "sso": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "url": { + "type": "string" + }, + "certificateAuthority": { + "type": "object", + "properties": { + "cert": { + "type": "string" + }, + "secretName": { + "type": "string" + } + }, + "additionalProperties": false + }, + "saml": { + "type": "object", + "properties": { + "entityDescriptor": { + "type": "string" + }, + "service": { + "type": "string" + }, + "metadata": { + "type": "string" + } + }, + "additionalProperties": false + }, + "oidc": { + "type": "object", + "properties": { + "authorization": { + "type": "string" + }, + "endSession": { + "type": "string" + }, + "jwksUri": { + "type": "string" + }, + "token": { + "type": "string" + }, + "userinfo": { + "type": "string" + }, + "jwks": { + "type": "string" + }, + "claims": { + "type": "object", + "properties": { + "email": { + "type": "string" + }, + "name": { + "type": "string" + }, + "username": { + "type": "string" + }, + "groups": { + "type": "string" + } + } + } + } + }, + "additionalProperties": false + } + }, + "flux": { + "$ref": "#/$defs/flux" + }, + "networkPolicies": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + }, + "controlPlaneCidr": { + "type": "string" + }, + "nodeCidr": { + "type": "string" + }, + "vpcCidr": { + "type": "string" + } + }, + "required": [ + "enabled" + ] + }, + "imagePullPolicy": { + "type": "string", + "enum": [ + "Never", + "Always", + "IfNotPresent" + ] + }, + "istio": { + "properties": { + "enabled": true, + "mtls": { + "type": "object" + }, + "sourceType": true, + "git": true, + "helmRepo": true, + "flux": true, + "values": true, + "postRenderers": true, + "enterprise": { + "type": "boolean" + }, + "ingressGateways": { + "type": "object" + }, + "gateways": { + "type": "object" + } + }, + "allOf": [ + { + "$ref": "#/$defs/basePackage" + } + ], + "additionalProperties": false + }, + "istioOperator": { + "properties": { + "enabled": true, + "sourceType": true, + "git": true, + "helmRepo": true, + "flux": true, + "values": true, + "postRenderers": true + }, + "allOf": [ + { + "$ref": "#/$defs/basePackage" + } + ], + "additionalProperties": false + }, + "jaeger": { + "required": [ + "sso", + "ingress" + ], + "properties": { + "enabled": true, + "sourceType": true, + "git": true, + "helmRepo": true, + "flux": true, + "values": true, + "postRenderers": true, + "istio": { + "$ref": "#/$defs/istio" + }, + "sso": { + "$ref": "#/$defs/sso" + }, + "ingress": { + "$ref": "#/$defs/ingress" + } + }, + "allOf": [ + { + "$ref": "#/$defs/basePackage" + } + ], + "additionalProperties": false + }, + "kiali": { + "required": [ + "sso", + "ingress" + ], + "properties": { + "enabled": true, + "sourceType": true, + "git": true, + "helmRepo": true, + "flux": true, + "values": true, + "postRenderers": true, + "istio": { + "$ref": "#/$defs/istio" + }, + "sso": { + "$ref": "#/$defs/sso" + }, + "ingress": { + "$ref": "#/$defs/ingress" + } + }, + "allOf": [ + { + "$ref": "#/$defs/basePackage" + } + ], + "additionalProperties": false + }, + "clusterAuditor": { + "properties": { + "enabled": true, + "sourceType": true, + "git": true, + "helmRepo": true, + "flux": true, + "values": true, + "postRenderers": true, + "istio": { + "$ref": "#/$defs/istio" + } + }, + "allOf": [ + { + "$ref": "#/$defs/basePackage" + } + ], + "additionalProperties": false + }, + "gatekeeper": { + "properties": { + "enabled": true, + "sourceType": true, + "git": true, + "helmRepo": true, + "flux": true, + "values": true, + "postRenderers": true + }, + "allOf": [ + { + "$ref": "#/$defs/basePackage" + } + ], + "additionalProperties": false + }, + "kyverno": { + "properties": { + "enabled": true, + "sourceType": true, + "git": true, + "helmRepo": true, + "flux": true, + "values": true, + "postRenderers": true + }, + "allOf": [ + { + "$ref": "#/$defs/basePackage" + } + ], + "additionalProperties": false + }, + "kyvernoPolicies": { + "properties": { + "enabled": true, + "sourceType": true, + "git": true, + "helmRepo": true, + "flux": true, + "values": true, + "postRenderers": true + }, + "allOf": [ + { + "$ref": "#/$defs/basePackage" + } + ], + "additionalProperties": false + }, + "kyvernoReporter": { + "properties": { + "enabled": true, + "sourceType": true, + "git": true, + "helmRepo": true, + "flux": true, + "values": true, + "postRenderers": true, + "istio": { + "$ref": "#/$defs/istio" + } + }, + "allOf": [ + { + "$ref": "#/$defs/basePackage" + } + ], + "additionalProperties": false + }, + "elasticsearchKibana": { + "required": [ + "sso", + "ingress" + ], + "properties": { + "enabled": true, + "sourceType": true, + "git": true, + "helmRepo": true, + "flux": true, + "values": true, + "postRenderers": true, + "istio": { + "$ref": "#/$defs/istio" + }, + "sso": { + "$ref": "#/$defs/sso" + }, + "ingress": { + "$ref": "#/$defs/ingress" + }, + "license": { + "properties": { + "trial": { + "type": "boolean" + }, + "keyJSON": { + "type": "string" + } + }, + "additionalProperties": false + }, + "serviceAccountAnnotations": { + "properties": { + "elasticsearch": true, + "kibana": true + } + } + }, + "allOf": [ + { + "$ref": "#/$defs/basePackage" + } + ], + "additionalProperties": false + }, + "eckOperator": { + "properties": { + "enabled": true, + "sourceType": true, + "git": true, + "helmRepo": true, + "flux": true, + "values": true, + "postRenderers": true, + "istio": { + "$ref": "#/$defs/istio" + } + }, + "allOf": [ + { + "$ref": "#/$defs/basePackage" + } + ], + "additionalProperties": false + }, + "fluentbit": { + "properties": { + "enabled": true, + "sourceType": true, + "git": true, + "helmRepo": true, + "flux": true, + "values": true, + "postRenderers": true, + "istio": { + "$ref": "#/$defs/istio" + } + }, + "allOf": [ + { + "$ref": "#/$defs/basePackage" + } + ], + "additionalProperties": false + }, + "promtail": { + "properties": { + "enabled": true, + "sourceType": true, + "git": true, + "helmRepo": true, + "flux": true, + "values": true, + "postRenderers": true, + "istio": { + "$ref": "#/$defs/istio" + } + }, + "allOf": [ + { + "$ref": "#/$defs/basePackage" + } + ], + "additionalProperties": false + }, + "loki": { + "required": [ + "strategy", + "objectStorage" + ], + "allOf": [ + { + "$ref": "#/$defs/basePackage" + } + ], + "properties": { + "enabled": true, + "clusterName": { + "type": "string" + }, + "sourceType": true, + "git": true, + "helmRepo": true, + "flux": true, + "values": true, + "postRenderers": true, + "istio": { + "$ref": "#/$defs/istio" + }, + "strategy": { + "type": "string", + "enum": [ + "monolith", + "scalable", + "distributed" + ] + }, + "objectStorage": { + "type": "object", + "required": [ + "endpoint", + "region", + "accessKey", + "accessSecret", + "bucketNames" + ], + "properties": { + "endpoint": { + "type": "string" + }, + "region": { + "type": "string" + }, + "accessKey": { + "type": "string" + }, + "accessSecret": { + "type": "string" + }, + "bucketNames": { + "type": "object" + } + } + } + }, + "additionalProperties": false + }, + "neuvector": { + "allOf": [ + { + "$ref": "#/$defs/basePackage" + } + ], + "properties": { + "enabled": true, + "sourceType": true, + "git": true, + "helmRepo": true, + "flux": true, + "values": true, + "postRenderers": true, + "istio": { + "$ref": "#/$defs/istio" + }, + "ingress": { + "$ref": "#/$defs/ingress" + }, + "sso": { + "type": "object", + "required": [ + "enabled", + "client_id", + "client_secret" + ], + "properties": { + "enabled": { + "type": "boolean" + }, + "client_id": { + "type": "string" + }, + "client_secret": { + "type": "string" + }, + "default_role": { + "type": "string" + }, + "issuer": { + "type": "string" + }, + "group_claim": { + "type": "string" + }, + "group_mapped_roles": { + "type": "array", + "items": { + "type": "object", + "properties": { + "group": { + "type": "string" + }, + "global_role":{ + "type": "string" + } + } + } + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + "tempo": { + "allOf": [ + { + "$ref": "#/$defs/basePackage" + } + ], + "properties": { + "enabled": true, + "sourceType": true, + "git": true, + "helmRepo": true, + "flux": true, + "values": true, + "postRenderers": true, + "istio": { + "$ref": "#/$defs/istio" + }, + "sso": { + "$ref": "#/$defs/sso" + }, + "ingress": { + "$ref": "#/$defs/ingress" + }, + "objectStorage": { + "type": "object", + "required": [ + "endpoint", + "region", + "accessKey", + "accessSecret", + "bucket", + "insecure" + ], + "properties": { + "endpoint": { + "type": "string" + }, + "region": { + "type": "string" + }, + "accessKey": { + "type": "string" + }, + "accessSecret": { + "type": "string" + }, + "bucket": { + "type": "string" + }, + "insecure": { + "type": "boolean" + } + } + } + }, + "additionalProperties": false + }, + "monitoring": { + "allOf": [ + { + "$ref": "#/$defs/basePackage" + } + ], + "properties": { + "enabled": true, + "sourceType": true, + "git": true, + "helmRepo": true, + "flux": true, + "values": true, + "postRenderers": true, + "istio": { + "$ref": "#/$defs/istio" + }, + "ingress": { + "$ref": "#/$defs/ingress" + }, + "sso": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + }, + "prometheus": { + "type": "object", + "properties": { + "client_id": { + "type": "string" + }, + "client_secret": { + "type": "string" + } + }, + "additionalProperties": false + }, + "alertmanager": { + "type": "object", + "properties": { + "client_id": { + "type": "string" + }, + "client_secret": { + "type": "string" + } + }, + "additionalProperties": false + }, + "grafana": { + "type": "object", + "properties": { + "client_id": { + "type": "string" + }, + "client_secret": { + "type": "string" + }, + "scopes": { + "type": "string" + }, + "allow_sign_up": { + "type": "boolean" + }, + "role_attribute_path": { + "type": "string" + }, + "token_url": { + "type": "string" + }, + "auth_url": { + "type": "string" + }, + "api_url": { + "type": "string" + }, + "tls_client_ca": { + "type": "string" + }, + "tls_skip_verify_insecure": { + "type": "boolean" + }, + "tls_client_cert": { + "type": "string" + }, + "tls_client_key": { + "type": "string" + }, + "allowed_domains": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + "grafana": { + "allOf": [ + { + "$ref": "#/$defs/basePackage" + } + ], + "properties": { + "enabled": true, + "sourceType": true, + "git": true, + "helmRepo": true, + "flux": true, + "values": true, + "postRenderers": true, + "istio": { + "$ref": "#/$defs/istio" + }, + "ingress": { + "$ref": "#/$defs/ingress" + }, + "sso": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + }, + "grafana": { + "type": "object", + "properties": { + "client_id": { + "type": "string" + }, + "client_secret": { + "type": "string" + }, + "scopes": { + "type": "string" + }, + "allow_sign_up": { + "type": "boolean" + }, + "role_attribute_path": { + "type": "string" + }, + "token_url": { + "type": "string" + }, + "auth_url": { + "type": "string" + }, + "api_url": { + "type": "string" + }, + "tls_client_ca": { + "type": "string" + }, + "tls_skip_verify_insecure": { + "type": "boolean" + }, + "tls_client_cert": { + "type": "string" + }, + "tls_client_key": { + "type": "string" + }, + "allowed_domains": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + "twistlock": { + "allOf": [ + { + "$ref": "#/$defs/basePackage" + } + ], + "properties": { + "enabled": true, + "sourceType": true, + "git": true, + "helmRepo": true, + "flux": true, + "values": true, + "postRenderers": true, + "istio": { + "$ref": "#/$defs/istio" + }, + "sso": { + "type": "object", + "required": [ + "enabled", + "client_id", + "provider_type" + ], + "properties": { + "enabled": { + "type": "boolean" + }, + "client_id": { + "type": "string" + }, + "provider_type": { + "type": "string" + }, + "provider_name": { + "type": "string" + }, + "groups": { + "type": "string" + }, + "issuer_uri": { + "type": "string" + }, + "idp_url": { + "type": "string" + }, + "console_url": { + "type": "string" + }, + "cert": { + "type": "string" + } + }, + "additionalProperties": false + }, + "ingress": { + "$ref": "#/$defs/ingress" + } + }, + "additionalProperties": false + }, + "addons": { + "type": "object", + "properties": { + "argocd": { + "allOf": [ + { + "$ref": "#/$defs/basePackage" + } + ], + "properties": { + "istio": { + "$ref": "#/$defs/istio" + } + } + }, + "authservice": { + "allOf": [ + { + "$ref": "#/$defs/basePackage" + } + ], + "properties": { + "istio": { + "$ref": "#/$defs/istio" + } + } + }, + "minioOperator": { + "allOf": [ + { + "$ref": "#/$defs/basePackage" + } + ], + "properties": { + "istio": { + "$ref": "#/$defs/istio" + } + } + }, + "minio": { + "allOf": [ + { + "$ref": "#/$defs/basePackage" + } + ], + "properties": { + "istio": { + "$ref": "#/$defs/istio" + } + } + }, + "gitlab": { + "allOf": [ + { + "$ref": "#/$defs/basePackage" + } + ], + "properties": { + "istio": { + "$ref": "#/$defs/istio" + } + } + }, + "gitlabRunner": { + "allOf": [ + { + "$ref": "#/$defs/basePackage" + } + ], + "properties": { + "istio": { + "$ref": "#/$defs/istio" + } + } + }, + "nexusRepositoryManager": { + "allOf": [ + { + "$ref": "#/$defs/basePackage" + } + ], + "properties": { + "istio": { + "$ref": "#/$defs/istio" + } + } + }, + "sonarqube": { + "allOf": [ + { + "$ref": "#/$defs/basePackage" + } + ], + "properties": { + "istio": { + "$ref": "#/$defs/istio" + } + } + }, + "fortify": { + "allOf": [ + { + "$ref": "#/$defs/basePackage" + } + ], + "properties": { + "istio": { + "$ref": "#/$defs/istio" + } + } + }, + "haproxy": { + "type": "object", + "required": [ + "git", + "flux", + "values" + ], + "properties": { + "git": { + "$ref": "#/$defs/git" + }, + "flux": { + "ref": "#/$defs/flux" + }, + "values": { + "$ref": "#/$defs/values" + }, + "istio": { + "$ref": "#/$defs/istio" + } + } + }, + "anchore": { + "allOf": [ + { + "$ref": "#/$defs/basePackage" + } + ], + "properties": { + "istio": { + "$ref": "#/$defs/istio" + } + } + }, + "mattermostOperator": { + "allOf": [ + { + "$ref": "#/$defs/basePackage" + } + ], + "properties": { + "istio": { + "$ref": "#/$defs/istio" + } + } + }, + "mattermost": { + "allOf": [ + { + "$ref": "#/$defs/basePackage" + } + ], + "properties": { + "istio": { + "$ref": "#/$defs/istio" + } + } + }, + "velero": { + "allOf": [ + { + "$ref": "#/$defs/basePackage" + } + ], + "properties": { + "istio": { + "$ref": "#/$defs/istio" + } + } + }, + "keycloak": { + "allOf": [ + { + "$ref": "#/$defs/basePackage" + } + ], + "properties": { + "istio": { + "$ref": "#/$defs/istio" + } + } + }, + "vault": { + "allOf": [ + { + "$ref": "#/$defs/basePackage" + } + ], + "properties": { + "istio": { + "$ref": "#/$defs/istio" + } + } + }, + "metricsServer": { + "type": "object", + "required": [ + "enabled", + "git", + "flux", + "values" + ], + "properties": { + "enabled": { + "type": [ + "boolean", + "string" + ], + "examples": [ + true, + false, + "auto" + ] + }, + "git": { + "$ref": "#/$defs/git" + }, + "flux": { + "ref": "#/$defs/flux" + }, + "values": { + "$ref": "#/$defs/values" + }, + "istio": { + "$ref": "#/$defs/istio" + } + } + }, + "harbor": { + "allOf": [ + { + "$ref": "#/$defs/basePackage" + } + ], + "properties": { + "istio": { + "$ref": "#/$defs/istio" + } + } + }, + "holocron": { + "allOf": [ + { + "$ref": "#/$defs/basePackage" + } + ], + "properties": { + "istio": { + "$ref": "#/$defs/istio" + } + } + }, + "thanos": { + "allOf": [ + { + "$ref": "#/$defs/basePackage" + } + ], + "properties": { + "istio": { + "$ref": "#/$defs/istio" + } + } + }, + "externalSecrets": { + "allOf": [ + { + "$ref": "#/$defs/basePackage" + } + ] + }, + "alloy": { + "allOf": [ + { + "$ref": "#/$defs/basePackage" + } + ] + } + } + }, + "wrapper": { + "type": "object", + "properties": { + "sourceType": { + "$ref": "#/$defs/sourceType" + }, + "git": { + "$ref": "#/$defs/git" + }, + "helmRepo": { + "$ref": "#/$defs/helmRepo" + } + }, + "additionalProperties": false + }, + "packages": { + "type": "object", + "additionalProperties": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "default": true + }, + "kustomize": { + "type": "boolean", + "default": false + } + } + } + } + }, + "$defs": { + "registryCredential": { + "type": "object", + "properties": { + "registry": { + "type": "string" + }, + "username": { + "type": "string" + }, + "password": { + "type": "string" + }, + "email": { + "type": "string" + } + }, + "required": [ + "registry", + "username", + "password" + ], + "additionalProperties": false + }, + "helmRepositories": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "repository": { + "type": "string", + "format": "uri" + }, + "existingSecret": { + "type": "string" + }, + "provider": { + "type": "string", + "enum": [ + "generic", + "aws", + "azure", + "gcp" + ] + }, + "type": { + "type": "string", + "enum": [ + "oci", + "default" + ] + }, + "username": { + "type": "string" + }, + "password": { + "type": "string" + }, + "email": { + "type": "string" + }, + "cosignPublicKey": { + "type": "string" + } + }, + "anyOf": [ + { + "required": [ + "existingSecret" + ] + }, + { + "required": [ + "username", + "password" + ] + }, + { + "required": [ + "provider" + ], + "not": { + "properties": { + "provider": { + "const": "generic" + } + } + } + } + ], + "required": [ + "name", + "repository" + ] + } + }, + "basePackage": { + "type": "object", + "required": [ + "enabled", + "sourceType", + "flux", + "values", + "postRenderers" + ], + "if": { + "properties": { + "sourceType": { + "const": "git" + } + } + }, + "then": { + "properties": { + "git": { + "$ref": "#/$defs/git" + } + }, + "required": [ + "git" + ] + }, + "else": { + "properties": { + "helmRepo": { + "$ref": "#/$defs/helmRepo" + } + }, + "required": [ + "helmRepo" + ] + }, + "properties": { + "enabled": { + "$ref": "#/$defs/enabled" + }, + "sourceType": { + "enum": [ + "git", + "helmRepo" + ] + }, + "flux": { + "$ref": "#/$defs/flux" + }, + "values": { + "$ref": "#/$defs/values" + }, + "postRenderers": { + "$ref": "#/$defs/postRenderers" + } + } + }, + "values": { + "type": "object", + "default": {}, + "required": [], + "properties": {} + }, + "flux": { + "install": { + "description": "Install holds the configuration for Helm install actions for this HelmRelease.", + "type": "object", + "properties": { + "crds": { + "description": "CRDs upgrade CRDs from the Helm Chart's crds directory according to the CRD upgrade policy provided here. Valid values are `Skip`, `Create` or `CreateReplace`. Default is `Create` and if omitted CRDs are installed but not updated. \n Skip: do neither install nor replace (update) any CRDs. \n Create: new CRDs are created, existing CRDs are neither updated nor deleted. \n CreateReplace: new CRDs are created, existing CRDs are updated (replaced) but not deleted. \n By default, CRDs are applied (installed) during Helm install action. With this option users can opt-in to CRD replace existing CRDs on Helm install actions, which is not (yet) natively supported by Helm. https://helm.sh/docs/chart_best_practices/custom_resource_definitions.", + "type": "string", + "enum": [ + "Skip", + "Create", + "CreateReplace" + ] + }, + "createNamespace": { + "description": "CreateNamespace tells the Helm install action to create the HelmReleaseSpec.TargetNamespace if it does not exist yet. On uninstall, the namespace will not be garbage collected.", + "type": "boolean" + }, + "disableHooks": { + "description": "DisableHooks prevents hooks from running during the Helm install action.", + "type": "boolean" + }, + "disableOpenAPIValidation": { + "description": "DisableOpenAPIValidation prevents the Helm install action from validating rendered templates against the Kubernetes OpenAPI Schema.", + "type": "boolean" + }, + "disableWait": { + "description": "DisableWait disables the waiting for resources to be ready after a Helm install has been performed.", + "type": "boolean" + }, + "disableWaitForJobs": { + "description": "DisableWaitForJobs disables waiting for jobs to complete after a Helm install has been performed.", + "type": "boolean" + }, + "remediation": { + "description": "Remediation holds the remediation configuration for when the Helm install action for the HelmRelease fails. The default is to not perform any action.", + "type": "object", + "properties": { + "ignoreTestFailures": { + "description": "IgnoreTestFailures tells the controller to skip remediation when the Helm tests are run after an install action but fail. Defaults to 'Test.IgnoreFailures'.", + "type": "boolean" + }, + "remediateLastFailure": { + "description": "RemediateLastFailure tells the controller to remediate the last failure, when no retries remain. Defaults to 'false'.", + "type": "boolean" + }, + "retries": { + "description": "Retries is the number of retries that should be attempted on failures before bailing. Remediation, using an uninstall, is performed between each attempt. Defaults to '0', a negative integer equals to unlimited retries.", + "type": "integer" + } + } + }, + "replace": { + "description": "Replace tells the Helm install action to re-use the 'ReleaseName', but only if that name is a deleted release which remains in the history.", + "type": "boolean" + }, + "skipCRDs": { + "description": "SkipCRDs tells the Helm install action to not install any CRDs. By default, CRDs are installed if not already present. \n Deprecated use CRD policy (`crds`) attribute with value `Skip` instead.", + "type": "boolean" + }, + "timeout": { + "description": "Timeout is the time to wait for any individual Kubernetes operation (like Jobs for hooks) during the performance of a Helm install action. Defaults to 'HelmReleaseSpec.Timeout'.", + "type": "string", + "pattern": "^([0-9]+(\\.[0-9]+)?(ms|s|m|h))+$" + } + } + }, + "interval": { + "description": "Interval at which to reconcile the Helm release.", + "type": "string", + "pattern": "^([0-9]+(\\.[0-9]+)?(ms|s|m|h))+$" + }, + "kubeConfig": { + "description": "KubeConfig for reconciling the HelmRelease on a remote cluster. When used in combination with HelmReleaseSpec.ServiceAccountName, forces the controller to act on behalf of that Service Account at the target cluster. If the --default-service-account flag is set, its value will be used as a controller level fallback for when HelmReleaseSpec.ServiceAccountName is empty.", + "type": "object", + "required": [ + "secretRef" + ], + "properties": { + "secretRef": { + "description": "SecretRef holds the name of a secret that contains a key with the kubeconfig file as the value. If no key is set, the key will default to 'value'. It is recommended that the kubeconfig is self-contained, and the secret is regularly updated if credentials such as a cloud-access-token expire. Cloud specific `cmd-path` auth helpers will not function without adding binaries and credentials to the Pod that is responsible for reconciling Kubernetes resources.", + "type": "object", + "required": [ + "name" + ], + "properties": { + "key": { + "description": "Key in the Secret, when not specified an implementation-specific default key is used.", + "type": "string" + }, + "name": { + "description": "Name of the Secret.", + "type": "string" + } + } + } + } + }, + "maxHistory": { + "description": "MaxHistory is the number of revisions saved by Helm for this HelmRelease. Use '0' for an unlimited number of revisions; defaults to '10'.", + "type": "integer" + }, + "persistentClient": { + "description": "PersistentClient tells the controller to use a persistent Kubernetes client for this release. When enabled, the client will be reused for the duration of the reconciliation, instead of being created and destroyed for each (step of a) Helm action. \n This can improve performance, but may cause issues with some Helm charts that for example do create Custom Resource Definitions during installation outside Helm's CRD lifecycle hooks, which are then not observed to be available by e.g. post-install hooks. \n If not set, it defaults to true.", + "type": "boolean" + }, + "releaseName": { + "description": "ReleaseName used for the Helm release. Defaults to a composition of '[TargetNamespace-]Name'.", + "type": "string", + "maxLength": 53, + "minLength": 1 + }, + "rollback": { + "description": "Rollback holds the configuration for Helm rollback actions for this HelmRelease.", + "type": "object", + "properties": { + "cleanupOnFail": { + "description": "CleanupOnFail allows deletion of new resources created during the Helm rollback action when it fails.", + "type": "boolean" + }, + "disableHooks": { + "description": "DisableHooks prevents hooks from running during the Helm rollback action.", + "type": "boolean" + }, + "disableWait": { + "description": "DisableWait disables the waiting for resources to be ready after a Helm rollback has been performed.", + "type": "boolean" + }, + "disableWaitForJobs": { + "description": "DisableWaitForJobs disables waiting for jobs to complete after a Helm rollback has been performed.", + "type": "boolean" + }, + "force": { + "description": "Force forces resource updates through a replacement strategy.", + "type": "boolean" + }, + "recreate": { + "description": "Recreate performs pod restarts for the resource if applicable.", + "type": "boolean" + }, + "timeout": { + "description": "Timeout is the time to wait for any individual Kubernetes operation (like Jobs for hooks) during the performance of a Helm rollback action. Defaults to 'HelmReleaseSpec.Timeout'.", + "type": "string", + "pattern": "^([0-9]+(\\.[0-9]+)?(ms|s|m|h))+$" + } + } + }, + "serviceAccountName": { + "description": "The name of the Kubernetes service account to impersonate when reconciling this HelmRelease.", + "type": "string" + }, + "storageNamespace": { + "description": "StorageNamespace used for the Helm storage. Defaults to the namespace of the HelmRelease.", + "type": "string", + "maxLength": 63, + "minLength": 1 + }, + "suspend": { + "description": "Suspend tells the controller to suspend reconciliation for this HelmRelease, it does not apply to already started reconciliations. Defaults to false.", + "type": "boolean" + }, + "test": { + "description": "Test holds the configuration for Helm test actions for this HelmRelease.", + "type": "object", + "properties": { + "enable": { + "description": "Enable enables Helm test actions for this HelmRelease after an Helm install or upgrade action has been performed.", + "type": "boolean" + }, + "ignoreFailures": { + "description": "IgnoreFailures tells the controller to skip remediation when the Helm tests are run but fail. Can be overwritten for tests run after install or upgrade actions in 'Install.IgnoreTestFailures' and 'Upgrade.IgnoreTestFailures'.", + "type": "boolean" + }, + "timeout": { + "description": "Timeout is the time to wait for any individual Kubernetes operation during the performance of a Helm test action. Defaults to 'HelmReleaseSpec.Timeout'.", + "type": "string", + "pattern": "^([0-9]+(\\.[0-9]+)?(ms|s|m|h))+$" + } + } + }, + "timeout": { + "description": "Timeout is the time to wait for any individual Kubernetes operation (like Jobs for hooks) during the performance of a Helm action. Defaults to '5m0s'.", + "type": "string", + "pattern": "^([0-9]+(\\.[0-9]+)?(ms|s|m|h))+$" + }, + "uninstall": { + "description": "Uninstall holds the configuration for Helm uninstall actions for this HelmRelease.", + "type": "object", + "properties": { + "deletionPropagation": { + "description": "DeletionPropagation specifies the deletion propagation policy when a Helm uninstall is performed.", + "type": "string", + "default": "background", + "enum": [ + "background", + "foreground", + "orphan" + ] + }, + "disableHooks": { + "description": "DisableHooks prevents hooks from running during the Helm rollback action.", + "type": "boolean" + }, + "disableWait": { + "description": "DisableWait disables waiting for all the resources to be deleted after a Helm uninstall is performed.", + "type": "boolean" + }, + "keepHistory": { + "description": "KeepHistory tells Helm to remove all associated resources and mark the release as deleted, but retain the release history.", + "type": "boolean" + }, + "timeout": { + "description": "Timeout is the time to wait for any individual Kubernetes operation (like Jobs for hooks) during the performance of a Helm uninstall action. Defaults to 'HelmReleaseSpec.Timeout'.", + "type": "string", + "pattern": "^([0-9]+(\\.[0-9]+)?(ms|s|m|h))+$" + } + } + }, + "upgrade": { + "description": "Upgrade holds the configuration for Helm upgrade actions for this HelmRelease.", + "type": "object", + "properties": { + "cleanupOnFail": { + "description": "CleanupOnFail allows deletion of new resources created during the Helm upgrade action when it fails.", + "type": "boolean" + }, + "crds": { + "description": "CRDs upgrade CRDs from the Helm Chart's crds directory according to the CRD upgrade policy provided here. Valid values are `Skip`, `Create` or `CreateReplace`. Default is `Skip` and if omitted CRDs are neither installed nor upgraded. \n Skip: do neither install nor replace (update) any CRDs. \n Create: new CRDs are created, existing CRDs are neither updated nor deleted. \n CreateReplace: new CRDs are created, existing CRDs are updated (replaced) but not deleted. \n By default, CRDs are not applied during Helm upgrade action. With this option users can opt-in to CRD upgrade, which is not (yet) natively supported by Helm. https://helm.sh/docs/chart_best_practices/custom_resource_definitions.", + "type": "string", + "enum": [ + "Skip", + "Create", + "CreateReplace" + ] + }, + "disableHooks": { + "description": "DisableHooks prevents hooks from running during the Helm upgrade action.", + "type": "boolean" + }, + "disableOpenAPIValidation": { + "description": "DisableOpenAPIValidation prevents the Helm upgrade action from validating rendered templates against the Kubernetes OpenAPI Schema.", + "type": "boolean" + }, + "disableWait": { + "description": "DisableWait disables the waiting for resources to be ready after a Helm upgrade has been performed.", + "type": "boolean" + }, + "disableWaitForJobs": { + "description": "DisableWaitForJobs disables waiting for jobs to complete after a Helm upgrade has been performed.", + "type": "boolean" + }, + "force": { + "description": "Force forces resource updates through a replacement strategy.", + "type": "boolean" + }, + "preserveValues": { + "description": "PreserveValues will make Helm reuse the last release's values and merge in overrides from 'Values'. Setting this flag makes the HelmRelease non-declarative.", + "type": "boolean" + }, + "remediation": { + "description": "Remediation holds the remediation configuration for when the Helm upgrade action for the HelmRelease fails. The default is to not perform any action.", + "type": "object", + "properties": { + "ignoreTestFailures": { + "description": "IgnoreTestFailures tells the controller to skip remediation when the Helm tests are run after an upgrade action but fail. Defaults to 'Test.IgnoreFailures'.", + "type": "boolean" + }, + "remediateLastFailure": { + "description": "RemediateLastFailure tells the controller to remediate the last failure, when no retries remain. Defaults to 'false' unless 'Retries' is greater than 0.", + "type": "boolean" + }, + "retries": { + "description": "Retries is the number of retries that should be attempted on failures before bailing. Remediation, using 'Strategy', is performed between each attempt. Defaults to '0', a negative integer equals to unlimited retries.", + "type": "integer" + }, + "strategy": { + "description": "Strategy to use for failure remediation. Defaults to 'rollback'.", + "type": "string", + "enum": [ + "rollback", + "uninstall" + ] + } + } + }, + "timeout": { + "description": "Timeout is the time to wait for any individual Kubernetes operation (like Jobs for hooks) during the performance of a Helm upgrade action. Defaults to 'HelmReleaseSpec.Timeout'.", + "type": "string", + "pattern": "^([0-9]+(\\.[0-9]+)?(ms|s|m|h))+$" + } + } + }, + "values": { + "description": "Values holds the values for this Helm release.", + "x-kubernetes-preserve-unknown-fields": true + } + }, + "git": { + "type": "object", + "required": [ + "repo", + "path" + ], + "anyOf": [ + { + "required": [ + "tag" + ], + "properties": { + "branch": { + "maxLength": 0 + }, + "commit": { + "maxLength": 0 + } + } + }, + { + "required": [ + "branch" + ], + "properties": { + "tag": { + "maxLength": 0 + } + } + }, + { + "required": [ + "semver" + ], + "properties": { + "branch": { + "maxLength": 0 + }, + "commit": { + "maxLength": 0 + }, + "tag": { + "maxLength": 0 + } + } + } + ], + "dependentRequired": { + "commit": [ + "branch" + ] + }, + "properties": { + "repo": { + "type": "string", + "examples": [ + "https://repo1.dso.mil/big-bang/product/packages/loki.git" + ] + }, + "path": { + "type": "string", + "examples": [ + "./chart" + ] + }, + "tag": { + "type": [ + "string", + "null" + ], + "nullable": false, + "examples": [ + "4.8.0-bb.0" + ] + }, + "branch": { + "minLength": 1, + "type": [ + "string", + "null" + ], + "nullable": false, + "examples": [ + "feature-branch" + ] + }, + "commit": { + "type": "string" + }, + "semver": { + "type": "string" + }, + "existingSecret": { + "type": "string" + }, + "credentials": { + "type": "object", + "properties": { + "username": { + "type": "string" + }, + "password": { + "type": "string" + }, + "caFile": { + "type": "string" + }, + "privateKey": { + "type": "string" + }, + "publicKey": { + "type": "string" + }, + "knownHosts": { + "type": "string" + } + }, + "required": [], + "anyOf": [ + { + "required": [ + "username", + "password" + ] + }, + { + "required": [ + "privateKey", + "publicKey", + "knownHosts" + ] + } + ], + "additionalProperties": false + } + }, + "additionalProperties": false, + "examples": [ + { + "repo": "https://repo1.dso.mil/big-bang/product/packages/loki.git", + "path": "./chart", + "tag": "4.8.0-bb.0" + } + ] + }, + "postRenderers": { + "description": "PostRenderers holds an array of Helm PostRenderers, which will be applied in order of their definition.", + "type": "array", + "items": { + "description": "PostRenderer contains a Helm PostRenderer specification.", + "type": "object", + "properties": { + "kustomize": { + "description": "Kustomization to apply as PostRenderer.", + "type": "object", + "properties": { + "images": { + "description": "Images is a list of (image name, new name, new tag or digest) for changing image names, tags or digests. This can also be achieved with a patch, but this operator is simpler to specify.", + "type": "array", + "items": { + "description": "Image contains an image name, a new name, a new tag or digest, which will replace the original name and tag.", + "type": "object", + "required": [ + "name" + ], + "properties": { + "digest": { + "description": "Digest is the value used to replace the original image tag. If digest is present NewTag value is ignored.", + "type": "string" + }, + "name": { + "description": "Name is a tag-less image name.", + "type": "string" + }, + "newName": { + "description": "NewName is the value used to replace the original name.", + "type": "string" + }, + "newTag": { + "description": "NewTag is the value used to replace the original tag.", + "type": "string" + } + } + } + }, + "patches": { + "description": "Strategic merge and JSON patches, defined as inline YAML objects, capable of targeting objects based on kind, label and annotation selectors.", + "type": "array", + "items": { + "description": "Patch contains an inline StrategicMerge or JSON6902 patch, and the target the patch should be applied to.", + "type": "object", + "required": [ + "patch" + ], + "properties": { + "patch": { + "description": "Patch contains an inline StrategicMerge patch or an inline JSON6902 patch with an array of operation objects.", + "type": "string" + }, + "target": { + "description": "Target points to the resources that the patch document should be applied to.", + "type": "object", + "properties": { + "annotationSelector": { + "description": "AnnotationSelector is a string that follows the label selection expression https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#api It matches with the resource annotations.", + "type": "string" + }, + "group": { + "description": "Group is the API group to select resources from. Together with Version and Kind it is capable of unambiguously identifying and/or selecting resources. https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md", + "type": "string" + }, + "kind": { + "description": "Kind of the API Group to select resources from. Together with Group and Version it is capable of unambiguously identifying and/or selecting resources. https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md", + "type": "string" + }, + "labelSelector": { + "description": "LabelSelector is a string that follows the label selection expression https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#api It matches with the resource labels.", + "type": "string" + }, + "name": { + "description": "Name to match resources with.", + "type": "string" + }, + "namespace": { + "description": "Namespace to select resources from.", + "type": "string" + }, + "version": { + "description": "Version of the API Group to select resources from. Together with Group and Kind it is capable of unambiguously identifying and/or selecting resources. https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md", + "type": "string" + } + } + } + } + } + }, + "patchesJson6902": { + "description": "JSON 6902 patches, defined as inline YAML objects.", + "type": "array", + "items": { + "description": "JSON6902Patch contains a JSON6902 patch and the target the patch should be applied to.", + "type": "object", + "required": [ + "patch", + "target" + ], + "properties": { + "patch": { + "description": "Patch contains the JSON6902 patch document with an array of operation objects.", + "type": "array", + "items": { + "description": "JSON6902 is a JSON6902 operation object. https://datatracker.ietf.org/doc/html/rfc6902#section-4", + "type": "object", + "required": [ + "op", + "path" + ], + "properties": { + "from": { + "description": "From contains a JSON-pointer value that references a location within the target document where the operation is performed. The meaning of the value depends on the value of Op, and is NOT taken into account by all operations.", + "type": "string" + }, + "op": { + "description": "Op indicates the operation to perform. Its value MUST be one of \"add\", \"remove\", \"replace\", \"move\", \"copy\", or \"test\". https://datatracker.ietf.org/doc/html/rfc6902#section-4", + "type": "string", + "enum": [ + "test", + "remove", + "add", + "replace", + "move", + "copy" + ] + }, + "path": { + "description": "Path contains the JSON-pointer value that references a location within the target document where the operation is performed. The meaning of the value depends on the value of Op.", + "type": "string" + }, + "value": { + "description": "Value contains a valid JSON structure. The meaning of the value depends on the value of Op, and is NOT taken into account by all operations.", + "x-kubernetes-preserve-unknown-fields": true + } + } + } + }, + "target": { + "description": "Target points to the resources that the patch document should be applied to.", + "type": "object", + "properties": { + "annotationSelector": { + "description": "AnnotationSelector is a string that follows the label selection expression https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#api It matches with the resource annotations.", + "type": "string" + }, + "group": { + "description": "Group is the API group to select resources from. Together with Version and Kind it is capable of unambiguously identifying and/or selecting resources. https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md", + "type": "string" + }, + "kind": { + "description": "Kind of the API Group to select resources from. Together with Group and Version it is capable of unambiguously identifying and/or selecting resources. https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md", + "type": "string" + }, + "labelSelector": { + "description": "LabelSelector is a string that follows the label selection expression https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#api It matches with the resource labels.", + "type": "string" + }, + "name": { + "description": "Name to match resources with.", + "type": "string" + }, + "namespace": { + "description": "Namespace to select resources from.", + "type": "string" + }, + "version": { + "description": "Version of the API Group to select resources from. Together with Group and Kind it is capable of unambiguously identifying and/or selecting resources. https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md", + "type": "string" + } + } + } + } + } + }, + "patchesStrategicMerge": { + "description": "Strategic merge patches, defined as inline YAML objects.", + "type": "array", + "items": { + "x-kubernetes-preserve-unknown-fields": true + } + } + } + } + } + } + }, + "enabled": { + "type": "boolean", + "default": false, + "examples": [ + false + ] + }, + "sso": { + "type": "object", + "required": [ + "enabled", + "client_id", + "client_secret" + ], + "properties": { + "enabled": { + "type": "boolean" + }, + "client_id": { + "type": "string" + }, + "client_secret": { + "type": "string" + } + }, + "additionalProperties": false + }, + "ingress": { + "type": "object", + "properties": { + "gateway": { + "type": "string" + } + }, + "additionalProperties": false + }, + "helmRepo": { + "type": "object", + "properties": { + "repoName": { + "type": "string" + }, + "chartName": { + "type": "string" + }, + "tag": { + "type": "string" + }, + "cosignVerify": { + "type": "boolean" + } + }, + "required": [ + "repoName", + "chartName", + "tag" + ], + "additionalProperties": false + }, + "sourceType": { + "enum": [ + "helmRepo", + "git" + ] + }, + "istio": { + "type": "object", + "properties": { + "injection": { + "enum": [ + "enabled", + "disabled" + ] + } + } + } + } +} diff --git a/chart/values.yaml b/chart/values.yaml new file mode 100644 index 0000000000000000000000000000000000000000..1fb63c8368f74338ceee6f978336e4d36459e2eb --- /dev/null +++ b/chart/values.yaml @@ -0,0 +1,2232 @@ +# -- Domain used for BigBang created exposed services, can be overridden by individual packages. +domain: dev.bigbang.mil + +# -- (experimental) Toggle sourcing from external repos. +# All this does right now is toggle GitRepositories, it is _not_ fully functional +offline: false + +# -- List of Helm repositories/credentials to pull helm charts from. +# OCI Type: Must specify username/password or existingSecret if repository requires auth. Using "private-registry" for existingSecret will reuse credentials from registryCredentials above. +# Default Type: Must specify existingSecret with auth - see https://fluxcd.io/flux/components/source/helmrepositories/#secret-reference for details on secret data required. +helmRepositories: [] + # - name: "registry1" + # repository: "oci://registry1.dso.mil/bigbang" + # existingSecret: "private-registry" + # type: "oci" + # username: "" + # password: "" + # email: "" + # # This is an array/list of public keys to be used. Template will append `.pub` to the key as required by Flux + # cosignPublicKeys: [] + # key1: | + # -----BEGIN PUBLIC KEY----- + # MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIE7v9J6ttQus6itUoyfMCqMjaIqm + # R8XrntaedsdEhPPchOQuFzqTyyAPGifV1SaEu8medVRi6mVICWbVwOteNg== + # -----END PUBLIC KEY----- + + +# -- Single set of registry credentials used to pull all images deployed by BigBang. +registryCredentials: + registry: registry1.dso.mil + username: "" + password: "" + email: "" + +# -- Multiple sets of registry credentials used to pull all images deployed by BigBang. +# Credentials will only be created when a valid combination exists, registry, username, and password (email is optional) +# Or a list of registires: +# - registry: registry1.dso.mil +# username: "" +# password: "" +# email: "" +# - registry: registry.dso.mil +# username: "" +# password: "" +# email: "" + +# Openshift Container Platform Feature Toggle +openshift: false + +# -- Git credential settings for accessing private repositories +# Order of precedence is: +# 1. existingSecret +# 2. http credentials (username/password/caFile) +# 3. ssh credentials (privateKey/publicKey/knownHosts) +git: + # -- Existing secret to use for git credentials, must be in the appropriate format: https://toolkit.fluxcd.io/components/source/gitrepositories/#https-authentication + existingSecret: "" + + # -- Chart created secrets with user defined values + credentials: + # -- HTTP git credentials, both username and password must be provided + username: "" + password: "" + # -- HTTPS certificate authority file. Required for any repo with a self signed certificate + caFile: "" + # -- SSH git credentials, privateKey, publicKey, and knownHosts must be provided + privateKey: "" + publicKey: "" + knownHosts: "" + +# -- Global SSO values used for BigBang deployments when sso is enabled +sso: + # -- Name of the identity provider. This is used by some packages as the SSO login label. + name: SSO + # -- Base URL for the identity provider. For OIDC, this is the issuer. For SAML this is the entityID. + url: https://login.dso.mil/auth/realms/baby-yoda + + # -- Certificate authority for the identity provider's certificates + certificateAuthority: + # -- The certificate authority public certificate in .pem format. Populating this will create a secret in each namespace that enables SSO. + cert: "" # See docs/assets/configs/example/dev-sso-values.yaml for an example + # -- The secret name to use for the certificate authority. Can be manually populated if cert is blank. + secretName: tls-ca-sso + + saml: + # -- SAML entityDescriptor (metadata) path + entityDescriptor: "{{ .Values.sso.url }}/protocol/saml/descriptor" + # -- SAML SSO Service path + service: "{{ .Values.sso.url }}/protocol/saml" + # -- Literal SAML XML metadata retrieved from `{{ .Values.sso.saml.entityDescriptor }}`. Required for SSO in Nexus, Twistlock, or Sonarqube. + metadata: "" # See docs/assets/configs/example/dev-sso-values.yaml for an example + # NOTE: SAML attribute names may vary by package. Use the package values to setup attribute names + + # -- OIDC endpoints can be retrieved from `{{ .Values.sso.url }}/.well-known/openid-configuration` + oidc: + # -- OIDC authorization path + authorization: "{{ .Values.sso.url }}/protocol/openid-connect/auth" + # -- OIDC logout / end session path + endSession: "{{ .Values.sso.url }}/protocol/openid-connect/logout" + # -- OIDC JSON Web Key Set (JWKS) path + jwksUri: "{{ .Values.sso.url }}/protocol/openid-connect/certs" + # -- OIDC token path + token: "{{ .Values.sso.url }}/protocol/openid-connect/token" + # -- OIDC user information path + userinfo: "{{ .Values.sso.url }}/protocol/openid-connect/userinfo" + # -- Literal OIDC JWKS data retrieved from JWKS Uri. Only needed if `jwsksUri` is not defined. + jwks: "" + # -- Identity provider claim names that store metadata about the authenticated user. + claims: + # -- IdP's claim name used for the user's email address. + email: email + # -- IdP's claim name used for the user's full name + name: name + # -- IdP's claim name used for the username + username: preferred_username + # -- IdP's claim name used for the user's groups or roles + groups: groups + +# -- (Advanced) Flux reconciliation parameters. +# The default values provided will be sufficient for the majority of workloads. +flux: + timeout: 10m + interval: 2m + test: + enable: false + install: + remediation: + retries: -1 + upgrade: + remediation: + retries: 3 + remediateLastFailure: true + cleanupOnFail: true + rollback: + timeout: 10m + cleanupOnFail: true + +# -- Global NetworkPolicies settings +networkPolicies: + # -- Toggle all package NetworkPolicies, can disable specific packages with `package.values.networkPolicies.enabled` + enabled: true + # -- Control Plane CIDR, defaults to 0.0.0.0/0, use `kubectl get endpoints -n default kubernetes` to get the CIDR range needed for your cluster + # Must be an IP CIDR range (x.x.x.x/x - ideally with /32 for the specific IP of a single endpoint, broader range for multiple masters/endpoints) + # Used by package NetworkPolicies to allow Kube API access + controlPlaneCidr: 0.0.0.0/0 + # -- Node CIDR, defaults to allowing "10.0.0.0/8" "172.16.0.0/12" "192.168.0.0/16" "100.64.0.0/10" networks. + # use `kubectl get nodes -owide` and review the `INTERNAL-IP` column to derive CIDR range. + # Must be an IP CIDR range (x.x.x.x/x - ideally a /16 or /24 to include multiple IPs) + nodeCidr: "" + # -- VPC CIDR, defaults to 0.0.0.0/0 + # In a production environment, it is recommended to setup a Private Endpoint for your AWS services like KMS or S3. + # Please review https://docs.aws.amazon.com/kms/latest/developerguide/kms-vpc-endpoint.html to setup routing to AWS services that never leave the AWS network. + # Once created update `networkPolicies.vpcCidr` to match the CIDR of your VPC so Vault will be able to reach your VPCs DNS and new KMS endpoint. + vpcCidr: 0.0.0.0/0 + +# -- Global ImagePullPolicy value for all packages +# Permitted values are: None, Always, IfNotPresent +imagePullPolicy: IfNotPresent + +# ---------------------------------------------------------------------------------------------------------------------- +# Istio +# +istio: + # -- Toggle deployment of Istio. + enabled: true + mtls: + # -- STRICT = Allow only mutual TLS traffic, + # PERMISSIVE = Allow both plain text and mutual TLS traffic + mode: STRICT + + # -- Choose source type of "git" or "helmRepo" + sourceType: "git" + + git: + repo: https://repo1.dso.mil/big-bang/product/packages/istio-controlplane.git + path: "./chart" + tag: "1.23.3-bb.2" + helmRepo: + repoName: "registry1" + chartName: "istio" + tag: "1.23.3-bb.2" + # -- If the HelmRelease should verify the cosign signature of the HelmRepo (only relevant if Repo is OCI). Set to 'false' to disable verification. + # cosignVerify: + + # -- Tetrate Istio Distribution - Tetrate provides FIPs verified Istio and Envoy software and support, + # validated through the FIPs Boring Crypto module. Find out more from Tetrate - https://www.tetrate.io/tetrate-istio-subscription + enterprise: false + + # Ingress gateways are created based on the key name. Adding more keys will add ingress gateways. + # Ingress gateways are setup in a Horizontal Pod Autoscaler with 1 to 5 replicas + # Besides some ports needed by Istio, only ports 80 and 443 are opened + # Ingress gateways that require more configuration can be completed using `istio.values` + ingressGateways: + public-ingressgateway: + type: "LoadBalancer" # or "NodePort" + kubernetesResourceSpec: {} # https://istio.io/latest/docs/reference/config/istio.operator.v1alpha1/#KubernetesResourcesSpec + + # private-ingressgateway: + # type: "LoadBalancer" # or "NodePort" + # kubernetesResourceSpec: # https://istio.io/latest/docs/reference/config/istio.operator.v1alpha1/#KubernetesResourcesSpec + # serviceAnnotations: # Example for AWS internal load balancer + # service.beta.kubernetes.io/aws-load-balancer-type: nlb + # service.beta.kubernetes.io/aws-load-balancer-internal: "true" + + # passthrough-ingressgateway: + # type: "NodePort" # or "LoadBalancer" + # # Node ports are assigned starting from nodePortBase. The nodePortBase specifies the start of a range of 4 unused node ports. + # # Node port will be assigned as follows: Port 15021 (Status) = nodePortBase, Port 80 = nodePortBase+1, Port 443 = nodePortBase+2, Port 15443 (SNI) = nodePortBase+3 + # # Node port base should be in the range from 30000 to 32764 + # nodePortBase: 32000 # Alternatively, the kubernetesResourceSpec can be used to configure all port parameters + + gateways: + public: + ingressGateway: "public-ingressgateway" + hosts: + - "*.{{ .Values.domain }}" + # -- Controls default HTTP/8080 server entry with HTTP to HTTPS Redirect. + autoHttpRedirect: + enabled: true + tls: + key: "" + cert: "" + minProtocolVersion: "" + # private: + # ingressGateway: "private-ingressgateway" + # hosts: + # - "example.bigbang.dev" + # ports: + # - name: tls-2 + # number: 1234 + # protocol: TCP + # - name: tls + # number: 5678 + # protocol: TCP + # # -- Controls default HTTP/8080 server entry with HTTP to HTTPS Redirect. + # autoHttpRedirect: + # enabled: false + # tls: + # key: "" + # cert: "" + # minProtocolVersion: "" + # passthrough: + # ingressGateway: "passthrough-ingressgateway" + # hosts: + + #### + # Alternate multi-server configuration method + #### + # private: + # ingressGateway: "private-ingressgateway" + # servers: + # - hosts: + # - "example.bigbang.dev" + # port: + # name: tls-1 + # number: 1234 + # protocol: TCP + # # -- Controls default HTTP/8080 server entry with HTTP to HTTPS Redirect. + # autoHttpRedirect: + # enabled: false + # tls: + # key: "" + # cert: "" + # minProtocolVersion: "" + # - hosts: + # - "example.bigbang.dev" + # port: + # name: tls-2 + # number: 5678 + # protocol: TCP + # # -- Controls default HTTP/8080 server entry with HTTP to HTTPS Redirect. + # autoHttpRedirect: + # enabled: false + # tls: + # key: "" + # cert: "" + # minProtocolVersion: "" + # passthrough: + # ingressGateway: "passthrough-ingressgateway" + # hosts: + # - "*.{{ .Values.domain }}" + # # -- Controls default HTTP/8080 server entry with HTTP to HTTPS Redirect. + # autoHttpRedirect: + # enabled: true + # tls: + # mode: "PASSTHROUGH" + # mutual: + # ingressGateway: "mutual-ingressgateway" + # hosts: + # - "*.{{ .Values.domain }}" + # # -- Controls default HTTP/8080 server entry with HTTP to HTTPS Redirect. + # autoHttpRedirect: + # enabled: true + # tls: + # mode: MUTUAL + # cert: "" + # key: "" + # ca: "" + + # -- Flux reconciliation overrides specifically for the Istio Package + flux: {} + + # -- Values to passthrough to the istio-controlplane chart: https://repo1.dso.mil/big-bang/product/packages/istio-controlplane.git + values: {} + + # -- Post Renderers. See docs/postrenders.md + postRenderers: [] + +istioOperator: + # -- Toggle deployment of Istio Operator. + enabled: true + + # -- Choose source type of "git" or "helmRepo" + sourceType: "git" + + git: + repo: https://repo1.dso.mil/big-bang/product/packages/istio-operator.git + path: "./chart" + tag: "1.23.3-bb.0" + helmRepo: + repoName: "registry1" + chartName: "istio-operator" + tag: "1.23.3-bb.0" + + # -- Flux reconciliation overrides specifically for the Istio Operator Package + flux: {} + + # -- Values to passthrough to the istio-operator chart: https://repo1.dso.mil/big-bang/product/packages/istio-operator.git + values: {} + + # -- Post Renderers. See docs/postrenders.md + postRenderers: [] + +jaeger: + # -- Toggle deployment of Jaeger. + enabled: false + + # -- Choose source type of "git" or "helmRepo" + sourceType: "git" + + git: + repo: https://repo1.dso.mil/big-bang/product/packages/jaeger.git + path: "./chart" + tag: "2.57.0-bb.0" + helmRepo: + repoName: "registry1" + chartName: "jaeger" + tag: "2.57.0-bb.0" + + # -- Flux reconciliation overrides specifically for the Jaeger Package + flux: + install: + crds: CreateReplace + upgrade: + crds: CreateReplace + + # -- Redirect the package ingress to a specific Istio Gateway (listed in `istio.gateways`). The default is "public". + ingress: + gateway: "" + + sso: + # -- Toggle SSO for Jaeger on and off + enabled: false + + # -- OIDC Client ID to use for Jaeger + client_id: "" + + # -- OIDC Client Secret to use for Jaeger + client_secret: "" + + # -- Values to pass through to Jaeger chart: https://repo1.dso.mil/big-bang/product/packages/jaeger.git + values: {} + + # -- Post Renderers. See docs/postrenders.md + postRenderers: [] + +kiali: + # -- Toggle deployment of Kiali. + enabled: true + + # -- Choose source type of "git" or "helmRepo" + sourceType: "git" + + git: + repo: https://repo1.dso.mil/big-bang/product/packages/kiali.git + path: "./chart" + tag: "2.3.0-bb.0" + helmRepo: + repoName: "registry1" + chartName: "kiali" + tag: "2.3.0-bb.0" + + # -- Flux reconciliation overrides specifically for the Kiali Package + flux: {} + + # -- Redirect the package ingress to a specific Istio Gateway (listed in `istio.gateways`). The default is "public". + ingress: + gateway: "" + + sso: + # -- Toggle SSO for Kiali on and off + enabled: false + + # -- OIDC Client ID to use for Kiali + client_id: "" + + # -- OIDC Client Secret to use for Kiali + client_secret: "" + + # -- Values to pass through to Kiali chart: https://repo1.dso.mil/big-bang/product/packages/kiali + values: {} + + # -- Post Renderers. See docs/postrenders.md + postRenderers: [] + +# ---------------------------------------------------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------------------------------------------------- +# Cluster Auditor +# +clusterAuditor: + # -- Toggle deployment of Cluster Auditor. + enabled: false + + # -- Choose source type of "git" or "helmRepo" + sourceType: "git" + + git: + repo: https://repo1.dso.mil/big-bang/product/packages/cluster-auditor.git + path: "./chart" + tag: "1.5.0-bb.22" + helmRepo: + repoName: "registry1" + chartName: "cluster-auditor" + tag: "1.5.0-bb.22" + + # -- Flux reconciliation overrides specifically for the Cluster Auditor Package + flux: {} + + # -- Values to passthrough to the cluster auditor chart: https://repo1.dso.mil/big-bang/product/packages/cluster-auditor.git + values: {} + + # -- Post Renderers. See docs/postrenders.md + postRenderers: [] +# ---------------------------------------------------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------------------------------------------------- +# OPA Gatekeeper +# +gatekeeper: + # -- Toggle deployment of OPA Gatekeeper. + enabled: false + + # -- Choose source type of "git" or "helmRepo" + sourceType: "git" + + git: + repo: https://repo1.dso.mil/big-bang/product/packages/policy.git + path: "./chart" + tag: "3.18.1-bb.0" + helmRepo: + repoName: "registry1" + chartName: "gatekeeper" + tag: "3.18.1-bb.0" + + # -- Flux reconciliation overrides specifically for the OPA Gatekeeper Package + flux: + install: + crds: CreateReplace + upgrade: + crds: CreateReplace + + # -- Values to passthrough to the gatekeeper chart: https://repo1.dso.mil/big-bang/product/packages/policy.git + values: {} + + # -- Post Renderers. See docs/postrenders.md + postRenderers: [] +# ---------------------------------------------------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------------------------------------------------- +# Kyverno +# +kyverno: + # -- Toggle deployment of Kyverno. + enabled: true + + # -- Choose source type of "git" or "helmRepo" + sourceType: "git" + + git: + repo: https://repo1.dso.mil/big-bang/product/packages/kyverno.git + path: "./chart" + tag: "3.3.4-bb.0" + helmRepo: + repoName: "registry1" + chartName: "kyverno" + tag: "3.3.4-bb.0" + + # -- Flux reconciliation overrides specifically for the Kyverno Package + flux: {} + + # -- Values to passthrough to the kyverno chart: https://repo1.dso.mil/big-bang/product/packages/kyverno.git + values: {} + + # -- Post Renderers. See docs/postrenders.md + postRenderers: [] + +kyvernoPolicies: + # -- Toggle deployment of Kyverno policies + enabled: true + + # -- Choose source type of "git" or "helmRepo" + sourceType: "git" + + git: + repo: https://repo1.dso.mil/big-bang/product/packages/kyverno-policies.git + path: ./chart + tag: "3.3.4-bb.0" + helmRepo: + repoName: "registry1" + chartName: "kyverno-policies" + tag: "3.3.4-bb.0" + + # -- Flux reconciliation overrides specifically for the Kyverno Package + flux: {} + + # -- Values to passthrough to the kyverno policies chart: https://repo1.dso.mil/big-bang/product/packages/kyverno-policies.git + values: {} + + # -- Post Renderers. See docs/postrenders.md + postRenderers: [] + +kyvernoReporter: + # -- Toggle deployment of Kyverno Reporter + enabled: true + + # -- Choose source type of "git" or "helmRepo" + sourceType: "git" + + git: + repo: https://repo1.dso.mil/big-bang/product/packages/kyverno-reporter.git + path: ./chart + tag: "2.24.2-bb.2" + helmRepo: + repoName: "registry1" + chartName: "kyverno-reporter" + tag: "2.24.2-bb.2" + + # -- Flux reconciliation overrides specifically for the Kyverno Reporter Package + flux: {} + + # -- Values to passthrough to the kyverno reporter chart: https://repo1.dso.mil/big-bang/product/packages/kyverno-reporter.git + values: {} + + # -- Post Renderers. See docs/postrenders.md + postRenderers: [] + +# ---------------------------------------------------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------------------------------------------------- +# Elasticsearch, Kibana, Fluentbit Logging stack +# +elasticsearchKibana: + # -- Toggle deployment of Logging (EFK). + enabled: false + + # -- Choose source type of "git" or "helmRepo" + sourceType: "git" + + git: + repo: https://repo1.dso.mil/big-bang/product/packages/elasticsearch-kibana.git + path: "./chart" + tag: "1.24.0-bb.2" + helmRepo: + repoName: "registry1" + chartName: "elasticsearch-kibana" + tag: "1.24.0-bb.2" + + # -- Flux reconciliation overrides specifically for the Logging (EFK) Package + flux: + timeout: 20m + + # -- Redirect the package ingress to a specific Istio Gateway (listed in `istio.gateways`). The default is "public". + ingress: + gateway: "" + + sso: + # -- Toggle OIDC SSO for Kibana/Elasticsearch on and off. + # Enabling this option will auto-create any required secrets. + enabled: false + + # -- Elasticsearch/Kibana OIDC client ID + client_id: "" + + # -- Elasticsearch/Kibana OIDC client secret + client_secret: "" + + # -- Elasticsearch/Kibana Service Account Annotations + serviceAccountAnnotations: + elasticsearch: {} + kibana: {} + + license: + # -- Toggle trial license installation of elasticsearch. Note that enterprise (non trial) is required for SSO to work. + trial: false + + # -- Elasticsearch license in json format seen here: https://repo1.dso.mil/big-bang/product/packages/elasticsearch-kibana#enterprise-license + keyJSON: "" + + # -- Values to passthrough to the elasticsearch-kibana chart: https://repo1.dso.mil/big-bang/product/packages/elasticsearch-kibana.git + values: {} + + # -- Post Renderers. See docs/postrenders.md + postRenderers: [] + +eckOperator: + # -- Toggle deployment of ECK Operator. + enabled: false + + # -- Choose source type of "git" or "helmRepo" + sourceType: "git" + + git: + repo: https://repo1.dso.mil/big-bang/product/packages/eck-operator.git + path: "./chart" + tag: "2.16.0-bb.0" + helmRepo: + repoName: "registry1" + chartName: "eck-operator" + tag: "2.16.0-bb.0" + + # -- Flux reconciliation overrides specifically for the ECK Operator Package + flux: {} + + # -- Values to passthrough to the eck-operator chart: https://repo1.dso.mil/big-bang/product/packages/eck-operator.git + values: {} + + # -- Post Renderers. See docs/postrenders.md + postRenderers: [] + +fluentbit: + # -- Toggle deployment of Fluent-Bit. + enabled: false + + # -- Choose source type of "git" or "helmRepo" + sourceType: "git" + + git: + repo: https://repo1.dso.mil/big-bang/product/packages/fluentbit.git + path: "./chart" + tag: "0.48.4-bb.0" + helmRepo: + repoName: "registry1" + chartName: "fluentbit" + tag: "0.48.4-bb.0" + + # -- Flux reconciliation overrides specifically for the Fluent-Bit Package + flux: {} + + # -- Values to passthrough to the fluentbit chart: https://repo1.dso.mil/big-bang/product/packages/fluentbit.git + values: {} + + # -- Post Renderers. See docs/postrenders.md + postRenderers: [] + +# ---------------------------------------------------------------------------------------------------------------------- +# Promtail / Loki Logging stack +# +promtail: + # -- Toggle deployment of Promtail. + enabled: true + + # -- Choose source type of "git" or "helmRepo" + sourceType: "git" + + git: + repo: https://repo1.dso.mil/big-bang/product/packages/promtail.git + path: "./chart" + tag: "6.16.2-bb.4" + helmRepo: + repoName: "registry1" + chartName: "promtail" + tag: "6.16.2-bb.4" + + # -- Flux reconciliation overrides specifically for the Promtail Package + flux: {} + + # -- Values to passthrough to the promtail chart: https://repo1.dso.mil/big-bang/product/packages/fluentbit.git + values: {} + + # -- Post Renderers. See docs/postrenders.md + postRenderers: [] + +loki: + # -- Toggle deployment of Loki. + enabled: true + + # -- Choose source type of "git" or "helmRepo" + sourceType: "git" + + git: + repo: https://repo1.dso.mil/big-bang/product/packages/loki.git + path: "./chart" + tag: "6.24.0-bb.0" + helmRepo: + repoName: "registry1" + chartName: "loki" + tag: "6.24.0-bb.0" + + # -- Flux reconciliation overrides specifically for the Loki Package + flux: {} + + # -- Loki architecture. Options are monolith and scalable + strategy: monolith + + # -- Loki clusterName identifier for Promtail and Dashboards + clusterName: "" + + + objectStorage: + # -- S3 compatible endpoint to use for connection information. + # examples: "https://s3.amazonaws.com" "https://s3.us-gov-west-1.amazonaws.com" "http://minio.minio.svc.cluster.local:9000" + endpoint: "" + + # -- S3 compatible region to use for connection information. + region: "" + + # -- Access key for connecting to object storage endpoint. + accessKey: "" + + # -- Secret key for connecting to object storage endpoint. + # Unencoded string data. This should be placed in the secret values and then encrypted + accessSecret: "" + + # -- Bucket Names for the Loki buckets as YAML + # chunks: loki-logs + # ruler: loki-ruler + # admin: loki-admin + bucketNames: {} + + # -- Values to passthrough to the Loki chart: https://repo1.dso.mil/big-bang/product/packages/loki.git + values: {} + + # -- Post Renderers. See docs/postrenders.md + postRenderers: [] + +# ---------------------------------------------------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------------------------------------------------- + +neuvector: + # -- Toggle deployment of Neuvector. + enabled: true + + # -- Choose source type of "git" or "helmRepo" + sourceType: "git" + + git: + repo: https://repo1.dso.mil/big-bang/product/packages/neuvector.git + path: "./chart" + tag: "2.8.3-bb.0" + helmRepo: + repoName: "registry1" + chartName: "neuvector" + tag: "2.8.3-bb.0" + + # -- Redirect the package ingress to a specific Istio Gateway (listed in `istio.gateways`). The default is "public". + ingress: + gateway: "" + + sso: + # -- Toggle SSO for Neuvector on and off + enabled: false + + # -- OIDC Client ID to use for Neuvector + client_id: "" + + # -- OIDC Client Secret to use for Neuvector + client_secret: "" + + # -- Default role to use for Neuvector OIDC users. Supports admin, reader, or no default + default_role: "" + + # -- Default role to use for Neuvector OIDC users. Supports admin, reader, or no default + group_claim: "" + + # -- Default role to use for Neuvector OIDC users. Supports admin, reader, or no default + group_mapped_roles: [] + + # -- Flux reconciliation overrides specifically for the Neuvector Package + flux: {} + + # -- Values to passthrough to the Neuvector chart: https://repo1.dso.mil/big-bang/product/packages/neuvector.git + values: {} + + # -- Post Renderers. See docs/postrenders.md + postRenderers: [] + +# ---------------------------------------------------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------------------------------------------------- + +tempo: + # -- Toggle deployment of Tempo. + enabled: true + + # -- Choose source type of "git" or "helmRepo" + sourceType: "git" + + git: + repo: https://repo1.dso.mil/big-bang/product/packages/tempo.git + path: "./chart" + tag: "1.16.0-bb.0" + helmRepo: + repoName: "registry1" + chartName: "tempo" + tag: "1.16.0-bb.0" + + # -- Redirect the package ingress to a specific Istio Gateway (listed in `istio.gateways`). The default is "public". + ingress: + gateway: "" + + # -- Flux reconciliation overrides specifically for the Tempo Package + flux: {} + + sso: + # -- Toggle SSO for Tempo on and off + enabled: false + + # -- OIDC Client ID to use for Tempo + client_id: "" + + # -- OIDC Client Secret to use for Tempo + client_secret: "" + + objectStorage: + # -- S3 compatible endpoint to use for connection information. + # examples: "s3.amazonaws.com" "s3.us-gov-west-1.amazonaws.com" "minio.minio.svc.cluster.local:9000" + # Note: tempo does not require protocol prefix for URL. + endpoint: "" + + # -- S3 compatible region to use for connection information. + region: "" + + # -- Access key for connecting to object storage endpoint. + accessKey: "" + + # -- Secret key for connecting to object storage endpoint. + # Unencoded string data. This should be placed in the secret values and then encrypted + accessSecret: "" + + # -- Bucket Name for Tempo + # examples: "tempo-traces" + bucket: "" + + # -- Whether or not objectStorage connection should require HTTPS, if connecting to in-cluster object + # storage on port 80/9000 set this value to true. + insecure: false + + # -- Values to passthrough to the Tempo chart: https://repo1.dso.mil/big-bang/product/packages/tempo.git + values: {} + + # -- Post Renderers. See docs/postrenders.md + postRenderers: [] +# ---------------------------------------------------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------------------------------------------------- + +# Monitoring +# +monitoring: + # -- Toggle deployment of Monitoring (Prometheus, Grafana, and Alertmanager). + enabled: true + + # -- Choose source type of "git" or "helmRepo" + sourceType: "git" + + git: + repo: https://repo1.dso.mil/big-bang/product/packages/monitoring.git + path: "./chart" + tag: "62.4.0-bb.1" + helmRepo: + repoName: "registry1" + chartName: "monitoring" + tag: "62.4.0-bb.1" + + # -- Flux reconciliation overrides specifically for the Monitoring Package + flux: + install: + crds: CreateReplace + upgrade: + crds: CreateReplace + + # -- Redirect the package ingress to a specific Istio Gateway (listed in `istio.gateways`). The default is "public". + ingress: + gateway: "" + + sso: + # -- Toggle SSO for monitoring components on and off + enabled: false + prometheus: + # -- Prometheus OIDC client ID + client_id: "" + + # -- Prometheus OIDC client secret + client_secret: "" + + alertmanager: + # -- Alertmanager OIDC client ID + client_id: "" + + # -- Alertmanager OIDC client secret + client_secret: "" + + # -- Values to passthrough to the monitoring chart: https://repo1.dso.mil/big-bang/product/packages/monitoring.git + values: {} + + # -- Post Renderers. See docs/postrenders.md + postRenderers: [] +# ---------------------------------------------------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------------------------------------------------- + +# Grafana +# +grafana: + # -- Toggle deployment of Grafana + enabled: true + + # -- Choose source type of "git" or "helmRepo" + sourceType: "git" + + git: + repo: https://repo1.dso.mil/big-bang/product/packages/grafana.git + path: "./chart" + tag: "8.8.2-bb.0" + helmRepo: + repoName: "registry1" + chartName: "grafana" + tag: "8.8.2-bb.0" + + # -- Flux reconciliation overrides specifically for the Monitoring Package + flux: {} + + # -- Redirect the package ingress to a specific Istio Gateway (listed in `istio.gateways`). The default is "public". + ingress: + gateway: "" + + sso: + # -- Toggle SSO for grafana components on and off + enabled: false + grafana: + # -- Grafana OIDC client ID + client_id: "" + + # -- Grafana OIDC client secret + client_secret: "" + + # -- Grafana OIDC client scopes, comma separated, see https://grafana.com/docs/grafana/latest/auth/generic-oauth/ + scopes: "" + + allow_sign_up: true + + role_attribute_path: "Viewer" + # -- Other options available, see package Documentation. + + # -- Values to passthrough to the grafana chart: https://repo1.dso.mil/big-bang/product/packages/grafana.git + values: {} + + # -- Post Renderers. See docs/postrenders.md + postRenderers: [] +# ---------------------------------------------------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------------------------------------------------- +# Twistlock +# +twistlock: + # -- Toggle deployment of Twistlock. + enabled: false + + # -- Choose source type of "git" or "helmRepo" + sourceType: "git" + + git: + repo: https://repo1.dso.mil/big-bang/product/packages/twistlock.git + path: "./chart" + tag: "0.18.0-bb.0" + helmRepo: + repoName: "registry1" + chartName: "twistlock" + tag: "0.18.0-bb.0" + + # -- Flux reconciliation overrides specifically for the Twistlock Package + flux: {} + + # -- Redirect the package ingress to a specific Istio Gateway (listed in `istio.gateways`). The default is "public". + ingress: + gateway: "" + + sso: + # -- Toggle SAML SSO, requires a license and enabling the init job - see https://repo1.dso.mil/big-bang/product/packages/initialization.md + enabled: false + + # -- SAML client ID + client_id: "" + + # -- SAML Identity Provider. `shibboleth` is recommended by Twistlock support for Keycloak + # Possible values: okta, gsuite, ping, shibboleth, azure, adfs + provider_type: "shibboleth" + + # -- Groups attribute (optional) + groups: "" + + # -- Values to passthrough to the twistlock chart: https://repo1.dso.mil/big-bang/product/packages/twistlock.git + values: {} + + # -- Post Renderers. See docs/postrenders.md + postRenderers: [] + +# +# ---------------------------------------------------------------------------------------------------------------------- +# +addons: + argocd: + # -- Toggle deployment of ArgoCD. + enabled: false + + # -- Choose source type of "git" or "helmRepo" + sourceType: "git" + + git: + repo: https://repo1.dso.mil/big-bang/product/packages/argocd.git + path: "./chart" + tag: "7.7.10-bb.0" + helmRepo: + repoName: "registry1" + chartName: "argocd" + tag: "7.7.10-bb.0" + + # -- Flux reconciliation overrides specifically for the ArgoCD Package + flux: {} + + # -- Redirect the package ingress to a specific Istio Gateway (listed in `istio.gateways`). The default is "public". + ingress: + gateway: "" + + redis: + # -- Hostname of a pre-existing Redis to use for ArgoCD. + # Entering connection info will enable external Redis and will auto-create any required secrets. + host: "" + + # -- Port of a pre-existing Redis to use for ArgoCD. + port: "" + + sso: + # -- Toggle SSO for ArgoCD on and off + enabled: false + + # -- ArgoCD OIDC client ID + client_id: "" + + # -- ArgoCD OIDC client secret + client_secret: "" + + # -- ArgoCD SSO group roles, see docs for more details: https://argo-cd.readthedocs.io/en/stable/operator-manual/rbac/ + groups: | + g, Impact Level 2 Authorized, role:admin + + # -- Values to passthrough to the argocd chart: https://repo1.dso.mil/big-bang/product/packages/argocd.git + values: {} + + # -- Post Renderers. See docs/postrenders.md + postRenderers: [] + + authservice: + # -- Toggle deployment of Authservice. + # if enabling authservice, a filter needs to be provided by either enabling + # sso for monitoring or istio, or manually adding a filter chain in the values here: + # values: + # chain: + # minimal: + # callback_uri: "https://somecallback" + enabled: false + + # -- Choose source type of "git" or "helmRepo" + sourceType: "git" + + git: + repo: https://repo1.dso.mil/big-bang/product/packages/authservice.git + path: "./chart" + tag: "1.0.3-bb.0" + helmRepo: + repoName: "registry1" + chartName: "authservice" + tag: "1.0.3-bb.0" + + # -- Flux reconciliation overrides specifically for the Authservice Package + flux: {} + + # -- Values to passthrough to the authservice chart: https://repo1.dso.mil/big-bang/product/packages/authservice.git + values: {} + + # -- Post Renderers. See docs/postrenders.md + postRenderers: [] + + # -- Additional authservice chain configurations. + chains: {} + + # ---------------------------------------------------------------------------------------------------------------------- + # Minio Operator and Instance + # + minioOperator: + # -- Toggle deployment of minio operator and instance. + enabled: false + + # -- Choose source type of "git" or "helmRepo" + sourceType: "git" + + git: + repo: https://repo1.dso.mil/big-bang/product/packages/minio-operator.git + path: "./chart" + tag: "6.0.4-bb.1" + helmRepo: + repoName: "registry1" + chartName: "minio-operator" + tag: "6.0.4-bb.1" + + # -- Flux reconciliation overrides specifically for the Minio Operator Package + flux: {} + + # -- Redirect the package ingress to a specific Istio Gateway (listed in `istio.gateways`). The default is "public". + ingress: + gateway: "" + + # -- Values to passthrough to the minio operator chart: https://repo1.dso.mil/big-bang/product/packages/minio-operator.git + values: {} + + # -- Post Renderers. See docs/postrenders.md + postRenderers: [] + + minio: + # -- Toggle deployment of minio. + enabled: false + + # -- Choose source type of "git" or "helmRepo" + sourceType: "git" + + git: + repo: https://repo1.dso.mil/big-bang/product/packages/minio.git + path: "./chart" + tag: "6.0.4-bb.5" + helmRepo: + repoName: "registry1" + chartName: "minio-instance" + tag: "6.0.4-bb.5" + + # -- Flux reconciliation overrides specifically for the Minio Package + flux: {} + + # -- Redirect the package ingress to a specific Istio Gateway (listed in `istio.gateways`). The default is "public". + ingress: + gateway: "" + + # -- Default access key to use for minio. + accesskey: "" + + # -- Default secret key to intstantiate with minio, you should change/delete this after installation. + secretkey: "" + + # -- Values to passthrough to the minio instance chart: https://repo1.dso.mil/big-bang/product/packages/minio.git + values: {} + + # -- Post Renderers. See docs/postrenders.md + postRenderers: [] + + gitlab: + # -- Toggle deployment of Gitlab + enabled: false + + hostnames: + # host name only without the domain + gitlab: gitlab + registry: registry + + # -- Choose source type of "git" or "helmRepo" + sourceType: "git" + + git: + repo: https://repo1.dso.mil/big-bang/product/packages/gitlab.git + path: "./chart" + tag: "8.6.2-bb.0" + helmRepo: + repoName: "registry1" + chartName: "gitlab" + tag: "8.6.2-bb.0" + + # -- Flux reconciliation overrides specifically for the Gitlab Package + flux: {} + + # -- Redirect the package ingress to a specific Istio Gateway (listed in `istio.gateways`). The default is "public". + ingress: + gateway: "" + + sso: + # -- Toggle OIDC SSO for Gitlab on and off. + # Enabling this option will auto-create any required secrets. + enabled: false + + # -- Gitlab OIDC client ID + client_id: "" + + # -- Gitlab OIDC client secret + client_secret: "" + + # -- Gitlab SSO Scopes, default is ["Gitlab"] + scopes: + - Gitlab + + # -- Fill out the groups block below and populate with Keycloak groups according to your desired Gitlab membership requirements. The default groupsAttribute is "groups". + # Full documentation: https://docs.gitlab.com/ee/administration/auth/oidc.html?tab=Linux+package+%28Omnibus%29#configure-users-based-on-oidc-group-membership + groups: [] + # groupsAttribute: "" + # requiredGroups: [] + # externalGroups: [] + # auditorGroups: [] + # adminGroups: [] + + database: + # -- Hostname of a pre-existing PostgreSQL database to use for Gitlab. + # Entering connection info will disable the deployment of an internal database and will auto-create any required secrets. + host: "" + + # -- Port of a pre-existing PostgreSQL database to use for Gitlab. + port: 5432 + + # -- Database name to connect to on host. + database: "" # example: gitlab + + # -- Username to connect as to external database, the user must have all privileges on the database. + username: "" + + # -- Database password for the username used to connect to the existing database. + password: "" + + objectStorage: + # -- Type of object storage to use for Gitlab, setting to s3 will assume an external, pre-existing object storage is to be used. + # Entering connection info will enable this option and will auto-create any required secrets + type: "" # supported types are "s3" or "minio" + + # -- S3 compatible endpoint to use for connection information. + # examples: "https://s3.amazonaws.com" "https://s3.us-gov-west-1.amazonaws.com" "http://minio.minio.svc.cluster.local:9000" + endpoint: "" + + # -- S3 compatible region to use for connection information. + region: "" + + # -- Access key for connecting to object storage endpoint. + # -- If using accessKey and accessSecret, the iamProfile must be left as an empty string: "" + accessKey: "" + + # -- Secret key for connecting to object storage endpoint. + # Unencoded string data. This should be placed in the secret values and then encrypted + accessSecret: "" + + # -- Bucket prefix to use for identifying buckets. + # Example: "prod" will produce "prod-gitlab-bucket" + bucketPrefix: "" + + # -- NOTE: Current bug with AWS IAM Profiles and Object Storage where only artifacts are stored. Fixed in Gitlab 14.5 + # -- Name of AWS IAM profile to use. + # -- If using an AWS IAM profile, the accessKey and accessSecret values must be left as empty strings eg: "" + iamProfile: "" + + smtp: + # -- Passwords should be placed in an encrypted file. Example: environment-bb-secret.enc.yaml + # If a value is provided BigBang will create a k8s secret named gitlab-smtp-password in the gitlab namespace + password: "" + + redis: + # -- Redis plain text password to connect to the redis server. If empty (""), the gitlab charts will create the gitlab-redis-secret + # with a random password. + # -- This needs to be set to a non-empty value in order for the Grafana Redis Datasource and Dashboards to be installed. + password: "" + + # -- Rails plain text secret to define. If empty (""), the gitlab charts will create the gitlab-rails-secret with randomized data. + # Read the following for more information on setting Gitlab rails secrets: https://docs.gitlab.com/charts/installation/secrets#gitlab-rails-secret + railsSecret: "" + + # -- Values to passthrough to the gitlab chart: https://repo1.dso.mil/big-bang/product/packages/gitlab.git + values: {} + + # -- Post Renderers. See docs/postrenders.md + postRenderers: [] + + gitlabRunner: + # -- Toggle deployment of Gitlab Runner + enabled: false + + # -- Choose source type of "git" or "helmRepo" + sourceType: "git" + + git: + repo: https://repo1.dso.mil/big-bang/product/packages/gitlab-runner.git + path: "./chart" + tag: "0.70.4-bb.1" + + helmRepo: + repoName: "registry1" + chartName: "gitlab-runner" + tag: "0.70.4-bb.1" + + + # -- Flux reconciliation overrides specifically for the Gitlab Runner Package + flux: {} + + # -- Values to passthrough to the gitlab runner chart: https://repo1.dso.mil/big-bang/product/packages/gitlab-runner.git + values: {} + + # -- Post Renderers. See docs/postrenders.md + postRenderers: [] + + nexusRepositoryManager: + # -- Toggle deployment of Nexus Repository Manager. + enabled: false + + # -- Choose source type of "git" or "helmRepo" + sourceType: "git" + + git: + repo: https://repo1.dso.mil/big-bang/product/packages/nexus.git + path: "./chart" + tag: "75.0.0-bb.1" + helmRepo: + repoName: "registry1" + chartName: "nexus-repository-manager" + tag: "75.0.0-bb.1" + + # -- Base64 encoded license file. + license_key: "" + + # -- Redirect the package ingress to a specific Istio Gateway (listed in `istio.gateways`). The default is "public". + ingress: + gateway: "" + + sso: + # -- Toggle SAML SSO for NXRM. + # -- handles SAML SSO, a Client must be configured in Keycloak or IdP + # -- to complete setup. + # -- https://support.sonatype.com/hc/en-us/articles/1500000976522-SAML-integration-for-Nexus-Repository-Manager-Pro-3-and-Nexus-IQ-Server-with-Keycloak#h_01EV7CWCYH3YKAPMAHG8XMQ599 + enabled: false + + # -- NXRM SAML SSO Integration data + idp_data: + # Nexus saml URL. example: "https://nexus.bigbang.dev/service/rest/v1/security/saml/metadata" + entityId: "" + + # -- IdP Field Mappings + # -- NXRM username attribute + username: "" + + # -- NXRM firstname attribute (optional) + firstName: "" + + # -- NXRM lastname attribute (optional) + lastName: "" + + # -- NXRM email attribute (optional) + email: "" + + # -- NXRM groups attribute (optional) + groups: "" + + # -- NXRM Role + role: + # the id must match the Keycloak group name (case sensitive) + - id: "" + name: "" + description: "" + privileges: [] + roles: [] + + # -- Flux reconciliation overrides specifically for the Nexus Repository Manager Package + flux: {} + + # -- Values to passthrough to the nxrm chart: https://repo1.dso.mil/big-bang/product/packages/nexus.git + values: {} + + # -- Post Renderers. See docs/postrenders.md + postRenderers: [] + + sonarqube: + # -- Toggle deployment of SonarQube. + enabled: false + + # -- Choose source type of "git" or "helmRepo" + sourceType: "git" + + git: + repo: https://repo1.dso.mil/big-bang/product/packages/sonarqube.git + path: "./chart" + tag: "10.6.1-bb.5" + helmRepo: + repoName: "registry1" + chartName: "sonarqube" + tag: "10.6.1-bb.5" + + # -- Flux reconciliation overrides specifically for the Sonarqube Package + flux: {} + + # -- Redirect the package ingress to a specific Istio Gateway (listed in `istio.gateways`). The default is "public". + ingress: + gateway: "" + + sso: + # -- Toggle SAML SSO for SonarQube. + # Enabling this option will auto-create any required secrets. + enabled: false + + # -- SonarQube SAML client ID + client_id: "" + + # -- SonarQube login sso attribute. + login: login + + # -- SonarQube name sso attribute. + name: name + + # -- SonarQube email sso attribute. + email: email + + # -- (optional) SonarQube group sso attribute. + group: group + + database: + # -- Hostname of a pre-existing PostgreSQL database to use for SonarQube. + host: "" + + # -- Port of a pre-existing PostgreSQL database to use for SonarQube. + port: 5432 + + # -- Database name to connect to on host. + database: "" + + # -- Username to connect as to external database, the user must have all privileges on the database. + username: "" + + # -- Database password for the username used to connect to the existing database. + password: "" + + # -- Values to passthrough to the sonarqube chart: https://repo1.dso.mil/big-bang/product/packages/sonarqube.git + values: {} + + # -- Post Renderers. See docs/postrenders.md + postRenderers: [] + + fortify: + # -- Toggle deployment of Fortify. + enabled: false + + # -- Choose source type of "git" or "helmRepo" + sourceType: "git" + + git: + repo: https://repo1.dso.mil/big-bang/product/packages/fortify.git + path: "./chart" + tag: "1.1.2320154-bb.21" + helmRepo: + repoName: "registry1" + chartName: "fortify-ssc" + tag: "1.1.2320154-bb.21" + + # -- Flux reconciliation overrides specifically for the Fortify Package + flux: {} + + # -- Redirect the package ingress to a specific Istio Gateway (listed in `istio.gateways`). The default is "public". + ingress: + gateway: "" + + sso: + # -- Toggle SSO for Fortify on and off + enabled: false + + # -- SAML Client ID to use for Fortify + client_id: "" + + # -- SAML Client Secret to use for Fortify + client_secret: "" + + # -- Values to passthrough to the fortify chart: https://repo1.dso.mil/big-bang/product/packages/fortify.git + values: {} + + # -- Post Renderers. See docs/postrenders.md + postRenderers: [] + + # ---------------------------------------------------------------------------------------------------------------------- + # Deployment of HAProxy is automatically toggled depending on Monitoring SSO and Monitoring Istio Injection + # + haproxy: + # -- Choose source type of "git" or "helmRepo" + sourceType: "git" + + git: + repo: https://repo1.dso.mil/big-bang/product/packages/haproxy.git + path: "./chart" + tag: "1.19.3-bb.8" + helmRepo: + repoName: "registry1" + chartName: "haproxy" + tag: "1.19.3-bb.8" + + # -- Flux reconciliation overrides specifically for the HAProxy Package + flux: {} + + # -- Redirect the package ingress to a specific Istio Gateway (listed in `istio.gateways`). The default is "public". + ingress: + gateway: "" + + # -- Values to passthrough to the haproxy chart: https://repo1.dso.mil/big-bang/product/packages/haproxy.git + values: {} + + # -- Post Renderers. See docs/postrenders.md + postRenderers: [] + + anchore: + # -- Toggle deployment of Anchore. + enabled: false + + # -- Choose source type of "git" or "helmRepo" + sourceType: "git" + + git: + repo: https://repo1.dso.mil/big-bang/product/packages/anchore-enterprise.git + path: "./chart" + tag: "3.3.1-bb.0" + helmRepo: + repoName: "registry1" + chartName: "anchore" + tag: "3.3.1-bb.0" + + # -- Flux reconciliation overrides specifically for the Anchore Package + flux: + upgrade: + disableWait: true + + # -- Initial admin password used to authenticate to Anchore. + adminPassword: "" + + # -- Anchore Enterprise functionality. + enterprise: + # -- License for Anchore Enterprise. Enterprise is the only option available for the chart starting with chart major version 2.X. + # For formatting examples see https://repo1.dso.mil/big-bang/product/packages/CHART.md#enabling-enterprise-services + licenseYaml: | + FULL LICENSE + + # -- Redirect the package ingress to a specific Istio Gateway (listed in `istio.gateways`). The default is "public". + ingress: + gateway: "" + + sso: + # -- Toggle SAML SSO for Anchore on and off. + # Enabling this option will auto-create any required secrets (Note: SSO requires an Enterprise license). + enabled: false + + # -- Anchore SAML client ID + client_id: "" + + # -- Anchore SAML client role attribute + role_attribute: "" + + database: + # -- Hostname of a pre-existing PostgreSQL database to use for Anchore. + # Entering connection info will disable the deployment of an internal database and will auto-create any required secrets. + host: "" + + # -- Port of a pre-existing PostgreSQL database to use for Anchore. + port: "" + + # -- Username to connect as to external database, the user must have all privileges on the database. + username: "" + + # -- Database password for the username used to connect to the existing database. + password: "" + + # -- Database name to connect to on host (Note: database name CANNOT contain hyphens). + database: "" + + # -- Feeds database name to connect to on host (Note: feeds database name CANNOT contain hyphens). + # Only required for enterprise edition of anchore. + # By default, feeds database will be configured with the same username and password as the main database. For formatting examples on how to use a separate username and password for the feeds database see https://repo1.dso.mil/big-bang/product/packages/CHART.md#handling-dependencies + feeds_database: "" + + redis: + # -- Hostname of a pre-existing Redis to use for Anchore Enterprise. + # Entering connection info will enable external redis and will auto-create any required secrets. + # Anchore only requires redis for enterprise deployments and will not provision an instance if using external + host: "" + + # -- Port of a pre-existing Redis to use for Anchore Enterprise. + port: "" + + # -- OPTIONAL: Username to connect to a pre-existing Redis (for password-only auth leave empty) + username: "" + + # -- Password to connect to pre-existing Redis. + password: "" + + # -- Values to passthrough to the anchore chart: https://repo1.dso.mil/big-bang/product/packages/anchore-enterprise.git + values: {} + + # -- Post Renderers. See docs/postrenders.md + postRenderers: [] + + # ---------------------------------------------------------------------------------------------------------------------- + # Mattermost Operator and Instance + # + mattermostOperator: + # -- Toggle deployment of Mattermost Operator. + enabled: false + + # -- Choose source type of "git" or "helmRepo" + sourceType: "git" + + git: + repo: https://repo1.dso.mil/big-bang/product/packages/mattermost-operator.git + path: "./chart" + tag: "1.22.1-bb.1" + helmRepo: + repoName: "registry1" + chartName: "mattermost-operator" + tag: "1.22.1-bb.1" + + # -- Flux reconciliation overrides specifically for the Mattermost Operator Package + flux: {} + + # -- Values to passthrough to the mattermost operator chart: https://repo1.dso.mil/big-bang/product/packages/values.yaml + values: {} + + # -- Post Renderers. See docs/postrenders.md + postRenderers: [] + + mattermost: + # -- Toggle deployment of Mattermost. + enabled: false + + # -- Choose source type of "git" or "helmRepo" + sourceType: "git" + + git: + repo: https://repo1.dso.mil/big-bang/product/packages/mattermost.git + path: "./chart" + tag: "10.2.0-bb.2" + helmRepo: + repoName: "registry1" + chartName: "mattermost" + tag: "10.2.0-bb.2" + + # -- Flux reconciliation overrides specifically for the Mattermost Package + flux: {} + + # -- Mattermost Enterprise functionality. + enterprise: + # -- Toggle the Mattermost Enterprise. This must be accompanied by a valid license unless you plan to start a trial post-install. + enabled: false + + # -- License for Mattermost. + # This should be the entire contents of the license file from Mattermost (should be one line), example below + # license: "eyJpZCI6InIxM205bjR3eTdkYjludG95Z3RiOD---REST---IS---HIDDEN + license: "" + + # -- Redirect the package ingress to a specific Istio Gateway (listed in `istio.gateways`). The default is "public". + ingress: + gateway: "" + + sso: + # -- Toggle OIDC SSO for Mattermost on and off. + # Enabling this option will auto-create any required secrets. + enabled: false + + # -- Mattermost OIDC client ID + client_id: "" + + # -- Mattermost OIDC client secret + client_secret: "" + + database: + # -- Hostname of a pre-existing PostgreSQL database to use for Mattermost. + # Entering connection info will disable the deployment of an internal database and will auto-create any required secrets. + host: "" + + # -- Port of a pre-existing PostgreSQL database to use for Mattermost. + port: "" + + # -- Username to connect as to external database, the user must have all privileges on the database. + username: "" + + # -- Database password for the username used to connect to the existing database. + password: "" + + # -- Database name to connect to on host. + database: "" + + # -- SSL Mode to use when connecting to the database. + # Allowable values for this are viewable in the postgres documentation: https://www.postgresql.org/docs/current/libpq-ssl.html#LIBPQ-SSL-SSLMODE-STATEMENTS + ssl_mode: "" + + objectStorage: + # -- S3 compatible endpoint to use for connection information. + # Entering connection info will enable this option and will auto-create any required secrets. + # examples: "s3.amazonaws.com" "s3.us-gov-west-1.amazonaws.com" "minio.minio.svc.cluster.local:9000" + endpoint: "" + + # -- Access key for connecting to object storage endpoint. + accessKey: "" + + # -- Secret key for connecting to object storage endpoint. + # Unencoded string data. This should be placed in the secret values and then encrypted + accessSecret: "" + + # -- Bucket name to use for Mattermost - will be auto-created. + bucket: "" + + # -- Mattermost Elasticsearch integration - requires enterprise E20 license - https://docs.mattermost.com/deployment/elasticsearch.html + # Connection info defaults to the BB deployed Elastic, all values can be overridden via the "values" passthrough for other connections. + # See values spec in MM chart "elasticsearch" yaml block - https://repo1.dso.mil/big-bang/product/packages/values.yaml + elasticsearch: + # -- Toggle interaction with Elastic for optimized search indexing + enabled: false + + # -- Values to passthrough to the Mattermost chart: https://repo1.dso.mil/big-bang/product/packages/values.yaml + values: {} + + # -- Post Renderers. See docs/postrenders.md + postRenderers: [] + + velero: + # -- Toggle deployment of Velero. + enabled: false + + # -- Choose source type of "git" or "helmRepo" + sourceType: "git" + + git: + repo: https://repo1.dso.mil/big-bang/product/packages/velero.git + path: "./chart" + tag: "8.2.0-bb.0" + helmRepo: + repoName: "registry1" + chartName: "velero" + tag: "8.2.0-bb.0" + + # -- Flux reconciliation overrides specifically for the Velero Package + flux: {} + + # -- Plugin provider for Velero - requires at least one plugin installed. Current supported values: aws, azure, csi + plugins: [] + # - aws + + # -- Values to passthrough to the Velero chart: https://repo1.dso.mil/big-bang/product/packages/values.yaml + values: {} + + # -- Post Renderers. See docs/postrenders.md + postRenderers: [] + # + # ---------------------------------------------------------------------------------------------------------------------- + + # ---------------------------------------------------------------------------------------------------------------------- + # Keycloak + # + keycloak: + # -- Toggle deployment of Keycloak. + # if you enable Keycloak you should uncomment the istio passthrough configurations above + # istio.ingressGateways.passthrough-ingressgateway and istio.gateways.passthrough + enabled: false + + # -- Choose source type of "git" or "helmRepo" + sourceType: "git" + + git: + repo: https://repo1.dso.mil/big-bang/product/packages/keycloak.git + path: "./chart" + tag: "2.5.1-bb.3" + helmRepo: + repoName: "registry1" + chartName: "keycloak" + tag: "2.5.1-bb.3" + + database: + # -- Hostname of a pre-existing database to use for Keycloak. + # Entering connection info will disable the deployment of an internal database and will auto-create any required secrets. + host: "" + + # -- Pre-existing database type (e.g. postgres) to use for Keycloak. + type: postgres + + # -- Port of a pre-existing database to use for Keycloak. + port: 5432 + + # -- Database name to connect to on host. + database: "" # example: keycloak + + # -- Username to connect as to external database, the user must have all privileges on the database. + username: "" + + # -- Database password for the username used to connect to the existing database. + password: "" + + # -- Flux reconciliation overrides specifically for the OPA Gatekeeper Package + flux: {} + + # -- Redirect the package ingress to a specific Istio Gateway (listed in `istio.gateways`). The default is "public". + ingress: + # the istio gateway for keycloak must have tls.mode: PASSTHROUGH + gateway: "passthrough" + # -- Certificate/Key pair to use as the certificate for exposing Keycloak + # Setting the ingress cert here will automatically create the volume and volumemounts in the Keycloak Package chart + key: "" + cert: "" + + # -- Values to passthrough to the keycloak chart: https://repo1.dso.mil/big-bang/product/packages/keycloak.git + values: {} + + # -- Post Renderers. See docs/postrenders.md + postRenderers: [] + + # ---------------------------------------------------------------------------------------------------------------------- + # Vault + # + vault: + # -- Toggle deployment of Vault. + enabled: false + + # -- Choose source type of "git" or "helmRepo" + sourceType: "git" + + git: + repo: https://repo1.dso.mil/big-bang/product/packages/vault.git + path: "./chart" + tag: "0.29.1-bb.2" + helmRepo: + repoName: "registry1" + chartName: "vault" + tag: "0.29.1-bb.2" + + # -- Flux reconciliation overrides specifically for the Vault Package + flux: {} + + # -- Redirect the package ingress to a specific Istio Gateway (listed in `istio.gateways`). The default is "public". + ingress: + gateway: "" + # -- Certificate/Key pair to use as the certificate for exposing Vault + # Setting the ingress cert here will automatically create the volume and volumemounts in the Vault package chart + key: "" + cert: "" + + # -- Values to passthrough to the vault chart: https://repo1.dso.mil/big-bang/product/packages/vault.git + values: {} + + # -- Post Renderers. See docs/postrenders.md + postRenderers: [] + + # ---------------------------------------------------------------------------------------------------------------------- + # Metrics Server + # + metricsServer: + # -- Toggle deployment of metrics server + # Acceptable options are enabled: true, enabled: false, enabled: auto + # true = enabled / false = disabled / auto = automatic (Installs only if metrics API endpoint is not present) + enabled: auto + + # -- Choose source type of "git" or "helmRepo" + sourceType: "git" + + git: + repo: https://repo1.dso.mil/big-bang/product/packages/metrics-server.git + path: "./chart" + tag: "3.12.2-bb.1" + helmRepo: + repoName: "registry1" + chartName: "metrics-server" + tag: "3.12.2-bb.1" + + # -- Flux reconciliation overrides specifically for the metrics server Package + flux: {} + + # -- Values to passthrough to the metrics server chart: https://repo1.dso.mil/big-bang/product/packages/metrics-server.git + values: {} + + # -- Post Renderers. See docs/postrenders.md + postRenderers: [] + + # ---------------------------------------------------------------------------------------------------------------------- + # Harbor + # + harbor: + # -- Toggle deployment of harbor + enabled: false + + # -- Choose source type of "git" or "helmRepo" + sourceType: "git" + + git: + repo: https://repo1.dso.mil/platform-one/big-bang/apps/sandbox/harbor.git + tag: "1.16.0-bb.2" + path: "./chart" + helmRepo: + repoName: "registry1" + chartName: "harbor" + tag: "1.16.0-bb.2" + + # -- Flux reconciliation overrides specifically for the Jaeger Package + flux: {} + + # -- Redirect the package ingress to a specific Istio Gateway (listed in `istio.gateways`). The default is "public". + ingress: + gateway: "" + + # -- Values to pass through to Habor chart: https://repo1.dso.mil/big-bang/product/packages/harbor.git + values: {} + + # -- Post Renderers. See docs/postrenders.md + postRenderers: [] + + holocron: + # -- Toggle deployment of Holocron. + enabled: false + + # -- Choose source type of "git" or "helmRepo" + sourceType: "git" + + git: + repo: https://repo1.dso.mil/big-bang/product/packages/holocron.git + tag: "1.0.12" + path: "./chart" + helmRepo: + repoName: "registry1" + chartName: "holocron" + tag: "1.0.12" + + collectorAuth: + # -- Name of existing secret with auth tokens for collector services: https://repo1.dso.mil/groups/big-bang/apps/sandbox/holocron/-/wikis/Administrator-Guide + # -- Default keys for secret are: + # -- gitlab-scm-0, gitlab-workflow-0, gitlab-build-0, jira-workflow-0, sonarqube-project-analysis-0 + # -- If not provided, one will be created + existingSecret: "" + # -- Tokens for the secret to be created + gitlabToken: mygitlabtoken + jiraToken: myjiratoken + sonarToken: mysonartoken + + jira: + # -- If there is a Jira deployment, enable a collector for it + enabled: false + service: + # -- The service name to communicate with + name: "" + # -- If network policies are enabled, a label to match the namespace for egress policy + label: + key: value + + # -- Flux reconciliation overrides specifically for the Holocron Package + flux: {} + + # -- Redirect the package ingress to a specific Istio Gateway (listed in `istio.gateways`). The default is "public". + ingress: + gateway: "" + + sso: + # -- Toggle SSO for Holocron on and off + enabled: false + + # -- OIDC Client ID to use for Holocron + client_id: "" + + # -- OIDC Client Secret to use for Holocron + client_secret: "" + + # -- Holocron SSO group roles: https://repo1.dso.mil/groups/big-bang/apps/sandbox/holocron/-/wikis/Administrator-Guide + groups: + admin: "" + leadership: "" + + database: + # -- Hostname of a pre-existing PostgreSQL database to use for Gitlab. + # -- Entering connection info will disable the deployment of an internal database and will auto-create any required secrets. + host: "" + + # -- Port of a pre-existing PostgreSQL database to use for Gitlab. + port: 5432 + + # -- Database name to connect to on host. + database: "holocron" + + # -- Username to connect as to external database, the user must have all privileges on the database. + username: "holocron" + + # -- Database password for the username used to connect to the existing database. + password: "holocron" + + # -- Post Renderers. See docs/postrenders.md + postRenderers: [] + + # -- Values to passthrough to the Holocron chart: https://repo1.dso.mil/big-bang/product/packages/holocron.git + values: {} + + # ---------------------------------------------------------------------------------------------------------------------- + # thanos + # + thanos: + # -- Toggle deployment of thanos + enabled: false + + sso: + # -- Toggle SSO for Thanos on and off + enabled: false + + # -- OIDC Client ID to use for Thanos + client_id: "" + + # -- OIDC Client Secret to use for Thanos + client_secret: "" + + #Enable S3 Object Storage for Thanos-sidecar https://thanos.io/tip/components/sidecar.md/ and enables Thanos Store Gateway by default https://thanos.io/tip/components/store.md/ + objectStorage: + # -- S3 compatible endpoint to use for connection information. + # examples: "s3.amazonaws.com" "s3.us-gov-west-1.amazonaws.com" "minio.minio.svc.cluster.local:9000" + # Note: Thanos does not require protocol prefix for URL. + endpoint: "" + + # -- S3 compatible region to use for connection information. + region: "" + + # -- Access key for connecting to object storage endpoint. + accessKey: "" + + # -- Secret key for connecting to object storage endpoint. + # Unencoded string data. This should be placed in the secret values and then encrypted + accessSecret: "" + + # -- Bucket Name for Thanos + # examples: "Thanos-metrics" + bucket: "" + + # -- Whether or not objectStorage connection should require HTTPS, if connecting to in-cluster object + insecure: false + + # -- Choose source type of "git" or "helmRepo" + sourceType: "git" + + git: + repo: https://repo1.dso.mil/big-bang/product/packages/thanos.git + tag: "15.9.1-bb.0" + path: "./chart" + helmRepo: + repoName: "registry1" + chartName: "thanos" + tag: "15.9.1-bb.0" + + # -- Flux reconciliation overrides specifically for the Thanos Package + flux: {} + + # -- Redirect the package ingress to a specific Istio Gateway (listed in `istio.gateways`). The default is "public". + ingress: + gateway: "" + + values: {} + + postRenderers: [] + + externalSecrets: + # -- Toggle deployment of external secrets + enabled: false + + # -- Choose source type of "git" or "helmRepo" + sourceType: "git" + + git: + repo: https://repo1.dso.mil/big-bang/product/packages/external-secrets.git + tag: "0.11.0-bb.3" + path: "./chart" + helmRepo: + repoName: "registry1" + chartName: "external-secrets" + tag: "0.11.0-bb.3" + + # -- Override flux settings for this package + flux: {} + + # -- Redirect the package ingress to a specific Istio Gateway (listed in `istio.gateways`). The default is "public". + ingress: + gateway: "" + + values: {} + + postRenderers: [] + + alloy: + # -- Toggle deployment of grafana alloy + enabled: false + + # -- Choose source type of "git" or "helmRepo" + sourceType: "git" + + git: + repo: https://repo1.dso.mil/big-bang/product/packages/alloy.git + tag: "1.6.16-bb.0" + path: "./chart" + helmRepo: + repoName: "registry1" + chartName: "k8s-monitoring" + tag: "1.6.16-bb.0" + + values: {} + + postRenderers: [] + + # -- Flux reconciliation overrides specifically for the alloy package + flux: {} + +# -- Wrapper chart for integrating Big Bang components alongside a package +wrapper: + # -- Choose source type of "git" or "helmRepo" + sourceType: "git" + + helmRepo: + # -- Repository holding OCI chart, corresponding to `helmRepositories` name + repoName: "registry1" + # -- Name of the OCI chart in `repo` + chartName: wrapper + # -- Tag of the OCI chart in `repo` + tag: "0.4.12" + git: + # -- Git repo holding the wrapper helm chart, example: https://repo1.dso.mil/big-bang/product/packages/wrapper + repo: "https://repo1.dso.mil/big-bang/product/packages/wrapper.git" + # -- Path inside of the git repo to find the helm chart, example: chart + path: "chart" + # -- Git tag to check out. Takes precedence over branch. [More info](https://fluxcd.io/flux/components/source/gitrepositories/#reference), example: 0.0.2 + tag: "0.4.12" + +# -- Packages to deploy with Big Bang +# @default - '{}' +packages: + # -- Package name. Each package will be independently wrapped for Big Bang integration. + # @default -- Uses `defaults/<package name>.yaml` for defaults. See `package` Helm chart for additional values that can be set. + sample: + # -- Toggle deployment of this package + # @default -- true + enabled: false + + # -- Choose source type of "git" or "helmRepo" + sourceType: "git" + + # -- Toggle wrapper functionality. See https://docs-bigbang.dso.mil/latest/docs/guides/deployment-scenarios/extra-package-deployment/#Wrapper-Deployment for more details. + # @default -- false + wrapper: + enabled: false + # -- After deployment, patch wrapper resources. [More info](https://fluxcd.io/flux/components/helm/helmreleases/#post-renderers) + postRenderers: [] + + # -- Use a kustomize deployment rather than Helm + kustomize: false + + # -- HelmRepo source is supported as an option for Helm deployments. If both `git` and `helmRepo` are provided `git` will take precedence. + helmRepo: + # -- Name of the HelmRepo specified in `helmRepositories` + # @default -- Uses `registry1` Helm Repository if not specified + repoName: + # -- Name of the chart stored in the Helm repository + # @default -- Uses values key/package name if not specified + chartName: + # -- Tag of the chart in the Helm repo, required + tag: + # -- If the HelmRelease should verify the cosign signature of the HelmRepo (only relevant if Repo is OCI). Set to 'false' to disable verification + #cosignVerify: + + # -- Git source is supported for both Helm and Kustomize deployments. If both `git` and `helmRepo` are provided `git` will take precedence. + git: + # -- Git repo URL holding the helm chart for this package, required if using git + repo: + # -- Git commit to check out. Takes precedence over semver, tag, and branch. [More info](https://fluxcd.io/flux/components/source/gitrepositories/#reference) + commit: + # -- Git semVer tag expression to check out. Takes precedence over tag. [More info](https://fluxcd.io/flux/components/source/gitrepositories/#reference) + semver: + # -- Git tag to check out. Takes precedence over branch. [More info](https://fluxcd.io/flux/components/source/gitrepositories/#reference) + tag: + # -- Git branch to check out. [More info](https://fluxcd.io/flux/components/source/gitrepositories/#reference). + # @default -- When no other reference is specified, `master` branch is used + branch: + # -- Path inside of the git repo to find the helm chart or kustomize + # @default -- For Helm charts `chart`. For Kustomize `/`. + path: + # -- Optional, alternative existing secret to use for git credentials, must be in the appropriate format: https://toolkit.fluxcd.io/components/source/gitrepositories/#https-authentication + existingSecret: "" + # -- Optional, alternative Chart created secrets with user defined values + credentials: + # -- HTTP git credentials, both username and password must be provided + username: "" + password: "" + # -- HTTPS certificate authority file. Required for any repo with a self signed certificate + caFile: "" + # -- SSH git credentials, privateKey, publicKey, and knownHosts must be provided + privateKey: "" + publicKey: "" + knownHosts: "" + + # -- Override flux settings for this package + flux: {} + + # -- After deployment, patch package resources. [More info](https://fluxcd.io/flux/components/helm/helmreleases/#post-renderers) + postRenderers: [] + + # -- Specify dependencies for the package. Only used for HelmRelease, does not effect Kustomization. See [here](https://fluxcd.io/flux/components/helm/helmreleases/#helmrelease-dependencies) for a reference. + dependsOn: [] + + # -- Package details for Istio. See [wrapper values](https://repo1.dso.mil/big-bang/product/packages/wrapper/-/blob/main/chart/values.yaml) for settings. + istio: {} + + # -- Package details for monitoring. See [wrapper values](https://repo1.dso.mil/big-bang/product/packages/wrapper/-/blob/main/chart/values.yaml) for settings. + monitor: {} + + # -- Package details for network policies. See [wrapper values](https://repo1.dso.mil/big-bang/product/packages/wrapper/-/blob/main/chart/values.yaml) for settings. + network: {} + + # -- Secrets that should be created prior to package installation. See [wrapper values](https://repo1.dso.mil/big-bang/product/packages/wrapper/-/blob/main/chart/values.yaml) for settings. + secrets: {} + + # -- ConfigMaps that should be created prior to package installation. See [wrapper values](https://repo1.dso.mil/big-bang/product/packages/wrapper/-/blob/main/chart/values.yaml) for settings. + configMaps: {} + + # -- Values to pass through to package Helm chart + values: {} + + diff --git a/docs/.pages b/docs/.pages new file mode 100644 index 0000000000000000000000000000000000000000..a680d63f91776a0df3803589ce10cf8ded9cf9a4 --- /dev/null +++ b/docs/.pages @@ -0,0 +1,8 @@ +nav: + - Overview: README.md + - Packages: packages.md + - Developer: developer + - Guides: guides + - Prerequisites: prerequisites + - Understanding Big Bang: understanding-bigbang + - FAQ: FAQ.md diff --git a/docs/FAQ.md b/docs/FAQ.md new file mode 100644 index 0000000000000000000000000000000000000000..1817e569305767e955f14f36d299ce722c9794d0 --- /dev/null +++ b/docs/FAQ.md @@ -0,0 +1,111 @@ +# Frequently Asked Questions + +## Costs and licensing Fees + +> Will a user, Government program, or support contract incur any costs, other +than their own labor, for installing and using Big Bang? + +Big Bang itself is open-source. You do not need to pay Platform One +to use it in your environment. + +Our baseline includes multiple software components, with a variety +of open-source and commercial licenses. Details of these components and +their licensing models can be found in +[Big Bang Licensing Model Overview.](./understanding-bigbang/licensing-model.md) + +In Big Bang 2.0, our default core components will be open source; however, paid +alternatives will remain available. + +You are in complete control over which components you install in your +environment, and choose whether or not to use commercial software. +However, your Approving Official may require certain commercial applications for a continuous Authority to Operate (cATO). + +> Are users required to set up a contract with Platform One in order to +use Big Bang? + +No. Big Bang is open source, and can be used by you and your organization +without payment to Platform One. + +Platform One does offer optional hosting and support contracts. These are listed in the following: + +- Our Big Bang Integration Team helps customers install, upgrade, and operate Big Bang on customer hardware and in customer environments. +- Our Digital Twin service will deploy an instance of your application to + our testing clusters, so we can ensure that changes to our baseline won't break your integration tests. Providing you with customized release notes for your environment. +- [Party Bus](https://p1.dso.mil/products/party-bus) is a managed environment and + instance of Big Bang, which an application can be hosted on. Party Bus removes the + need for you to operate a cluster entirely. + +For more information on services, [contact us](https://p1.dso.mil/contact-us) or email platformone@dso.mil. + +> Do we need a government PM to send a formal request to Platform One in order +to get started? + +No. Big Bang is Open Source, and you do not need our permission to use it. +However, we always like to hear from our users, both to know how large an +impact this effort is making, and to make sure we are addressing our users' +most pressing needs. + +<!-- +TODO: reach out link +--> + +## Security + +> Is Big Bang secure? What about its plugins? + +Big Bang is compliant with the +[DevSecOps Reference Architecture](https://dodcio.defense.gov/Portals/0/Documents/Library/DoD%20Enterprise%20DevSecOps%20Reference%20Design%20-%20CNCF%20Kubernetes%20w-DD1910_cleared_20211022.pdf), and is used at all impact levels and classifications. + +[Iron Bank](https://p1.dso.mil/products/iron-bank) performs automated scans of all image +components used in Big Bang, and patches vulnerabilities as they are found. Big Bang +pulls all hardened images from Iron Bank. + +<!-- +TODO: link to cATO docs - Cyber is working on a Care Package at IL4 to link here +--> + +## Deployment + +> Can we stand up our own instance of Big Bang in AWS GovCloud? + +Yes. Big Bang strives to be vendor-agnostic, and will run on Cloud One, +AWS GovCloud, Microsoft Azure, on-prem hardware, and in air-gapped +environments. + +> Do we have to set up a full Kubernetes distribution? Can we just deploy Big Bang to a Virtural Machine? + +Big Bang is, at its core, a Helm chart, which creates templates for Kubernetes +resources. As such, Big Bang requires a full Kubernetes environment. + +If your organization is unable to support a full Kubernetes environment, you may wish to +consider [Party Bus](https://p1.dso.mil/products/party-bus), which is Platform One's +managed Big Bang Platform as a Service (PaaS) solution, or one of the [Big Bang Resellers](https://p1.dso.mil/resellers). + +## Change Control + +> How do you manage change control on Big Bang? How can we be notified of changes? + +Big Bang has a two-week release cadence. You can view our +[release schedule](https://docs-bigbang.dso.mil/latest/#Navigating-our-documentation), +our [project milestones](https://repo1.dso.mil/groups/big-bang/-/milestones), +and our [release notes](https://repo1.dso.mil/big-bang/bigbang/-/releases) +for more information. + +## Documentation and Briefings + +> Can you provide the latest documentation and briefings? + +The most up-to-date information on BigBang can be found on +[Big Bang Docs.](https://docs-bigbang.dso.mil/latest/docs) + +An overview of BigBang's architecture, and the packages available, can be found +on the [Big Bang Universe.](https://universe.bigbang.dso.mil/) + +It would also be useful to review +[Understanding Big Bang.](https://docs-bigbang.dso.mil/latest/docs/understanding-bigbang/?h=understanding+bigbang%2F) + +## New Packages + +> How do I get a new package integrated into Big Bang? + +To integrate a new package into Big Bang, follow the steps outlined in the [package integration documents](developer/package-integration/README.md) and the [developing a package document](developer/develop-package.md). diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000000000000000000000000000000000000..863dae808ae0df576966f522c3ccf44fe907721d --- /dev/null +++ b/docs/README.md @@ -0,0 +1,79 @@ +# Big Bang Documentation README + +## What is Big Bang? + +* Big Bang is a Helm Chart that is used to deploy a DevSecOps Platform on a Kubernetes Cluster. The DevSecOps Platform is composed of application packages which are bundled as helm charts that leverage Iron Bank hardened container images. +* The Big Bang Helm Chart deploys gitrepository and helmrelease Custom Resources to a Kubernetes Cluster running the Flux GitOps Operator, these can be seen using `kubectl get gitrepository,helmrelease -n=bigbang.` Flux then installs the helm charts defined by the Custom Resources into the cluster. +* The Big Bang Helm Chart has a values.yaml file that does two main things: + * Defines which DevSecOps Platform packages/helm charts will be deployed. + * Defines what input parameters will be passed through to the chosen helm charts. +* You can see what applications are part of the platform by checking the following resources: + * [packages.md](./packages.md) lists the packages and organizes them in categories. + * [Release Notes](https://repo1.dso.mil/big-bang/bigbang/-/releases) lists the packages and their versions. + * For a code based source of truth, you can check [Big Bang's default values.yaml](../chart/values.yaml), and `[CTRL] + [F]`, `"repo:"`, to quickly iterate through the list of applications supported by the Big Bang team. + * [Big Bang Universe](https://universe.bigbang.dso.mil) provides an interactive visual of all packages in Core, Addons, and Community as described in [Big Bang README](../README.md#usage--scope) + +### What *isn't* Big Bang? + +* Big Bang by itself is not intended to be an End-to-End Secure Kubernetes Cluster Solution, but rather a reusable secure component/piece of a full solution. +* A Secure Kubernetes Cluster Solution will have multiple components that can each be swappable and in some cases considered optional depending on use case and risk tolerance: + Example of some potential components in a full End-to-End Solution: + * Ingress traffic protection + * Platform One's Cloud Native Access Point (CNAP) is one solution. + * CNAP can be swapped with an equivalent, or considered optional in an internet disconnected setup. + * Hardened Host OS + * Hardened Kubernetes Cluster + * Big Bang assumes Bring your own Cluster (BYOC) + * The Big Bang team recommends consumers who are interested in a full solution, partner with Vendors of Kubernetes Distributions to satisfy the prerequisite of a Hardened Kubernetes Cluster. + * Hardened Applications running on the Cluster + * Iron Bank provides hardened containers that helps solve this component. + * Big Bang utilizes the hardened containers in Iron Bank. + +## What are the benefits of using Big Bang? + +* Compliant with the [DoD DevSecOps Reference Architecture Design](https://dodcio.defense.gov/Portals/0/Documents/Library/DoD%20Enterprise%20DevSecOps%20Reference%20Design%20-%20CNCF%20Kubernetes%20w-DD1910_cleared_20211022.pdf). +* Can be used to check some but not all of the boxes needed to achieve a Continuous Authority to Operate (cATO) or Authority to Operate (ATO). +* Left shift supply chain security concerns using hardened Iron Bank container images. +* GitOps adds security benefits, and Big Bang leverages GitOps, and can be further extended using GitOps. + Security Benefits of GitOps: + * Prevents configuration drift between state of a live cluster and IaC/CaC source of truth: By avoiding giving any humans direct `kubectl` access, by only allowing humans to deploy via git commits, out of band changes are limited. + * Git Repo based deployments create an audit trail. + * Reusable secure configurations lowers the burden of implementing secure configurations. +* Lowers maintainability overhead involved in keeping the images of a DevSecOps Platform up to date and maintaining a secure posture over the long term. This is achieved by pairing the GitOps pattern with the Umbrella Helm Chart Pattern. + Let's walk through an example: + * Initially a `kustomization.yaml` file in a git repo will tell the Flux GitOps operator (software deployment bot running in the cluster), to deploy version 1.0.0 of Big Bang. Big Bang could deploy 10 helm charts and each helm chart could deploy 10 images. (In this example, Big Bang is managing 100 container images.) + * After a two-week sprint, version 1.1.0 of Big Bang is released. A Big Bang consumer updates the `kustomization.yaml` file in their git repo to point to version 1.1.0 of the Big Bang Helm Chart. That triggers an update of 10 helm charts to a new version of the helm chart. Each updated helm chart will point to newer versions of the container images managed by the helm chart. + * When the end user edits the version of one `kustomization.yaml` file, that triggers a chain reaction that updates 100 container images in the cluster. + * These upgrades are pre-tested. The Big Bang team "eats our own dogfood." Our CI jobs for developing the Big Bang product, run against a Big Bang Dogfood Cluster, and as part of our release process we upgrade our Big Bang Dogfood Cluster, before publishing each release. + > **Note:** We ONLY support and recommend successive upgrades. We do not test upgrades that skip multiple minor versions. + * Auto updates are also possible by setting kustomization.yaml to 1.x.x, because Big Bang follows semantic versioning per the [Big Bang README](../README.md#release-schedule), and flux is smart enough to read x as the most recent version number. +* SSO support is included in the Big Bang platform offering. Operations teams can leverage Big Bang's free Single Sign On capability by deploying the [Keycloak project](https://www.keycloak.org/). Using Keycloak, an ops team configures the platform SSO settings so that SSO can be leveraged by all apps hosted on the platform. For details, see the [SSO Readme](docs/developer/package-integration/sso.md). Once Authservice is configured, to enable SSO for an individual app, developers need only ensure the presence of the two following labels: + - __Namespace__ `istio-injection=enabled`: transparently injects mTLS service mesh protection into their application's Kubernetes YAML manifest + - __Pod__ `protect=keycloak`: declares an EnvoyFilter CustomResource to auto inject an SSO Authentication Proxy in front of the data path to get to their application + +## How do I deploy Big Bang? + +**Note:** The Deployment Process and Pre-Requisites will vary depending on the deployment scenario. The [Quick Start Demo Deployment](./guides/deployment-scenarios/quickstart.md) for example, allows some steps to be skipped due to a mixture of automation and generically reusable demonstration configuration that satisfies pre-requisites. The following is a general overview of the process, reference the [deployment guides](./guides/#deployment-scenarios) for more detail. + +1. Satisfy Pre-Requisites: + * Provision a Kubernetes Cluster according to [best practices](./prerequisites/kubernetes-preconfiguration.md#best-practices). + * Ensure the cluster has network connectivity to a Git Repo you control. + * Install Flux GitOps Operator on the cluster. + * Configure Flux, the cluster, and the Git Repo for GitOps Deployments that support deploying encrypted values. + * Commit to the Git Repo Big Bang's `values.yaml` and encrypted secrets that have been configured to match the desired state of the cluster (including HTTPS Certs and DNS names). +1. `kubectl apply --filename bigbang.yaml` + * [bigbang.yaml](https://repo1.dso.mil/big-bang/customers/template/-/blob/main/umbrella-strategy/bigbang.yaml) will trigger a chain reaction of GitOps Custom Resources that will deploy other GitOps Custom Resources that will eventually deploy an instance of a DevSecOps Platform that's declaratively defined in your Git Repo. + * To be specific, the chain reaction pattern we consider best practice is to have: + * `bigbang.yaml` deploys a git repository and kustomization Custom Resource. + * Flux reads the declarative configuration stored in the kustomization Custom Resource to do a GitOps equivalent of `kustomize build . | kubectl apply --filename -`, to deploy a helmrelease Custom Resource of the Big Bang Helm Chart, that references input `values.yaml` files defined in the Git Repo. + * Flux reads the declarative configuration stored in the helmrelease Custom Resource to do a GitOps equivalent of `helm upgrade --install bigbang /chart --namespace=bigbang --filename encrypted_values.yaml --filename values.yaml --create-namespace=true`, the Big Bang Helm Chart, then deploys more Custom Resources that flux uses to deploy packages specified in Big Bang's `values.yaml.` + +## New User Orientation + +New users are encouraged to read through the useful background information present in the [Understanding Big Bang Section](./understanding-bigbang). + +## Frequently Asked Questions + +You can view answers to a number of [frequently asked questions](FAQ.md). + + Please direct all code changes, issues, and comments to [https://repo1.dso.mil/big-bang/bigbang](https://repo1.dso.mil/big-bang/bigbang). diff --git a/docs/assets/configs/appliance-mode/values.yaml b/docs/assets/configs/appliance-mode/values.yaml new file mode 100644 index 0000000000000000000000000000000000000000..3ce3fd11b1f8e43ca01f96703822466e67ba577b --- /dev/null +++ b/docs/assets/configs/appliance-mode/values.yaml @@ -0,0 +1,209 @@ +--- +# Enables and configures packages for [Appliance Mode](../../../guides/deployment-scenarios/appliance-mode.md): +istio: + values: + istiod: + resources: + requests: + cpu: 100m + memory: 256Mi + values: + global: + proxy: + resources: + requests: + cpu: 50m + memory: 128Mi + proxy_init: + resources: + requests: + cpu: 50m + memory: 128Mi + +istioOperator: + values: + operator: + resources: + requests: + cpu: 100m + memory: 128Mi + +jaeger: + enabled: false + +kiali: + enabled: false + +clusterAuditor: + enabled: false + values: + resources: + requests: + cpu: 100m + memory: 256Mi + +gatekeeper: + enabled: false + values: + replicas: 1 + controllerManager: + resources: + requests: + cpu: 100m + memory: 256Mi + audit: + resources: + requests: + cpu: 100m + memory: 256Mi + limits: + cpu: 600m + memory: 512Mi + +kyverno: + enabled: true + values: + replicaCount: 1 + resources: + limits: + cpu: 350m + memory: 512Mi + requests: + cpu: 350m + memory: 512Mi + +kyvernoReporter: + enabled: true + values: + resources: + limits: + cpu: 50m + memory: 100Mi + requests: + cpu: 50m + memory: 100Mi + +kyvernoPolicies: + enabled: true + +elasticsearchKibana: + enabled: false + +eckOperator: + enabled: false + +fluentbit: + enabled: false + +promtail: + enabled: true + values: + resources: + requests: + cpu: 50m + memory: 32Mi + +loki: + enabled: true + values: + singleBinary: + replicas: 1 + resources: + requests: + cpu: 100m + memory: 256Mi + +neuvector: + enabled: false + values: + controller: + replicas: 1 + resources: + limits: + cpu: 200m + memory: 768Mi + requests: + cpu: 100m + memory: 512Mi + cve: + scanner: + replicas: 1 + k3s: + enabled: true + +tempo: + enabled: true + values: + tempo: + resources: + limits: + cpu: 200m + memory: 256Mi + requests: + cpu: 200m + memory: 256Mi + tempoQuery: + resources: + limits: + cpu: 100m + memory: 256Mi + requests: + cpu: 100m + memory: 256Mi + + +monitoring: + values: + prometheus: + prometheusSpec: + resources: + requests: + cpu: 100m + memory: 128Mi + limits: + cpu: 300m + memory: 2Gi + kube-state-metrics: + resources: + requests: + cpu: 10m + memory: 128Mi + prometheus-node-exporter: + hostRootFsMount: + enabled: false + resources: + requests: + cpu: 100m + memory: 128Mi + grafana: + testFramework: + enabled: false + prometheusOperator: + resources: + requests: + cpu: 100m + memory: 128Mi + prometheusConfigReloader: + resources: + requests: + cpu: 50m + memory: 50Mi + limits: + cpu: 100m + memory: 50Mi + +twistlock: + enabled: true + values: + resources: + requests: + memory: 512Mi + cpu: 50m + init: + resources: + requests: + cpu: 100m + memory: 128Mi + limits: + cpu: 100m + memory: 128Mi diff --git a/docs/assets/configs/example/core-packages-1-x.yaml b/docs/assets/configs/example/core-packages-1-x.yaml new file mode 100644 index 0000000000000000000000000000000000000000..fbf5272c61bb39267d0c00b27b2e5ba67cf6d4a9 --- /dev/null +++ b/docs/assets/configs/example/core-packages-1-x.yaml @@ -0,0 +1,35 @@ +# Runtime Security +twistlock: + enabled: true +neuvector: + enabled: false + +# Log Forwarding +fluentbit: + enabled: true +promtail: + enabled: false + +# Log Storage +elasticsearchKibana: + enabled: true +loki: + enabled: false + +# Policy Enforcement +gatekeeper: + enabled: true +clusterAuditor: + enabled: true +kyverno: + enabled: false +kyvernoReporter: + enabled: false +kyvernoPolicies: + enabled: false + +# Tracing +jaeger: + enabled: true +tempo: + enabled: false diff --git a/docs/assets/configs/example/dev-sso-values.yaml b/docs/assets/configs/example/dev-sso-values.yaml new file mode 100644 index 0000000000000000000000000000000000000000..61b2fcabe9082ff5ad9d06044e6f718e51ec1527 --- /dev/null +++ b/docs/assets/configs/example/dev-sso-values.yaml @@ -0,0 +1,329 @@ +# Enables and configures sso for all packages using the test dev.bigbang.mil clients: +sso: + name: P1 SSO + # Entrust certificate authority for login.dso.mil + # do not use this CA with a Keycloak deployed with a different certificate authority + # For example *.dev.bigbang.mil because that certificate is issued by a different CA + certificateAuthority: + cert: | + -----BEGIN CERTIFICATE----- + MIII9DCCBtygAwIBAgIQcDdmU10lewJL420LUmSlqzANBgkqhkiG9w0BAQsFADBR + MQswCQYDVQQGEwJVUzEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9uMSgwJgYDVQQD + DB9FbnRydXN0IE9WIFRMUyBJc3N1aW5nIFJTQSBDQSAxMB4XDTI0MTIwMzE0MDMx + NFoXDTI1MTIwMzA2MDAwMFowbTELMAkGA1UEBhMCVVMxETAPBgNVBAgMCENvbG9y + YWRvMRkwFwYDVQQHDBBDb2xvcmFkbyBTcHJpbmdzMR4wHAYDVQQKDBVEZXBhcnRt + ZW50IG9mIERlZmVuc2UxEDAOBgNVBAMMB2Rzby5taWwwggIiMA0GCSqGSIb3DQEB + AQUAA4ICDwAwggIKAoICAQCgmjtHCGVsA5GnVUMHRO8LdOXdw8y6Nz6+j3cpPrrx + /H1ylwFk2ep8uwxj3fIbehj1oeG9+ULDdJdpL/FKIYCJrmEcJqEdAClP8955oEqo + boCFnWziit4TfWCM8kdsrbJU1eI9GofG3R5Nx+fyCSICiccmTSH4TNHRSLMrFUP8 + jNcm3rjPVYL9OEg5JL2rkpn7bu6Izlkqn+vtt2KNW+/OdY3pMuwL/tAcf6XV3UpT + BM5VM6JquJUv9t3dE/YzQaKeXqnnscbUHXlRK/qA+EvymHeB2Ts8qIC4FYlDs6xZ + 49tuSDN74F/SLVp4PeaNo8j7GoY4kmlirzgnSOkx1hYQ1goq1uGjfuq2cpXGncb2 + 2G438iJeEEBGJm0L0/ZAovAnDsrakOhM4QfaSvJ5EFTttl/HsuSCwnDWhMWr1UQJ + ZCaaJ5FLaTHRp8oIVDC+WzWJVlrmBtJhw/BZOp0eSsaungLNbRuJ2Tofc9OU82lN + XqFRGl3FDadW6Y0sWY5pvPsEFGfruP0QFDO3wIgv47S/he0uwFraE56teEGhj4AT + GlyPM6Q+O/ichOUJ8vcyEd9yCeIoHeZHLBQBmnduHVgsc0b15Vq+Co09wYrb9/ba + Qta0mbBdPs1rMvvA+zJWrJ/MZC2J0H3a83biKiEtTYOxzkTlUD7Lp5vOB/3IFocZ + MQIDAQABo4IDqjCCA6YwDAYDVR0TAQH/BAIwADAfBgNVHSMEGDAWgBRoDUXKNcLn + mhvws4Td1dp/C4nBETBoBggrBgEFBQcBAQRcMFowNgYIKwYBBQUHMAKGKmh0dHA6 + Ly9jZXJ0LnNzbC5jb20vRW50cnVzdC1PVlRMUy1JLVIxLmNlcjAgBggrBgEFBQcw + AYYUaHR0cDovL29jc3BzLnNzbC5jb20wgdgGA1UdEQSB0DCBzYIHZHNvLm1pbIIJ + Ki5kc28ubWlsgg0qLmlsMi5kc28ubWlsgg0qLmlsNC5kc28ubWlsgg0qLmlsNS5k + c28ubWlsgg4qLmFwcHMuZHNvLm1pbIIRKi5zdGFnaW5nLmRzby5taWyCDyouYWRt + aW4uZHNvLm1pbIIRKi5wcmVwcm9kLmRzby5taWyCEioucGFydHlidXMuZHNvLm1p + bIIaKi5zdGFnaW5nLnBhcnR5YnVzLmRzby5taWyCEyouYWRtaW4uaWw1LmRzby5t + aWwwIwYDVR0gBBwwGjAIBgZngQwBAgIwDgYMKwYBBAGCqTABAwECMB0GA1UdJQQW + MBQGCCsGAQUFBwMCBggrBgEFBQcDATA7BgNVHR8ENDAyMDCgLqAshipodHRwOi8v + Y3Jscy5zc2wuY29tL0VudHJ1c3QtT1ZUTFMtSS1SMS5jcmwwHQYDVR0OBBYEFPGH + pZq/OFeRdtSYgjOVRE7aVMJSMA4GA1UdDwEB/wQEAwIFoDCCAX4GCisGAQQB1nkC + BAIEggFuBIIBagFoAHYADeHyMCvTDcFAYhIJ6lUu/Ed0fLHX6TDvDkIetH5OqjQA + AAGTjN4/JgAABAMARzBFAiAxkZx3K+1Hx05hRiEqSHiKQR6MZBm07LEi+fV++CQ8 + HQIhAPtLwyKZQr3G4lPnRXMn/H9NFTXcrF7elq3bLn0EvWseAHUAzPsPaoVxCWX+ + lZtTzumyfCLphVwNl422qX5UwP5MDbAAAAGTjN4/FQAABAMARjBEAiBOBZUgjBHx + 4j1UYkDqCx/06cI6V/QPpS7b6ATlUTaGTwIgR3iZnsN2mWYyDBHEa9FJzLLQDdrs + j2QJTm9HW/yMmS0AdwAS8U40vVNyTIQGGcOPP3oT+Oe1YoeInG0wBYTr5YYmOgAA + AZOM3j7QAAAEAwBIMEYCIQDHT+NqmdIg0NxvjKw7Mtbdrz272LFquQLha2KCdzHl + tgIhAPm2CevtO+Iv49S0JeERtw5JIGTQ343VQ+CDyjgMIrQqMA0GCSqGSIb3DQEB + CwUAA4ICAQAKc7xdwZeA1thWzsDBAhFG7XwjgfNrPhHPm98pB+smkeP1gKsdb+FV + IsBr+6iercGBQSXn9GrZkb0RdUlqy5X6HVxMNZ7E7mJhkq3HT1Sw7y7ZQGJpvmZh + 7tWgZ4ajoutvuAFq4AVWvIK0MjXmOKR9xBUe+SMetw30jdNMzc8fJJhKcJxuitC2 + Xglij9X1uqGXmXaFdFXAPAY6uWn+jp9XnHKqwHYYq8WIPGRRXzR62QhvScGO79yN + BMe8Wc5Q1lkEZNSv45d44GqHcpjfAS2Hpt8SzM5DoqUvgJst56nnsENKfGDPzass + +VSL4ESBa8Lhm8K9m/KMQNaxIJ5HDu7NFfvp+0yXIpr5l/li5IZ/ah9746dmvyvJ + RX4lgAyWiZXFC51lSYvafXF7Tm6BN48LvSCJTD5E5uZvhR3hBiM1dcEu2VsmFzS5 + HWq2ypRZwDk4jRGN8is3kY8nBdHWr0joyQC4OYRSpoU13oP8m+eYbtXcu8gAo72M + 4eVjq0PSqYYyoburXTwP+jFy7vkcUu/9t9/L5sNYVoQIWoFtK0gwBUl70cBPWYoK + ZQb50ftfJ4pXNyrC1jPN5Ci7jRZHySGsRHkoHLLQdfk/LNUrwioWrDl0v7lJGnsx + xZ9PISLI7RmnJj1omDtq6DGyAq5HE1Al47TKroeGuwqjpsKmDuyEQw== + -----END CERTIFICATE----- + -----BEGIN CERTIFICATE----- + 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 + -----END CERTIFICATE----- + -----BEGIN CERTIFICATE----- + MIIFiTCCA3GgAwIBAgIQb77arXO9CEDii02+1PdbkTANBgkqhkiG9w0BAQsFADBO + MQswCQYDVQQGEwJVUzEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9uMSUwIwYDVQQD + DBxTU0wuY29tIFRMUyBSU0EgUm9vdCBDQSAyMDIyMB4XDTIyMDgyNTE2MzQyMloX + DTQ2MDgxOTE2MzQyMVowTjELMAkGA1UEBhMCVVMxGDAWBgNVBAoMD1NTTCBDb3Jw + b3JhdGlvbjElMCMGA1UEAwwcU1NMLmNvbSBUTFMgUlNBIFJvb3QgQ0EgMjAyMjCC + AiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANCkCXJPQIgSYT41I57u9nTP + L3tYPc48DRAokC+X94xI2KDYJbFMsBFMF3NQ0CJKY7uB0ylu1bUJPiYYf7ISf5OY + t6/wNr/y7hienDtSxUcZXXTzZGbVXcdotL8bHAajvI9AI7YexoS9UcQbOcGV0ins + S657Lb85/bRi3pZ7QcacoOAGcvvwB5cJOYF0r/c0WRFXCsJbwST0MXMwgsadugL3 + PnxEX4MN8/HdIGkWCVDi1FW24IBydm5MR7d1VVm0U3TZlMZBrViKMWYPHqIbKUBO + L9975hYsLfy/7PO0+r4Y9ptJ1O4Fbtk085zx7AGL0SDGD6C1vBdOSHtRwvzpXGk3 + R2azaPgVKPC506QVzFpPulJwoxJF3ca6TvvC0PeoUidtbnm1jPx7jMEWTO6Af77w + dr5BUxIzrlo4QqvXDz5BjXYHMtWrifZOZ9mxQnUjbvPNQrL8VfVThxc7wDNY8VLS + +YCk8OjwO4s4zKTGkH8PnP2L0aPP2oOnaclQNtVcBdIKQXTbYxE3waWglksejBYS + d66UNHsef8JmAOSqg+qKkK3ONkRN0VHpvB/zagX9wHQfJRlAUW7qglFA35u5CCoG + AtUjHBPW6dvbxrB6y3snm/vg1UYk7RBLY0ulBY+6uB0rpvqR4pJSvezrZ5dtmi2f + gTIFZzL7SAg/2SW4BCUvAgMBAAGjYzBhMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0j + BBgwFoAU+y437uOEeicuzRk1sTN8/9REQrkwHQYDVR0OBBYEFPsuN+7jhHonLs0Z + NbEzfP/UREK5MA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAgEAjYlt + hEUY8U+zoO9opMAdrDC8Z2awms22qyIZZtM7QbUQnRC6cm4pJCAcAZli05bg4vsM + QtfhWsSWTVTNj8pDU/0quOr4ZcoBwq1gaAafORpR2eCNJvkLTqVTJXojpBzOCBvf + R4iyrT7gJ4eLSYwfqUdYe5byiB0YrrPRpgqU+tvT5TgKa3kSM/tKWTcWQA673vWJ + DPFs0/dRa1419dvAJuoSc06pkZCmF8NsLzjUo3KUQyxi4U5cMj29TH0ZR6LDSeeW + P4+a0zvkEdiLA9z2tmBVGKaBUfPhqBVq6+AL8BQx1rmMRTqoENjwuSfr98t67wVy + lrXEj5ZzxOhWc5y8aVFjvO9nHEMaX3cZHxj4HCUp+UmZKbaSPaKDN7EgkaibMOlq + bLQjk2UEqxHzDh1TJElTHaE/nUiSEeJ9DU/1172iWD54nR4fK/4huxoTtrEoZP2w + AgDHbICivRZQIA9ygV/MlP+7mea6kMvq+cYMwq7FGc4zoWtcu358NFcXrfA/rs3q + r5nsLFR+jM4uElZI7xc7P0peYNLcdDa8pUNjyw9bowJWCZ4kLOGGgYz+qxcs+sji + Mho6/4UIyYOf8kpIEFR3N+2ivEC+5BB09+Rbu7nzifmPQdjH5FCQNYA+HLhNkNPU + 98OwoX6EyneSMSy4kLGCenROmxMmtNVQZlR4rmA= + -----END CERTIFICATE----- + + + # # LetsEncrypt certificate authority for keycloak.dev.bigbang.mil + # # Use this CA if you deployed Keycloak with *.dev.bigbang.mil certificate using docs/assets/configs/example/keycloak-dev-values.yaml + # certificate_authority: | + # -----BEGIN CERTIFICATE----- + # MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw + # TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh + # cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4 + # WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJu + # ZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY + # MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54rVygc + # h77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+ + # 0TM8ukj13Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6U + # A5/TR5d8mUgjU+g4rk8Kb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sW + # T8KOEUt+zwvo/7V3LvSye0rgTBIlDHCNAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyH + # B5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ4Q7e2RCOFvu396j3x+UC + # B5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf1b0SHzUv + # KBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWn + # OlFuhjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTn + # jh8BCNAw1FtxNrQHusEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbw + # qHyGO0aoSCqI3Haadr8faqU9GY/rOPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CI + # rU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV + # HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY9umbbjANBgkq + # hkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL + # ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ + # 3BebYhtF8GaV0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KK + # NFtY2PwByVS5uCbMiogziUwthDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5 + # ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJwTdwJx4nLCgdNbOhdjsnvzqvHu7Ur + # TkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nxe5AW0wdeRlN8NwdC + # jNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZAJzVc + # oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq + # 4RgqsahDYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPA + # mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d + # emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc= + # -----END CERTIFICATE----- + saml: + # Retrieve from https://login.dso.mil/auth/realms/baby-yoda/protocol/saml/descriptor + metadata: <md:EntityDescriptor xmlns="urn:oasis:names:tc:SAML:2.0:metadata" xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" entityID="https://login.dso.mil/auth/realms/baby-yoda"><md:IDPSSODescriptor WantAuthnRequestsSigned="true" protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol"><md:KeyDescriptor use="signing"><ds:KeyInfo><ds:KeyName>4CK69bW66HE2wph9VuBs0fTc1MaETSTpU1iflEkBHR4</ds:KeyName><ds:X509Data><ds:X509Certificate>MIICoTCCAYkCBgFyLIEqUjANBgkqhkiG9w0BAQsFADAUMRIwEAYDVQQDDAliYWJ5LXlvZGEwHhcNMjAwNTE5MTAzNDIyWhcNMzAwNTE5MTAzNjAyWjAUMRIwEAYDVQQDDAliYWJ5LXlvZGEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCGIwvWSPD6zDbkGBpkjUDJ+BwJEE8ko8T7DC22prs03Gm2v/lEIEa4leoPKjenW+NxtvwqN0qdcjuRZ6vxvY/P9E/Wb9Bw+so7FKW6TsZkXwBGxzoU8ZvNiCLyjxwFVKxqaXodnOk3dmcfgMVnbuJ8z5SX8/IzFnZrB6iEhqLNen6uAXtGqlq/k1dTCZxLIfws/3Y1Ui4WUPcdhMMaixVt8D+78fblnhcIYpb+8sNM2uXw9wDceoigP681q/Kx3ECr8o3DuIstzQouyMVhJ0kv/ngftC5uwZHQDIissu6sluoC2+20YkrfyTldhYojBga27qKInCNJvtS2idV0+HxXAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAIVkoDYkM6ryBcuchdAL5OmyKbmmY4WDrMlatfa3uniK5jvFXrmVaJ3rcu0apdY/NhBeLSOLFVlC5w1QroGUhWm0EjAA4zyuU63Pk0sro0vyHrxztBrGPQrGXI3kjXEssaehZZvYP4b9VtYpus6oGP6bTmaDw94Zu+WrDsWdFs+27VEYwBuU0D6E+ENDGlfR+9ADEW53t6H2M3H0VsOtbArEutYgb4gmQcOIBygC7L1tGJ4IqbnhTYLh9DMKNklU+tq8TMHacps9FxELpeAib3O0J0E5zYXdraQobCCe+ao1Y7sA/wqcGQBCVuoFgty7Y37nNL7LMvygcafgqVDqw5U=</ds:X509Certificate></ds:X509Data></ds:KeyInfo></md:KeyDescriptor><md:ArtifactResolutionService Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP" Location="https://login.dso.mil/auth/realms/baby-yoda/protocol/saml/resolve" index="0"/><md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://login.dso.mil/auth/realms/baby-yoda/protocol/saml"/><md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://login.dso.mil/auth/realms/baby-yoda/protocol/saml"/><md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact" Location="https://login.dso.mil/auth/realms/baby-yoda/protocol/saml"/><md:NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:persistent</md:NameIDFormat><md:NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:transient</md:NameIDFormat><md:NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified</md:NameIDFormat><md:NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress</md:NameIDFormat><md:SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://login.dso.mil/auth/realms/baby-yoda/protocol/saml"/><md:SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://login.dso.mil/auth/realms/baby-yoda/protocol/saml"/><md:SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP" Location="https://login.dso.mil/auth/realms/baby-yoda/protocol/saml"/><md:SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact" Location="https://login.dso.mil/auth/realms/baby-yoda/protocol/saml"/></md:IDPSSODescriptor></md:EntityDescriptor> + +kiali: + sso: + enabled: true + client_id: platform1_a8604cc9-f5e9-4656-802d-d05624370245_bb8-kiali + +jaeger: + sso: + enabled: true + client_id: platform1_a8604cc9-f5e9-4656-802d-d05624370245_bb8-jaeger + +elasticsearchKibana: + sso: + enabled: true + client_id: platform1_a8604cc9-f5e9-4656-802d-d05624370245_bb8-kibana + license: + trial: true + +tempo: + sso: + enabled: true + client_id: platform1_a8604cc9-f5e9-4656-802d-d05624370245_bb8-jaeger + # If deploying both Jaeger and Tempo you will need the tempo specific client below (matches the `tempo.dev.bigbang.mil` VS) + # client_id: platform1_a8604cc9-f5e9-4656-802d-d05624370245_bb8-tempo + +monitoring: + sso: + enabled: true + prometheus: + client_id: platform1_a8604cc9-f5e9-4656-802d-d05624370245_bb8-prometheus + alertmanager: + client_id: platform1_a8604cc9-f5e9-4656-802d-d05624370245_bb8-alertmanager + +grafana: + sso: + enabled: true + grafana: + client_id: platform1_a8604cc9-f5e9-4656-802d-d05624370245_bb8-grafana + scopes: "openid Grafana" + +twistlock: + # SSO (SAML) requires a license and enabling the init job - see https://repo1.dso.mil/big-bang/product/packages/twistlock/-/blob/main/docs/initialization.md + sso: + enabled: true + client_id: platform1_a8604cc9-f5e9-4656-802d-d05624370245_bb8-twistlock + +neuvector: + sso: + enabled: true + client_id: platform1_a8604cc9-f5e9-4656-802d-d05624370245_bb8-neuvector + client_secret: AyAixE3 + default_role: admin + group_claim: roles + group_mapped_roles: + - group: admin + global_role: admin + - group: reader + global_role: reader + +addons: + authservice: + enabled: true + argocd: + sso: + enabled: true + client_id: platform1_a8604cc9-f5e9-4656-802d-d05624370245_bb8-argocd + client_secret: anything-for-dev + groups: | + g, Impact Level 2 Authorized, role:admin + gitlab: + sso: + enabled: true + client_id: platform1_a8604cc9-f5e9-4656-802d-d05624370245_bb8-gitlab + sonarqube: + sso: + enabled: true + client_id: platform1_a8604cc9-f5e9-4656-802d-d05624370245_bb8-saml-sonarqube + login: login + name: name + email: email + anchore: + adminPassword: admin + sso: + enabled: true + client_id: platform1_a8604cc9-f5e9-4656-802d-d05624370245_bb8-anchore + enterprise: + enabled: true + licenseYaml: | + "TBD" + jira: + sso: + enabled: true + client_id: platform1_a8604cc9-f5e9-4656-802d-d05624370245_bb8-jira + confluence: + sso: + enabled: true + client_id: platform1_a8604cc9-f5e9-4656-802d-d05624370245_bb8-confluence + mattermost: + sso: + enabled: true + client_id: "platform1_a8604cc9-f5e9-4656-802d-d05624370245_bb8-mattermost" + client_secret: "no-secret" + thanos: + sso: + enabled: true + client_id: platform1_a8604cc9-f5e9-4656-802d-d05624370245_bb8-thanos + fortify: + sso: + enabled: true + client_id: "platform1_a8604cc9-f5e9-4656-802d-d05624370245_bb8-fortify" + holocron: + sso: + enabled: true + client_id: "platform1_a8604cc9-f5e9-4656-802d-d05624370245_bb8-holocron" + + nexusRepositoryManager: + # Nexus requires manual configuration in Keycloak client and cannot be tested with login.dso.mil + # you must test with your own dev deployment. Example: keycloak.dev.bigbang.mil + # See more info in Nexus Package docs /docs/keycloak.md + # Nexus SSO is behind a paywall. You must have a valid license to enable SSO + # -- Base64 encoded license file. + # cat ~/Downloads/sonatype-license-YYYY-MM-ddTnnnnnnZ.lic | base64 -w 0 ; echo + license_key: "enter-single-line-base64-encoded-string-here" + sso: + # -- https://support.sonatype.com/hc/en-us/articles/1500000976522-SAML-integration-for-Nexus-Repository-Manager-Pro-3-and-Nexus-IQ-Server-with-Keycloak#h_01EV7CWCYH3YKAPMAHG8XMQ599 + enabled: true + idp_data: + entityId: "https://nexus.dev.bigbang.mil/service/rest/v1/security/saml/metadata" + # -- IdP Field Mappings + # -- NXRM username attribute + username: "username" + firstName: "firstName" + lastName: "lastName" + email: "email" + groups: "groups" + role: + # id is the name of the Keycloak group (case sensitive) + - id: "Nexus" + name: "Keycloak Nexus Group" + description: "unprivilaged users" + privileges: [] + roles: [] + - id: "Nexus-Admin" + name: "Keycloak Nexus Admin Group" + description: "keycloak users as admins" + privileges: + - "nx-all" + roles: + - "nx-admin" + # NexusNotes: | + # get nexus x509 cert from Nexus Admin UI + # https://nexus.dev.bigbang.mil/service/rest/v1/security/saml/metadata + # copy and paste the nexus single line cert into a text file and save it + # vi nexus-x509.txt + # -----BEGIN CERTIFICATE----- + # put-single-line-nexus-x509-certificate-here + # -----END CERTIFICATE----- + # make a valid pem file with proper wrapping at 64 characters per line + # fold -w 64 nexus-x509.txt > nexus.pem + # make a PKCS12 from nexus.pem + # keytool -import -alias alias -file nexus.pem -keystore nexus.p12 -storetype PKCS12 -storepass password + # In Keycloak go to the nexus client and on the Keys tab import PKCS12 using the nexus.p12 file in two places + # key alias = alias + # store password = password diff --git a/docs/assets/configs/example/git-repo-values.yaml b/docs/assets/configs/example/git-repo-values.yaml new file mode 100644 index 0000000000000000000000000000000000000000..2ba49642c66246cdaaa8595e0ad536eda2a054ba --- /dev/null +++ b/docs/assets/configs/example/git-repo-values.yaml @@ -0,0 +1,192 @@ +# -- Git credential settings for accessing private repositories +# Order of precedence is: +# 1. existingSecret +# 2. http credentials (username/password/caFile) +# 3. ssh credentials (privateKey/publicKey/knownHosts) +git: + # -- Existing secret to use for git credentials, must be in the appropriate format: https://toolkit.fluxcd.io/components/source/gitrepositories/#https-authentication + existingSecret: "" + + # -- Chart created secrets with user defined values + credentials: + # -- HTTP git credentials, both username and password must be provided + username: "" + password: "" + # -- HTTPS certificate authority file. Required for any repo with a self signed certificate + caFile: "" + # -- SSH git credentials, privateKey, publicKey, and knownHosts must be provided + privateKey: "" + publicKey: "" + knownHosts: "" + +istio: + git: + repo: https://repo1.dso.mil/big-bang/product/packages/istio-controlplane.git + path: "./chart" + branch: "my-dev-branch" +istioOperator: + git: + repo: https://repo1.dso.mil/big-bang/product/packages/istio-operator.git + path: "./chart" + branch: "my-dev-branch" +jaeger: + git: + repo: https://repo1.dso.mil/big-bang/product/packages/jaeger.git + path: "./chart" + branch: "my-dev-branch" +kiali: + git: + repo: https://repo1.dso.mil/big-bang/product/packages/kiali.git + path: "./chart" + branch: "my-dev-branch" +clusterAuditor: + git: + repo: https://repo1.dso.mil/big-bang/product/packages/cluster-auditor.git + path: "./chart" + branch: "my-dev-branch" +gatekeeper: + git: + repo: https://repo1.dso.mil/big-bang/product/packages/policy.git + path: "./chart" + branch: "my-dev-branch" +kyverno: + git: + repo: https://repo1.dso.mil/big-bang/product/packages/kyverno.git + path: "./chart" + branch: "my-dev-branch" +kyvernoPolicies: + git: + repo: https://repo1.dso.mil/big-bang/product/packages/kyverno-policies.git + path: ./chart + branch: "my-dev-branch" +kyvernoReporter: + git: + repo: https://repo1.dso.mil/big-bang/product/packages/kyverno-reporter + path: ./chart + branch: "my-dev-branch" +elasticsearchKibana: + git: + repo: https://repo1.dso.mil/big-bang/product/packages/elasticsearch-kibana.git + path: "./chart" + branch: "my-dev-branch" +eckOperator: + git: + repo: https://repo1.dso.mil/big-bang/product/packages/eck-operator.git + path: "./chart" + branch: "my-dev-branch" +fluentbit: + git: + repo: https://repo1.dso.mil/big-bang/product/packages/fluentbit.git + path: "./chart" + branch: "my-dev-branch" +promtail: + git: + repo: https://repo1.dso.mil/big-bang/product/packages/promtail.git + path: "./chart" + branch: "my-dev-branch" +loki: + git: + repo: https://repo1.dso.mil/big-bang/product/packages/loki.git + path: "./chart" + branch: "my-dev-branch" +neuvector: + git: + repo: https://repo1.dso.mil/big-bang/product/packages/neuvector.git + path: "./chart" + branch: "my-dev-branch" +tempo: + git: + repo: https://repo1.dso.mil/big-bang/product/packages/tempo.git + path: "./chart" + branch: "my-dev-branch" +monitoring: + git: + repo: https://repo1.dso.mil/big-bang/product/packages/monitoring.git + path: "./chart" + branch: "my-dev-branch" +twistlock: + git: + repo: https://repo1.dso.mil/big-bang/product/packages/twistlock.git + path: "./chart" + branch: "my-dev-branch" +addons: + argocd: + git: + repo: https://repo1.dso.mil/big-bang/product/packages/argocd.git + path: "./chart" + branch: "my-dev-branch" + authservice: + git: + repo: https://repo1.dso.mil/big-bang/product/packages/authservice.git + path: "./chart" + branch: "my-dev-branch" + minioOperator: + git: + repo: https://repo1.dso.mil/big-bang/product/packages/minio-operator.git + path: "./chart" + branch: "my-dev-branch" + minio: + git: + repo: https://repo1.dso.mil/big-bang/product/packages/minio.git + path: "./chart" + branch: "my-dev-branch" + gitlab: + git: + repo: https://repo1.dso.mil/big-bang/product/packages/gitlab.git + path: "./chart" + branch: "my-dev-branch" + gitlabRunner: + git: + repo: https://repo1.dso.mil/big-bang/product/packages/gitlab-runner.git + path: "./chart" + branch: "my-dev-branch" + nexusRepositoryManager: + git: + repo: https://repo1.dso.mil/big-bang/product/packages/nexus.git + path: "./chart" + branch: "my-dev-branch" + sonarqube: + git: + repo: https://repo1.dso.mil/big-bang/product/packages/sonarqube.git + path: "./chart" + branch: "my-dev-branch" + haproxy: + git: + repo: https://repo1.dso.mil/big-bang/product/packages/haproxy.git + path: "./chart" + branch: "my-dev-branch" + anchore: + git: + repo: https://repo1.dso.mil/big-bang/product/packages/anchore-enterprise.git + path: "./chart" + branch: "my-dev-branch" + mattermostOperator: + git: + repo: https://repo1.dso.mil/big-bang/product/packages/mattermost-operator.git + path: "./chart" + branch: "my-dev-branch" + mattermost: + git: + repo: https://repo1.dso.mil/big-bang/product/packages/mattermost.git + path: "./chart" + branch: "my-dev-branch" + velero: + git: + repo: https://repo1.dso.mil/big-bang/product/packages/velero.git + path: "./chart" + branch: "my-dev-branch" + keycloak: + git: + repo: https://repo1.dso.mil/big-bang/product/packages/keycloak.git + path: "./chart" + branch: "my-dev-branch" + vault: + git: + repo: https://repo1.dso.mil/big-bang/product/packages/vault.git + path: "./chart" + branch: "my-dev-branch" + metricsServer: + git: + repo: https://repo1.dso.mil/big-bang/product/packages/metrics-server.git + path: "./chart" + branch: "my-dev-branch" diff --git a/docs/assets/configs/example/google-auth-example-values.yaml b/docs/assets/configs/example/google-auth-example-values.yaml new file mode 100644 index 0000000000000000000000000000000000000000..43582a2f33b9eaee71cfd1bbf8a4b4656cb663ee --- /dev/null +++ b/docs/assets/configs/example/google-auth-example-values.yaml @@ -0,0 +1,43 @@ +# +# The values below demonstrate how to override the default SSO provider (Keycloak) in favor of google auth. +# +# Current tested implementations and reference docs: +# * grafana - https://grafana.com/docs/grafana/latest/auth/google/ +# * kibana/es - https://www.elastic.co/guide/en/elasticsearch/reference/7.12/oidc-guide-stack.html +# - https://www.elastic.co/guide/en/kibana/current/kibana-authentication.html#oidc +# +sso: + name: Google SSO + url: https://accounts.google.com + oidc: + authorization: https://accounts.google.com/o/oauth2/v2/auth + endSession: "" + jwksUri: https://www.googleapis.com/oauth2/v3/certs + token: https://oauth2.googleapis.com/token + userinfo: https://openidconnect.googleapis.com/v1/userinfo + claims: + username: email + groups: "" + +monitoring: + sso: + enabled: true + grafana: + client_id: <client_id> + client_secret: <client_secret> + scopes: "https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email" + allowed_domains: <allowed_domains> + signout_redirect_url: https://www.google.com/accounts/Logout?continue=https://appengine.google.com/_ah/logout?continue=https://grafana.bigbang.dev +elasticsearchKibana: + sso: + enabled: true + client_secret: "<client_secret>" + client_id: "<client_id>" + # additional fields (required to override keycloak defaults) + claims_principal_pattern: "<regex for allowed email domains>" # example: "^([^@]+)@leapfrog\\.ai$" + requested_scopes: + - openid + - email + signature_algorithm: "" + license: + trial: true \ No newline at end of file diff --git a/docs/assets/configs/example/keycloak-dev-values.yaml b/docs/assets/configs/example/keycloak-dev-values.yaml new file mode 100644 index 0000000000000000000000000000000000000000..c7613a969f464d336b99761afbab88d832231b7b --- /dev/null +++ b/docs/assets/configs/example/keycloak-dev-values.yaml @@ -0,0 +1,132 @@ +comments: | + This example values override file is provided FOR DEVELOPMENT/DEMO/TEST PURPOSES ONLY + +domain: dev.bigbang.mil + +flux: + interval: 1m + rollback: + cleanupOnFail: false + +istio: + ingressGateways: + passthrough-ingressgateway: + type: "LoadBalancer" + + gateways: + passthrough: + ingressGateway: "passthrough-ingressgateway" + hosts: + - "*.{{ .Values.domain }}" + tls: + mode: "PASSTHROUGH" + +addons: + keycloak: + enabled: true + + ingress: + gateway: "passthrough" + + # For development include the *.dev.bigbang.mil cert from ./chart/ingress-certs.yaml + # key: | + # -----BEGIN PRIVATE KEY----- + # INSERT KEY HERE + # -----END PRIVATE KEY----- + # cert: | + # -----BEGIN CERTIFICATE----- + # INSERT CERT HERE + # -----END CERTIFICATE----- + + values: + replicas: 1 + command: + - "/opt/keycloak/bin/kc.sh" + args: + # - "start" + - "start-dev" + - "--import-realm" + # import-realm is not recommended for operational environments. + + # https://www.keycloak.org/server/all-config + extraEnv: |- + - name: KC_HTTPS_CERTIFICATE_FILE + value: /opt/keycloak/conf/tls.crt + - name: KC_HTTPS_CERTIFICATE_KEY_FILE + value: /opt/keycloak/conf/tls.key + - name: KC_HTTPS_CLIENT_AUTH + value: request + - name: KC_HTTPS_TRUST_STORE_FILE + value: /opt/keycloak/conf/truststore.jks + - name: KC_HTTPS_TRUST_STORE_PASSWORD + value: password + - name: KC_HOSTNAME + value: keycloak.dev.bigbang.mil + - name: KC_HOSTNAME_STRICT + value: "true" + - name: KC_LOG_LEVEL + value: "org.keycloak.events:DEBUG,org.infinispan:INFO,org.jgroups:INFO" + secrets: + env: + stringData: + CUSTOM_REGISTRATION_CONFIG: /opt/keycloak/conf/customreg.yaml + customreg: + stringData: + customreg.yaml: '{{ .Files.Get "resources/dev/baby-yoda.yaml" }}' + realm: + stringData: + realm.json: '{{ .Files.Get "resources/dev/baby-yoda.json" }}' + truststore: + data: + truststore.jks: |- + {{ .Files.Get "resources/dev/truststore.jks" | b64enc }} + quarkusproperties: + stringData: + quarkus.properties: '{{ .Files.Get "resources/dev/quarkus.properties" }}' + + extraInitContainers: |- + - name: plugin + image: registry1.dso.mil/ironbank/big-bang/p1-keycloak-plugin:X.X.X + imagePullPolicy: Always + command: + - sh + - -c + - | + cp /app/p1-keycloak-plugin.jar /init + ls -l /init + volumeMounts: + - name: plugin + mountPath: "/init" + extraVolumes: |- + - name: customreg + secret: + secretName: {{ include "keycloak.fullname" . }}-customreg + - name: realm + secret: + secretName: {{ include "keycloak.fullname" . }}-realm + - name: plugin + emptyDir: {} + - name: truststore + secret: + secretName: {{ include "keycloak.fullname" . }}-truststore + - name: quarkusproperties + secret: + secretName: {{ include "keycloak.fullname" . }}-quarkusproperties + defaultMode: 0777 + extraVolumeMounts: |- + - name: customreg + mountPath: /opt/keycloak/conf/customreg.yaml + subPath: customreg.yaml + readOnly: true + - name: realm + mountPath: /opt/keycloak/data/import/realm.json + subPath: realm.json + - name: plugin + mountPath: /opt/keycloak/providers/p1-keycloak-plugin.jar + subPath: p1-keycloak-plugin.jar + - name: truststore + mountPath: /opt/keycloak/conf/truststore.jks + subPath: truststore.jks + - name: quarkusproperties + mountPath: /opt/keycloak/conf/quarkus.properties + subPath: quarkus.properties \ No newline at end of file diff --git a/docs/assets/configs/example/keycloak-prod-values.yaml b/docs/assets/configs/example/keycloak-prod-values.yaml new file mode 100644 index 0000000000000000000000000000000000000000..e24956ed95dc24dd19b5b3402ba225a085997d91 --- /dev/null +++ b/docs/assets/configs/example/keycloak-prod-values.yaml @@ -0,0 +1,190 @@ +comments: | + Operational deployments use a different configuration including but not limited to: + - a custom realm would not automatically be loaded. + - needed secrets would be created independently through a GitOps process rather than using the keycloak chart to create secrets + - the certificate would not be inlined in the values.yaml but instead the keycloak-tlscert and keycloak-tlskey secrets are created independently through a GitOps process + - an external database would be used + - master realm would be disabled or restricted to prevent admin login + + Here are some of the URL paths that are available in Keycloak + Admin UI. Default credentials for development are admin:password + https://keycloak.dev.bigbang.mil/auth/admin + User registration and/or account page + https://keycloak.dev.bigbang.mil/ + + For an example "baby-yoda" keycloak realm file that already has sso clients configured see + https://repo1.dso.mil/big-bang/product/packages/keycloak/-/blob/main/chart/resources/dev/baby-yoda.json + Within the Keycloak Admin Console UI import your custom realm.json file. + + +domain: dev.bigbang.mil + +flux: + interval: 1m + rollback: + cleanupOnFail: false + +istio: + ingressGateways: + passthrough-ingressgateway: + type: "LoadBalancer" + + gateways: + passthrough: + ingressGateway: "passthrough-ingressgateway" + hosts: + - "*.{{ .Values.domain }}" + tls: + mode: "PASSTHROUGH" + +addons: + keycloak: + enabled: true + + ingress: + gateway: "passthrough" + + # the cert and private key should be separated into a separate SOPS encrypted values file + key: | + -----BEGIN PRIVATE KEY----- + INSERT KEY HERE + -----END PRIVATE KEY----- + cert: | + -----BEGIN CERTIFICATE----- + INSERT CERT HERE + -----END CERTIFICATE----- + + values: + #replicas: 3 + autoscaling: + enabled: true + minReplcias: 2 + maxReplicas: 5 + command: + - "/opt/keycloak/bin/kc.sh" + args: + - "start" + # - "--import-realm" + # import-realm is not recommended for production/operational environments. + # For a new production deployment a realm file can be manually imported from the Admin Console + + # https://www.keycloak.org/server/all-config + extraEnv: |- + - name: KC_HTTPS_CERTIFICATE_FILE + value: /opt/keycloak/conf/tls.crt + - name: KC_HTTPS_CERTIFICATE_KEY_FILE + value: /opt/keycloak/conf/tls.key + - name: KC_HTTPS_CLIENT_AUTH + value: request + - name: KC_HTTPS_TRUST_STORE_FILE + value: /opt/keycloak/conf/truststore.jks + - name: KC_HTTPS_TRUST_STORE_PASSWORD + value: password + - name: KC_HOSTNAME + value: keycloak.dev.bigbang.mil + - name: KC_HOSTNAME_STRICT + value: "true" + - name: KC_LOG_LEVEL + value: "org.keycloak.events:DEBUG,org.infinispan:INFO,org.jgroups:INFO" + secrets: + env: + stringData: + # the admin credentials should be separated into a separate SOPS encrypted values file + KEYCLOAK_ADMIN: "admin" + KEYCLOAK_ADMIN_PASSWORD: "your-super-secure-password" + CUSTOM_REGISTRATION_CONFIG: /opt/keycloak/conf/customreg.yaml + customreg: + stringData: + customreg.yaml: '{{ .Files.Get "resources/dev/baby-yoda.yaml" }}' + realm: + stringData: + realm.json: '{{ .Files.Get "resources/dev/baby-yoda.json" }}' + truststore: + data: + truststore.jks: |- + {{ .Files.Get "resources/dev/truststore.jks" | b64enc }} + # This config example includes quarkus properties for changing the realm name to something other than "baby-yoda" + # The p1-keycloak-plugin has a custom quarkus extention for custom routing and redirects + # the quarkus.properties file is how you configure it + quarkusproperties: + stringData: + quarkus.properties: |- + quarkus.http.non-application-root-path=/ + # custom redirects + quarkus.kc-routing.path-redirect./=/auth/realms/YOUR-REALM-NAME/account + quarkus.kc-routing.path-redirect./auth=/auth/realms/YOUR-REALM-NAME/account + quarkus.kc-routing.path-redirect./register=/auth/realms/YOUR-REALM-NAME/protocol/openid-connect/registrations?client_id=account&response_type=code + quarkus.kc-routing.path-prefix./oauth/authorize=/auth/realms/YOUR-REALM-NAME/protocol/openid-connect/auth + quarkus.kc-routing.path-filter./api/v4/user=/auth/realms/YOUR-REALM-NAME/protocol/openid-connect/userinfo + quarkus.kc-routing.path-filter./oauth/token=/auth/realms/YOUR-REALM-NAME/protocol/openid-connect/token + # block metrics and health enpoints from being exposed through the istio ingress + quarkus.kc-routing.path-recursive-block./metrics=8443 + quarkus.kc-routing.path-recursive-block./health=8443 + + + # This config includes an example of injecting a custom theme jar on startup + # Instructions for building a custom theme can be found in the Big Bang Keycloak repository + # https://repo1.dso.mil/big-bang/product/packages/keycloak/-/blob/main/development/README.md + extraInitContainers: |- + - name: plugin + image: registry1.dso.mil/ironbank/big-bang/p1-keycloak-plugin:X.X.X + imagePullPolicy: Always + command: + - sh + - -c + - | + cp /app/p1-keycloak-plugin.jar /init + ls -l /init + volumeMounts: + - name: plugin + mountPath: "/init" + - name: custom-theme + image: YOUR-REGISTRY-NAME/PATH-TO-IMAGE/YOUR-CUSTOM-THEME-IMAGE-NAME:X.X.X + imagePullPolicy: Always + command: + - sh + - -c + - | + cp /app/YOUR-CUSTOM-THEME-JAR-NAME.jar /init + ls -l /init + volumeMounts: + - name: custom-theme + mountPath: "/init" + extraVolumes: |- + - name: customreg + secret: + secretName: {{ include "keycloak.fullname" . }}-customreg + - name: realm + secret: + secretName: {{ include "keycloak.fullname" . }}-realm + - name: plugin + emptyDir: {} + - name: truststore + secret: + secretName: {{ include "keycloak.fullname" . }}-truststore + - name: quarkusproperties + secret: + secretName: {{ include "keycloak.fullname" . }}-quarkusproperties + defaultMode: 0777 + - name: custom-theme + emptyDir: {} + extraVolumeMounts: |- + - name: customreg + mountPath: /opt/keycloak/conf/customreg.yaml + subPath: customreg.yaml + readOnly: true + - name: realm + mountPath: /opt/keycloak/data/import/realm.json + subPath: realm.json + - name: plugin + mountPath: /opt/keycloak/providers/p1-keycloak-plugin.jar + subPath: p1-keycloak-plugin.jar + - name: truststore + mountPath: /opt/keycloak/conf/truststore.jks + subPath: truststore.jks + - name: quarkusproperties + mountPath: /opt/keycloak/conf/quarkus.properties + subPath: quarkus.properties + - name: custom-theme + mountPath: /opt/keycloak/providers/YOUR-CUSTOM-THEME-JAR-NAME.jar + subPath: YOUR-CUSTOM-THEME-JAR-NAME.jar diff --git a/docs/assets/configs/example/policy-overrides-k3d.yaml b/docs/assets/configs/example/policy-overrides-k3d.yaml new file mode 100644 index 0000000000000000000000000000000000000000..e1ec18b91d1c76d998551ad04b0a27ab844e2a72 --- /dev/null +++ b/docs/assets/configs/example/policy-overrides-k3d.yaml @@ -0,0 +1,77 @@ +# enables and configures gatekeeper to add an exception for the allowedDockerRegistries violations in the istio-system namespace (when using k3d) +# this is required for development deployments to allow the istio loadbalancer daemonset to come up with rancher images rather than images from registry1.dso.mil or registry.dso.mil + +gatekeeper: + values: + violations: + allowedCapabilities: + parameters: + excludedResources: + # Allows k3d load balancer containers to not drop capabilities + - istio-system/lb-port-.* + allowedDockerRegistries: + parameters: + excludedResources: + # Allows k3d load balancer containers to pull from public repos + - istio-system/lb-port-.* + allowedSecCompProfiles: + parameters: + excludedResources: + # Allows k3d load balancer containers to have an undefined defined seccomp + - istio-system/lb-port-.* + allowedUsers: + parameters: + excludedResources: + # Allows k3d load balancer containers to run as any user/group + - istio-system/lb-port-.* + containerRatio: + parameters: + excludedResources: + # Allows k3d load balancer containers to have undefined limits/requests + - istio-system/lb-port-.* + hostNetworking: + parameters: + excludedResources: + # Allows k3d load balancer containers to mount host ports + - istio-system/lb-port-.* + noBigContainers: + parameters: + excludedResources: + # Allows k3d load balancer containers to have undefined limits/requests + - istio-system/lb-port-.* + noPrivilegedEscalation: + parameters: + excludedResources: + # Allows k3d load balancer containers to have undefined security context + - istio-system/lb-port-.* + readOnlyRoot: + parameters: + excludedResources: + # Allows k3d load balancer containers to mount filesystems read/write + - istio-system/lb-port-.* + requiredLabels: + parameters: + excludedResources: + # Allows k3d load balancer pods to not have required labels + - istio-system/svclb-.* + requiredProbes: + parameters: + excludedResources: + # Allows k3d load balancer containers to not have readiness/liveness probes + - istio-system/lb-port-.* + +kyvernoPolicies: + values: + exclude: + any: + # Allows k3d load balancer to bypass policies. + - resources: + namespaces: + - istio-system + names: + - svclb-* + policies: + restrict-host-path-mount-pv: + parameters: + allow: + - /var/lib/rancher/k3s/storage/pvc-* diff --git a/docs/assets/configs/example/public-ingressgateway-cert.yaml b/docs/assets/configs/example/public-ingressgateway-cert.yaml new file mode 100644 index 0000000000000000000000000000000000000000..15f43338686460c9a449318aae4a5aef67dd195f --- /dev/null +++ b/docs/assets/configs/example/public-ingressgateway-cert.yaml @@ -0,0 +1,12 @@ +istio: + gateways: + public: + tls: + key: | + -----BEGIN PRIVATE KEY----- + INSERT KEY HERE + -----END PRIVATE KEY----- + cert: | + -----BEGIN CERTIFICATE----- + INSERT CERT HERE + -----END CERTIFICATE----- \ No newline at end of file diff --git a/docs/assets/configs/example/vault-production-values.yaml b/docs/assets/configs/example/vault-production-values.yaml new file mode 100644 index 0000000000000000000000000000000000000000..bd174873af1dbdb51036d2b410b1b702ab64a50b --- /dev/null +++ b/docs/assets/configs/example/vault-production-values.yaml @@ -0,0 +1,128 @@ +istio: + enabled: true + + ingressGateways: + passthrough-ingressgateway: + type: "LoadBalancer" + # nodePortBase: 30200 + + gateways: + passthrough: + ingressGateway: "passthrough-ingressgateway" + hosts: + - "*.{{ .Values.domain }}" + tls: + mode: "PASSTHROUGH" + +addons: + vault: + enabled: true + ingress: + gateway: "passthrough" + # provide the Vault TLS cert and key. BigBang will create the secret and volumemount for you + # Leave blank to create your own secret and provide values for your own volume and volumemount + key: | + -----BEGIN PRIVATE KEY----- + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + -----END PRIVATE KEY----- + cert: | + -----BEGIN CERTIFICATE----- + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + -----END CERTIFICATE----- + + values: + # disable autoInit. It should not be used for operations. + autoInit: + enabled: false + + global: + # this is a double negative. Put "false" to enable TLS for passthrough ingress + tlsDisable: false + + server: + # Increase default resources + resources: + requests: + memory: 8Gi + cpu: 2000m + limits: + memory: 8Gi + cpu: 2000m + + # disable the Vault provided ingress so that Istio ingress can be used. + ingress: + enabled: false + + # Extra environment variable to support high availability + extraEnvironmentVars: + # the istio gateway domain + VAULT_SKIP_VERIFY: "true" + VAULT_LOG_FORMAT: "json" + VAULT_LICENSE: "your-license-key-goes-here" + + ha: + # enable high availability. + enabled: true + replicas: 3 + + # tell the deployments where our Vault API endpoint is + # see https://github.com/hashicorp/vault-helm/issues/789 + apiAddr: "https://vault.dev.bigbang.mil" + + # raft is the license free most simple solution for a distributed filesystem + raft: + enabled: true + setNodeId: true + + # these values should be encrypted to prevent the kms_key_id from being revealed + config: | + ui = true + + listener "tcp" { + tls_disable = 0 + address = "[::]:8200" + cluster_address = "[::]:8201" + tls_cert_file = "/vault/tls/tls.crt" + tls_key_file = "/vault/tls/tls.key" + } + + storage "raft" { + path = "/vault/data" + + retry_join { + leader_api_addr = "https://vault-vault-0.vault-vault-internal:8200" + leader_client_cert_file = "/vault/tls/tls.crt" + leader_client_key_file = "/vault/tls/tls.key" + leader_tls_servername = "vault.dev.bigbang.mil" + } + + retry_join { + leader_api_addr = "https://vault-vault-1.vault-vault-internal:8200" + leader_client_cert_file = "/vault/tls/tls.crt" + leader_client_key_file = "/vault/tls/tls.key" + leader_tls_servername = "vault.dev.bigbang.mil" + } + + retry_join { + leader_api_addr = "https://vault-vault-2.vault-vault-internal:8200" + leader_client_cert_file = "/vault/tls/tls.crt" + leader_client_key_file = "/vault/tls/tls.key" + leader_tls_servername = "vault.dev.bigbang.mil" + } + } + + seal "awskms" { + region = "us-gov-west-1" + kms_key_id = "your-kms-key-goes-here" + endpoint = "https://kms.us-gov-west-1.amazonaws.com" + } + + telemetry { + prometheus_retention_time = "24h" + disable_hostname = true + unauthenticated_metrics_access = true + } + + service_registration "kubernetes" {} diff --git a/docs/assets/configs/k8s-storage/benchmark.yaml b/docs/assets/configs/k8s-storage/benchmark.yaml new file mode 100644 index 0000000000000000000000000000000000000000..a7f625d713283f89432b65ed3650ed412a4ba9d2 --- /dev/null +++ b/docs/assets/configs/k8s-storage/benchmark.yaml @@ -0,0 +1,43 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: benchmark +--- +kind: PersistentVolumeClaim +apiVersion: v1 +metadata: + name: dbench + namespace: benchmark +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 50Gi +--- +apiVersion: batch/v1 +kind: Job +metadata: + name: dbench + namespace: benchmark +spec: + template: + spec: + containers: + - name: dbench + image: sotoaster/dbench:latest + imagePullPolicy: IfNotPresent + env: + - name: DBENCH_MOUNTPOINT + value: /data + - name: FIO_SIZE + value: 25G + volumeMounts: + - name: dbench-pv + mountPath: /data + restartPolicy: Never + volumes: + - name: dbench-pv + persistentVolumeClaim: + claimName: dbench + backoffLimit: 4 \ No newline at end of file diff --git a/docs/assets/configs/k8s-storage/rwx-test.yaml b/docs/assets/configs/k8s-storage/rwx-test.yaml new file mode 100644 index 0000000000000000000000000000000000000000..5a754267ee2a6a5fa8c51c055eef90aa30f53ca2 --- /dev/null +++ b/docs/assets/configs/k8s-storage/rwx-test.yaml @@ -0,0 +1,56 @@ +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: rwx-test +spec: + accessModes: + - ReadWriteMany + resources: + requests: + storage: 1Gi +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: rwx-test + labels: + app: rwx-test +spec: + replicas: 3 + selector: + matchLabels: + app: rwx-test + strategy: + type: Recreate + template: + metadata: + labels: + app: rwx-test + spec: + containers: + - image: ubuntu:xenial + imagePullPolicy: Always + command: ["/bin/sh", "-c"] + args: + - sleep 30; touch /mnt/rwx-test/test.log; while true; do date >> /mnt/rwx-test/test.log; sleep 1; done; + name: rwx-test + stdin: true + tty: true + livenessProbe: + exec: + command: + - timeout + - "10" + - ls + - /mnt/rwx-test + initialDelaySeconds: 10 + periodSeconds: 10 + timeoutSeconds: 10 + volumeMounts: + - mountPath: /mnt/rwx-test + name: rwx-test + restartPolicy: Always + volumes: + - name: rwx-test + persistentVolumeClaim: + claimName: rwx-test diff --git a/docs/assets/configs/zarf/config/custom.yaml b/docs/assets/configs/zarf/config/custom.yaml new file mode 100644 index 0000000000000000000000000000000000000000..bd9da8855fc0b41ca17929aa9c2d8478d22ef683 --- /dev/null +++ b/docs/assets/configs/zarf/config/custom.yaml @@ -0,0 +1,5 @@ +monitoring: + enabled: false + +neuvector: + enabled: false diff --git a/docs/assets/configs/zarf/config/kyverno.yaml b/docs/assets/configs/zarf/config/kyverno.yaml new file mode 100644 index 0000000000000000000000000000000000000000..0270d2975f579691fa7e86b6bdf22dc7104a604d --- /dev/null +++ b/docs/assets/configs/zarf/config/kyverno.yaml @@ -0,0 +1,27 @@ +# Use Kyverno instead of Gatekeeper +gatekeeper: + enabled: false +clusterAuditor: + enabled: false +kyverno: + enabled: true +kyvernoPolicies: + enabled: true + values: + policies: + disallow-shared-subpath-volume-writes: + validationFailureAction: audit + restrict-host-ports: + validationFailureAction: audit + restrict-capabilities: + validationFailureAction: audit + restrict-image-registries: + validationFailureAction: audit + disallow-host-namespaces: + validationFailureAction: audit + disallow-privileged-containers: + validationFailureAction: audit + require-non-root-user: + validationFailureAction: audit + restrict-host-path-mount-pv: + validationFailureAction: audit diff --git a/docs/assets/configs/zarf/metallb/config.yaml b/docs/assets/configs/zarf/metallb/config.yaml new file mode 100644 index 0000000000000000000000000000000000000000..b1826cdbede56a1fb5f3b2d9ab5a1a4a7b9335e9 --- /dev/null +++ b/docs/assets/configs/zarf/metallb/config.yaml @@ -0,0 +1,25 @@ +--- +apiVersion: metallb.io/v1beta1 +kind: IPAddressPool +metadata: + name: primary-pool + namespace: metallb-system +spec: + addresses: + - "###ZARF_VAR_PRIVATE_IP_1###/32" + +#--- +#apiVersion: metallb.io/v1beta1 +#kind: IPAddressPool +#metadata: +# name: secondary-pool +# namespace: metallb-system +#spec: +# addresses: +# - "###ZARF_VAR_PRIVATE_IP_2###/32" +--- +apiVersion: metallb.io/v1beta1 +kind: L2Advertisement +metadata: + name: empty + namespace: metallb-system diff --git a/docs/assets/configs/zarf/metallb/metallb-native-0.13.9.yaml b/docs/assets/configs/zarf/metallb/metallb-native-0.13.9.yaml new file mode 100644 index 0000000000000000000000000000000000000000..e821aed31cbd215208604b48db6b2e8b602591bc --- /dev/null +++ b/docs/assets/configs/zarf/metallb/metallb-native-0.13.9.yaml @@ -0,0 +1,2008 @@ +apiVersion: v1 +kind: Namespace +metadata: + labels: + pod-security.kubernetes.io/audit: privileged + pod-security.kubernetes.io/enforce: privileged + pod-security.kubernetes.io/warn: privileged + name: metallb-system +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.11.1 + name: addresspools.metallb.io +spec: + conversion: + strategy: Webhook + webhook: + clientConfig: + caBundle: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tDQpNSUlGWlRDQ0EwMmdBd0lCQWdJVU5GRW1XcTM3MVpKdGkrMmlSQzk1WmpBV1MxZ3dEUVlKS29aSWh2Y05BUUVMDQpCUUF3UWpFTE1Ba0dBMVVFQmhNQ1dGZ3hGVEFUQmdOVkJBY01ERVJsWm1GMWJIUWdRMmwwZVRFY01Cb0dBMVVFDQpDZ3dUUkdWbVlYVnNkQ0JEYjIxd1lXNTVJRXgwWkRBZUZ3MHlNakEzTVRrd09UTXlNek5hRncweU1qQTRNVGd3DQpPVE15TXpOYU1FSXhDekFKQmdOVkJBWVRBbGhZTVJVd0V3WURWUVFIREF4RVpXWmhkV3gwSUVOcGRIa3hIREFhDQpCZ05WQkFvTUUwUmxabUYxYkhRZ1EyOXRjR0Z1ZVNCTWRHUXdnZ0lpTUEwR0NTcUdTSWIzRFFFQkFRVUFBNElDDQpEd0F3Z2dJS0FvSUNBUUNxVFpxMWZRcC9vYkdlenhES0o3OVB3Ny94azJwellualNzMlkzb1ZYSm5sRmM4YjVlDQpma2ZZQnY2bndscW1keW5PL2phWFBaQmRQSS82aFdOUDBkdVhadEtWU0NCUUpyZzEyOGNXb3F0MGNTN3pLb1VpDQpvcU1tQ0QvRXVBeFFNZjhRZDF2c1gvVllkZ0poVTZBRXJLZEpIaXpFOUJtUkNkTDBGMW1OVW55Rk82UnRtWFZUDQpidkxsTDVYeTc2R0FaQVBLOFB4aVlDa0NtbDdxN0VnTWNiOXlLWldCYmlxQ3VkTXE5TGJLNmdKNzF6YkZnSXV4DQo1L1pXK2JraTB2RlplWk9ZODUxb1psckFUNzJvMDI4NHNTWW9uN0pHZVZkY3NoUnh5R1VpSFpSTzdkaXZVTDVTDQpmM2JmSDFYbWY1ZDQzT0NWTWRuUUV2NWVaOG8zeWVLa3ZrbkZQUGVJMU9BbjdGbDlFRVNNR2dhOGFaSG1URSttDQpsLzlMSmdDYjBnQmtPT0M0WnV4bWh2aERKV1EzWnJCS3pMQlNUZXN0NWlLNVlwcXRWVVk2THRyRW9FelVTK1lsDQpwWndXY2VQWHlHeHM5ZURsR3lNVmQraW15Y3NTU1UvVno2Mmx6MnZCS21NTXBkYldDQWhud0RsRTVqU2dyMjRRDQp0eGNXLys2N3d5KzhuQlI3UXdqVTFITndVRjBzeERWdEwrZ1NHVERnSEVZSlhZelYvT05zMy94TkpoVFNPSkxNDQpoeXNVdyttaGdackdhbUdXcHVIVU1DUitvTWJzMTc1UkcrQjJnUFFHVytPTjJnUTRyOXN2b0ZBNHBBQm8xd1dLDQpRYjRhY3pmeVVscElBOVFoSmFsZEY3S3dPSHVlV3gwRUNrNXg0T2tvVDBvWVp0dzFiR0JjRGtaSmF3SURBUUFCDQpvMU13VVRBZEJnTlZIUTRFRmdRVW90UlNIUm9IWTEyRFZ4R0NCdEhpb1g2ZmVFQXdId1lEVlIwakJCZ3dGb0FVDQpvdFJTSFJvSFkxMkRWeEdDQnRIaW9YNmZlRUF3RHdZRFZSMFRBUUgvQkFVd0F3RUIvekFOQmdrcWhraUc5dzBCDQpBUXNGQUFPQ0FnRUFSbkpsWWRjMTFHd0VxWnh6RDF2R3BDR2pDN2VWTlQ3aVY1d3IybXlybHdPYi9aUWFEa0xYDQpvVStaOVVXT1VlSXJTdzUydDdmQUpvVVAwSm5iYkMveVIrU1lqUGhvUXNiVHduOTc2ZldBWTduM3FMOXhCd1Y0DQphek41OXNjeUp0dlhMeUtOL2N5ak1ReDRLajBIMFg0bWJ6bzVZNUtzWWtYVU0vOEFPdWZMcEd0S1NGVGgrSEFDDQpab1Q5YnZHS25adnNHd0tYZFF0Wnh0akhaUjVqK3U3ZGtQOTJBT051RFNabS8rWVV4b2tBK09JbzdSR3BwSHNXDQo1ZTdNY0FTVXRtb1FORXd6dVFoVkJaRWQ1OGtKYjUrV0VWbGNzanlXNnRTbzErZ25tTWNqR1BsMWgxR2hVbjV4DQpFY0lWRnBIWXM5YWo1NmpBSjk1MVQvZjhMaWxmTlVnanBLQ0c1bnl0SUt3emxhOHNtdGlPdm1UNEpYbXBwSkI2DQo4bmdHRVluVjUrUTYwWFJ2OEhSSGp1VG9CRHVhaERrVDA2R1JGODU1d09FR2V4bkZpMXZYWUxLVllWb1V2MXRKDQo4dVdUR1pwNllDSVJldlBqbzg5ZytWTlJSaVFYUThJd0dybXE5c0RoVTlqTjA0SjdVL1RvRDFpNHE3VnlsRUc5DQorV1VGNkNLaEdBeTJIaEhwVncyTGFoOS9lUzdZMUZ1YURrWmhPZG1laG1BOCtqdHNZamJadnR5Mm1SWlF0UUZzDQpUU1VUUjREbUR2bVVPRVRmeStpRHdzK2RkWXVNTnJGeVVYV2dkMnpBQU4ydVl1UHFGY2pRcFNPODFzVTJTU3R3DQoxVzAyeUtYOGJEYmZFdjBzbUh3UzliQnFlSGo5NEM1Mjg0YXpsdTBmaUdpTm1OUEM4ckJLRmhBPQ0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQ== + service: + name: webhook-service + namespace: metallb-system + path: /convert + conversionReviewVersions: + - v1alpha1 + - v1beta1 + group: metallb.io + names: + kind: AddressPool + listKind: AddressPoolList + plural: addresspools + singular: addresspool + scope: Namespaced + versions: + - deprecated: true + deprecationWarning: metallb.io v1alpha1 AddressPool is deprecated + name: v1alpha1 + schema: + openAPIV3Schema: + description: AddressPool is the Schema for the addresspools API. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: AddressPoolSpec defines the desired state of AddressPool. + properties: + addresses: + description: A list of IP address ranges over which MetalLB has authority. + You can list multiple ranges in a single pool, they will all share + the same settings. Each range can be either a CIDR prefix, or an + explicit start-end range of IPs. + items: + type: string + type: array + autoAssign: + default: true + description: AutoAssign flag used to prevent MetallB from automatic + allocation for a pool. + type: boolean + bgpAdvertisements: + description: When an IP is allocated from this pool, how should it + be translated into BGP announcements? + items: + properties: + aggregationLength: + default: 32 + description: The aggregation-length advertisement option lets + you “roll up†the /32s into a larger prefix. + format: int32 + minimum: 1 + type: integer + aggregationLengthV6: + default: 128 + description: Optional, defaults to 128 (i.e. no aggregation) + if not specified. + format: int32 + type: integer + communities: + description: BGP communities + items: + type: string + type: array + localPref: + description: BGP LOCAL_PREF attribute which is used by BGP best + path algorithm, Path with higher localpref is preferred over + one with lower localpref. + format: int32 + type: integer + type: object + type: array + protocol: + description: Protocol can be used to select how the announcement is + done. + enum: + - layer2 + - bgp + type: string + required: + - addresses + - protocol + type: object + status: + description: AddressPoolStatus defines the observed state of AddressPool. + type: object + required: + - spec + type: object + served: true + storage: false + subresources: + status: {} + - deprecated: true + deprecationWarning: metallb.io v1beta1 AddressPool is deprecated, consider using + IPAddressPool + name: v1beta1 + schema: + openAPIV3Schema: + description: AddressPool represents a pool of IP addresses that can be allocated + to LoadBalancer services. AddressPool is deprecated and being replaced by + IPAddressPool. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: AddressPoolSpec defines the desired state of AddressPool. + properties: + addresses: + description: A list of IP address ranges over which MetalLB has authority. + You can list multiple ranges in a single pool, they will all share + the same settings. Each range can be either a CIDR prefix, or an + explicit start-end range of IPs. + items: + type: string + type: array + autoAssign: + default: true + description: AutoAssign flag used to prevent MetallB from automatic + allocation for a pool. + type: boolean + bgpAdvertisements: + description: Drives how an IP allocated from this pool should translated + into BGP announcements. + items: + properties: + aggregationLength: + default: 32 + description: The aggregation-length advertisement option lets + you “roll up†the /32s into a larger prefix. + format: int32 + minimum: 1 + type: integer + aggregationLengthV6: + default: 128 + description: Optional, defaults to 128 (i.e. no aggregation) + if not specified. + format: int32 + type: integer + communities: + description: BGP communities to be associated with the given + advertisement. + items: + type: string + type: array + localPref: + description: BGP LOCAL_PREF attribute which is used by BGP best + path algorithm, Path with higher localpref is preferred over + one with lower localpref. + format: int32 + type: integer + type: object + type: array + protocol: + description: Protocol can be used to select how the announcement is + done. + enum: + - layer2 + - bgp + type: string + required: + - addresses + - protocol + type: object + status: + description: AddressPoolStatus defines the observed state of AddressPool. + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.11.1 + creationTimestamp: null + name: bfdprofiles.metallb.io +spec: + group: metallb.io + names: + kind: BFDProfile + listKind: BFDProfileList + plural: bfdprofiles + singular: bfdprofile + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .spec.passiveMode + name: Passive Mode + type: boolean + - jsonPath: .spec.transmitInterval + name: Transmit Interval + type: integer + - jsonPath: .spec.receiveInterval + name: Receive Interval + type: integer + - jsonPath: .spec.detectMultiplier + name: Multiplier + type: integer + name: v1beta1 + schema: + openAPIV3Schema: + description: BFDProfile represents the settings of the bfd session that can + be optionally associated with a BGP session. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: BFDProfileSpec defines the desired state of BFDProfile. + properties: + detectMultiplier: + description: Configures the detection multiplier to determine packet + loss. The remote transmission interval will be multiplied by this + value to determine the connection loss detection timer. + format: int32 + maximum: 255 + minimum: 2 + type: integer + echoInterval: + description: Configures the minimal echo receive transmission interval + that this system is capable of handling in milliseconds. Defaults + to 50ms + format: int32 + maximum: 60000 + minimum: 10 + type: integer + echoMode: + description: Enables or disables the echo transmission mode. This + mode is disabled by default, and not supported on multi hops setups. + type: boolean + minimumTtl: + description: 'For multi hop sessions only: configure the minimum expected + TTL for an incoming BFD control packet.' + format: int32 + maximum: 254 + minimum: 1 + type: integer + passiveMode: + description: 'Mark session as passive: a passive session will not + attempt to start the connection and will wait for control packets + from peer before it begins replying.' + type: boolean + receiveInterval: + description: The minimum interval that this system is capable of receiving + control packets in milliseconds. Defaults to 300ms. + format: int32 + maximum: 60000 + minimum: 10 + type: integer + transmitInterval: + description: The minimum transmission interval (less jitter) that + this system wants to use to send BFD control packets in milliseconds. + Defaults to 300ms + format: int32 + maximum: 60000 + minimum: 10 + type: integer + type: object + status: + description: BFDProfileStatus defines the observed state of BFDProfile. + type: object + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.11.1 + creationTimestamp: null + name: bgpadvertisements.metallb.io +spec: + group: metallb.io + names: + kind: BGPAdvertisement + listKind: BGPAdvertisementList + plural: bgpadvertisements + singular: bgpadvertisement + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .spec.ipAddressPools + name: IPAddressPools + type: string + - jsonPath: .spec.ipAddressPoolSelectors + name: IPAddressPool Selectors + type: string + - jsonPath: .spec.peers + name: Peers + type: string + - jsonPath: .spec.nodeSelectors + name: Node Selectors + priority: 10 + type: string + name: v1beta1 + schema: + openAPIV3Schema: + description: BGPAdvertisement allows to advertise the IPs coming from the + selected IPAddressPools via BGP, setting the parameters of the BGP Advertisement. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: BGPAdvertisementSpec defines the desired state of BGPAdvertisement. + properties: + aggregationLength: + default: 32 + description: The aggregation-length advertisement option lets you + “roll up†the /32s into a larger prefix. Defaults to 32. Works for + IPv4 addresses. + format: int32 + minimum: 1 + type: integer + aggregationLengthV6: + default: 128 + description: The aggregation-length advertisement option lets you + “roll up†the /128s into a larger prefix. Defaults to 128. Works + for IPv6 addresses. + format: int32 + type: integer + communities: + description: The BGP communities to be associated with the announcement. + Each item can be a community of the form 1234:1234 or the name of + an alias defined in the Community CRD. + items: + type: string + type: array + ipAddressPoolSelectors: + description: A selector for the IPAddressPools which would get advertised + via this advertisement. If no IPAddressPool is selected by this + or by the list, the advertisement is applied to all the IPAddressPools. + items: + description: A label selector is a label query over a set of resources. + The result of matchLabels and matchExpressions are ANDed. An empty + label selector matches all objects. A null label selector matches + no objects. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. + The requirements are ANDed. + items: + description: A label selector requirement is a selector that + contains values, a key, and an operator that relates the + key and values. + properties: + key: + description: key is the label key that the selector applies + to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of string values. If the + operator is In or NotIn, the values array must be non-empty. + If the operator is Exists or DoesNotExist, the values + array must be empty. This array is replaced during a + strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single + {key,value} in the matchLabels map is equivalent to an element + of matchExpressions, whose key field is "key", the operator + is "In", and the values array contains only "value". The requirements + are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + type: array + ipAddressPools: + description: The list of IPAddressPools to advertise via this advertisement, + selected by name. + items: + type: string + type: array + localPref: + description: The BGP LOCAL_PREF attribute which is used by BGP best + path algorithm, Path with higher localpref is preferred over one + with lower localpref. + format: int32 + type: integer + nodeSelectors: + description: NodeSelectors allows to limit the nodes to announce as + next hops for the LoadBalancer IP. When empty, all the nodes having are + announced as next hops. + items: + description: A label selector is a label query over a set of resources. + The result of matchLabels and matchExpressions are ANDed. An empty + label selector matches all objects. A null label selector matches + no objects. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. + The requirements are ANDed. + items: + description: A label selector requirement is a selector that + contains values, a key, and an operator that relates the + key and values. + properties: + key: + description: key is the label key that the selector applies + to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of string values. If the + operator is In or NotIn, the values array must be non-empty. + If the operator is Exists or DoesNotExist, the values + array must be empty. This array is replaced during a + strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single + {key,value} in the matchLabels map is equivalent to an element + of matchExpressions, whose key field is "key", the operator + is "In", and the values array contains only "value". The requirements + are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + type: array + peers: + description: Peers limits the bgppeer to advertise the ips of the + selected pools to. When empty, the loadbalancer IP is announced + to all the BGPPeers configured. + items: + type: string + type: array + type: object + status: + description: BGPAdvertisementStatus defines the observed state of BGPAdvertisement. + type: object + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.11.1 + name: bgppeers.metallb.io +spec: + conversion: + strategy: Webhook + webhook: + clientConfig: + caBundle: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tDQpNSUlGWlRDQ0EwMmdBd0lCQWdJVU5GRW1XcTM3MVpKdGkrMmlSQzk1WmpBV1MxZ3dEUVlKS29aSWh2Y05BUUVMDQpCUUF3UWpFTE1Ba0dBMVVFQmhNQ1dGZ3hGVEFUQmdOVkJBY01ERVJsWm1GMWJIUWdRMmwwZVRFY01Cb0dBMVVFDQpDZ3dUUkdWbVlYVnNkQ0JEYjIxd1lXNTVJRXgwWkRBZUZ3MHlNakEzTVRrd09UTXlNek5hRncweU1qQTRNVGd3DQpPVE15TXpOYU1FSXhDekFKQmdOVkJBWVRBbGhZTVJVd0V3WURWUVFIREF4RVpXWmhkV3gwSUVOcGRIa3hIREFhDQpCZ05WQkFvTUUwUmxabUYxYkhRZ1EyOXRjR0Z1ZVNCTWRHUXdnZ0lpTUEwR0NTcUdTSWIzRFFFQkFRVUFBNElDDQpEd0F3Z2dJS0FvSUNBUUNxVFpxMWZRcC9vYkdlenhES0o3OVB3Ny94azJwellualNzMlkzb1ZYSm5sRmM4YjVlDQpma2ZZQnY2bndscW1keW5PL2phWFBaQmRQSS82aFdOUDBkdVhadEtWU0NCUUpyZzEyOGNXb3F0MGNTN3pLb1VpDQpvcU1tQ0QvRXVBeFFNZjhRZDF2c1gvVllkZ0poVTZBRXJLZEpIaXpFOUJtUkNkTDBGMW1OVW55Rk82UnRtWFZUDQpidkxsTDVYeTc2R0FaQVBLOFB4aVlDa0NtbDdxN0VnTWNiOXlLWldCYmlxQ3VkTXE5TGJLNmdKNzF6YkZnSXV4DQo1L1pXK2JraTB2RlplWk9ZODUxb1psckFUNzJvMDI4NHNTWW9uN0pHZVZkY3NoUnh5R1VpSFpSTzdkaXZVTDVTDQpmM2JmSDFYbWY1ZDQzT0NWTWRuUUV2NWVaOG8zeWVLa3ZrbkZQUGVJMU9BbjdGbDlFRVNNR2dhOGFaSG1URSttDQpsLzlMSmdDYjBnQmtPT0M0WnV4bWh2aERKV1EzWnJCS3pMQlNUZXN0NWlLNVlwcXRWVVk2THRyRW9FelVTK1lsDQpwWndXY2VQWHlHeHM5ZURsR3lNVmQraW15Y3NTU1UvVno2Mmx6MnZCS21NTXBkYldDQWhud0RsRTVqU2dyMjRRDQp0eGNXLys2N3d5KzhuQlI3UXdqVTFITndVRjBzeERWdEwrZ1NHVERnSEVZSlhZelYvT05zMy94TkpoVFNPSkxNDQpoeXNVdyttaGdackdhbUdXcHVIVU1DUitvTWJzMTc1UkcrQjJnUFFHVytPTjJnUTRyOXN2b0ZBNHBBQm8xd1dLDQpRYjRhY3pmeVVscElBOVFoSmFsZEY3S3dPSHVlV3gwRUNrNXg0T2tvVDBvWVp0dzFiR0JjRGtaSmF3SURBUUFCDQpvMU13VVRBZEJnTlZIUTRFRmdRVW90UlNIUm9IWTEyRFZ4R0NCdEhpb1g2ZmVFQXdId1lEVlIwakJCZ3dGb0FVDQpvdFJTSFJvSFkxMkRWeEdDQnRIaW9YNmZlRUF3RHdZRFZSMFRBUUgvQkFVd0F3RUIvekFOQmdrcWhraUc5dzBCDQpBUXNGQUFPQ0FnRUFSbkpsWWRjMTFHd0VxWnh6RDF2R3BDR2pDN2VWTlQ3aVY1d3IybXlybHdPYi9aUWFEa0xYDQpvVStaOVVXT1VlSXJTdzUydDdmQUpvVVAwSm5iYkMveVIrU1lqUGhvUXNiVHduOTc2ZldBWTduM3FMOXhCd1Y0DQphek41OXNjeUp0dlhMeUtOL2N5ak1ReDRLajBIMFg0bWJ6bzVZNUtzWWtYVU0vOEFPdWZMcEd0S1NGVGgrSEFDDQpab1Q5YnZHS25adnNHd0tYZFF0Wnh0akhaUjVqK3U3ZGtQOTJBT051RFNabS8rWVV4b2tBK09JbzdSR3BwSHNXDQo1ZTdNY0FTVXRtb1FORXd6dVFoVkJaRWQ1OGtKYjUrV0VWbGNzanlXNnRTbzErZ25tTWNqR1BsMWgxR2hVbjV4DQpFY0lWRnBIWXM5YWo1NmpBSjk1MVQvZjhMaWxmTlVnanBLQ0c1bnl0SUt3emxhOHNtdGlPdm1UNEpYbXBwSkI2DQo4bmdHRVluVjUrUTYwWFJ2OEhSSGp1VG9CRHVhaERrVDA2R1JGODU1d09FR2V4bkZpMXZYWUxLVllWb1V2MXRKDQo4dVdUR1pwNllDSVJldlBqbzg5ZytWTlJSaVFYUThJd0dybXE5c0RoVTlqTjA0SjdVL1RvRDFpNHE3VnlsRUc5DQorV1VGNkNLaEdBeTJIaEhwVncyTGFoOS9lUzdZMUZ1YURrWmhPZG1laG1BOCtqdHNZamJadnR5Mm1SWlF0UUZzDQpUU1VUUjREbUR2bVVPRVRmeStpRHdzK2RkWXVNTnJGeVVYV2dkMnpBQU4ydVl1UHFGY2pRcFNPODFzVTJTU3R3DQoxVzAyeUtYOGJEYmZFdjBzbUh3UzliQnFlSGo5NEM1Mjg0YXpsdTBmaUdpTm1OUEM4ckJLRmhBPQ0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQ== + service: + name: webhook-service + namespace: metallb-system + path: /convert + conversionReviewVersions: + - v1beta1 + - v1beta2 + group: metallb.io + names: + kind: BGPPeer + listKind: BGPPeerList + plural: bgppeers + singular: bgppeer + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .spec.peerAddress + name: Address + type: string + - jsonPath: .spec.peerASN + name: ASN + type: string + - jsonPath: .spec.bfdProfile + name: BFD Profile + type: string + - jsonPath: .spec.ebgpMultiHop + name: Multi Hops + type: string + name: v1beta1 + schema: + openAPIV3Schema: + description: BGPPeer is the Schema for the peers API. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: BGPPeerSpec defines the desired state of Peer. + properties: + bfdProfile: + type: string + ebgpMultiHop: + description: EBGP peer is multi-hops away + type: boolean + holdTime: + description: Requested BGP hold time, per RFC4271. + type: string + keepaliveTime: + description: Requested BGP keepalive time, per RFC4271. + type: string + myASN: + description: AS number to use for the local end of the session. + format: int32 + maximum: 4294967295 + minimum: 0 + type: integer + nodeSelectors: + description: Only connect to this peer on nodes that match one of + these selectors. + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + minItems: 1 + type: array + required: + - key + - operator + - values + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + type: array + password: + description: Authentication password for routers enforcing TCP MD5 + authenticated sessions + type: string + peerASN: + description: AS number to expect from the remote end of the session. + format: int32 + maximum: 4294967295 + minimum: 0 + type: integer + peerAddress: + description: Address to dial when establishing the session. + type: string + peerPort: + description: Port to dial when establishing the session. + maximum: 16384 + minimum: 0 + type: integer + routerID: + description: BGP router ID to advertise to the peer + type: string + sourceAddress: + description: Source address to use when establishing the session. + type: string + required: + - myASN + - peerASN + - peerAddress + type: object + status: + description: BGPPeerStatus defines the observed state of Peer. + type: object + type: object + served: true + storage: false + subresources: + status: {} + - additionalPrinterColumns: + - jsonPath: .spec.peerAddress + name: Address + type: string + - jsonPath: .spec.peerASN + name: ASN + type: string + - jsonPath: .spec.bfdProfile + name: BFD Profile + type: string + - jsonPath: .spec.ebgpMultiHop + name: Multi Hops + type: string + name: v1beta2 + schema: + openAPIV3Schema: + description: BGPPeer is the Schema for the peers API. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: BGPPeerSpec defines the desired state of Peer. + properties: + bfdProfile: + description: The name of the BFD Profile to be used for the BFD session + associated to the BGP session. If not set, the BFD session won't + be set up. + type: string + ebgpMultiHop: + description: To set if the BGPPeer is multi-hops away. Needed for + FRR mode only. + type: boolean + holdTime: + description: Requested BGP hold time, per RFC4271. + type: string + keepaliveTime: + description: Requested BGP keepalive time, per RFC4271. + type: string + myASN: + description: AS number to use for the local end of the session. + format: int32 + maximum: 4294967295 + minimum: 0 + type: integer + nodeSelectors: + description: Only connect to this peer on nodes that match one of + these selectors. + items: + description: A label selector is a label query over a set of resources. + The result of matchLabels and matchExpressions are ANDed. An empty + label selector matches all objects. A null label selector matches + no objects. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. + The requirements are ANDed. + items: + description: A label selector requirement is a selector that + contains values, a key, and an operator that relates the + key and values. + properties: + key: + description: key is the label key that the selector applies + to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of string values. If the + operator is In or NotIn, the values array must be non-empty. + If the operator is Exists or DoesNotExist, the values + array must be empty. This array is replaced during a + strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single + {key,value} in the matchLabels map is equivalent to an element + of matchExpressions, whose key field is "key", the operator + is "In", and the values array contains only "value". The requirements + are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + type: array + password: + description: Authentication password for routers enforcing TCP MD5 + authenticated sessions + type: string + passwordSecret: + description: passwordSecret is name of the authentication secret for + BGP Peer. the secret must be of type "kubernetes.io/basic-auth", + and created in the same namespace as the MetalLB deployment. The + password is stored in the secret as the key "password". + properties: + name: + description: name is unique within a namespace to reference a + secret resource. + type: string + namespace: + description: namespace defines the space within which the secret + name must be unique. + type: string + type: object + x-kubernetes-map-type: atomic + peerASN: + description: AS number to expect from the remote end of the session. + format: int32 + maximum: 4294967295 + minimum: 0 + type: integer + peerAddress: + description: Address to dial when establishing the session. + type: string + peerPort: + default: 179 + description: Port to dial when establishing the session. + maximum: 16384 + minimum: 0 + type: integer + routerID: + description: BGP router ID to advertise to the peer + type: string + sourceAddress: + description: Source address to use when establishing the session. + type: string + vrf: + description: To set if we want to peer with the BGPPeer using an interface + belonging to a host vrf + type: string + required: + - myASN + - peerASN + - peerAddress + type: object + status: + description: BGPPeerStatus defines the observed state of Peer. + type: object + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.11.1 + creationTimestamp: null + name: communities.metallb.io +spec: + group: metallb.io + names: + kind: Community + listKind: CommunityList + plural: communities + singular: community + scope: Namespaced + versions: + - name: v1beta1 + schema: + openAPIV3Schema: + description: Community is a collection of aliases for communities. Users can + define named aliases to be used in the BGPPeer CRD. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: CommunitySpec defines the desired state of Community. + properties: + communities: + items: + properties: + name: + description: The name of the alias for the community. + type: string + value: + description: The BGP community value corresponding to the given + name. + type: string + type: object + type: array + type: object + status: + description: CommunityStatus defines the observed state of Community. + type: object + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.11.1 + creationTimestamp: null + name: ipaddresspools.metallb.io +spec: + group: metallb.io + names: + kind: IPAddressPool + listKind: IPAddressPoolList + plural: ipaddresspools + singular: ipaddresspool + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .spec.autoAssign + name: Auto Assign + type: boolean + - jsonPath: .spec.avoidBuggyIPs + name: Avoid Buggy IPs + type: boolean + - jsonPath: .spec.addresses + name: Addresses + type: string + name: v1beta1 + schema: + openAPIV3Schema: + description: IPAddressPool represents a pool of IP addresses that can be allocated + to LoadBalancer services. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: IPAddressPoolSpec defines the desired state of IPAddressPool. + properties: + addresses: + description: A list of IP address ranges over which MetalLB has authority. + You can list multiple ranges in a single pool, they will all share + the same settings. Each range can be either a CIDR prefix, or an + explicit start-end range of IPs. + items: + type: string + type: array + autoAssign: + default: true + description: AutoAssign flag used to prevent MetallB from automatic + allocation for a pool. + type: boolean + avoidBuggyIPs: + default: false + description: AvoidBuggyIPs prevents addresses ending with .0 and .255 + to be used by a pool. + type: boolean + serviceAllocation: + description: AllocateTo makes ip pool allocation to specific namespace + and/or service. The controller will use the pool with lowest value + of priority in case of multiple matches. A pool with no priority + set will be used only if the pools with priority can't be used. + If multiple matching IPAddressPools are available it will check + for the availability of IPs sorting the matching IPAddressPools + by priority, starting from the highest to the lowest. If multiple + IPAddressPools have the same priority, choice will be random. + properties: + namespaceSelectors: + description: NamespaceSelectors list of label selectors to select + namespace(s) for ip pool, an alternative to using namespace + list. + items: + description: A label selector is a label query over a set of + resources. The result of matchLabels and matchExpressions + are ANDed. An empty label selector matches all objects. A + null label selector matches no objects. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector + that contains values, a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are In, NotIn, + Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. + If the operator is In or NotIn, the values array + must be non-empty. If the operator is Exists or + DoesNotExist, the values array must be empty. This + array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. + A single {key,value} in the matchLabels map is equivalent + to an element of matchExpressions, whose key field is + "key", the operator is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + type: array + namespaces: + description: Namespaces list of namespace(s) on which ip pool + can be attached. + items: + type: string + type: array + priority: + description: Priority priority given for ip pool while ip allocation + on a service. + type: integer + serviceSelectors: + description: ServiceSelectors list of label selector to select + service(s) for which ip pool can be used for ip allocation. + items: + description: A label selector is a label query over a set of + resources. The result of matchLabels and matchExpressions + are ANDed. An empty label selector matches all objects. A + null label selector matches no objects. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector + that contains values, a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are In, NotIn, + Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. + If the operator is In or NotIn, the values array + must be non-empty. If the operator is Exists or + DoesNotExist, the values array must be empty. This + array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. + A single {key,value} in the matchLabels map is equivalent + to an element of matchExpressions, whose key field is + "key", the operator is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + type: array + type: object + required: + - addresses + type: object + status: + description: IPAddressPoolStatus defines the observed state of IPAddressPool. + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.11.1 + creationTimestamp: null + name: l2advertisements.metallb.io +spec: + group: metallb.io + names: + kind: L2Advertisement + listKind: L2AdvertisementList + plural: l2advertisements + singular: l2advertisement + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .spec.ipAddressPools + name: IPAddressPools + type: string + - jsonPath: .spec.ipAddressPoolSelectors + name: IPAddressPool Selectors + type: string + - jsonPath: .spec.interfaces + name: Interfaces + type: string + - jsonPath: .spec.nodeSelectors + name: Node Selectors + priority: 10 + type: string + name: v1beta1 + schema: + openAPIV3Schema: + description: L2Advertisement allows to advertise the LoadBalancer IPs provided + by the selected pools via L2. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: L2AdvertisementSpec defines the desired state of L2Advertisement. + properties: + interfaces: + description: A list of interfaces to announce from. The LB IP will + be announced only from these interfaces. If the field is not set, + we advertise from all the interfaces on the host. + items: + type: string + type: array + ipAddressPoolSelectors: + description: A selector for the IPAddressPools which would get advertised + via this advertisement. If no IPAddressPool is selected by this + or by the list, the advertisement is applied to all the IPAddressPools. + items: + description: A label selector is a label query over a set of resources. + The result of matchLabels and matchExpressions are ANDed. An empty + label selector matches all objects. A null label selector matches + no objects. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. + The requirements are ANDed. + items: + description: A label selector requirement is a selector that + contains values, a key, and an operator that relates the + key and values. + properties: + key: + description: key is the label key that the selector applies + to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of string values. If the + operator is In or NotIn, the values array must be non-empty. + If the operator is Exists or DoesNotExist, the values + array must be empty. This array is replaced during a + strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single + {key,value} in the matchLabels map is equivalent to an element + of matchExpressions, whose key field is "key", the operator + is "In", and the values array contains only "value". The requirements + are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + type: array + ipAddressPools: + description: The list of IPAddressPools to advertise via this advertisement, + selected by name. + items: + type: string + type: array + nodeSelectors: + description: NodeSelectors allows to limit the nodes to announce as + next hops for the LoadBalancer IP. When empty, all the nodes having are + announced as next hops. + items: + description: A label selector is a label query over a set of resources. + The result of matchLabels and matchExpressions are ANDed. An empty + label selector matches all objects. A null label selector matches + no objects. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. + The requirements are ANDed. + items: + description: A label selector requirement is a selector that + contains values, a key, and an operator that relates the + key and values. + properties: + key: + description: key is the label key that the selector applies + to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of string values. If the + operator is In or NotIn, the values array must be non-empty. + If the operator is Exists or DoesNotExist, the values + array must be empty. This array is replaced during a + strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single + {key,value} in the matchLabels map is equivalent to an element + of matchExpressions, whose key field is "key", the operator + is "In", and the values array contains only "value". The requirements + are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + type: array + type: object + status: + description: L2AdvertisementStatus defines the observed state of L2Advertisement. + type: object + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app: metallb + name: controller + namespace: metallb-system +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app: metallb + name: speaker + namespace: metallb-system +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + labels: + app: metallb + name: controller + namespace: metallb-system +rules: + - apiGroups: + - "" + resources: + - secrets + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - "" + resourceNames: + - memberlist + resources: + - secrets + verbs: + - list + - apiGroups: + - apps + resourceNames: + - controller + resources: + - deployments + verbs: + - get + - apiGroups: + - metallb.io + resources: + - bgppeers + verbs: + - get + - list + - apiGroups: + - metallb.io + resources: + - addresspools + verbs: + - get + - list + - watch + - apiGroups: + - metallb.io + resources: + - bfdprofiles + verbs: + - get + - list + - watch + - apiGroups: + - metallb.io + resources: + - ipaddresspools + verbs: + - get + - list + - watch + - apiGroups: + - metallb.io + resources: + - bgpadvertisements + verbs: + - get + - list + - watch + - apiGroups: + - metallb.io + resources: + - l2advertisements + verbs: + - get + - list + - watch + - apiGroups: + - metallb.io + resources: + - communities + verbs: + - get + - list + - watch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + labels: + app: metallb + name: pod-lister + namespace: metallb-system +rules: + - apiGroups: + - "" + resources: + - pods + verbs: + - list + - apiGroups: + - "" + resources: + - secrets + verbs: + - get + - list + - watch + - apiGroups: + - metallb.io + resources: + - addresspools + verbs: + - get + - list + - watch + - apiGroups: + - metallb.io + resources: + - bfdprofiles + verbs: + - get + - list + - watch + - apiGroups: + - metallb.io + resources: + - bgppeers + verbs: + - get + - list + - watch + - apiGroups: + - metallb.io + resources: + - l2advertisements + verbs: + - get + - list + - watch + - apiGroups: + - metallb.io + resources: + - bgpadvertisements + verbs: + - get + - list + - watch + - apiGroups: + - metallb.io + resources: + - ipaddresspools + verbs: + - get + - list + - watch + - apiGroups: + - metallb.io + resources: + - communities + verbs: + - get + - list + - watch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app: metallb + name: metallb-system:controller +rules: + - apiGroups: + - "" + resources: + - services + - namespaces + verbs: + - get + - list + - watch + - apiGroups: + - "" + resources: + - services/status + verbs: + - update + - apiGroups: + - "" + resources: + - events + verbs: + - create + - patch + - apiGroups: + - policy + resourceNames: + - controller + resources: + - podsecuritypolicies + verbs: + - use + - apiGroups: + - admissionregistration.k8s.io + resourceNames: + - metallb-webhook-configuration + resources: + - validatingwebhookconfigurations + - mutatingwebhookconfigurations + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - admissionregistration.k8s.io + resources: + - validatingwebhookconfigurations + - mutatingwebhookconfigurations + verbs: + - list + - watch + - apiGroups: + - apiextensions.k8s.io + resourceNames: + - addresspools.metallb.io + - bfdprofiles.metallb.io + - bgpadvertisements.metallb.io + - bgppeers.metallb.io + - ipaddresspools.metallb.io + - l2advertisements.metallb.io + - communities.metallb.io + resources: + - customresourcedefinitions + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - apiextensions.k8s.io + resources: + - customresourcedefinitions + verbs: + - list + - watch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app: metallb + name: metallb-system:speaker +rules: + - apiGroups: + - "" + resources: + - services + - endpoints + - nodes + - namespaces + verbs: + - get + - list + - watch + - apiGroups: + - discovery.k8s.io + resources: + - endpointslices + verbs: + - get + - list + - watch + - apiGroups: + - "" + resources: + - events + verbs: + - create + - patch + - apiGroups: + - policy + resourceNames: + - speaker + resources: + - podsecuritypolicies + verbs: + - use +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + app: metallb + name: controller + namespace: metallb-system +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: controller +subjects: + - kind: ServiceAccount + name: controller + namespace: metallb-system +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + app: metallb + name: pod-lister + namespace: metallb-system +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: pod-lister +subjects: + - kind: ServiceAccount + name: speaker + namespace: metallb-system +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + app: metallb + name: metallb-system:controller +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: metallb-system:controller +subjects: + - kind: ServiceAccount + name: controller + namespace: metallb-system +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + app: metallb + name: metallb-system:speaker +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: metallb-system:speaker +subjects: + - kind: ServiceAccount + name: speaker + namespace: metallb-system +--- +apiVersion: v1 +kind: Secret +metadata: + name: webhook-server-cert + namespace: metallb-system +--- +apiVersion: v1 +kind: Service +metadata: + name: webhook-service + namespace: metallb-system +spec: + ports: + - port: 443 + targetPort: 9443 + selector: + component: controller +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app: metallb + component: controller + name: controller + namespace: metallb-system +spec: + revisionHistoryLimit: 3 + selector: + matchLabels: + app: metallb + component: controller + template: + metadata: + annotations: + prometheus.io/port: "7472" + prometheus.io/scrape: "true" + labels: + app: metallb + component: controller + spec: + containers: + - args: + - --port=7472 + - --log-level=info + env: + - name: METALLB_ML_SECRET_NAME + value: memberlist + - name: METALLB_DEPLOYMENT + value: controller + image: quay.io/metallb/controller:v0.13.9 + livenessProbe: + failureThreshold: 3 + httpGet: + path: /metrics + port: monitoring + initialDelaySeconds: 10 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + name: controller + ports: + - containerPort: 7472 + name: monitoring + - containerPort: 9443 + name: webhook-server + protocol: TCP + readinessProbe: + failureThreshold: 3 + httpGet: + path: /metrics + port: monitoring + initialDelaySeconds: 10 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - all + readOnlyRootFilesystem: true + volumeMounts: + - mountPath: /tmp/k8s-webhook-server/serving-certs + name: cert + readOnly: true + nodeSelector: + kubernetes.io/os: linux + securityContext: + fsGroup: 65534 + runAsNonRoot: true + runAsUser: 65534 + serviceAccountName: controller + terminationGracePeriodSeconds: 0 + volumes: + - name: cert + secret: + defaultMode: 420 + secretName: webhook-server-cert +--- +apiVersion: apps/v1 +kind: DaemonSet +metadata: + labels: + app: metallb + component: speaker + name: speaker + namespace: metallb-system +spec: + selector: + matchLabels: + app: metallb + component: speaker + template: + metadata: + annotations: + prometheus.io/port: "7472" + prometheus.io/scrape: "true" + labels: + app: metallb + component: speaker + spec: + containers: + - args: + - --port=7472 + - --log-level=info + env: + - name: METALLB_NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + - name: METALLB_HOST + valueFrom: + fieldRef: + fieldPath: status.hostIP + - name: METALLB_ML_BIND_ADDR + valueFrom: + fieldRef: + fieldPath: status.podIP + - name: METALLB_ML_LABELS + value: app=metallb,component=speaker + - name: METALLB_ML_SECRET_KEY_PATH + value: /etc/ml_secret_key + image: quay.io/metallb/speaker:v0.13.9 + livenessProbe: + failureThreshold: 3 + httpGet: + path: /metrics + port: monitoring + initialDelaySeconds: 10 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + name: speaker + ports: + - containerPort: 7472 + name: monitoring + - containerPort: 7946 + name: memberlist-tcp + - containerPort: 7946 + name: memberlist-udp + protocol: UDP + readinessProbe: + failureThreshold: 3 + httpGet: + path: /metrics + port: monitoring + initialDelaySeconds: 10 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + securityContext: + allowPrivilegeEscalation: false + capabilities: + add: + - NET_RAW + drop: + - ALL + readOnlyRootFilesystem: true + volumeMounts: + - mountPath: /etc/ml_secret_key + name: memberlist + readOnly: true + hostNetwork: true + nodeSelector: + kubernetes.io/os: linux + serviceAccountName: speaker + terminationGracePeriodSeconds: 2 + tolerations: + - effect: NoSchedule + key: node-role.kubernetes.io/master + operator: Exists + - effect: NoSchedule + key: node-role.kubernetes.io/control-plane + operator: Exists + volumes: + - name: memberlist + secret: + defaultMode: 420 + secretName: memberlist +--- +apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingWebhookConfiguration +metadata: + creationTimestamp: null + name: metallb-webhook-configuration +webhooks: + - admissionReviewVersions: + - v1 + clientConfig: + service: + name: webhook-service + namespace: metallb-system + path: /validate-metallb-io-v1beta2-bgppeer + failurePolicy: Fail + name: bgppeersvalidationwebhook.metallb.io + rules: + - apiGroups: + - metallb.io + apiVersions: + - v1beta2 + operations: + - CREATE + - UPDATE + resources: + - bgppeers + sideEffects: None + - admissionReviewVersions: + - v1 + clientConfig: + service: + name: webhook-service + namespace: metallb-system + path: /validate-metallb-io-v1beta1-addresspool + failurePolicy: Fail + name: addresspoolvalidationwebhook.metallb.io + rules: + - apiGroups: + - metallb.io + apiVersions: + - v1beta1 + operations: + - CREATE + - UPDATE + resources: + - addresspools + sideEffects: None + - admissionReviewVersions: + - v1 + clientConfig: + service: + name: webhook-service + namespace: metallb-system + path: /validate-metallb-io-v1beta1-bfdprofile + failurePolicy: Fail + name: bfdprofilevalidationwebhook.metallb.io + rules: + - apiGroups: + - metallb.io + apiVersions: + - v1beta1 + operations: + - CREATE + - DELETE + resources: + - bfdprofiles + sideEffects: None + - admissionReviewVersions: + - v1 + clientConfig: + service: + name: webhook-service + namespace: metallb-system + path: /validate-metallb-io-v1beta1-bgpadvertisement + failurePolicy: Fail + name: bgpadvertisementvalidationwebhook.metallb.io + rules: + - apiGroups: + - metallb.io + apiVersions: + - v1beta1 + operations: + - CREATE + - UPDATE + resources: + - bgpadvertisements + sideEffects: None + - admissionReviewVersions: + - v1 + clientConfig: + service: + name: webhook-service + namespace: metallb-system + path: /validate-metallb-io-v1beta1-community + failurePolicy: Fail + name: communityvalidationwebhook.metallb.io + rules: + - apiGroups: + - metallb.io + apiVersions: + - v1beta1 + operations: + - CREATE + - UPDATE + resources: + - communities + sideEffects: None + - admissionReviewVersions: + - v1 + clientConfig: + service: + name: webhook-service + namespace: metallb-system + path: /validate-metallb-io-v1beta1-ipaddresspool + failurePolicy: Fail + name: ipaddresspoolvalidationwebhook.metallb.io + rules: + - apiGroups: + - metallb.io + apiVersions: + - v1beta1 + operations: + - CREATE + - UPDATE + resources: + - ipaddresspools + sideEffects: None + - admissionReviewVersions: + - v1 + clientConfig: + service: + name: webhook-service + namespace: metallb-system + path: /validate-metallb-io-v1beta1-l2advertisement + failurePolicy: Fail + name: l2advertisementvalidationwebhook.metallb.io + rules: + - apiGroups: + - metallb.io + apiVersions: + - v1beta1 + operations: + - CREATE + - UPDATE + resources: + - l2advertisements + sideEffects: None \ No newline at end of file diff --git a/docs/assets/configs/zarf/metallb/zarf.yaml b/docs/assets/configs/zarf/metallb/zarf.yaml new file mode 100644 index 0000000000000000000000000000000000000000..66bbc46a260308847fda32239f5b25aeae8386e4 --- /dev/null +++ b/docs/assets/configs/zarf/metallb/zarf.yaml @@ -0,0 +1,26 @@ +kind: ZarfPackageConfig +metadata: + name: metallb + description: "Deploy MetalLB" + version: 1.0.0 + url: https://bigbang.dso.mil + architecture: amd64 + +variables: + - name: PRIVATE_IP_1 +# - name: PRIVATE_IP_2 + +components: + - name: metallb + manifests: + - name: metallb-baseline + namespace: metallb-system + files: + - metallb-native-0.13.9.yaml + - name: metallb-config + namespace: metallb-system + files: + - config.yaml + images: + - quay.io/metallb/speaker:v0.13.9 + - quay.io/metallb/controller:v0.13.9 diff --git a/docs/assets/configs/zarf/virtualservices/gitea.yaml b/docs/assets/configs/zarf/virtualservices/gitea.yaml new file mode 100644 index 0000000000000000000000000000000000000000..713d68305576d7f5b96a8932e5c17fc195e17648 --- /dev/null +++ b/docs/assets/configs/zarf/virtualservices/gitea.yaml @@ -0,0 +1,16 @@ +apiVersion: networking.istio.io/v1alpha3 +kind: VirtualService +metadata: + name: gitea + namespace: zarf +spec: + gateways: + - istio-system/public + hosts: + - gitea.###ZARF_VAR_DOMAIN### + http: + - route: + - destination: + host: zarf-gitea-http.zarf.svc.cluster.local + port: + number: 3000 diff --git a/docs/assets/configs/zarf/zarf.yaml b/docs/assets/configs/zarf/zarf.yaml new file mode 100644 index 0000000000000000000000000000000000000000..71ae95e53a96db3f9046dc557314f604f851fed1 --- /dev/null +++ b/docs/assets/configs/zarf/zarf.yaml @@ -0,0 +1,36 @@ +kind: ZarfPackageConfig +metadata: + name: big-bang + description: "Deploy Big Bang Core" + version: BIGBANG_VERSION + url: https://p1.dso.mil/products/big-bang + architecture: amd64 + +variables: + - name: DOMAIN + default: "bigbang.dev" + prompt: false + +components: + - name: metallb + required: false + import: + path: metallb + - name: bigbang + required: true + extensions: + bigbang: + version: BIGBANG_VERSION + valuesFiles: + - ../../../../chart/ingress-certs.yaml + - config/kyverno.yaml + - config/custom.yaml + - name: gitea-virtual-service + description: > + Expose the internal Zarf Gitea server through the Big Bang Istio deployment via a virtual service. + (only applies if you are using the Zarf-provided Gitea deployment - not an externally configured git host) + manifests: + - name: gitea + namespace: zarf + files: + - virtualservices/gitea.yaml diff --git a/docs/assets/diagrams/developer/bb-gitlab-ci-diagram.drawio b/docs/assets/diagrams/developer/bb-gitlab-ci-diagram.drawio new file mode 100644 index 0000000000000000000000000000000000000000..1061b8ead0001602099e332fdceafa08ca293728 --- /dev/null +++ b/docs/assets/diagrams/developer/bb-gitlab-ci-diagram.drawio @@ -0,0 +1 @@ +<mxfile host="Electron" modified="2021-09-13T18:30:18.191Z" agent="5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/12.9.9 Chrome/80.0.3987.163 Electron/8.2.1 Safari/537.36" etag="pn3BY3rUH7aw4UmqKB5J" version="12.9.9" type="device" pages="2"><diagram id="C5RBs43oDa-KdzZeNtuy" name="BB pipelines">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</diagram><diagram id="7LAne4oA9n-VVIV32Hwe" name="Package pipeline">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</diagram></mxfile> diff --git a/docs/assets/diagrams/developer/dev_ci_workflow.drawio b/docs/assets/diagrams/developer/dev_ci_workflow.drawio new file mode 100644 index 0000000000000000000000000000000000000000..baf7a1532161283a3eb561be6a2a616f1901745f --- /dev/null +++ b/docs/assets/diagrams/developer/dev_ci_workflow.drawio @@ -0,0 +1 @@ +<mxfile host="app.diagrams.net" modified="2021-01-06T06:20:42.230Z" agent="5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36" etag="kpGPMNrXRMedev0xIThy" version="14.1.8" type="device"><diagram id="7sAzJ7kZBJ19-CyqRDUJ" name="Page-1">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</diagram></mxfile> \ No newline at end of file diff --git a/docs/assets/imgs/developer/bb-pipelines.png b/docs/assets/imgs/developer/bb-pipelines.png new file mode 100644 index 0000000000000000000000000000000000000000..cf02dba233204f486f94a7c498fa0404702cb207 Binary files /dev/null and b/docs/assets/imgs/developer/bb-pipelines.png differ diff --git a/docs/assets/imgs/developer/dev_ci_workflow.png b/docs/assets/imgs/developer/dev_ci_workflow.png new file mode 100644 index 0000000000000000000000000000000000000000..174d32fb6cab8e094df8757afe6173d8b772d30f Binary files /dev/null and b/docs/assets/imgs/developer/dev_ci_workflow.png differ diff --git a/docs/assets/imgs/developer/infra-test-pipelines.png b/docs/assets/imgs/developer/infra-test-pipelines.png new file mode 100644 index 0000000000000000000000000000000000000000..29dfce99ef545042f4ed4001042281aa4341d0ea Binary files /dev/null and b/docs/assets/imgs/developer/infra-test-pipelines.png differ diff --git a/docs/assets/imgs/developer/metrics-server-scraping.png b/docs/assets/imgs/developer/metrics-server-scraping.png new file mode 100644 index 0000000000000000000000000000000000000000..1d8cd3e10973ec43f09802395ad8afb1e52811a7 Binary files /dev/null and b/docs/assets/imgs/developer/metrics-server-scraping.png differ diff --git a/docs/assets/imgs/developer/package-pipeline.png b/docs/assets/imgs/developer/package-pipeline.png new file mode 100644 index 0000000000000000000000000000000000000000..20aa8d02da90191fe438e3fcde350a9d71e37316 Binary files /dev/null and b/docs/assets/imgs/developer/package-pipeline.png differ diff --git a/docs/assets/imgs/guides/doom.png b/docs/assets/imgs/guides/doom.png new file mode 100644 index 0000000000000000000000000000000000000000..1a19366136f477ec62299a87d590c000fc496d26 Binary files /dev/null and b/docs/assets/imgs/guides/doom.png differ diff --git a/docs/assets/imgs/guides/grafana-dashboard-manage.jpeg b/docs/assets/imgs/guides/grafana-dashboard-manage.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..76fb9832c70b737c2c35412b94abe3b61c460a7b Binary files /dev/null and b/docs/assets/imgs/guides/grafana-dashboard-manage.jpeg differ diff --git a/docs/assets/imgs/guides/grafana-dashboard.jpeg b/docs/assets/imgs/guides/grafana-dashboard.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..fcd75502a7615aed26b822ad164b6069d495d38b Binary files /dev/null and b/docs/assets/imgs/guides/grafana-dashboard.jpeg differ diff --git a/docs/assets/imgs/guides/volume-snapshot.png b/docs/assets/imgs/guides/volume-snapshot.png new file mode 100644 index 0000000000000000000000000000000000000000..5a64612679ff626aa61702de33237d83ac9f0a7c Binary files /dev/null and b/docs/assets/imgs/guides/volume-snapshot.png differ diff --git a/docs/assets/imgs/understanding-bigbang/kube-apiserver-webhooks-diagram.app.diagrams.net.png b/docs/assets/imgs/understanding-bigbang/kube-apiserver-webhooks-diagram.app.diagrams.net.png new file mode 100644 index 0000000000000000000000000000000000000000..fd1d8242d0adcaf7cd27bceda700a31bd148ab11 Binary files /dev/null and b/docs/assets/imgs/understanding-bigbang/kube-apiserver-webhooks-diagram.app.diagrams.net.png differ diff --git a/docs/assets/imgs/understanding-bigbang/kube-apiserver-webhooks-diagram.app.diagrams.net.xml b/docs/assets/imgs/understanding-bigbang/kube-apiserver-webhooks-diagram.app.diagrams.net.xml new file mode 100644 index 0000000000000000000000000000000000000000..5acf1cb72bb4eab34142e34b0a32b6ad7fccff95 --- /dev/null +++ b/docs/assets/imgs/understanding-bigbang/kube-apiserver-webhooks-diagram.app.diagrams.net.xml @@ -0,0 +1 @@ +<mxfile host="app.diagrams.net" modified="2021-06-07T17:27:03.744Z" agent="5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.77 Safari/537.36" etag="0r8jiw2W0FVdHgPBe3XZ" version="14.7.6" type="device"><diagram id="g1U51R3u2F-uOywQiJtT" name="Page-1">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</diagram></mxfile> \ No newline at end of file diff --git a/docs/assets/imgs/understanding-bigbang/logs-data-flow-diagram.app.diagrams.net.png b/docs/assets/imgs/understanding-bigbang/logs-data-flow-diagram.app.diagrams.net.png new file mode 100644 index 0000000000000000000000000000000000000000..eae84627576ac6d52326211cae93a6af0bb3328b Binary files /dev/null and b/docs/assets/imgs/understanding-bigbang/logs-data-flow-diagram.app.diagrams.net.png differ diff --git a/docs/assets/imgs/understanding-bigbang/logs-data-flow-diagram.app.diagrams.net.xml b/docs/assets/imgs/understanding-bigbang/logs-data-flow-diagram.app.diagrams.net.xml new file mode 100644 index 0000000000000000000000000000000000000000..9244eed435d8c3fecbe4b261c830bd30a2905b3a --- /dev/null +++ b/docs/assets/imgs/understanding-bigbang/logs-data-flow-diagram.app.diagrams.net.xml @@ -0,0 +1 @@ +<mxfile host="app.diagrams.net" modified="2021-04-01T03:29:15.169Z" agent="5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36" etag="D8lnvlAFDhG5Sz-aWDvn" version="14.5.3" type="device"><diagram id="w6dHBhk2DzmvdH_unnzh" name="Page-1">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</diagram></mxfile> \ No newline at end of file diff --git a/docs/assets/imgs/understanding-bigbang/metrics-data-flow-diagram.app.diagrams.net.png b/docs/assets/imgs/understanding-bigbang/metrics-data-flow-diagram.app.diagrams.net.png new file mode 100644 index 0000000000000000000000000000000000000000..78da7e686da15cbee40eec2f6d214994c15c034f Binary files /dev/null and b/docs/assets/imgs/understanding-bigbang/metrics-data-flow-diagram.app.diagrams.net.png differ diff --git a/docs/assets/imgs/understanding-bigbang/metrics-data-flow-diagram.app.diagrams.net.xml b/docs/assets/imgs/understanding-bigbang/metrics-data-flow-diagram.app.diagrams.net.xml new file mode 100644 index 0000000000000000000000000000000000000000..024d48d3d7dfa16042abbefd5d7e64ffea243399 --- /dev/null +++ b/docs/assets/imgs/understanding-bigbang/metrics-data-flow-diagram.app.diagrams.net.xml @@ -0,0 +1 @@ +<mxfile host="app.diagrams.net" modified="2021-04-01T03:06:34.651Z" agent="5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36" etag="yaGJlwZQux8Q-9mWfGid" version="14.5.3" type="device"><diagram id="w6dHBhk2DzmvdH_unnzh" name="Page-1">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</diagram></mxfile> \ No newline at end of file diff --git a/docs/assets/imgs/understanding-bigbang/network-encryption-and-ingress-diagram.app.diagrams.net.png b/docs/assets/imgs/understanding-bigbang/network-encryption-and-ingress-diagram.app.diagrams.net.png new file mode 100644 index 0000000000000000000000000000000000000000..01acd3924a036855fd8d231dee7634a8342045c8 Binary files /dev/null and b/docs/assets/imgs/understanding-bigbang/network-encryption-and-ingress-diagram.app.diagrams.net.png differ diff --git a/docs/assets/imgs/understanding-bigbang/network-encryption-and-ingress-diagram.app.diagrams.net.xml b/docs/assets/imgs/understanding-bigbang/network-encryption-and-ingress-diagram.app.diagrams.net.xml new file mode 100644 index 0000000000000000000000000000000000000000..2514c4b4972432f2aa1fe381b117960f59c1aff5 --- /dev/null +++ b/docs/assets/imgs/understanding-bigbang/network-encryption-and-ingress-diagram.app.diagrams.net.xml @@ -0,0 +1 @@ +<mxfile host="app.diagrams.net" modified="2021-06-07T15:27:58.885Z" agent="5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.77 Safari/537.36" etag="Bb40DoR4N_jHFy3m_1Ff" version="14.7.2" type="device"><diagram id="g1U51R3u2F-uOywQiJtT" name="Page-1">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</diagram></mxfile> \ No newline at end of file diff --git a/docs/assets/scripts/airgap-dev/airgap.sh b/docs/assets/scripts/airgap-dev/airgap.sh new file mode 100644 index 0000000000000000000000000000000000000000..312b7271954cecd29c80cde2ba5bb155a0c88641 --- /dev/null +++ b/docs/assets/scripts/airgap-dev/airgap.sh @@ -0,0 +1,7 @@ +#!/bin/sh + +PUBLICINTERFACE=$( route | grep '^default' | grep -o '[^ ]*$' ) +iptables -I DOCKER-USER -i ${PUBLICINTERFACE} -j DROP +iptables -I DOCKER-USER -d 10.42.0.0/16 -j RETURN +iptables -I DOCKER-USER -d 10.43.0.0/16 -j RETURN +iptables -A DOCKER-USER -j RETURN \ No newline at end of file diff --git a/docs/assets/scripts/airgap-dev/config.toml.tmpl b/docs/assets/scripts/airgap-dev/config.toml.tmpl new file mode 100644 index 0000000000000000000000000000000000000000..70c5a462e89693ec49fe21d4d021aba2e409825b --- /dev/null +++ b/docs/assets/scripts/airgap-dev/config.toml.tmpl @@ -0,0 +1,135 @@ +version = 2 +root = "/var/lib/containerd" +state = "/run/containerd" +plugin_dir = "" +disabled_plugins = [] +required_plugins = [] +oom_score = 0 + +[grpc] + address = "/run/containerd/containerd.sock" + tcp_address = "" + tcp_tls_cert = "" + tcp_tls_key = "" + uid = 0 + gid = 0 + max_recv_message_size = 16777216 + max_send_message_size = 16777216 + +[ttrpc] + address = "" + uid = 0 + gid = 0 + +[debug] + address = "" + uid = 0 + gid = 0 + level = "" + +[metrics] + address = "{{ansible_host}}:1338" + grpc_histogram = false + +[cgroup] + path = "" + +[timeouts] + "io.containerd.timeout.shim.cleanup" = "5s" + "io.containerd.timeout.shim.load" = "5s" + "io.containerd.timeout.shim.shutdown" = "3s" + "io.containerd.timeout.task.state" = "2s" + +[plugins] + [plugins."io.containerd.gc.v1.scheduler"] + pause_threshold = 0.02 + deletion_threshold = 0 + mutation_threshold = 100 + schedule_delay = "0s" + startup_delay = "100ms" + [plugins."io.containerd.grpc.v1.cri"] + disable_tcp_service = true + stream_server_address = "127.0.0.1" + stream_server_port = "0" + stream_idle_timeout = "4h0m0s" + enable_selinux = false + sandbox_image = "prodmicroservicesregistry.azurecr.io/k8s.gcr.io/pause:3.1" + stats_collect_period = 10 + systemd_cgroup = false + enable_tls_streaming = false + max_container_log_line_size = 16384 + disable_cgroup = false + disable_apparmor = false + restrict_oom_score_adj = false + max_concurrent_downloads = 3 + disable_proc_mount = false + [plugins."io.containerd.grpc.v1.cri".containerd] + snapshotter = "overlayfs" + default_runtime_name = "runc" + no_pivot = false + [plugins."io.containerd.grpc.v1.cri".containerd.default_runtime] + runtime_type = "" + runtime_engine = "" + runtime_root = "" + privileged_without_host_devices = false + [plugins."io.containerd.grpc.v1.cri".containerd.untrusted_workload_runtime] + runtime_type = "" + runtime_engine = "" + runtime_root = "" + privileged_without_host_devices = false + [plugins."io.containerd.grpc.v1.cri".containerd.runtimes] + [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc] + runtime_type = "io.containerd.runc.v1" + runtime_engine = "" + runtime_root = "" + privileged_without_host_devices = false + [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.nvidia-container-runtime] + runtime_type = "io.containerd.runc.v1" + [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.nvidia-container-runtime.options] + BinaryName = "/usr/bin/nvidia-container-runtime" + [plugins."io.containerd.grpc.v1.cri".cni] + bin_dir = "/opt/cni/bin" + conf_dir = "/etc/cni/net.d" + max_conf_num = 1 + conf_template = "" + [plugins."io.containerd.grpc.v1.cri".registry] + [plugins."io.containerd.grpc.v1.cri".registry.mirrors] + [plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.elastic.co"] + endpoint = ["{{ registry_endpoint }}"] + [plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"] + endpoint = ["{{ registry_endpoint }}","https://registry-1.docker.io"] + [plugins."io.containerd.grpc.v1.cri".registry.mirrors."gcr.io"] + endpoint = ["{{ registry_endpoint }}"] + [plugins."io.containerd.grpc.v1.cri".registry.mirrors."quay.io"] + endpoint = ["{{ registry_endpoint }}"] + [plugins."io.containerd.grpc.v1.cri".registry.configs] + [plugins."io.containerd.grpc.v1.cri".registry.configs."{{registry_server}}".auth] + username = "{{ registry_user }}" + password = "{{ registry_password }}" + auth = "" + identitytoken = "" + [plugins."io.containerd.grpc.v1.cri".x509_key_pair_streaming] + tls_cert_file = "" + tls_key_file = "" + [plugins."io.containerd.internal.v1.opt"] + path = "/opt/containerd" + [plugins."io.containerd.internal.v1.restart"] + interval = "10s" + [plugins."io.containerd.metadata.v1.bolt"] + content_sharing_policy = "shared" + [plugins."io.containerd.monitor.v1.cgroups"] + no_prometheus = false + [plugins."io.containerd.runtime.v1.linux"] + shim = "containerd-shim" + runtime = "runc" + runtime_root = "" + no_shim = false + shim_debug = false + [plugins."io.containerd.runtime.v2.task"] + platforms = ["linux/amd64"] + [plugins."io.containerd.service.v1.diff-service"] + default = ["walking"] + [plugins."io.containerd.snapshotter.v1.devmapper"] + root_path = "" + pool_name = "" + base_image_size = "" diff --git a/docs/assets/scripts/airgap-dev/copy-containerd-config.yaml b/docs/assets/scripts/airgap-dev/copy-containerd-config.yaml new file mode 100644 index 0000000000000000000000000000000000000000..3cfb58b81123e17ad2673629e6459bb4f8be21be --- /dev/null +++ b/docs/assets/scripts/airgap-dev/copy-containerd-config.yaml @@ -0,0 +1,23 @@ +--- +- hosts: all + gather_facts: no + become: yes + vars: + registry_endpoint: http://localregistry/v2/ + registry_server: localregistry + registry_user: someuser + vars_prompt: + - name: registry_password + prompt: Enter registry password + private: yes + tasks: + - name: Copy containerd config + template: + src: config.toml.tmpl + dest: /etc/containerd/config.toml + owner: root + group: root + - name: Restart containerd + service: + name: containerd + state: restarted \ No newline at end of file diff --git a/docs/assets/scripts/airgap-dev/deploy-images.sh b/docs/assets/scripts/airgap-dev/deploy-images.sh new file mode 100644 index 0000000000000000000000000000000000000000..181386e4aea62d621022b7f3c9d64d448775b43d --- /dev/null +++ b/docs/assets/scripts/airgap-dev/deploy-images.sh @@ -0,0 +1,30 @@ +#!/usr/bin/env bash + +set -e +trap 'echo exit at ${0}:${LINENO}, command was: ${BASH_COMMAND} 1>&2' ERR + +REGISTRY_PACKAGE_IMAGE="registry:package" +REGISTRY_PACKAGE_TGZ="${REGISTRY_PACKAGE_IMAGE}.tar.gz" + +function purge_registry_containers { + echo "Stopping local registry containers" + docker stop registry &>/dev/null || true + docker rm registry &>/dev/null || true +} + +function purge_registry_images { + echo "Removing local registry images" + docker image rm ${REGISTRY_PACKAGE_IMAGE} &>/dev/null || true +} + +purge_registry_containers +purge_registry_images + +echo "Loading local registry package tgz" +docker load < ${REGISTRY_PACKAGE_TGZ} + +echo "Creating package registry container" +docker run -d -p 5000:5000 --name registry ${REGISTRY_PACKAGE_IMAGE} >/dev/null + +echo "Showing package container registry catalog" +sleep 1; curl -sX GET http://localhost:5000/v2/_catalog \ No newline at end of file diff --git a/docs/assets/scripts/airgap-dev/images.txt b/docs/assets/scripts/airgap-dev/images.txt new file mode 100644 index 0000000000000000000000000000000000000000..3b9946a4e298916669a83e5f4aa0f01435950173 --- /dev/null +++ b/docs/assets/scripts/airgap-dev/images.txt @@ -0,0 +1,4 @@ +docker.io/library/busybox:1.32 +docker.io/rancher/coredns-coredns:1.8.0 +docker.io/rancher/klipper-lb:v0.1.2 +docker.io/rancher/library-busybox:1.31.1 diff --git a/docs/assets/scripts/airgap-dev/package-images.sh b/docs/assets/scripts/airgap-dev/package-images.sh new file mode 100644 index 0000000000000000000000000000000000000000..a792acc82fe176897631815b0042e884b27072ef --- /dev/null +++ b/docs/assets/scripts/airgap-dev/package-images.sh @@ -0,0 +1,90 @@ +#!/usr/bin/env bash + +set -e +trap 'echo exit at ${0}:${LINENO}, command was: ${BASH_COMMAND} 1>&2' ERR + +IMAGES_TXT="images.txt" +REGISTRY_IMAGE="registry:2" +REGISTRY_PACKAGE_IMAGE="registry:package" +REGISTRY_PACKAGE_TGZ="${REGISTRY_PACKAGE_IMAGE}.tar.gz" + +# $1 = image_original - original full image url from existing repository +function get_image_sections { + image_full=$(echo ${1} | sed -n 's/^.*\/\(.*:.*\)$/\1/p') + image_base=$(echo ${image_full} | sed -n 's/\(^.*\):\(.*$\)/\1/p') + image_tag=$(echo ${image_full} | sed -n 's/\(^.*\):\(.*$\)/\2/p') + # [ -z "${image_full}" ] && { echo "Error: Unable to set image full variable"; exit 1; } + # [ -z "${image_base}" ] && { echo "Error: Unable to set image base variable"; exit 1; } + # [ -z "${image_tag}" ] && { echo "Error: Unable to set image tag variable"; exit 1; } +} + +# $1 = image_base - image name and tag (nginx:latest) +# $1 = image_tag - image tag only (latest) +function verify_catalog_image { + echo "Verifying \"${1}\" exists in registry catalog with tag \"${2}\"" + reg_tag=$(curl -sX GET http://localhost:5000/v2/${1}/tags/list | jq -r '.tags | .[0]') + if [ "${2}" != "${reg_tag}" ]; then + echo "Error: Unable to verify ${1} exists in catalog" + exit 1 + fi +} + +function purge_registry_containers { + echo "Stopping local registry containers" + docker stop registry &>/dev/null || true + docker rm registry &>/dev/null || true +} + +function purge_registry_images { + echo "Removing local registry images" + docker image rm ${REGISTRY_IMAGE} &>/dev/null || true + docker image rm ${REGISTRY_PACKAGE_IMAGE} &>/dev/null || true +} + +echo "Removing local registry package tgz" +rm -rf ${REGISTRY_PACKAGE_TGZ} + +purge_registry_containers +purge_registry_images + +echo "Creating initial registry container" +docker run -d -p 5000:5000 --name registry ${REGISTRY_IMAGE} &>/dev/null + +echo "--" +for image_original in $(sed '/^$/d' ${IMAGES_TXT}); do + get_image_sections ${image_original} + echo "Referencing \"${image_original}\"" + echo "Uploading to registry as \"${image_base}\" with tag \"${image_tag}\"" + docker pull ${image_original} >/dev/null + docker tag ${image_original} localhost:5000/${image_full} >/dev/null + docker push localhost:5000/${image_full} >/dev/null + verify_catalog_image ${image_base} ${image_tag} + echo "--" +done + +# TODO - is a pass-through proxy needed? - https://docs.docker.com/registry/recipes/mirror/ +echo "Creating persistent package inside registry container" +docker cp registry-config.yml registry:/etc/docker/registry/config.yml >/dev/null +docker exec -it registry cp -r /var/lib/registry/ /var/lib/registry-package >/dev/null + +echo "Commiting initial registry image to package registry image" +docker commit registry ${REGISTRY_PACKAGE_IMAGE} >/dev/null + +purge_registry_containers + +echo "Creating package registry container" +docker run -d -p 5000:5000 --name registry ${REGISTRY_PACKAGE_IMAGE} &>/dev/null + +echo "--" +for image_original in $(sed '/^$/d' ${IMAGES_TXT}); do + get_image_sections ${image_original} + verify_catalog_image ${image_base} ${image_tag} +done +echo "--" + +purge_registry_containers + +echo "Saving local registry package tgz" +docker save ${REGISTRY_PACKAGE_IMAGE} | gzip --stdout > ${REGISTRY_PACKAGE_TGZ} + +purge_registry_images \ No newline at end of file diff --git a/docs/assets/scripts/airgap-dev/package-repos.sh b/docs/assets/scripts/airgap-dev/package-repos.sh new file mode 100644 index 0000000000000000000000000000000000000000..c7cad843276286c52db04c77d8ad4280940eddf0 --- /dev/null +++ b/docs/assets/scripts/airgap-dev/package-repos.sh @@ -0,0 +1,14 @@ +#!/usr/bin/env bash + +set -x + +GITEA_IMAGE="gitea/gitea:1.13.2" + +GITEA_HTTP_METHOD="http" +GITEA_URL="localhost:3000" +GITEA_USERNAME="admin" +GITEA_PASSWORD="password" + +curl -X POST "${GITEA_HTTP_METHOD}://${GITEA_USERNAME}:${GITEA_PASSWORD}@${GITEA_URL}/api/v1/user/repos" -H "accept: application/json" -H "content-type: application/json" -d \ + "{\"name\":\"test-repo\", \"description\": \"Sample description\" }" + \ No newline at end of file diff --git a/docs/assets/scripts/airgap-dev/registry-config.yaml b/docs/assets/scripts/airgap-dev/registry-config.yaml new file mode 100644 index 0000000000000000000000000000000000000000..b0e651bba25650d83d5d76958ae2d2e818186370 --- /dev/null +++ b/docs/assets/scripts/airgap-dev/registry-config.yaml @@ -0,0 +1,18 @@ +version: 0.1 +log: + fields: + service: registry +storage: + cache: + blobdescriptor: inmemory + filesystem: + rootdirectory: /var/lib/registry-package +http: + addr: :5000 + headers: + X-Content-Type-Options: [nosniff] +health: + storagedriver: + enabled: true + interval: 10s + threshold: 3 \ No newline at end of file diff --git a/docs/assets/scripts/airgap-dev/registry.sh b/docs/assets/scripts/airgap-dev/registry.sh new file mode 100644 index 0000000000000000000000000000000000000000..c69864cf6244f321ed0ce40ea0c3e7c8cef0ff62 --- /dev/null +++ b/docs/assets/scripts/airgap-dev/registry.sh @@ -0,0 +1,108 @@ +#!/usr/bin/env bash +set -e +trap 'echo exit at ${0}:${LINENO}, command was: ${BASH_COMMAND} 1>&2' ERR + +# Installs/Configures: +# - Docker Registy Container with self-signed cert +# +# Tested on Ubuntu 14.04.1 + +# Must be executed with elevated privilages +if [ "$(id -u)" != "0" ]; then + printf "This script must be ran as root or sudo!\n" + exit 1 +fi + +# prompt helper function +function prompt () { + if [ -z ${!1} ]; then + local response="" + while [[ ${response} = "" ]]; do + read -p "$2: " response + done + eval $1=${response} + fi +} + +# collect required information +# - C Country +# - ST State +# - L Location +# - O Organization +# - OU Organizational Unit +# - CN Common Name +echo -e "\nRequired information:" +prompt BITS "Enter bit size for certs (Ex. 4096)" +prompt DAYS "Enter number of days to sign the certs with (Ex. 3650)" +prompt COUNTRY "Enter the 'Country' for the cert (Ex. US)" +prompt STATE "Enter the 'State' for the cert (Ex. CO)" +prompt LOCATION "Enter the 'Location' for the cert (Ex. ColoradoSprings)" +prompt ORGANIZATION "Enter the 'Organization' for the cert (Ex. PlatformOne)" +prompt OUNIT "Enter the 'Organizational Unit' for the cert (Ex. Bigbang)" +prompt COMMON "Enter the 'Common Name' for the cert (Must be a FQDN (at least one period character) E.g. host.k3d.internal" +prompt ALTNAMES "Enter the 'Subject Alternative Names' for the cert E.g. DNS:host.k3d.internal,IP:PRIVATEIP)" + +# ... Certs ... +# ~~~~~~~~~~~~~ + +# ... prep certs ... + +echo -e "\nGenerating certs ..." +mkdir -p certs +cd certs +# Generate a root key +openssl genrsa -out rootCA.key ${BITS} + +# Generate a root certificate +openssl req -x509 -new -nodes -key rootCA.key -days ${DAYS}\ + -subj "/C=${COUNTRY}/ST=${STATE}/L=${LOCATION}/O=${ORGANIZATION}/CN=${COMMON}" \ + -out rootCA.crt + +# Generate key for host +openssl genrsa -out ${COMMON}.key ${BITS} + +# Generate CSR +openssl req -new -key ${COMMON}.key \ + -subj "/C=${COUNTRY}/ST=${STATE}/L=${LOCATION}/O=${ORGANIZATION}/CN=${COMMON}" \ + -out ${COMMON}.csr + +# Sign certificate request +echo subjectAltName = DNS:${COMMON},${ALTNAMES} > extfile.cnf +openssl x509 -req -in ${COMMON}.csr -CA rootCA.crt -CAkey rootCA.key -CAcreateserial -days ${DAYS} \ +-out ${COMMON}.crt -extfile extfile.cnf + + +openssl rsa -in ${COMMON}.key -text > ${COMMON}.private.pem +openssl x509 -inform PEM -in ${COMMON}.crt > ${COMMON}.public.pem + +mkdir -p /certs/${COMMON} +cp rootCA.crt /certs/${COMMON}/ca.crt + + +# ... launch registry ... +# ~~~~~~~~~~~~~~~~~~~~~~~ + +echo -e "\nLaunching our private registry ..." +cd .. +docker run -d -p 5443:5000 --restart=always --name bigbang_registry \ + -v `pwd`/certs:/certs \ + -v `pwd`/var/lib/registry:/var/lib/registry \ + -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/${COMMON}.crt \ + -e REGISTRY_HTTP_TLS_KEY=/certs/${COMMON}.key \ + registry:2 + + +# Instructions +echo -e "\nInstallation finished ... + +Notes +===== + +To see images in the registry; + +========================= +For example, + curl https://host.k3d.internal:5443/v2/_catalog -k +========================= + +" \ No newline at end of file diff --git a/docs/assets/scripts/airgap-dev/values.yaml b/docs/assets/scripts/airgap-dev/values.yaml new file mode 100644 index 0000000000000000000000000000000000000000..01107d00dd96f01699b97b4fa324992f61720435 --- /dev/null +++ b/docs/assets/scripts/airgap-dev/values.yaml @@ -0,0 +1,125 @@ +# -- Domain used for BigBang created exposed services, can be overridden by individual packages. +hostname: bigbang.dev +registryCredentials: + registry: host.k3d.internal + username: "" + password: "" + email: "" +git: + # -- Existing secret to use for git credentials, must be in the appropriate format: https://toolkit.fluxcd.io/components/source/gitrepositories/#https-authentication + existingSecret: "ssh-credentials" + +flux: + interval: 1m + rollback: + cleanupOnFail: false + + +eckOperator: + enabled: true + git: + repo: ssh://git@host.k3d.internal/home/git/repos/eck-operator + +fluentbit: + enabled: true + git: + repo: ssh://git@host.k3d.internal/home/git/repos/fluentbit +elasticsearchKibana: + enabled: true + git: + repo: ssh://git@host.k3d.internal/home/git/repos/elasticsearch-kibana + +istio: + enabled: true + git: + repo: ssh://git@host.k3d.internal/home/git/repos/istio-controlplane + +istioOperator: + enabled: true + git: + repo: ssh://git@host.k3d.internal/home/git/repos/istio-operator + +clusterAuditor: + enabled: true + git: + repo: ssh://git@host.k3d.internal/home/git/repos/cluster-auditor + values: + resources: + requests: + cpu: 100m + memory: 0.5Gi + +monitoring: + enabled: true + git: + repo: ssh://git@host.k3d.internal/home/git/repos/monitoring + +gatekeeper: + enabled: true + git: + repo: ssh://git@host.k3d.internal/home/git/repos/policy + +twistlock: + enabled: true + git: + repo: ssh://git@host.k3d.internal/home/git/repos/twistlock + +# Explicitly enable all addons for CI +addons: + argocd: + enabled: false + git: + repo: ssh://git@host.k3d.internal/home/git/repos/argocd + authservice: + enabled: false + git: + repo: ssh://git@host.k3d.internal/home/git/repos/authservice + chains: + minimal: + callback_uri: "https://minimal.bigbang.dev" + gitlab: + enabled: false + git: + repo: ssh://git@host.k3d.internal/home/git/repos/gitlab + sso: + enabled: false + gitlabRunner: + enabled: false + git: + repo: ssh://git@host.k3d.internal/home/git/repos/gitlab-runner + anchore: + enabled: false + git: + repo: ssh://git@host.k3d.internal/home/git/repos/anchore-enterprise + sonarqube: + enabled: true + git: + repo: ssh://git@host.k3d.internal/home/git/repos/sonarqube + minioOperator: + enabled: false + git: + repo: ssh://git@host.k3d.internal/home/git/repos/minio-operator + minio: + enabled: false + git: + repo: ssh://git@host.k3d.internal/home/git/repos/minio + haproxy: + enabled: false + git: + repo: ssh://git@host.k3d.internal/home/git/repos/haproxy + mattermostOperator: + enabled: false + git: + repo: ssh://git@host.k3d.internal/home/git/repos/mattermost-operator + mattermost: + enabled: false + git: + repo: ssh://git@host.k3d.internal/home/git/repos/mattermost + keycloak: + enabled: false + git: + repo: ssh://git@host.k3d.internal/home/git/repos/keycloak + nexusRepositoryManager: + enabled: false + git: + repo: ssh://git@host.k3d.internal/home/git/repos/nexus diff --git a/docs/assets/scripts/airgap-zarf/zarf-dev.sh b/docs/assets/scripts/airgap-zarf/zarf-dev.sh new file mode 100755 index 0000000000000000000000000000000000000000..acf4a0299b216d9925532afbf5a111fcf072111a --- /dev/null +++ b/docs/assets/scripts/airgap-zarf/zarf-dev.sh @@ -0,0 +1,45 @@ +#!/usr/bin/env bash + +ZARF_VERSION=v0.26.1 +BIGBANG_VERSION=2.0.0 + +# Choices: warn, info, debug, trace +# Currently set only for zarf package deploy +ZARF_LOG_LEVEL=${ZARF_LOG_LEVEL:=info} + +# Prerequisites: REGISTRY1_USERNAME and REGISTRY1_PASSWORD must be exported locally. +# Configurable: ZARF_TEST_REPO, ZARF_TEST_REPO_BRANCH, ZARF_TEST_REPO_DIRECTORY all define where to pick up the zarf.yaml file. +# Example with configuration: ZARF_TEST_REPO=https://repo1.dso.mil/some-repo.git ZARF_TEST_REPO_BRANCH=development docs/assets/scripts/airgap-zarf/zarf-dev.sh + +AWSUSERNAME=${AWSUSERNAME:=`aws sts get-caller-identity --query Arn --output text | cut -f 2 -d '/'`} +echo "Username: $AWSUSERNAME" +KeyName=${AWSUSERNAME}-dev +PublicIP=`aws ec2 describe-instances --output text \ + --query "Reservations[].Instances[].PublicIpAddress" \ + --filters "Name=tag:Name,Values=${AWSUSERNAME}-dev" "Name=instance-state-name,Values=running"` +echo "Public IP: ${PublicIP}" + +ZARF_TEST_REPO=${ZARF_TEST_REPO:=https://github.com/defenseunicorns/zarf} +ZARF_TEST_REPO_BRANCH=${ZARF_TEST_REPO_BRANCH:=$ZARF_VERSION} +ZARF_TEST_REPO_DIRECTORY=${ZARF_TEST_REPO_DIRECTORY:=zarf/examples/big-bang} + +function run() { + ssh -i ~/.ssh/${KeyName}.pem -o StrictHostKeyChecking=no -o IdentitiesOnly=yes ubuntu@${PublicIP} $1 +} + +# install zarf +echo "Installing Zarf ${ZARF_VERSION}"... +run "curl -LO https://github.com/defenseunicorns/zarf/releases/download/${ZARF_VERSION}/zarf_${ZARF_VERSION}_Linux_amd64" +run "sudo mv /home/ubuntu/zarf_${ZARF_VERSION}_Linux_amd64 /usr/local/bin/zarf" +run "sudo chmod +x /usr/local/bin/zarf" + +# get zarf init package +echo "Retrieving zarf init package..." +run "wget -q https://github.com/defenseunicorns/zarf/releases/download/${ZARF_VERSION}/zarf-init-amd64-${ZARF_VERSION}.tar.zst" + +# zarf init, package and deploy +run "set +o history && echo ${REGISTRY1_PASSWORD} | zarf tools registry login registry1.dso.mil --username ${REGISTRY1_USERNAME} --password-stdin || set -o history" +run "zarf init --components=git-server --confirm --log-level=${ZARF_LOG_LEVEL}" +run "git clone --depth 1 --single-branch --branch ${ZARF_TEST_REPO_BRANCH} ${ZARF_TEST_REPO}" +run "cd ${ZARF_TEST_REPO_DIRECTORY} && zarf package create --confirm --max-package-size=0" +run "cd ${ZARF_TEST_REPO_DIRECTORY} && zarf package deploy zarf-package-big-bang-example-amd64-${BIGBANG_VERSION}.tar.zst --confirm --components=gitea-virtual-service --log-level=${ZARF_LOG_LEVEL}" diff --git a/docs/assets/scripts/developer/aws-mfa.sh b/docs/assets/scripts/developer/aws-mfa.sh new file mode 100644 index 0000000000000000000000000000000000000000..6edff68268b2bcc13f4161be546004be0bb6d940 --- /dev/null +++ b/docs/assets/scripts/developer/aws-mfa.sh @@ -0,0 +1,48 @@ +#!/bin/bash +################################################################################## +# This MFA authentication script will add temporary access keys to your credentials file plus an additional AWS Session Token which is valid for a maximum of 12 hours. +# Pass parameters in like so... temporary profile must already exist with region configured in your CLI profile. See example in docs. +# bash aws-mfa.sh --user <username> --profile <temporary profile> --token <token-code> +# You can hard code your username after the - on line 9 +# profile_long variable is your long term access keys + +user=${user:-} +profile=${profile:-default} +profile_long=bigbang +token=${token:-} +serial="arn:aws-us-gov:iam::141078740716:mfa/${user}" + +echo "If having issues with this script please see example ~/.aws/credentials file for setup @ https://repo1.dso.mil/big-bang/bigbang/-/blob/add-aws-mfa-scripting-to-k3d-dev/docs/assets/scripts/developer/mfa-aws-creds-example" + +while [ $# -gt 0 ]; do + if [[ $1 == *"--"* ]]; then + param="${1/--/}" + declare $param="$2" + # echo $1 $2 # Optional to see the parameter:value result + fi + shift +done + +if [ ${#token} -ne 6 ]; then + echo "Please provide a six digit token code with --token <token-code>" + exit 1 +fi + +echo "user: $user" +echo "profile: $profile" +echo "profile-long-term: $profile_long" +echo "token: $token" +echo "serial: $serial" + +################################################################################## +# Remove existing environment variable values +unset AWS_ACCESS_KEY_ID +unset AWS_SECRET_ACCESS_KEY +unset AWS_SESSION_TOKEN + +# Get temporary MFA credentials +creds=$(aws sts get-session-token --token-code $token --profile $profile_long --serial-number $serial --query 'Credentials') +aws configure set aws_access_key_id $(echo $creds | python3 -c "import sys, json; print(json.load(sys.stdin)['AccessKeyId'])") --profile=$profile +aws configure set aws_secret_access_key $(echo $creds | python3 -c "import sys, json; print(json.load(sys.stdin)['SecretAccessKey'])") --profile=$profile +aws configure set aws_session_token $(echo $creds | python3 -c "import sys, json; print(json.load(sys.stdin)['SessionToken'])") --profile=$profile +aws sts get-caller-identity --profile $profile diff --git a/docs/assets/scripts/developer/k3d-dev.sh b/docs/assets/scripts/developer/k3d-dev.sh new file mode 100755 index 0000000000000000000000000000000000000000..528be6b511433e35c838074436edc555fd80ac9e --- /dev/null +++ b/docs/assets/scripts/developer/k3d-dev.sh @@ -0,0 +1,970 @@ +#!/bin/bash + +K3D_VERSION="5.7.3" +DEFAULT_K3S_TAG="v1.31.4-k3s1" + +# get the current script dir +SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) + +function run() { + ssh -i ~/.ssh/${KeyName}.pem -o StrictHostKeyChecking=no -o IdentitiesOnly=yes ubuntu@${PublicIP} "$@" +} + +function runwithexitcode() { + ssh -i ~/.ssh/${KeyName}.pem -o StrictHostKeyChecking=no -o IdentitiesOnly=yes ubuntu@${PublicIP} "$@" + exitcode=$? + [ $exitcode -eq 0 ] +} + +function runwithreturn() { + echo $(ssh -i ~/.ssh/${KeyName}.pem -o StrictHostKeyChecking=no -o IdentitiesOnly=yes ubuntu@${PublicIP} "$@") +} + +function getPrivateIP2() { + echo `aws ec2 describe-instances --output json --no-cli-pager --instance-ids ${InstId} | jq -r '.Reservations[0].Instances[0].NetworkInterfaces[0].PrivateIpAddresses[] | select(.Primary==false) | .PrivateIpAddress'` +} + +function getDefaultAmi() { + local partition + local ubuntu_account_id + local image_id + # extract partition from the ARN + partition=$(aws sts get-caller-identity --query 'Arn' --output text | awk -F ":" '{print $2}') + # Select the correct AWS Account ID for Ubuntu Server AMI based on the partition + if [[ "${partition}" == "aws-us-gov" ]]; then + ubuntu_account_id="513442679011" + elif [[ "${partition}" == "aws" ]]; then + ubuntu_account_id="099720109477" + else + echo "Unrecognized AWS partition" + exit 1 + fi + # Filter on latest 22.04 jammy server + image_id=$(aws ec2 describe-images \ + --owners ${ubuntu_account_id} \ + --filters 'Name=name,Values=ubuntu/images/hvm-ssd/ubuntu-jammy-22.04-amd64-server-*' \ + --query 'sort_by(Images,&CreationDate)[-1].ImageId' \ + --output text) + + if [ $? -ne 0 ] || [ "${image_id}" == "None" ]; then + echo "Error getting AMI ID" + exit 1 + fi + echo "${image_id}" +} + +function update_ec2_security_group +{ + # Look up the security group created to get the ID + echo -n Retrieving ID for security group ${SGname} ... + #### SecurityGroupId=$(aws ec2 describe-security-groups --output json --no-cli-pager --group-names ${SGname} --query "SecurityGroups[0].GroupId" --output text) + SecurityGroupId=$(aws ec2 describe-security-groups --filter Name=vpc-id,Values=$VPC_ID Name=group-name,Values=$SGname --query 'SecurityGroups[*].[GroupId]' --output text) + echo done + + # Add name tag to security group + aws ec2 create-tags --resources ${SecurityGroupId} --tags Key=Name,Value=${SGname} &> /dev/null + aws ec2 create-tags --resources ${SecurityGroupId} --tags Key=Project,Value=${PROJECTTAG} &> /dev/null + + # Add rule for IP based filtering + WorkstationIP=`curl http://checkip.amazonaws.com/ 2> /dev/null` + echo -n Checking if ${WorkstationIP} is authorized in security group ... + #### aws ec2 describe-security-groups --output json --no-cli-pager --group-names ${SGname} | grep ${WorkstationIP} > /dev/null || ipauth=missing + aws ec2 describe-security-groups --filter Name=vpc-id,Values=$VPC_ID Name=group-name,Values=$SGname | grep ${WorkstationIP} > /dev/null || ipauth=missing + if [ "${ipauth}" == "missing" ]; then + echo -e "missing\nAdding ${WorkstationIP} to security group ${SGname} ..." + if [[ "$PRIVATE_IP" == true ]]; + then + #### aws ec2 authorize-security-group-ingress --output json --no-cli-pager --group-name ${SGname} --protocol tcp --port 22 --cidr ${WorkstationIP}/32 + #### aws ec2 authorize-security-group-ingress --output json --no-cli-pager --group-name ${SGname} --protocol tcp --port 6443 --cidr ${WorkstationIP}/32 + aws ec2 authorize-security-group-ingress --output json --no-cli-pager --group-id ${SecurityGroupId} --protocol tcp --port 22 --cidr ${WorkstationIP}/32 + aws ec2 authorize-security-group-ingress --output json --no-cli-pager --group-id ${SecurityGroupId} --protocol tcp --port 6443 --cidr ${WorkstationIP}/32 + else # all protocols to all ports is the default + #### aws ec2 authorize-security-group-ingress --output json --no-cli-pager --group-name ${SGname} --protocol all --cidr ${WorkstationIP}/32 + aws ec2 authorize-security-group-ingress --output json --no-cli-pager --group-id ${SecurityGroupId} --protocol all --cidr ${WorkstationIP}/32 + fi + echo done + else + echo found + fi +} + +function destroy_instances +{ + AWSINSTANCEIDs=$( aws ec2 describe-instances \ + --output text \ + --query "Reservations[].Instances[].InstanceId" \ + --filters "Name=tag:Name,Values=${AWSUSERNAME}-dev" "Name=tag:Project,Values=${PROJECTTAG}" "Name=instance-state-name,Values=running" ) + # If instance exists then terminate it + if [[ $AWSINSTANCEIDs ]]; then + echo "aws instances being terminated: ${AWSINSTANCEIDs}" + + read -p "Are you sure you want to delete these instances (y/n)? " -r + if [[ ! $REPLY =~ ^[Yy]$ ]] + then + echo + exit 1 + fi + + aws ec2 terminate-instances --instance-ids ${AWSINSTANCEIDs} &>/dev/null + echo -n "Waiting for instance termination..." + aws ec2 wait instance-terminated --instance-ids ${AWSINSTANCEIDs} &> /dev/null + echo "done" + else + echo "You had no running instances." + fi + echo "SecurityGroup name to be deleted: ${SGname}" + aws ec2 delete-security-group --group-name=${SGname} &> /dev/null + echo "KeyPair to be deleted: ${KeyName}" + aws ec2 delete-key-pair --key-name ${KeyName}-${PROJECT} &> /dev/null + ALLOCATIONIDs=(`aws ec2 describe-addresses --output text --filters "Name=tag:Owner,Values=${AWSUSERNAME}" "Name=tag:Project,Values=${PROJECTTAG}" --query "Addresses[].AllocationId"`) + for i in "${ALLOCATIONIDs[@]}" + do + echo -n "Releasing Elastic IP $i ..." + aws ec2 release-address --allocation-id $i + echo "done" + done + exit 0 +} + +function update_instances +{ + update_ec2_security_group +} + + +function create_instances +{ + echo "Checking for existing cluster for ${AWSUSERNAME}." + InstId=`aws ec2 describe-instances \ + --output text \ + --query "Reservations[].Instances[].InstanceId" \ + --filters "Name=tag:Name,Values=${AWSUSERNAME}-dev" "Name=tag:Project,Values=${PROJECTTAG}" "Name=instance-state-name,Values=running"` + if [[ $InstId ]]; then + PublicIP=`aws ec2 describe-instances --output text --no-cli-pager --instance-id ${InstId} --query "Reservations[].Instances[].PublicIpAddress"` + PrivateIP=`aws ec2 describe-instances --output json --no-cli-pager --instance-ids ${InstId} | jq -r '.Reservations[0].Instances[0].PrivateIpAddress'` + echo "Existing cluster found running on instance ${InstId} on ${PublicIP} / ${PrivateIP}" + echo "💣 Big Bang Cluster Management 💣" + PS3="Please select an option: " + options=("Re-create K3D cluster" "Recreate the EC2 instance from scratch" "Quit") + + select opt in "${options[@]}" + do + case $REPLY in + 1) + read -p "Are you sure you want to re-create a K3D cluster on this instance (y/n)? " -r + if [[ ! $REPLY =~ ^[Yy]$ ]] + then + echo + exit 1 + fi + RESET_K3D=true + SecondaryIP=`aws ec2 describe-instances --output json --no-cli-pager --instance-ids ${InstId} | jq -r '.Reservations[0].Instances[0].NetworkInterfaces[0].PrivateIpAddresses[] | select(.Primary==false) | .Association.PublicIp'` + PrivateIP2=$(getPrivateIP2) + if [[ "${ATTACH_SECONDARY_IP}" == true && -z "${SecondaryIP}" ]]; then + echo "Secondary IP didn't exist at the time of creation of the instance, so cannot attach one without re-creating it with the -a flag selected." + exit 1 + fi + run "k3d cluster delete" + run "docker ps -aq | xargs docker stop | xargs docker rm" + break;; + 2) + read -p "Are you sure you want to destroy this instance ${InstId}, and create a new one in its place (y/n)? " -r + if [[ ! $REPLY =~ ^[Yy]$ ]] + then + echo + exit 1 + fi + + aws ec2 terminate-instances --instance-ids ${InstId} &>/dev/null + echo -n "Instance is being terminated..." + if [[ "${ATTACH_SECONDARY_IP}" == true ]]; then + echo -n "Waiting for instance termination..." + aws ec2 wait instance-terminated --instance-ids ${InstId} &> /dev/null + echo "done" + fi + break;; + 3) + echo "Bye." + exit 0;; + *) + echo "Option $1 not recognized";; + esac + done + fi + + if [[ "${RESET_K3D}" == false ]]; then + if [[ "$BIG_INSTANCE" == true ]] + then + echo "Will use large m5a.4xlarge spot instance" + InstSize="m5a.4xlarge" + SpotPrice="0.69" + else + echo "Will use standard t3a.2xlarge spot instance" + InstSize="t3a.2xlarge" + SpotPrice="0.35" + fi + + + #### Cleaning up unused Elastic IPs + ALLOCATIONIDs=(`aws ec2 describe-addresses --filters "Name=tag:Owner,Values=${AWSUSERNAME}" "Name=tag:Project,Values=${PROJECTTAG}" --query "Addresses[?AssociationId==null]" | jq -r '.[].AllocationId'`) + for i in "${ALLOCATIONIDs[@]}" + do + echo -n "Releasing Elastic IP $i ..." + aws ec2 release-address --allocation-id $i + echo "done" + done + + #### SSH Key Pair + # Create SSH key if it doesn't exist + echo -n Checking if key pair ${KeyName} exists ... + aws ec2 describe-key-pairs --output json --no-cli-pager --key-names ${KeyName} > /dev/null 2>&1 || keypair=missing + if [ "${keypair}" == "missing" ]; then + echo -n -e "missing\nCreating key pair ${KeyName} ... " + aws ec2 create-key-pair --output json --no-cli-pager --key-name ${KeyName} | jq -r '.KeyMaterial' > ~/.ssh/${KeyName}.pem + chmod 600 ~/.ssh/${KeyName}.pem + echo done + else + echo found + fi + + + #### Security Group + # Create security group if it doesn't exist + echo -n "Checking if security group ${SGname} exists ..." + aws ec2 describe-security-groups --output json --no-cli-pager --group-names ${SGname} > /dev/null 2>&1 || secgrp=missing + if [ "${secgrp}" == "missing" ]; then + echo -e "missing\nCreating security group ${SGname} ... " + aws ec2 create-security-group --output json --no-cli-pager --description "IP based filtering for ${SGname}" --group-name ${SGname} --vpc-id ${VPC} + echo done + else + echo found + fi + + update_ec2_security_group + + ##### Launch Specification + # Typical settings for Big Bang development + InstanceType="${InstSize}" + VolumeSize=120 + + echo "Using AMI image id ${AMI_ID}" + ImageId="${AMI_ID}" + + # Create userdata.txt + tmpdir=$(mktemp -d) + cat << EOF > "$tmpdir/userdata.txt" +#!/usr/bin/env bash + +echo "* soft nofile 13181250" >> /etc/security/limits.d/ulimits.conf +echo "* hard nofile 13181250" >> /etc/security/limits.d/ulimits.conf +echo "* soft nproc 13181250" >> /etc/security/limits.d/ulimits.conf +echo "* hard nproc 13181250" >> /etc/security/limits.d/ulimits.conf + +echo "vm.max_map_count=524288" > /etc/sysctl.d/vm-max_map_count.conf +echo "fs.nr_open=13181252" > /etc/sysctl.d/fs-nr_open.conf +echo "fs.file-max=13181250" > /etc/sysctl.d/fs-file-max.conf +echo "fs.inotify.max_user_instances=1024" > /etc/sysctl.d/fs-inotify-max_user_instances.conf +echo "fs.inotify.max_user_watches=1048576" > /etc/sysctl.d/fs-inotify-max_user_watches.conf +echo "fs.may_detach_mounts=1" >> /etc/sysctl.d/fs-may_detach_mounts.conf + +sysctl --system + +echo "br_netfilter" >> /etc/modules-load.d/istio-iptables.conf +echo "nf_nat_redirect" >> /etc/modules-load.d/istio-iptables.conf +echo "xt_REDIRECT" >> /etc/modules-load.d/istio-iptables.conf +echo "xt_owner" >> /etc/modules-load.d/istio-iptables.conf +echo "xt_statistic" >> /etc/modules-load.d/istio-iptables.conf + +systemctl restart systemd-modules-load.service +EOF + + # Create the device mapping and spot options JSON files + echo "Creating device_mappings.json ..." + + # gp3 volumes are 20% cheaper than gp2 and comes with 3000 Iops baseline and 125 MiB/s baseline throughput for free. + cat << EOF > "$tmpdir/device_mappings.json" +[ + { + "DeviceName": "/dev/sda1", + "Ebs": { + "DeleteOnTermination": true, + "VolumeType": "gp3", + "VolumeSize": ${VolumeSize}, + "Encrypted": true + } + } +] +EOF + + echo "Creating spot_options.json ..." + cat << EOF > "$tmpdir/spot_options.json" + { + "MarketType": "spot", + "SpotOptions": { + "MaxPrice": "${SpotPrice}", + "SpotInstanceType": "one-time" + } + } +EOF + + #### Request a Spot Instance + # Location of your private SSH key created during setup + PEM=~/.ssh/${KeyName}.pem + + # Run a spot instance with our launch spec for the max. of 6 hours + # NOTE: t3a.2xlarge spot price is 0.35 m5a.4xlarge is 0.69 + echo "Running spot instance ..." + + if [[ "${ATTACH_SECONDARY_IP}" == true ]]; then + # If we are using a secondary IP, we don't want to assign public IPs at launch time. Instead, the script will attach both public IPs after the instance is launched. + additional_create_instance_options="--no-associate-public-ip-address --secondary-private-ip-address-count 1" + else + additional_create_instance_options="--associate-public-ip-address" + fi + + InstId=`aws ec2 run-instances \ + --output json --no-paginate \ + --count 1 --image-id "${ImageId}" \ + --instance-type "${InstanceType}" \ + --subnet-id "${SUBNET_ID}" \ + --key-name "${KeyName}" \ + --security-group-ids "${SecurityGroupId}" \ + --instance-initiated-shutdown-behavior "terminate" \ + --user-data "file://$tmpdir/userdata.txt" \ + --block-device-mappings "file://$tmpdir/device_mappings.json" \ + --instance-market-options "file://$tmpdir/spot_options.json" \ + ${additional_create_instance_options} \ + | jq -r '.Instances[0].InstanceId'` + + # Check if spot instance request was not created + if [ -z ${InstId} ]; then + exit 1; + fi + + # Add name tag to spot instance + aws ec2 create-tags --resources ${InstId} --tags Key=Name,Value=${AWSUSERNAME}-dev &> /dev/null + aws ec2 create-tags --resources ${InstId} --tags Key=Project,Value=${PROJECTTAG} &> /dev/null + + # Request was created, now you need to wait for it to be filled + echo "Waiting for instance ${InstId} to be ready ..." + aws ec2 wait instance-running --output json --no-cli-pager --instance-ids ${InstId} &> /dev/null + + # allow some extra seconds for the instance to be fully initialized + echo "Almost there, 15 seconds to go..." + sleep 15 + + ## IP Address Allocation and Attachment + CURRENT_EPOCH=`date +'%s'` + + # Get the private IP address of our instance + PrivateIP=`aws ec2 describe-instances --output json --no-cli-pager --instance-ids ${InstId} | jq -r '.Reservations[0].Instances[0].PrivateIpAddress'` + + # Use Elastic IPs if a Secondary IP is required, instead of the auto assigned one. + if [[ "${ATTACH_SECONDARY_IP}" == false ]]; then + PublicIP=`aws ec2 describe-instances --output json --no-cli-pager --instance-ids ${InstId} | jq -r '.Reservations[0].Instances[0].PublicIpAddress'` + else + echo "Checking to see if an Elastic IP is already allocated and not attached..." + PublicIP=`aws ec2 describe-addresses --filters "Name=tag:Name,Values=${AWSUSERNAME}-EIP1" "Name=tag:Project,Values=${PROJECTTAG}" --query 'Addresses[?AssociationId==null]' | jq -r '.[0].PublicIp // ""'` + if [[ -z "${PublicIP}" ]]; then + echo "Allocating a new/another primary elastic IP..." + PublicIP=`aws ec2 allocate-address --output json --no-cli-pager --tag-specifications="ResourceType=elastic-ip,Tags=[{Key=Name,Value=${AWSUSERNAME}-EIP1},{Key=Owner,Value=${AWSUSERNAME}}]" | jq -r '.PublicIp'` + else + echo "Previously allocated primary Elastic IP ${PublicIP} found." + fi + + echo -n "Associating IP ${PublicIP} address to instance ${InstId} ..." + EIP1_ASSOCIATION_ID=`aws ec2 associate-address --output json --no-cli-pager --instance-id ${InstId} --private-ip ${PrivateIP} --public-ip $PublicIP | jq -r '.AssociationId'` + echo "${EIP1_ASSOCIATION_ID}" + EIP1_ID=`aws ec2 describe-addresses --public-ips ${PublicIP} | jq -r '.Addresses[].AllocationId'` + aws ec2 create-tags --resources ${EIP1_ID} --tags Key="lastused",Value="${CURRENT_EPOCH}" + aws ec2 create-tags --resources ${EIP1_ID} --tags Key="Project",Value="${PROJECTTAG}" + + PrivateIP2=$(getPrivateIP2) + echo "Checking to see if a Secondary Elastic IP is already allocated and not attached..." + SecondaryIP=`aws ec2 describe-addresses --filters "Name=tag:Name,Values=${AWSUSERNAME}-EIP2" "Name=tag:Project,Values=${PROJECTTAG}" --query 'Addresses[?AssociationId==null]' | jq -r '.[0].PublicIp // ""'` + if [[ -z "${SecondaryIP}" ]]; then + echo "Allocating a new/another secondary elastic IP..." + SecondaryIP=`aws ec2 allocate-address --output json --no-cli-pager --tag-specifications="ResourceType=elastic-ip,Tags=[{Key=Name,Value=${AWSUSERNAME}-EIP2},{Key=Owner,Value=${AWSUSERNAME}}]" | jq -r '.PublicIp'` + else + echo "Previously allocated secondary Elastic IP ${SecondaryIP} found." + fi + echo -n "Associating Secondary IP ${SecondaryIP} address to instance ${InstId}..." + EIP2_ASSOCIATION_ID=`aws ec2 associate-address --output json --no-cli-pager --instance-id ${InstId} --private-ip ${PrivateIP2} --public-ip $SecondaryIP | jq -r '.AssociationId'` + echo "${EIP2_ASSOCIATION_ID}" + EIP2_ID=`aws ec2 describe-addresses --public-ips ${SecondaryIP} | jq -r '.Addresses[].AllocationId'` + aws ec2 create-tags --resources ${EIP2_ID} --tags Key="lastused",Value="${CURRENT_EPOCH}" + aws ec2 create-tags --resources ${EIP2_ID} --tags Key="Project",Value="${PROJECTTAG}" + echo "Secondary public IP is ${SecondaryIP}" + fi + + echo + echo "Instance ${InstId} is ready!" + echo "Instance Public IP is ${PublicIP}" + echo "Instance Private IP is ${PrivateIP}" + echo + + # Remove previous keys related to this IP from your SSH known hosts so you don't end up with a conflict + ssh-keygen -f "${HOME}/.ssh/known_hosts" -R "${PublicIP}" + + echo "ssh init" + # this is a do-nothing remote ssh command just to initialize ssh and make sure that the connection is working + until run "hostname"; do + sleep 5 + echo "Retry ssh command.." + done + echo + + ##### Configure Instance + ## TODO: replace these individual commands with userdata when the spot instance is created? + echo + echo + echo "starting instance config" + + echo "Instance will automatically terminate 8 hours from now unless you alter the root crontab" + run "sudo bash -c 'echo \"\$(date -u -d \"+8 hours\" +\"%M %H\") * * * /usr/sbin/shutdown -h now\" | crontab -'" + echo + + if [[ $APT_UPDATE = "true" ]]; then + echo + echo "updating packages" + run "sudo apt-get update && sudo apt-get upgrade -y" + fi + + echo + echo "installing docker" + # install dependencies + run "sudo apt-get install -y apt-transport-https ca-certificates curl gnupg lsb-release gnupg-agent software-properties-common" + # Add the Docker repository, we are installing from Docker and not the Ubuntu APT repo. + run 'sudo mkdir -m 0755 -p /etc/apt/keyrings' + run 'curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg' + run 'echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null' + run "sudo apt-get update && sudo apt-get -y install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin" + + echo + echo + # Add your base user to the Docker group so that you do not need sudo to run docker commands + run "sudo usermod -aG docker ubuntu" + echo + fi + + # install k3d on instance + echo "Installing k3d on instance" + run "curl -s https://raw.githubusercontent.com/k3d-io/k3d/main/install.sh | TAG=v${K3D_VERSION} bash" + echo + echo "k3d version" + run "k3d version" + echo + + echo "creating k3d cluster" + + # Shared k3d settings across all options + # 1 server, 3 agents + k3d_command="export K3D_FIX_MOUNTS=1; k3d cluster create --servers 1 --agents 3 --verbose" + # Volumes to support Twistlock defenders + k3d_command+=" -v /etc:/etc@server:*\;agent:* -v /dev/log:/dev/log@server:*\;agent:* -v /run/systemd/private:/run/systemd/private@server:*\;agent:*" + # Disable traefik and metrics-server + k3d_command+=" --k3s-arg \"--disable=traefik@server:0\" --k3s-arg \"--disable=metrics-server@server:0\"" + + # Port mappings to support Istio ingress + API access + if [[ -z "${PrivateIP2}" ]]; then + k3d_command+=" --port ${PrivateIP}:80:80@loadbalancer --port ${PrivateIP}:443:443@loadbalancer --api-port 6443" + fi + + # Selecting K8S version through the use of a K3S image tag + K3S_IMAGE_TAG=${K3S_IMAGE_TAG:="${DEFAULT_K3S_TAG}"} + if [[ $K3S_IMAGE_TAG ]]; then + echo "Using custom K3S image tag $K3S_IMAGE_TAG..." + k3d_command+=" --image docker.io/rancher/k3s:$K3S_IMAGE_TAG" + fi + + # create docker network for k3d cluster + echo "creating docker network for k3d cluster" + run "docker network remove k3d-network" + run "docker network create k3d-network --driver=bridge --subnet=172.20.0.0/16 --gateway 172.20.0.1" + k3d_command+=" --network k3d-network" + + # Add MetalLB specific k3d config + if [[ "$METAL_LB" == true || "$ATTACH_SECONDARY_IP" == true ]]; then + k3d_command+=" --k3s-arg \"--disable=servicelb@server:0\"" + fi + + # Add Public/Private IP specific k3d config + if [[ "$PRIVATE_IP" == true ]]; then + echo "using private ip for k3d" + k3d_command+=" --k3s-arg \"--tls-san=${PrivateIP}@server:0\"" + else + echo "using public ip for k3d" + k3d_command+=" --k3s-arg \"--tls-san=${PublicIP}@server:0\"" + fi + + # use weave instead of flannel -- helps with large installs + # we match the 172.x subnets used by CI for consistency + if [[ "$USE_WEAVE" == true ]]; then + + run "if [[ ! -f /opt/cni/bin/loopback ]]; then sudo mkdir -p /opt/cni/bin && sudo curl -s -L https://github.com/containernetworking/plugins/releases/download/v1.3.0/cni-plugins-linux-amd64-v1.3.0.tgz | sudo tar xvz -C /opt/cni/bin; fi" + + scp -i ~/.ssh/${KeyName}.pem -o StrictHostKeyChecking=no -o IdentitiesOnly=yes ${SCRIPT_DIR}/weave/* ubuntu@${PublicIP}:/tmp/ + + # network settings + k3d_command+=" --k3s-arg \"--flannel-backend=none@server:*\"" + k3d_command+=" --k3s-arg \"--disable-network-policy@server:*\"" + k3d_command+=" --k3s-arg \"--cluster-cidr=172.21.0.0/16@server:*\"" + k3d_command+=" --k3s-arg \"--service-cidr=172.20.0.0/16@server:*\"" + k3d_command+=" --k3s-arg \"--cluster-dns=172.20.0.10@server:*\"" + + # volume mounts + k3d_command+=" --volume \"/tmp/weave.yaml:/var/lib/rancher/k3s/server/manifests/weave.yaml@server:*\"" + k3d_command+=" --volume /tmp/machine-id-server-0:/etc/machine-id@server:0" + k3d_command+=" --volume /tmp/machine-id-agent-0:/etc/machine-id@agent:0" + k3d_command+=" --volume /tmp/machine-id-agent-1:/etc/machine-id@agent:1" + k3d_command+=" --volume /tmp/machine-id-agent-2:/etc/machine-id@agent:2" + k3d_command+=" --volume /opt/cni/bin:/opt/cni/bin@all:*" + fi + + # Create k3d cluster + echo "Creating k3d cluster with command: ${k3d_command}" + run "${k3d_command}" + + # install kubectl + echo Installing kubectl based on k8s version... + K3S_IMAGE_TAG=${K3S_IMAGE_TAG:="${DEFAULT_K3S_TAG}"} + if [[ $K3S_IMAGE_TAG ]]; then + KUBECTL_VERSION=$(echo $K3S_IMAGE_TAG | cut -d'-' -f1) + echo "Using specified kubectl version $KUBECTL_VERSION based on k3s image tag." + else + KUBECTL_VERSION=$(runwithreturn "k3d version -o json" | jq -r '.k3s' | cut -d'-' -f1) + echo "Using k3d default k8s version $KUBECTL_VERSION." + fi + KUBECTL_CHECKSUM=`curl -sL https://dl.k8s.io/${KUBECTL_VERSION}/bin/linux/amd64/kubectl.sha256` + run "curl -LO https://dl.k8s.io/release/${KUBECTL_VERSION}/bin/linux/amd64/kubectl" + runwithexitcode "echo ${KUBECTL_CHECKSUM} kubectl | sha256sum --check" && echo "Good checksum" || { echo "Bad checksum" ; exit 1; } + run 'sudo mv /home/ubuntu/kubectl /usr/local/bin/' + run 'sudo chmod +x /usr/local/bin/kubectl' + + run "kubectl config use-context k3d-k3s-default" + run "kubectl cluster-info && kubectl get nodes" + + echo "copying kubeconfig to workstation..." + mkdir -p ~/.kube + scp -i ~/.ssh/${KeyName}.pem -o StrictHostKeyChecking=no -o IdentitiesOnly=yes ubuntu@${PublicIP}:/home/ubuntu/.kube/config ~/.kube/${AWSUSERNAME}-dev-${PROJECTTAG}-config + if [[ "$PRIVATE_IP" == true ]]; then + $sed_gsed -i "s/0\.0\.0\.0/${PrivateIP}/g" ~/.kube/${AWSUSERNAME}-dev-${PROJECTTAG}-config + else # default is to use public ip + $sed_gsed -i "s/0\.0\.0\.0/${PublicIP}/g" ~/.kube/${AWSUSERNAME}-dev-${PROJECTTAG}-config + fi + + # Handle MetalLB cluster resource creation + if [[ "${METAL_LB}" == true || "${ATTACH_SECONDARY_IP}" == true ]]; then + echo "Installing MetalLB..." + + until [[ ${REGISTRY_USERNAME} ]]; do + read -p "Please enter your Registry1 username: " REGISTRY_USERNAME + done + until [[ ${REGISTRY_PASSWORD} ]]; do + read -s -p "Please enter your Registry1 password: " REGISTRY_PASSWORD + done + run "kubectl create namespace metallb-system" + run "kubectl create secret docker-registry registry1 \ + --docker-server=registry1.dso.mil \ + --docker-username=${REGISTRY_USERNAME} \ + --docker-password=${REGISTRY_PASSWORD} \ + -n metallb-system" + + run "mkdir /tmp/metallb" + scp -i ~/.ssh/${KeyName}.pem -o StrictHostKeyChecking=no -o IdentitiesOnly=yes ${SCRIPT_DIR}/metallb/* ubuntu@${PublicIP}:/tmp/metallb + run "kubectl apply -k /tmp/metallb" + + # Wait for controller to be live so that validating webhooks function when we apply the config + echo "Waiting for MetalLB controller..." + run "kubectl wait --for=condition=available --timeout 120s -n metallb-system deployment controller" + echo "MetalLB is installed." + + if [[ "$METAL_LB" == true ]]; then + echo "Building MetalLB configuration for -m mode." + cat << EOF > "$tmpdir/metallb-config.yaml" +apiVersion: metallb.io/v1beta1 +kind: IPAddressPool +metadata: + name: default + namespace: metallb-system +spec: + addresses: + - 172.20.1.240-172.20.1.243 +--- +apiVersion: metallb.io/v1beta1 +kind: L2Advertisement +metadata: + name: l2advertisement1 + namespace: metallb-system +spec: + ipAddressPools: + - default +EOF + + elif [[ "$ATTACH_SECONDARY_IP" == true ]]; then + echo "Building MetalLB configuration for -a mode." + cat << EOF > "$tmpdir/metallb-config.yaml" +--- +apiVersion: metallb.io/v1beta1 +kind: IPAddressPool +metadata: + name: primary + namespace: metallb-system + labels: + privateIp: "$PrivateIP" + publicIp: "$PublicIP" +spec: + addresses: + - "172.20.1.241/32" + serviceAllocation: + priority: 100 + namespaces: + - istio-system + serviceSelectors: + - matchExpressions: + - {key: app, operator: In, values: [public-ingressgateway]} +--- +apiVersion: metallb.io/v1beta1 +kind: IPAddressPool +metadata: + name: secondary + namespace: metallb-system + labels: + privateIp: "$PrivateIP2" + publicIp: "$SecondaryIP" +spec: + addresses: + - "172.20.1.240/32" + serviceAllocation: + priority: 100 + namespaces: + - istio-system + serviceSelectors: + - matchExpressions: + - {key: app, operator: In, values: [passthrough-ingressgateway]} +--- +apiVersion: metallb.io/v1beta1 +kind: L2Advertisement +metadata: + name: primary + namespace: metallb-system +spec: + ipAddressPools: + - primary +--- +apiVersion: metallb.io/v1beta1 +kind: L2Advertisement +metadata: + name: secondary + namespace: metallb-system +spec: + ipAddressPools: + - secondary +EOF + + cat << EOF > "$tmpdir/primary-proxy.yaml" +ports: + 443.tcp: + - 172.20.1.241 +settings: + workerConnections: 1024 +EOF + + cat << EOF > "$tmpdir/secondary-proxy.yaml" +ports: + 443.tcp: + - 172.20.1.240 +settings: + workerConnections: 1024 +EOF + + scp -i ~/.ssh/${KeyName}.pem -o StrictHostKeyChecking=no -o IdentitiesOnly=yes "$tmpdir/primary-proxy.yaml" ubuntu@${PublicIP}:/home/ubuntu/primary-proxy.yaml + scp -i ~/.ssh/${KeyName}.pem -o StrictHostKeyChecking=no -o IdentitiesOnly=yes "$tmpdir/secondary-proxy.yaml" ubuntu@${PublicIP}:/home/ubuntu/secondary-proxy.yaml + + run "docker run -d --name=primaryProxy --network=k3d-network -p $PrivateIP:443:443 -v /home/ubuntu/primary-proxy.yaml:/etc/confd/values.yaml ghcr.io/k3d-io/k3d-proxy:$K3D_VERSION" + run "docker run -d --name=secondaryProxy --network=k3d-network -p $PrivateIP2:443:443 -v /home/ubuntu/secondary-proxy.yaml:/etc/confd/values.yaml ghcr.io/k3d-io/k3d-proxy:$K3D_VERSION" + fi + + scp -i ~/.ssh/${KeyName}.pem -o StrictHostKeyChecking=no -o IdentitiesOnly=yes "$tmpdir/metallb-config.yaml" ubuntu@${PublicIP}:/home/ubuntu/metallb-config.yaml + + run "kubectl create -f metallb-config.yaml" + fi + + cat << EOF > "$tmpdir/dns-update.sh" +#!/usr/bin/env bash +mkdir -p /root/.kube +cp /home/ubuntu/.kube/config /root/.kube/config +sed -i '/dev.bigbang.mil/d' /etc/hosts +EOF + + if [[ "$METAL_LB" == true ]]; then + cat << EOF >> "$tmpdir/dns-update.sh" +echo '## begin dev.bigbang.mil section (METAL_LB)' >> /etc/hosts +echo '172.20.1.240 keycloak.dev.bigbang.mil vault.dev.bigbang.mil' >> /etc/hosts +echo '172.20.1.241 anchore-api.dev.bigbang.mil anchore.dev.bigbang.mil argocd.dev.bigbang.mil gitlab.dev.bigbang.mil registry.dev.bigbang.mil tracing.dev.bigbang.mil kiali.dev.bigbang.mil kibana.dev.bigbang.mil chat.dev.bigbang.mil minio.dev.bigbang.mil minio-api.dev.bigbang.mil alertmanager.dev.bigbang.mil grafana.dev.bigbang.mil prometheus.dev.bigbang.mil nexus.dev.bigbang.mil sonarqube.dev.bigbang.mil tempo.dev.bigbang.mil twistlock.dev.bigbang.mil' >> /etc/hosts +echo '## end dev.bigbang.mil section' >> /etc/hosts + +kubectl get configmap -n kube-system coredns -o yaml | sed '/^ 172.20.0.1 host.k3d.internal$/a\ \ \ \ 172.20.1.240 keycloak.dev.bigbang.mil vault.dev.bigbang.mil' | kubectl apply -f - +EOF + elif [[ "$ATTACH_SECONDARY_IP" == true ]]; then + + cat << EOF >> "$tmpdir/dns-update.sh" +echo '## begin dev.bigbang.mil section (ATTACH_SECONDARY_IP)' >> /etc/hosts +echo '$PrivateIP2 keycloak.dev.bigbang.mil vault.dev.bigbang.mil' >> /etc/hosts +echo '$PrivateIP anchore-api.dev.bigbang.mil anchore.dev.bigbang.mil argocd.dev.bigbang.mil gitlab.dev.bigbang.mil registry.dev.bigbang.mil tracing.dev.bigbang.mil kiali.dev.bigbang.mil kibana.dev.bigbang.mil chat.dev.bigbang.mil minio.dev.bigbang.mil minio-api.dev.bigbang.mil alertmanager.dev.bigbang.mil grafana.dev.bigbang.mil prometheus.dev.bigbang.mil nexus.dev.bigbang.mil sonarqube.dev.bigbang.mil tempo.dev.bigbang.mil twistlock.dev.bigbang.mil' >> /etc/hosts +echo '## end dev.bigbang.mil section' >> /etc/hosts + +kubectl get configmap -n kube-system coredns -o yaml | sed '/^ .* host.k3d.internal$/a\ \ \ \ $PrivateIP2 keycloak.dev.bigbang.mil vault.dev.bigbang.mil' | kubectl apply -f - +EOF + fi + + cat << EOF >> "$tmpdir/dns-update.sh" +kubectl delete pod -n kube-system -l k8s-app=kube-dns +EOF + + scp -i ~/.ssh/${KeyName}.pem -o StrictHostKeyChecking=no -o IdentitiesOnly=yes "$tmpdir/dns-update.sh" ubuntu@${PublicIP}:/home/ubuntu/dns-update.sh + run "sudo bash /home/ubuntu/dns-update.sh" + + echo + echo "================================================================================" + echo "====================== DEPLOYMENT FINISHED =====================================" + echo "================================================================================" + # ending instructions + echo + echo "SAVE THE FOLLOWING INSTRUCTIONS INTO A TEMPORARY TEXT DOCUMENT SO THAT YOU DON'T LOSE THEM" + echo "NOTE: The EC2 instance will automatically terminate 8 hours from the time of creation unless you delete the root cron job" + echo + echo "ssh to instance:" + echo " ssh -i ~/.ssh/${KeyName}.pem -o IdentitiesOnly=yes ubuntu@${PublicIP}" + echo + echo "To use kubectl from your local workstation you must set the KUBECONFIG environment variable:" + echo " export KUBECONFIG=~/.kube/${AWSUSERNAME}-dev-${PROJECTTAG}-config" + if [[ "$PRIVATE_IP" == true ]] + then + echo "The cluster connection will not work until you start sshuttle as described below." + fi + echo + + if [[ "$METAL_LB" == true ]]; then # using MetalLB + if [[ "$PRIVATE_IP" == true ]]; then # using MetalLB and private IP + echo "Start sshuttle in a separate terminal window:" + echo " sshuttle --dns -vr ubuntu@${PublicIP} 172.31.0.0/16 --ssh-cmd 'ssh -i ~/.ssh/${KeyName}.pem -D 127.0.0.1:12345'" + echo "Do not edit /etc/hosts on your local workstation." + echo "Edit /etc/hosts on the EC2 instance. Sample /etc/host entries have already been added there." + echo "Manually add more hostnames as needed." + echo "The IPs to use come from the istio-system services of type LOADBALANCER EXTERNAL-IP that are created when Istio is deployed." + echo "You must use Firefox browser with with manual SOCKs v5 proxy configuration to localhost with port 12345." + echo "Also ensure 'Proxy DNS when using SOCKS v5' is checked." + echo "Or, with other browsers like Chrome you could use a browser plugin like foxyproxy to do the same thing as Firefox." + else # using MetalLB and public IP + echo "OPTION 1: ACCESS APPLICATIONS WITH WEB BROWSER ONLY" + echo "To access apps from browser only start ssh with application-level port forwarding:" + echo " ssh -i ~/.ssh/${KeyName}.pem ubuntu@${PublicIP} -D 127.0.0.1:12345" + echo "Do not edit /etc/hosts on your local workstation." + echo "Edit /etc/hosts on the EC2 instance. Sample /etc/host entries have already been added there." + echo "Manually add more hostnames as needed." + echo "The IPs to use come from the istio-system services of type LOADBALANCER EXTERNAL-IP that are created when Istio is deployed." + echo "You must use Firefox browser with with manual SOCKs v5 proxy configuration to localhost with port 12345." + echo "Also ensure 'Proxy DNS when using SOCKS v5' is checked." + echo "Or, with other browsers like Chrome you could use a browser plugin like foxyproxy to do the same thing as Firefox." + echo + echo "OPTION 2: ACCESS APPLICATIONS WITH WEB BROWSER AND COMMAND LINE" + echo "To access apps from browser and from the workstation command line start sshuttle in a separate terminal window." + echo " sshuttle --dns -vr ubuntu@${PublicIP} 172.20.1.0/24 --ssh-cmd 'ssh -i ~/.ssh/${KeyName}.pem'" + echo "Edit your workstation /etc/hosts to add the LOADBALANCER EXTERNAL-IPs from the istio-system services with application hostnames." + echo "Here is an example. You might have to change this depending on the number of gateways you configure for k8s cluster." + echo " # METALLB ISTIO INGRESS IPs" + echo " 172.20.1.240 keycloak.dev.bigbang.mil vault.dev.bigbang.mil" + echo " 172.20.1.241 sonarqube.dev.bigbang.mil prometheus.dev.bigbang.mil nexus.dev.bigbang.mil gitlab.dev.bigbang.mil" + fi + elif [[ "$PRIVATE_IP" == true ]]; then # not using MetalLB + # Not using MetalLB and using private IP + echo "Start sshuttle in a separate terminal window:" + echo " sshuttle --dns -vr ubuntu@${PublicIP} 172.31.0.0/16 --ssh-cmd 'ssh -i ~/.ssh/${KeyName}.pem'" + echo + echo "To access apps from a browser edit your /etc/hosts to add the private IP of your EC2 instance with application hostnames. Example:" + echo " ${PrivateIP} gitlab.dev.bigbang.mil prometheus.dev.bigbang.mil kibana.dev.bigbang.mil" + echo + else # Not using MetalLB and using public IP. This is the default + echo "To access apps from a browser edit your /etc/hosts to add the public IP of your EC2 instance with application hostnames." + echo "Example:" + echo " ${PublicIP} gitlab.dev.bigbang.mil prometheus.dev.bigbang.mil kibana.dev.bigbang.mil" + echo + + if [[ $SecondaryIP ]]; then + echo "A secondary IP is available for use if you wish to have a passthrough ingress for Istio along with a public Ingress Gateway, this maybe useful for Keycloak x509 mTLS authentication." + echo " $SecondaryIP keycloak.dev.bigbang.mil" + fi + fi +} + +function report_instances +{ + aws ec2 describe-instances \ + --filters "Name=tag:Name,Values=${AWSUSERNAME}-dev" \ + --query 'Reservations[*].Instances[*].[InstanceId,State.Name,PublicIpAddress,SecurityGroups[0].GroupId,Tags[?Key==`Project`].Value | [0]]' \ + --output text +} + +#### Global variables - These allow the script to be run by non-bigbang devs easily - Update VPC_ID here or export environment variable for it if not default VPC +if [[ -z "${VPC_ID}" ]]; then + VPC_ID="$(aws ec2 describe-vpcs --filters Name=is-default,Values=true | jq -j .Vpcs[0].VpcId)" + if [[ -z "${VPC_ID}" ]]; then + echo "AWS account has no default VPC - please provide VPC_ID" + exit 1 + fi +fi + +if [[ -n "${SUBNET_ID}" ]]; then + if [[ "$(aws ec2 describe-subnets --subnet-id "${SUBNET_ID}" --filters "Name=vpc-id,Values=${VPC_ID}" | jq -j .Subnets[0])" == "null" ]]; then + echo "SUBNET_ID ${SUBNET_ID} does not belong to VPC ${VPC_ID}" + exit 1 + fi +else + SUBNET_ID="$(aws ec2 describe-subnets --filters "Name=vpc-id,Values=${VPC_ID}" "Name=default-for-az,Values=true" | jq -j .Subnets[0].SubnetId)" + if [[ "${SUBNET_ID}" == "null" ]]; then + echo "VPC ${VPC_ID} has no default subnets - please provide SUBNET_ID" + exit 1 + fi +fi + +# If the user is using her own AMI, then respect that and do not update it. +APT_UPDATE="true" +if [[ $AMI_ID ]]; then + APT_UPDATE="false" +else + # default + AMI_ID=$(getDefaultAmi) +fi + +#### Preflight Checks +# Check that the VPC is available +EXISTING_VPC=$(aws ec2 describe-vpcs | grep ${VPC_ID}) +if [[ -z "${EXISTING_VPC}" ]]; then + echo "VPC is not available in the current AWS_PROFILE - Update VPC_ID" + exit 1 +fi +# check for tools +tooldependencies=(jq sed aws ssh ssh-keygen scp kubectl tr base64) +for tooldependency in "${tooldependencies[@]}" + do + command -v $tooldependency >/dev/null 2>&1 || { echo >&2 " $tooldependency is not installed."; missingtool=1; } + done +sed_gsed="sed" +# verify sed version if mac +# alias prohibited, symlinks permitted +uname="$(uname -s)" +if [[ "${uname}" == "Darwin" ]]; then + if [[ $(command -v gsed) ]]; then + sed_gsed="gsed" + else + missingtool=1 + echo ' gnu-sed is not installed. "brew install gnu-sed"' + fi +fi +# if tool missing, exit +if [[ "${missingtool}" == 1 ]]; then + echo " Please install required tools. Aborting." + exit 1 +fi + +# getting AWS user name +AWSUSERNAME=$( aws sts get-caller-identity --query Arn --output text | cut -f 2 -d '/' ) + +# check for aws username environment variable. If not found then terminate script +if [[ -z "${AWSUSERNAME}" ]]; then + echo "You must configure your AWS credentials. Your AWS user name is used to name resources in AWS. Example:" + echo " aws configure" + exit 1 +else + echo "AWS User Name: ${AWSUSERNAME}" +fi + + +#### Configure Environment +# Identify which VPC to create the spot instance in +VPC="${VPC_ID}" # default VPC +RESET_K3D=false +ATTACH_SECONDARY_IP=${ATTACH_SECONDARY_IP:=false} +PROJECTTAG="default" +# Assign a name for your Security Group. Typically, people use their username to make it easy to identify +SGname="${AWSUSERNAME}-dev-${PROJECTTAG}" +# Assign a name for your SSH Key Pair. Typically, people use their username to make it easy to identify +KeyName="${AWSUSERNAME}-dev-${PROJECTTAG}" +# The action to perform +action=create_instances + +while [ -n "$1" ]; do # while loop starts + + case "$1" in + + -t) echo "-t option passed to use additional tags on instance" + shift + PROJECTTAG=$1 + SGname="${AWSUSERNAME}-dev-${PROJECTTAG}" + KeyName="${AWSUSERNAME}-dev-${PROJECTTAG}" + ;; + + -b) echo "-b option passed for big k3d cluster using M5 instance" + BIG_INSTANCE=true + ;; + + -p) echo "-p option passed to create k3d cluster with private ip" + if [[ "${ATTACH_SECONDARY_IP}" = false ]]; then + PRIVATE_IP=true + else + echo "Disabling -p option because -a was specified." + fi + ;; + + -m) echo "-m option passed to install MetalLB" + if [[ "${ATTACH_SECONDARY_IP}" = false ]]; then + METAL_LB=true + else + echo "Disabling -m option because -a was specified." + fi + ;; + + -a) echo "-a option passed to create secondary public IP (-p and -m flags are skipped if set)" + PRIVATE_IP=false + METAL_LB=false + ATTACH_SECONDARY_IP=true + ;; + + -d) echo "-d option passed to destroy the AWS resources" + action=destroy_instances + ;; + + -h) echo "Usage: $0 [argument ...]" + echo "" + echo "arguments:" + echo " -a attach secondary Public IP (overrides -p and -m flags)" + echo " -b use BIG M5 instance. Default is m5a.4xlarge" + echo " -d destroy related AWS resources" + echo " -h output help" + echo " -m create k3d cluster with metalLB" + echo " -p use private IP for security group and k3d cluster" + echo " -r Report on all instances owned by your user" + echo " -t Set the project tag on the instance" + echo " -u Update security group for instances" + echo " -w install the weave CNI instead of the default flannel CNI" + exit 0 + ;; + + -u) action=update_instances + ;; + + -r) action=report_instances + ;; + + -w) echo "-w option passed to use Weave CNI" + USE_WEAVE=true + ;; + + *) echo "Option $1 not recognized" ;; # In case a non-existent option is submitted + + esac + shift +done + +${action} diff --git a/docs/assets/scripts/developer/metallb/kustomization.yaml b/docs/assets/scripts/developer/metallb/kustomization.yaml new file mode 100644 index 0000000000000000000000000000000000000000..e21b9693502317194c8d171872752b4294864ed6 --- /dev/null +++ b/docs/assets/scripts/developer/metallb/kustomization.yaml @@ -0,0 +1,47 @@ +resources: + - https://raw.githubusercontent.com/metallb/metallb/v0.14.9/config/manifests/metallb-native.yaml + +images: + - name: quay.io/metallb/controller + newName: registry1.dso.mil/ironbank/opensource/metallb/controller + newTag: v0.14.9 + - name: quay.io/metallb/speaker + newName: registry1.dso.mil/ironbank/opensource/metallb/speaker + newTag: v0.14.9 + +patches: + - target: + kind: Deployment + name: controller + patch: |- + apiVersion: apps/v1 + kind: Deployment + metadata: + name: controller + spec: + template: + spec: + imagePullSecrets: + - name: registry1 + securityContext: + fsGroup: 65532 + runAsNonRoot: true + runAsUser: 65532 + runAsGroup: 65532 + - target: + kind: DaemonSet + name: speaker + patch: |- + apiVersion: apps/v1 + kind: DaemonSet + metadata: + name: speaker + spec: + template: + spec: + imagePullSecrets: + - name: registry1 + securityContext: + fsGroup: 65532 + runAsUser: 0 + diff --git a/docs/assets/scripts/developer/mfa-aws-creds-example b/docs/assets/scripts/developer/mfa-aws-creds-example new file mode 100644 index 0000000000000000000000000000000000000000..8fba5a4a862f9d4c8bc30794a6e5470b271e2fb7 --- /dev/null +++ b/docs/assets/scripts/developer/mfa-aws-creds-example @@ -0,0 +1,7 @@ +[bigbang] +region = us-gov-west-1 +## REPLACE WITH YOUR EXISTING ACCESS KEYS FOR YOUR DEV ACCOUNT +aws_access_key_id = XXXXXXXXXXXXXXXXXXXXX +aws_secret_access_key = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +[default] +region=us-gov-west-1 \ No newline at end of file diff --git a/docs/assets/scripts/developer/weave/README-weave.md b/docs/assets/scripts/developer/weave/README-weave.md new file mode 100644 index 0000000000000000000000000000000000000000..ee4d2a79b4e557571fa9770754ff89d36e5047d4 --- /dev/null +++ b/docs/assets/scripts/developer/weave/README-weave.md @@ -0,0 +1,17 @@ +# K3d + +``` +curl -L https://github.com/weaveworks/weave/releases/download/v2.8.1/weave-daemonset-k8s.yaml -O > weave.yaml +``` + +Weave expects `/etc/machine-id` to be a file, and each k3d node needs to have a unique value in this file. + +BB k3d uses the 172.21.0.0/16 cidr subnet for pods, so `IPALLOC_RANGE` needs to match: + +``` + containers: + - name: weave + env: + - name: IPALLOC_RANGE + value: "172.21.0.0/16" +``` diff --git a/docs/assets/scripts/developer/weave/machine-id-agent-0 b/docs/assets/scripts/developer/weave/machine-id-agent-0 new file mode 100644 index 0000000000000000000000000000000000000000..3fea3c1afd536277de9083218fd03e7a8ea9c858 --- /dev/null +++ b/docs/assets/scripts/developer/weave/machine-id-agent-0 @@ -0,0 +1 @@ +242892d11ac2521aac3d2ad864baaa22 diff --git a/docs/assets/scripts/developer/weave/machine-id-agent-1 b/docs/assets/scripts/developer/weave/machine-id-agent-1 new file mode 100644 index 0000000000000000000000000000000000000000..701baa2381b01e8254be0572eab122b237ee8309 --- /dev/null +++ b/docs/assets/scripts/developer/weave/machine-id-agent-1 @@ -0,0 +1 @@ +242892d11ac2521aac3d2ad864baaa23 diff --git a/docs/assets/scripts/developer/weave/machine-id-agent-2 b/docs/assets/scripts/developer/weave/machine-id-agent-2 new file mode 100644 index 0000000000000000000000000000000000000000..819a7199f0d863be48aa5d6a8d11a89dd02dd820 --- /dev/null +++ b/docs/assets/scripts/developer/weave/machine-id-agent-2 @@ -0,0 +1 @@ +242892d11ac2521aac3d2ad864baaa24 diff --git a/docs/assets/scripts/developer/weave/machine-id-server-0 b/docs/assets/scripts/developer/weave/machine-id-server-0 new file mode 100644 index 0000000000000000000000000000000000000000..a9578ff130f542ed1c2c24d8f2fe1293ed96179f --- /dev/null +++ b/docs/assets/scripts/developer/weave/machine-id-server-0 @@ -0,0 +1 @@ +242892d11ac2521aac3d2ad864baaa21 diff --git a/docs/assets/scripts/developer/weave/weave.yaml b/docs/assets/scripts/developer/weave/weave.yaml new file mode 100644 index 0000000000000000000000000000000000000000..7507854c4e95adfaee6951bbbc2f4551f3872baf --- /dev/null +++ b/docs/assets/scripts/developer/weave/weave.yaml @@ -0,0 +1,239 @@ +apiVersion: v1 +kind: List +items: + - apiVersion: v1 + kind: ServiceAccount + metadata: + name: weave-net + labels: + name: weave-net + namespace: kube-system + - apiVersion: rbac.authorization.k8s.io/v1 + kind: ClusterRole + metadata: + name: weave-net + labels: + name: weave-net + rules: + - apiGroups: + - '' + resources: + - pods + - namespaces + - nodes + verbs: + - get + - list + - watch + - apiGroups: + - extensions + resources: + - networkpolicies + verbs: + - get + - list + - watch + - apiGroups: + - 'networking.k8s.io' + resources: + - networkpolicies + verbs: + - get + - list + - watch + - apiGroups: + - '' + resources: + - nodes/status + verbs: + - patch + - update + - apiVersion: rbac.authorization.k8s.io/v1 + kind: ClusterRoleBinding + metadata: + name: weave-net + labels: + name: weave-net + roleRef: + kind: ClusterRole + name: weave-net + apiGroup: rbac.authorization.k8s.io + subjects: + - kind: ServiceAccount + name: weave-net + namespace: kube-system + - apiVersion: rbac.authorization.k8s.io/v1 + kind: Role + metadata: + name: weave-net + namespace: kube-system + labels: + name: weave-net + rules: + - apiGroups: + - '' + resources: + - configmaps + resourceNames: + - weave-net + verbs: + - get + - update + - apiGroups: + - '' + resources: + - configmaps + verbs: + - create + - apiVersion: rbac.authorization.k8s.io/v1 + kind: RoleBinding + metadata: + name: weave-net + namespace: kube-system + labels: + name: weave-net + roleRef: + kind: Role + name: weave-net + apiGroup: rbac.authorization.k8s.io + subjects: + - kind: ServiceAccount + name: weave-net + namespace: kube-system + - apiVersion: apps/v1 + kind: DaemonSet + metadata: + name: weave-net + labels: + name: weave-net + namespace: kube-system + spec: + # Wait 5 seconds to let pod connect before rolling next pod + selector: + matchLabels: + name: weave-net + minReadySeconds: 5 + template: + metadata: + labels: + name: weave-net + spec: + initContainers: + - name: weave-init + image: 'registry.dso.mil/big-bang/pipeline-templates/pipeline-templates/weave-kube:latest' + imagePullPolicy: Always + command: + - /home/weave/init.sh + env: + securityContext: + privileged: true + volumeMounts: + - name: cni-bin + mountPath: /host/opt + - name: cni-bin2 + mountPath: /host/home + - name: cni-conf + mountPath: /host/etc + - name: lib-modules + mountPath: /lib/modules + - name: xtables-lock + mountPath: /run/xtables.lock + readOnly: false + containers: + - name: weave + command: + - /home/weave/launch.sh + env: + - name: IPALLOC_RANGE + value: "172.21.0.0/16" + - name: INIT_CONTAINER + value: "true" + - name: HOSTNAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: spec.nodeName + image: 'registry.dso.mil/big-bang/pipeline-templates/pipeline-templates/weave-kube:latest' + imagePullPolicy: Always + readinessProbe: + httpGet: + host: 127.0.0.1 + path: /status + port: 6784 + resources: + requests: + cpu: 50m + securityContext: + privileged: true + volumeMounts: + - name: weavedb + mountPath: /weavedb + - name: dbus + mountPath: /host/var/lib/dbus + readOnly: true + - mountPath: /host/etc/machine-id + name: cni-machine-id + readOnly: true + - name: xtables-lock + mountPath: /run/xtables.lock + readOnly: false + - name: weave-npc + env: + - name: HOSTNAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: spec.nodeName + image: 'registry.dso.mil/big-bang/pipeline-templates/pipeline-templates/weave-npc:latest' + imagePullPolicy: Always +#npc-args + resources: + requests: + cpu: 50m + securityContext: + privileged: true + volumeMounts: + - name: xtables-lock + mountPath: /run/xtables.lock + readOnly: false + hostNetwork: true + dnsPolicy: ClusterFirstWithHostNet + hostPID: false + restartPolicy: Always + securityContext: + seLinuxOptions: {} + serviceAccountName: weave-net + tolerations: + - effect: NoSchedule + operator: Exists + - effect: NoExecute + operator: Exists + volumes: + - name: weavedb + hostPath: + path: /var/lib/weave + - name: cni-bin + hostPath: + path: /opt + - name: cni-bin2 + hostPath: + path: /home + - name: cni-conf + hostPath: + path: /etc + - name: cni-machine-id + hostPath: + path: /etc/machine-id + - name: dbus + hostPath: + path: /var/lib/dbus + - name: lib-modules + hostPath: + path: /lib/modules + - name: xtables-lock + hostPath: + path: /run/xtables.lock + type: FileOrCreate + priorityClassName: system-node-critical + updateStrategy: + type: RollingUpdate diff --git a/docs/assets/terraform/airgap-dev/README.md b/docs/assets/terraform/airgap-dev/README.md new file mode 100644 index 0000000000000000000000000000000000000000..a248093b6a79f01dec489d56ab6565be7358a63f --- /dev/null +++ b/docs/assets/terraform/airgap-dev/README.md @@ -0,0 +1,3 @@ +# README + +Terraform that creates a new VPC and two subnets. One subnet is public the other is airgapped except for access to/from the public subnet. This allows for a jump box or other resources to be easily moved in and out of the public subnet for setting up your development environment for the private subnet. diff --git a/docs/assets/terraform/airgap-dev/main.tf b/docs/assets/terraform/airgap-dev/main.tf new file mode 100644 index 0000000000000000000000000000000000000000..45b23ef5706255b4eef63eea162450b013b0ef6b --- /dev/null +++ b/docs/assets/terraform/airgap-dev/main.tf @@ -0,0 +1,115 @@ +# Locals +locals { + az = format("%s%s", var.region_id, "a") +} + +# Provider +provider "aws" { + profile = var.profile_id + region = var.region_id +} + +# Vpc +resource "aws_vpc" "airgap_vpc" { + cidr_block = "10.0.0.0/16" + enable_dns_hostnames = true + + tags = { + Name = "${var.cluster_id}-${random_string.random.result}-vpc" + } +} + +# Public subnet +resource "aws_subnet" "public" { + vpc_id = aws_vpc.airgap_vpc.id + cidr_block = "10.0.0.0/24" + availability_zone = local.az + + tags = { + Name = "airgap-public-subnet" + } +} + +# Igw +resource "aws_internet_gateway" "airgap_vpc_igw" { + vpc_id = aws_vpc.airgap_vpc.id + + tags = { + Name = "airgap-igw" + } +} + +# Public route table +resource "aws_route_table" "airgap_vpc_region_public" { + vpc_id = aws_vpc.airgap_vpc.id + + route { + cidr_block = "0.0.0.0/0" + gateway_id = aws_internet_gateway.airgap_vpc_igw.id + } + + tags = { + Name = "airgap-public-rt" + } +} + +# Public route table associations +resource "aws_route_table_association" "airgap_vpc_region_public" { + subnet_id = aws_subnet.public.id + route_table_id = aws_route_table.airgap_vpc_region_public.id +} + +# Private subnet +resource "aws_subnet" "private" { + vpc_id = aws_vpc.airgap_vpc.id + cidr_block = "10.0.2.0/24" + availability_zone = local.az + + tags = { + Name = "airgap-private-subnet" + } +} + +# Private routing table +resource "aws_route_table" "airgap_vpc_region_private" { + vpc_id = aws_vpc.airgap_vpc.id + + tags = { + Name = "airgap-private-rt" + } +} + +# Private routing table association +resource "aws_route_table_association" "airgap_vpc_region_private" { + subnet_id = aws_subnet.private.id + route_table_id = aws_route_table.airgap_vpc_region_private.id +} + +# Output +#output "connection_details" { +# value = <<EOF + +# Use the following to connect to the bootstrap node and enjoy the ride... + +# ssh -J ${var.image_username}@${aws_instance.staging_instance.public_ip} ${var.image_username}@${aws_instance.bootstrap_instance.private_ip} + +# EOF +#} + +#output "public_ip" { +# description = "List of public IP addresses assigned to the instances, if applicable" +# value = "${aws_instance.staging_instance.*.public_ip}" +#} + +#output "private_ip" { +# description = "List of private IP addresses assigned to the instances, if applicable" +# value = "${aws_instance.bootstrap_instance.*.private_ip}" +#} + +output "follow_up" { + value = <<EOF + + Nothing to see here but I have finished. + + EOF +} diff --git a/docs/assets/terraform/airgap-dev/variables.tf b/docs/assets/terraform/airgap-dev/variables.tf new file mode 100644 index 0000000000000000000000000000000000000000..8c4dc099611e5a098bf6708198afd247a7256c9a --- /dev/null +++ b/docs/assets/terraform/airgap-dev/variables.tf @@ -0,0 +1,64 @@ + +# Provider id based on Mesosphere account information +variable "profile_id" { + description = "" + # Default region is default + default = "default" +} + +# AWS Region id +variable "region_id" { + description = "" + # Default region is us-gov-west-1 + default = "us-gov-west-1" +} + +# Cluster UUID +resource "random_string" "random" { + length = 4 + special = false + lower = true + upper = false +} + +# Cluster id +variable "cluster_id" { + description = "" + # Default region is airgap-???? + default = "airgap-" +} + +# ec2.tf +variable "image_id" { + description = "Amazon AWS AMI" + # default = "ami-06eeaf749779ed329" + default = "ami-06eeaf749779ed329" +} + +# ec2.tf +variable "image_username" { + description = "Amazon AWS AMI username" + default = "centos" +} + +# ec2.tf +variable "ec2_instance_type" { + description = "AWS EC2 Instance type" + # Default instance type m5.xlarge + default = "m5.xlarge" +} + +# Ssh keyname +variable "ssh_key_name" { + description = "" + # Comment + default = "airgap" +} + +# Cluster owner +#variable "owner" { +# description = "Owner of the cluster" +# # Comment +# default = "egoode" +#} + diff --git a/docs/developer/.pages b/docs/developer/.pages new file mode 100644 index 0000000000000000000000000000000000000000..dba8eaa82d510d2abf16e42049c92192c80df80d --- /dev/null +++ b/docs/developer/.pages @@ -0,0 +1,12 @@ +nav: + - Overview: README.md + - AWS Dev Script: aws-k3d-script.md + - CI Workflow: ci-workflow.md + - Package Development: develop-package.md + - Development Environment: development-environment.md + - K8s Storage Options: k8s-storage.md + - Partybus Pipelines: mdo-partybus-pipelines.md + - Release Process: release-process.md + - Testing: testing.md + - Testing Vendor Distros: vendor-distro-integration.md + - Package Integration: package-integration diff --git a/docs/developer/IstioHardened.md b/docs/developer/IstioHardened.md new file mode 100644 index 0000000000000000000000000000000000000000..b50d03c6990c7dd5e704041676732378897683e4 --- /dev/null +++ b/docs/developer/IstioHardened.md @@ -0,0 +1,111 @@ +# Istio Hardened +Big Bang has added the `.Values.istio.hardened` map attibute to the values of applications that can be istio-injected, when `.Values.istio.enabled` is `true`. This document walks through the impact of setting `.Values.istio.hardened: true` on how traffic is managed within a given istio-injected package. + +## Prerequisites +In order for `.Values.istio.hardened.enabled: true` to have any impact, the package must also have `.Values.istio.enabled: true` set. This is because all of the resources created by setting `.Values.istio.hardened.enabled: true` are applied to the istio service mesh, which includes istio sidecar proxies. If there are no istio proxies, then no mesh components exist in the namespace and therefore istio Kubernetes resources in the namespace will not effect anything. + +## REGISTRY_ONLY Istio Sidecar Resources +When `.Values.istio.hardened.enabled: true` is set, a `Sidecar` resource is applied to the package's namespace that sets the outboundTrafficPolicy of the Sidecar to `REGISTRY_ONLY`. What this means is that for pods with an istio-proxy running as a "sidecar", the only egress traffic allowed is for traffic that is destinated for a service that exists within the istio service mesh registry. + +By default, all Kubernetes Services are added to this registry. However, cluster-external hostnames, IP addresses, and other endpoints will NOT be reachable with this Sidecar in place. For example, if an application attempts to reach out to the Kubernetes API Service at `kubernetes.default.svc.cluster.local`, or any of it's SANs, the request will not be blocked by the Sidecar. Conversely, if the application attempts to reach out to s3.us-gov-west-1.amazonaws.com, the request with fail unless there is a ServiceEntry (refer to the example below) that adds s3.us-gov-west-1.amazonaws.com to the service mesh registry. This Sidecar is added in order to provide defense in depth, working alongside NetworkPolicies to prevent data exfiltration by malicious actors. + +## ServiceEntry Istio Resources +Because some application have well-documented requirements to reach out to cluster external endpoints (e.g., S3 is one common example), Big Bang has added ServiceEntries to get those endpoints included in the Istio service registry. If we missed one, please open an issue detailing what endpoint needs to be whitelisted with a ServiceEntry. Alternatively, you can create your own whitelisted endpoints by using the `.Values.istio.hardened.customServiceEntries` list, which will generate a ServiceEntry according to the `.spec` map you set. + +> `customServiceEntries` is there for *edge cases* that may be specific to your requirements, and not all `customServiceEntries` may be appropriate for all Big Bang users. + +### Example CustomServiceEntry +To create a ServiceEntry for google, the corresponding customServiceEntry attribute could be set to the following: +```yaml +istio: + enabled: true + hardened: + enabled: true + customServiceEntries: + - name: "allow-google" + enabled: true + spec: + hosts: + - google.com + location: MESH_EXTERNAL + ports: + - number: 443 + protocol: TLS + name: https + resolution: DNS +``` + +This would result in the following ServiceEntry being created: +```yaml +apiVersion: networking.istio.io/v1beta1 +kind: ServiceEntry +metadata: + name: allow-google + namespace: my-app-namespace +spec: + hosts: + - google.com + location: MESH_EXTERNAL + ports: + - name: https + number: 443 + protocol: TLS + resolution: DNS +``` + +For more information on writting ServiceEntries, see [this documentation](https://istio.io/latest/docs/reference/config/networking/service-entry/) + +## Authorization Policies +[Istio Authorization Policies](https://istio.io/latest/docs/reference/config/security/authorization-policy/#AuthorizationPolicy) will be created provided `istio.enabled` and `istio.hardened.enabled` are set to `true`. There is a default deny policy which will deny everything that is not explicitly allowed with another policy. Denials look like a 403 with the message `RBAC: access denied`. Other policies that are created might include allow ingress gateways, allow monitoring, or allow a supported service that needs access to these resources. You will find these listed under `istio.hardened` as named objects that have three properties: `enabled`, `namespaces`, and `principals`. There are also templates which allow you to create custom authorization policies through additional values, these are described in greater detail below. The last rules to note are global rules. These are any rules created in the `istio-system` namespace. Rather than affecting just the `istio-system` namespace, they will apply to all namespaces. + +### Rules +Apart from the default deny, most rules will be explicit allows. Included rules will be for other supported packages. Any other rules will need to be created with the templates described below. Rules affect a namespace. Rules go on the "server" in the "client-server" relationship. + +Application Order: +1. If there are any CUSTOM policies that match the request, evaluate and deny the request if the evaluation result is deny. +1. If there are any DENY policies that match the request, deny the request. +1. If there are no ALLOW policies for the workload, allow the request. +1. If any of the ALLOW policies match the request, allow the request. +1. Deny the request. + +### Templates +Templates are just an easy way to inject more authorization policies by just modifying values files. They essentially allow you to pass in a name and spec, then have it deploy an authorization policy with that spec in the `.Release.Namespace`. They also allow you to enable/disable specific policies for development, debugging, and other purposes. + +If you pass these partial values: +```yaml +istio: + hardened: + customAuthorizationPolicies: + - name: "allow-my-namespace" + enabled: true + spec: + selector: + matchLabels: + app.kubernetes.io/name: "server-app" + action: ALLOW + rules: + - from: + - source: + namespaces: + - "my-namespace" +``` + +This policy would be generated: +```yaml +apiVersion: security.istio.io/v1 +kind: AuthorizationPolicy +metadata: + name: "allow-my-namespace" + namespace: {{ $.Release.Namespace }} + +spec: + selector: + matchLabels: + app.kubernetes.io/name: "server-app" + action: ALLOW + rules: + - from: + - source: + namespaces: + - "my-namespace" +``` diff --git a/docs/developer/README.md b/docs/developer/README.md new file mode 100644 index 0000000000000000000000000000000000000000..967e378e071dbd1b7f441ce284386fb7443d299b --- /dev/null +++ b/docs/developer/README.md @@ -0,0 +1,38 @@ +# Developer Documentation + +[[_TOC_]] + +## Preface + +Please read through the documentation linked here and in the [understanding Big Bang folder](https://repo1.dso.mil/big-bang/bigbang/-/tree/master/docs/understanding_bigbang) to understand Big Bang concepts and development standards. Study all the documents carefully before you start developing. + +## Communications + +Join MatterMost channels to ask questions and communicate with the team. Here is the list of relevant Mattermost channels for Big Bang development: + +* [Value Stream - Big Bang](https://chat.il2.dso.mil/platform-one/channels/team---big-bang) +* [Topic - Big Bang Documentation](https://chat.il2.dso.mil/platform-one/channels/topic-big-bang-documentation) + +## Set up a Development Environment + +[Set up a Development Environment](./development-environment.md). + +## Package Requirements + +[Big Bang Package Integration Guide](./package-integration/README.md) and [BBTOC Graduated Requirements](https://repo1.dso.mil/platform-one/bbtoc/-/tree/master/process#graduated-project-requirements) + +## Package Development + +[Develop a Big Bang Package](./develop-package.md). + +## Add Package to Big Bang + +[Integrate Package with Big Bang](./package-integration/README.md). + +## Package Owner Overview + +[Package Owner Requirements & Overview](./package-integration/ownership.md). + +## Big Bang Code Through Party Bus Pipeline + +[Code Through Party Bus MDO Pipeline](./mdo-partybus-pipelines.md). diff --git a/docs/developer/aws-k3d-script.md b/docs/developer/aws-k3d-script.md new file mode 100644 index 0000000000000000000000000000000000000000..57965a67a8911a381b8a30f1cf215ddeaf140998 --- /dev/null +++ b/docs/developer/aws-k3d-script.md @@ -0,0 +1,128 @@ +# Development k3d Cluster Automation + +> **NOTE:** This script does not does not install Flux or deploy Big Bang. You must handle those deployments after your k3d dev cluster is ready. + +The instance will automatically terminate eight hours after creation. + +## Install and Configure Dependencies + +1. Install aws cli. + + ```shell + curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" + # sudo apt install unzip -y + unzip awscliv2.zip + sudo ./aws/install + rm -rf aws + rm awscliv2.zip + aws --version + ``` + +1. Configure aws cli. + + ```shell + aws configure + # aws_access_key_id - The AWS access key part of your credentials + # aws_secret_access_key - The AWS secret access key part of your credentials + # region - us-gov-west-1 + # output - json + + # Verify configuration + aws configure list + ``` + +1. Install jq. + Follow jq installation instructions for your workstation operating system. + <https://stedolan.github.io/jq/download/> + +1. Mac users will need to install the GNU version of the sed command. + <https://medium.com/@bramblexu/install-gnu-sed-on-mac-os-and-set-it-as-default-7c17ef1b8f64> + +## Usage + +The default with no options specified is to use the EC2 public IP for the k3d cluster and the security group. + +```shell +./docs/assets/scripts/developer/k3d-dev.sh -h +AWS User Name: your.name +Usage: +k3d-dev.sh -b -p -m -a -d -h + + -b use BIG M5 instance. Default is m5a.4xlarge + -p use private IP for security group and k3d cluster + -m create k3d cluster with metalLB + -a attach secondary Public IP (overrides -p and -m flags) + -d destroy related AWS resources + -w install the weave CNI instead of the default flannel CNI + -h output help +``` +## To use a different AWS profile, VPC, or AMI +The script uses the default AWS profile and defaults the VPC id and AMI id. +To change this default behavior you can export environment variables before running the script. + +Run the script with a specific AWS profile by first exporting the AWS_PROFILE environment variable: +```shell +export AWS_PROFILE=my-aws-profile +``` +To run the script with a specific VPC: +```shell +export VPC_ID=vpc-XXXXXXXXXXXX +``` +To run the script with a specific AMI: +```shell +export AMI_ID=ami-XXXXXXXXXX +``` +To specify a specific Kubernetes version (the eligible choices are [here](https://hub.docker.com/r/rancher/k3s/tags)): +```shell +export K3S_IMAGE_TAG=sometag +``` + +You can also run these inline with the script, without exporting them to your environment. Example: + +```shell +K3S_IMAGE_TAG=v1.24.12-k3s1 ./docs/assets/scripts/developer/k3d-dev.sh +``` + +## After Running The Script + +Follow the instructions from the script output to access and use the cluster. + + +## Install FluxCD + +The Big Bang product is tightly coupled with the GitOps tool FluxCD. Before you can deploy Big Bang you must deploy FluxCD on your k8s cluster. To guarantee that you are using the version of FluxCD that is compatible with the version of Big Bang that you are deploying use the Big Bang provided [script](../../scripts/install_flux.sh). You will need your Iron Bank pull credentials and command line access to the k8s cluster from your workstation. + +```shell +./scripts/install_flux.sh -u your-user-name -p your-password +``` + +## Deploy Bigbang + +From the bigbang directory, deploy BigBang via helm. +```shell +helm upgrade -i bigbang chart/ -n bigbang --create-namespace --set registryCredentials.username=XXXXX --set registryCredentials.password='XXXXX' -f chart/ingress-certs.yaml -f chart/values.yaml +``` + +Overrides can be supplemented by adding references to the specific yaml file, the right-most values file will take highest precedence: +```shell +-f ../other-overrides.yaml +``` + +## Testing Keycloak + +Refer to this [documentation](package-integration/sso.md#Prerequisites) for various options for testing Keycloak which requires two ingresses on the same EC2 instance. + +## Troubleshooting + +1. If you are on a Mac, ensure that you have GNU sed command installed. Otherwise, you will see this error and the kubeconfig will not be updated with the IP from the instance. + + ```console + copy kubeconfig + config 100% 3019 72.9KB/s 00:00 + sed: 1: "...": extra characters at the end of p command + + ``` + +2. If you get a failure from the script, study and correct the error. Then run script with "-d" option to clean up resources. Then re-run your original command. + +3. Occasionally, a ssh command will fail because of connection problems. If this happens, the script will fail with "unexpected EOF". Simply try again. Run the script with `-d` to clean up resources. Then re-run your original command. diff --git a/docs/developer/ci-workflow.md b/docs/developer/ci-workflow.md new file mode 100644 index 0000000000000000000000000000000000000000..431392be40ea65d4cccfac60b816db60ae08ed28 --- /dev/null +++ b/docs/developer/ci-workflow.md @@ -0,0 +1,200 @@ +# Big Bang GitLab Continuous Integration (CI) Workflow + +This document is meant to serve as an overview of the pipeline stages required to get a commit merged. There are package, bigbang, and infrastructure pipelines. + +[[_TOC_]] + +## Bigbang Runners Overview + +### Privileged Runners + + These run on a privileged node pool with limited access to allow for docker in docker k3d clusters. + * Package runners: + * Separate runners for each BBTOC stage: graduated, incubating, and sandbox. + * These run package k3d pipelines. + * bigbang runner: + * Runner used specifically for the bigbang repo. + * This runs bigbang k3d pipelines. + +### Non-Privileged Runners + + These run on a non-privileged node pool. + * Generic runner: + * This runner picks up all non-privileged stages within all pipelines: configuration validation, chart update check, and pre vars. + * Used to spin up infrastructure testing clusters. + * Release runner: + * This runner handles all package and release stages in all pipelines. + * Hashes, signs, and pushes all artifacts to bigbang umbrella s3 bucket. + +## Package Pipeline Stages + +This pipeline is triggered by the following for individual bigbang packages: + +* Merge Request (MR) events + * **NOTE:** Currently upgrade step only runs during MR events +* Manual tag events +* Commits to default branch + +![Package Pipeline](../assets/imgs/developer/package-pipeline.png) + +[Link to draw.io diagram file](../assets/diagrams/developer/bb-gitlab-ci-diagram.drawio). This diagram file should be modified on draw.io and exported into this repository when the developer/CI workflow changes. It is provided here for ease of use. + +### Chart Update Check + +This stage validates that the required files have been updated; README, Changelog, and Chart.yaml. All of these are needed to ensure a package releases can be created. If changes are only documentation a 'SKIP UPDATE CHECK' can be added to the merge request title to skip this check. + +### Configuration Validation + +This stage runs a `helm conftest` which is a plugin for testing helm charts with Open Policy Agent. It provides the following checks: + +* Confirms that the helm chart is valid (e.g., should fail similar to how a helm lint fails if there is bad yaml). +* Runs the helm chart against a set of rego policies. Currently, these tests will only raise warnings on "insecure" things and will allow pipeline to proceed. + +This stage also validates the oscal-component.yaml and checks for api deprecations within the package. + +### Validate MR + +This stage checks the MR description to ensure the `## Upgrade Notices` section contains information that is not the default `(Include any relevant notes about upgrades here or write "N/A" if there are none)`. This section is required to be filled out as if an upgrade notice is present, r2d2 will pull it into the Release Notes for the corresponding milestone. These Notices should be seen and written as customer facing when a template/secret/value name is updated that may require users to alter their configuration, this is not meant for internal or CI facing notes. + +### Package Tests + +This stage verifies several easy-to-check assumptions, including the following: + +* Does package successfully install? +* Does package successfully upgrade (from master)? +* Package specific tests. + +If required, the upgrade step can be skipped when the MR title starts with 'SKIP UPGRADE.' + +### Auto Tag + +When there is a merge into the default branch of a package, this stage is triggered and it will create a tag based on the version in the packages Chart.yaml. + +### Package + +This stage is triggered when a protected tag is created. It is responsible for populating the image list, packaging the repo, prepping release, publishing to the s3 bucket, and pulling release notes from the changelog. + +### Release + +Upon successful completion of the package stage, this release stage will use those artifacts and run the gitlab release-cli utility to publish the release. + +### Creating bigbang MR + +Post merge to the default branch and tag creation above, the last step of the package release stage will perform `Creating bigbang Merge Request` which will pull down information from the package MR and auto increment the package's `git/helmRepo.tag` value along with pulling in the CHANGELOG and linking the package merge request. This stage can be skipped by adding `skip-bb-mr` label to the package MR pre-tag/release pipeline if a bigbang MR is already opened that will be manually updated to include the new tag. + +## bigbang Pipeline Stages + +This pipeline is triggered by the following for bigbang: + +* MR events + * **NOTE:** Currently upgrade step only runs during MR events +* Manual tag events +* Commits to default branch + +The pipeline is split into several stages: + +![BB Pipeline](../assets/imgs/developer/bb-pipelines.png) + +[Link to draw.io diagram file](../assets/diagrams/developer/bb-gitlab-ci-diagram.drawio). This diagram file should be modified on draw.io and exported into this repository when the developer/ci workflow changes. It is provided here for ease of use. + +### Pre Vars + +This stage generates a terraform var, grabs merge request labels, checks for changes from master to determine what packages have changes, and validates the oscal-component.yaml. + +### Smoke Tests + +For fast feedback testing, an ephemeral in cluster pipeline is created using [`k3d`](https://k3d.io) that lives for the lifetime of the gitlab ci job (max 1 hour). Within that cluster, BigBang is deployed, and an initial set of smoke tests are performed against the deployment to ensure basic conformance. + +This stage verifies several easy to check assumptions, including: + +* Does BigBang successfully install? +* Does BigBang successfully upgrade (from master)? +* Are endpoints routable? + +This stage will fail if: + +* script failures +* gitrepositories status condition != ready +* expected helm releases are not present +* helm releases fail or timeout +* kustomization secrets are not ready or timeout +* deployments status condition != ready +* jobs status condition != complete +* statefulsets/daemonsets not 100% ready (ex. 0/1) +* any virtual service endpoints are not accessible + +This stage also serves as a guide for local development, and care is taken to ensure all pipeline actions within this stage are repeatable locally. + +This stage is ran on every MR event, and is a requirement for merging. + +### Package + +This stage is triggered when a protected tag is created. It is responsible for populating the image list, packaging repos, prepping release, publishing to the s3 bucket, and pulling release notes from the changelog. + +### Release + +Upon successful completion of the package stage this release stage will use those artifacts and run the gitlab release-cli utility to publish the release. + +## Infrastructure Testing Pipeline Stages + +Ultimately, BigBang is designed to deploy production ready workloads on real infrastructure. While local and ephemeral clusters are excellent for fast feedback during development, changes must ultimately be tested on real clusters on real infrastructure. + +As part of Big Bang's architecture, it is expected work on any CNCF conformant Kubernetes cluster, on multiple clouds, and on premise environments. By very definition, this means infrastructure testing is _slow_. To strive for a pipeline with a happy medium of providing fast feedback while still exhaustively testing against environments that closely mirror production, __infrastructure testing only occurs on manual actions on merge request commits.__ +This requires adding `test-ci::infra` label to your MR. In addition, infrastructure testing pipeline is run nightly on a schedule. + +**NOTE:** Due to the amount of resources and time required for this pipeline, the `test-ci::infra` label should be used sparingly. The scheduled nightly run will ideally catch issues if they are already in master. The `test-ci::infra` label should mainly be used when: + +* Your changes affect the infra ci +* Your changes are large in scope and likely to behave differently on "real" clusters + +When you are comfortable your branch is ready to be merged, opening up an merge request will trigger the creation of a suite of infrastructure testing jobs which will require a manual action from a project maintainer (assuming smoke tests have passed). Once the commit(s) are validated against the infrastructure tests, your changes are ready to be merged! + +For _most_ of the infrastructure testing, `terraform` is chosen as the IAC tool of choice for infrastructure that BigBang owns, while the cluster creation process follows the vendors recommended installation process. + +The infrastructure pipeline is designed to have _no_ human interaction, and is scoped to the lifecycle of the pipeline. This means a single pipeline is fully responsible for provisioning infrastructure, but just as important, deprovisioning infrastructure, ensuring resources are not orphaned. + +More information on the full set of infrastructure tests are provided in the following: + +![Infra Pipeline](../assets/imgs/developer/infra-test-pipelines.png) + +[Link to draw.io diagram file](../assets/diagrams/developer/bb-gitlab-ci-diagram.drawio). This diagram file should be modified on draw.io and exported into this repository when the developer / ci workflow changes. It is provided here for ease of use. + +### Network Creation + +For each cloud, a BigBang owned network will be created that conform with the appropriate set of tests about to be ran. For example, to validate that Big Bang deploys in a connected environment on AWS, a VPC, subnets, and/or route tables are created, and the outputs are made available through terraform's remote `data` source. + +At this time the infrastructure testing pipeline is only utilizing internet-connect AWS govcloud. + +### Cluster Creation + +The infrastructure pipeline is currently setup to standup an `rke2` cluster by default. + +An `rke2` cluster is created that leverages the upstream [terraform modules](https://repo1.dso.mil/platform-one/distros/rancher-federal/rke2/rke2-aws-terraform) + +It is a hard requirement at this stage that every cluster outputs an admin scoped `kubeconfig` as a gitlab ci artifact. This artifact will be leveraged in the following stages for interacting with the created cluster. + +### Big Bang Installation + +Given the kubeconfig created in the previous stage, BigBang is installed on the cluster using the same installation process used in the smoke tests. + +Like any BigBang installation, several cluster requirements (see [Pre-requisites](../prerequisites/kubernetes-preconfiguration.md)) must be met before BigBang is installed, and it is up to the vendor to ensure those requirements are met. + +### Big Bang Tests + +Assuming BigBang has installed successfully, additional tests residing within the `./tests` folder of this repository are run against the deployed cluster. + +Currently, there are three test scripts that test the following: + +* Wait for resources to be ready, ensures everything goes to running at a kubernetes level. +* Curl VirtualService endpoints, to validate istio works + the UIs are up. +* Fetch a list of non-IB images; this test never fails, but provides some contextual info. + +### Teardown + +Infrastructure teardown happens in the reverse sequence as to which they are deployed, and the pipeline will ensure these teardown jobs are *always* ran, regardless of whether or not the previous jobs were successful. + +Combined with terraform's declarative remote state, the "always on" teardown ensures no orphaned resources are left over once tests are run. + +Within the teardown process, the commit scoped terraform workspace is also deleted to ensure the remote state remains clean. + +For example, if an RKE2 cluster fails to provision, a full teardown of bigbang, RKE2, and the network will be run, even though BigBang was never deployed. This will result in two failing jobs (i.e., RKE2 up and bigbang down), but will ensure that no infrastructure resources become orphaned. diff --git a/docs/developer/dev-oci-workflow.md b/docs/developer/dev-oci-workflow.md new file mode 100644 index 0000000000000000000000000000000000000000..1f48dea92d98e071dcce44fa93391dfdda7188c3 --- /dev/null +++ b/docs/developer/dev-oci-workflow.md @@ -0,0 +1,163 @@ +# Dev Workflow with OCI + +âš ï¸ **NOTE: This doc is a work in progress as OCI is not the expected or default workflow in Big Bang yet. Changes might be made to the structure or process at any time.** âš ï¸ + +If you want to test deployment of a package off of your dev branch, you have two options. This doc covers the OCI workflow. The Git workflow requires nothing more than the values specified in [example git values](../assets/configs/example/git-repo-values.yaml) pointed to your development branch. + +## Package Chart for OCI + +After making your changes to a chart you will need to package it with `helm package chart`. You should see output similar to the following: + +```console +Successfully packaged chart and saved it to: /Users/me/bigbang/anchore/anchore-1.19.7-bb.4.tgz +``` + +Note that Helm strictly enforces the OCI name and tag to match the chart name and version (see [HIP 0006](https://github.com/helm/community/blob/main/hips/hip-0006.md#3-chart-versions--oci-reference-tags)), and artifacts will always match the above syntax. + +## Pushing OCI "Somewhere" + +In order to use this OCI artifact, you will need to push it to an OCI compatible registry. There are multiple options here: you can push to a self-hosted docker registry, push to Registry1 staging, or push to a Big Bang registry. + +### Push to self-Hosted Docker Registry + +The preferred option for OCI storage is in your own personal registry. We can do this by running a registry with the standard docker `registry:2` image. + +**NOTE:** We have to host this as a TLS registry due to limitations with Helm. + +You will want to spin up the registry on the same host as your cluster (i.e., your ec2 instance, if following the normal developer workflow). + +TODO: Make this all happen with a flag in the dev script, this should not be too challenging to automate. + +1. Grab the `*.bigbang.dev` cert to use for the registry. If you follow the commands below, using `curl` and `yq`, this is a simple process. + + ```console + mkdir certs + curl -sS https://repo1.dso.mil/big-bang/bigbang/-/raw/master/chart/ingress-certs.yaml | yq '.istio.gateways.public.tls.key' > certs/tls.key + curl -sS https://repo1.dso.mil/big-bang/bigbang/-/raw/master/chart/ingress-certs.yaml | yq '.istio.gateways.public.tls.cert' > certs/tls.crt + ``` + +1. Set up a docker registry, mounting the certs to expose this as a TLS (HTTPS) registry. + + ```console + docker volume create registry + docker run -d -p 5000:5000 --restart=always --name registry \ + -v registry:/var/lib/registry \ + -v `pwd`/certs:/certs \ + -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/tls.crt \ + -e REGISTRY_HTTP_TLS_KEY=/certs/tls.key \ + registry:2 + ``` + +1. Spin up your development cluster as you normally would. Do not install Flux or Big Bang on top of the cluster yet. + +1. Modify CoreDNS for your cluster to resolve your registry address to the private IP of your cluster host. In the example below we are using `oci.bigbang.dev`. Run the commands from your cluster host (i.e., ec2 instance if using it) listed in the following: + + ```console + # Note that these commands assume a Linux host and k3d cluster + export PRIVATE_IP=$(hostname -I | cut -d " " -f1) + kubectl get configmap -n kube-system coredns -o jsonpath='{.data.NodeHosts}' > newhosts + echo "${PRIVATE_IP} oci.bigbang.dev" >> newhosts + hosts=$(cat newhosts) yq e -n '.data.NodeHosts = strenv(hosts)' > patch.yaml + kubectl patch configmap -n kube-system coredns --patch "$(cat patch.yaml)" + kubectl rollout restart deployment -n kube-system coredns + ``` + +1. If your cluster is not on your local machine, also modify /etc/hosts to resolve your registry address (i.e. `oci.bigbang.dev`) to your cluster/registry host's public IP. + + ```console + # Run on your registry/cluster host to print public IP + curl http://checkip.amazonaws.com/ 2> /dev/null + + # From developer machine add this IP to /etc/hosts + sudo sh -c "echo '<IP from curl above> oci.bigbang.dev' >> /etc/hosts" + ``` + +1. Push OCI artifact to this registry with `helm push <artifact name> oci://oci.bigbang.dev:5000`. Following this example that would look like this: + + ```console + ⯠helm push anchore-1.19.7-bb.4.tgz oci://oci.bigbang.dev:5000 + Pushed: oci.bigbang.dev:5000/anchore:1.19.7-bb.4 + Digest: sha256:3cb826ee59fab459aa3cd723ded448fc6d7ef2d025b55142b826b33c480f0a4c + ``` + +1. Configure your Big Bang values to setup an additional `HelmRepository` and point the package to that repository. Then install Flux and Big Bang as you normally would. + + ```yaml + helmRepositories: + - name: "registry1" + repository: "oci://registry1.dso.mil/bigbang" + existingSecret: "private-registry" + - name: "k3d" + repository: "oci://oci.bigbang.dev:5000" + + addons: + anchore: + helmRepo: + repoName: "k3d" + chartName: "anchore" + tag: "1.19.7-bb.4" + ``` + +### Push to Registry1 Staging + +Another option is to push your OCI artifacts to the Big Bang Staging area of Registry1. This is a SHARED area that internal Big Bang team members have access to. + +**NOTE:** You may overwrite other developer's artifacts if you take this approach. + +1. Login to registry1 with helm: `helm registry login registry1.dso.mil`. Follow the prompts to add your normal username and CLI token for registry1 auth. + + ```console + ⯠helm registry login registry1.dso.mil + Username: myusername + Password: + Login Succeeded + ``` + +1. Push OCI artifact to the staging area with `helm push <artifact name> oci://registry1.dso.mil/bigbang-staging`. + + ```console + ⯠helm push anchore-1.19.7-bb.4.tgz oci://registry1.dso.mil/bigbang-staging + Pushed: registry1.dso.mil/bigbang-staging/anchore:1.19.7-bb.4 + Digest: sha256:3cb826ee59fab459aa3cd723ded448fc6d7ef2d025b55142b826b33c480f0a4c + ``` + +1. Configure your Big Bang values to setup an additional `HelmRepository` and point the package to that repository. An example is provided in the following: + + ```yaml + helmRepositores: + - name: "registry1" + repository: "oci://registry1.dso.mil/bigbang" + existingSecret: "private-registry" + type: "oci" + - name: "staging" + repository: "oci://registry1.dso.mil/bigbang-staging" + existingSecret: "private-registry" + type: "oci" + + addons: + anchore: + helmRepo: + repoName: "staging" + chartName: "anchore + tag: "1.19.7-bb.4" + ``` + +### Push to a Big Bang Registry + +Note that this has a limited use case, since this requires at minimum Istio + Registry to be installed in advance. This may not work well if you are testing Istio or the registry package itself. + +Currently you could leverage any of the following as your OCI registry: + +* Gitlab Project Registries (in a Big Bang installed Gitlab, not Repo1) +* Nexus Registry (refer to CI test values for auto-creation of OCI registry) +* Harbor (currently in sandbox, but functioning well with the test values) + +1. Install a minimal Big Bang on your cluster, not including the package you want to test. You should at least install Istio and the registry (i.e., Gitlab, Nexus, and/or Harbor). + +1. Modify CoreDNS for your cluster to route traffic to `x.bigbang.dev` (e.g., `harbor.bigbang.dev`) to the IP of the public ingress gateway. + +1. Modify `/etc/hosts` to route `x.bigbang.dev` to the Public IP of your instance (if using a remote/ec2 based cluster). + +1. Push Helm tgz to your chosen registry. + +1. Configure your Big Bang values to set up an additional `HelmRepository` and point the package to that repository. diff --git a/docs/developer/develop-package.md b/docs/developer/develop-package.md new file mode 100644 index 0000000000000000000000000000000000000000..d1b6c9fb831b5264feb4e8bd43522e60787bef5f --- /dev/null +++ b/docs/developer/develop-package.md @@ -0,0 +1,218 @@ +# Package Development + +Package is the term we use for an application that has been prepared to be deployed with the Big Bang helm chart. Big Bang Packages are wrappers around Helm charts. All of the pertinent information should be included in the chart/values.yaml for configuration of the Package. These values are then available to be overridden in the Big Bang chart/values.yaml file. The goal of these Packages is to take something that might be very complex and simplify it for consumers of Big Bang. Rational and safe defaults should be used where possible while also allowing for overriding values when fine-grained control is needed. As much as possible, test after each step so that the errors don't pile up; "code a little, test a little." The steps are provided in the following: + +1. Create a repository under the appropriate group (e.g., Security Tools, Developer Tools, Collaboration Tools) in [Repo1](https://repo1.dso.mil/big-bang/apps). + +2. Create a "main" branch that will serve as the master branch. + +3. There are two ways to start a new package. + + a. If there is no upstream helm chart, we create a helm chart from scratch. Here is a T3 video that demonstrates creating a new helm chart. Create a directory called "chart" in your repo, change to the chart directory, and scaffold a new chart in the chart directory. + + ```shell + # Scaffold new helm chart + mkdir chart + cd chart + helm create name-of-your-application + ``` + + b. If there is an existing upstream chart, we will use it and modify it. Essentially we create a "fork" of the upstream code. Use kpt to import the helm chart code into your repository. Note that kpt is not used to keep the Package code in sync with the upstream chart. It is a one time pull just to document where the upstream chart code came from. Kpt will generate a Kptfile that has the details. Do not manually create the "chart" directory. The kpt command will create it. Here is an example from when Gitlab Package was created. It is a good idea to push a commit "initial upstream chart with no changes" so you can refer back to the original code while you are developing. + + ```shell + kpt pkg get https://gitlab.com/gitlab-org/charts/gitlab.git@v4.8.0 chart + ``` + +4. Run a helm dependency update that will download any external sub-chart dependencies. Commit any *.tgz files that are downloaded into the "charts" directory. The reason for doing this is that BigBang Packages must be able to be installed in an air-gap without any internet connectivity. + + ```shell + helm dependency update + ``` + +5. Edit the Chart.yaml and set the chart ```version:``` number to be compliant with the charter versioning which is {UpstreamChartVersion}-bb.{BigBangVersion}. Note that the chart version is not the same thing as the application version. If this is a patch to an existing Package chart then increment the {BigBangVersion}. Here is an example from Gitlab Runner. + + ```yaml + apiVersion: v1 + name: gitlab-runner + version: 0.19.2-bb.3 + appVersion: 13.2.2 + description: GitLab Runner + ``` + +6. In the values.yaml replace public upstream images with IronBank hardened images. The image version should be compatible with the chart version. Here is a command to identify the images that need to be changed. + + ```shell + # list images + helm template <releasename> ./chart -n <namespace> -f chart/values.yaml | grep image: + ``` + + Add the "imagePullSecrets" tag if not already there. You can still test without the private-registry secret existing if your k8s cluster is configured with the pull credentials. Here is an example from Gitlab Package. + + ```yaml + registry: + enabled: true + host: "registry.bigbang.dev" + image: + repository: registry1.dso.mil/ironbank/gitlab/gitlab/gitlab-container-registry + tag: 13.7.2 + pullSecrets: + - name: private-registry + ``` + +7. Add a VirtualService if your application has a back-end API or a front-end GUI. Create the VirtualService in the sub-directory "chart/templates/bigbang/VirtualService.yaml". You will need to manually create the "bigbang" directory. It is convenient to copy VirtualService code from one of the other Packages and then modify it. You should be able to load the application in your browser if all the configuration is correct. + +8. Add NetworkPolices templates in the sub-directory "chart/templates/bigbang/networkpolicies/*.yaml." The intent is to lock down all ingress and egress traffic except for what is required for the application to function properly. Start with a deny-all policy and then add additional policies to open traffic as needed. Refer to the other Packages code for examples. The [Gitlab package](https://repo1.dso.mil/big-bang/product/packages/gitlab/-/tree/main/chart/templates/bigbang/networkpolicies) is a good/complete example. + +9. Add a Continuous Integration (CI) pipeline to the Package. A Package should be able to be deployed by itself, independently from the Big Bang chart. The Package pipeline takes advantage of this to run a Package pipeline test. The package testing is done with a helm test library. Reference the [pipeline documentation](https://repo1.dso.mil/big-bang/pipeline-templates/pipeline-templates#using-the-infrastructure-in-your-package-ci-gitlab-pipeline) for how to create a pipeline and also [detailed instructions](https://repo1.dso.mil/big-bang/apps/library-charts/gluon/-/blob/master/docs/bb-tests.md) in the gluon library. Instructions are not repeated here. + +10. Documentation for the Package should be included. A "docs" directory would include all detailed documentation. Reference other Packages for examples. + + a. You should include a `DEVELOPMENT_MAINTENANCE.md` file in this directory. Outlined in this file should the following: + + * How to update the package. + * How to deploy the package in a test environment. + * How to test the package. + * A list of modifications that were made from the upstream chart. + + +11. Add the following markdown files to complete the Package. Reference other that Packages for examples of how to create them. + + ```shell + CHANGELOG.md < standard history of changes made + CODEOWNERS < list of the code maintainers. Minimum of two people from separate organizations + CONTRIBUTING.md < instructions for how to contribute to the project + README.md < introduction and high level information + ``` + +12. Create a top-level tests directory and inside put a test-values.yaml file that includes any special values overrides that are needed for CI pipeline testing. Refer to other packages for examples. But this is specific to what is needed for your package. + + ```shell + mkdir tests + touch test-values.yaml + ``` + +13. At a high level, a Package structure should look like this (below) when you are finished. + + ```plaintext + ├── chart/ + └── templates/ + └── bigbang/ + ├── networkpolicies/ + ├── egress-*.yaml + └── ingress-*.yaml + └── virtualservice.yaml + ├── tests/ + ├── cypress/ + └── scripts/ + ├── docs/ + ├── DEVELOPMENT_MAINTENANCE.md + ├── documentation-file-1.md + └── documentation-file-2.md + ├── tests/ + └── test-values.yaml + ├── CHANGELOG.md + ├── CODEOWNERS + ├── CONTRIBUTING.md + └── README.md + ``` + +14. Merging code should require approval from a minimum of two codeowners. To se tup merge requests to work properly with CODEOWNERS approval, change these settings in your project: + + a. Under Settings → General → Merge Request Approvals, change "Any eligible user" "Approvals required" to 1. Also ensure that "Require new approvals when new commits are added to an MR" is checked. + + b. Under Settings → Repository → Protected Branches, add the main branch with "Developers + Maintainers" allowed to merge, "No one" allowed to push, and "Codeowner approval required" turned on. + + c. Under Settings → Repository → Default Branch, ensure that main is selected. + +15. Development Testing Cycle: Test your Package chart by deploying with helm. Test frequently so you don't pile up multiple layers of errors. The goal is for Packages to be deployable independently of the bigbang chart. Most upstream helm charts come with internal services like a database that can be toggled on or off. If available use them for testing and CI pipelines. In some cases this is not an option. You can manually deploy required in-cluster services in order to complete your development testing. Here is an example of an in-cluster postgres database. + + ```shell + helm repo add bitnami https://charts.bitnami.com/bitnami + helm install postgres bitnami/postgresql -n postgres --create-namespace --set postgresqlPostgresPassword=postgres --set postgresqlPassword=postgres + # test it + kubectl run postgresql-postgresql-client --rm --tty -i --restart='Never' --namespace default --image bitnami/postgresql --env="PGPASSWORD=postgres" --command -- psql --host postgres-postgresql-headless.postgres.svc.cluster.local -U postgres -d postgres -p 5432 + # Postgres commands + \l < list tables + \du < list users + \q < quit + ``` + + Here is an example of an in-cluster object storage service using MinIO (api compatible with AWS S3 storage) + + ```shell + helm repo add minio https://helm.min.io/ + helm install minio minio/minio --set accessKey=myaccesskey --set secretKey=mysecretkey -n minio --create-namespace + # test and configure it + kubectl run minio-mc-client --rm --tty -i --restart='Never' --namespace default --image minio/mc --command -- bash + # MinIo commands + mc alias set minio http://minio.minio.svc.cluster.local:9000 myaccesskey mysecretkey < set a connection alias + mc mb minio/myBucket < make a bucket + mc ls minio < list the buckets + ``` + + Create a local directory on your workstation where you store your helm values override files. Don't make test changes in the Package values.yaml because they could accidentally be committed. The most convenient location is in a sibling directory next to the Package repo. Here is an example directory structure: + + ```plaintext + ├── PackageRepo/ + └── overrides/ + └── override-values.yaml + ``` + + Here are the dev test steps you can iterate: + + ```shell + # Test that the helm chart templates successfully and examine the output to insure expected results + helm template <releasename> ./chart -n <namespace> -f ../overrides/override-values.yaml + # Deploy with helm + helm upgrade -i <releasename> ./chart -n <namespace> --create-namespace -f ../overrides/override-values.yaml + # Conduct testing + # Tear down + helm delete <releasename> -n <namespace> + # Manually delete the namespace to insure that everything is gone + kubectl delete ns <namespace> + ``` + +16. Wait to create a git tag release until integration testing with BigBang chart is completed. You will very likely discover more Package changes that are needed during BigBang integration. When you are confident that the Package code is complete, squash commits and rebase your development branch with the "main" branch. + + ```shell + git rebase origin/main + git reset $(git merge-base origin/main $(git rev-parse --abbrev-ref HEAD)) + git add -A + git commit -m "feat: example conventional commit" + git push --force + ``` + +17. Then, create a merge request to branch "main." + +18. After the merge create a git tag following the charter convention of {UpstreamChartVersion}-bb.{BigBangVersion}. The tag should exactly match the chart version in the Chart.yaml. +example: 1.2.3-bb.0 + +## Private registry secret creation + +In some instances you may wish to manually create a private-registry secret in the namespace or during a helm deployment. There are a couple of ways to do this: + +19. The first way is to add the secret manually using kubectl. This method is useful for standalone package testing/development. + + ```shell + kubectl create secret docker-registry private-registry --docker-server="https://registry1.dso.mil" --docker-username='Username' --docker-password="CLI secret" --docker-email=<your-email> --namespace=<package-namespace> + ``` + +20. The second is to create a yaml file containing the secret and apply it during a helm install. This method is applicable when installing your new package as part of the Big Bang chart. In this example the file name is "reg-creds.yaml": + + Create the file with the secret contents: + + ```yaml + registryCredentials: + registry: registry1.dso.mil + username: "" + password: "" + email: "" + ``` + + Then include a reference to your file during your helm install command by adding the below `-f` to your Big Bang install command: + + ```shell + -f reg-creds.yaml + ``` + +21. Integrate the package using the [Package Integration Documents](package-integration/README.md). diff --git a/docs/developer/development-environment.md b/docs/developer/development-environment.md new file mode 100644 index 0000000000000000000000000000000000000000..3e74fb7d41342f088fb88236529f9ccfa2557519 --- /dev/null +++ b/docs/developer/development-environment.md @@ -0,0 +1,26 @@ +# Development Environment + +[[_TOC_]] + +Big Bang developers use [k3d](https://k3d.io/), a lightweight wrapper to run [k3s](https://github.com/rancher/k3s) (Rancher Lab’s minimal Kubernetes distribution) in Docker. K3d is a virtualized kubernetes cluster that is quick to start and tear down for fast development iteration. K3d is sufficient for 95% of BigBang development work. In limited cases, developers will use real infrastructure k8s deployments with Rancher, Konvoy, EKS, and more. Only k3d is covered in this document. + +It is not recommended to run k3d with Big Bang on your local workstation. Instead, use a remote k3d cluster running on an EC2 instance to shift the compute and network bandwidth to the cloud. Big Bang can be quite resource intensive and it requires a huge download bandwidth for the images. If you do insist on running k3d locally, you should disable certain packages before deploying. You can do this in the values.yaml file by setting the package deploy to false. One of the packages that is most resource-intensive is the logging package. And you should create a local image registry cache to minimize the amount of image downloading. + +There is a script that automates the creation and teardown of a remote k3d development environment. First, read the [script instructions](aws-k3d-script.md), understand what it does, and install required dependencies. Then, run the script [docs/assets/scripts/developer/k3d-dev.sh](../assets/scripts/developer/k3d-dev.sh) from your workstation. The console output at the end of the script will give you the information necessary to access and use the dev environment. Also, there is a video tutorial in Platform One IL2 Confluence. Search for "T3" and click the link to the page. Scroll down the page to the 57th video on 22-February-2022. + +## Prerequisites + +### Required Access + +* AWS GovCloud "Big Bang dev" account: talk to your team government lead for access +* [BigBang repository](https://repo1.dso.mil/big-bang/bigbang) +* [Iron Bank registry](https://registry1.dso.mil/) + +### Local Utilities + +* [Helm](https://helm.sh/docs/intro/install/) +* [kubectl](https://kubernetes.io/docs/tasks/tools/install-kubectl/) +* [AWS cli](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) +* [jq](https://stedolan.github.io/jq/download/) +* [KPT pre v1](https://github.com/kptdev/kpt/releases/tag/v0.39.2) +* optional: [kustomize](https://kubectl.docs.kubernetes.io/installation/kustomize/) diff --git a/docs/developer/ironbank-testing.md b/docs/developer/ironbank-testing.md new file mode 100644 index 0000000000000000000000000000000000000000..b94e02ff334a964b963dd9f29f7af36eb55f34b4 --- /dev/null +++ b/docs/developer/ironbank-testing.md @@ -0,0 +1,49 @@ +# Big Bang Integration Testing Strategy + +This document is to detail the Big Bang integration testing strategy for changes to Big Bang images by the container hardening team. + +## Using Big Bang repository to Test Changes to Big Bang images + +Developers can leverage the Big Bang repository Continuous Integration (CI) pipelines to test the integration with Big Bang core components. Big Bang CI installs core Big Bang applications by default plus additional applications using Merge Request (MR) labels. For example, adding the Nexus label to a Big Bang MR will install Big Bang core (e.g., istio, kyverno, monitoring, tempo, kiali, neuvector, promtail, loki and/or grafana) plus Nexus Repository. + +## Big Bang Core Integration Test + +To perform an integration test with Big Bang core, complete the following: + +1. Create branch in the [Big Bang repository](https://repo1.dso.mil/big-bang/bigbang). +2. Add an override in [bigbang/chart/values.yaml](../../chart/values.yaml) for the image and repository to be tested on your branch. An example is provided below. If testing Nexus, navigate to the Nexus configuration section and modify the values with image and repository overrides. Our CI can pull images from ironbank or ironbank-staging within registry1.dso.mil. + +### Find section in Big Bang chart values: + + NexusRepositoryManager: + values: {} + +### Replace with: + + NexusRepositoryManager: + values: + image: + repository: registry1.dso.mil/ironbank-staging/sonatype/nexus/nexus + tag: <tagToBeTested> + +Big Bang package values can differ from this example. Navigate to the specific Big Bang package in [product packages](https://repo1.dso.mil/big-bang/product/packages) to verify how to override repository and image tag. Repository and image tag can be found in the package values. For example, [Nexus package values](https://repo1.dso.mil/big-bang/product/packages/nexus/-/blob/main/chart/values.yaml) + +3. Push branch to repo1. + +4. Create draft Merge Request (MR) from your branch into master branch. Be sure to leave the MR in draft status and do not include a review label. If you're testing a package not included in Big Bang core, add the appropriate label for that package. Fill out the description with details, such as testing x.y.z image - container hardening team. + +5. Creating an MR should trigger a CI run under the pipelines tab. If the correct package label was added prior to opening the MR, the pipeline should install that package. Review the results of your MR pipeline. Two pipeline jobs are created in the same stage to test the Big Bang umbrella helm chart installation. + +**Clean install: Installs Big Bang core, plus any packages included in labels off of the branch being tested. This tests a clean install of Big Bang to a k3d cluster.** + +**Upgrade: Installs Big Bang core, plus any packages included in labels off of master. Followed by a helm upgrade to the branch being tested. This tests the upgrade path on a k3d cluster.** + +6. Reviewing results of pipeline -> navigate to the output of the pipeline jobs. + +### Things to observe from pipeline output: + +* Expand the 03_wait_for_helmreleases.sh. At the bottom of this section, users can review that all pods were running on the cluster at completion of this script. +* Collapse the previous section and review the 03_helm_tests.sh. This section should contain results of our CI tests on the live applications installed by Big Bang. Each package testing is different. Packages with frontends typically include a cypress test. Cypress test artifacts can typically be reviewed from the Job Artifacts. Navigate to browse job artifacts to watch a .mp4 video file of the cypress test for your package. +* Some packages do not include cypress tests. Some do not include tests at all (e.g., istioOperator) In this case we recommend validating that the package installed to the cluster and that the tenant application ran successfully in the CI job output. Verify pods running using the 03_wait_for_helmreleases.sh section and all helmReleases succeeded using the Helmreleases section. + +7. Once testing is complete, close the MR and the branch will be cleaned up automatically. diff --git a/docs/developer/k8s-storage.md b/docs/developer/k8s-storage.md new file mode 100644 index 0000000000000000000000000000000000000000..e667e93704c82abfe826e049087af471720f8099 --- /dev/null +++ b/docs/developer/k8s-storage.md @@ -0,0 +1,122 @@ +# Kubernetes Storage Options + +Use this data to assist in your CSI decision. However, when using a cloud provider, we suggest you use their Kubernetes CSI. + +## Feature Matrix + +| Product | BB Compatible | License Type | In Ironbank | RWX/RWM Support | Airgap Compatible | Cloud Agnostic | +| --------------- | ------------- | ------------------------------------------------------------------------------------------------ | ----------- | ------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------- | +| Amazon EBS CSI | **X** | Apache License 2.0 | | **X** | AWS Dependent | No | +| Azure Disk CSI | Not Tested | Apache License 2.0 | | **X** | Azure Dependent | No | +| Longhorn v1.1.0 | **X** | Apache License 2.0 | | **X** | **X** - [Docs](https://longhorn.io/docs/1.1.0/advanced-resources/deploy/airgap/) | Yes, uses host storage | +| OpenEBS (jiva) | **X** | Apache License 2.0 | | **X** **[Alpha](https://docs.openebs.io/docs/next/rwm.html)** | Manual Work Required | Yes, uses host storage | +| Rook-Ceph | **X** | Rook - Apache License 2.0. Ceph - dual licensed under the LGPL version 2.1 or 3.0 | | **X** | Manual Work Required | Yes, uses host storage | +| Portworx | **X** | Tiered License - [See website](https://docs.portworx.com/reference/licensing/) | | **X** | **X** - [Docs](https://docs.portworx.com/install-portworx/on-premises/airgapped/airgap-install/) | Yes, uses host storage | + +## Benchmark Results + +Benchmarks were tested on AWS with GP2 ebs volumes using using FIO, see [example](../assets/configs/k8s-storage/benchmark.yaml) + +| Product | Random Read/Write IOPS | Average Latency (usec) | Sequential Read/Write | Mixed Random Read/Write IOPS | +| --------------- | ------------------------------------- | ---------------------- | --------------------- | ---------------------------- | +| Amazon EBS CSI | 2997/2996. BW: 128MiB/s / 128MiB/s | 1331.61 | 129MiB/s / 131MiB/s | 7203/2390 | +| Azure Disk CSI | | | | +| Longhorn v1.1.0 | 6155/1551 BW: 230MiB/s / 96.3MiB/s | 1042.53 | 319MiB/s / 130MiB/s | 3804/1267 | +| OpenEBS (jiva) | 2183/770. BW: 76.8MiB/s / 45.8MiB/s | 2059.55 | 132MiB/s / 98.2MiB/s | 1590/533 | +| Rook-Ceph | 10.7k/3205. BW: 503MiB/s / 148MiB/s | 548.36/s | 496MiB/s / 154MiB/s | 6664/2228 | +| Portworx 2.6 | 3016/19.3k. BW: 74.5MiB/s / 85.1MiB/s | 1337.31 | 113MiB/s / 124MiB/s | 35.1k/11.1k | + +## Amazon EBS CSI + +[Website/Docs](https://docs.aws.amazon.com/eks/latest/userguide/ebs-csi.html) + +### Requirements + +- Must be using AWS. + +### Notes + +- Apache License 2.0 +- Very easy to install and use; apply CSI spec and you are ready. + +## Azure Disk CSI + +[Website/Docs](https://docs.microsoft.com/en-us/azure/aks/azure-disk-csi) + +### Requirements + +- Must be using Azure. + +### Notes + +- Apache License 2.0 +- Very easy to install and use; apply CSI spec and you are ready. + +## Longhorn + +[Website/Docs](https://longhorn.io/) + +### Requirements + +- RWX requires `nfs-common` to be installed on the nodes. [Longhorn RWX Docs](https://longhorn.io/docs/1.1.0/advanced-resources/rwx-workloads/) + +### Notes + +- Apache License 2.0 +- Easiest to install. +- Built-in backup tool. +- Documented airgap install process: [Docs](https://longhorn.io/docs/1.1.0/advanced-resources/deploy/airgap/). +- GUI provides data and observability; replica status, cluster health status, backup status, and backup initiation/recovery. +- Native backup to S3 or NFS. + +## OpenEBS + +- [Website/Docs](https://openebs.io/) + +### Requirements + +- Blank and un-partitioned attached disk(s). +- RWX is in Alpha and requires work; [OpenEBS RWX Docs](https://docs.openebs.io/docs/next/rwm.html). + +### Notes + +- Very flexible, supports multiple storage designs. + +| Application requirements | Storage Type | OpenEBS Volumes | +| --------------------------------------------------------------------------------------------- | ------------------------------------ | ------------------------------ | +| Low Latency, High Availability, Synchronous replication, Snapshots, Clones, Thin provisioning | SSDs/Cloud Volumes | OpenEBS Mayastor | +| High Availability, Synchronous replication, Snapshots, Clones, Thin provisioning | Disks/SSDs/Cloud Volumes | OpenEBS cStor | +| High Availability, Synchronous replication, Thin provisioning | hostpath or external mounted storage | OpenEBS Jiva | +| Low latency, Local PV | hostpath or external mounted storage | Dynamic Local PV - Hostpath | +| Low latency, Local PV | Disks/SSDs/Cloud Volumes | Dynamic Local PV - Device | +| Low latency, Local PV, Snapshots, Clones | Disks/SSDs/Cloud Volumes | OpenEBS Dynamic Local PV - ZFS | + +## Rook-Ceph + +[Website/Docs](https://rook.io/) + +### Requirements + +- Blank and un-partitioned attached disk(s) + +### Notes + +- Rook: Apache License 2.0. +- Ceph: dual licensed under the LGPL version 2.1 or 3.0. +- Very Fast + +## Portworx + +[Website/Docs](https://docs.portworx.com/portworx-install-with-kubernetes/) + +### Requirements + +- Blank and un-partitioned attached disk(s) + +### Notes + +- Portworx Essentials is free **up to** 5nodes, 5TB Storage, 500 volumes +- Portworx Enterprise and PX-Backup require paid licenses +- Best Mixed IOPS, average read/write performance +- Install is very picky about the container runtime hostpath +- Tested on Konvoy 1.6.1 due to Portworx issues when using RKE2 diff --git a/docs/developer/mdo-partybus-pipelines.md b/docs/developer/mdo-partybus-pipelines.md new file mode 100644 index 0000000000000000000000000000000000000000..e89aa1977b9036406ebf537d8c1007928e835444 --- /dev/null +++ b/docs/developer/mdo-partybus-pipelines.md @@ -0,0 +1,8 @@ +# MDO Pipelines Overview + +At times, Big Bang will have code for a plugin, binary, and/or extension that we'll need to fork/create/re-host. When we do so, we should have the code ran through a Party Bus MDO pipeline and the resulting artifact used within the Platform. + +1. Create a repo for the code within repo1 under https://repo1.dso.mil/big-bang/apps/product-tools/. +1. This repo will need to be mirrored to code.il2.dso.mil. Create issue for the MDO team within [Jira IL2](https://jira.il2.dso.mil/servicedesk/customer/portal/73) as a "New Pipeline Request" and state that you would like a pipeline and repo created from this repo1 link. +1. Create access token within repo1 project for the IL2 cloning, browse to Settings for the project > Access Tokens > check `read_repository` with a role of `Reporter` enter a name mentioning `partybus-il2` and ensure there is a date of expiration set for 1 year from this creation time > Click `Create project access token` and save the output at the top of the page to send to the MDO team over chat.il4 when prompted. +1. Once mirroring to code.il2 is successful, the pipeline will start running and depending on the language, will run it's specific lint and unit testing stages and eventually get to trufflehog, fortify, dependencyCheck & sonarqube stages at the end. If any of these are throwing errors, you will have to investigate why and can open issues to gain exceptions for any false-positives or other issues within [JIRA IL2](https://jira.il2.dso.mil/servicedesk/customer/portal/73) with a "Pipeline Exception Request". diff --git a/docs/developer/oscal-contributing.md b/docs/developer/oscal-contributing.md new file mode 100644 index 0000000000000000000000000000000000000000..621913ad95250101819af5edacd60fac6bafc4ad --- /dev/null +++ b/docs/developer/oscal-contributing.md @@ -0,0 +1,170 @@ +# Contributing to Package OSCAL Documents within Big Bang + +## Why we have OSCAL documents in Big Bang Packages + +Open Security Controls Assessment Language (OSCAL) artifacts are used in Big Bang packages to provide a standardized format for representing security controls and their implementation details. By using OSCAL artifacts, we ensure consistency, interoperability, and ease of understanding when working with security controls across different systems and tools. + +## The Basics of OSCAL Component Schema + +The OSCAL Component definition schema defines the structure and properties of a component in an OSCAL document. You can find detailed information about the OSCAL Component schema in the official OSCAL documentation: [OSCAL Component Schema](https://pages.nist.gov/OSCAL-Reference/models/latest/component-definition/json-reference/). + +### Example + +The following is an example of our `oscal-component.yaml` file: + +```yaml +component-definition: + uuid: <<unique uuid>> + metadata: + title: << Component Name>> + last-modified: '2021-10-19T12:00:00Z' + version: 20211019 + oscal-version: 1.0.0 + parties: + # Should be consistent across all of the packages, but where is ground truth? + - uuid: 72134592-08C2-4A77-ABAD-C880F109367A + type: organization + name: Platform One + links: + - href: <https://p1.dso.mil> + rel: website + components: + - uuid: <<unique uuid>> + type: software + title: << Component Name >> + description: | + << Fill me out >> + purpose: << Fill me out >> + responsible-roles: + - role-id: provider + party-uuid: 72134592-08C2-4A77-ABAD-C880F109367A # matches parties entry for p1 + control-implementations: + - uuid: <<unique uuid>> + source: https://raw.githubusercontent.com/usnistgov/oscal-content/master/nist.gov/SP800-53/rev5/json/NIST_SP-800-53_rev5_catalog.json + description: + Controls implemented by <component> for inheritance by applications + implemented-requirements: + // for each row + - uuid: 6EC9C476-9C9D-4EF6-854B-A5B799D8AED1 + control-id: <control-id> // The control in the row that has a non-empty cell in the column for this package + description: >- + < insert the contents of the cell in the the table + +``` +## How to validate package OSCAL documents against JSON Schema + +Validating package OSCAL documents against the JSON Schema ensures that they adhere to the defined structure and properties. In addition to having OSCAL component validation within the Big Bang CI pipelines, it is possible to manually validate an OSCAL document against the JSON Schema, you can use JSON Schema validation tools or libraries available for your programming language of choice. + +### OSCAL Schema Compliance + +When creating or updating OSCAL artifacts to reflect changes in the underlying components, it is imperative to ensure the artifacts remain compliant with the schema - allowing for interoperability between tools that will consume the OSCAL. + +[Lula](https://docs.lula.dev) provides awareness of all OSCAL schemas `>=1.0.4` and will both auto-detect the artifact `oscal-version` as well as validate the artifact for validity against said schema. + +Validating any OSCAL model/artifact can be done with the following command: +```bash +lula tools lint -f oscal-component.yaml +``` + +This process is ran in [pipelines](https://repo1.dso.mil/big-bang/pipeline-templates/pipeline-templates/-/blob/master/library/templates.sh?ref_type=heads#L127) to ensure that any modifications to the OSCAL is caught during Configuration Checks. + +## OSCAL Upgrades + +Keeping OSCAL artifacts up-to-date is important in ensuring the long-term success of Big Bang re-usable control information. + +Lula provides an upgrade command to help reduce the cognitive burden when performing this action: + +```bash +lula tools upgrade -f oscal-component.yaml +``` + +This command validates the integrity of the data against the target version schema - determines if there are any required updates to perform - and in the event there are no breaking changes will auto-upgrade the OSCAL artifact. Otherwise Lula will provide information for where information may be lost for remediation purposes. + +## Considerations when Updating Package OSCAL Documents + +When updating package OSCAL documents, it's essential to consider the following: + +* **Ensure PartyID Consistency:** The partyID should remain consistent throughout all packages. Changing the partyID can cause confusion and potential errors. Always verify and ensure that the partyID remains unchanged during updates. +* **Generate New UUID:** Whenever a package OSCAL document is modified, a new Universally Unique Identifier (UUID) should be generated for the updated document. This ensures that the document retains its uniqueness and avoids potential conflicts. + +## How to add a control-implementation - Manual + +To add a control-implementation to a package OSCAL document within Big Bang, follow these steps: + +* Identify the appropriate component or control section in the OSCAL document where the new control-implementation should be added. +* Create a new control-implementation element within the component or control section. +* Populate the necessary properties and values for the control-implementation, such as control ID, implementation status, responsible roles, and associated resources. +* Validate the updated OSCAL document against the JSON Schema to ensure its correctness. + +Adding control-implementations allows for the documentation of specific control implementation details within the Big Bang package. + +## How to add a control-implementation - Automated & Reproducible + +Lula provides the ability to generate component definitions given required context for performing the operation. + +Given the following: +- Source of an OSCAL catalog to pull control information + - This must be the raw source url + - IE https://raw.githubusercontent.com/usnistgov/oscal-content/main/nist.gov/SP800-53/rev5/json/NIST_SP-800-53_rev5_catalog.json +- Controls to include +- Title of the component +- Remark target + +Lula can generate a component definition with the following command: +```bash +lula generate component -c <catalogsource> -r ac-1,ac-2,au-4 --component "Service Mesh" --remarks assessment-objective -o oscal-component.yaml +``` + +Lula will generate a component with a control-implementation containing the controls from the catalog translated to implemented-requirements. + +This operation will both produce an annotation for how to imperatively reproduce the artifact generation as well as allows for merging content into existing objects. If a component already exists in a component-definition and the `-o` flag directs the output of the command into this existing file, Lula will perform a merge operation to add or update existing information as required. + +Example Annotation for Istio and an Impact-Level 4 framework +```yaml +props: + - name: generation + ns: https://docs.lula.dev/oscal/ns + value: lula generate component --catalog-source https://raw.githubusercontent.com/GSA/fedramp-automation/93ca0e20ff5e54fc04140613476fba80f08e3c7d/dist/content/rev5/baselines/json/FedRAMP_rev5_HIGH-baseline-resolved-profile_catalog.json --component 'Istio Controlplane' --requirements ac-14,ac-4,ac-4.21,ac-4.4,ac-6.3,ac-6.9,au-12,au-2,au-3,au-3.1,cm-5,sc-10,sc-13,sc-23,sc-3,sc-39,sc-4,sc-7.20,sc-7.21,sc-7.4,sc-7.8,sc-8,sc-8.1,sc-8.2 --remarks assessment-objective --framework il4 +``` + +## Assessment Automation + +OSCAL generically provides data for security controls of components that can be applied against systems that consume Big Bang. We can further augment that value of OSCAL by implementing [Lula Validations](https://docs.lula.dev/reference/) for which to automatically assess security controls in the context of a single package in isolation or that of a full Big Bang deployment. + +Lula does this by insertion of one-to-many `lula` links per `implemented-requirement` which map the control to a list of `Validations` that perform the collection of holistic context (all pods in a cluster, namespace metadata, etc) and then evaluate that data against a policy which allows for measuring adherence. + +These links can be in the form of an item in the associated `back-matter` of the `component-definition` or a separate local or remote file containing the validations. + +Examples: +```yaml +links: + - href: 'file://./istio/healthcheck/validation.yaml' + rel: lula + text: Check that Istio is healthy with a local validation file + - href: '#7df8abad-d2e3-4944-a500-68bfe4f8c591' + rel: lula + text: Check that Istio is healthy with a validation in the back matter +``` + +Once a link as established as a Lula validation, Lula will collect and perform the execution of a validation and map the result as evidence to support whether the security control (with context of locality) enables a security control to be met in a given environment. + +## Compliance Evaluation + +Given the process above automating the assessment of packages and OSCAL, we can instrument an Automated Governance workflow that ensures all development of a package ensures equal or greater compliance has been met prior to allowing the merge of proposed changes. + +This is accomplished with in a [pipeline](https://repo1.dso.mil/big-bang/pipeline-templates/pipeline-templates/-/blob/master/library/package-functions.sh?ref_type=heads#L483) by using a previous assessment (in the form of the assessment-results OSCAL model artifact) and ensuring that the new assessment meets or exceeds the threshold result, otherwise failing. + +The core of this workflow is as follows: +```bash +# perform validation and create or merge with the existing oscal-assessment-results.yaml artifact +lula validate -f oscal-component.yaml -o oscal-assessment-results.yaml + +# perform evaluation of compliance adherence +lula evaluate -f oscal-assessment-results.yaml + +# If there was no pre-existing oscal-assessment-results.yaml artifact the command will exit successfully stating there is no previous state to evaluate against. + +# If there is a previous threshold result established, it will compare the state of findings, requiring all previously `satisfied` controls to still be `satisfied` otherwise failing. +``` + +**NOTE:** Remember to refer to the OSCAL documentation and guidelines provided by BigBang for specific implementation details and any updates to the contributing process. diff --git a/docs/developer/package-integration/.pages b/docs/developer/package-integration/.pages new file mode 100644 index 0000000000000000000000000000000000000000..c142d8f054d87be70edd1d14293314e60c490db7 --- /dev/null +++ b/docs/developer/package-integration/.pages @@ -0,0 +1,18 @@ +nav: + - Overview: README.md + - Database: database.md + - Documentation: documentation.md + - Flux: flux.md + - Helm Standards: helm-standards.md + - Istio Hardened: istioHardened.md + - Monitoring: monitoring.md + - Network Policies: network-policies.md + - Ownership: ownership.md + - Pipeline: pipeline.md + - Policy Enforcement: policy-enforcement.md + - Service Mesh: service-mesh.md + - SSO: sso.md + - Object Storage: storage.md + - Supported: supported.md + - Testing: testing.md + - Upstream: upstream.md diff --git a/docs/developer/package-integration/IstioHardened.md b/docs/developer/package-integration/IstioHardened.md new file mode 100644 index 0000000000000000000000000000000000000000..39c49d9f5386f97cd81df96ba98501d1ae755ed0 --- /dev/null +++ b/docs/developer/package-integration/IstioHardened.md @@ -0,0 +1,111 @@ +# Istio Hardened +Big Bang has added the `.Values.istio.hardened` map attibute to the values of applications that can be istio-injected (when `.Values.istio.enabled` is `true`). This document walks through the impact of setting `.Values.istio.hardened: true` on how traffic is managed within a given istio-injected package. + +## Prerequisites +In order for `.Values.istio.hardened.enabled: true` to have any impact, the package must also have `.Values.istio.enabled: true` set. This is because all of the resources created by setting `.Values.istio.hardened.enabled: true` are applied to the istio service mesh, which includes istio sidecar proxies. If there are no istio proxies, then no mesh components exist in the namespace and therefore istio Kubernetes resources in the namespace will not effect anything. + +## REGISTRY_ONLY Istio Sidecar resources +When `.Values.istio.hardened.enabled: true` is set, a `Sidecar` resource is applied to the package's namespace that sets the outboundTrafficPolicy of the Sidecar to `REGISTRY_ONLY`. What this means is that for pods with an istio-proxy running as a "sidecar", the only egress traffic allowed is for traffic that is destinated for a service that exists within the istio service mesh registry. + +By default, all Kubernetes Services are added to this registry. However, cluster-external hostnames, IP addresses, and other endpoints will NOT be reachable with this Sidecar in place. For example, if an application attempts to reach out to the Kubernetes API Service at `kubernetes.default.svc.cluster.local` (or any of it's SANs), the request will not be blocked by the Sidecar. Conversely, if the application attempts to reach out to s3.us-gov-west-1.amazonaws.com, the request with fail unless there is a ServiceEntry (see below) that adds s3.us-gov-west-1.amazonaws.com to the service mesh registry. This Sidecar is added in order to provide defense in depth, working alongside NetworkPolicies to prevent data exfiltration by malicious actors. + +## ServiceEntry Istio resources +Because some application have well-documented requirements to reach out to cluster external endpoints (S3 is one common example), Big Bang has added ServiceEntries to get those endpoints included in the Istio service registry. If we missed one, please open an issue detailing what endpoint needs to be whitelisted with a ServiceEntry. Alternatively, you can create your own whitelisted endpoints by using the `.Values.istio.hardened.customServiceEntries` list, which will generate a ServiceEntry according to the `.spec` map you set. + +> `customServiceEntries` is there for *edge cases* that may be specific to your requirements, and not all `customServiceEntries` may be appropriate for all Big Bang users. + +### Example customServiceEntry +To create a ServiceEntry for google, the corresponding customServiceEntry attribute could be set: +```yaml +istio: + enabled: true + hardened: + enabled: true + customServiceEntries: + - name: "allow-google" + enabled: true + spec: + hosts: + - google.com + location: MESH_EXTERNAL + ports: + - number: 443 + protocol: TLS + name: https + resolution: DNS +``` + +This would result in the following ServiceEntry being created: +```yaml +apiVersion: networking.istio.io/v1beta1 +kind: ServiceEntry +metadata: + name: allow-google + namespace: my-app-namespace +spec: + hosts: + - google.com + location: MESH_EXTERNAL + ports: + - name: https + number: 443 + protocol: TLS + resolution: DNS +``` + +For more information on writting ServiceEntries, see [this documentation](https://istio.io/latest/docs/reference/config/networking/service-entry/) + +## Authorization Policies +[Istio Authorization Policies](https://istio.io/latest/docs/reference/config/security/authorization-policy/#AuthorizationPolicy) will be created provided `istio.enabled` and `istio.hardened.enabled` are set to `true`. There is a default deny policy which will deny everything that is not explicitly allowed with another policy. Denials look like a 403 with the message `RBAC: access denied`. Other policies that are created might include allow ingress gateways, allow monitoring, or allow a supported service that needs access to these resources. You will find these listed under `istio.hardened` as named objects that have three properties: `enabled`, `namespaces`, and `principals`. There are also templates which allow you to create custom authorization policies through additional values, these are described in greater detail below. The last rules to note are global rules. These are any rules created in the `istio-system` namespace. Rather than affecting just the `istio-system` namespace, they will apply to all namespaces. + +### Rules +Apart from the default deny, most rules will be explicit allows. Included rules will be for other supported packages. Any other rules will need to be created with the templates described below. Rules affect a namespace. Rules go on the "server" in the "client-server" relationship. + +Application Order: +1. If there are any CUSTOM policies that match the request, evaluate and deny the request if the evaluation result is deny. +1. If there are any DENY policies that match the request, deny the request. +1. If there are no ALLOW policies for the workload, allow the request. +1. If any of the ALLOW policies match the request, allow the request. +1. Deny the request. + +### Templates +Templates are just an easy way to inject more authorization policies by just modifying values files. They essentially allow you to pass in a name and spec, then have it deploy an authorization policy with that spec in the `.Release.Namespace`. They also allow you to enable/disable specific policies for development, debugging, and other purposes. + +If you pass these partial values: +```yaml +istio: + hardened: + customAuthorizationPolicies: + - name: "allow-my-namespace" + enabled: true + spec: + selector: + matchLabels: + app.kubernetes.io/name: "server-app" + action: ALLOW + rules: + - from: + - source: + namespaces: + - "my-namespace" +``` + +This policy would be generated: +```yaml +apiVersion: security.istio.io/v1 +kind: AuthorizationPolicy +metadata: + name: "allow-my-namespace" + namespace: {{ $.Release.Namespace }} + +spec: + selector: + matchLabels: + app.kubernetes.io/name: "server-app" + action: ALLOW + rules: + - from: + - source: + namespaces: + - "my-namespace" +``` diff --git a/docs/developer/package-integration/README.md b/docs/developer/package-integration/README.md new file mode 100644 index 0000000000000000000000000000000000000000..ec9182ac206f1854e01c3d4d94f7007010885d08 --- /dev/null +++ b/docs/developer/package-integration/README.md @@ -0,0 +1,20 @@ +# Integration: Overview + +The following documents should be followed, in order, to fully integrate a new package into Big Bang: + +1. [Get BBTOC Approval](https://repo1.dso.mil/big-bang/product/bbtoc/-/blob/main/process/Package%20Maintenance%20Tracks.md): Follow the BBTOC Package Maintenance Tracks process to get approval for package integration +1. [Upstream Helm Chart](upstream.md): Initialize package workspace using an upstream Helm chart +1. [CICD Pipeline](pipeline.md): Establish a baseline package pipeline for testing changes +1. [Flux Helm Chart](flux.md): Create Flux compatible GitOps Helm chart required by Big Bang +1. [Service mesh](service-mesh.md): Integrate with service mesh for ingress/egress +1. [Monitoring](monitoring.md): Enable metrics scraping on product +1. [Database](database.md): If required, add internal and external database support using Big Bang values +1. [Object Storage](storage.md): If required, add internal or external object storage support using Big Bang values +1. [Single-Sign On](sso.md): If available, add Single-Sign On (SSO) through internal or external identify provider +1. [Additional Tests](testing.md): Add testing to validate basic functionality +1. [Network Policies](network-policies.md): Add ingress/egress policies to restrict network traffic for security +1. [Policy Enforcement](policy-enforcement.md): Update package to comply with default security and governance policies in Big Bang +1. [Istio Hardening](../IstioHardened.md): Update package to comply with Istio hardening policies in Big Bang +1. [Supported Package](supported.md): Migrate package into the Big Bang repo as a supported package +1. [Final Documentation](documentation.md): Add additional Big Bang documentation for final release +1. [Big Bang Merge Request](bigbang-merge-request.md): Create Big Bang Merge Request and run all packages pipeline diff --git a/docs/developer/package-integration/bigbang-merge-request.md b/docs/developer/package-integration/bigbang-merge-request.md new file mode 100644 index 0000000000000000000000000000000000000000..6c39ee9cd03a3df7345133a6e8cce901ebf2061c --- /dev/null +++ b/docs/developer/package-integration/bigbang-merge-request.md @@ -0,0 +1,6 @@ +# Create a Big Bang Merge Request + +Following the steps in the [flux integration](flux.md), create a Merge Request (MR) into Big Bang for your package. +When ready, add the all-packages label to the MR and run the pipeline. This will trigger a pipeline with all big bang packages installed to a k3d cluster. + +A passing all-packages pipeline is required prior to merging the new package. This validates that the additional package works with existing packages. diff --git a/docs/developer/package-integration/database.md b/docs/developer/package-integration/database.md new file mode 100644 index 0000000000000000000000000000000000000000..0186aab635a0f5c24ddb63f4ff086bab8e39174e --- /dev/null +++ b/docs/developer/package-integration/database.md @@ -0,0 +1,134 @@ +# Database Integration + +If the package you are integrating connects to a database, you will need to follow the instructions below to integrate this feature into Big Bang. + +## Prerequisites + +- Existing database + +## Integration + +Stateful applications in Big Bang use two different common patterns to connect to a database. + +1. Package charts accept value inputs for hostname, username, and password. The package chart generates the required Kubernetes Secret and/or ConfigMap. + +2. Package chart accepts a secret name where all the DB connection info is defined. In these cases, we generate the secret in the Big Bang umbrella chart. + +Both ways will first require the following step: + +1. Add database values for the package in bigbang/chart/values.yaml + + **NOTE:** Names of key/values may differ based on the specific package application. Please refer to package chart values to validate key/value pairs are valid. Refer to specific application documentation for additional information on connecting to a database. + +```yaml +<package> + database: + # -- Hostname of a pre-existing PostgreSQL database to use. + host: "" + # -- Port of a pre-existing PostgreSQL database to use. + port: "" + # -- Database name to connect to on host. + database: "" + # -- Username to connect as to external database, the user must have all privileges on the database. + username: "" + # -- Database password for the username used to connect to the existing database. + password: "" +``` + +Example: [Anchore](https://repo1.dso.mil/big-bang/bigbang/-/blob/10d43bea9351b91dfc6f14d3b0c2b2a60fe60c6a/chart/values.yaml#L882) + +**Next details the first way packages connect to a pre-existing database.** + +1. Package charts accept values for hostname, username, and/or password. The package chart generates the required Secret and/or ConfigMap. + + * Add a conditional statement to `bigbang/chart/templates/<package>/values` that will check if the database values exist and creates the necessary postgresql values. + + * To disable internal package StatefulSet database: input server, database, username, and port database values. Internal database is disabled by setting `enabled: false`. + + * If database values are NOT provided, then the internal package StatefulSet database is enabled by default with default credentials. + +```yaml +# External Postgres config +{{- with .Values.<package>.database }} +postgresql: + {{- if and .host .username .password .database .port }} + # Use external database + enabled: false + postgresqlServer: {{ .host }} + postgresqlDatabase: {{ .database }} + postgresqlUsername: {{ .username }} + service: + port: {{ .port }} + {{- else }} + # Use internal database, defaults are fine + enabled: true + {{- end }} +{{- end }} +``` + +Example: [Anchore](https://repo1.dso.mil/big-bang/bigbang/-/blob/10d43bea9351b91dfc6f14d3b0c2b2a60fe60c6a/chart/templates/anchore/values.yaml#L49) + +**The alternative way packages connect to a pre-existing database is detailed below.** + +1. Package chart accepts a secret name where all the DB connection info is defined. In these cases, we make the secret in the BB chart. + + * Add conditional statement in `chart/templates/<package>/values.yaml` to add values for database secret, if database values exist. Otherwise, the internal database is deployed. + +```yaml +{{- with .Values.addons.<package>.database }} +{{- if and .username .password .host .port .database }} +database: + secret: "<package>-database-secret" +{{- else }} +postgresql: + image: + pullSecrets: + - private-registry + install: true +{{- end }} +{{- end }} +``` + +Example: [Mattermost](https://repo1.dso.mil/big-bang/bigbang/-/blob/10d43bea9351b91dfc6f14d3b0c2b2a60fe60c6a/chart/templates/mattermost/mattermost/values.yaml#L49) + + * Create manifest that uses database values to create the database secret referenced above. + +```yaml +{{- if .Values.addons.<package>.enabled }} +{{- with .Values.addons.<package>.database }} +{{- if and .username .password .host .port .database }} +apiVersion: v1 +kind: Secret +type: Opaque +metadata: + name: <package>-database-secret + namespace: <package> + labels: + {{- include "commonLabels" $ | nindent 4}} +stringData: + DB_CONNECTION_CHECK_URL: "postgres://{{ .username }}:{{ .password }}@{{ .host }}:{{ .port }}/{{ .database }}?connect_timeout=10&sslmode={{ .ssl_mode | default "disable" }}" + DB_CONNECTION_STRING: "postgres://{{ .username }}:{{ .password }}@{{ .host }}:{{ .port }}/{{ .database }}?connect_timeout=10&sslmode={{ .ssl_mode | default "disable" }}" +{{- end }} +{{- end }} +{{- end }} +``` + +Example: [Mattermost](https://repo1.dso.mil/big-bang/bigbang/-/blob/10d43bea9351b91dfc6f14d3b0c2b2a60fe60c6a/chart/templates/mattermost/mattermost/secret-database.yaml) + +## Validation + +For validating connection to the external database in your environment or testing in CI pipeline, you will need to add the database specific values to your overrides file or `./tests/test-values.yaml` respectively. + +Mattermost Example: + +```yaml +addons: + mattermost: + enabled: true + database: + host: "mm-postgres.bigbang.dev" + port: "5432" + username: "admin" + password: "Pa55w0rd" + database: "db1 +``` diff --git a/docs/developer/package-integration/documentation.md b/docs/developer/package-integration/documentation.md new file mode 100644 index 0000000000000000000000000000000000000000..92b978c65a08b7644bd737222afb13d439699df4 --- /dev/null +++ b/docs/developer/package-integration/documentation.md @@ -0,0 +1,9 @@ +# Documentation + +Big Bang requires some additional documentation for supported packages to help users understand how it interacts with other components. The following are documents that should be created or updated for integration into Big Bang: + +- Package Architecture: Refer to [Big Bang's Architecture instructions](../../understanding-bigbang/package-architecture/ref-package.md). Examples are included in [the package architecture](../../understanding-bigbang/package-architecture/README.md). +- [Big Bang Packages](../../packages.md) +- [Default Credentials](../../guides/using-bigbang/default-credentials.md) +- [Licensing](../../understanding-bigbang/licensing-model.md) +- [Minimum Hardware Requirements](../../prerequisites/minimum-hardware-requirements.md) diff --git a/docs/developer/package-integration/flux.md b/docs/developer/package-integration/flux.md new file mode 100644 index 0000000000000000000000000000000000000000..6a0ef42288e25c40c3a58a45e1efbbbc5cf8200e --- /dev/null +++ b/docs/developer/package-integration/flux.md @@ -0,0 +1,402 @@ +# Flux Integration + +Following the steps in this guide will result in the `integration` job being run for Third Party and Sandbox pipelines. + +If there's a need to disable this job, add `SKIP INTEGRATION` to the title of the Merge Request. + +Big Bang uses a continuous deployment tool, [Flux](https://fluxcd.io/) to deploy packages using Helm charts sourced from Git ([GitOps](https://www.weave.works/technologies/gitops/)). This document will cover how to integrate a Helm chart, from a mission application or other package, into the Flux pattern required by Big Bang. Once complete, you will be able to deploy your package with Big Bang. + +## Prerequisites + +* [Helm](https://helm.sh/docs/intro/install/) +* [Kubectl](https://kubernetes.io/docs/tasks/tools/#kubectl) +* [Git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git) +* A multi-node Kubernetes cluster to deploy Big Bang and your package +* A [Big Bang project containing the upstream Helm chart](./upstream.md) + +> Throughout this document, we will be setting up an application called `podinfo` as a demonstration. + +## Big Bang Helm Chart + +The purpose of the Big Bang Helm chart is to create a Big Bang compatible, easy-to-use spec for deploying the package. Reasonable and safe defaults are provided and any needed secrets are auto-created. We accept the trade-off of easy deployment for complicated template code. Details are provided in the following: + + ```shell + gitrepository.yaml # Flux GitRepository, configured by Big Bang chart values. + helmrelease.yaml # Flux HelmRelease, configured by Big Bang chart values. + namespace.yaml # Namespace creation and configuration + imagepullsecret.yaml # Secret creation for image pull credentials + values.yaml # Big Bang customization of the package and passthrough values. + ``` + +Create a new Helm chart for Big Bang resources in the root of your Git repository: + +```shell +# short name of the package +export PKGNAME=podinfo + +# version of the package in semver format +export PKGVER=6.0.0 + +# Make directory structure +mkdir -p bigbang/templates/$PKGNAME + +# Create values file +touch bigbang/values.yaml + +# Copy helpers from Big Bang +curl -sL -o bigbang/templates/_helpers.tpl https://repo1.dso.mil/big-bang/bigbang/-/raw/master/chart/templates/_helpers.tpl + +# Create chart file +cat << EOF >> bigbang/Chart.yaml +apiVersion: v2 +name: bigbang-$PKGNAME +description: BigBang compatible Helm chart for $PKGNAME +type: application +version: 0.1.0 +appVersion: "$PKGVER" +EOF +``` + +### Namespace + +The package will be deployed in its own namespace. Big Bang pre-creates this namespace so that labels and annotations can be controlled. Set up `bigbang/templates/$PKGNAME/namespace.yaml` with the following: + +```yaml +{{- $pkg := "podinfo" }} +{{- if (get .Values $pkg).enabled }} +apiVersion: v1 +kind: Namespace +metadata: + name: {{ $pkg }} + labels: + app.kubernetes.io/name: {{ $pkg }} + {{- include "commonLabels" . | nindent 4}} +{{- end }} +``` + +In order for the namespace Helm template to be properly created, the following values need to be added to `bigbang/values.yaml`: + +```yaml +# Identifies if our package should be deployed or ignored +podinfo: + enabled: true +``` + +### Flux Custom Resources + +#### GitRepository + +Flux's source controller uses the [GitRepository](https://fluxcd.io/docs/components/source/gitrepositories/) resource to pull Helm chart changes from Git. Use the [GitRepository API Specification](https://fluxcd.io/docs/components/source/gitrepositories/#specification) to create a `GitRepository` resource named `bigbang/templates/$PKGNAME/gitrepository.yaml` with the following content: + +```yaml +{{- $pkg := "podinfo" }} +{{- if (get .Values $pkg).enabled }} +{{- $gitCredsDict := dict + "name" $pkg + "packageGitScope" (get .Values pkg).git + "rootScope" . + "releaseName" $.Release.Name +}} +apiVersion: source.toolkit.fluxcd.io/v1 +kind: GitRepository +metadata: + name: {{ $pkg }} + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ $pkg }} + {{- include "commonLabels" . | nindent 4}} +spec: + interval: {{ .Values.flux.interval }} + url: {{ (get .Values $pkg).git.repo }} + ref: + {{- include "validRef" (get .Values $pkg).git | nindent 4 }} + {{ include "gitIgnore" . }} + {{- include "gitCredsExtended" $gitCredsDict | nindent 2 }} +{{- end }} +``` + +The `GitRepository` Helm template above requires the following values to be added to `bigbang/values.yaml`: + +```yaml +podinfo: + # The Git location of the package Helm chart + git: + repo: https://repo1.dso.mil/big-bang/product/packages/podinfo + branch: master +``` + +> If you are working on a branch, change `master` to the branch you are working from in the values above. + +#### HelmRelease + +Big Bang exclusively uses Helm charts for deployment through Flux. Using the [HelmRelease API Specification](https://fluxcd.io/docs/components/helm/helmreleases/#specification), create a `HelmRelease` resource named `bigbang/templates/$PKGNAME/helmrelease.yaml` with the following content: + +```yaml +{{- $pkg := "podinfo" }} +{{- $fluxSettings := mergeOverwrite .Values.flux (get .Values $pkg).flux -}} +{{- if (get .Values $pkg).enabled }} +apiVersion: helm.toolkit.fluxcd.io/v2beta2 +kind: HelmRelease +metadata: + name: {{ $pkg }} + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ $pkg }} + {{- include "commonLabels" . | nindent 4}} +spec: + targetNamespace: {{ $pkg }} + chart: + spec: + chart: {{ (get .Values $pkg).git.path }} + interval: 5m + sourceRef: + kind: GitRepository + name: {{ $pkg }} + namespace: {{ .Release.Namespace }} + + {{- toYaml $fluxSettings | nindent 2 }} + + {{- if (get .Values $pkg).postRenderers }} + postRenderers: + {{ toYaml (get .Values $pkg).postRenderers | nindent 4 }} + {{- end }} + valuesFrom: + - name: {{ .Release.Name }}-{{ $pkg }}-values + kind: Secret + valuesKey: "common" + - name: {{ .Release.Name }}-{{ $pkg }}-values + kind: Secret + valuesKey: "defaults" + - name: {{ .Release.Name }}-{{ $pkg }}-values + kind: Secret + valuesKey: "overlays" +{{- end }} +``` + +The following values need to be added into `bigbang/values.yaml` for `HelmRelease`: + +```yaml +podinfo: + # Directory in git where Helm chart is located + git: + path: chart + # Flux specific settings for package + flux: {} +``` + +### ImagePullSecret + +Big Bang images are pulled from Iron Bank. In order to provide credentials for Iron Bank, Big Bang will create a secret for each package called `private-registry.` In `bigbang/templates/$PKGNAME/imagepullsecret.yaml,` add the following content: + +```yaml +{{- $pkg := "podinfo" }} +{{- if (get .Values $pkg).enabled }} +{{- if ( include "imagePullSecret" . ) }} +apiVersion: v1 +kind: Secret +metadata: + name: private-registry + namespace: {{ $pkg }} + labels: + app.kubernetes.io/name: {{ $pkg }} + {{- include "commonLabels" . | nindent 4}} +type: kubernetes.io/dockerconfigjson +data: + .dockerconfigjson: {{ template "imagePullSecret" . }} +{{- end }} +{{- end }} +``` + +> Other secrets can be added for credentials and/or certificates by creating a file named `bigbang/templates/$PKGNAME/secret-<name>.yaml`. Big Bang is responsible for creating these secrets using values from the user. More details are included in the integration documentation for databases, object stores, and/or SSO. + +### Package Values + +Package values (chart/values.yaml) should contain upstream values plus any placeholders of values needed for Big Bang.The following guidelines should be used when adding values to the package: + +* Assume the package will be run without Big Bang. Values enabling features from other packages (e.g., metrics, ingress, and/or SSO) should be turned off by default. Big Bang will enable them through overrides. +* Re-use existing chart values rather than adding new ones when possible. +* Only change the default values from the upstream Helm chart when necessary. +* Comment any changes made to the upstream Helm values so it is clear that the changes should carry forward on upgrades. +* Assume that Big Bang will create secrets (e.g., TLS certificates and/or credentials) and provide the reference to the chart. +* Create blank placeholders for Big Bang values to avoid Helm errors during deployment. + +### Override Values + +Big Bang has a few options for overwriting values in packages. The package's `HelmRelease`, that we created earlier, contains a `ValuesFrom` section that references a secret with `common`, `default`, and `overlay` keys. Each of these keys can contain a set of override values that get passed down to the package. Here is a table explaining the difference between the possible overlays: + +| Name | Description | Source | Priority | +| --------- | ----------------------------------------------- | -------------------------------------------- | --------- | +| `overlay` | Values provided by user when deploying Big Bang | `bigbang/values.yaml`:`$PKGNAME.values.*` | Highest 1 | +| `default` | Values created by Big Bang | `bigbang/templates/$PKGNAME/values.yaml`:`*` | 2 | +| `common` | Big Bang values common to all packages | Not currently used | 3 | +| `package` | Package defaults | `chart/values.yaml`:`*` | Lowest 4 | + +This means that if a user provides a value for the package, that overwrites the value Big Bang or the package would create. + +For the package to implement this hierarchy, `bigbang/templates/$PKGNAME/values.yaml` must be created with the following: + +```yaml +{{- $pkg := "podinfo" }} +{{- define "bigbang.defaults.podinfo" -}} + +{{- end }} + +{{- /* Create secret */ -}} +{{- if (get .Values $pkg).enabled }} +{{- include "values-secret" (dict "root" $ "package" (get .Values $pkg) "name" $pkg "defaults" (include (printf "bigbang.defaults.%s" $pkg) .)) }} +{{- end }} +``` + +### Check Syntax + +At this point, you should have a minimum viable set of values in `bigbang/values.yaml` that looks like this: + +```yaml +podinfo: + enabled: true + git: + repo: https://repo1.dso.mil/big-bang/product/packages/podinfo + branch: bigbang + path: chart + flux: {} +``` + +Use the Big Bang default values to make sure our Helm templates don't have any syntax errors. Run the following: + + ```shell + # Get the helm chart + git clone https://repo1.dso.mil/big-bang/bigbang ~/bigbang + + # Check that our chart generates without errors + # We want our local values to override the big bang defaults, so we need to specify both + helm template -n bigbang -f ~/bigbang/chart/values.yaml -f bigbang/values.yaml bigbang-podinfo bigbang + ``` + +### Validation + +To validate that the Helm chart is working, perform the following steps to deploy your package. This assumes you already have a Kubernetes cluster running. + +1. Disable all packages that are enabled by default in Big Bang by adding the following to `bigbang/values.yaml` + + ```yaml + # Network Policies + networkPolicies: + enabled: false + + # Istio + istioOperator: + enabled: false + istio: + enabled: false + + # Gatekeeper + gatekeeper: + enabled: false + clusterAuditor: + enabled: false + + # Logging + eckOperator: + enabled: false + elasticsearchKibana: + enabled: false + fluentbit: + enabled: false + + # Monitoring + monitoring: + enabled: false + + # Other Tools + jaeger: + enabled: false + kiali: + enabled: false + twistlock: + enabled: false + ``` + +1. To enable Big Bang packages that are disabled by default, add the appropriate code block for the Big Bang package from the Big Bang helm chart [values file](https://repo1.dso.mil/big-bang/bigbang/-/blob/master/chart/values.yaml). + + * For example, if you want to test a package's functionality with MinIO, you would add this block from the Big Bang helm chart values file to the package repo's `bigbang/values.yaml` file. + + ```yaml + addons: + minioOperator: + enabled: true + + minio: + enabled: true + ``` + + * This would deploy MinIO in the `integration` stage with default configurations + + * Any values that are present in the Big Bang helm chart values file can be configured here also. The pipeline merges these two files into a single values file before deployment, so the package repo's `bigbang/values.yaml` provides a way to configure a Third Party or Sandbox package along with Big Bang package configurations in a single values file. + + * A `tests/test-values.yaml` in a package repo can be used as override values for the pipeline. It allows pipeline-specific configurations so that the package's `chart/values.yaml` doesn't have to be changed. + +1. Install flux using the [instructions from Big Bang](https://repo1.dso.mil/big-bang/bigbang/-/blob/master/docs/guides/deployment-scenarios/quickstart.md#step-8-install-flux). +1. Install the package using the bigbang Helm chart. + + ```shell + helm upgrade -i -n bigbang --create-namespace -f ~/bigbang/chart/values.yaml -f bigbang/values.yaml bigbang-podinfo bigbang + ``` + +1. Watch the `GitRepository`, `HelmRelease`, and `Pods`: + + ```shell + watch kubectl get gitrepo,hr,po -A + ``` + +1. Troubleshoot any errors. + + ```shell + kubectl get events -A + ``` + + > If you are using a private Git repository or pulling images from a private image repository, you will need to add credentials into the `git.credentials.username`/`git.credentials.password` and/or `registryCredentials.username`/`registryCredentials.password` using the `--set` option for Helm. + +1. Clean up cluster. + + ```shell + helm delete -n bigbang bigbang-podinfo + ``` + +1. Add the following to `bigbang/README.md` to document this Helm charts usage: + + ```markdown + # Big Bang compatible Helm chart + + This helm chart deploys the application using the same methods and values as Big Bang. + + ## Prerequisites + + - Kubernetes cluster matching [Big Bang's Prerequisites](https://repo1.dso.mil/big-bang/bigbang/-/tree/master/docs/guides/prerequisites) + - [FluxCD](https://fluxcd.io/) running in the cluster + - The [Big Bang git repository](https://repo1.dso.mil/big-bang/bigbang) cloned into `~/bigbang` + - [Helm](https://helm.sh/docs/intro/install/) + + ## Usage + + ### Installation + + 1. Install Big Bang. + `helm upgrade -i -n bigbang --create-namespace -f ~/bigbang/chart/values.yaml -f bigbang/values.yaml bigbang ~/bigbang/chart` + 2. Install this chart. + `helm upgrade -i -n bigbang --create-namespace -f ~/bigbang/chart/values.yaml -f bigbang/values.yaml bigbang-podinfo bigbang` + + ### Removal + + `helm delete -n bigbang bigbang-podinfo` + + ``` + +1. Commit your changes. + + > If you are developing something different than `podinfo`, run `grep -ir podinfo` to make sure your replaced all of the instances with your application name. + + ```shell + git add -A + git commit -m "feat: added bigbang helm chart" + git push + ``` diff --git a/docs/developer/package-integration/helm-standards.md b/docs/developer/package-integration/helm-standards.md new file mode 100644 index 0000000000000000000000000000000000000000..354e0333009b8ec2d415c290720610e4ffa21da4 --- /dev/null +++ b/docs/developer/package-integration/helm-standards.md @@ -0,0 +1,124 @@ +# Helm Package Standards + +This document describes the technical guidelines that should be in place when building a Helm chart and integrating it with Big Bang. + +## Helm Package Versioning Scheme + +Big Bang packages follow a standard semantic versioning scheme for both the package tag and the chart version. The package tag will always be in line with the chart version (not the `appVersion`). To distinguish between BigBang specific changes within the semantic version of the upstream chart, a suffix of `-bb.#` will be added to _all_ charts and tags. + +For example, for the upstream [`istio-operator`](https://github.com/istio/istio/tree/1.7.3/manifests/charts/istio-operator) pinned at version `1.7.3`, the Big Bang version (with the modified `values.yaml` for an Iron Bank image) will be tagged `1.7.3-bb.0`. If in the same `istio-operator` release, Big Bang requires chart modifications (such as to support `imagePullSecrets`), then the new version becomes `1.7.3-bb.1`. + +For another example in using the [`kube-prometheus-stack`](https://github.com/prometheus-community/helm-charts/tree/kube-prometheus-stack-12.2.2/charts/kube-prometheus-stack), the upstream is versioned at `12.2.2`, meaning BigBang's initial fork will be `12.2.2-bb.0`. Future additions, such as adding `VirtualServices` for the ingresses, bumps to the `-bb.#` will happen in sequence every time BigBang updates the chart within the same version. + +## Big Bang Values File + +* In the values.yaml file [here](../../../chart/values.yaml), each package should have its own region at `.package_name` if its in Core or `.addons.package_name.` +* User Interface: + * If there exists need for ingress traffic into the package, the package should create a VirtualService conditional on the existence of `istio.enabled` being set to true. This value should default to false. The BigBang chart should set this true for all packages. + * There should be a region under the package for configuring SSO that looks like this when there are multiple packages. + + ```yaml + sso: + enabled: false + kiali: + client_id: kiali + client_secret: "change_me" + jaeger: + client_id: jaeger + client_secret: "change_me" + ``` + + or like this if there is a single user interface: + + ```yaml + sso: + enabled: false + client_id: twistlock_id + client_secret: "change_me" + ``` + + * If sso is enabled and a value is not provided in the SSO configuration of the package, it should default to the top level SSO configuration. +* Database Connections: + * The BigBang chart should prevent the use of a database bundled as part of the package chart by default, and warn if an end user uses one anyways. + * There should be a database section under the package configuration that matches the following section. + + ```yaml + database: + # Entering connection info will enable external database and will auto-create any required secrets. + host: "" + port: "" + username: "" + password: "" + database: "" + type: "" # Optional. One of mysql, mssql, postgres, mongo if ther + ``` + +* Monitoring: + * Charts should expect a value `monitoring.enabled` to be set by the BigBang chart to conditionally create monitoring components (e.g., `ServiceMonitors` and/or `PodMonitors`). This value should default to false. + + +## Secrets + +* The BigBang chart should make an `ImagePullSecret` in the namespace the package will be deployed in. +* If the package chart cannot accept credentials (e.g., for databases) as a value, then the BigBang chart should make the secret with values passed into BigBang and pass the Secret to the package chart by name. + +## Big Bang Helm Release + +* The `ImagePullSecret` name as `private-registry` should be configured in each package's `chart/template/{package}/values.yaml` to be passed in to each Package. + +## Common Values + +* Every object in a package should have the following labels: + +| Key | Description | Example | +| ------| -------| ------| +| app.kubernetes.io/name | The name of the application | `argocd` | +| app.kubernetes.io/instance | The unique name identifying the instance of an application. Name of the `HelmRelease` | `argocd` +| app.kubernetes.io/version | The chart version that manages the object | `1.0.1-bb.10` +| app.kubernetes.io/component | the component within the architecture | `database` | + +Each package shall have the ability to add labels to all objects via a top level `commonLabels` map. The labels that will be passed in from +the Big Bang chart shall include at least: + +| Key | Description | Example | +| ------| -------| ------| +| app.kubernetes.io/part-of | the name of a higher level application this one is part of | `bigbang` | +| app.kubernetes.io/managed-by | the tool being used to manage the operation of an application | `flux` | +| app.kubernetes.io/bigbang-version | The version of bigbang deployed | `1.0.7` | + +which would be passed in via: + +```yaml +commonLabels: + app.kubernetes.io/part-of: bigbang + app.kubernetes.io/managed-by: flux + app.kubernetes.io/bigbang-version: 1.6.0 +``` + +## Big Bang Package Readme Generation + +Follow [this guide](https://repo1.dso.mil/big-bang/product/packages/gluon/-/blob/master/docs/bb-package-readme.md?ref_type=heads) for package readme.md generation. + +Note the Big Bang package README.md is separate from the README.md included as part of the upstream chart. See ArgoCD for an example, [Big Bang package README.md](https://repo1.dso.mil/big-bang/product/packages/argocd/-/blob/main/README.md?ref_type=heads) vs [upstream chart README.md](https://repo1.dso.mil/big-bang/product/packages/argocd/-/blob/main/chart/README.md?ref_type=heads). + +Each package value in values.yaml should have a comment descriptor above the value. We generate the package README.md using a script that expects this format. The README.md will contain a table with default configurations and descriptors pulled from the comments. + +# This is a comment for the value below +enabled: false + +# This comment describes the purpose of the configurable value below +strategy: scalable + +## Kubernetes Objects + +These requirements for the kubernetes components come from the Kubernetes STIG, Kubesec.io and other best practices. + +* Resource Limits and Requests set for cpu and memory and they are [Guaranteed QoS](https://kubernetes.io/docs/tasks/configure-pod-container/quality-service-pod/#create-a-pod-that-gets-assigned-a-qos-class-of-guaranteed) +* Containers are not run in privileged mode +* Read Only Root File System is set to true +* Containers are not run as root +* runAsUser >= 1000 +* Each deployment/daemonset/statefulset should use its own service account with least privilege permission set +* HostPath volumes are not allowed +* All resources contain the [Kubernetes Common Labels](https://kubernetes.io/docs/concepts/overview/working-with-objects/common-labels/) +* All containers contain health and liveness checks diff --git a/docs/developer/package-integration/monitoring.md b/docs/developer/package-integration/monitoring.md new file mode 100644 index 0000000000000000000000000000000000000000..2dbde83768a0b52b1aa7e5952c767412c82c596d --- /dev/null +++ b/docs/developer/package-integration/monitoring.md @@ -0,0 +1,211 @@ +# Monitoring + +Monitoring packages requires a way to scrape metrics, provide those to data storage, and analyze the results. Big Bang uses Prometheus and Grafana as the service for monitoring. Most packages offer built-in Prometheus metrics scraping or an add-on that will scrape the metrics. This document will show you how to integrate metrics scraping with Big Bang. + +## Prerequisites + +Before integrating with Prometheus, you must identify the following: + +* Does the application support metrics exporting for Prometheus? If not, you will need to find a Prometheus exporter to provide this service. +* Does the upstream Helm chart for the application (or exporter) support Prometheus natively? If not, we'll have to create our own monitoring resources. + > Searching the Helm chart for `monitoring.coreos.com` will usually find any resources that support Prometheus. +* What path and port are used to scrape metrics on the application or exporter? +* What services and/or pods are deployed that should be monitored? +* Is there a pre-existing Grafana dashboard that can be leveraged? If not, we will need to create one. + +## Integration + +### Placeholder values + +The package requires placeholder values for whether the monitoring stack (e.g., Prometheus/Grafana) is enabled and what label to use for dashboards. In `chart/values.yaml`, add placeholders for these: + +```yaml +serviceMonitor: + enabled: false + ## Added by Big Bang + dashboards: + # Namespace to put .json ConfigMap so Grafana sidecar will find it + namespace: "" + # Label to apply to dashboard so Grafana sidecar will find it + label: grafana_dashboard +``` + +> In this case, we put the values under `serviceMonitor:` since it already exists in the upstream Helm chart. Otherwise, we would create `monitoring:` for the values. + +### Pass down values + +Big Bang needs to set the placeholders above to the appropriate values. In addition, upstream charts may already have values related to monitoring that need to be set. + +In `bigbang/templates/podinfo/values.yaml`, add the following to pass down the values from Big Bang to PodInfo. + +```yaml +serviceMonitor: + enabled: {{ .Values.monitoring.enabled }} + dashboards: + namespace: monitoring + label: {{ dig "values" "grafana" "sidecar" "dashboards" "label" "grafana_dashboard" .Values.monitoring }} +``` + +### Dependency + +If we plan to scrape metrics from the application with the monitoring stack, we need to make sure the monitoring stack is deployed first so that CRDs are in place before we deploy our resources. To do this, we add a `dependsOn` section in the `bigbang/templates/podinfo/helmrelease.yaml` file like this: + +```yaml +spec: + {{- if or .Values.istio.enabled .Values.monitoring.enabled }} + dependsOn: + {{- if .Values.istio.enabled }} + - name: istio + namespace: {{ .Release.Namespace }} + {{- end }} + {{- if .Values.monitoring.enabled }} + - name: monitoring + namespace: {{ .Release.Namespace }} + {{- end }} + {{- end }} +``` + +> We previously had a dependency on Istio, which we leave in place in this example. + +### Service Monitor + +If the upstream Helm chart provides you with a `ServiceMonitor` and `Service` for scraping metrics, verify that there is a conditional around each one to only deploy them if monitoring is enabled (e.g., `{{- if .Values.serviceMonitor.enabled }}` or `{{- if .Values.monitoring.enabled }}`). + +If the upstream chart does **not** provide a `ServiceMonitor` and `Service` for scraping metrics, you will need to create one yourself using the [Prometheus instructions for running an exporter](https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/user-guides/running-exporters.md). + +> Any new resources should be placed in the `chart/templates/bigbang` folder. + +### RBAC + +If the application is using Role Based Access Control (RBAC), you may need to create rules for Prometheus to access the metrics. Check the upstream Helm chart to make sure this is already done for you, or implement a new `ClusterRole` and `ClusterRoleBinding` into the chart following the [Prometheus RBAC documentation](https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/user-guides/getting-started.md#enable-rbac-rules-for-prometheus-pods) + +### Alerts + +Alerting rules allow you to define alert conditions based on Prometheus expression language expressions and to send notifications about firing alerts to an external service. By creating a `PrometheusRule`, you can configure these conditions for your application. + +You will need to decide what aspects of the application should be monitored and alerted on to detect potential failures in the service it provides. Several examples are listed in the following: + +* Low disk space on a persistent volume +* Loss of connectivity to external resources +* Metrics cannot be scraped +* Operator down +* Pods in CrashLookBackOff state +* Pods restarting too often +* Latency too high +* Web application returns 4xx or 5xx too often +* No log messages for too long +* Pod memory too close to limit + +All of these rules must be based on [PromQL queries](https://prometheus.io/docs/prometheus/latest/querying/basics/) using the application's metrics. + +Once you have identified what you want to monitor, create [Prometheus Alerting Rules](https://prometheus.io/docs/prometheus/latest/configuration/alerting_rules/) and add them to a [PrometheusRule](https://prometheus-operator.dev/docs/operator/api/#prometheusrule) resource. The rule should reside in the `chart/templates/bigbang` folder and only be deployed if monitoring is enabled. + +Some examples of rules can be found in the [Big Bang monitoring chart](https://repo1.dso.mil/big-bang/product/packages/monitoring/-/tree/main/chart/templates/prometheus/rules). + +### Dashboards + +Dashboards are important for administrators to understand what is happening in your package and when action needs to be taken. + +1. Create a dashboard: + + Some packages or maintainers provide Grafana dashboards upstream, otherwise you can search [Grafana's Dashboard Repository](https://grafana.com/grafana/dashboards/) for a relevant Dashboard. If there is already a ready-made Grafana dashboard for your package provided upstream, you should use [Kpt](https://googlecontainertools.github.io/kpt/installation/) to sync it into monitoring package (for example flux provides the JSON dashboards in their upstream repo): + + ```shell + # There isn't a dashboard for podinfo, so we use flux as an example here + kpt pkg get https://github.com/fluxcd/flux2.git//manifests/monitoring/grafana/dashboards@v0.9.1 chart/dashboards/ + ``` + + If you need to create your own dashboard, open Grafana and use `Create > Dashboard`. Add a panel and setup the query to pull custom data from your package or general data about your pods (e.g., container_processes). After you have saved your dashboard in Grafana, use `Share (icon) > Export` to save the dashboard to a .json file in `chart/dashboards`. You can leave the `Export for sharing externally` slider off. + +1. We will store dashboards in a ConfigMap for Grafana's sidecar to parse. Create a ConfigMapList in `chart/templates/bigbang/dashboards.yaml` to store all of the dashboards: + + ```yaml + {{- $pkg := "podinfo" }} + {{- $files := .Files.Glob "dashboards/*.json" }} + {{- if and .Values.serviceMonitor.enabled $files }} + apiVersion: v1 + kind: ConfigMapList + items: + {{- range $path, $fileContents := $files }} + {{- $dashboardName := regexReplaceAll "(^.*/)(.*)\\.json$" $path "${2}" }} + - apiVersion: v1 + kind: ConfigMap + metadata: + name: {{ printf "%s-%s" $pkg $dashboardName | trunc 63 | trimSuffix "-" }} + namespace: {{ default $.Release.Namespace $.Values.serviceMonitor.dashboards.namespace }} + labels: + {{- if $.Values.serviceMonitor.dashboards.label }} + {{ $.Values.serviceMonitor.dashboards.label }}: "1" + {{- end }} + app: {{ $pkg }}-grafana + {{- include (printf "%s.labels" $pkg) $ | nindent 6 }} + data: + {{ $dashboardName }}.json: {{ $.Files.Get $path | toJson }} + {{- end }} + {{- end }} + ``` + + > Podinfo's Helm chart already had a key for monitoring named `serviceMonitor.` You may need to use a different key or create one named `monitoring.` + +1. Commit your dashboard files: + + ```shell + git add -A + git commit -m "feat: Grafana dashboards" + git push + ``` + +1. If your package is being integrated as a supported application in Big Bang, you can add your Dashboards to the core monitoring package. + + Create a new folder within `chart/dashboards/APP_NAME` and sync your JSON files for your dashboard(s) there, whether using KPT from a Github repo or individual files from Grafana's Dashboard Repository. + + Commit your dashboard files: + + ```shell + git add -A + git commit -m "feat: Adding APP_NAME Grafana Dashboards" + git push + ``` + + Any JSON dashboards in the `chart/dashboards` folder automatically get created and imported into the monitoring stack via the Operator. + +## Validation + +### Setup + +Monitoring must be enabled in our Big Bang deployment and our application. We do this by setting `monitoring.enabled`: `true` in `bigbang/values.yaml`. Then, deploy Big Bang and your application to your cluster. + +```shell +# This assumes you have the Big Bang repository cloned in ~/bigbang +helm upgrade -i -n bigbang --create-namespace -f ~/bigbang/chart/values.yaml -f bigbang/values.yaml bigbang ~/bigbang/chart + +# Deploy your application on top of Big Bang using the same values +helm upgrade -i -n bigbang --create-namespace -f ~/bigbang/chart/values.yaml -f bigbang/values.yaml bigbang-podinfo bigbang +``` + +> Don't forget to also include your Big Bang values for [TLS certificates](https://repo1.dso.mil/big-bang/bigbang/-/blob/master/chart/ingress-certs.yaml) and Iron Bank pull credentials. + +```shell +# Wait for the cluster to deploy +watch kubectl get gitrepo,hr,po -A + +# Test ingress to monitoring stack +curl -L https://prometheus.bigbang.dev +curl -L https://grafana.bigbang.dev +``` + +> If your application also has an ingress, test it (e.g. `https://podinfo.bigbang.dev`). + +### Target + +Open `https://prometheus.bigbang.dev` and navigate to `Status > Targets.` The `State` should show `UP` if metrics are being scraped for your package. + +> There should be one `Endpoint` for every replica pod of your package. + +### Alert Rules + +In Prometheus, navigate to `Alerts.` Verify that the `PrometheusRule` alerting rules show up here and are green. + +### Dashboards + +Open `https://grafana.bigbang.dev` and navigate to `Dashboards > Manage.` Make sure your dashboards are listed. Select each one and verify that it is working correctly. diff --git a/docs/developer/package-integration/network-policies.md b/docs/developer/package-integration/network-policies.md new file mode 100644 index 0000000000000000000000000000000000000000..9570d26eb21bdbf7599f942e167d1ba8f335aa03 --- /dev/null +++ b/docs/developer/package-integration/network-policies.md @@ -0,0 +1,244 @@ +# Network Policies + +To increase the overall security posture of Big Bang, network policies are put in place to only allow ingress and egress from package namespaces to other needed services. A deny by default policy is put in place to deny all traffic that is not explicitly allowed. The following is how to implement the network policies per Big Bang standards. + +## Table of Contents + +[[_TOC_]] + +## Prerequisites + +- Understanding of ports and communications of applications and other components within Big Bang. +- `chart/templates/bigbang` and `chart/templates/bigbang/networkpolicies` folders within package for committing bigbang specific templates. + +## Integration + +All examples in this documentation will center on [podinfo](https://repo1.dso.mil/big-bang/product/packages/podinfo). + +### Default Deny + +In order to keep Big Bang secure, a default deny policy must be put into place for each package. Create `default-deny-all.yaml` inside `chart/templates/bigbang/networkpolicies` with the following details: + +```yaml +{{ if .Values.networkPolicies.enabled }} +# Default deny everything to/from this namespace +kind: NetworkPolicy +apiVersion: networking.k8s.io/v1 +metadata: + name: default-deny-all + namespace: {{ .Release.Namespace }} +spec: + podSelector: {} + policyTypes: + - Ingress + - Egress + egress: [] + ingress: [] +{{- end }} +``` + +### Default Allow + +For packages with more than one pod/deployment and those pods/deployments need to talk to each other, add a policy that allows all ingress/egress between pods in the namespace. Create `default-allow-ns.yaml` inside `chart/templates/bigbang/networkpolicies` with the following details: + +```yaml +{{- if .Values.networkPolicies.enabled }} +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: default-allow-ns + namespace: {{ .Release.Namespace }} +spec: + podSelector: {} + policyTypes: + - Ingress + - Egress + ingress: + - from: + - podSelector: {} + egress: + - to: + - podSelector: {} +{{- end }} +``` + +### Was Something Important Blocked? + +There are a few ways to determine if a network policy is blocking egress or ingress to or from a pod. +* Test things from the pod's perspective using ssh/exec. See [this portion](../../guides/deployment-scenarios/sso-quickstart.md#step-18-update-inner-cluster-dns-on-the-workload-cluster) of the keycloak quickstart for an example of how do to that. +* Curl a pod's IP from another pod to see if network polices are blocking that traffic. Use `kubectl pod -o wide -n <podNamespace>` to see pod IP addresses. +* Check the pod logs (or curl from one container to the service) for a `context deadline exceeded` or `connection refused` message. + +### Allowing Exceptions + +* Egress exceptions to consider: + * Pod to pod + * SSO: + * When available, use a value from the helm values for the port. + * Otherwise, use the SSO default and allow egress to all IPs, except the cloud metadata IP. The default port should be 443. + * Storage database: + * When available, use a value from the helm values for the port. + * Otherwise, use the database default and allow egress to all IPs, except the cloud metadata IP. + * Istiod for istio-proxy sidecars +* Ingress exceptions to consider: + * Kube-api + * Prometheus + * Istio for virtual service + * Web endpoints +* Once you have determined an exception needs to be made, create a template in `chart/templates/bigbang/networkpolicies`. +* NetworkPolicy templates follow the naming convention of `direction-destination.yaml` (eg: egress-dns.yaml). +* Each networkPolicy template in the package will have an if statement checking for `networkPolicies.enabled` and will only be present when `enabled: true` + +For example, if the podinfo package needs to send information to istiod, add the following content to a file named `egress-istio-d.yaml`: + +```yaml +{{- if and .Values.networkPolicies.enabled .Values.istio.enabled }} +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: egress-istiod + namespace: {{ .Release.Namespace }} +spec: + podSelector: {} + policyTypes: + - Egress + egress: + - to: + - namespaceSelector: + matchLabels: + app.kubernetes.io/name: istio-controlplane + podSelector: + matchLabels: + app: istiod + ports: + - port: 15012 +{{- end }} +``` + +Similarly, if prometheus needs access to podinfo to scrape metrics, create an `ingress-monitoring-prometheus.yaml` file with the following contents: + +```yaml +{{- if and .Values.networkPolicies.enabled .Values.monitoring.enabled }} +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: ingress-monitoring-prometheus + namespace: {{ .Release.Namespace }} +spec: + policyTypes: + - Ingress + ingress: + - from: + - namespaceSelector: + matchLabels: + app.kubernetes.io/name: monitoring + podSelector: + matchLabels: + app: prometheus + ports: + # Port numbers will vary, dependent on the pod + - port: 9797 + podSelector: + matchLabels: + app.kubernetes.io/name: podinfo +{{- end }} +``` + +### Additional Configuration + +Sample `chart/values.yaml` code at the package level: + +```yaml +# BigBang specific Network Policy Configuration +networkPolicies: + enabled: false + + # See `kubectl cluster-info` and then resolve to IP + controlPlaneCidr: 0.0.0.0/0 + + ingressLabels: + app: istio-ingressgateway + istio: ingressgateway +``` + +* Use the `enabled: false` code above in order to disable networkPolicy templates for the package. The networkPolicy templates will be enabled by default when deployed from BigBang because it will inherit the `networkPolicies.enabled` [value](https://repo1.dso.mil/big-bang/bigbang/-/blob/master/chart/values.yaml#L102). +* The ingressLabels portion supports packages that have an externally accessible UIs. Values from Big Bang will also be inherited in this portion to ensure traffic from the correct istio ingressgateway is whitelisted. + +Example of a Big Bang value configuration, `bigbang/templates/podinfo/values.yaml`, when adding a package into Big Bang with networkPolicies: + +```yaml +networkPolicies: + enabled: {{ .Values.networkPolicies.enabled }} + ingressLabels: + {{- $gateway := default "public" .Values.addons.podinfo.ingress.gateway }} + {{- $default := dict "app" (dig "gateways" $gateway "ingressGateway" nil .Values.istio) "istio" nil }} + {{- toYaml (dig "values" "gateways" $gateway "selector" $default .Values.istio) | nindent 4 }} + controlPlaneCidr: {{ .Values.networkPolicies.controlPlaneCidr }} +``` + +* If the package needs to talk to the kube-api service (eg: operators) then the `controlPlaneCidr` value will be required. + * The `controlPlaneCidr` will control egress to the kube-api and be wide open by default, but will inherit the `networkPolicies.controlPlaneCidr` value from Big Bang so the range can be locked down. + +Sample `chart/templates/bigbang/networkpolicies/egress-kube-api.yaml`: + +```yaml +{{- if .Values.networkPolicies.enabled }} +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: egress-kube-api + namespace: {{ .Release.Namespace }} +spec: + podSelector: {} + egress: + - to: + - ipBlock: + cidr: {{ .Values.networkPolicies.controlPlaneCidr }} + {{- if eq .Values.networkPolicies.controlPlaneCidr "0.0.0.0/0" }} + # ONLY Block requests to cloud metadata IP + except: + - 169.254.169.254/32 + {{- end }} + policyTypes: + - Egress +{{- end }} +``` + +- The networkPolicy template for kube-api egress will look like the above, so that communication to the [AWS Instance Metadata](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html) and [Azure Instance Metadata](https://docs.microsoft.com/en-us/azure/virtual-machines/windows/instance-metadata-service) can be limited unless required by the package. + +### Supporting Additional Network Policies through values.yaml + +All Big Bang core and supported addon packages are expected to provide support for the deployment of additional network policies through the values yaml [as per the user guide](../../guides/using-bigbang/network-policies.md). There is a standard mechanism for the implementation of this pattern, with two use cases: + +* Where a package will only be deployed into its own namespace (i.e., the majority of bigbang packages). +* Where a package may be used in inside another package's namespace or deployed into its own namespace (e.g., the gitlab-runner). + +#### Single Namespace + +For this use case, a simple iteration over the values is sufficient to create the needed functionality. The standard pattern is to place this into `<package>/chart/templates/bigbang/networkpolicies/additional-networkpolicies.yaml`: + +``` +{{- if .Values.networkPolicies.enabled }} +{{- range $policy := .Values.networkPolicies.additionalPolicies -}} +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ $policy.name }} +spec: + {{ tpl ($policy.spec | toYaml) $ | nindent 2 }} +--- +{{- end }} +{{- end }} +``` + +#### Multiple Namespaces + +For this use case, refer to [the gitlab runner implementation](https://repo1.dso.mil/big-bang/product/packages/gitlab-runner/-/blob/main/chart/templates/bigbang/networkpolicies/egress-runner-jobs.yaml?ref_type=heads). In this pattern, a given chart may be deployed into one or more namespaces. However, you may only want to enable to control of additional network policies in a certain subset of those namespaces. In these cases, it is sufficient to extend the conditional at the top that checks for the flag in the values: + +``` +{{- if and .Values.networkPolicies.enabled (ne .Release.Namespace "NAMESPACE-YOU-DONT-WANT-TO-DO-THIS-IN") }} +``` + +## Validation + +* Package functions as expected and is able to communicate with all Big Bang touchpoints. diff --git a/docs/developer/package-integration/ownership.md b/docs/developer/package-integration/ownership.md new file mode 100644 index 0000000000000000000000000000000000000000..e036701ab6ed39d8908a42700db58439e2cb126e --- /dev/null +++ b/docs/developer/package-integration/ownership.md @@ -0,0 +1,31 @@ +# Package Owners + +Package owners will be responsible for the following: + +* Cutting releases for the packages and getting into Big Bang. +* Implementing package requirements outlined by the [package integration guide](../README.md). +* Reviewing Merge Requests (MRs) into the package repository. +* Reviewing MR CI/CD pipeline execution results to ensure that there are no regressions in conformance tests nor package cypress tests. +* Tracking upstream changes to packages including new features, architectures, dependencies. +* Upgrading package with new upstream versions. +* Implementing features based on customer requests/requirements. +* Adding and improving interactions with current new new Big Bang packages. +* IronBank interactions: + * Identifying new images to harden. + * Notify IronBank of new versions available. + * Testing new IronBank images. + * [Long term] Providing CI processes for hardening images. + +Package Owners will be identified by the use of [CODEOWNERS](https://docs.gitlab.com/ee/user/project/code_owners.html) files in the repository. + +There must be at least three package owners for each application and they shall be from different companies. Inactive package owners from different value streams or external vendors shall be removed. + +## Package Shadows + +There can also be defined, for each package, shadows that are tracking ownership for each package. These shadows are responsible for filling in for the primary package +owners as needed. This could be the result of a package owner being on leave, or transitioning off of the team. The shadows will maintain situational awareness on all +Merge Requests and be ready and able to participate in resolving production issues. Shadows will be listed in the CODEOWNERS file like package owners. + +## New Package Owners + +A majority of package owners can approve the addition of a new member to the CODEOWNERs file, as long as one company does not control more than half the owners. diff --git a/docs/developer/package-integration/pipeline.md b/docs/developer/package-integration/pipeline.md new file mode 100644 index 0000000000000000000000000000000000000000..d36a342df493f1f8036d60265f106bf2763be3e4 --- /dev/null +++ b/docs/developer/package-integration/pipeline.md @@ -0,0 +1,111 @@ +# Pipeline Integration + +Big Bang contains and uses a continuous deployment tool to deploy packages using Helm charts sourced from Git. This document will cover how to integrate a Helm chart from a mission application or other package into the pattern Big Bang requires. Once complete, you will be able to deploy your package with Big Bang. + +## Prerequisites + +* [Git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git) +* [Docker CLI](https://docs.docker.com/get-docker/) +* [Big Bang package project containing your Helm chart](./upstream.md) + > You will need to have the Container Registry enabled. This can be requested from the Big Bang team. + +> Throughout this document, we will be setting up an application called `podinfo` as a demonstration. + +## Branching + +Each package will have a default branch of `main.` Immutable tags will be used to identify releases and will follow a semver versioning scheme. + +## Package Pipeline + +Pipelines provide rapid feedback to changes in our Helm chart as we develop and should be put in place as early as possible. Big Bang has a few different pipelines that can be used for packages. + +* [bigbang-package](https://repo1.dso.mil/big-bang/pipeline-templates/pipeline-templates/-/blob/master/pipelines/bigbang-package.yaml) +* [sandbox](https://repo1.dso.mil/big-bang/pipeline-templates/pipeline-templates/-/blob/master/pipelines/sandbox.yaml) +* [third-party](https://repo1.dso.mil/big-bang/pipeline-templates/pipeline-templates/-/blob/master/pipelines/third-party.yaml) + + +The pipeline **requires** that all images are stored in either Iron Bank (`registry1.dso.mil`) or Repo1 (`registry.dso.mil`). In some cases, you may be able to substitute images already in Iron Bank for the ones in the Helm chart. For example, images for `curl`, `kubectl` or `jq` can use `registry1.dso.mil/ironbank/big-bang/base.` If you have not already submitted your containers to Iron Bank, [start the process](https://repo1.dso.mil/dsop/dccscr/-/blob/master/README.md). While you are working your way to Iron Bank approval, you can temporarily put the images in `registry.dso.mil` for development by doing the following: + +> Check if the Container Registry is on by navigating to `https://repo1.dso.mil/big-bang/apps/sandbox/<your project>/container_registry`. If you get a 404 error, you need to request a Maintainer turn this feature on in your project via Settings > General > Visibility > Container Registry. + +```shell +# Image Info +export IMGSRC_REPO=docker.io +export IMGSRC_PROJ=stefanprodan +export IMGDST_REPO=registry.dso.mil +export IMGDST_PROJ=platform-one/big-bang/apps/sandbox/podinfo +export IMGNAME=podinfo +export IMGTAG=6.0.0 + +# Pull image locally +docker pull $IMGSRC_REPO/$IMGSRC_PROJ/$IMGNAME:$IMGTAG + +# Retag image +docker tag $IMGSRC_REPO/$IMGSRC_PROJ/$IMGNAME:$IMGTAG $IMGDST_REPO/$IMGDST_PROJ/$IMGNAME:$IMGTAG + +# Login in docker registry +docker login $IMGDST_REPO + +# Push to registry +docker push $IMGDST_REPO/$IMGDST_PROJ/$IMGNAME:$IMGTAG +``` + +1. Update `chart/values.yaml` with either the `registry1.dso.mil` or `registry.dso.mil` for images. For example: + ```yaml + image: + repository: registry.dso.mil/platform-one/big-bang/apps/sandbox/podinfo/podinfo + tag: 6.0.0 + ``` + +1. Update the repo's CI/CD settings to call the pipeline (`Settings > CI/CD > General pipelines > Expand > CI/CD configuration file`). + For Big Bang: + + ```plaintext + pipelines/bigbang-package.yaml@big-bang/pipeline-templates/pipeline-templates:master + ``` + + For Third party: + + ```plaintext + pipelines/third-party.yaml@big-bang/pipeline-templates/pipeline-templates:master + ``` + + For Sandbox: + + ```plaintext + pipelines/sandbox.yaml@big-bang/pipeline-templates/pipeline-templates:master + ``` + +1. Add overlay values for testing into `tests/test-values.yaml.` This will be where you add values needed for running in the pipeline. For now it can be a blank, placeholder. + +1. Commit the changes. + + ```shell + git add -A + git commit -m "feat: package pipeline" + git push + ``` + +1. Big Bang requires a Merge Request (MR) to run the pipeline. Open a MR to merge your branch into the main branch. + + > You will need to add `SKIP UPDATE CHECK` and `SKIP UPGRADE` into the title of the first MR or it will fail. Until you have a baseline Helm chart and CHANGELOG in place, these stages need to be skipped. + +1. The pipeline will install the package, run any Helm tests (`chart/tests`), and run any custom tests (`tests`). + +1. Troubleshoot and fix any failures from the pipeline. + +## Big Bang Integration for Third-Party and Sandbox Packages + +Big Bang uses a continuous deployment tool, [Flux](https://fluxcd.io) to deploy packages using Helm charts sourced from Git ([GitOps](https://www.weave.works/technologies/gitops/)). + +Third-party and sandbox pipelines both have an `integration` stage that will deploy and test a package as a Big Bang compatible package. + +Examples of components that contribute to a package being "Big Bang compatible": + +* Configuring a package to be deployed via Flux custom resource definitions ([GitRepositories](https://fluxcd.io/docs/components/source/gitrepositories/) and [HelmReleases](https://fluxcd.io/docs/components/helm/helmreleases/)). + +* Service mesh components ([Automatic Istio sidecar injection](https://istio.io/latest/docs/setup/additional-setup/sidecar-injection/#automatic-sidecar-injection) and [Istio VirtualService](https://istio.io/latest/docs/reference/config/networking/virtual-service/)). + +This stage also allows any Big Bang core or add-on packages to be deployed alongside a third-party or sandbox package for testing compatibility/functionality. + +To set this up in a package repo, see the guide [here](./flux.md). diff --git a/docs/developer/package-integration/policy-enforcement.md b/docs/developer/package-integration/policy-enforcement.md new file mode 100644 index 0000000000000000000000000000000000000000..a66561166285cadbe8cace95c1b5c8f35afdb843 --- /dev/null +++ b/docs/developer/package-integration/policy-enforcement.md @@ -0,0 +1,86 @@ +# Policy Enforcement + +Big Bang has several policies for Kubernetes resources to ensure best practices and security. For example, images must be pulled from Iron Bank, and containers must be run as non-root. These policies are currently enforced by [Kyverno](https://repo1.dso.mil/big-bang/product/packages/kyverno), which replaces OPA Gatekeeper as the primary policy management tool in Big Bang. + +When integrating your package, you must adhere to the policies enforced by Kyverno, or your resources will be denied by the Kubernetes admission controller. This document will guide you on how to identify and resolve policy violations using Kyverno. + +## Prerequisites + +* A K8s cluster with Big Bang installed. +* Cluster admin access to the cluster with [kubectl](https://kubernetes.io/docs/tasks/tools/). + +## Integration + +### 1. Deploying a Policy Enforcement Tool (Kyverno) + +Kyverno is deployed as the first package in the default Big Bang configuration. This set up allows Kyverno to protect the cluster from the start by enforcing policies on all resources. Your package will interact with the cluster under the governance of Kyverno's policy engine. + +### 2. Identifying Violations Found on Your Application + +In the following section, you will learn how to identify violations found in your package. The app [PodInfo](https://repo1.dso.mil/big-bang/apps/sandbox/podinfo) will be used for all examples. Kyverno provides detailed reports on policy violations. To check for any issues with your package, use the following commands: + +To deploy an application like PodInfo and check for violations: + +```bash +âžœ helm install flux-podinfo chart +Error: INSTALLATION FAILED: 1 error occurred: + * admission webhook "validate.kyverno.svc-fail" denied the request: + +resource Deployment/default/flux-podinfo was blocked due to the following policies + +disallow-root: + autogen-ensure-non-root: 'validation error: Running as root is not allowed. rule + autogen-ensure-non-root failed at path /spec/template/spec/containers/0/securityContext/' + +``` +There was a policy violation, and Kyverno blocked the deployment while providing feedback. + +Kyverno’s output is structured to give clear information about which policies were violated and why, making it easy for users to understand the necessary changes to comply with the policy requirements. + + +### 3. Fixing Policy Violations + +Upon identifying the policy violation(s), modify your Kubernetes manifests according to the Kyverno policies. For instance, if a policy requires that no containers run as privileged, you should ensure your deployment manifests respect this rule. + + +### 4. Exemptions to Policy Exceptions + +While fixing the violation in the application is preferred, sometimes an exception to the policy is necessary, allowing the violation to remain. + +If you require an exception to a policy, please refer to our [exception doc](https://repo1.dso.mil/big-bang/product/packages/policy/-/blob/main/docs/exceptions.md) for more information. + +## Validation + +After fixing the violation, we can run `helm upgrade flux-podinfo chart`. We can then check all the events in our cluster. This will show us if we've fixed our policy violation, but will also reveal non-policy related issues. + +```bash +âžœ helm upgrade flux-podinfo chart +Release "flux-podinfo" has been upgraded. Happy Helming! +NAME: flux-podinfo +LAST DEPLOYED: Mon Apr 08 16:20:36 2024 +NAMESPACE: default +STATUS: deployed +REVISION: 3 +TEST SUITE: None +NOTES: +1. Get the application URL by running these commands: + echo "Visit http://127.0.0.1:8080 to use your application" + kubectl -n default port-forward deploy/flux-podinfo 8080:9898 +``` +Lastly, run `kubectl get all -n default` to verify that your deployment was successful. + +```bash +âžœ kubectl get all -n default +NAME READY STATUS RESTARTS AGE +pod/flux-podinfo-5976b5c4b9-rtr9b 1/1 Running 0 2m20s + +NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE +service/flux-podinfo ClusterIP 10.100.67.167 <none> 9898/TCP,9999/TCP 21m +service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 69m + +NAME READY UP-TO-DATE AVAILABLE AGE +deployment.apps/flux-podinfo 1/1 1 1 2m20s + +NAME DESIRED CURRENT READY AGE +replicaset.apps/flux-podinfo-5976b5c4b9 1 1 1 2m20s +``` diff --git a/docs/developer/package-integration/service-mesh.md b/docs/developer/package-integration/service-mesh.md new file mode 100644 index 0000000000000000000000000000000000000000..7149ecdfa70fe0bad6ff96267b4bf217e29572e3 --- /dev/null +++ b/docs/developer/package-integration/service-mesh.md @@ -0,0 +1,350 @@ + +# Service Mesh Integration + +[Istio](https://istio.io/) provides the [service mesh](https://istio.io/latest/about/service-mesh/) for Big Bang. The service mesh assists with secure traffic routing in the cluster. This document will show you how to update your package to support Big Bang's configuration of Istio. + +## Prerequisites + +- [Helm](https://helm.sh/docs/intro/install/) +- [Kubectl](https://kubernetes.io/docs/tasks/tools/#kubectl) +- [Git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git) +- A multi-node Kubernetes cluster to deploy Big Bang and your package +- A [Big Bang project containing the upstream Helm chart](./upstream.md) + +> Throughout this document, we will be setting up an application called `podinfo` as a demonstration + +## Sidecar + +The [Istio sidecar](https://istio.io/latest/docs/reference/config/networking/sidecar/) is a container that can be automatically injected into all package pods to provide encrypted traffic using [mutual TLS](https://istio.io/latest/docs/tasks/security/authentication/authn-policy/#auto-mutual-tls). It also enables detailed [packet tracing](https://istio.io/latest/docs/tasks/observability/distributed-tracing/jaeger/) and [network traffic metrics](https://istio.io/latest/docs/ops/configuration/telemetry/envoy-stats/). + +When Istio is enabled in the values, we want the sidecar to automatically be injected. This can be achieved by adding the following to `bigbang/templates/podinfo/namespace.yaml`: + +```yaml +metadata: + labels: + {{- if .Values.istio.enabled }} + istio-injection: "enabled" + {{- end }} +``` + +> Most packages are compatible with Istio's sidecar, but if you need to disable this, change the label to `istio-injection: "disabled"` in `bigbang/templates/podinfo/namespace.yaml`. + +## Virtual Service + +If your package has an externally facing service (e.g. URL, port), you will need to setup a `VirtualService` in Istio to access it from outside the cluster. + +> Connections from inside the cluster can use the `Service` and do not require a `VirtualService` + +For `https` connections, Istio will provide end-to-end encryption using TLS termination and mutual TLS to the sidecar. Therefore, the `http` connection on the pod can be used for the virtual service. + +> In some cases, you may have multiple services that need to be exposed. A separate `VirtualService` should be created for each one. See [this example](https://repo1.dso.mil/big-bang/product/packages/anchore-enterprise/-/blob/1.14.7-bb.2/chart/templates/bigbang/anchore-vs.yaml) + +### virtualservice.yaml + +Setup `chart/templates/bigbang/virtualservice.yaml` with the following default content: + +```yaml +{{- $pkg := "podinfo" }} +{{- if and .Values.istio.enabled (get .Values.istio $pkg).enabled }} +apiVersion: networking.istio.io/v1beta1 +kind: VirtualService +metadata: + name: {{ $pkg }} + namespace: {{ .Release.Namespace }} + labels: + {{- include (printf "%s.labels" $pkg) . | nindent 4 }} + app.kubernetes.io/instance: {{ .Release.Name }} +spec: + gateways: + {{- range (get .Values.istio $pkg).gateways }} + - {{ . }} + {{- end }} + hosts: + {{- range (get .Values.istio $pkg).hosts }} + - {{ tpl . $}} + {{- end }} + http: + - route: + - destination: + port: + number: {{ .Values.port | default "8080" }} + host: {{ $pkg }}.{{ .Release.Namespace }}.svc.cluster.local +{{- end }} +``` + +The virtual service must be adjusted to make it compatible with the upstream chart by making the following changes: + +- Change the service name to use the same pattern as other resources in the package. For `podinfo`, this is `template "podinfo.fullname" .`. +- Adjust the labels to adhere to the [standard Helm labels](https://helm.sh/docs/chart_best_practices/labels/#standard-labels) + - Re-use `_helper.tpl` functions from the upstream chart for common labels. In this case, we are including the helper `podinfo.labels`. + - Supplement the missing labels from the helper function. In our case, the helper function was missing `app.kubernetes.io/instance`. +- Typically, there is a value for the http port in `chart/values.yaml`. Use this in `spec.http[0].route[0].destination.port.number`. In this case, we need to change `.Values.port` to `.Values.service.externalPort`. +- If your service name is not the same as the package name, you will need to change `spec.http[0].route[0].destination.host` to the service name. For `podinfo`, it uses the helper `podinfo.fullname` to create the service name. + +The final `virtualservice.yaml` looks like this: + +```yaml +{{- $pkg := "podinfo" }} +{{- if and .Values.istio.enabled (get .Values.istio $pkg).enabled }} +apiVersion: networking.istio.io/v1beta1 +kind: VirtualService +metadata: + name: {{ template "podinfo.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include (printf "%s.labels" $pkg) . | nindent 4 }} + app.kubernetes.io/instance: {{ .Release.Name }} +spec: + gateways: + {{- range (get .Values.istio $pkg).gateways }} + - {{ . }} + {{- end }} + hosts: + {{- range (get .Values.istio $pkg).hosts }} + - {{ tpl . $}} + {{- end }} + http: + - route: + - destination: + port: + number: {{ .Values.service.externalPort | default "8080" }} + host: {{ template "podinfo.fullname" . }}.{{ .Release.Namespace }}.svc.cluster.local +{{- end }} +``` + +> For configuring a connection for something other than `http`, read [Istio's documentation on traffic management](https://istio.io/latest/docs/ops/configuration/traffic-management/) to determine the best course of action. + +### Package Defaults + +In `chart/values.yaml`, default values for Istio are required as placeholders for the Helm templating. We should assume that Istio is **not** installed in our defaults. Add the following content to the values: + +```yaml +# Big Bang Values +domain: bigbang.dev +istio: + enabled: false + podinfo: + enabled: true + gateways: + - istio-system/main + hosts: + - podinfo.{{ .Values.domain }} +``` + +Some notes on the defaults: + +- Always add a comment to modifications made to the upstream chart to assist with upgrading in the future +- `istio-system/main` is the default gateway created by the Istio Helm chart. Big Bang will override this with `istio-system/public`, which it uses as the default gateway. +- The default FQDN is `podinfo.bigbang.dev`, which can be overridden if desired + +#### Big Bang Defaults + +Set the following in `bigbang/values.yaml` to enable Istio for integration testing. These values will be used in the next section: + +```yaml +# Update existing values +istioOperator: + enabled: true +istio: + enabled: true + +# Add new value +podinfo: + ingress: + gateway: "" +``` + +### Big Bang Passdowns + +Big Bang must override the default values for the package to pass-down configuration. It uses `bigbang/templates/podinfo/values.yaml` to do this. Add the following content to the `bigbang.defaults.podinfo` definition: + +```yaml +{{- define "bigbang.defaults.podinfo" -}} +# hostname is deprecated and replaced with domain. But if hostname exists then use it. +domain: {{ default .Values.domain .Values.hostname }} +istio: + enabled: {{ .Values.istio.enabled }} + podinfo: + gateways: + - istio-system/{{ default "public" .Values.podinfo.ingress.gateway }} +{{- end }} +``` + +### Dependencies + +If we have enabled sidecar injection or created a virtual service, we will need to make sure Istio is deployed before our package. This is done in the `HelmRelease` resource using `dependsOn`. Add the following to `bigbang/templates/podinfo/helmrelease.yaml`: + +```yaml +spec: + {{- if .Values.istio.enabled }} + dependsOn: + {{- if .Values.istio.enabled }} + - name: istio + namespace: {{ .Release.Namespace }} + {{- end }} + {{- end }} +``` + +> There are two conditionals on purpose. As we add more dependencies, the outer conditional will be used to determine if any dependencies are enabled. The inner conditional(s) will be used to print each dependency. + +## Validation + +Test the following items to ensure Istio is working properly with your application: + +1. Verify syntax and resolve errors: + + ```shell + helm template -n bigbang -f ~/bigbang/chart/values.yaml -f bigbang/values.yaml bigbang-podinfo bigbang + ``` + +1. Commit changes + + ```shell + git add -A + git commit -m "feat: Istio integration" + git push + ``` + +1. Install Big Bang core with `bigbang.dev` certificate + + ```shell + # Iron Bank credentials are required since you are pulling Big Bang images from Iron Bank + helm upgrade -i -n bigbang --create-namespace -f ~/bigbang/chart/values.yaml -f ~/bigbang/chart/ingress-certs.yaml -f bigbang/values.yaml --set registryCredentials.username=<your Iron Bank username> --set registryCredentials.password=<your Iron Bank PAT> bigbang ~/bigbang/chart + ``` + +1. Install the package + + ```shell + # Iron Bank credentials are optional until we migrate the package to an Iron Bank image + helm upgrade -i -n bigbang --create-namespace -f ~/bigbang/chart/values.yaml -f ~/bigbang/chart/ingress-certs.yaml -f bigbang/values.yaml --set registryCredentials.username=<your Iron Bank username> --set registryCredentials.password=<your Iron Bank PAT> bigbang-podinfo bigbang + ``` + +1. Watch the `GitRepository`, `HelmRelease`, and `Pods` by running `watch kubectl get gitrepo,hr,po -A`. Istio operator, Istio control plane, and the package should all be installed. + +1. Troubleshoot any deployment errors + +1. Validate the TLS certificate is in the secret `istio-system/public-cert`. This is the certificate Istio uses to provide https access to your package from outside the cluster. + + ```shell + kubectl get secret -n istio-system public-cert -o 'go-template={{ index .data "tls.crt" }}' | base64 -d + + ## OUTPUT ## + -----BEGIN CERTIFICATE----- + MIIFYDCCB... + ``` + + > Istio self generates a different certificate for mutual TLS encryption between the Istio control plane and the Istio sidecar inside the pod for traffic into the pod. + +1. Validate Istio's Ingress Gateway service is running. This is the load balancer that listens for traffic coming from outside the cluster. + + ```shell + kubectl describe services -n istio-system public-ingressgateway + + ## OUTPUT ## + Name: public-ingressgateway + Namespace: istio-system + Labels: ... + ``` + + > Big Bang defaults to a single ingress gateway called `public-ingressgateway`. + + In the description, you can see the following: + - Type is `LoadBalancer` + - `status-port` is configured for a health status check on ingress + - `http` is configured to listen on port 80 and forward to port 8080 + - `https` is configured to listen on port 443 and forward to port 8443 + - LoadBalancer Ingress IPs are external IPs assigned to the load balancer that can be accessed outside of the cluster. + +1. Validate Istio's Gateway is configured correctly. Istio will use the Gateway's configuration for TLS encryption and host/port-based traffic matching. + + ```shell + kubectl describe gateway -n istio-system + + ## OUTPUT ## + Name: public + Namespace: istio-system + Labels: ... + ``` + + > Big Bang defaults to a single `Gateway` called `public`. + + By default the Gateway is setup with the following: + + - Connected to the `public-ingressgateway` using `spec.selector` + - `http`: + - Matches traffic for any hostname + - Listen on port 8080 + - Redirects all traffic to `https` + - `https`: + - Matches all hosts in domain (`*.bigbang.dev`) + - Listen on port 8443 + - Uses TLS certificate from `public-cert` for encryption/decryption + +1. Validate the package's virtual service. The virtual service controls the traffic routing between Istio and the package. + + ```shell + kubectl describe virtualservice -n podinfo + + ## OUTPUT ## + Name: podinfo-podinfo + Namespace: podinfo + Labels: ... + ``` + + The virtual service should have the following configured: + - Connection to Istio's `istio-system/public` Gateway using `spec.gateway` + - Matches specific host for package (`podinfo.bigbang.dev`) + - Routes `http` traffic to package's service and port. You can view the service name and `http` port using `kubectl describe service -n podinfo`. + +1. Validate Istio's sidecar is running in the package's pod. + + ```shell + # Get "ready" status of running containers + kubectl get pods -n podinfo -o jsonpath='{range .items[*].status.containerStatuses[*]}{@.name}{" "}{@.ready}{"\n"}' + + ## OUTPUT ## + istio-proxy true + podinfo true + ``` + + > If `istio-proxy` is not listed in the running containers, try restarting your pod. Use `kubectl get deploy,sts,ds -n podinfo` to get the name and `kubectl rollout restart -n podinfo <name>` to restart it. Then, check for the `istio-proxy` container again. + +1. Check the package's URL + + > The hostname `*.bigbang.dev` points to your local IP address of 127.0.0.1. If you are running the cluster on a different machine, you will need to add the hostname and host machine's IP to `/etc/hosts`. + + ```shell + curl -sL https://podinfo.bigbang.dev + + ## OUTPUT ## + { + "hostname": "podinfo-podinfo-86b4b9d85c-rnd4z", + "version": "6.0.0", + "revision": "", + "color": "#34577c", + "logo": "https://raw.githubusercontent.com/stefanprodan/podinfo/gh-pages/cuddle_clap.gif", + "message": "greetings from podinfo v6.0.0", + "goos": "linux", + "goarch": "amd64", + "runtime": "go1.15.7", + "num_goroutine": "8", + "num_cpu": "32" + } + ``` + +You have now verified Istio is working properly with the package. To recap, incoming traffic to the cluster is first processed by Istio's ingress gateway listening on specific ports on each node. `http` and `https` traffic is forwarded to internal ports 8080 and 8443 respectively. The Istio Gateway configuration redirects `http` traffic to `https` and `https` traffic matching the domain (`bigbang.dev`) is TLS decrypted. The Virtual Service configuration processes `https` traffic from the Gateway matching the package's hostname (`podinfo.bigbang.dev`) and routes traffic to the package's service and `http` port. The service then directs traffic to the pod for handling. Since the pod has the Istio sidecar running, the mutual TLS Istio feature will automatically encrypt traffic from the gateway to the pod inside the cluster (even though its http). The sidecar will then decrypt to package before sending it over to the package for handling. The following diagram illustrates this flow: + +> 15006 is the port reserved for Istio Proxy incoming traffic + +```mermaid +graph + A(Browser) -->|https://podinfo.bigbang.dev| B + B(Ingress Gateway) -->|https://*:8443| C + C(Gateway) -->|mTLS-http://*.bigbang.dev:15006| D + D(Virtual Service) -->|mTLS-http://podinfo.bigbang.dev:15006| E + E(Service) --> |mTLS-http://<pod IP>:15006| F + F(Pod/Istio-Proxy) --> |http://localhost:8989| G + G(Pod/PodInfo) +``` + +As a final test, you can use your browser to navigate to `https://podinfo.bigbang.dev` to see the web user interface for podinfo. diff --git a/docs/developer/package-integration/sso.md b/docs/developer/package-integration/sso.md new file mode 100644 index 0000000000000000000000000000000000000000..33802f43b8b6f2aaa66117073065aa9a76274ef4 --- /dev/null +++ b/docs/developer/package-integration/sso.md @@ -0,0 +1,97 @@ +# Single Sign On (SSO) + +Big Bang has configuration for Single Sign-On (SSO) authentication using an identity provider, like Keycloak. If the package supports SSO, you will need to integrate Big Bang's configuration with the package. If the package does not support SSO, an [authentication service](https://repo1.dso.mil/big-bang/product/packages/authservice) can be used to intercept traffic and provide SSO. This document details how to setup your package for either scenario. + +## Prerequisites + +The development environment can be set up in one of three ways: + +1. Two k3d clusters with Keycloak in one cluster and Big Bang and all other apps in the second cluster (see [this quick start guide](../../guides/deployment-scenarios/sso-quickstart.md) for more information). + +1. One k3d cluster using MetalLB to have Keycloak, Big Bang, and all other apps in the one cluster (see [this example config](../../assets/configs/example/keycloak-dev-values.yaml) for more information). + +1. Use a single K3D cluster with two Public IP addresses and the `-a` option on the `k3d-dev.sh` script. This will provision two Elastic IPs, MetalLB, and two specialized `k3d-proxy` containers for connecting the Elastic IPs to the MetalLB IPs. This allows for both a Public and Passthrough Istio Gateway to work simultaneously, specifically to allow for x509 mTLS authentication with Keycloak. Keep in mind that `keycloak.bigbang.dev` will need to point to the Secondary IP in your `/etc/hosts` file. The `k3d-dev.sh` script will inform you of this and return the SecondaryIP. + +## Integration + +### SSO Integration + +All package SSO Integrations within BigBang require a `<package>.sso` block within the BigBang [chart values](../../../chart/values.yaml) for your package along with an enabled flag: + +```yaml +<package>: + sso: + enabled: true +``` + +Based on the authentication protocol implemented by the package being integrated, either Security Access Markup Language (SAML) or OpenID (OIDC), follow the appropriate example below. + +#### OIDC + +For SSO integration using OIDC, at a minimum this usually requires `sso.client_id` and `sso.client_secret` values under the same block above. We can then reference these values further down in either the template values for your package ([eg: Gitlab](../../../chart/templates/gitlab/values.yaml)) or [Authservice Values template](../../../chart/templates/authservice/values.yaml) if there is no built-in support for OIDC or SAML in the package. Authservice will be discussed in more detail further down. + +```yaml +<package>: + sso: + enabled: true + client_id: "XXXXXX-XXXXXX-XXXXXX-APP" + client_secret: "XXXXXXXXXXXX" +``` + +* A `bigbang/chart/templates/<package>/secret-sso.yaml` may need to be created in order to auto-generate secrets if required by the upstream documentation. We can see in the Gitlab documentation for SSO the configuration is handled [via JSON configuration](https://docs.gitlab.com/ee/administration/auth/oidc.html) [within a secret](https://docs.gitlab.com/charts/charts/globals.html#providers). This `secret-sso.yaml` can conditionally be created when `<package>.sso.enabled=true` within the Big Bang values. + + Example: [GitLab SSO Secret template](https://repo1.dso.mil/big-bang/bigbang/-/blob/master/chart/templates/gitlab/secret-sso.yaml) + +* If configuration isn't destined for a secret and the package supports SSO options directly via helm values, we can create and reference the necessary options from the `<package>.sso` values block. For example, elasticsearch documentation specifies a few [values required to enable and configure OIDC](https://www.elastic.co/guide/en/elasticsearch/reference/master/oidc-guide.html#oidc-enable-token) that we can configure and set to be conditional on `<package>.sso.enabled`. + + Example: [ECK Values template](../../../chart/templates/elasticsearch-kibana/values.yaml) + +#### SAML + +For SSO integration using SAML, review the upstream documentation specific to the package and create the necessary items to passthrough from BigBang to the package values under the `<package>.sso` key. For example, Sonarqube configures SSO settings through `sonarProperties` values, which are collected from defined values under `addons.sonarqube.sso` within BigBang and passed through in the [sonarqube Values template](../../../chart/templates/sonarqube/values.yaml). + +### AuthService Integration + +If SSO is not available on the package to be integrated, Istio AuthService can be used for authentication. For AuthService integration, add `<package>.sso.client_id` and `<package>.sso.client_secret` definitions for the package within `../../chart/values.yaml`. Authservice has `global` settings defined and any values not explicitly set in this file will be inherited from the global values (like `authorization_uri`, `certificate_authority`, `jwks`, etc). Review the example below below of the jaeger specific chain configured within BigBang and passed through to the authservice values. + +Example: [Jaeger chain in Authservice template values](../../../chart/templates/authservice/values.yaml) + +In order to use Authservice, Istio injection is required and utilized to route all pod traffic through the Istio side car proxy and the associated Authentication and Authorization policies. + +1. The first step is to ensure your namespace template where you package is destined is istio injected, and the appropriate label is set in `chart/templates/<package>/namespace.yaml`. + + Example: [Jaeger Namespace template](../../../chart/templates/jaeger/namespace.yaml) + +1. Next, ensure the following label is applied to the workload (e.g., pod, deployment, replicaset, and/or daemonset) that will be behind the Authservice gate: + + ```yaml + ... + {{- $<package>AuthserviceKey := (dig "selector" "key" "protect" .Values.addons.authservice.values) }} + {{- $<package>AuthserviceValue := (dig "selector" "value" "keycloak" .Values.addons.authservice.values) }} + ... + metadata: + labels: + {{ $<package>AuthserviceKey }}: {{ $<package>AuthserviceValue }} + ``` + +This label is set in the Authservice package, and is set to `protect=keycloak` by default, the above logic will check if anyone overwrites these values within their BigBang installation and overwrite the label accordingly. + +Example: [Jaeger Values template](../../../chart/templates/jaeger/values.yaml) + +## Validation + +For validating package integration with SSO, carry out the following basic steps: + +1. Enable the package and SSO within Big Bang through the values added in the sections above. + +1. Using an internet browser, browse to your application (e.g., sonarqube.bigbang.dev). + +1. If using built-in SAML/OIDC, click the login button, confirm a redirect to the Identity Provider happens. If using Authservice, confirm a redirect to the Identity Provider happens, prompting user sign in. + +1. Sign in as a valid user. + +1. Successful sign in should return you to the application page. + +1. Confirm you are in the expected account within the application and that you are able to use the application. + +**NOTE:** An unsuccessful sign in may result in an `x509` cert issues, `invalid client ID/group/user` error, `JWKS` error, or other issues. diff --git a/docs/developer/package-integration/storage.md b/docs/developer/package-integration/storage.md new file mode 100644 index 0000000000000000000000000000000000000000..39ca7809991f620a157e5b000ef543bf27fffbc6 --- /dev/null +++ b/docs/developer/package-integration/storage.md @@ -0,0 +1,159 @@ +# Object Storage + +If the package you are integrating connects to object storage (e.g., S3 buckets), you will need to follow the instructions provided here to integrate this feature into Big Bang. + +In Big Bang, Minio is a consistent, performant and scalable object store for the cloud strategies. Minio is Kubernetes-native by design and provides S3 compatible endpoints. + +## Prerequisites + +Blob storage bucket is available with correct permissions, or Minio Addon is enabled at the Big Bang level. Alternatively, you have either: + +1. An existing Minio Instance, or + +1. AWS S3 AccessKey and SecretKey. + +## Integration + +There are currently two ways in Big Bang that packages connect to object storage. They are listed in the following: + +1. Package charts accept values for endpoint, accessKey, and/or bucket values and the chart makes the necessary secret and/or configmap. + +1. Package chart accepts a secret name where all the object storage connection info is defined. In these cases, we make the secret in the BB chart. + +Both ways will first require the following step: + +Add objectStorage values for the package in bigbang/chart/values.yaml. + + Notes: + +* Names of key/values may differ based on the application being integrated (e.g., iamProfile for Gitlab objectStorage values). Please refer to package chart values to ensure key/values coincide and application documentation for additional information on connecting to object storage. + +* Some packages may have in-built object storage and the implementation may vary. + +```yaml +<package> + objectStorage: + # -- Type of object storage to use for Gitlab, setting to s3 will assume an external, pre-existing object storage is to be used. + # Entering connection info will enable this option and will auto-create any required secrets + type: "s3" + + # -- S3 compatible endpoint to use for connection information. + endpoint: "https://s3.amazonaws.com" + + # -- S3 compatible region to use for connection information. + region: "" + + # -- Access key for connecting to object storage endpoint. + # -- If using accessKey and accessSecret, the iamProfile must be left as an empty string: "" + accessKey: "AHDKEJ3BYNC8B2BFJ38NRB" + + # -- Secret key for connecting to object storage endpoint. + # Unencoded string data. This should be placed in the secret values and then encrypted + accessSecret: "LKSJF2343KS9LS21J3KK20" + + # -- Bucket prefix to use for identifying buckets. + bucketPrefix: "prod" + + # -- NOTE: Current bug with AWS IAM Profiles and Object Storage where only artifacts are stored. Fixed in Gitlab 14.5 + # -- Name of AWS IAM profile to use. + # -- If using an AWS IAM profile, the accessKey and accessSecret values must be left as empty strings eg: "" + iamProfile: "" +``` + +**Options for packages connecting to a pre-existing object storage.** + +1. Package charts accept values for endpoint, accessKey, and/or bucket values and the chart makes the necessary secret and/or configmap. + + * Add a conditional statement to `bigbang/chart/templates/<package>/values` that will check if the object storage values exist and creates the necessary object storage values. + + * If object storage values are present, then the internal object storage is disabled by setting `enabled: false` and the endpoint, accessKey, accessSecret, and bucket values are set. + + * If object storage values are NOT present then the minio cluster is enabled and default values declared in the package are used. + +```yaml +{{- with .Values.addons.<package>.objectStorage }} +{{- if and .endpoint .accessKey .accessSecret .bucket }} +fileStore: + accessKey: "{{ .accessKey }}" + accessSecret: "{{ .accessSecret }}" + endpoint: "{{ .endpoint }}" + bucket: "{{ .bucket }}" +{{- end }} +{{- end }} +``` + +Example: [MatterMost](https://repo1.dso.mil/big-bang/bigbang/-/blob/master/chart/templates/mattermost/values.yaml#L101) passes the endpoint and bucket via chart values. + +1. Package chart accepts a secret name where all the object storage connection info is defined. In these cases, we make the secret in the Big Bang chart. + + * Add conditional statement in `chart/templates/<package>/values.yaml` to add values for object storage secret, if object storage values exist. Otherwise, the minio cluster is used. + +```yaml +objectStorage: + config: + secret: <package>-object-storage + key: backups +``` + +Example: [GitLab](https://repo1.dso.mil/big-bang/bigbang/-/blob/master/chart/templates/gitlab/values.yaml#L76) + + * Create the secret in the Big Bang chart. (**NOTE:** Replace `<package>` with your package name in the example below.) + +```yaml +{{- if .Values.addons.<package>.enabled }} +{{- with .Values.addons.<package>.objectStorage }} +{{- if and .endpoint .accessKey .accessSecret }} +apiVersion: v1 +kind: Secret +metadata: + name: <package>-object-storage + namespace: <package> +type: kubernetes.io/opaque +stringData: + bucket: {{ .bucket | default "<package>-bucket" }} + accesskey: {{ .accessKey }} + secretkey: {{ .accessSecret }} + endpoint: {{ .endpoint }} +{{- end }} +{{- end }} +{{- end }} +``` + +Example: [GitLab secret-objectstore.yaml](https://repo1.dso.mil/big-bang/bigbang/-/blob/master/chart/templates/gitlab/secret-objectstore.yaml) + +## Validation + +For validating connection to the object storage in your environment or testing in CI pipeline, you will need to add the object storage specific values to your overrides file or `./tests/test-values.yaml`, respectively. If you are using Minio, ensure `addons.minio.enabled: true`. + +Mattermost Example: + +```yaml +addons: + mattermost: + enabled: true + objectStorage: + endpoint: "s3.amazonaws.com" + accessKey: "AHDKEJ3BYNC8B2BFJ38NRB" + accessSecret: "LKSJF2343KS9LS21J3KK20" + bucket: "myMMBucket" +``` + +For testing with the CI pipeline, create a `tests/dependencies.yaml` and include Minio. + +```yaml +minioOperator: + git: + repo: "https://repo1.dso.mil/big-bang/product/packages/minio-operator.git" + tag: "4.2.3-bb.2" + namespace: "minio-operator" + +minio: + git: + repo: "https://repo1.dso.mil/big-bang/product/packages/minio.git" + tag: "4.2.3-bb.6" + namespace: minio +``` + +Example: [Velero dependencies.yaml](https://repo1.dso.mil/big-bang/product/packages/velero/-/blob/main/tests/dependencies.yaml) + +In order to test that the object storage is working, perform an action that stores a file. For example, if using Mattermost, upload an image for a user avatar. diff --git a/docs/developer/package-integration/supported.md b/docs/developer/package-integration/supported.md new file mode 100644 index 0000000000000000000000000000000000000000..5896909a579eed07430971acf8a7c43a48ced3c6 --- /dev/null +++ b/docs/developer/package-integration/supported.md @@ -0,0 +1,201 @@ +# Supported Package Integration + +After [graduating your package](https://repo1.dso.mil/platform-one/bbtoc/-/tree/master/process) and getting approval to add it to Big Bang, the instructions provided here must be completed. + +[[_TOC_]] + +## Prerequisites + +- [Helm](https://helm.sh/docs/intro/install/) +- [Kubectl](https://kubernetes.io/docs/tasks/tools/#kubectl) +- [Git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git) +- A multi-node Kubernetes cluster to deploy Big Bang and your package +- Graduated package Helm chart in a Git repository + +## Package Updates + +1. Have a Big Bang owner move the package's GitLab project from sandbox to `https://repo1.dso.mil/big-bang/apps/<category>`. + +1. Have a Big Bang maintainer create a new tag and release for your project that matches your Helm chart `version` in `chart/Chart.yaml`. + +## Big Bang Updates + +1. Open an issue under `https://repo1.dso.mil/big-bang/bigbang/-/issues` to track your work for the new package. + +1. Clone the [Big Bang Git repository](https://repo1.dso.mil/big-bang/bigbang) to your machine using `git clone https://repo1.dso.mil/big-bang/bigbang` + +1. Make a branch from the Big Bang chart repository `master` branch. You can automatically create a branch from the Repo1 Gitlab issue or, in some cases, you might manually create the branch. Name the branch with your issue number. For example, if your issue number is `9999` then your branch name can be `9999-my-description`. It is best practice to make branch names short and simple. + +1. Make sure the files described in this [document](./flux.md) have been generated in `chart/templates/<your-package-name>` directory. + +1. More details about secret-*.yaml: The secret template is where the code for secrets go. Typically, you will see secrets for imagePullSecret, sso, database, and possibly object storage. These secrets are a BigBang chart enhancement. They are created conditionally based on what the user enables in the config. For example if the app supports SSO and will need a Certificate Authority supplied to trust the connection to the IdP there should be a `secret-ca.yaml` template to populate a secret with the `sso.certificateAuthority.cert` value in the application namespace. + +1. Merge your default package values from `<your-package-git-folder>/bigbang/values.yaml` into `chart/values.yaml.` Only the "standard" keys used across packages should be used. Keep in mind that values can be passed directly to the package using `.Values.<package>.values.` + + > If your package is an `addon`, it falls into a different location than core packages. In this case, you will need to update all your references from `.Values.<package>` to `.Values.addons.<package>`. + + Example: + + ```yaml + addons: + mypackage: + enabled: false # default to false + git: + repo: https://repo1.dso.mil/big-bang/product/packages/mypackage.git + path: "./chart" + tag: "1.2.3-bb.0" + sso: + enabled: false # default to false + client_id: "" + database: + host: "" + port: "" + username: "" + database: "" + password: {} # unencoded stringData + objectstorage: + type: s3 # supported types are "s3" or "minio" + endpoint: "" # ignored if type is "s3". used only for minio. example " http://minio.minio.svc.cluster.local:9000" + host: s3.amazonaws.com # used for gitlab backup storage + region: us-west-1 + accessKey: "" + accessSecret: "" + bucketPrefix: "" # optional. example: dev- + values: {} + ``` + +1. Edit `tests/test-values.yaml.` These are the settings that the CI pipeline uses to run a deployment test. Set your Package to be enabled and add any other necessary values. Where possible reduce the number of replicas to a minimum to reduce strain on the CI infrastructure. When you commit your code the pipeline will run. You can view the pipeline in the Repo1 Gitlab console. Fix any errors in the pipeline output. The pipeline automatically runs a "smoke" test. It deploys bigbang on a k3d cluster using the test values file. + +1. You will also need to create an MR into the pipeline templates to update [02_wait_for_helmreleases.sh](https://repo1.dso.mil/big-bang/pipeline-templates/pipeline-templates/-/blob/master/scripts/deploy/03_wait_for_helmreleases.sh) and add your package's HR name to the core or addon lists. + + To test your pipeline changes you can make a draft MR pointing to your pipeline branch in `.gitlab-ci.yml`: + ```yaml + include: + - project: 'platform-one/big-bang/pipeline-templates/pipeline-templates' + ref: your-branch + file: '/pipelines/bigbang.yaml' + variables: + PIPELINE_REPO_BRANCH: 'your-branch' + ``` + +1. Create an override directory as a sibling directory next to the Big Bang code directory. Put your override yaml files in this directory. The reason we do this is to avoid modifying the bigbang values.yaml that is under source control. You could accidentally commit it with your secrets. Avoid that mistake by create a local override directory. One option is to copy the tests/ci/k3d/values.yaml to make the override-values.yaml and make modifications. The file structure is like this: + + ```plaintext + ├── bigbang/ + └── overrides/ + ├── override-values.yaml + ├── registry-values.yaml + └── any-other-values.yaml + ``` + + Make the registry-values yaml like this: + + ```yaml + registryCredentials: + - registry: registry1.dso.mil + username: your-name + password: your-pull-token + email: xxx@xxx.xxx + ``` + + You will use these files as arguments in your helm commands. + +1. Verify your package works when deployed through Big Bang. See the instructions below in the ```BigBang Development and Testing Cycle``` for the manual ```imperative``` way to deploy with helm upgrade commands. While testing you should use your package git branch instead of a tag. If you don't null the tag your branch will not get deployed. Here is an example: + + ```yaml + addons: + app1: + git: + tag: null + branch: "999-your-dev-branch-name" + ``` + +1. After you have tested Big Bang integration, complete a Package MR and contact the codeowners to create a release tag. Package release tags follow the naming convention of {UpstreamChartVersion}-bb.{BigBangVersion} – example 1.2.3-bb.0. + +1. Make sure to change the chart/values.yaml file to point to the new release tag rather than your dev branch (i.e. tag: "1.2.3-bb.0" in place of branch: "999-your-dev-branch-name"). example: + + ```yaml + addons: + app1: + git: + tag: "1.2.3-bb.0" + ``` + +1. When you are done developing the BigBang chart features for your Package make a merge request in "Draft" status and add a label corresponding to your package name (must match the name in `values.yaml`). Also add any labels for dependencies of the package that are NOT core apps. The merge request will start a pipeline and use the labels to determine which addons to deploy. Fix any errors that appear in the pipeline. When the pipeline has pass and the MR is ready take it out of "Draft" and add the `status::review` label. Address any issues raised in the merge request comments. + +## BigBang Development and Testing Cycle + +There are two ways to test BigBang, imperative or GitOps with Flux. Your initial development can start with imperative testing. But you should finish with GitOps to make sure that your code works with Flux. + +### Imperative + +You can manually deploy Big Bang with helm command line. With this method, you can test local code changes without committing to a repository. Here are the steps that you can iterate with "code a little, test a little". You should have previously created the ../overrides directory as described in step #10 above. From the root of your local bigbang repo: + +```shell +# Deploy with helm while pointing to your override values files. +# In this example the files are placed on your workstation at ../overrides/* +# Bigbang packages should create any needed secrets from the chart values +# If you have the values file encrypted with sops, temporarily decrypt it +helm upgrade -i bigbang ./chart -n bigbang --create-namespace -f ../overrides/override-values.yaml -f ../overrides/registry-values.yaml -f ./chart/ingress-certs.yaml + +# Conduct testing +# If you make code changes you can run another helm upgrade to pick up the new changes +helm upgrade -i bigbang ./chart -n bigbang --create-namespace -f ../overrides/override-values.yaml -f ../overrides/registry-values.yaml -f ./chart/ingress-certs.yaml + +# Tear down +helm delete bigbang -n bigbang +# Helm delete will not delete the bigbang namespace +kubectl delete ns bigbang +# Istio namespace will be stuck in "finalizing". So run the script to delete it. +./scripts/remove-ns-finalizer.sh istio-system +``` + +### GitOps with Flux + +Using GitOps for development is NOT recommended. Your development iteration cycle time will be slowed down waiting for flux reconciliation. This is not an efficient use of your time. These instructions are included here for informational purposes. You can deploy your development code the same way a customer would deploy using GitOps. You must commit any code changes to your development branches because this is how GitOps works. There is a [customer template repository](https://repo1.dso.mil/big-bang/customers/template) that has an example template for how to deploy using BigBang. You must fork or copy this repo to your own private repo. Make the necessary modifications as explained in the README.md. The setup information is not repeated here. Before committing code it is a good idea to manually run `helm template` and a `helm install` with dry run. This will reveal many errors before you make a commit. Here are the steps you can iterate: + +```shell +# Verify chart code before committing +helm template bigbang ./chart -n bigbang -f ../customers/template/dev/configmap.yaml --debug +helm install bigbang ./chart -n bigbang -f ../customers/template/dev/configmap.yaml --dry-run +# Commit and push your code +# Deploy your bigbang template +kubectl apply -f dev/bigbang.yaml +# Monitor rollout +watch kubectl get pod,helmrelease -A +# Conduct testing +# Tear down +kubectl delete -f dev/bigbang.yaml +# Istio namespace will be stuck in "finalizing". So run the script to delete it. You will need 'jq' installed +./scripts/remove-ns-finalizer.sh istio-system + +# If you have pushed code changes before the tear down, occasionally the bigbang deployments are not terminated because Flux has not had enough time to reconcile the helmreleases + +# Re-deploy bigbang +kubectl apply -f dev/bigbang.yaml +# Run the sync script. +./scripts/sync.sh +# Tear down +kubectl delete -f dev/bigbang.yaml +./scripts/remove-ns-finalizer.sh istio-system +``` + +### Validation + +In order to validate that the new package is running as expected, we recommend checking the following things: + +1. Make sure that the steps from the other documentation in `package-integration` directory has been completed. + +1. Deploy the package following the imperative step described [above](#imperative). + +1. Make sure that a namespace has been created for the package deployed (`kubectl get ns`). + +1. The Helm Release (HR) reconciled successfully for the package (`kubectl get hr -A`). + +1. All the pods and services we expected are up and running (`kubectl get po -n <Package Namespace>`). + +1. Make sure all the pods are in a healthy state and have the right specs. + +1. Utilize grafana to make sure the pods have the right resources if needed. + +1. Create a merge request and validate passing CI tests. diff --git a/docs/developer/package-integration/testing.md b/docs/developer/package-integration/testing.md new file mode 100644 index 0000000000000000000000000000000000000000..73bff5a7df89457988bab46b44ef9951ee4b4ebc --- /dev/null +++ b/docs/developer/package-integration/testing.md @@ -0,0 +1,97 @@ +# Testing + +Usually, Helm charts come with a set of Helm tests that can be run to test the deployment of the application. Big Bang requires some additional tests to verify integration is working as expected. By adding additional tests, the goal is to verify that the package is functioning. For example, we may want to validate the following: + +* The HTTPS endpoint can be reached, +* The admin user can login using the configured (or randomized) password, +* A non-admin user can be created and can login, +* Data can be stored and retrieved from the database, +* Artifacts can be stored and retrieved from the object storage, and +* Interactions with other services/packages works. + +## Prerequisites + +* Package helm chart with CI settings pointing to one of bigbang's [package pipelines](./pipeline.md). + +## Integration + +Big Bang provides a library helm chart called [Gluon](https://repo1.dso.mil/big-bang/product/packages/gluon) to help simplify the process of creating both cypress and script helm tests. + +To include this library as a subchart in your package repo, follow the instructions provided in the pipeline repo [here](https://repo1.dso.mil/big-bang/pipeline-templates/pipeline-templates#including-the-gluon-helm-test-library-in-your-package). Then, in your chart/values.yaml, add values for bbtests, any variables used, and default it to false. +```yaml +# Bigbang helm test values default disabled +bbtests: + enabled: false + cypress: + artifacts: true + envs: + cypress_url: 'http://{{ template "podinfo.fullname" . }}.{{ .Release.Namespace }}.svc.cluster.local:{{ .Values.service.externalPort }}' + scripts: + envs: + URL: 'http://{{ template "podinfo.fullname" . }}.{{ .Release.Namespace }}.svc.cluster.local:{{ .Values.service.externalPort }}' +``` +**NOTE:** At the package level, we are pointing to the service and service port instead of the istio virtual service because istio isn't enabled by default. At the Big Bang test level we will point to the virtualservice url because istio will be present. + +We will enable these tests in `tests/test-values.yaml`: +```yaml +bbtests: + enabled: true +``` +### Cypress Test + +Now we need to add the cypress gluon template yaml to `chart/templates/tests/cypress-test.yaml`: +```yaml +{{- include "gluon.tests.cypress-configmap.base" .}} +--- +{{- include "gluon.tests.cypress-runner.base" .}} +``` + +We need to add a cypress test to `chart/tests/cypress/podinfo-health.spec.js`: + +```yaml +describe('Basic Podinfo', function() { + it('Check Podinfo is accessible', function() { + cy.visit(Cypress.env('url')) + }) +}) +``` +**NOTE:** This is basic cypress test that will visit the `cypress_url` defined in values.yaml. For more information on cypress tests visit [here](https://docs.cypress.io/guides/overview/why-cypress#In-a-nutshell). + +We also need a cypress.json config file with any cypress configurations we need placed `chart/tests/cypress/cypress.json`: + +```json +{ + "pluginsFile": false, + "supportFile": false, + "fixturesFolder": false +} +``` +### Script Test + +Now we need to add the script gluon template yaml to `chart/templates/tests/script-test.yaml`: +```yaml +{{- include "gluon.tests.script-configmap.base" .}} +--- +{{- include "gluon.tests.script-runner.base" .}} +``` + +We need a script to run `chart/tests/scripts/script-test.sh`: +```bash +#!/bin/bash +set -ex + +echo "-----------------------------------------" +echo "BEGIN podinfo jwt test" +echo "-----------------------------------------" +TOKEN=$(curl -sd 'test' ${URL}/token | jq -r .token) && +curl -sH "Authorization: Bearer ${TOKEN}" ${URL}/token/validate | grep test +echo "-----------------------------------------" +echo "END podinfo jwt test" +echo "-----------------------------------------" +``` + +More information on cypress tests and creating tests with scripts for testing non-UI portions of an app can be found [here](https://repo1.dso.mil/big-bang/product/packages/gluon/-/blob/master/docs/bb-tests.md). + +## Validation + +To validate these changes and view the cypress test we can create a merge request with these changes and a pipeline will automatically kick off deploying our package and running the helm tests. Artifacts of these tests (e.g., screenshots and videos) are stored in the `Clean Install`, `Upgrade`, and `Integration Test` Jobs. Just click one of the jobs and there will be `job artifacts` on the right pane. diff --git a/docs/developer/package-integration/upstream.md b/docs/developer/package-integration/upstream.md new file mode 100644 index 0000000000000000000000000000000000000000..c90decda995f15540505e633601baeec9cf55054 --- /dev/null +++ b/docs/developer/package-integration/upstream.md @@ -0,0 +1,243 @@ +# Upstream Integration + +Before beginning the process of integrating a package into Big Bang, you will need to create a workspace and create or sync the package's Helm chart. This document shows you how to set up the workspace and sync the upstream Helm chart. + +## Prerequisites + +- [Kpt version 0.39.2](https://github.com/kptdev/kpt/releases/tag/v0.39.2) (Later versions of kpt are incompatible with Bigbang) +- [Git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git) + +> Throughout this document, we will be setting up an application called `podinfo` as a demonstration. + +## Project + +It is recommended that you create your project in [Big Bang's Sandbox](https://repo1.dso.mil/big-bang/apps/sandbox). This allows you to leverage Big Bang's pipelines, collaborate with Big Bang developers, and easily migrate to a fully graduated project. + +You will need to request a sandbox project and Developer access from a Big Bang team member. + +## Helm Chart + +Big Bang requires a Helm chart to deploy your package. This Helm chart must be enhanced to support full integration with Big Bang components. + +### Cloning Upstream + +To minimize maintenance, it is preferable to reuse existing Helm charts available in the community (upstream). Changes to the upstream Helm chart should be made with new files when possible, and always clearly marked as Big Bang additions. + +> Sometimes, it is not possible to find an upstream Helm chart and you must develop your own. This is beyond the scope of this document. + +1. Identify the location of an existing Helm chart for the package. + + > If selecting between several Helm charts, give preference to a Helm chart that: + > + > * Was created by the company that owns the package; + > * Has recent and frequent updates; + > * Offers maximum flexibility through values; + > * Does not bundle several packages together (unless they can be individually disabled); and + > * Provides advanced features like high availability, scaling, affinity, taints/tolerations, and security context. + +1. Using [Kpt](https://googlecontainertools.github.io/kpt/installation/), create a clone of the package's Helm chart + + ```shell + # Change these for your upstream helm chart + export GITREPO=https://github.com/stefanprodan/podinfo + export GITDIR=charts/podinfo + export GITTAG=5.2.1 + + # Clone + kpt pkg get $GITREPO/$GITDIR@$GITTAG chart + ``` + + > Always use an release tag for `GITTAG` so your chart is immutable. Never use a branch or `latest`. + +1. Add `-bb.0` suffix on `chart/Chart.yaml`, `version`. For example: + + ```yaml + version: 6.0.0-bb.0 + ``` + + > The `bb.#` will increment for each change we merge into our `main` branch. It will also become our release label. + +1. Add the following files to the Git repository at the root: + + - CHANGELOG.md + + The format of the changelog should be based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) with versions equivalent to the Helm chart version. An example is provided in the following: + + ```markdown + # Changelog + + Format: [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) + + ## [6.0.0-bb.0] - 2021-09-30 + ### Added + - Initial creation of the chart + ``` + + - CODEOWNERS + + Code owners are required approvals on merge requests in the Big Bang repository. This file should be setup based on [GitLab's Code Owners guidance](https://docs.gitlab.com/ee/user/project/code_owners.html). An example is provided in the following: + + ```plaintext + * @gitlabuser + ``` + + - CONTRIBUTING.md + + This document should outline the steps required for someone new to contribute to the repository. An example is provided in the following: + + ```markdown + # Contributing + + This repository uses the following conventions: + + * [Semantic Versioning](https://semver.org/) + * [Keep a Changelog](https://keepachangelog.com/) + * [Conventional Commits](https://www.conventionalcommits.org/) + * [Cypress](https://www.cypress.io) or a shell script for testing + + Development requires the following tools: + + * [kubectl](https://kubernetes.io/docs/tasks/tools/#kubectl) + * [helm](https://helm.sh/docs/intro/install/) + * [fluxcd](https://fluxcd.io/docs/installation/) + + To contribute a change: + + 1. Open an issue in GitLab describing the scope of your work. + 2. Assign yourself to the issue. + 3. Label the issue with `status::doing`. + 4. Create a branch in the repository using your issue number as a prefix. + 5. Make changes in code and push to your branch. + 6. Write tests using [cypress](https://www.cypress.io) and/or shell scripts. + 7. Make commits using the [Conventional Commits](https://www.conventionalcommits.org/) format. + 8. Update `CHANGELOG.md` using the [Keep a Changelog](https://keepachangelog.com) format. + 9. Open a merge request into the `main` branch. + 10. Add a reference to the issue in the merge request description. + 11. Resolve any failures from the pipeline. + 12. Resolve any merge conflicts. + 13. Label the Merge Request with `status::review`. + 14. Contact the code owners to expedite your Merge Request review. + 15. Address any review comments and merge conflicts during the review process. + 16. Wait for a code owner to approve and merge your changes. + 17. Request a repository maintainer to create a release and tag. + ``` + + - LICENSE + + The license file should contain the license terms and conditions for using the Helm charts. In general, Big Bang uses the [Apache 2.0 License](https://www.apache.org/licenses/LICENSE-2.0). + + - README.md + + The readme contains high-level information about the package. This document covers the following topics: + + - Upstream References: Links to external documentation + - Documents: Links to /docs in repository + - Prerequisites: Tools needed to install and use + - Deployment: How to install / upgrade + - Values: How to configure Helm chart values + - Contributing: Link to contributing guide + + There is a standard Big Bang template used for all packages. This can be created by following the [templating instructions](https://repo1.dso.mil/big-bang/product/packages/gluon/-/blob/master/docs/bb-package-readme.md) + + > This process produces a `README.md`, `README.md.gotpl`, and `.helmdocsignore`. The `gotpl` file is used as values to update the `README.md`. + > To avoid having the `flux` helm chart also added to the `README.md`, run `echo 'flux/*' >> .helmdocsignore`. + + Example: + +<!-- markdownlint-disable --> + ```markdown + # podinfo + + ![Version: 6.0.0-bb.0](https://img.shields.io/badge/Version-6.0.0--bb.0-informational?style=flat-square) ![AppVersion: 6.0.0](https://img.shields.io/badge/AppVersion-6.0.0-informational?style=flat-square). + + Podinfo Helm chart for Kubernetes + + ## Upstream References + * <https://github.com/stefanprodan/podinfo> + + ## Learn More + * [Application Overview](docs/overview.md) + * [Other Documentation](docs/) + + ## Pre-Requisites + + * Kubernetes Cluster deployed + * Kubernetes config installed in `~/.kube/config` + * Helm installed + + Kubernetes: `>=1.19.0-0` + + Install Helm + + https://helm.sh/docs/intro/install/ + + ## Deployment + + * Clone down the repository + * cd into directory + * helm install podinfo chart/ + + ## Values + + | Key | Type | Default | Description | + | ------------ | ------ | -------- | ----------- | + | replicaCount | int | `1` | | + | logLevel | string | `"info"` | | + | host | string | `nil` | | + | backend | string | `nil` | | + ... + + ## Contributing + + Please see the [contributing guide](./CONTRIBUTING.md) if you are interested in contributing. + ``` +<!-- markdownlint-enable --> + + + +5. Commit changes. + + ```shell + git add -A + git commit -m "feat: initial helm chart" + git push --set-upstream origin bigbang + ``` + +### Updating Upstream + +If a new version of the upstream Helm chart is released, this is how to sync it and retain the Big Bang enhancements. + +```shell +export GITTAG=6.0.0 + +# Before upgrading, identify changes made to upstream chart +kpt pkg diff chart > bb-mods-pre.txt + +# Sync with new Helm chart release +kpt pkg update chart@$GITTAG --strategy alpha-git-patch + +# Resolve merge conflicts, if any, by +# - Manually merging conflicts identified +# - Add changes to git using `git add` +# - Continuing the patch with `git am --continue` + +# After upgrading, identify deltas to upstream chart +kpt pkg diff chart > bb-mods-post.txt + +# Look at the differences between the pre and post changes to make sure nothing was missed. Add any missing items back into the chart +diff bb-mods-pre.txt bb-mods-post.txt + +# Commit and push changes +rm bb-mods-*.txt +git add -A +git commit -m "chore: update helm chart to $GITTAG" +git push +``` + +> In Kpt 1.0, `alpha-git-patch` was renamed to `resource-merge`. + +## Validation + +If you are not already familiar with the package, deploy the package using the upstream helm chart onto a Kubernetes cluster and explore the functionality before continuing. The Helm chart can be deployed according to the upstream package's documentation. + + > It is recommended that you follow the instructions in [development environment](../development-environment.md) to get a Kubernetes cluster running. diff --git a/docs/developer/release-process.md b/docs/developer/release-process.md new file mode 100644 index 0000000000000000000000000000000000000000..81fea7200f770a2e3e0fdf91f7b5b33c4ce3eea3 --- /dev/null +++ b/docs/developer/release-process.md @@ -0,0 +1,7 @@ +# Release Process + +Big Bang Applications shall implement a release process adhering to the following requirements: + +* Each Application shall maintain a long running release branch for all application version "N-2," meaning current upstream release and the previous two releases. +* The release process shall be automated by merging into this release branch. +* The release process shall validate the application against all **supported** dependency releases using the automated [Testing Framework](testing.md). diff --git a/docs/developer/renovate-maintenance.md b/docs/developer/renovate-maintenance.md new file mode 100644 index 0000000000000000000000000000000000000000..82882f87048ab9c0d704d8e3024a4aa0f629d0da --- /dev/null +++ b/docs/developer/renovate-maintenance.md @@ -0,0 +1,46 @@ +# Renovate Package Maintenance + +The bread and butter of Big Bang is updating and providing timely releases for the Big Bang maintained helm charts. Most of these helm charts are based off of upstream vendor charts and repositories. This can be confirmed via seeing if a `chart/Kptfile` exists in our repository. + +1. All Big Bang packages should contain a `docs/DEVELOPMENT_MAINTENANCE.md` file which should be reviewed and understood by codeowners and those working the package updates. It has all of the necessary changes to begin working a Renovate update for any given package. Repository CODEOWNERS should also be using this document when reviewing the updates for a Merge Request that is in `status::review` to ensure all items are being performed, or updating the documentation if a portion is no longer relevant or needed. This document is where all of our local changes and caveats should be documented when creating changes which deviate from upstream templates or values according to the [Develop Package](./develop-package.md) steps when onboarding a new package. + +1. Once the package has been updated, tested, and verified according to the DEVELOPMENT_MAINTENANCE.md guide, the following steps should then be taken: + + a. Review pipeline and ensure all items are passing or if warnings are found, they are notated in the Merge Request comments or description. If an item mentioned in the [CI Workflow Document](./ci-workflow.md) is added `SKIP UPGRADE/skip-bb-mr` ensure this is notated why so we have justification as to why this was needed. + + b. The `## Upgrade Notices` section is accurately filled out in the MR description. This notice should be treated as customer public facing and should not include any internal team or CI specific notes for the package. Good examples of relevant upgrade notices are when a template or value moves or is renamed like a ENV var or value for an admin password for example, some change that will require downstream consumers of Big Bang to read and perform a change for their environment. + + c. Ensure `SKIP UPDATE CHECK` is removed from the MR title and a pipeline has ran with a `chart update check` stage. + + d. Add `status::review` label to issue and Merge Request. + +1. Once merged into `main`, ensure post-MR pipelines for `main` and tag creation fully pass. Reach out to CODEOWNERS or anchors if issues arise. + +1. After all MR, main, and tag pipelines pass and are successful, bigbang-bot will open a Big Bang Merge Request. Link your issue your assigned in the description after the `Closes` (e.g., `Closes https://repo1.dso.mil/ISSUE`). Ensure pipeline is passing and package/change related issues are not present in pipeline. Once pipeline is passing and is linked take MR out of draft status. Assign anchors and Big Bang codeowners as reviewers. + +## General Renovate Issue Workflow + +```mermaid +flowchart TD + Initial((Issue)) -.-> |Assign Yourself\n label status::Doing\n Weight Issue| Initial + Initial --> |If MR exists\n Open MR| MR{{Merge Request}} + MR -.-> |Assign Yourself\n label status::Doing| MR + MR --> WorkIssue>Work Issue] + WorkIssue -.-> |If Renovate Issue,\n Follow dev maintenance doc| WorkIssue + WorkIssue -.-> |Bump Chart version: bb.x \n Update CHANGELOG \n Regenerate readme| WorkIssue + WorkIssue --> |Push to Repo1| Repo1[(Repo1 MR)] + Repo1 --> |Pipeline Fails| WorkIssue + Repo1 --> |Pipeline Passes| Test>Test Work] + Test -.-> |Deploy Big Bang \n Test branch changes\n For Install/Upgrade| Test + Test --> |Testing Fails| WorkIssue + Test --> |Testing Passes| Review{{Merge Request}} + Review -.-> |Add status::Review label to MR and Issue \n Take MR out of Draft\n Assign CODEOWNERS as Reviewers| Review + Review --> Codeowners>Review] + Codeowners -.-> |Reviewer checks changes and pipeline status \n Reviewer Deploys Big Bang \n Testing branch changes\n For Install/Upgrade| Codeowners + Codeowners --> |Testing Fails \n Relabels to status::Doing \n Notify Assignee| WorkIssue + Codeowners --> |Testing Passes \n Approve and Merge| Pipelines + Pipelines -.-> |Pipelines run \n Changes Merged \n New Release Tag is made| Pipelines + Pipelines --> |New MR opens in Big Bang| BigBang((Big Bang)) + BigBang -.-> |Add links if needed \n Make sure pipeline passes \n Take MR out of Draft \n Add status::Review label\n Assign CODEOWNERS as Reviewers| BigBang + BigBang --> |MR Merged\n Issue Closed| Initial +``` diff --git a/docs/developer/test-package-against-bb.md b/docs/developer/test-package-against-bb.md new file mode 100644 index 0000000000000000000000000000000000000000..ba429f6754743d1bff5f6c9f3c4c981e94946ddf --- /dev/null +++ b/docs/developer/test-package-against-bb.md @@ -0,0 +1,27 @@ +# Testing your Package Branch against Bigbang before Package Merge + +These instructions right now are written for istio changes, but the same is probably true for kyverno and possibly for others. CODEOWNERS reviewing Merge Requests (MRs) should enforce this. + +## Run Bigbang Tests Against your Branch + +As part of your MR that modifies istio you will need to run bigbang tests against your branch. To do this, at a minimum, you will need to complete the following: + +1. Create a new branch on bigbang off of master `git checkout master && git pull && git checkout -b my-bigbang-branch-for-testing.` +1. Modify the [test values](https://repo1.dso.mil/big-bang/bigbang/-/blob/master/tests/test-values.yaml?ref_type=heads). Yours will be different for your package, you may need more than this. + ```yaml + myAppPackage: + git: + tag: null + branch: my-package-branch-that-needs-testing + values: + istio: + hardened: + enabled: true + ``` +1. Stage your changes `git add -A.` +1. Commit your changes `git commit -m "prepping for test."` +1. Push your changes `git push -u origin my-bigbang-branch-for-testing.` +1. Create the bigbang MR as a draft with `TEST ONLY DO NOT MERGE` in the title, and add the label of the package to test (e.g., `monitoring`). +1. Wait for tests to finish, and do fixes on your package branch as needed until they pass. +1. Close the bigbang MR by deleting the bigbang branch `git push -d origin my-bigbang-branch-for-testing.` +1. Link the bigbang MR on your package MR as evidence of your package working in bigbang. diff --git a/docs/developer/testing-repo1-CI.md b/docs/developer/testing-repo1-CI.md new file mode 100644 index 0000000000000000000000000000000000000000..06e9fa4cdb3b7a89051f13ce1a614ffc6862e97f --- /dev/null +++ b/docs/developer/testing-repo1-CI.md @@ -0,0 +1,86 @@ +# Testing repo1 CI against a dedicated runner + +This page will describe how to deploy bigbang with a GitLab Runner that is connected to repo1. Source documentation for GitLab Runner is available at https://docs.gitlab.com/runner/. + +## Why + +* You need to test GitLab Runner configuration against repo1 +* You need to test integrating CI pipelines to infrastructure or other bigbang services. + +## How + +### Request access + +You will need either of these: + +* Admin access to a repo on repo1 +* Or access to create personal repos under your account on repo1 + +Contact the Big Bang Government Team Lead to request access. + +### Create gitlab runner and token + +1. Go to *Settings -> CI/CD* on the repo you want to test against. +1. Expand the *Runners* section and click *New project runner* +1. Select *Run untagged jobs* and *Lock to current projects* and click *Create runner* +1. On the next page Copy the *runner authentication token* for later + +### Deploy a k8s cluster and install flux + +by default the easiest way to test is to spin up a cluster using the k3d-dev.sh script. +you can follow the directions <https://repo1.dso.mil/big-bang/bigbang/-/blob/master/docs/developer/aws-k3d-script.md> + +### Deploy Big Bang + +1. Create an overrides file with the following content, along with any additional [configuration settings](https://docs.gitlab.com/runner/executors/kubernetes/#configuration-settings) you need to test + +```yaml +# enable grafana alloy to push traces to +addons: + alloy: + enabled: true + +# enable gitlabrunners for ci-tracing + gitlabRunner: + enabled: true + values: + # set the url to repo1 + gitlabUrl: https://repo1.dso.mil + runners: + # use custom config and remove cloneUrl paramaters + config: | + [[runners]] + [runners.kubernetes] + pull_policy = "always" + namespace = "{{.Release.Namespace}}" + image = "{{ printf "%s/%s:%s" .Values.runners.job.registry .Values.runners.job.repository .Values.runners.job.tag }}" + helper_image = "{{ printf "%s/%s:%s" .Values.runners.helper.registry .Values.runners.helper.repository .Values.runners.helper.tag }}" + image_pull_secrets = ["private-registry"] + [runners.kubernetes.pod_security_context] + run_as_non_root = true + run_as_user = 1001 + [runners.kubernetes.helper_container_security_context] + run_as_non_root = true + run_as_user = 1001 + [runners.kubernetes.pod_labels] + "job_id" = "${CI_JOB_ID}" + "job_name" = "${CI_JOB_NAME}" + "pipeline_id" = "${CI_PIPELINE_ID}" + "app" = "gitlab-runner" +``` + +1. Deploy BigBang with the above override file + +```bash +helm upgrade -i bigbang ./chart -n bigbang --create-namespace -f ./docs/assets/configs/example/policy-overrides-k3d.yaml -f ../overrides/registry-values.yaml -f ./chart/ingress-certs.yaml -f ../overrides/gitlabrunner-test.yaml +``` + +1. Create a secret with the token for the runner +Replace *runnertoken* with the token that was created for the runner. + +```bash +kubectl -n gitlab-runner create secret generic gitlab-gitlab-runner-secret --from-literal=runner-registration-token=runnertoken --from-literal=runner-token=runnertoken +``` + +1. Validate that the runner is connected to repo1. Goto the repo on repo1 then *Settings->CI/CD*, expand the *Runners* section the runner should be marked as green. +1. Now create a CI workflow for the repo and let it run, it should choose the gitlab runner on your k3d cluster. diff --git a/docs/developer/testing.md b/docs/developer/testing.md new file mode 100644 index 0000000000000000000000000000000000000000..5e3889ca3fb249458b327e33fa9f5ff2bb427e41 --- /dev/null +++ b/docs/developer/testing.md @@ -0,0 +1,117 @@ +# Testing + +There are multiple phases of testing for an application to get into a customer environment. + +## Types of Changes + +* New Iron Bank Image +* Changes to Manifests for deployments +* Helm Chart Tests to verify operation within the cluster +* Newly supported configurations of application + +## Testing Platform + +Big Bang Applications will leverage GitLab Runners to execute these common Big Bang Pipelines. Each Big Bang application is required to use the Big Bang Pipelines, whose functionality is outlined here. + +A detailed description of the pipelines and how to execute the testing process on a local system is described in the README.md in <https://repo1.dso.mil/big-bang/pipeline-templates/pipeline-templates>. + +## Application Testing + +When a Big Bang application developer submits changes to a particular Big Bang application, the application needs to be tested to ensure functionality, as well as compliance with core [Package Requirements](./package-integration/README.md). + +A core feature of all testing capabilities is its ability to be run locally by developers using their own environment, or by other teams looking to test proposed changes to the application (e.g., IronBank as part of container creation). The GitLab pipelines will be simple wrappers around these common testing and deployment tools. + +### Linting + +Initial phases of the applications tests will focus on compliance with approved formatting and rendering policies for Big Bang. + +### Smoke Deployments + +The next phase of testing for each application will be to stand up healthy on a lightweight Kubernetes cluster. The GitLab Runners will standup a ephemeral Kubernetes cluster for use for the deployment, deploy the application and its dependencies and ensure the application comes up "Healthy." The testing configuration will allow for a configuration of the application and the ability to define and test functionality. + +Each "test" scenario will contain the following information: + +1. The Kubernetes cluster to stand up. Initial implementations will only allow customization of a k3d cluster. +2. Application configuration files. Once a repository format/tool is decided, this may look like a Helm values file, or a set of Kustomization overlays on a base deployment. +3. A smoke test configuration file. Format TBD based on tool decided (e.g., Locust.io, Selenium, and/or Citrus). + +The Smoke tests will be run internal on the Kubernetes cluster via a Job. The testing framework will inject a configuration object provided in the repo as a configmap for the job and run the job, ensure it is successful, and provide the logs back to the user CI/CD pipeline for review. + +### Helm Chart Testing + +The Big Bang application pipelines have the ability to execute one or more [Helm Chart tests](https://helm.sh/docs/topics/chart_tests) after a chart has been deployed to the cluster. Helm tests deploy one or more pods/containers and any other supporting kubernetes objects in order to verify that the application is operational. + +For example, the Minio instance package has additional CLI testing capabilities via the use of Helm Chart Tests. These tests invoke the MC command line tool to create, delete, populate, and retrieve information from Minio buckets. Examples of other types of Helm Chart Tests including: + +* Validate that your configuration from the values.yaml file was properly injected. +* Make sure your username and password work correctly for the configuration. +* Use CLI or API tests to access the application. + +The package pipelines have been enhanced to execute the "helm test" command and dump the log files of the tests results. + +In order to add Helm Chart tests to your application, the following enhancements need to be made to the Helm Chart: + +* A test directory is added to templates/directory within the helm chart. This directory contains Kubernetes object definitions which are deployed only when a "helm test" command is executed. As an example, tests can be YAML files that execute pods with containers, deploy config maps, secrets, or other objects. +* When a files contain a pod/container definition that executions tests, the container must return success or failure (i.e., the container should exit successfully with an exit 0 for a test to be considered a success). +* Each test object definition must contain a "helm.sh/hook: test-success" annotation telling Helm that this object is a test and should only be deployed when tests are executed. The following example create a configmap that is only created during testing. + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: "{{ .Release.Name }}-cypress-test-configmap" + annotations: + "helm.sh/hook": test-success + "helm.sh/hook-weight": "5" + sidecar.istio.io/inject: "false" + labels: + helm-test: enabled + {{- include "minio.labels" . | nindent 4 }} + namespace: {{ .Release.Namespace }} +data: +{{ (.Files.Glob "cypress/*").AsConfig | indent 2 }} + +``` + +Also note that the "helm.sh/hook-weight" can be used to order the creation and execution of test objects. + +## Umbrella Testing + +The end consumable is the Umbrella Application. As new versions of Big Bang Applications become available, those changes need to be integrated into the Umbrella and tested. Each Merge Request into the Umbrella Repo requires passing of an [Upgrade Tests](#upgrade-tests) and the [End to End Tests](#end-to-end-tests) for all mock environments. + +### Environments + +The Umbrella application will be tested for functionality with customer focused kubernetes environments. As the Integration team works with customers to adopt Big Bang, the team will provide feedback to Umbrella Test Environments to provide representative environments to perform full End to End regression tests. A representative environment for the e2e tests is Mock Fences, which attempts to mirror the Fences environment owned by GBSD. + +Each environment will contain the Infrastructure as Code (IaC) to deploy the base infrastructure that Big Bang will be deployed onto. These tests will not validate that upgrades to IaC are successful. + +### Upgrade Tests + +The Umbrella application is responsible for not only deploying fresh environments, but managing the upgrades to existing environments. As a result, a key component of testing is to validate that upgrades are successful. The Umbrella test script will stand up the applications with the latest current release and then apply an upgrade to the changes in the Merge Request and ensure there is a safe process for upgrading. If there are custom scripts needed to perform the upgrade, the umbrella application will have those configured as part of the application definition. + +### End to End Tests + +The GitLab job will then identify each set of smoke tests defined in each application and execute those tests on the upgraded mock environment to assure proper functionality of each application. + +## Single Sign On (SSO) + +Part of testing shall provide tests for Single Sign On verification that applications are able to be configured to use Keycloak. For each application that has an SSO option, Keycloak will be deployed into the ephemeral cluster and the application will be configured to use the deployment for SSO. The application will be required to have smoke tests that validate the ability to log into Keycloak. + +## Testing Infrastructure + +### Application Testing Infrastructure + +The GitLab runners used for testing Big Bang Applications will stand up dynamic [K3d](https://k3d.io/) or [Kind](https://kind.sigs.k8s.io/docs/) clusters. To do this dynamically in Kubernetes, the pods need access to the host. As a result, Big Bang with deploy and managed a separate Kubernetes cluster that GitLab will use to deploy ephemeral Kubernetes clusters for testing. + +This cluster will remain separate from the environment running GitLab since the use of privileged containers could pose a security risk to adjacent pods on the nodes. + +### Umbrella Testing Infrastructure + +The GitLab Runners used for Umbrella testing will be provided appropriate service account credentials to provision mock environments. For AWS environments, the environment will reside in the same project as GitLab. For other cloud providers, a dedicated project will be provisioned to be used exclusively by BigBang Umbrella testing. As a result, there must be the ability to have concurrent environments in the same cloud project. + +#### Umbrella Clusters + +Clusters for testing the Umbrella app will be provisioned from vendors that allow for creation of dev and test clusters without licensing limitations. Vendors will be required to provide the following: + +1. A repository inside <https://repo1.dso.mil/platform-one/distros> to maintain code. +2. A GitLab pipeline task that provisions their distribution: [Vendor Distribution Integration](vendor-distro-integration.md). diff --git a/docs/developer/vendor-distro-integration.md b/docs/developer/vendor-distro-integration.md new file mode 100644 index 0000000000000000000000000000000000000000..6fccb35f2b3449e237b04041adf34190f0d43e9a --- /dev/null +++ b/docs/developer/vendor-distro-integration.md @@ -0,0 +1,27 @@ +# Testing Vendor Distributions in our Pipeline + +## Overview + +Vendor distributions are tested within the umbrella project's ci [pipelines][0]. These pipelines include jobs from the [umbrella-templates][1] repository. + +The main thing to take into account is your cluster should have the following: + +* A single stage for spinning up. +* A single stage for spinning down. +* Within each job you're allowed whatever tools/resources needed just store them in the `jobs/<your-job>/dependencies` folder. +* We provision a VPC and subnets inside a separate job, you can access this information via `terraform remote_state.` +* We expect you to export the `kubeconfig` file to connect to your cluster as a `GitLab artifact.` + +Vendors can ignore the `smoke tests` as they are run against a k3d cluster. All other stages are important for vendors to understand. We have also made the assumption that `terraform` is the base tool that all vendors will use to deploy their clusters in our pipelines. + +### Working Example + +A working example for rke2 can be found [here][2]. + +**NOTE:** This link is pinned to a specific commit to show you exactly where in the code it is being implemented, look at the code to get a gist then view `master` branch to make sure nothing has changed). + +You can find more information about specific jobs in each jobs specific README.md inside [umbrella-templates][1]. + +[0]: https://repo1.dso.mil/big-bang/bigbang/-/pipelines +[1]: https://repo1.dso.mil/big-bang/pipeline-templates/umbrella-templates +[2]: https://repo1.dso.mil/big-bang/bigbang/-/blob/a1b7926ce05127a57661fe5ff72c6d7a23db0470/.gitlab-ci.yml#L148 diff --git a/docs/guides/.pages b/docs/guides/.pages new file mode 100644 index 0000000000000000000000000000000000000000..b6abddd883887d1bf64dbd60c6218d80eeb938b7 --- /dev/null +++ b/docs/guides/.pages @@ -0,0 +1,6 @@ +nav: + - Overview: README.md + - Using Big Bang: using-bigbang + - Deployment Scenarios: deployment-scenarios + - Backup and Restore: backup-and-restore + - Airgap: airgap-zarf diff --git a/docs/guides/README.md b/docs/guides/README.md new file mode 100644 index 0000000000000000000000000000000000000000..a7dd2670321f4a8eeaf1a5450c44e9a8eb0bbedb --- /dev/null +++ b/docs/guides/README.md @@ -0,0 +1,32 @@ +# User Guides + +[[_TOC_]] + +## Preface + +The guides included here are not all inclusive of every situation. Please open an issue or provide an MR for any guide improvements or additions. + +## Using Big Bang + +[Chart Values Guide](./using-bigbang/values-guide.md) | +[Default Credentials](./using-bigbang/default-credentials.md) | +[Image Pull Policy](./using-bigbang/image-pull-policy.md) | +[Pod Usage in Grafana](./using-bigbang/pod-usage-in-grafana.md) | +[Migrating Logging from ELK to PLG](./using-bigbang/efk-plg-logging-migration.md) +[Testing Deployments](./using-bigbang/testing-deployments.md) + +## Deployment Scenarios + +[Quickstart](./deployment-scenarios/quickstart.md) | +[Multiple Ingress](./deployment-scenarios/multiple-ingress.md) | +[SSO Quickstart](./deployment-scenarios/sso-quickstart.md) + +### Airgap Deployments + +[Airgap Deployments](./airgap/README.md) | +[Airgap w/Zarf](./airgap-zarf/README.md) + +## Backup and Restore + +[GitLab Backup and Restore](./backup-and-restore/gitlab-backup-restore.md) | +[Nexus Migration with Velero](./backup-and-restore/nexus-migration-with-velero.md) diff --git a/docs/guides/airgap-zarf/README.md b/docs/guides/airgap-zarf/README.md new file mode 100644 index 0000000000000000000000000000000000000000..fae38cf0e468c46e10ddb7ad5fa2aca034668949 --- /dev/null +++ b/docs/guides/airgap-zarf/README.md @@ -0,0 +1,34 @@ +# Airgap w/Zarf + +> âš ï¸ This is a work in-progress. + +### Requires Big Bang 1.54.0 and greater. + +This section is currently purely devoted to building and testing packages on a development cluster. The result could be a set of archives that can be used for moving across an airgap. Essentially, this automates a few of the steps indicated in this [documentation](https://docs.zarf.dev/docs/zarf-tutorials/big-bang). + +The first step would be to stand up a Big Bang dev cluster. This is most easily represented by following the steps outlined here, but would ultimately result in running the below command, which stands up a larger development cluster. Take note of the KeyName and Public IP address which will be used in a later step. + +```shell +docs/assets/scripts/developer/k3d-dev.sh -b +``` + +Be sure to export your Registry1 credentials next as seen in the following: + +```shell +export REGISTRY1_USERNAME=<username> +export REGISTRY1_PASSWORD=<password> +``` + +Now you can execute the following, which will automatically detect your SSH key location, name and Public IP, based off the current `AWS_PROFILE` declared locally: + +```shell +docs/assets/scripts/airgap-zarf/zarf-dev.sh +``` + +The above will clone the latest `main` branch of the [defenseunicorns/zarf](https://github.com/defenseunicorns/zarf) repository and execute the stock `examples/big-bang/zarf.yaml`. If you want to use a different `zarf.yaml`, you can override this by setting any of these variables ahead of time, either by exporting them or setting them as part of the command. + +* `ZARF_TEST_REPO`: sets the repository to clone from. +* `ZARF_TEST_REPO_BRANCH`: sets the branch to switch to from the cloned repo. +* `ZARF_TEST_REPO_DIRECTORY`: sets the directory where the desired `zarf.yaml` is. + +Also since this all uses the same dev script, you should be able to use whatever k8s tooling (such as `kubectl` or `k9s`) you already might use on a dev cluster as `KUBECONFIG` is still transferred locally and available. diff --git a/docs/guides/airgap/README.md b/docs/guides/airgap/README.md new file mode 100644 index 0000000000000000000000000000000000000000..db8774d9840d9ce81439b9429758a969c4caac97 --- /dev/null +++ b/docs/guides/airgap/README.md @@ -0,0 +1,519 @@ +# Airgap + +Currently this is in proof of concept mode, so play around with this to get an idea of it. + +This work was quickly developed to entertain certain paths for image packaging and deployment. + +## Image Packaging/Deployment + +`package_images.sh` - Proof of concept script for image packaging + +* Dependencies: + * `docker` - The docker CLI tool + * `images.txt` - A list of all requires airgap images + * `jq` - The jq CLI tool +* Deliverables: + * `registry:package.tar.gz` - Modified `registry:2` container loaded with airgap images + * NOTE - `registry:2` vs `harbor` vs anything else is trivial, we can use whatever we want + * Packaged images are loaded and retrievable immediately upon container start + * `/var/lib/registry-package` is created and populated with images + * `/etc/docker/registry/config.yml` is templated to use new registry folder + * This is due to the fact that `/var/lib/registry` is a docker volume + +`deploy_images.sh` - Proof of concept script for image deployment + +* Dependencies: + * `docker` - The docker CLI tool + * `registry:package.tar.gz` - Modified `registry:2` container loaded with airgap images +* Deliverables: + * Running `registry` container with airgap images deployed and retrievable + +Hack commands: +* `curl -sX GET http://localhost:5000/v2/_catalog | jq -r .` + * Verify the catalog of a local running registry container + +## Repository Packaging/Deployment + +Airgap Deployment is a form of deployment which does not have any direct connection to the Internet or external network during cluster setup or runtime. During installation, bigbang requires certain images and git repositories for installation. Since we will be installing in internet-disconnected environment, we need to perform extra steps to make sure these resources are available. + +## Requirements and Prerequisites + +### General Prerequisites + +* A kubernetes cluster with container mirroring support. There is a section below that covers mirroring in more detail with examples for supported clusters. +* Big Bang [release artifacts](https://repo1.dso.mil/big-bang/bigbang/-/releases). +* Utility Server. + +### Package Specific Prerequisites + +#### Elastic (Logging) + +Elastic requires a larger number of memory map areas than some OSes support by default. This can be change at startup with a cloud config or later using sysctl. + +```shell +MIME-Version: 1.0 + Content-Type: multipart/mixed; boundary="==MYBOUNDARY==" + + --==MYBOUNDARY== + Content-Type: text/x-shellscript; charset="us-ascii" + + #!/bin/bash + # Set the vm.max_map_count to 262144. + # Required for Elastic to run correctly without OOM errors. + sysctl -w vm.max_map_count=262144 +``` + +## Utility Server + +Utility Server is an internet-disconnected server that will host the private registry and git server that are required to deploy Big Bang. It should include these command-line tools listed in the following: + +* `docker`: for running docker registry. + * `registry:2` image + * `openssl` for self-signed certificate. +* `curl`: For troubleshooting registry. +* `git`: for setup git server. + +## Git Server + +As part of Big Bang release, we provide `repositories.tar.gz` which contains all the git repositories that BB depend on for deployment. You have two options for serving up these packages for Flux. These options are detailed in the following: + +### Option One + +You can follow the process below to setup git with `repositories.tar.gz` on the Utility Server. + +* Create Git user and SSH key. + +```shell +sudo useradd --create-home --shell /bin/bash git +ssh-keygen -b 4096 -t rsa -f ~/.ssh/identity -q -N "" +``` + +* Create .SSH folder for `git` user. + + ```shell + sudo su - git + mkdir -p .ssh && chmod 700 .ssh/ + touch ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys + exit + ``` + +* Add client ssh key to `git` user `authorized_keys`. + + ```shell + sudo su + cat /[client-public-key-path]/identity.pub >> /home/git/.ssh/authorized_keys + exit + ``` + +* Extract `repositories.tar.gz` to git user home directory. + + ```shell + sudo tar -xvf repositories.tar.gz --directory /home/git/ + ``` + +* Add Hostname alias. + + ```shell + PRIVATEIP=$( curl http://169.254.169.254/latest/meta-data/local-ipv4 ) + sudo sed -i -e '1i'$PRIVATEIP' 'myhostname.com'\' /etc/hosts + sudo sed -i -e '1i'$PRIVATEIP' 'host.k3d.internal'\' /etc/hosts #only for k3d + ``` + +* To test the client key, complete the following: + + ```shell + GIT_SSH_COMMAND='ssh -i /[client-private-key-path] -o IdentitiesOnly=yes' git clone git@[hostname/IP]:/home/git/repos/[sample-repo] + + #For example; + GIT_SSH_COMMAND='ssh -i ~/.ssh/identity -o IdentitiesOnly=yes' git clone git@host.k3d.internal:/home/git/repos/bigbang + #checkout release branch + git checkout 1.3.0 + ``` + +### Option Two + +There are some cases where you do not have access to or cannot create an ssh user on the utility server. It is possible to run an ssh git server on a non-standard port using Docker. + +* Create an SSH key. + +```shell +ssh-keygen -b 4096 -t rsa -f ./identity -q -N "" +``` + +* Extract `repositories.tar.gz` to your working directory. + +```shell +sudo tar -xvf repositories.tar.gz +``` + +* Start the provided Docker image (TODO: move this to an IB image when ready). + +```shell +docker run -d -p 4001:22 -v ${PWD}/identity.pub:/home/git/.ssh/authorized_keys -v ${PWD}/repos:/home/git servicesengineering/gitshim:0.0.1 +``` + +You will now be able to test by checking out some of the code. + +```shell +GIT_SSH_COMMAND='ssh -i /[client-private-key-path] -o IdentitiesOnly=yes' git clone git@[hostname/IP]:[PORT]/home/git/repos/[sample-repo] + +# For example; +GIT_SSH_COMMAND='ssh -i ~/.ssh/identity -o IdentitiesOnly=yes' git clone git@host.k3d.internal:[PORT]/home/git/repos/bigbang +# Check out release branch +git checkout 1.3.0 +``` + +## Private Registry + +Images needed to run BB in your cluster is packaged as part of the release in `images.tar.gz`. You can see the list of required images in `images.txt`. In our airgap environment, we need to set up a registry that our cluster can pull required images from or an existing cluster where we can copy images from `images.tar.gz` into. + +### Set Up + +To set up the registry, we will be using `registry:2` to run a private registry with self-signed certificate. + +* First, untar `images.tar.gz`; + +```shell +tar -xvf images.tar.gz -C . +``` + +* SCP `registry:2` tar file + +```shell +docker save -o registry2.tar registry:2 +docker save -o k3s.tar rancher/k3s:v1.20.5-rc1-k3s1 #check release matching version +scp registry2.tar k3s.tar ubuntu@hostname:~ #modify according to your environment +docker load -i registry2.tar #on your registry server +docker load -i k3s.tar +``` + +* Use the script [registry.sh](../../assets/scripts/airgap-dev/registry.sh) to create registry. + +```shell +$ chmod +x registry.sh && sudo ./registry.sh + +Required information: +Enter bit size for certs (Ex. 4096): 4096 +Enter number of days to sign the certs with (Ex. 3650): 3650 +Enter the 'Country' for the cert (Ex. US): US +Enter the 'State' for the cert (Ex. CO): CO +Enter the 'Location' for the cert (Ex. ColoradoSprings): ColoradoSprings +Enter the 'Organization' for the cert (Ex. PlatformOne): PlatformOne +Enter the 'Organizational Unit' for the cert (Ex. Bigbang): BigBang +Enter the 'Common Name' for the cert (Must be a FQDN (at least one period character) E.g. myregistry.com): myregistry.com +Enter the 'Subject Alternative Name' for the cert(E.g. 1.2.3.4): 10.0.52.144 + +Generating certs ... +mkdir: cannot create directory ‘certs’: File exists +Generating RSA private key, 4096 bit long modulus +.............................................................................................................++ +.....................................++ +e is 65537 (0x10001) +Generating RSA private key, 4096 bit long modulus +......................................................................................................................++ +.......................++ +e is 65537 (0x10001) +Signature ok +subject=/C=US/ST=CO/L=ColoradoSprings/O=PlatformOne/CN=myregistry.com +Getting CA Private Key + +Launching our private registry ... +def21e7025c7d4ea7bbb30603955e0b7da14d077592851b327e59d78a849cb7d + +Installation finished ... + +**Notes:** +===== + +To see images in the registry; + +========================= +curl https://myhostname.com:5443/v2/_catalog -k +========================= +``` + +A folder is created with TLS certs that we are going to supply to our k8s cluster when pulling from the registry. + +You can ensure the images are now loaded in the registry; + +```shell + curl -k https://myhostname.com:5443/v2/_catalog +{"repositories":["ironbank/anchore/engine/engine","ironbank/anchore/enterprise/enterprise","ironbank/anchore/enterpriseui/enterpriseui","ironbank/big-bang/argocd","ironbank/bitnami/analytics/redis-exporter","ironbank/elastic/eck-operator/eck-operator","ironbank/elastic/elasticsearch/elasticsearch","ironbank/elastic/kibana/kibana","ironbank/fluxcd/helm-controller","ironbank/fluxcd/kustomize-controller","ironbank/fluxcd/notification-controller","ironbank/fluxcd/source-controller","ironbank/gitlab/gitlab/alpine-certificates","ironbank/gitlab/gitlab/cfssl-self-sign","ironbank/gitlab/gitlab/gitaly",...] +``` + +### Mirroring + +The images specified as part of the helm charts in Big Bang are expected to be sourced from `registry1.dso.mil` hence this registry needs to be mirrored to the one set up above. To reduce the amount of work needed on the developer part, we will be taking advantage of container mirroring which is supported by `containerd` as well as `cri-o`. Check if your container runtime supports this as it is required for smooth developer experience when deploying BB. You should also check documentation on how your cluster supports passing these configuration to the runtime. For example, TKG and RKE2 support such configuration for `containerd` below to enable `registry.dso.mil` and `registry1.dso.mil` . + +​You need to also configure your cluster with appropriate registry TLS. Please consult your cluster documentation on how to configure this. + +If you need to handle mirroring manually, there is an example Ansible script provided that will update the containerd mirroring and restart the container runtimes for each node in your inventory (copy-containerd-config.yaml). + +#### Konvoy Cluster + +Modify the `cluster.yaml` file and apply. More details can be found on the [D2iQ Konvoy documentation](https://docs.d2iq.com/dkp/konvoy/1.8/install/install-airgapped/). + +```yaml +kind: ClusterConfiguration +apiVersion: konvoy.mesosphere.io/v1beta2 +spec: + imageRegistries: + - server: https://registry1.dso.mil:443 + username: "myuser" + password: "mypassword" + default: true + - server: https://registry.dso.mil:443 + username: "myuser" + password: "mypassword" + default: true +``` + +#### TKG Cluster + +```yaml +... + - path: /etc/containerd/config.toml + content: | + version = 2 + [plugins] + [plugins."io.containerd.grpc.v1.cri"] + sandbox_image = "registry.tkg.vmware.run/pause:3.2" + [plugins."io.containerd.grpc.v1.cri".registry] + [plugins."io.containerd.grpc.v1.cri".registry.mirrors] + [plugins."io.containerd.grpc.v1.cri".registry.mirrors."registry1.dso.mil"] + endpoint = ["https://myregistry.com:5443"] + [plugins."io.containerd.grpc.v1.cri".registry.mirrors."registry.dso.mil"] + endpoint = ["https://myregistry.com:5443"] + ... +``` + +#### RKE2 cluster + +```yaml +#registries.yaml +mirrors: + registry.dso.mil: + endpoint: + - https://myhostname.com:5443 + registry1.dso.mil: + endpoint: + - https://myhostname.com:5443 + registry1.dso.mil: + endpoint: + - https://myhostname.com:5443 +configs: + myhostname.com:5443: + tls: + ca_file: "/etc/ssl/certs/registry1.pem" +``` + +## Installing Big Bang + +```shell +cd bigbang +``` + +Install flux + +Install Flux 2 into the cluster using the provided artifacts. These are located in the scripts section of the Big Bang repository. + +```shell +kubectl apply -f ./scripts/deploy/flux.yaml +``` + +After Flux is up and running you are ready to deploy Big Bang. We will do this using Helm. To first check to see if Flux is ready, you have several options: + +You can watch to see if Flux is reconciling the projects by watching the progress. + +```shell +watch kubectl get all -n flux-system +``` + +We need a namespace for our preparations and eventually for Big Bang to deploy into. + +```shell +kubectl create ns bigbang +``` + +Installing Big Bang in an air gap environment currently uses the Helm charts from the **[Big Bang Repo](https://repo1.dso.mil/big-bang/bigbang)**. + +All changes are modified in the custom [values.yaml](../../assets/scripts/airgap-dev/values.yaml) file. Modify as needed and replace IP. + +Change the hostname for the installation. It is currently set to the development domain: + +```yaml +# -- Domain used for BigBang created exposed services, can be overridden by individual packages. +hostname: bigbang.dev +``` + +Add your registry URL. This will be the IP address or URL of the utility server or the registry in which you have loaded all of the Big Bang images (note: it is possible that your registry doesn't have a username or password, there will be ignored for insecure registries.): + +```yaml +# -- Single set of registry credentials used to pull all images deployed by BigBang. +registryCredentials: + registry: 10.0.52.144 + username: "asdfasdfasdf" + password: "asdfasdfasdfasdfasdf" + email: "" +``` + +For your Git repository you have two options for setting up the credentials. + +Option 1: Use an existing secret. + +```shell +cd ~/.ssh +ssh-keygen -b 4096 -t rsa -f ~/.ssh/identity -q -N "" +ssh-keyscan <YOUR GIT URL HERE> ./known_hosts + +kubectl create secret generic -n bigbang ssh-credentials \ + --from-file=./identity \ + --from-file=./identity.pub \ + --from-file=./known_hosts +``` + +In the above example we created a new set of keys to use, you could also use an existing set of keys. These are just SSH keys, so any SSH key pair should work. The second command is going to create a known hosts file. There is no way to answer yes to the unknown hosts prompt, this alleviates that need. + +Once we have our private key, public key and the known hosts file, we place all of those into the secret using kubectl. This creates a BASE64 encoded secret of these values. !!! It is VERY important that the names of the files match above. So if you are using your own keypair change the names. Kubernetes uses the names of the files to create the keys inside of the secret. + +If you want to create your secret and store in the Kubernetes format you can add the -o yaml --dry-run to the above command to get that output. + +```shell +kubectl create secret generic ssh-credentials \ + --from-file=./identity \ + --from-file=./identity.pub \ + --from-file=./known_hosts \ + -o yaml --dry-run +``` + +Once your secret is created you can add that value to the values.yaml that we were modifying above. + +```yaml +git: + # -- Existing secret to use for git credentials, must be in the appropriate format: https://toolkit.fluxcd.io/components/source/gitrepositories/#https-authentication + existingSecret: "ssh-credentials" +``` + +**Note that we substituted the name of the secret from the example to the secret created above. This value is arbitrary, so if you created your secret with a different name use that name instead.** + +Option 2: Put the values of your ssh keys directly in the values.yaml file. + +You can also elect to just put the key values and the known hosts directly into the chart's values.yaml file. + +```shell +ssh-keygen -q -N "" -f ./identity +ssh-keyscan <YOUR GIT URL HERE> ./known_hosts + +cat identity +cat identity.pub +cat known_hosts +``` + +Take the values from each of these files and place in the correct fields in the values.yaml. + +```yaml +git: + # -- SSH git credentials, privateKey, publicKey, and knownHosts must be provided + privateKey: | + -----BEGIN RSA PRIVATE KEY----- + MIIEowIBAAKCAQEAwcG6YKsqDC6728XZ7/8oiqnQaw3OkQnvMBrzvZjxd//PsEog + xVc+F9YqW4FIeTH57wN6JXIC4iMbE0QGd6+1yOoYiXkhi66tuO5FN+n4PeMnvKcC + JXtFWme4W/9YnEk/3sbNOgAMPlhMhTsudzLiXtHd3g+xCmNs1pdEIInaNadrolWn + QTM0krUCcC6VLCri7ae/pDloglX4cBJ+EfqFC94T6wUICPd1P7zYsy8WwIQtPhLT + lbY8CHj9iMlxlUdwdiXTlifqHsPgTh3X5e9Vptd+wi0+vfjvrXd/8SuM1q8xdQvY + bZ27AlhgfQsVl9WQrk/47xd3g430G4cqSbyhLQIDAQABAoIBAFlSu153akIFhXtz + Ad7fbcxHLxs7WUCKKOevdTCyApgEqbWm5uazKqAIjqxytHuS65shqjz7C5M/Beti + z+x7Z73BFiDCZBgmLNZ1mhmF1niJcTdKcvXel4FvEZHv7OTX7AcC9XfIr9xKDrTZ + LLmtDqkR7UvDRiX44iMnxzOM+bkDsHVva00e3IoSiOsQ4DKQ1l/HFseVlPIaGzfZ + Z2q0myUrBzlOYE06VJluhexsrrVDi7KdIfR8UGpN4kC5R/vOnOi7ycd4tfsZe2Wb + CjbKMTNYRFnVTt6/SXAhhFu+kz0FftDXNTIOhikVB8ryZ5iyNXszYqiptUI9VUZB + mQLdPuECgYEA9odVxlPUgSMLhbE5vD57jbtB6Cswy5ztAuyCHMABM4U6pVvFDSNb + 244y0ov0TzviaCZkb+0qrAM0ZSNItLQ1PmbeD0SnB4q/C8hDvVtpB+0SPBJMX8so + 49n1Wr5dH0axGMLaZXGmQ4DPEW/t0dNbYpN1Sxgn6KZPprISXigBufkCgYEAyTNe + kY3vaJ6Nla1pBVUmiK7hu1G3Ddihy1w56upHbOnDvJySuVOM5HRPm2ISFwW38/b5 + 5+cGKWnmu7UhFi1d8Iz3Kmr6kpfRxEDtbrk5rkgKJmTtduxAzBH8CTZfxuYIC5xS + 3fbcFpFYfrtE+3tjqlXJSOpLOuDqbA3uGwWFTdUCgYEAkSi9A8uGnAdDmJPzF/l+ + jMTPGOKdl7auBAO41S7lRi3Ti1xO2d6RDuVa3YiU8TakqIi6qQDwGFrGtiqhe+2E + UFsHs9vLsfArb8eaw1uYq5c7HpHzsJASYp+LDcR7VpgsXRUWvZa+vI6S3oSWdu9J + pvCGpxHxJdcPnWrKz/AknBkCgYAnej/U+W9/LJUFSFgx5qo/6Wh7M6ZiPh5I45it + ojhPg3KXgHU9jco4TSYNi+mWwNV+NfiE6wyHdbMDI6ARVOd4uoAIv6M9NDLBeifc + MNXDf3kWXXlGe0afg+va9uNGCH6NoKeVy8kVWIFvpFj9qxE8K8bp2qbWL6lveDA+ + 9w9X3QKBgGtkQi9OI7TyrloZ5F6/0/LnOJMGd/+e2cJUN6Pa10ZAjQh12JZ5fK7i + Vwh5l0P5CGQsuC96n4xPELoBnbTdr+y17f0o+kAuSDAsXnDf/Jjr0y/+uzL6YYCg + VD1yNitgcQw6oHKdTbGn4jni3/VemzONOz0uTB+/K7WhW2J7faaJ + -----END RSA PRIVATE KEY----- + publicKey: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDBwbpgqyoMLrvbxdnv/yiKqdBrDc6RCe8wGvO9mPF3/+wSiDFVz4X1ipbgUh3MfnvA2olcgLiIxsTRAZ8r7XI6hiJeSGLrq2123kU36fg94ye8pwIle0VaZ7hb/1icST/exs06AAw+WEyFOy53MuJe0d3e$" + knownHosts: "10.0.52.144 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBPFZzQ6BmaswdhT8UWD5a/VYmZYrGv1qD3T+euf/gFjkPkeySYRIyM+Kg/UdHCHVBzc4aaFdBDmugHimZ4lbWpE=" +``` + +** Note the above values are all examples and are intentionally not operational keys.** + +Then install Big Bang using Helm. + +```shell + helm upgrade -i bigbang chart -n bigbang --create-namespace -f values.yaml + watch kubectl get gitrepositories,kustomizations,hr,po -A +``` + +**Note that the --create-namespace isn't needed if you created it earlier, but it doesn't hurt anything.** + +You should see the different projects configure working through their reconciliation starting with "gatekeeper". + +## Using 3rd Party Packages + +The third party guide assumes that you already have or are planning to install Big Bang Core. + +### Package your Git repository + +This section provides instructions on packaging your repository from Git. + +```shell +git clone --no-checkout https://repo1.dso.mil/big-bang/apps/third-party/kafka.git && tar -zcvf kafka-repo.tar.gz kafka +``` + +This creates a tar of a full git repo without a checkout. After you have placed this git repo in its destination, you can get the files to view by doing. + +```shell +git checkout +``` + +### Package your registry images + +Package image: + +```shell +docker save -o image-name.tar image-name:image-version +``` + +Unpack the image on your utility server. + +```shell +tar -xvf image-name.tar +``` + +Move the image to the location of your other images. + +Restart your local registry and it should pick up the new image. + +```shell +cd ./var/lib/registry +docker run -p 25000:5000 -v $(pwd):/var/lib/registry registry:2 +# verify the registry mounted correctly +curl http://localhost:25000/v2/_catalog -k +# a list of Big Bang images should be displayed, if not check the volume mount of the registry +``` + +Configure `./synker.yaml` + +Example + +```yaml +destination: + registry: + # Hostname of the destination registry to push to + hostname: 10.0.0.10 + # Port of the destination registry to push to + port: 5000 +``` + +If you are using runtime mirroring, the new image should be available at the original location on your cluster. diff --git a/docs/guides/airgap/k3d.md b/docs/guides/airgap/k3d.md new file mode 100644 index 0000000000000000000000000000000000000000..d1c2f6e82b849cc2095355ace55894cc47ea3b7b --- /dev/null +++ b/docs/guides/airgap/k3d.md @@ -0,0 +1,76 @@ +# K3D + +To test Airgap BigBang on k3d, complete the following steps: + +## Steps + +- Launch EC2 instance of size `c5.2xlarge` and ssh into the instance with at least 50GB storage. + +- Install `k3d` and `docker` cli tools. + +- Download `images.tar.gz`, `repositories.tar.gz` and `bigbang-version.tar.gz` from BigBang release. + + ```shell + curl -O https://umbrella-bigbang-releases.s3-us-gov-west-1.amazonaws.com/umbrella/1.3.0/repositories.tar.gz + curl -O https://umbrella-bigbang-releases.s3-us-gov-west-1.amazonaws.com/umbrella/1.3.0/images.tar.gz + sudo apt install -y net-tools + ``` + +- Follow [Airgap Documentation](./README.md) to install Git server and Registry. + +- Once Git Server and Registry is up, setup k3d mirroring configuration `registries.yaml` + + ```yaml + mirrors: + registry.dso.mil: + endpoint: + - https://host.k3d.internal:5443 + registry1.dso.mil: + endpoint: + - https://host.k3d.internal:5443 + docker.io: + endpoint: + - https://host.k3d.internal:5443 + configs: + host.k3d.internal:5443: + tls: + ca_file: "/etc/ssl/certs/registry1.pem" + ``` + +- Launch k3d cluster. + + ```shell + PRIVATEIP=$( curl http://169.254.169.254/latest/meta-data/local-ipv4 ) + $ k3d cluster create --image "rancher/k3s:v1.20.5-rc1-k3s1" --api-port "33989" -s 1 -a 2 -v "${HOME}/registries.yaml:/etc/rancher/k3s/registries.yaml" -v /etc/machine-id:/etc/machine-id -v "${HOME}/certs/host.k3d.internal.public.pem:/etc/ssl/certs/registry1.pem" --k3s-server-arg "--disable=traefik" --k3s-server-arg "--disable=metrics-server" --k3s-server-arg "--tls-san=$PRIVATEIP" -p 80:80@loadbalancer -p 443:443@loadbalancer + ``` + +- Block all egress with `iptables` except those going to instance IP before deploying bigbang by running [airgap.sh](../../assets/scripts/airgap-dev/airgap.sh). + +```shell +sudo ./k3d_airgap.sh +curl https://$PRIVATEIP:5443/v2/_catalog -k # Show return list of images +curl https://$PRIVATEIP:5443/v2/repositories/rancher/library-busybox/tags +``` + +​To permanently save the iptable rules across reboot, check out [link](https://unix.stackexchange.com/questions/52376/why-do-iptables-rules-disappear-when-restarting-my-debian-system) + +- Test that mirroring is working. + +```shell +curl -k -X GET https://$PRIVATEIP:5443/v2/rancher/local-path-provisioner/tags/list +kubectl run -i --tty test --image=registry1.dso.mil/rancher/local-path-provisioner:v0.0.19 --image-pull-policy='Always' --command sleep infinity -- sh +kubectl run test --image=registry1.dso.mil/rancher/library-busybox:1.31.1 --image-pull-policy='Always' --restart=Never --command sleep infinity +telnet default.kube-system.svc.cluster.local 443 +kubectl describe po test +kubectl delete po test +``` + +- Test that cluster cannot pull outside private registry. + +```shell +kubectl run test --image=nginx +kubectl describe po test # Should fail +kubectl delete po test +``` + +- Proceed to [bigbang deployment process](./README.md#installing-big-bang). diff --git a/docs/guides/airgap/pipeline.md b/docs/guides/airgap/pipeline.md new file mode 100644 index 0000000000000000000000000000000000000000..5ff4eae6d2f6ad3036ac510e4a48f7c81e95ed16 --- /dev/null +++ b/docs/guides/airgap/pipeline.md @@ -0,0 +1,80 @@ +# Current Pipeline Outline and Notes + +1. .pre + + 1. **changelog** + + Does a diff to lint what has changed for the logs. + 1. **commits** + + Enforces the conventional commits stuff. + 1. **pre vars** + + pre checks + 1. **version** + + Gets various versions to build a complex version number for the build. + +1. **smoke tests** + + 1. **clean install** + + Doesn't really effect airgap, this sets up things like cluster names and such. + 1. **upgrade** + + Splits out testing and determines if there are breaking changes for testing of upgrades. + +1. **network up** + + 1. **airgap/network up** + + Creates a VPC and subnets for the cluster to be deployed in. + 1. **aws/airgap/package** + + Packages everything needed for the airgap install into a tar file. This leaves the repositories and images bundled in the Releases section for Big Bang [https://repo1.dso.mil/big-bang/bigbang/-/releases](https://repo1.dso.mil/big-bang/bigbang/-/releases). + +1. **airgap up** + + 1. **aws/airgap/utility up** + + Sets up proxies using Route 53 to essentially fake out where Repo 1 and Registry 1 exist for the purposes of using an air gap registry and git repo. + +1. **cluster up** + + 1. **airgap/rke2/cluster up** + + Stands up an RKE2 cluster for BB in an airgapped network. \*\* Uses terraform ./gitlab-ci/jobs/rke2/dependencies/terraform/. + + Both this and the non-airgapped use the same image registry.dso.mil/platform-one/big-bang/pipeline-templates/pipeline-templates/k3d-builder:0.0.1. + +1. **bigbang up** + + 1. **airgap/rke2/bigbang up** + + Stands up the Big Bang instance. + +1. **test** + + 1. **airgap/rke2/bigbang test** + + Runs some basic tests to make sure that Big Bang is up and working. + +1. **bigbang down** + + 1. **airgap/rke2/bigbang down** + + Tears down the Big Bang instance. + +1. **cluster down** + + 1. **airgap/rke2/cluster down** + +1. **airgap down** + + 1. **aws/airgap/package delete** + + 1. **aws/airgap/utility down** + +1. **network down** + + 1. **airgap/network down** diff --git a/docs/guides/airgap/synker.md b/docs/guides/airgap/synker.md new file mode 100644 index 0000000000000000000000000000000000000000..ad671ee9e89ff40095600035bab19f7259f1fb7d --- /dev/null +++ b/docs/guides/airgap/synker.md @@ -0,0 +1,80 @@ +# Airgap Image Sync + +## Prerequisite + +- `images.tar.gz` from [Big Bang Releases](https://repo1.dso.mil/big-bang/bigbang/-/releases) +- 40gb disk space +- docker + +## Usage + +Unpack + +```shell +tar -xvf images.tar.gz +``` + +Start a local registry based on the images we just unpacked. + +```shell +cd ./var/lib/registry +docker load < registry.tar +docker run -p 25000:5000 -v $(pwd):/var/lib/registry registry:2 +# Verify the registry mounted correctly +curl http://localhost:25000/v2/_catalog -k +# A list of Big Bang images should be displayed, if not check the volume mount of the registry +``` + +Configure `./synker.yaml` + +Example: + +```yaml +destination: + registry: + # Hostname of the destination registry to push to + hostname: 10.0.0.10 + # Port of the destination registry to push to + port: 5000 +``` + +If using Harbor, reference the project name. + +```yaml +destination: + registry: + # Hostname of the destination registry to push to + hostname: harbor.domain.com/ironbank + # Port of the destination registry to push to + port: 443 +``` + +If your destination repo requires credentials, add them to `~/.docker/config.json`. + +```json +{ + "auths": { + "registry.dso.mil": { + "username": "gitlab -user", + "password": "", + "auth": "==" + }, + "registry1.dso.mil": { + "auth": "" + }, + "harbor.yourdomain.com": { + "username": "robot", + "password": "", + "auth": "base64(username:password)=" + } + } +} +``` + +**WARNING:** Verify your credentials with docker login before running synker. If your environment has login lockout after failed attempts synker could trigger a lockout if your credentials are incorrect. + +```shell +./synker push +``` + +Verify the images were pushed to your registry. diff --git a/docs/guides/backup-and-restore/gitlab-backup-restore.md b/docs/guides/backup-and-restore/gitlab-backup-restore.md new file mode 100644 index 0000000000000000000000000000000000000000..1892d1cbce86142e4cb84e71d3131b939b838ccf --- /dev/null +++ b/docs/guides/backup-and-restore/gitlab-backup-restore.md @@ -0,0 +1,103 @@ +# Gitlab Backups and Restores + +## Gitlab Helm Chart Configuration + +1. Follow the `Backup and rename gitlab-rails-secret` task within the [Production document](../../understanding-bigbang/configuration/sample-prod-config.md). +1. Fill in our externalStorage values, specifically `addons.gitlab.objectStorage.iamProfile` or both `.Values.addons.gitlab.objectStorage.accessKey` & `.Values.addons.gitlab.objectStorage.accessSecret` along with `.Values.addons.gitlab.objectStorage.bucketPrefix` or you can override in the name for your own bucket eg: +```yaml +addons: + gitlab: + values: + global: + appConfig: + backups: + bucket: "BUCKET_NAME" +``` +* If you would like to perform manual backups, you will need to ensure the `tmp` location in the toolbox pod has a PVC attached: +```yaml +addons: + gitlab: + values: + gitlab: + toolbox: + persistence: + enabled: true + size: 100Gi +``` + +## Backing up Gitlab + +### Manual Steps + +To perform a manual complete backup of Gitlab, exec into your Gitlab Toolbox pod and run the following: + 1. Find your Gitlab Toolbox pod. + ```shell + kubectl get pods -l release=gitlab,app=toolbox -n gitlab + kubectl exec -it gitlab-toolbox-XXXXXXXXX-XXXXX -n gitlab -- /bin/sh + ``` + 1. Execute the backup-utility command which will pull down data from the database, gitaly, and other portions of the ecosystem. Tar them up and push to your configured cloud storage. + ```shell + backup-utility --skip registry,lfs,artifacts,packages,uploads,pseudonymizer,terraformState,backups + ``` + +You can read more on the upstream documentation: https://docs.gitlab.com/charts/backup-restore/backup.html#create-the-backup. + +### Automatic Cron-based Backups + +It is recommended to set up automatic backups via Gitlab toolbox's cron settings: +```yaml +addons: + gitlab: + values: + gitlab: + toolbox: + backups: + cron: + enabled: true + extraArgs: "--skip registry,lfs,artifacts,packages,uploads,pseudonymizer,terraformState,backups" + persistence: + enabled: true + size: '200Gi' + resources: + limits: + cpu: 800m + memory: "2Gi" + requests: + cpu: 800m + memory: "2Gi" +``` +You can read more on the upstream documentation: https://docs.gitlab.com/charts/charts/gitlab/toolbox/#configuration + +## Restore Gitlab + +1. Ensure your gitlab-rails secret is present in gitops or in-cluster and it correctly matches the database to which the chart is pointed. + * If you need to replace or update your rails secret, once it is updated be sure to restart the following pods: + ```shell + kubectl rollout -n gitlab restart deploy/gitlab-sidekiq-all-in-1-v2 + kubectl rollout -n gitlab restart deploy/gitlab-webservice-default + kubectl rollout -n gitlab restart deploy/gitlab-toolbox + ``` +2. Exec into the toolbox pod and run the backup-utility command: + 1. find your Gitlab Toolbox pod. + ```shell + kubectl get pods -l release=gitlab,app=toolbox -n gitlab + kubectl exec -it gitlab-toolbox-XXXXXXXXX-XXXXX -n gitlab -- /bin/sh + ``` + * Find your most recent backup from cloud storage by finding the last line of your most recent backup job pod: + ```shell + kubectl get po -l release=gitlab,job-name -n gitlab --sort-by=.metadata.creationTimestamp + kubectl logs gitlab-toolbox-backup-XXXXXXXX-XXXXX -n gitlab + ``` + * Find your most recent backup via AWS CLI: + ```shell + aws s3api list-objects --bucket gitlab-backups --query 'reverse(sort_by(Contents,&LastModified))[0].Key' --output + # Save the output, it is in the format TIMESTAMP_VALUE.tar + ``` + 2. Execute the backup-utility command which will pull down the tarred data from your configured cloud storage and restore. + ```shell + # Using the filename + backup-utility --restore -f s3://BUCKET_NAME/ARCHIVE_NAME.tar + # Using the Timestamp + backup-utility --restore -t TIMESTAMP_VALUE + ``` +You can read more on the upstream documentation: https://docs.gitlab.com/charts/backup-restore/restore.html#restoring-the-backup-file. diff --git a/docs/guides/backup-and-restore/nexus-migration-with-velero.md b/docs/guides/backup-and-restore/nexus-migration-with-velero.md new file mode 100644 index 0000000000000000000000000000000000000000..8167d55d803aa6f8e4d1c6a18768a00a0b07e37f --- /dev/null +++ b/docs/guides/backup-and-restore/nexus-migration-with-velero.md @@ -0,0 +1,152 @@ +# Migrating a Nexus Repository Using Velero + +This guide demonstrates how to perform a migration of Nexus repositories and artifacts between Kubernetes clusters. + +[[_TOC_]] + +## Prerequisites/Assumptions + +* K8s running in AWS +* Nexus PersistentVolume is using AWS EBS +* Migration is between clusters on the same AWS instance and availability zone (due to known Velero [limitations](https://velero.io/docs/v1.6/locations/#limitations--caveats)) +* Migration occurs between K8s clusters with the same version +* Velero CLI [tool](https://github.com/vmware-tanzu/velero/releases) +* Crane CLI [tool](https://github.com/google/go-containerregistry) + +## Preparation + +1. Ensure the Velero addon in the Big Bang values file is properly configured. Sample configuration is provided in the following: + + ```yaml + addons: + velero: + enabled: true + plugins: + - aws + values: + serviceAccount: + server: + name: velero + configuration: + provider: aws + backupStorageLocation: + bucket: nexus-velero-backup + volumeSnapshotLocation: + provider: aws + config: + region: us-east-1 + credentials: + useSecret: true + secretContents: + cloud: | + [default] + aws_access_key_id = <CHANGE ME> + aws_secret_access_key = <CHANGE ME> + ``` + +1. Manually create an S3 bucket that the backup configuration will be stored in (in this case it is named `nexus-velero-backup`), this should match the `configuration.backupStorageLocation.bucket` key above. +1. The `credentials.secretContents.cloud` credentials should have the necessary permissions to read/write to S3, volumes and volume snapshots. +1. As a sanity check, take a look at the Velero logs to make sure the backup location (S3 bucket) is valid, you should see something similar to the following: + + ```plaintext + level=info msg="Backup storage location valid, marking as available" backup-storage-location=default controller=backup-storage-location logSource="pkg/controller/backup_storage_location_controller.go:121" + ``` + +1. Ensure there are images/artifacts in Nexus. An as example we will use the [Doom DOS image](https://earthly.dev/blog/dos-gaming-in-docker/) and a simple nginx image. Running `crane catalog nexus-docker.bigbang.dev` will show all of the artifacts and images in Nexus: + + ```console + repository/nexus-docker/doom-dos + repository/nexus-docker/nginx + ``` + +## Backing Up Nexus + +In the cluster containing the Nexus repositories to migrate, running the following command will create a backup called `nexus-ns-backup` and will backup all resources in the `nexus-repository-manager` namespace, including the associated PersistentVolume: + +```shell +velero backup create nexus-ns-backup --include-namespaces nexus-repository-manager --include-cluster-resources=true +``` + +Specifically, this will backup all Nexus resources to the S3 bucket `configuration.backupStorageLocation.bucket` specified above and will create a volume snapshot of the Nexus EBS volume. + + **Double-check** AWS to make sure this is the case by reviewing the contents of the S3 bucket: + + ```shell + aws s3 ls s3://nexus-velero-backup --recursive --human-readable --summarize + ``` + +Expected output: + +```console +backups/nexus-ns-backup/nexus-ns-backup-csi-volumesnapshotcontents.json.gz +backups/nexus-ns-backup/nexus-ns-backup-csi-volumesnapshots.json.gz +backups/nexus-ns-backup/nexus-ns-backup-logs.gz +backups/nexus-ns-backup/nexus-ns-backup-podvolumebackups.json.gz +backups/nexus-ns-backup/nexus-ns-backup-resource-list.json.gz +backups/nexus-ns-backup/nexus-ns-backup-volumesnapshots.json.gz +backups/nexus-ns-backup/nexus-ns-backup.tar.gz +backups/nexus-ns-backup/velero-backup.json +``` + +Also ensure an EBS volume snapshot has been created and the Snapshot status is `Completed`. +![volume-snapshot](../../assets/imgs/guides/volume-snapshot.png) + +## Restoring From Backup + +1. In the new cluster, ensure that Nexus and Velero are running and healthy. + - It is critical to ensure that Nexus has been included in the new cluster's Big Bang deployment, otherwise the restored Nexus configuration will not be managed by the Big Bang Helm chart. +1. If you are using the same `velero.values` from above, Velero should automatically be configured to use the same backup location as before. Verify this with `velero backup get` and you should see output that looks similar to the following: + + ```console + NAME STATUS ERRORS WARNINGS CREATED EXPIRES STORAGE LOCATION SELECTOR + nexus-ns-backup Completed 0 0 2022-02-08 12:34:46 +0100 CET 29d default <none> + ``` + +1. To perform the migration, Nexus must be shut down. In the Nexus Deployment, bring the `spec.replicas` down to `0`. +1. Ensure that the Nexus PVC and PV are also removed (**you may have to delete these manually!**), and that the corresponding Nexus EBS volume has been deleted. + - If you have to remove the Nexus PV and PVC manually, delete the PVC first, which should cascade to the PV. Then, manually delete the underlying EBS volume (if it still exists). + +1. Now that Nexus is down and the new cluster is configured to use the same backup location as the old one, perform the migration by running: + `velero restore create --from-backup nexus-ns-backup` + +1. The Nexus PV and PVC should be recreated (**NOTE:** verify this before continuing!), but the pod will fail to start due to the previous change in the Nexus deployment spec. Change the Nexus deployment `spec.replicas` back to `1`. This will bring up the Nexus pod which should connect to the PVC and PV created during the Velero restore. + +1. Once the Nexus pod is running and healthy, log in to Nexus and verify that the repositories have been restored. + - The credentials to log in will have been restored from the Nexus backup, so they should match the credentials of the Nexus that was migrated (not the new installation!). + - It is recommended to log in to Nexus and download a sampling of images/artifacts to ensure they are working as expected. + + For example, login to Nexus using the migrated credentials: + `docker login -u admin -p admin nexus-docker.bigbang.dev/repository/nexus-docker` + + Running `crane catalog nexus-docker.bigbang.dev` should show the same output as before: + + ```console + repository/nexus-docker/doom-dos + repository/nexus-docker/nginx + ``` + + To ensure the integrity of the migrated image, we will pull and run the `doom-dos` image and defeat evil! + + ```shell + docker pull nexus-docker.bigbang.dev/repository/nexus-docker/doom-dos:latest && \ + docker run -p 8000:8000 nexus-docker.bigbang.dev/repository/nexus-docker/doom-dos:latest + ``` + + ![doom](../../assets/imgs/guides/doom.png "doom") + +## Appendix + +### Sample Nexus values + +```yaml +addons: + nexusRepositoryManager: + enabled: true + values: + nexus: + docker: + enabled: true + registries: + - host: nexus-docker.bigbang.dev + port: 5000 +``` diff --git a/docs/guides/deployment-scenarios/.pages b/docs/guides/deployment-scenarios/.pages new file mode 100644 index 0000000000000000000000000000000000000000..97fcaa89e9f552c35accca4ccd38d7d79d7fac0d --- /dev/null +++ b/docs/guides/deployment-scenarios/.pages @@ -0,0 +1,6 @@ +nav: + - Quickstart: quickstart.md + - SSO Quickstart: sso-quickstart.md + - Extra Package Deployment: extra-package-deployment.md + - Multiple Ingress: multiple-ingress.md + - Appliance Mode: appliance-mode.md diff --git a/docs/guides/deployment-scenarios/appliance-mode.md b/docs/guides/deployment-scenarios/appliance-mode.md new file mode 100644 index 0000000000000000000000000000000000000000..36bea51cbf37e377a218f032b61d3d717db15abc --- /dev/null +++ b/docs/guides/deployment-scenarios/appliance-mode.md @@ -0,0 +1,23 @@ +# Appliance Mode + +Big Bang Core currently provides the ability for all packages to be enabled and running Highly Available while being able to fit within the following footprint: +* 4 vCPU +* 16 GB Ram + +There is a values.yaml file in this same directory which provides an example of some overrides for the core packages. Flux is also required and included as part of the resource consumption and allocation. + +| Big Bang Core Package | Comments | +|-------|---| +| Flux | source, helm, kustomize & notification controllers | +| Istio | Possibly too heavy for reduced compute but still able to run on above machine | +| Jaeger | Not enough value to justify value and footprint above Tempo | +| Tempo | tracing capability integrated with grafana | +| Kiali | Not enough value to justify running in smaller footprint | +| Monitoring | Prometheus/Alertmanager/Grafana for monitoring/alerting | +| ECK | Too heavy for reduced compute | +| Loki/Promtail | need logging | +| Gatekeeper/Kyverno | Static environment on edge, compliance will be validated in development/cloud | +| Cluster Auditor/Kyerno Reporter | Static environment on edge, compliance will be validated in development/cloud | +| Twistlock/Neuvector | Runtime security at least | + +Review and reference [the values file in the configs folder to deploy BigBang in Appliance Mode](../../assets/configs/appliance-mode/values.yaml). diff --git a/docs/guides/deployment-scenarios/extra-package-deployment.md b/docs/guides/deployment-scenarios/extra-package-deployment.md new file mode 100644 index 0000000000000000000000000000000000000000..3fd93e5819048ec895ac479477e279c16b395de6 --- /dev/null +++ b/docs/guides/deployment-scenarios/extra-package-deployment.md @@ -0,0 +1,205 @@ +# Extra Package Deployment + +When using Big Bang you often find that you need or want to deploy an additional package alongside your chosen core/add-on packages. This might be a mission app or just an extra helm chart from the Big Bang community or broader helm/kubernetes community. + +In order to ease the burden on end users and increase integration with Big Bang components, we have provided a way to deploy these additional packages with optional extra "wrapping" to provide integration with Big Bang capabilities. + +Please open an issue in the [Big Bang repository](https://repo1.dso.mil/big-bang/bigbang/-/issues) or in the [Wrapper repository ](https://repo1.dso.mil/big-bang/product/packages/wrapper/-/issues) for any bugs you discover or for any new features or functionality you would like the package/wrapper to support. + +## What is provided + +When utilizing the extra package values/logic, there are two main pieces that are deployed: your package and optionally, the "wrapper." Each of these pieces provides certain things necessary for deploying. The standalone package functionality is recommended for charts that already have Big Bang integration (i.e., networkpolicies, monitoring support, and Istio support). Utilizing the optional wrapper method is recommended for non-integrated charts or mission applications. + +## Package Deployment + +By deploying your package with the Big Bang values, you will accomplish multiple things all through Big Bang values control. These accomplishments are listed in the following: + +* Flux `GitRepository` or `HelmRepository,` depending on configuration. +* Flux `HelmRelease` or `Kustomization,` depending on configuration. +* Control of flux settings for the above. +* Control of `postRenderers` if using Flux `HelmRelease.` +* Passthrough of values to configure your package chart. + +The alternative is that customers would need to manage these things in a "sideloaded" fashion and not have these tied to the Big Bang deployment lifecycle/management. + +### Basic Overrides/Passthroughs + +There are some basic override values provided to modify your Helm chart installation. These do NOT require the `wrapper.` An example of these values is included in the following: + +```yaml +packages: + podinfo: + git: + repo: https://github.com/stefanprodan/podinfo.git + tag: 6.3.4 + path: charts/podinfo + flux: + timeout: 5m + postRenderers: [] + dependsOn: + - name: monitoring + namespace: bigbang + values: + replicaCount: 3 +``` + +In this example, we are doing three things: + +* Overriding the Flux timeout on our `HelmRelease` to be five minutes. +* Adding a dependency on the `monitoring` HelmRelease in the `bigbang` namespace to ensure `podinfo` doesn't deploy until after `monitoring.` +* Passing a value directly to the Podinfo chart to create three replicas. + +We could also specify a `postRenderers` value here, which is documented well in [this document](../../understanding-bigbang/configuration/postrenderers.md). + +If you would like to have values for your extra package deployment adapt based on your Big Bang configuration, you could do something like what is listed in the following: + +```yaml +packages: + podinfo: + values: + istio: + enabled: "{{ .Values.istio.enabled }}" +``` + +In this example, Istio will only be configured for podinfo if Istio is enabled for Big Bang. + +## Wrapper Deployment + +The [Wrapper](https://repo1.dso.mil/big-bang/product/packages/wrapper) is a helm chart that provides additional integrations with key Big Bang components and standards, as well as extensibility features for common use cases. All of these can be tailored to a given package's needs with a simple interface. Currently included are those listed in the following: +* **Istio:** injection/sidecars, `VirtualService` for ingress, and `PeerAuthentication` for mTLS. +* **Monitoring:** `ServiceMonitor` for metrics, alerts for alertmanager, dashboards for Grafana. +* **NetworkPolicies:** Default set of "best practice" network policies with options to extend. +* **Secret creation** (of arbitrary content). +* **Configmap creation** (of arbitrary content). +* **SSO configuration with Authservice** (not fully automated, requires additional configuration of chains and labeling of workload to route to authservice). + +These pieces can typically be complicated to get set up correctly and connected to components that are provided in Big Bang core; therefore, we provide a simplified interface to add them. + +### How to Use the Wrapper + +```yaml +packages: + podinfo: + enabled: true + wrapper: + enabled: true + git: + repo: https://github.com/stefanprodan/podinfo.git + tag: 6.3.4 + path: charts/podinfo +``` + +**NOTE:** The wrapper is an opt-in feature. Without enabling the wrapper, the `packages` will default to just deploying the pieces [mentioned above](#package-deployment). + +The package also has HelmRepository support for sourcing the artifacts from a HelmRepo (of normal or OCI type). Usage of HelmRepos is encouraged if you have access to these types of artifacts. + +With these values added, you should have a very basic deployment of `podinfo` added onto your Big Bang install with some basic default integrations. The rest of this guide will walk you through each section of Big Bang touchpoints and some example configurations you could use. Each of the configurations are compatible with each other (i.e., you can combine the examples that are provided in this document). + +### Istio Configuration + +The wrapper chart provides a number of different ways to provide Istio configuration. The below is a basic example configuring some pieces for the `podinfo` application: + +```yaml +packages: + podinfo: + git: + repo: https://github.com/stefanprodan/podinfo.git + tag: 6.3.4 + path: charts/podinfo + wrapper: + enabled: true + istio: + hosts: + - names: + - podinfo + gateways: + - public + destination: + port: 9898 +``` + +In this example, we are primarily adding a virtual service for ingress to our application (i.e., leveraging defaults to select the proper service). By using the wrapper we are also getting several default options including istio sidecar injection and STRICT mTLS. + +There are more ways to modify the virtual service creation and mTLS config. Additional values can be referenced in the [wrapper chart istio section](https://repo1.dso.mil/big-bang/product/packages/wrapper/-/blob/6536759fef016db8b5504ad6c237f2daffe22844/chart/values.yaml#L31-75). + +### Monitoring Configuration + +The wrapper chart also provides ways to integrate with the monitoring stack (e.g., Prometheus, Alertmanager, and Grafana). A basic way to configure monitoring for `podinfo` is provided in the following: + +```yaml +packages: + podinfo: + git: + repo: https://github.com/stefanprodan/podinfo.git + tag: 6.3.4 + path: charts/podinfo + wrapper: + enabled: true + monitor: + services: + - spec: + endpoints: + - port: http +``` + +In this example we are adding a service monitor that will target the port named `http.` We are leveraging a number of defaults here to select the proper service and metrics paths. + +There are other ways to further modify monitoring settings including more advanced service monitor config. Additional values can be referenced in the [wrapper chart monitor section](https://repo1.dso.mil/big-bang/product/packages/wrapper/-/blob/6536759fef016db8b5504ad6c237f2daffe22844/chart/values.yaml#L77-91). + +### Network Policy Configuration + +The wrapper chart provides ways to configure network policies as needed for your application. A basic config for the `podinfo` application is provided in the following: + +```yaml +packages: + podinfo: + git: + repo: https://github.com/stefanprodan/podinfo.git + tag: 6.3.4 + path: charts/podinfo + wrapper: + enabled: true + network: + allowControlPlaneEgress: true + additionalPolicies: [] + # example of additional egress network policy + # - name: egress-additional + # spec: + # podSelector: {} + # policyTypes: + # - Egress + # egress: + # - to: + # ports: + # - protocol: + # port: 9999 +``` + +In this example, we are allowing the package to have egress to the Kubernetes control plane (i.e.,) API). This particular setting can be beneficial for operators that may need to create Kubernetes resources. + +There are a number of additional configurations including allowing egress to https or more custom needs. Additional values can be referenced in the [wrapper chart network section](https://repo1.dso.mil/big-bang/product/packages/wrapper/-/blob/6536759fef016db8b5504ad6c237f2daffe22844/chart/values.yaml#L93-113). + +### Configmap/Secret Creation + +Often when deploying a Helm chart, you may be expected to point to an existing secret for credentials, a license, or external service configuration (i.e., S3/RDS). The values that can be helpful in creation of these items are provided in the following: + +```yaml +packages: + podinfo: + git: + repo: https://github.com/stefanprodan/podinfo.git + tag: 6.3.4 + path: charts/podinfo + wrapper: + enabled: true + configMaps: + - name: config + data: + foo: bar + secrets: + - name: secret + data: + foo: YmFyCg== +``` + +These secrets/configmaps are created prior to installation of your package; therefore, they can be referenced in any values you use to configure your package. diff --git a/docs/guides/deployment-scenarios/multiple-ingress.md b/docs/guides/deployment-scenarios/multiple-ingress.md new file mode 100644 index 0000000000000000000000000000000000000000..e95cb8017a451834ba1e589fc8461093b1690d61 --- /dev/null +++ b/docs/guides/deployment-scenarios/multiple-ingress.md @@ -0,0 +1,195 @@ +# Using Big Bang with Multiple Ingress Gateways + +By default, Big Bang only creates one ingress for all of the packages. Although this architecture reduces complexity, it also limits the ability to independently control network access and load balancing to groups of packages. By configuring Big Bang for multiple ingress gateways through [Istio](https://istio.io/latest/), package access and load can be better controlled. + +## Architecture + +The following diagram illustrates a typical multiple ingress architecture for Big Bang with the following characteristics: + +- A Kubernetes cluster running on a private subnet. +- Some apps with exposure to the internet through a public network load balancer. +- Some apps without exposure to the internet through a private (aka internal) network load balancer. +- Single Sign-On (SSO) connected to the internet through a dedicated public network load balancer. +- A service mesh ([Istio](https://istio.io/latest/)) handling TLS for all apps except SSO. + +Big Bang is capable of setting up everything within the private subnet using configuration. The public load balancers would need to be configured outside of Big Bang's deployment. + +```mermaid +graph LR + internet((Internet))--http: 80<br/>https: 443-->pub_nlb & kc_nlb + + subgraph "Public Subnet" + pub_nlb("Public Network Load Balancer") + kc_nlb("Keycloak Network Load Balancer") + end + + subgraph "Private Subnet" + pri_nlb("Private Network Load Balancer<br/>10.0.0.0/24")--Dynamic-->pri_igw + + subgraph "Kubernetes Cluster" + pub_nlb--status: 30000<br/>http: 30001<br/>https:30002-->pub_igw + kc_nlb--status: 30100<br/>http: 30101<br/>https:30102-->kc_igw + + pub_igw("Public Ingress Gateway<br/>Type: NodePort")--http: 8080<br/>https: 8443-->pub_gw + pri_igw("Private Ingress Gateway<br/>Type: Load Balancer")--http: 8080<br/>https: 8443-->pri_gw + kc_igw("Keycloak Ingress Gateway"<br/>Type: NodePort)--http: 8080<br/>https: 8443-->kc_gw + + pub_gw("Public Gateway<br/>TLS Terminated<br/>*.bigbang.dev")--http: 8080<br/>gitlab.bigbang.dev-->pub_vs1 + pub_gw--http: 8080<br/>chat.bigbang.dev-->pub_vs2 + pri_gw("Private Gateway<br/>TLS Terminated<br/>*.bigbang.dev")--http: 8080<br/>grafana.bigbang.dev-->pri_vs1 + pri_gw--http: 8080<br/>kibana.bigbang.dev-->pri_vs2 + kc_gw("Keycloak Gateway<br/>TLS Passthrough<br/>keycloak.bigbang.dev")--https: 8443<br/>keycloak.bigbang.dev-->kc_vs1 + + pub_vs1("Virtual Service<br/>Gitlab")--http-->pub_ser1("Service<br/>Gitlab")-->pub_pod1a("Pod") & pub_pod1b("Pod") + pub_vs2("Virtual Service<br/>Mattermost")--http-->pub_ser2("Service<br/>Mattermost")-->pub_pod2a("Pod") & pub_pod2b("Pod") + pri_vs1("Virtual Service<br/>Grafana")--http-->pri_ser1("Service<br/>Grafana")-->pri_pod1a("Pod") & pri_pod1b("Pod") + pri_vs2("Virtual Service<br/>Kibana")--http-->pri_ser2("Service<br/>Kibana")-->pri_pod2a("Pod") & pri_pod2b("Pod") + kc_vs1("Virtual Service<br/>Keycloak")--https-->kc_ser1("Service<br/>Keycloak")-->kc_pod1a("Pod") & kc_pod1b("Pod") + end + end + +``` + +### Load Balancers + +Load balancers are used to ensure traffic is distributed to Istio's control plane running across the Kubernetes nodes. In the diagram above, we only show one Kubernetes node for simplicity. However, most clusters are run with multiple nodes. Load balancers should be connected to all of the nodes. It is recommended that you use Layer 3/4 network load balancers in Big Bang since Istio can handle Layer 7 routing and balancing. + +#### Public Load Balancer + +Public load balancers must be created independent of Big Bang. This is because the cluster is deployed in a private subnet and therefore, does not have access to create resources in the public, internet-facing subnet. In order for the load balancer, in the public subnet, to communicate to the Istio's Ingress Gateway, in the private subnet, node ports must be used. Node ports will bind a port on each cluster node to a listener in the ingress gateway. The load balancer will distribute traffic on that port to the cluster nodes. + +> Not all deployments have a public subnet. For example, a private network that can only be accessed through a VPN would not have a public subnet and not require any public load balancers. + +In Big Bang, this is how you would setup an ingress gateway for Node Ports: + +```yaml +istio: + ingressGateways: + public-ingressgateway: # This creates a new ingress gateway called "public-ingressgateway" + type: "NodePort" # Tell Big Bang this should be a node port ingress gateway rather than a load balancer type + nodePortBase: 30000 # Bind the following ports: Status <-> 30000; HTTP <-> 30001; HTTPS <-> 30002; SNI <-> 30003 +``` + +The load balancer can then be setup to forward HTTP traffic to all nodes on port 30001 and HTTPS traffic on all nodes to 30002. Istio provides a ready status that can be reached via HTTP on the status port. So, the load balancer's health check can be setup for all nodes on port 30000 to the URL `/healthz/ready.` DNS entries should be created for each hostname to point to the load balancer's DNS. Package endpoints can then be accessed using the FQDN from the internet. + +#### Private/Internal Load Balancer + +Private or internal load balancers can usually be created automatically by Big Bang via Istio using service annotations. By using these annotations, a load balancer will be created for you and automatically mapped to the appropriate nodes/ports for distributing the load. + +Here is how you would setup Big Bang for a private load balancer on AWS. For other cloud providers, review [Kubernetes internal load balancer documentation](https://kubernetes.io/docs/concepts/services-networking/_print/#internal-load-balancer): + +```yaml +istio: + ingressGateways: + private-ingressgateway: # This creates a new ingress gateway called "private-ingressgateway" + type: "LoadBalancer" # Tell Big Bang this should be a load balancer ingress gateway rather than a node port type + kubernetesResourceSpec: + serviceAnnotations: + # The following annotations tell Istio to setup an internal network load balancer through AWS + service.beta.kubernetes.io/aws-load-balancer-type: nlb + service.beta.kubernetes.io/aws-load-balancer-internal: "true" +``` + +After the load balancer is created, you will need to setup DNS entries (e.g., Route 53 on AWS) to point to the load balancer using the host names of the applications. You should then be able to access the package endpoints from the private network using the FQDN. + +> Private network access can be achieved through SSH on a jump box (aka bastion), VPN, or other secure gateway. + +### Ingress Gateways + +Istio's Ingress Gateways are services that sit on the edge of the Kubernetes cluster and listen for incoming traffic. In Big Bang, the Ingress Gateways are either setup as Node Port or Load Balancer services. As a Node Port type, ports on the node are bound to the service and incoming traffic is routed to the nodes on those ports. As a Load Balancer type, a load balancer is automatically created and configured to communicate to the service. + +> In some cases, automatic load balancer creating and configuration is not supported and a Node Port service must be used. + +Ingress Gateways will listen for incoming traffic on their assigned ports and forward that traffic to attached Gateways on the appropriate port. For example, traffic may be received on port 30002 and forwarded to all attached Gateways on port 8443. + +In Big Bang, ingress gateways can be created and configured using the `istio.ingressGateways` values. By adding additional keys under this value, additional ingress gateways will be created. An example of setting up three Ingress Gateways to match the architecture diagram above is provided in the following: + +> It is recommended that you add `-ingressgateway` on the end of the name of the key to help identify the pods created in the Kubernetes cluster. + +```yaml +istio: + ingressGateways: + public-ingressgateway: + type: "NodePort" + nodePortBase: 30000 # Bind the following ports: Status (15021) <-> 30000; HTTP (8080) <-> 30001; HTTPS (8443) <-> 30002; SNI (15443) <-> 30003 + + private-ingressgateway: + type: "LoadBalancer" + kubernetesResourceSpec: + # Setup an AWS internal (private) load balancer + serviceAnnotations: + service.beta.kubernetes.io/aws-load-balancer-type: nlb + service.beta.kubernetes.io/aws-load-balancer-internal: "true" + + passthrough-ingressgateway: + type: "NodePort" + nodePortBase: 30100 # Bind the following ports: Status (15021) <-> 30100; HTTP (8080) <-> 30101; HTTPS (8443) <-> 30102; SNI (15443) <-> 30103 +``` + +The default values for Ingress Gateways will work for most situations. However, if you need finer control over the configuration, any of the settings in the [Kubernetes Resource Spec](https://istio.io/latest/docs/reference/config/istio.operator.v1alpha1/#KubernetesResourcesSpec) can be added to `kubernetesResourceSpec` as a map. Some examples of additional settings include environmental variables, service selectors, affinity mapping, or additional ports. + +### Gateways + +While Ingress Gateways handle traffic using ports, Gateways manage traffic using protocol and hostname. Each Gateway must be assigned to one or more Ingress Gateways to receive traffic. Gateways are set up to listen on ports for specific protocols and hostnames. Traffic is then sent on to Virtual Services for further routing. + +Gateways can handle TLS encryption, including termination. If a Gateway is set up for TLS termination, it handles the full TLS handshake during HTTPS connections and decrypts messages at the Gateway before passing traffic on the backend in the clear. To perform this function, the Gateway must be provided a TLS private key and certificate. There are [other TLS modes](https://istio.io/latest/docs/reference/config/networking/gateway/#ServerTLSSettings-TLSmode) supported by Gateways that may also be used. + +In Big Bang, Gateways can be created and configured using the `istio.gateways` values. By adding additional keys under this value, additional Gateways will be created. By default, HTTP traffic is always redirected to HTTPS traffic in the Gateway. An example of setting up three Gateways to match the architecture diagram above is provided in the following: + +> By default Big Bang uses TLS termination on Gateways. For Keycloak, the package must manage the TLS encryption. In that case, we use TLS passthrough on the Gateway and setup the TLS keys in the package. + +```yaml + gateways: + public: + ingressGateway: "public-ingressgateway" # Connect to the 'public-ingressgateway' + hosts: + - "*.bigbang.dev" # Match all hostnames in the domain + tls: + key: "-----BEGIN PRIVATE KEY-----\nMIIE...." # TLS Private Key + cert: "-----BEGIN CERTIFICATE-----\nMIIF...." # TLS Certificate + private: + ingressGateway: "private-ingressgateway" # Connect to 'private-ingressgateway' + hosts: + - "*.bigbang.dev" # Match all hostnames in the domain + tls: + key: "-----BEGIN PRIVATE KEY-----\nMIIE...." # TLS Private Key + cert: "-----BEGIN CERTIFICATE-----\nMIIF...." # TLS Certificate + passthrough: + ingressGateway: "passthrough-ingressgateway" # Connect to 'passthrough-ingressgateway' + hosts: + - "keycloak.bigbang.dev" # Only match keycloak hostname + tls: + mode: "PASSTHROUGH" # Pass TLS encrypted traffic to application +``` + +Big Bang will automatically create a secret with the TLS key and cert provided for each Gateway. In some cases, it may be advantageous to create the secrets ahead of time and have Big Bang use them. In this case a TLS secret named `{name of gateway}-cert` can be prepopulated with the key and `tls.key` and `tls.cert` values can be left blank. For example, for the `private` Gateway, a `private-cert` TLS secret would be created. + +### Virtual Services + +Virtual services use full URL host and path information to route incoming traffic to a service. Each package in Big Bang manages its own Virtual Services since the paths and ports vary for each package. However, in order to receive traffic at the Virtual Service, it must be connected to a Gateway. In Big Bang we configure this under each package. An example of this configuration that matches the architecture diagram above is provided in the following. + +```yaml +monitoring: + ingress: + gateway: "private" +elasticsearchKibana: + ingress: + gateway: "private" +addons: + gitlab: + enabled: true + ingress: + gateway: "public" + mattermost: + enabled: true + ingress: + gateway: "public" + keycloak: + enabled: true + ingress: + gateway: "passthrough" +``` + +### Services and Pods + +Once traffic passes through the Virtual Service, it is passed to a Service. The service may have several redundant pods and a load balancing scheme to manage incoming traffic. It will route the traffic to the appropriate pod based on these settings. Each package implements the service and pods differently and typically the default configuration is adequate for most deployments. diff --git a/docs/guides/deployment-scenarios/quickstart.md b/docs/guides/deployment-scenarios/quickstart.md new file mode 100644 index 0000000000000000000000000000000000000000..db27250d66480c698cf231e2ee86d9769524cf4d --- /dev/null +++ b/docs/guides/deployment-scenarios/quickstart.md @@ -0,0 +1,1076 @@ +# Quick Start + +[[_TOC_]] + +## Video Walkthrough + +A 36-minute speed run video walkthrough of this quickstart can be found on the following two mirrored locations: +* [Google Drive - Video Mirror](https://drive.google.com/file/d/1m1pR0a-lrWr_Wed4EsI8-vimkYfb06GQ/view) +* [Repo1 - Video Mirror](https://repo1.dso.mil/platform-one/bullhorn-delivery-static-assets/-/blob/master/big_bang/bigbang_quickstart.mp4) + +## Overview + +This quick start guide explains in beginner-friendly terminology how to complete the following tasks in under an hour: + +1. Turn a Virtual Machine (VM) into a k3d single-node Kubernetes cluster. +1. Deploy Big Bang on the cluster using a demonstration and local development-friendly workflow. + + > **NOTE:** This guide mainly focuses on the scenario of deploying Big Bang to a remote VM with enough resources to run Big Bang [(refer to step 1 for recommended resources)](#step-1-provision-a-virtual-machine). If your workstation has sufficient resources, or you are willing to disable packages to lower the resource requirements, then local development is possible. This quick start guide is valid for both remote and local deployment scenarios. + +1. Customize the demonstration deployment of Big Bang. + +## Important Security Notice + +All Developer and Quick Start Guides in this repo are intended to deploy environments for development, demonstration, and learning purposes. There are practices that are bad for security, but make perfect sense for these use cases: using of default values, minimal configuration, tinkering with new functionality that could introduce a security misconfiguration, and even purposefully using insecure passwords and disabling security measures like Kyverno for convenience. Many applications have default username and passwords combinations stored in the public git repo, these insecure default credentials and configurations are intended to be overridden during production deployments. + +When deploying a dev/demo environment there is a high chance of deploying Big Bang in an insecure configuration. Such deployments should be treated as if they could become easily compromised if made publicly accessible. + +### Recommended Security Guidelines for Dev/Demo Deployments + +* Ideally, these environments should be spun up on VMs with private IP addresses that are not publicly accessible. Local network access or an authenticated remote network access solution like a VPN or [sshuttle](https://github.com/sshuttle/sshuttle#readme) should be used to reach the private network. +* DO NOT deploy publicly routable dev/demo clusters into shared VPCs (i.e., like a shared dev environment VPCs) or on VMs with IAM Roles attached. If the demo cluster were compromised, an adversary might be able to use it as a stepping stone to move deeper into an environment. +* If you want to safely demo on Cloud Provider VMs with public IPs you must follow these guidelines: + * Prevent Compromise: + * Use firewalls that only allow the two VMs to talk to each other and your whitelisted IP. + * Limit Blast Radius of Potential Compromise: + * Only deploy to an isolated VPC, not a shared VPC. + * Only deploy to VMs with no IAM roles/rights attached. + +## Network Requirements Notice + +This install guide by default requires network connectivity from your server to external DNS providers, specifically the Google DNS server at `8.8.8.8`, you can test that your node has connectivity to this DNS server by running the command `nslookup google.com 8.8.8.8` (run this from the node). + +If this command returns `DNS request timed out`, then you will need to follow the steps in [troubleshooting](#Troubleshooting) to change the upstream DNS server in your kubernetes cluster to your networks DNS server. + +Additionally, if your network has a proxy that has custom/internal SSL certificates then this may cause problems with pulling docker images as the image verification process can sometimes fail. Ensure you are aware of your network rules and restrictions before proceeding with the installation in order to understand potential problems when installing. + +## Important Background Contextual Information + +`BLUF:` This quick start guide optimizes the speed at which a demonstrable and tinker-able deployment of Big Bang can be achieved by minimizing prerequisite dependencies and substituting them with quickly implementable alternatives. Refer to the [Customer Template Repo](https://repo1.dso.mil/big-bang/customers/template) for guidance on production deployments. + +`Details of how each prerequisite/dependency is quickly satisfied:` + +* **Operating System Prerequisite:** Any Linux distribution that supports Docker should work. +* **Operating System Pre-configuration:** This quick start includes easy paste-able commands to quickly satisfy this prerequisite. +* **Kubernetes Cluster Prerequisite:** is implemented using k3d (k3s in Docker) +* **Default Storage Class Prerequisite:** k3d ships with a local volume storage class. +* **Support for automated provisioning of Kubernetes Service of type LB Prerequisite:** is implemented by taking advantage of k3d's ability to easily map port 443 of the VM to port 443 of a Dockerized LB that forwards traffic to a single Istio Ingress Gateway. Important limitations of this quick start guide's implementation of k3d to be aware of: + * Multiple Ingress Gateways aren't supported by this implementation as they would each require their own LB, and this trick of using the host's port 443 only works for automated provisioning of a single service of type LB that leverages port 443. + * Multiple Ingress Gateways makes a demoable/tinkerable KeyCloak and locally hosted SSO deployment much easier. + * Multiple Ingress Gateways can be demoed on k3d if configuration tweaks are made, MetalLB is used, and you are developing using a local Linux Desktop. (network connectivity limitations of the implementation would only allow a the web browser on the k3d host server to see the webpages.) + * If you want to easily demo and tinker with Multiple Ingress Gateways and Keycloak, then MetalLB + k3s (or another non-Dockerized Kubernetes distribution) would be a happy path to look into. (or alternatively create an issue ticket requesting prioritization of a keycloak quick start or better yet a Merge Request.) +* Access to Container Images Prerequisite is satisfied by using personal image pull credentials and internet connectivity to <https://registry1.dso.mil> +* Customer Controlled Private Git Repo Prerequisite isn't required due to substituting declarative git ops installation of the Big Bang Helm chart with an imperative helm cli based installation. +* Encrypting Secrets as code Prerequisite is substituted with clear text secrets on your local machine. +* Installing and Configuring Flux Prerequisite: Not using GitOps for the quick start eliminates the need to configure flux, and installation is covered within this guide. +* HTTPS Certificate and hostname configuration Prerequisites: Are satisfied by leveraging default hostname values and the demo HTTPS wildcard certificate that's uploaded to the Big Bang repo, which is valid for *.bigbang.dev, *.admin.bigbang.dev, and a few others. The demo HTTPS wildcard certificate is signed by the Lets Encrypt Free, a Certificate Authority trusted on the public internet, so demo sites like grafana.bigbang.dev will show a trusted HTTPS certificate. +* DNS Prerequisite: is substituted by making use of your workstation's Hosts file. + +## Step 1: Provision a Virtual Machine + +The following requirements are recommended for Demonstration Purposes: + +* 1 Virtual Machine with 32GB RAM, 8-Core CPU (t3a.2xlarge for AWS users), and 100GB of disk space should be sufficient. +* Ubuntu Server 20.04 LTS (Ubuntu comes up slightly faster than CentOS, in reality any Linux distribution with Docker installed should work). +* Most Cloud Service Provider provisioned VMs default to passwordless sudo being preconfigured, but if you're doing local development or a bare metal deployment then it's recommended that you configure passwordless sudo. + * Steps for configuring passwordless sudo: [(source)](https://unix.stackexchange.com/questions/468416/setting-up-passwordless-sudo-on-linux-distributions) + 1. `sudo visudo` + 1. Change: + + ```plaintext + # Allow members of group sudo to execute any command + %sudo ALL=(ALL:ALL) ALL + ``` + + To: + + ```plaintext + # Allow members of group sudo to execute any command, no password + %sudo ALL=(ALL:ALL) NOPASSWD:ALL + ``` + +* Network connectivity to Virtual Machine (provisioning with a public IP and a security group locked down to your IP should work. Otherwise a Bare Metal server or even a Vagrant Box Virtual Machine configured for remote ssh works fine.) + +> **NOTE**: If your workstation has Docker, sufficient compute, and has ports 80, 443, and 6443 free, you can use your workstation in place of a remote virtual machine and do local development. + +## Step 2: SSH to Remote VM + +* ssh and passwordless sudo should be configured on the remote machine. +* You can skip this step if you are doing local development. + +1. Set up SSH. + + ```shell + # [admin@Unix_Laptop:~] + mkdir -p ~/.ssh + chmod 700 ~/.ssh + touch ~/.ssh/config + chmod 600 ~/.ssh/config + temp="""########################## + Host k3d + Hostname x.x.x.x #IP Address of k3d node + IdentityFile ~/.ssh/bb-onboarding-attendees.ssh.privatekey #ssh key authorized to access k3d node + User ubuntu + StrictHostKeyChecking no #Useful for vagrant where you'd reuse IP from repeated tear downs + #########################""" + echo "$temp" | tee -a ~/.ssh/config #tee -a, appends to preexisting config file + ``` + +1. SSH to instance. + + ```shell + # [admin@Laptop:~] + ssh k3d + + # [ubuntu@Ubuntu_VM:~] + ``` + +## Step 3: Install Prerequisite Software + +**NOTE:** This guide follows the DevOps best practice of left-shifting feedback on mistakes and surfacing errors as early in the process as possible. This is done by leveraging tests and verification commands. + +1. Install Git. + + ```shell + sudo apt install git -y + ``` + +1. Install Docker and add $USER to Docker group. + + ```shell + # [ubuntu@Ubuntu_VM:~] + sudo apt update -y && sudo apt install apt-transport-https ca-certificates curl gnupg lsb-release -y && curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg && echo "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null && sudo apt update -y && sudo apt install docker-ce docker-ce-cli containerd.io -y && sudo usermod --append --groups docker $USER + + + # Alternative command (less safe due to curl | bash, but more generic): + # curl -fsSL https://get.docker.com | bash && sudo usermod --append --groups docker $USER + ``` + +1. Log out and login to allow the `usermod` change to take effect. + + ```shell + # [ubuntu@Ubuntu_VM:~] + exit + ``` + + ```shell + # [admin@Laptop:~] + ssh k3d + ``` + +1. Verify Docker Installation. + + ```shell + # [ubuntu@Ubuntu_VM:~] + docker run hello-world + ``` + + ```console + Hello from Docker! + ``` + +1. Install k3d. + + ```shell + # [ubuntu@Ubuntu_VM:~] + # The following downloads the 64 bit linux version of k3d v5.5.1, checks it + # against a copy of the sha256 checksum, if they match k3d gets installed + wget -q -O - https://github.com/k3d-io/k3d/releases/download/v5.5.1/k3d-linux-amd64 > k3d + + echo 4849027dc5e835bcce49070af3f4eeeaada81d96bce49a8b89904832a0c3c2c0 k3d | sha256sum -c | grep OK + # 4849027dc5e835bcce49070af3f4eeeaada81d96bce49a8b89904832a0c3c2c0 came from running the following against a trusted internet connection. + # wget -q -O - https://github.com/k3d-io/k3d/releases/download/v5.5.1/k3d-linux-amd64 | sha256sum | cut -d ' ' -f 1 + + if [ $? == 0 ]; then chmod +x k3d && sudo mv k3d /usr/local/bin/k3d; fi + + + # Alternative command (less safe due to curl | bash, but more generic): + # wget -q -O - https://raw.githubusercontent.com/k3d-io/k3d/main/install.sh | TAG=v5.5.1 bash + ``` + +1. Verify k3d installation. + + ```shell + # [ubuntu@Ubuntu_VM:~] + k3d --version + ``` + + ```console + k3d version v5.5.1 + k3s version v1.26.4-k3s1 (default) + ``` + +1. Install kubectl. + + ```shell + # [ubuntu@Ubuntu_VM:~] + # The following downloads the 64 bit linux version of kubectl v1.23.5, checks it + # against a copy of the sha256 checksum, if they match kubectl gets installed + wget -q -O - https://dl.k8s.io/release/v1.23.5/bin/linux/amd64/kubectl > kubectl + + echo 715da05c56aa4f8df09cb1f9d96a2aa2c33a1232f6fd195e3ffce6e98a50a879 kubectl | sha256sum -c | grep OK + # 715da05c56aa4f8df09cb1f9d96a2aa2c33a1232f6fd195e3ffce6e98a50a879 came from + # wget -q -O - https://dl.k8s.io/release/v1.23.5/bin/linux/amd64/kubectl.sha256 + + if [ $? == 0 ]; then chmod +x kubectl && sudo mv kubectl /usr/local/bin/kubectl; fi + + # Create a symbolic link from k to kubectl + sudo ln -s /usr/local/bin/kubectl /usr/local/bin/k + ``` + +1. Verify kubectl installation. + + ```shell + # [ubuntu@Ubuntu_VM:~] + kubectl version --client + ``` + + ```console + Client Version: version.Info{Major:"1", Minor:"23", GitVersion:"v1.23.5", GitCommit:"c285e781331a3785a7f436042c65c5641ce8a9e9", GitTreeState:"clean", BuildDate:"2022-03-16T15:58:47Z", GoVersion:"go1.17.8", Compiler:"gc", Platform:"linux/amd64"} + ``` + +1. Install Kustomize. + + ```shell + # [ubuntu@Ubuntu_VM:~] + # The following downloads the 64 bit linux version of kustomize v4.5.4, checks it + # against a copy of the sha256 checksum, if they match kustomize gets installed + wget -q -O - https://github.com/kubernetes-sigs/kustomize/releases/download/kustomize%2Fv4.5.4/kustomize_v4.5.4_linux_amd64.tar.gz > kustomize.tar.gz + + echo 1159c5c17c964257123b10e7d8864e9fe7f9a580d4124a388e746e4003added3 kustomize.tar.gz | sha256sum -c | grep OK + # 1159c5c17c964257123b10e7d8864e9fe7f9a580d4124a388e746e4003added3 + # came from https://github.com/kubernetes-sigs/kustomize/releases/download/kustomize%2Fv4.5.4/checksums.txt + + if [ $? == 0 ]; then tar -xvf kustomize.tar.gz && chmod +x kustomize && sudo mv kustomize /usr/local/bin/kustomize && rm kustomize.tar.gz ; fi + + + # Alternative commands (less safe due to curl | bash, but more generic): + # curl -s "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh" | bash + # chmod +x kustomize + # sudo mv kustomize /usr/bin/kustomize + ``` + +1. Verify Kustomize installation. + + ```shell + # [ubuntu@Ubuntu_VM:~] + kustomize version + ``` + + ```console + {Version:kustomize/v4.5.4 GitCommit:cf3a452ddd6f83945d39d582243b8592ec627ae3 BuildDate:2022-03-28T23:12:45Z GoOs:linux GoArch:amd64} + ``` + +1. Install Helm. + + ```shell + # [ubuntu@Ubuntu_VM:~] + # The following downloads the 64 bit linux version of helm v3.8.1, checks it + # against a copy of the sha256 checksum, if they match helm gets installed + wget -q -O - https://get.helm.sh/helm-v3.13.3-linux-amd64.tar.gz > helm.tar.gz + + echo bbb6e7c6201458b235f335280f35493950dcd856825ddcfd1d3b40ae757d5c7d helm.tar.gz | sha256sum -c | grep OK + # bbb6e7c6201458b235f335280f35493950dcd856825ddcfd1d3b40ae757d5c7d + # came from https://github.com/helm/helm/releases/tag/v3.13.3 + + if [ $? == 0 ]; then tar -xvf helm.tar.gz && chmod +x linux-amd64/helm && sudo mv linux-amd64/helm /usr/local/bin/helm && rm -rf linux-amd64 && rm helm.tar.gz ; fi + + + # Alternative command (less safe due to curl | bash, but more generic): + # curl https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 | bash + ``` + +1. Verify Helm installation. + + ```shell + # [ubuntu@Ubuntu_VM:~] + helm version + ``` + + ```console + version.BuildInfo{Version:"v3.13.3", GitCommit:"c8b948945e52abba22ff885446a1486cb5fd3474", GitTreeState:"clean", GoVersion:"go1.20.11"} + ``` + +## Step 4: Configure Host Operating System Prerequisites + +* Run Operating System Pre-configuration + + ```shell + # [ubuntu@Ubuntu_VM:~] + # Needed for ECK to run correctly without OOM errors + echo 'vm.max_map_count=524288' | sudo tee -a /etc/sysctl.d/vm-max_map_count.conf + # Alternatively can use (not persistent after restart): + # sudo sysctl -w vm.max_map_count=524288 + + + # Needed by Sonarqube + echo 'fs.file-max=131072' | sudo tee -a /etc/sysctl.d/fs-file-max.conf + # Alternatively can use (not persistent after restart): + # sudo sysctl -w fs.file-max=131072 + + # Also Needed by Sonarqube + ulimit -n 131072 + ulimit -u 8192 + + # Load updated configuration + sudo sysctl --load --system + + # Preload kernel modules, required by istio-init running on SELinux enforcing instances + sudo modprobe xt_REDIRECT + sudo modprobe xt_owner + sudo modprobe xt_statistic + + # Persist kernel modules settings after reboots + printf "xt_REDIRECT\nxt_owner\nxt_statistic\n" | sudo tee -a /etc/modules + + # Kubernetes requires swap disabled + # Turn off all swap devices and files (won't last reboot) + sudo swapoff -a + + # For swap to stay off, you can remove any references found via + # cat /proc/swaps + # cat /etc/fstab + ``` + +## Step 5: Create a k3d Cluster + +After reading the notes on the purpose of k3d's command flags, you will be able to copy and paste the command to create a k3d cluster. + +### Explanation of k3d Command Flags, Relevant to the Quick Start + +* `SERVER_IP="10.10.16.11"` and `--k3s-arg "--tls-san=$SERVER_IP@server:0"`: + These associate an extra IP to the Kubernetes API server's generated HTTPS certificate. + + **Explanation of the effect:** + + 1. If you are running k3d from a local host or you plan to run 100% of kubectl commands while ssh'd into the k3d server, then you can omit these flags or paste unmodified incorrect values with no ill effect. + + 1. If you plan to run k3d on a remote server, but run kubectl, helm, and kustomize commands from a workstation, which would be needed if you wanted to do something like kubectl port-forward then you would need to specify the remote server's public or private IP address here. After pasting the ~/.kube/config file from the k3d server to your workstation, you will need to edit the IP inside of the file from 0.0.0.0 to the value you used for SERVER_IP. + + **Tips for looking up the value to plug into SERVER_IP:** + + * Method 1: If your k3d server is a remote box, then run the following command from your workstation. + `cat ~/.ssh/config | grep k3d -A 6` + * Method 2: If the remote server was provisioned with a Public IP, then run the following command from the server hosting k3d. + `curl ifconfig.me --ipv4` + * Method 3: If the server hosting k3d only has a Private IP, then run the following command from the server hosting k3d + `ip address` + (You will see more than one address, use the one in the same subnet as your workstation) + +* `--volume /etc/machine-id:/etc/machine-id`: +This is required for fluentbit log shipper to work. + +* `IMAGE_CACHE=${HOME}/.k3d-container-image-cache`, `cd ~`, `mkdir -p ${IMAGE_CACHE}`, and `--volume ${IMAGE_CACHE}:/var/lib/rancher/k3s/agent/containerd/io.containerd.content.v1.content`: +These make it so that if you fully deploy Big Bang and then want to reset the cluster to a fresh state to retest some deployment logic. Then after running `k3d cluster delete k3s-default` and redeploying, subsequent deployments will be faster because all container images used will have been prefetched. + +* `--servers 1 --agents 3`: +These flags are not used and shouldn't be added. This is because the image caching logic works more reliably on a one node Dockerized cluster, vs a four node Dockerized cluster. If you need to add these flags to simulate multi nodes to test pod and node affinity rules, then you should remove the image cache flags, or you may experience weird image pull errors. + +* `--port 80:80@loadbalancer` and `--port 443:443@loadbalancer`: +These map the virtual machine's port 80 and 443 to port 80 and 443 of a Dockerized LB that will point to the NodePorts of the Dockerized k3s node. + +* `--k3s-arg "--disable=traefik@server:0"`: +This flag prevents the traefik ingress controller from being deployed. Without this flag traefik would provision a service of type LoadBalancer, and claim k3d's only LoadBalancer that works with ports 80 and 443. Disabling this makes it so the Istio Ingress Gateway will be able to claim the service of type LoadBalancer. + +### k3d Cluster Creation Commands + +```shell +# [ubuntu@Ubuntu_VM:~] +SERVER_IP="10.10.16.11" #(Change this value, if you need remote kubectl access) + +# Create image cache directory +IMAGE_CACHE=${HOME}/.k3d-container-image-cache + +mkdir -p ${IMAGE_CACHE} + +k3d cluster create \ + --k3s-arg "--tls-san=$SERVER_IP@server:0" \ + --volume /etc/machine-id:/etc/machine-id \ + --volume ${IMAGE_CACHE}:/var/lib/rancher/k3s/agent/containerd/io.containerd.content.v1.content \ + --k3s-arg "--disable=traefik@server:0" \ + --port 80:80@loadbalancer \ + --port 443:443@loadbalancer \ + --api-port 6443 +``` + +### k3d Cluster Verification Command + +```shell +# [ubuntu@Ubuntu_VM:~] +kubectl config use-context k3d-k3s-default +kubectl get node +``` + +```console +Switched to context "k3d-k3s-default". +NAME STATUS ROLES AGE VERSION +k3d-k3s-default-server-0 Ready control-plane,master 11m v1.22.7+k3s1 +``` + +## Step 6: Verify Your IronBank Image Pull Credentials + +1. Here we continue to follow the DevOps best practice of enabling early left-shifted feedback whenever possible; Before adding credentials to a configuration file and not finding out there is an issue until after we see an ImagePullBackOff error during deployment, we will do a quick left-shifted verification of the credentials. + +1. Look up your IronBank image pull credentials. + + 1. In a web browser go to [https://registry1.dso.mil](https://registry1.dso.mil). + 1. Login via OIDC provider. + 1. In the top right of the page, click your name, and then User Profile. + 1. Your image pull username is labeled "Username." + 1. Your image pull password is labeled "CLI secret." + + > **NOTE:** The image pull credentials are tied to the life cycle of an OIDC token which expires after ~3 days, so if 3 days have passed since your last login to IronBank, the credentials will stop working until you re-login to the [https://registry1.dso.mil](https://registry1.dso.mil) GUI. + +1. Verify your credentials work. + + ```shell + # [ubuntu@Ubuntu_VM:~] + # Turn off bash history + set +o history + + export REGISTRY1_USERNAME=<REPLACE_ME> + export REGISTRY1_PASSWORD=<REPLACE_ME> + echo $REGISTRY1_PASSWORD | docker login registry1.dso.mil --username $REGISTRY1_USERNAME --password-stdin + + # Turn on bash history + set -o history + ``` + +## Step 7: Clone Your Desired Version of the Big Bang Umbrella Helm Chart + +```shell +# [ubuntu@Ubuntu_VM:~] +cd ~ +git clone https://repo1.dso.mil/big-bang/bigbang.git + +# Checkout version latest stable version of Big Bang +cd ~/bigbang +git checkout tags/$(grep 'tag:' base/gitrepository.yaml | awk '{print $2}') +git status +cd ~ + +# Note you can do the following to checkout a specific version of bigbang +# cd ~/bigbang +# git checkout tags/1.30.1 +``` + +```console +HEAD detached at (latest version) +``` + +> **NOTE:** HEAD is git speak for current context within a tree of commits. + +## Step 8: Install Flux + +The `echo $REGISTRY1_USERNAME` is there to verify that the value of your environmental variable is still populated. If you switch terminals or re-login, you may need to reestablish these variables. + + ```shell + # [ubuntu@Ubuntu_VM:~] + echo $REGISTRY1_USERNAME + cd ~/bigbang + $HOME/bigbang/scripts/install_flux.sh -u $REGISTRY1_USERNAME -p $REGISTRY1_PASSWORD + # NOTE: After running this command the terminal may appear to be stuck on + # "networkpolicy.networking.k8s.io/allow-webhooks created" + # It's not stuck, the end of the .sh script has a kubectl wait command, give it 5 min + # Also if you have slow internet/hardware you might see a false error message + # error: timed out waiting for the condition on deployments/helm-controller + + # As long as the following command shows STATUS Running you're good to move on + kubectl get pods --namespace=flux-system + ``` + + ```console + NAME READY STATUS RESTARTS AGE + helm-controller-746d586c6-ln7dl 1/1 Running 0 3m8s + notification-controller-f6658d796-fdzjx 1/1 Running 0 3m8s + kustomize-controller-5887bb8dd7-jzp7m 1/1 Running 0 3m8s + source-controller-7c4564d74c-7ffrf 1/1 Running 0 3m8s + ``` + +## Step 9: Create Helm Values .yaml Files To Act as Input Variables for the Big Bang Helm Chart + +> Note for those new to linux: The following are multi line copy pasteable commands to quickly generate config files from the CLI, make sure you copy from cat to EOF, if you get stuck in the terminal use ctrl + c + +```shell +# [ubuntu@Ubuntu_VM:~] +cat << EOF > ~/ib_creds.yaml +registryCredentials: + registry: registry1.dso.mil + username: "$REGISTRY1_USERNAME" + password: "$REGISTRY1_PASSWORD" +EOF + + +cat << EOF > ~/demo_values.yaml +elasticsearchKibana: + values: + kibana: + count: 1 + resources: + requests: + cpu: 400m + memory: 1Gi + limits: + cpu: null # nonexistent cpu limit results in faster spin up + memory: null + elasticsearch: + master: + count: 1 + resources: + requests: + cpu: 400m + memory: 2Gi + limits: + cpu: null + memory: null + data: + count: 1 + resources: + requests: + cpu: 400m + memory: 2Gi + limits: + cpu: null + memory: null + +clusterAuditor: + values: + resources: + requests: + cpu: 400m + memory: 2Gi + limits: + cpu: null + memory: null + +gatekeeper: + enabled: false + values: + replicas: 1 + controllerManager: + resources: + requests: + cpu: 100m + memory: 512Mi + limits: + cpu: null + memory: null + audit: + resources: + requests: + cpu: 400m + memory: 768Mi + limits: + cpu: null + memory: null + violations: + allowedDockerRegistries: + enforcementAction: dryrun + +istio: + values: + values: # possible values found here https://istio.io/v1.5/docs/reference/config/installation-options (ignore 1.5, latest docs point here) + global: # global istio operator values + proxy: # mutating webhook injected istio sidecar proxy's values + resources: + requests: + cpu: 0m # null get ignored if used here + memory: 0Mi + limits: + cpu: 0m + memory: 0Mi + +twistlock: + enabled: false # twistlock requires a license to work, so we're disabling it + +# to set all Kyverno policies to audit only +kyvernoPolicies: + enabled: true + values: + validationFailureAction: "audit" + +# under Neuvector section +neuvector: + enabled: true + values: + k3s: + enabled: true +EOF +``` + +## Step 10: Install Big Bang Using the Local Development Workflow + +```shell +# [ubuntu@Ubuntu_VM:~] +helm upgrade --install bigbang $HOME/bigbang/chart \ + --values https://repo1.dso.mil/big-bang/bigbang/-/raw/master/chart/ingress-certs.yaml \ + --values $HOME/ib_creds.yaml \ + --values $HOME/demo_values.yaml \ + --namespace=bigbang --create-namespace +``` + +Explanation of flags used in the imperative helm install command: + +`upgrade --install`: +This makes the command more idempotent by allowing the exact same command to work for both the initial installation and upgrade use cases. + +`bigbang $HOME/bigbang/chart`: +bigbang is the name of the helm release that you'd see if you run `helm list -n=bigbang`. `$HOME/bigbang/chart` is a reference to the helm chart being installed. + +`--values https://repo1.dso.mil/big-bang/bigbang/-/raw/master/chart/ingress-certs.yaml`: +References demonstration HTTPS certificates embedded in the public repository. The *.bigbang.dev wildcard certificate is signed by Let's Encrypt, a free public internet Certificate Authority. Note the URL path to the copy of the cert on master branch is used instead of `$HOME/bigbang/chart/ingress-certs.yaml`, because the Let's Encrypt certs expire after 3 months, and if you deploy a tagged release of BigBang, like 1.15.0, the version of the cert stored in the tagged git commit/release of Big Bang could be expired. Referencing the master branches copy via URL ensures you receive the latest version of the cert, which won't be expired. + +`--namespace=bigbang --create-namespace`: +Means it will install the bigbang helm chart in the bigbang namespace and create the namespace if it doesn't exist. + +## Step 11: Verify Big Bang Has Had Enough Time To Finish Installing + +* If you try to run the command in Step 11 too soon, you'll see an ignorable temporary error message. + + ```shell + # [ubuntu@Ubuntu_VM:~] + kubectl get virtualservices --all-namespaces + + # Note after running the above command, you may see an ignorable temporary error message + # The error message may be different based on your timing, but could look like this: + # error: the server doesn't have a resource type "virtualservices" + # or + # No resources found + + # The above errors could be seen if you run the command too early + # Give Big Bang some time to finish installing, then run the following command to check it's status + + kubectl get po -A + ``` + +* If after running `kubectl get po -A` (which is the shorthand of `kubectl get pods --all-namespaces`) you see something like the following, then you need to wait longer. + + ```console + NAMESPACE NAME READY STATUS RESTARTS AGE + kube-system metrics-server-86cbb8457f-dqsl5 1/1 Running 0 39m + kube-system coredns-7448499f4d-ct895 1/1 Running 0 39m + flux-system notification-controller-65dffcb7-qpgj5 1/1 Running 0 32m + flux-system kustomize-controller-d689c6688-6dd5n 1/1 Running 0 32m + flux-system source-controller-5fdb69cc66-s9pvw 1/1 Running 0 32m + kube-system local-path-provisioner-5ff76fc89d-gnvp4 1/1 Running 1 39m + flux-system helm-controller-6c67b58f78-6dzqw 1/1 Running 0 32m + gatekeeper-system gatekeeper-controller-manager-5cf7696bcf-xclc4 0/1 Running 0 4m6s + gatekeeper-system gatekeeper-audit-79695c56b8-qgfbl 0/1 Running 0 4m6s + istio-operator istio-operator-5f6cfb6d5b-hx7bs 1/1 Running 0 4m8s + eck-operator elastic-operator-0 1/1 Running 1 4m10s + istio-system istiod-65798dff85-9rx4z 1/1 Running 0 87s + istio-system public-ingressgateway-6cc4dbcd65-fp9hv 0/1 ContainerCreating 0 46s + logging logging-fluent-bit-dbkxx 0/2 Init:0/1 0 44s + monitoring monitoring-monitoring-kube-admission-create-q5j2x 0/1 ContainerCreating 0 42s + logging logging-ek-kb-564d7779d5-qjdxp 0/2 Init:0/2 0 41s + logging logging-ek-es-data-0 0/2 Init:0/2 0 44s + istio-system svclb-public-ingressgateway-ggkvx 5/5 Running 0 39s + logging logging-ek-es-master-0 0/2 Init:0/2 0 37s + ``` + +* Wait up to 10 minutes then re-run `kubectl get po -A`, until all pods show STATUS Running. + +* `helm list -n=bigbang` should also show STATUS deployed + + ```console + NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION + bigbang bigbang 1 2022-03-31 12:07:49.239343968 +0000 UTC deployed bigbang-1.30.1 + cluster-auditor-cluster-auditor cluster-auditor 1 2022-03-31 12:14:23.004377605 +0000 UTC deployed cluster-auditor-1.4.0-bb.0 0.0.4 + eck-operator-eck-operator eck-operator 1 2022-03-31 12:09:52.921098159 +0000 UTC deployed eck-operator-2.0.0-bb.0 2.0.0 + gatekeeper-system-gatekeeper gatekeeper-system 1 2022-03-31 12:07:53.52890717 +0000 UTC deployed gatekeeper-3.7.1-bb.0 v3.7.1 + istio-operator-istio-operator istio-operator 1 2022-03-31 12:07:55.111321595 +0000 UTC deployed istio-operator-1.13.2-bb.1 1.13.2 + istio-system-istio istio-system 1 2022-03-31 12:08:23.439981427 +0000 UTC deployed istio-1.13.2-bb.0 1.13.2 + jaeger-jaeger jaeger 1 2022-03-31 12:12:58.068313509 +0000 UTC deployed jaeger-operator-2.29.0-bb.0 1.32.0 + kiali-kiali kiali 1 2022-03-31 12:12:57.011215896 +0000 UTC deployed kiali-operator-1.47.0-bb.1 1.47.0 + logging-ek logging 1 2022-03-31 12:10:52.785810021 +0000 UTC deployed logging-0.7.0-bb.0 7.17.1 + logging-fluent-bit logging 1 2022-03-31 12:12:53.27612266 +0000 UTC deployed fluent-bit-0.19.20-bb.1 1.8.13 + monitoring-monitoring monitoring 1 2022-03-31 12:10:02.31254196 +0000 UTC deployed kube-prometheus-stack-33.2.0-bb.0 0.54.1 + ``` + +## Step 12: Edit Your Workstation’s Hosts File To Access the Web Pages Hosted on the Big Bang Cluster + +Run the following command, which is the short hand equivalent of `kubectl get virtualservices --all-namespaces` to see a list of websites you'll need to add to your hosts file. + +```shell +kubectl get vs -A +``` + +```console +NAMESPACE NAME GATEWAYS HOSTS AGE +logging kibana ["istio-system/public"] ["kibana.bigbang.dev"] 10m +monitoring monitoring-monitoring-kube-alertmanager ["istio-system/public"] ["alertmanager.bigbang.dev"] 10m +monitoring monitoring-monitoring-kube-grafana ["istio-system/public"] ["grafana.bigbang.dev"] 10m +monitoring monitoring-monitoring-kube-prometheus ["istio-system/public"] ["prometheus.bigbang.dev"] 10m +kiali kiali ["istio-system/public"] ["kiali.bigbang.dev"] 8m21s +jaeger jaeger ["istio-system/public"] ["tracing.bigbang.dev"] 7m46s +``` + +### Linux/Mac Users + +```shell +# [admin@Laptop:~] +sudo vi /etc/hosts +``` + +### Windows Users + +1. Right click Notepad -> Run as Administrator +1. Open C:\Windows\System32\drivers\etc\hosts + +### Linux/Mac/Windows Users + +Add the following entries to the Hosts file, where x.x.x.x = k3d virtual machine's IP. + +> Hint: find and replace is your friend + +```plaintext +x.x.x.x kibana.bigbang.dev +x.x.x.x alertmanager.bigbang.dev +x.x.x.x grafana.bigbang.dev +x.x.x.x prometheus.bigbang.dev +x.x.x.x kiali.bigbang.dev +x.x.x.x tracing.bigbang.dev +x.x.x.x argocd.bigbang.dev +``` + +## Step 13: Visit a Webpage + +In a browser, visit one of the sites listed using the `kubectl get vs -A` command. + +Note, default credentials for Big Bang packages can be found [here](../using-bigbang/default-credentials.md). + +## Step 14: Play + +Here's an example of post deployment customization of Big Bang. +After looking at <https://repo1.dso.mil/big-bang/bigbang/-/blob/master/chart/values.yaml> +It should make sense that the following is a valid edit. + +```shell +# [ubuntu@Ubuntu_VM:~] + +cat << EOF > ~/tinkering.yaml +addons: + argocd: + enabled: true +EOF + +helm upgrade --install bigbang $HOME/bigbang/chart \ +--values https://repo1.dso.mil/big-bang/bigbang/-/raw/master/chart/ingress-certs.yaml \ +--values $HOME/ib_creds.yaml \ +--values $HOME/demo_values.yaml \ +--values $HOME/tinkering.yaml \ +--namespace=bigbang --create-namespace + +# NOTE: There may be a ~1 minute delay for the change to apply + +kubectl get vs -A +# Now ArgoCD should show up, if it doesn't wait a minute and rerun the command + +kubectl get po -n=argocd +# Once these are all Running you can visit argocd's webpage +``` + +> Remember to un-edit your Hosts file when you are finished tinkering. + +## Step 15: Implementing Mission Applications within your bigbang environment + +Big Bang by itself serves as a jumping off point, but many users will want to implement their own mission specific applications in to the cluster. BigBang has implemented a `packages:` and `wrapper:` section to enable and support this in a way that ensures connectivity between your mission specific requirements and existing BigBang utilities, such as istio, the monitoring stack, and network policy management. [Here](https://repo1.dso.mil/big-bang/bigbang/-/blob/master/docs/guides/deployment-scenarios/extra-package-deployment.md) is the documentation for the `packages` utility. + +We will implement a simple additional utility as a proof of concept, starting with a basic podinfo client. This will use the `wrapper` key to provide integration between bigbang and the Mission Application, without requiring the full Istio configuration to be placed inside BigBang specific keys of the dependent chart. + + +```shell +cat << EOF > ~/podinfo_wrapper.yaml +packages: + # -- Package name. Each package will be independently wrapped for Big Bang integration. + # @default -- Uses `defaults/<package name>.yaml` for defaults. See `package` Helm chart for additional values that can be set. + podinfo: + # -- Toggle deployment of this package + # @default -- true + enabled: true + + # -- Toggle wrapper functionality. See https://docs-bigbang.dso.mil/latest/docs/guides/deployment-scenarios/extra-package-deployment/#Wrapper-Deployment for more details. + # @default -- false + wrapper: + enabled: true + + # -- Use a kustomize deployment rather than Helm + kustomize: false + + # -- HelmRepo source is supported as an option for Helm deployments. If both `git` and `helmRepo` are provided `git` will take precedence. + helmRepo: + # -- Name of the HelmRepo specified in `helmRepositories` + # @default -- Uses `registry1` Helm Repository if not specified + repoName: + # -- Name of the chart stored in the Helm repository + # @default -- Uses values key/package name if not specified + chartName: + # -- Tag of the chart in the Helm repo, required + tag: + + # -- Git source is supported for both Helm and Kustomize deployments. If both `git` and `helmRepo` are provided `git` will take precedence. + git: + # -- Git repo URL holding the helm chart for this package, required if using git + repo: "https://repo1.dso.mil/big-bang/product/packages/podinfo.git" + # -- Git commit to check out. Takes precedence over semver, tag, and branch. [More info](https://fluxcd.io/flux/components/source/gitrepositories/#reference) + commit: + # -- Git semVer tag expression to check out. Takes precedence over tag. [More info](https://fluxcd.io/flux/components/source/gitrepositories/#reference) + semver: + # -- Git tag to check out. Takes precedence over branch. [More info](https://fluxcd.io/flux/components/source/gitrepositories/#reference) + tag: "6.0.0-bb.7" + # -- Git branch to check out. [More info](https://fluxcd.io/flux/components/source/gitrepositories/#reference). + # @default -- When no other reference is specified, `master` branch is used + branch: + # -- Path inside of the git repo to find the helm chart or kustomize + # @default -- For Helm charts `chart`. For Kustomize `/`. + path: "chart" + + # -- Override flux settings for this package + flux: {} + + # -- After deployment, patch resources. [More info](https://fluxcd.io/flux/components/helm/helmreleases/#post-renderers) + postRenderers: [] + + # -- Specify dependencies for the package. Only used for HelmRelease, does not effect Kustomization. See [here](https://fluxcd.io/flux/components/helm/helmreleases/#helmrelease-dependencies) for a reference. + dependsOn: [] + + # -- Package details for Istio. See [wrapper values](https://repo1.dso.mil/big-bang/apps/wrapper/-/blob/main/chart/values.yaml) for settings. + istio: + hosts: + - names: + - missionapp + gateways: + - public + destination: + service: missionapp-missionapp + port: 9898 + + # -- Package details for monitoring. See [wrapper values](https://repo1.dso.mil/big-bang/apps/wrapper/-/blob/main/chart/values.yaml) for settings. + monitor: {} + + # -- Package details for network policies. See [wrapper values](https://repo1.dso.mil/big-bang/apps/wrapper/-/blob/main/chart/values.yaml) for settings. + network: {} + + # -- Secrets that should be created prior to package installation. See [wrapper values](https://repo1.dso.mil/big-bang/apps/wrapper/-/blob/main/chart/values.yaml) for settings. + secrets: {} + + # -- ConfigMaps that should be created prior to package installation. See [wrapper values](https://repo1.dso.mil/big-bang/apps/wrapper/-/blob/main/chart/values.yaml) for settings. + configMaps: {} + + # -- Values to pass through to package Helm chart + values: + istio: + enabled: "{{ .Values.istio.enabled }}" + ui: + color: "#fcba03" #yellow + +EOF + +helm upgrade --install bigbang $HOME/bigbang/chart \ +--values https://repo1.dso.mil/big-bang/bigbang/-/raw/master/chart/ingress-certs.yaml \ +--values $HOME/ib_creds.yaml \ +--values $HOME/demo_values.yaml \ +--values $HOME/podinfo_wrapper.yaml \ +--namespace=bigbang --create-namespace + +# NOTE: There may be a ~1 minute delay for the change to apply + +kubectl get vs -A +# Now missionapp should show up, if it doesn't wait a minute and rerun the command + +kubectl get po -n=missionapp +# Once these are all Running you can visit missionapp's webpage +``` + +Wrappers also allow you to abstract out Monitoring, Secrets, Network Policies, and ConfigMaps. Additional Configuration information can be found [here](./extra-package-deployment.md) + +## Troubleshooting +This section will provide guidance for troubleshooting problems that may occur during your Big Bang installation and instructions for additional configuration changes that may be required in restricted networks. + +### Changing CoreDNS upstream DNS server: +After completing step 5, if you are unable to connect to external DNS providers using the command `nslookup google.com 8.8.8.8`, to test the connection. Then use the steps below to change the upstream DNS server to your networks DNS server. Please note that this change will not perist after a restart of the host server therefore, if you restart or shutdown your server you will need to re-apply these changes to CoreDNS. + +1. Open config editor to change the CoreDNS pod configuration. + + ```shell + kubectl -n kube-system edit configmaps CoreDNS -o yaml + ``` + +1. Change: + + ```plaintext + forward . /etc/resolv.conf + ``` + + To: + + ```plaintext + forward . <DNS Server IP> + ``` + +1. Save changes in editor (for vi use `:wq`). + +1. Verify changes in terminal output that prints new config + +### Useful Commands for Obtaining Detailed Logs from Kubernetes Cluster or Containers + +* Print all pods including information related to the status of each pod. + ```shell + kubectl get pods --all-namespaces + ``` +* Print logs for specified pod. + ```shell + kubectl logs <pod name> -n=<namespace of pod> + ``` +* Print a dump of relevent information for debugging and diagnosing your kubernetes cluster. + ```shell + kubectl cluster-info dump + ``` + +### Documentation References for Command Line Tools Used + +* Kubectl - https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands +* k3d - https://k3d.io/v5.5.1/usage/k3s/ +* Docker - https://docs.docker.com/desktop/linux/troubleshoot/#diagnosing-from-the-terminal +* Helm - https://helm.sh/docs/helm/helm/ + +### NeuVector "Failed to Get Container" + +If the NeuVector pods come online but give errors like: + +```shell +ERRO|AGT|container.(*containerdDriver).GetContainer: Failed to get container - error=container "4d9a6e20883271ed9f921e86c7816549e9731fbd74cefa987025f27b4ad59fa1" in namespace "k8s.io │ +ERRO|AGT|main.main: Failed to get local device information - error=container "4d9a6e20883271ed9f921e86c7816549e9731fbd74cefa987025f27b4ad59fa1" in namespace "k8s.io": not found +``` + +It could be because Ubuntu prior to 21 ships with cgroup v1 by default, and NeuVector on cgroup v1 with containerd doesn't work well. To check if your installation is running cgroup v1, run: + +```shell +cat /sys/fs/cgroup/cgroup.controllers +``` + +If you get a "No such file or directory", that means its running v1, and needs to be running v2. Follow the documentation here - https://rootlesscontaine.rs/getting-started/common/cgroup2/#checking-whether-cgroup-v2-is-already-enabled to enable v2 + +### "Too Many Open Files" + +If the NeuVector pods fail to open, and you look at the K8s logs only to find that it's giving the "too many open files" error, you'll need to increase your inotify max's. Consider grabbing your current fs.inotify.max values and increasing them like the following + +```shell +sudo sysctl fs.inotify.max_queued_events=616384 +sudo sysctl fs.inotify.max_user_instances=512 +sudo sysctl fs.inotify.max_user_watches=501208 +``` +### Failed to provide IP to istio-system/public-ingressgateway + +As one option to provide IP to the istio-system/public-ingressgateway, metallb can be run. The following steps will demonstrate a standard configuration, however, some changes may need to be made for each individual system (e.g., specific /ets/hosts addresses). + +#### Step 1: K3d Deploy + +To facilitate metallb, servicelb needs to be disabled on the initial install. Replace the above k3d deploy command with the following: +```shell +k3d cluster create \ + --k3s-arg "--tls-san=$SERVER_IP@server:0" \ + --volume /etc/machine-id:/etc/machine-id \ + --volume ${IMAGE_CACHE}:/var/lib/rancher/k3s/agent/containerd/io.containerd.content.v1.content \ + --k3s-arg "--disable=traefik@server:0" \ + --k3s-arg "--disable=servicelb@server:0" \ + --port 80:80@loadbalancer \ + --port 443:443@loadbalancer \ + --api-port 6443 +``` + +#### Step 2: Deploy MetalLB + +After following the above instructions to deploy flux, deploy the metallb controller and speaker. +```shell +kubectl create -f https://raw.githubusercontent.com/metallb/metallb/v0.13.9/config/manifests/metallb-native.yaml +``` +Wait for the pods to be running: +```shell +kubectl get po -n metallb-system +``` + +```console +NAME READY STATUS RESTARTS AGE +controller-5684477f66-s99jg 1/1 Running 0 30s +speaker-jrddv 1/1 Running 0 30s +``` + +#### Step 3: Configure MetalLB + +**NOTE:** This step will not work if either the controller or speaker are not in a running condition. + +The following configuration addresses will need to be filled with the values that match your configuration. These can typically be found by looking at your docker subnet using the 'docker network ls' command. If there is no subnet currently configured you can use the following as an example to set up your subnet. 'docker network create --opt com.docker.network.bridge.name=$NETWORK_NAME $NETWORK_NAME --driver=bridge -o "com.docker.network.driver.mtu"="1450" --subnet=172.x.x.x/16 --gateway 172.x.x.x'. Be sure to replace the network name, subnet and gateway values as needed. + +```shell +export SUBNET_RANGE=172.x.x.x-172.x.x.x +cat << EOF > ~/metallb-config.yaml +apiVersion: metallb.io/v1beta1 +kind: IPAddressPool +metadata: + name: default + namespace: metallb-system +spec: + addresses: + - $SUBNET_RANGE +--- +apiVersion: metallb.io/v1beta1 +kind: L2Advertisement +metadata: + name: l2advertisement1 + namespace: metallb-system +spec: + ipAddressPools: + - default +EOF + +kubectl create -f $HOME/metallb-config.yaml +``` +#### Step 4: Configure /etc/hosts + +Lastly, configure /etc/hosts/ with the new IP Addresses (**NOTE:** you can add your own as needed for services). You will need to fill in the values used for the subnet. + +```shell + export PASSTHROUGH_GATEWAY_IP=172.x.x.x + export PUBLIC_GATEWAY_IP=172.x.x.x + sudo sed -i '/bigbang.dev/d' /etc/hosts + sudo bash -c "echo '## begin bigbang.dev section (METAL_LB)' >> /etc/hosts" + sudo bash -c "echo $PASSTHROUGH_GATEWAY_IP keycloak.bigbang.dev vault.bigbang.dev >> /etc/hosts" + sudo bash -c "echo $PUBLIC_GATEWAY_IP anchore-api.bigbang.dev anchore.bigbang.dev argocd.bigbang.dev gitlab.bigbang.dev registry.bigbang.dev tracing.bigbang.dev kiali.bigbang.dev kibana.bigbang.dev chat.bigbang.dev minio.bigbang.dev minio-api.bigbang.dev alertmanager.bigbang.dev grafana.bigbang.dev prometheus.bigbang.dev nexus.bigbang.dev sonarqube.bigbang.dev tempo.bigbang.dev twistlock.bigbang.dev >> /etc/hosts" + sudo bash -c "echo '## end bigbang.dev section' >> /etc/hosts" + # run kubectl to add keycloak and vault's hostname/IP to the configmap for coredns, restart coredns + kubectl get configmap -n kube-system coredns -o yaml | sed '/^ $PASSTHROUGH_GATEWAY_IP host.k3d.internal$/a\ \ \ \ $PASSTHROUGH_GATEWAY_IP keycloak.bigbang.dev vault.bigbang.dev' | kubectl apply -f - + kubectl delete pod -n kube-system -l k8s-app=kube-dns +``` + +From this point continue with the helm upgrade command above. + +### WSL2 + +This section will provide guidance for troubleshooting problems that may occur during your Big Bang installation specifically involving WSL2. + +#### NeuVector "Failed to Get Container" + +In you receive a similar error to the above "Failed to get container" with NeuVector it could be because of the cgroup configurations in WSL2. WSL2 often tries to run both cgroup and cgroup v2 in a unified manner which can confuse docker and affect deployments. To remedy this you need to create a .wslconfig file in the C:\Users\<UserName>\ directory. In this file you need to add the following: + +```shell +[wsl2] +kernelCommandLine = cgroup_no_v1=all +``` + +Once created you need to restart wsl2. + +If this doesn't remedy the issue and the cgroup.controllers file is still located in the /sys/fs/cgroup/unified directory you may have to modify /etc/fstab and add the following: + +```shell +cgroup2 /sys/fs/cgroup cgroup2 rw,nosuid,nodev,noexec,relatime,nsdelegate 0 0 +``` + +#### Container Fails to Start: "Not Enough Memory" + +Wsl2 limits the amount of memory available to half of what your computer has. If you have 32g or less (16g or less available) this is often not enough to run all of the standard big bang services. If you have more available memory you can modify the initial limit by modifying (or creating) the C:\Users\<UserName>\.wslconfig file by adding: + +```shell +[wsl2] +memory=24GB +``` diff --git a/docs/guides/deployment-scenarios/sso-quickstart-resources/sso-quickstart-deprecated.md b/docs/guides/deployment-scenarios/sso-quickstart-resources/sso-quickstart-deprecated.md new file mode 100644 index 0000000000000000000000000000000000000000..622f26dffaddc2e3e17730197071221753283441 --- /dev/null +++ b/docs/guides/deployment-scenarios/sso-quickstart-resources/sso-quickstart-deprecated.md @@ -0,0 +1,4 @@ +# Auth Service and Keycloak SSO Quick Start Demo + +[[_TOC_]] + diff --git a/docs/guides/deployment-scenarios/sso-quickstart.md b/docs/guides/deployment-scenarios/sso-quickstart.md new file mode 100644 index 0000000000000000000000000000000000000000..93cd231f1a698e7bb5d679cff826d466a20859ef --- /dev/null +++ b/docs/guides/deployment-scenarios/sso-quickstart.md @@ -0,0 +1,3 @@ +# Enabling SSO for Big Bang with Keycloak and Authservice + +If you would like to protect your applications in Big Bang with Single Sign On (SSO) authentication, this can be accomplished using Keycloak with the Authservice plugin enabled. To learn more about it, see [Big Bang Docs / Developer / Package Integration / SSO](https://docs-bigbang.dso.mil/latest/docs/developer/package-integration/sso/). \ No newline at end of file diff --git a/docs/guides/renovate/deployment.md b/docs/guides/renovate/deployment.md new file mode 100644 index 0000000000000000000000000000000000000000..4fa32e1476de8faf30c3b6f5540a7c32c3ddbe8f --- /dev/null +++ b/docs/guides/renovate/deployment.md @@ -0,0 +1,48 @@ +### Deployment of Renovate + +Follow the [Extra Package Deployment Guide](../deployment-scenarios/extra-package-deployment.md) + +#### Example Deployment Values +``` yaml +packages: + renovate: + enabled: true + git: + repo: https://repo1.dso.mil/big-bang/product/packages/renovate.git + tag: 32.38.0-bb.1 + values: + networkPolicies: + enabled: "{{ $.Values.networkPolicies.enabled }}" + istio: + enabled: "{{ $.Values.istio.enabled }}" + cronjob: + schedule: '0 1 * * *' + renovate: + config: | + { + "platform": "gitlab", + "endpoint": "https://gitlab.example.com/api/v4", + "token": "your-gitlab-renovate-user-token", + "autodiscover": "false", + "dryRun": true, + "printConfig": true, + "repositories": ["username/repo", "orgname/repo"] + } +``` + +#### Config +The configuration sets up a self-hosted instance of Renovate that connects with a platform. In the example, we connect to GitLab using the GitLab API v4 at a specified URL. + +##### Auth +It is recommended to use a repository-scoped auth token with developer access for least privilege. + +##### Repositories +The repositories key in this self-hosted renovate configuration specifies which repositories should be included in the update checks performed by renovate Accepts an array of strings or objects. + +See [Self Hosted Configuration](https://docs.renovatebot.com/self-hosted-configuration/#self-hosted-configuration-options) for more details + +#### Cron Job +Refer to the [Scheduling Renovate Guide](./scheduling.md). + +#### Individual Package Configuration +The configuration file for Renovate is called `renovate.json` and is located in each project's root directory. See [Package Configuration](./package-configuration.md) diff --git a/docs/guides/renovate/package-configuration.md b/docs/guides/renovate/package-configuration.md new file mode 100644 index 0000000000000000000000000000000000000000..3d3f53c47457e23af5fa6b8c9972f53937eaf363 --- /dev/null +++ b/docs/guides/renovate/package-configuration.md @@ -0,0 +1,170 @@ +# Renovate Configuration for Big Bang Customer Template + +## Package Configuration + +### Example Package Configuration + +> The following example is for a user fork of the [customer template](https://repo1.dso.mil/big-bang/customers/template). + +The first ten lines set up the basics of what a Renovate ticket is expected to look like when created. Package Rules is set up to use git-tags. Regex Managers are detailed below. +```json +{ + "baseBranches": ["main"], + "configWarningReuseIssue": false, + "dependencyDashboard": true, + "dependencyDashboardHeader": "- [ ] Review Big Bang changelog/release notes.", + "dependencyDashboardTitle": "Renovate: Upgrade Big Bang", + "draftPR": true, + "enabledManagers": ["regex"], + "labels": ["renovate"], + "commitMessagePrefix": "", + "separateMajorMinor": false, + "packageRules": [ + { + "groupName": "Big Bang", + "matchDatasources": ["git-tags"] + } + ], + "regexManagers": [ + { + "fileMatch": ["^base/kustomization\\.yaml$"], + "matchStrings": [ + ".+?ref=+(?<currentValue>.+)" + ], + "depNameTemplate": "https://repo1.dso.mil/big-bang/bigbang.git", + "datasourceTemplate": "git-tags", + "versioningTemplate": "regex:^(?<major>\\d+)\\.(?<minor>\\d+)\\.(?<patch>\\d+)$" + }, + { + "fileMatch": ["^dev/kustomization\\.yaml$"], + "matchStrings": [ + "tag:\\s+\"(?<currentValue>.+)\"" + ], + "depNameTemplate": "https://repo1.dso.mil/big-bang/bigbang.git", + "datasourceTemplate": "git-tags", + "versioningTemplate": "regex:^(?<major>\\d+)\\.(?<minor>\\d+)\\.(?<patch>\\d+)$" + }, + { + "fileMatch": ["^dev/configmap\\.yaml$"], + "matchStrings": [ + "git:\\s+repo:\\s+(?<depName>.+)\\s+tag:\\s+\"(?<currentValue>.+)\"" + ], + "datasourceTemplate": "git-tags", + "versioningTemplate": "regex:^(?<major>\\d+)\\.(?<minor>\\d+)\\.(?<patch>\\d+)-bb\\.(?<build>\\d+)$" + } + ], +} +``` + +#### RegEx Managers +This is where regex-based rules for updating dependencies are defined. This is where the majority of the work is done for Renovate. + +In this example, the version of Big Bang tracked by the base/kustomization.yaml is the target of renovate. +The regex targets `- git::https://repo1.dso.mil/big-bang/bigbang.git//base?ref=1.41.0` setting `1.41.0` as a capture group. + +```json + { + "fileMatch": ["^base/kustomization\\.yaml$"], + "matchStrings": [ + ".+?ref=+(?<currentValue>.+)" + ], + "depNameTemplate": "https://repo1.dso.mil/big-bang/bigbang.git", + "datasourceTemplate": "git-tags", + "versioningTemplate": "regex:^(?<major>\\d+)\\.(?<minor>\\d+)\\.(?<patch>\\d+)$" + } +``` +> The same concept can be applied to dev/kustomization.yaml or the kustomization for any folder for a specific environment. + + +Targeting packages requires a more complex regex statement. In this example, we are asking renovate to update the version number of `git.tag` where `git.repository` matches the `depName` + +```json + { + "fileMatch": ["^dev/configmap\\.yaml$"], + "matchStrings": [ + "git:\\s+repo:\\s+(?<depName>.+)\\s+tag:\\s+\"(?<currentValue>.+)\"" + ], + "depNameTemplate": "https://repo1.dso.mil/big-bang/product/packages/kyverno.git", + "datasourceTemplate": "git-tags", + "versioningTemplate": "regex:^(?<major>\\d+)\\.(?<minor>\\d+)\\.(?<patch>\\d+)-bb\\.(?<build>\\d+)$" + } +``` + +```yaml +kyverno: + git: + repo: https://repo1.dso.mil/big-bang/product/packages/kyverno.git + tag: "2.6.5-bb.2" + values: + replicaCount: 1 +``` +## Package Configuration Options +The options that are commonly used to configure the options of Renovate include the following: regexManagers, Dashboard options, and packageRules. + +### regexManagers +Several `regexManagers` are defined in the package configuration example, each with a specific `fileMatch` path and `matchStrings` regex. It can accept an array of objects. Provided below are several of the common properties of those objects. + +#### File Match + +The `fileMatch` array is a list of files that you want to parse. It uses a regular expression match on the files starting in the repository base directory. For example `["^chart/values\\.yaml$"]` will match the `chart/values.yaml` file. + +#### Match Strings + +`matchString` is used to identify the current version, data source type, dependency name or current digest in a file. You must use special capture groups in regex to identify these items, or create a template for Renovate to understand. The following are required to be captured: + +- `<currentValue>`: This is the current version or tag of the dependency (e.g. v1.2.3). +- `<datasource>`: This is the type of the dependency. For Big Bang packages you will want to use `git-tags`. +- `<depName>`: This is the name of the dependency and is uses as the repository for the dependency when looking it up in the registry. + +You can optionally capture `<currentDigest>` as the SHA256 digest for an image if you want renovate to replace this value. + +To capture a group, you simply use [regex named groups](https://www.regular-expressions.info/refext.html). + +See [Renovate Configuration](https://docs.renovatebot.com/configuration-options/#regexmanagers) for more details. + +### Dashboard Options + +#### dependencyDashboard +When the dependencyDashboard is enabled, Renovate will create a new issue in the configured repository. This issue acts as a "dashboard" where you can get an overview of the status of all updates. It can accept a boolean value. + +#### dependencyDashboardHeader +This key sets a header for the dependencyDashboard which lists tasks to be completed by the user in the form of the issue description on Gitlab. The header will appear at the top of the dependencyDashboard. In the given example, the header contains a checklist for reviewing the BB release notes/changelog. It can accept a string. + +#### dependencyDashboardTitle +This key is used to set the title for the dependencyDashboard. In the example, it is set as "Renovate: Upgrade Big Bang". It can accept a string. + +> Refer to [Renovate Configuration](https://docs.renovatebot.com/configuration-options/#dependencydashboard) for more information. + +### packageRules +This key provides an array of rules that define how packages are matched and grouped. In the example, any matching package with the datasource `git-tags` will be grouped under the name `Big Bang`. It can accept an array of objects see [Renovate packageRules Docs](https://docs.renovatebot.com/configuration-options/#packagerules) for more info. + +## Additional Package Configuration Options + +### baseBranches +This key is used to specify the base branches for Renovate to compare against. It can accept an array of strings. In the example yaml, Renovate will compare against the `main` branch. + +### configWarningReuseIssue +This key specifies whether to reuse an existing pull request for updates, and whether to warn if an existing pull request cannot be re-used. It can accept a boolean value. + +### draftPR +This key specifies whether the generated pull requests should be marked as drafts. It can accept a boolean value. + +### enabledManagers +This key specifies which dependency managers to enable. In the example, Renovate will use `regex`. It can accept an array of strings. + +### ignorePaths +This key lists the file paths for Renovate to ignore when checking dependencies. It can accept an array of strings. + +### labels +This key assigns labels to the created pull requests. In the example a `renovate` label is applied. It can accept an array of strings. + +### commitMessagePrefix +This key sets a prefix that will be added to commit messages. It can accept a string. + +### separateMajorMinor +This key specifies whether to separate major/minor updates into separate pull requests. It can accept a boolean value. + +### ignoreDeps +The configuration field allows you to define a list of dependency names to be ignored by Renovate. Currently, it supports only "exact match" dependency names and not any patterns. It can accept an array of strings. + +In conclusion, the `renovate.json` file allows us to configure the Renovate bot to keep our Helm chart repository up-to-date with the latest dependencies, by using various settings to suit our needs. diff --git a/docs/guides/renovate/scheduling.md b/docs/guides/renovate/scheduling.md new file mode 100644 index 0000000000000000000000000000000000000000..06946ebee6bf623ed9eb05fe0bd25c20e75db734 --- /dev/null +++ b/docs/guides/renovate/scheduling.md @@ -0,0 +1,74 @@ +## Handling Scheduling in the Chart + +To handle scheduling in the chart for a Renovate configuration, you can use a Kubernetes CronJob object, which allows you to schedule jobs to run at specific intervals. To configure the scheduling, you will need to modify the schedule field in the cronjob section of the values.yaml file. + +The schedule option allows you to define times of week or month for Renovate updates. Running Renovate around the clock can be too "noisy" for some projects. To reduce the noise, you can use the schedule config option to limit the time frame in which Renovate will perform actions on your repository. You can use the standard Cron syntax and Later syntax to define your schedule. + +The default value for schedule is `0 1 * * *` for at `01:00 everyday`. + +The easiest way to define a schedule is to use a preset if one of them fits your requirements. Refer to the schedule presets for details and feel free to request a new one in the source repository if you think others would also benefit from it. + +### Additional Examples + +Otherwise, here are some text schedules that are known to work: +``` +every weekend +before 5:00am +after 10pm and before 5:00am +after 10pm and before 5am every weekday +on friday and saturday +every 3 months on the first day of the month +* 0 2 * * +``` +##### Cron Syntax +```R +* * * * * +- - - - - +| | | | | +| | | | +----- day of the week (0 - 6) (Sunday=0) +| | | +---------- month (1 - 12) +| | +--------------- day of the month (1 - 31) +| +-------------------- hour (0 - 23) ++------------------------- minute (0 - 59) +``` + +> For example, to run the Renovate job every day at 1:00 AM, you would set the schedule field to `0 1 * * *`. + +### Other Options + +You can also configure other options in the CronJob section, including: suspend to temporarily disable the job, concurrencyPolicy to control how multiple instances of the job are run, and startingDeadlineSeconds to specify the maximum amount of time to wait for a job to start before considering it failed. + +* `suspend`: If set to `true`, the job will be suspended and will not be executed. +* `concurrencyPolicy`: This determines how the job handles concurrent executions. Valid values are `Allow`, `Forbid`, and `Replace`. +* `failedJobsHistoryLimit`: This defines the number of failed jobs that will be kept in history. +* `successfulJobsHistoryLimit`: This defines the number of successful jobs that will be kept in history. +* `jobRestartPolicy`: This determines how the job will be restarted when it fails. Valid values are `Never` and `OnFailure`. +* `jobBackoffLimit`: This defines the maximum number of retries that can be attempted before the job is considered failed. +* `startingDeadlineSeconds`: This defines the deadline for starting the job. If the job is not started before the deadline, it will be cancelled. + +Once you have configured the schedule in the values.yaml file, you can deploy the Renovate chart using `helm install` or `helm upgrade` commands. The Renovate job will then run according to the specified schedule. + +### Example Yaml +```yaml +packages: + renovate: + enabled: true + git: + repo: https://repo1.dso.mil/big-bang/product/packages/renovate.git + tag: 32.38.0-bb.1 + values: + cronjob: + # At 01:00 every day + schedule: '0 1 * * *' + # -- If it is set to true, all subsequent executions are suspended. This setting does not apply to already started executions. + suspend: false + annotations: {} + labels: {} + concurrencyPolicy: '' + failedJobsHistoryLimit: '' + successfulJobsHistoryLimit: '' + jobRestartPolicy: Never + jobBackoffLimit: '' + startingDeadlineSeconds: '' + + ``` diff --git a/docs/guides/using-bigbang/autoscaling-fluentbit-and-promtail.md b/docs/guides/using-bigbang/autoscaling-fluentbit-and-promtail.md new file mode 100644 index 0000000000000000000000000000000000000000..cdbb827faab65fb9000897c55a2d1f1a0ebf2ef5 --- /dev/null +++ b/docs/guides/using-bigbang/autoscaling-fluentbit-and-promtail.md @@ -0,0 +1,93 @@ +# Installing and Configuring Vertical Pod Autoscaler (VPA) for Vertical Scaling of Fluent Bit and Promtail Pods + +Since log forwarder pods, like Fluentbit and Promtail, are designed to have one pod per node via a ReplicaSet instantiation, they are unable to be horizontally scaled when reaching their resource limits. They can still be vertically scaled once [VPA](https://repo1.dso.mil/big-bang/product/packages/vpa) is installed. + +# 1. Prerequisites + +- Kubernetes cluster must be running version 1.14 or later. +- Kubectl command-line tool must be configured to access the cluster. + +# 2. Install the Vertical Pod Autoscaler + 1. Run the following commands to install the VPA components from the package repo: + + + git clone https://repo1.dso.mil/big-bang/product/packages/vpa.git + cd vpa + helm install vertical-pod-autoscaler chart/ + + 2. Add package via the Big Bang 2.0 `packages:` key: + + packages: + vpa: + enabled: true + git: + repo: "https://repo1.dso.mil/big-bang/product/packages/vpa.git" + tag: LATEST_TAG + path: chart + ... + + +# 3.Configure Fluent Bit Deployment +For Fluentbit, make sure the following settings are added to the packages Helm Chart [values.yaml](https://repo1.dso.mil/big-bang/product/packages/fluentbit/-/blob/main/chart/values.yaml_) file: + +```yaml +autoscaling: + vpa: + enabled: true + annotations: {} + # List of resources that the vertical pod autoscaler can control. Defaults to cpu and memory + controlledResources: [] + # Define the max allowed resources for the pod + maxAllowed: + cpu: 200m + memory: 100Mi + # Define the min allowed resources for the pod + minAllowed: + cpu: 200m + memory: 100Mi +``` + +# 4.Configure Promtail Deployment + +For Promtail, make sure the following settings are added to the Packages Helm Chart [values.yaml](https://repo1.dso.mil/big-bang/product/packages/promtail/-/blob/main/chart/values.yaml) file: + +```yaml +# -- config for VerticalPodAutoscaler +vpa: + enabled: true + # kind -- DaemonSet or Deployment + kind: DaemonSet + annotations: {} + # List of resources that the vertical pod autoscaler can control. Defaults to cpu and memory + controlledResources: [] + # Define the max allowed resources for the pod + maxAllowed: + cpu: 200m + memory: 100Mi + # Define the min allowed resources for the pod + minAllowed: + cpu: 200m + memory: 100Mi + updatePolicy: + # Specifies whether recommended updates are applied when a Pod is started and whether recommended updates + # are applied during the life of a Pod. Possible values are "Off", "Initial", "Recreate", and "Auto". + updateMode: Auto +``` + +# 5.Verify VPA Status + +Check the VPA status to ensure it is functioning correctly and providing recommendations. + +Run the following command: + +```shell + kubectl describe vpa -A +``` + +Look for the Conditions section and verify that the status is Healthy. + +# 6.Monitor and Observe Scaling + +Monitor the cluster and observe how the VPA scales the Fluent Bit and Promtail pods based on resource utilization. Review the pod resource utilization metrics using commands like kubectl top pods or monitoring tools like Prometheus and Grafana. + +By following these steps, you should be able to install and configure the VPA to vertically scale Fluent Bit and Promtail pods in your Kubernetes cluster when additional resources are needed and headroom is available. Adjust the configurations and policies based on your specific requirements and application characteristics. diff --git a/docs/guides/using-bigbang/default-credentials.md b/docs/guides/using-bigbang/default-credentials.md new file mode 100644 index 0000000000000000000000000000000000000000..7d848b968ab6f23109bc3edd053c6bf8aeae3bf7 --- /dev/null +++ b/docs/guides/using-bigbang/default-credentials.md @@ -0,0 +1,33 @@ +# Credentials for Big Bang Packages + +This document includes details on credentials to access each package in a default install (i.e., without SSO). It is safe to assume that any packages not listed in the two categories below either have no need for authentication or use different methods (e.g., Velero require kubectl access). + +## Packages With No Built-in Authentication + +Although the below applications have no built in authentication, Big Bang's helm values can be configured to deploy authservice in front of these endpoints. Authservice is an Authentication Proxy that can integrate with SSO providers like Keycloak. + +- Jaeger +- Monitoring (Prometheus) +- Monitoring (Alertmanager) + +## Packages With Built-in Authentication + +The applications in the table below provide both SSO and built-in authentication. The table gives default credentials and ways to access and/or override those. + +| Package (Application) | Default Username | Default Password | Additional Notes | +| --------------------- | ---------------- | ---------------- | ---------------- | +| Kiali | N/A | (randomly generated) | Use `kubectl -n kiali create token kiali-service-account` to create a temporary token | +| Logging (Kibana) | `elastic` | (randomly generated) | Use `kubectl get secrets -n logging logging-ek-es-elastic-user -o go-template='{{.data.elastic \| base64decode}}'` to get the password | +| Grafana | `admin` | `prom-operator` | Default password can be overridden with Helm values `grafana.values.adminPassword` | +| Twistlock | `admin` | `change_this_password` | Admin account will be automatically setup on fresh installs if `init.enabled` is `true`. Default password can be overridden by setting `twistlock.values.console.credentials.password` | +| ArgoCD | `admin` | (randomly generated) | Use `kubectl -n argocd get secret argocd-initial-admin-secret -o go-template='{{.data.password \| base64decode}}'` to get the password. Note: If the argocd-initial-admin-secret does not exist, you will need to [reset the admin password](https://github.com/argoproj/argo-cd/blob/master/docs/faq.md#i-forgot-the-admin-password-how-do-i-reset-it). | +| Minio | `minio` | `minio123` | Access and secret key can be overridden with Helm values `addons.minio.accesskey` and `addons.minio.secretkey` respectively | +| Gitlab | `root` | (randomly generated) | Use `kubectl -n gitlab get secret gitlab-gitlab-initial-root-password -o go-template='{{.data.password \| base64decode}}'` to get the password | +| Nexus | `admin` | (randomly generated) | Use `kubectl get secret -n nexus-repository-manager nexus-repository-manager-secret -o go-template='{{index .data "admin.password" \| base64decode}}'` to get the password | +| Sonarqube | `admin` | `admin` | Default password can be overridden with Helm values `addons.sonarqube.values.account.adminPassword` | +| Anchore | `admin` | (randomly generated) | Use `kubectl get secrets -n anchore anchore-anchore-enterprise -o go-template='{{.data.ANCHORE_ADMIN_PASSWORD \| base64decode}}'` to get the password, or override with Helm values `addons.anchore.values.anchoreGlobal.defaultAdminPassword` | +| Mattermost | N/A | N/A | Prompted to setup an account when you first hit the virtual service - this user becomes admin, no default user | +| Keycloak | `admin` | `password` | Default username and password can be overridden with Helm values `addons.keycloak.values.secrets.env.stringData.KEYCLOAK_ADMIN` and `addons.keycloak.values.secrets.env.stringData.KEYCLOAK_ADMIN_PASSWORD` respectively | +| Neuvector | `admin` | `admin` | You should change the default password when you log into Neuvector. Can also be changed via the chart at the `controller.secret.data.userinitcfg.yaml` key, see the [upstream docs for more details and examples](https://open-docs.neuvector.com/deploying/production/configmap).| +| Harbor | `admin` | `Harbor12345` | Default password can be overridden with Helm values `addons.harbor.values.harborAdminPassword` | +| Fortify | `admin` | `admin` | You will be prompted to change the admin user password when you first attempt to login to Fortify using the default credentials | diff --git a/docs/guides/using-bigbang/efk-plg-logging-migration.md b/docs/guides/using-bigbang/efk-plg-logging-migration.md new file mode 100644 index 0000000000000000000000000000000000000000..783da0d7e549fe87ee6151a7c88c8f8dc497d1ce --- /dev/null +++ b/docs/guides/using-bigbang/efk-plg-logging-migration.md @@ -0,0 +1,68 @@ +# Switching Between EFK and PLG + +These instructions detail how to switch between Elasticsearch, Fluentbit, and Kibana (EFK) and Promtail, Loki, and Grafana (PLG) logging solutions. + +The EFK stack is an open-source choice for the Kubernetes log aggregation and analysis and is comprised of the following: +- Elasticsearch is a distributed and scalable search engine commonly used to sift through large volumes of log data. +- Fluentbit is a log shipper. It is an open source log collection agent which support multiple data sources and output formats. +- Kibana is a User Interface (UI) tool for querying, data visualization and dashboards. + +Today the EFK stack is enabled by default in the Big Bang chart. The EFK stack appears within the chart as shown in the following: + +```yaml + +elasticsearchKibana: + # -- Toggle deployment of Logging (Elastic/Kibana). + enabled: true + +eckOperator: + # -- Toggle deployment of ECK Operator. + enabled: true + +fluentbit: + # -- Toggle deployment of Fluent-Bit. + enabled: true + +``` + +If you want to use a logging solution that doesn't require a license and has a smaller footprint, Big Bang provides PLG. PLG is comprised of the following: + +- Promtail is an agent that detects targets (e.g., local log files), attaches labels to log streams from the pods, and ships them to Loki. +- Loki is an open-source, multi-tenant log aggregation system. It can be used with Grafana and Promtail to collect and access logs. +- Grafana is an open-source visualization platform that processes time-series data from Loki and makes the logs accessible in a web UI. + +Currently, the way to switch from the default EFK stack to PLG is to set the following values in the bigbang chart: + +```yaml + +elasticsearchKibana: + # -- Toggle deployment of Logging (EFK). + enabled: false // Disables the Elasticsearch Kibana deployment + +eckOperator: + # -- Toggle deployment of ECK Operator. + enabled: false // Do not need the eck operator either + +fluentbit: + # -- Toggle deployment of Fluent-Bit. + enabled: false // Disables Fluentbit + +jaeger: + # -- Toggle deployment of Jaeger. + enabled: false // Disables Jaeger | Uses elasticsearch to persist searches, not required when elasticsearch is disabled + +loki: + # -- Toggle deployment of Loki. + enabled: true // Deploys Loki | Logging injester and queryer replacing elasticsearch kibana + +promtail: + # -- Toggle deployment of Promtail. + enabled: true // Deploys Promtail + +tempo: + # -- Toggle deployment of Tempo. + enabled: true // Deploys Tempo | Tracing backend replacing jaeger + +``` + +**NOTE:** Both Fluentbit and Promtail forward logs to Grafana Loki. Should you want a logging stack comprised solely of Grafana technologies, the PLG stack will accommodate. The use of Fluentbit to send logs (i.e., log forwarder) is still a viable option rather than Promtail, and is configured within Big Bang to ship to Loki if enabled. Big Bang's recommendation is to use Fluentbit as a log forwarder because it is more feature rich. Promtail can only send to a limited set of endpoints (e.g., Loki and S3), whereas Fluentbit can send to numerous endpoints. diff --git a/docs/guides/using-bigbang/image-pull-policy.md b/docs/guides/using-bigbang/image-pull-policy.md new file mode 100644 index 0000000000000000000000000000000000000000..8d6822526de15a5e396e1096db2d0135c75c1bc9 --- /dev/null +++ b/docs/guides/using-bigbang/image-pull-policy.md @@ -0,0 +1,42 @@ +# ImagePullPolicy for Big Bang + +## Setting ImagePullPolicy at the Big Bang Level + +Big Bang is currently working to standardize the adoption of a global image pull policy so that customers can set a single value and have it passed to all packages. + +The global image pull policy has been adopted in Big Bang for the core packages and for addons. In the Big Bang values.yaml file, a global parameter has been created to set the global image pull policy (`imagePullPolicy` in values) and it gets passed down to all core packages and add-ons spec. The default value for this global policy is `IfNotPresent`. + +We have also documented the package overrides required if you want to set a single package/pod with a different pull policy than the global. + +## Setting ImagePullPolicy per Package + +| Package | Default | Value Override | +|---|---|---| +| Istio Controlplane | None | <pre lang="yaml">istio:<br> values:<br> imagePullPolicy: IfNotPresent</pre> | +| Istio Operator | `IfNotPresent` | <pre lang="yaml">istio-operator:<br> values:<br> imagePullPolicy: IfNotPresent</pre> | +| Jaeger | `Always` | <pre lang="yaml">jaeger:<br> values:<br> image:<br> pullPolicy: IfNotPresent</pre> | +| Kiali | `IfNotPresent` | <pre lang="yaml">kiali:<br> values:<br> image:<br> pullPolicy: IfNotPresent<br> cr:<br> spec:<br> deployment:<br> image_pull_policy: IfNotPresent</pre> | +| Cluster Auditor | `Always` | <pre lang="yaml">clusterAuditor:<br> values:<br> image:<br> imagePullPolicy: IfNotPresent</pre> | +| OPA Gatekeeper | `IfNotPresent` | <pre lang="yaml">gatekeeper:<br> values:<br> postInstall:<br> labelNamespace:<br> image:<br> pullPolicy: IfNotPresent<br> postUpgrade:<br> cleanupCRD:<br> image:<br> pullPolicy: IfNotPresent<br> image:<br> pullPolicy: IfNotPresent</pre> | +| Kyverno | `IfNotPresent` | <pre lang="yaml">addons:<br> kyverno:<br> values:<br> image:<br> pullPolicy: IfNotPresent<br> initImage:<br> pullPolicy: IfNotPresent</pre> | +| Elasticsearch / Kibana | `IfNotPresent` | <pre lang="yaml">elasticsearchKibana:<br> values:<br> imagePullPolicy: IfNotPresent</pre> | +| ECK Operator | `IfNotPresent` | <pre lang="yaml">eckOperator:<br> values:<br> image:<br> pullPolicy: IfNotPresent</pre> | +| Fluentbit | `Always` | <pre lang="yaml">fluentbit:<br> values:<br> image:<br> pullPolicy: IfNotPresent</pre> | +| Loki | `IfNotPresent` | <pre lang="yaml">loki:<br> values:<br> image:<br> pullPolicy: IfNotPresent</pre> | +| Monitoring | Varies | <pre lang="yaml">monitoring:<br> values: <br> kube-state-metrics:<br> image:<br> pullPolicy: IfNotPresent<br> grafana:<br> image:<br> pullPolicy: IfNotPresent<br> sidecar:<br> imagePullPolicy: IfNotPresent<br> prometheus-node-exporter:<br> image:<br> pullPolicy: IfNotPresent<br> prometheusOperator:<br> image:<br> pullPolicy: IfNotPresent<br> admissionWebhooks:<br> cleanupProxy:<br> image:<br> pullPolicy: IfNotPresent<br> patch: <br> image:<br> pullPolicy: IfNotPresent<br> prometheus:<br> prometheusSpec:<br> containers:<br> - name: "prometheus"<br> imagePullPolicy: IfNotPresent<br> - name: "config-reloader"<br> imagePullPolicy: IfNotPresent<br> alertmanager:<br> alertmanagerSpec:<br> containers:<br> - name: "alertmanager"<br> imagePullPolicy: IfNotPresent<br> - name: "config-reloader"<br> imagePullPolicy: IfNotPresent</pre> | +| Twistlock | `IfNotPresent` | <pre lang="yaml">twistlock:<br> values:<br> console:<br> image:<br> imagePullPolicy: IfNotPresent</pre> | +| Promtail | `IfNotPresent` | <pre lang="yaml">promtail:<br> values:<br> init:<br> image:<br> pullPolicy: IfNotPresent<br> image:<br> pullPolicy: IfNotPresent</pre> | +| ArgoCD | Varies | <pre lang="yaml">addons:<br> argocd:<br> values:<br> global:<br> image:<br> imagePullPolicy: IfNotPresent<br> controller:<br> image:<br> imagePullPolicy: IfNotPresent<br> dex:<br> image:<br> imagePullPolicy: IfNotPresent<br> redis-bb:<br> image:<br> pullPolicy: IfNotPresent<br> server:<br> image:<br> imagePullPolicy: IfNotPresent<br> repoServer:<br> image:<br> imagePullPolicy: IfNotPresent</pre> | +| Authservice | `IfNotPresent` | <pre lang="yaml">addons:<br> authservice:<br> values:<br> image:<br> pullPolicy: IfNotPresent</pre> | +| MinIO Operator | `IfNotPresent` | <pre lang="yaml">addons:<br> minioOperator:<br> values:<br> operator:<br> image:<br> pullPolicy: IfNotPresent</pre> | +| MinIO | `IfNotPresent` | <pre lang="yaml">addons:<br> minio:<br> values:<br> tenants:<br> image:<br> pullPolicy: IfNotPresent</pre> | +| Gitlab | None | <pre lang="yaml">addons:<br> gitlab:<br> values:<br> global:<br> image:<br> pullPolicy: IfNotPresent</pre> | +| Gitlab Runners | `IfNotPresent` | <pre lang="yaml">addons:<br> gitlabRunner:<br> values:<br> imagePullPolicy: IfNotPresent</pre> | +| Nexus | `IfNotPresent` | <pre lang="yaml">addons:<br> nexusRepositoryManager:<br> values:<br> image:<br> pullPolicy: IfNotPresent<br> job_image:<br> pullPolicy: IfNotPresent</pre> | +| Sonarqube | `IfNotPresent` | <pre lang="yaml">addons:<br> sonarqube:<br> values:<br> image:<br> pullPolicy: IfNotPresent</pre> | +| Anchore | `IfNotPresent` | <pre lang="yaml">addons:<br> anchore:<br> values:<br> anchoreGlobal:<br> imagePullPolicy: IfNotPresent<br> anchoreEnterpriseGlobal:<br> imagePullPolicy: IfNotPresent<br> anchoreEnterpriseUi:<br> imagePullPolicy: IfNotPresent</pre> | +| Mattermost Operator | `IfNotPresent` | <pre lang="yaml">addons:<br> mattermostOperator:<br> values:<br> image:<br> imagePullPolicy: IfNotPresent</pre> | +| Mattermost | `IfNotPresent` | <pre lang="yaml">addons:<br> mattermost:<br> values:<br> image:<br> imagePullPolicy: IfNotPresent</pre> | +| Velero | `IfNotPresent` | <pre lang="yaml">addons:<br> velero:<br> values:<br> image:<br> pullPolicy: IfNotPresent</pre> | +| Keycloak | `IfNotPresent` | <pre lang="yaml">addons:<br> keycloak:<br> values:<br> image:<br> pullPolicy: IfNotPresent<br> pgchecker:<br> image:<br> pullPolicy: IfNotPresent</pre> | +| Vault | `IfNotPresent` | <pre lang="yaml">addons:<br> vault:<br> values:<br> injector:<br> image:<br> pullPolicy: IfNotPresent<br> server:<br> image:<br> pullPolicy: IfNotPresent<br> csi:<br> image:<br> pullPolicy: IfNotPresent</pre> | diff --git a/docs/guides/using-bigbang/kyverno-use-by-apps.md b/docs/guides/using-bigbang/kyverno-use-by-apps.md new file mode 100644 index 0000000000000000000000000000000000000000..d50e5129afa621f7cf78d30bc2b2acca23f7d4c6 --- /dev/null +++ b/docs/guides/using-bigbang/kyverno-use-by-apps.md @@ -0,0 +1,17 @@ +# List Of Big Bang Applications That Are Using Kyverno + +## Gitlab Runner + +In order for Gitlab Runner auto registration to work, the runner must be deployed in the `gitlab` namespace or have a copy of the 'gitlab-runner-secret' in its separate namespace. The Big Bang helm chart deploys Gitlab Runner in a separate namespace. Gitlab Runner uses Kyverno to copy the gitlab runner secret. There are alternate options if Kyverno is not wanted. + +1. By default Gitlab Runner uses Kyverno to support auto registration. +2. The runner token can be added to value overrides. +3. The gitlab-runner-secret can be manually copied to the `gitlab-runner` namespace. + +## Fluentbit + +In order for Fluentbit to automatically have a connection set up for Elastic, the Elastic root password and certificate secrets must be copied from the `logging` namespace to `fluentbit`. Kyverno is leveraged to copy these automatically. There are alternatives if using Kyverno is not desired. These alternatives are listed in the following: + +1. By default Kyverno is used for auto-connection. +2. `fluentbit.values.additionalOutputs.elasticsearch` could be used to setup a connection with Elastic rather than the auto-connection. +3. Secrets can be manually copied to the `fluentbit` namespace. diff --git a/docs/guides/using-bigbang/monitoring-applications-with-annotations-scraping.md b/docs/guides/using-bigbang/monitoring-applications-with-annotations-scraping.md new file mode 100644 index 0000000000000000000000000000000000000000..8a60567964ea04a13dabf50a2b254684dc8922ad --- /dev/null +++ b/docs/guides/using-bigbang/monitoring-applications-with-annotations-scraping.md @@ -0,0 +1,55 @@ +# Integrating Prometheus Label Scraping for Sample Application + +## Introduction + +Integrating Prometheus metrics scraping with label scraping services is helpful for monitoring monitoring applications that either don't ship with a a ServiceMonitor, for testing in researching to build out a serviceMonitor resource, or in-development applications where creating and managing annotations is simpler than building and managing ServiceMonitors. This guide will explain how to integrate metrics scraping for your annotated service endpoints or specific pods with Big Bang. + +By default, global endpoint monitoring is behind a hidden value in Big Bang. If you wish to enable, it the sections below are for each configuration. + +The available Global serviceMonitor for annotated endpoints service is defined by the prometheus job name `kubernetes-service-endpoints` with following hidden value `monitoring.globalServiceEndpointMetrics` in `values.yaml`: +``` +monitoring: + globalServiceEndpointMetrics: + enabled: true +``` + +The available Global serviceMonitor for annotated pods is defined by the prometheus job name `kubernetes-pods` with following hidden value `monitoring.globalPodEndpointMetrics` in `values.yaml`: +``` +monitoring: + globalPodEndpointMetrics: + enabled: true +``` + +## Prerequisites + +Before integrating with Prometheus, ensure the following: + +- Determine if the application supports Prometheus metrics exporting. If not, find a Prometheus exporter to provide this service. +- Identify the path and port used to scrape metrics on the application or exporter. +- List the services and/or pods that should be monitored. + +## Integration Steps + +### 1. Define Placeholder Values for a Service (Recommended) + +Add placeholders in `chart/values.yaml` to configure whether the monitoring stack (Prometheus) is enabled: +the following is an example of a placeholder for allowing scraping of the `metrics-server` service endpoint: +```yaml +addons: + metrics-server: + values: + service: + annotations: + prometheus.io/scrape: "true" + prometheus.io/port: "10250" + prometheus.io/path: "/metrics" + serviceMonitor: + enabled: false # set to true to enable monitoring if the service is not already being scraped. This is an easily re-producible example but ideally the app will not ship with a serviceMonitor. + +**NOTE:** The example above is for the metrics-server application, you will need to update the service annotations to match your application. Also note that metrics-server is already being scraped by a local serviceMonitor, so you will need to disable it so label scraping can be enabled. +``` + +Applications configured correctly will be scraped by Prometheus under the `target->` `kubernetes-service-endpoints` in the Prometheus User Interface (UI). Refer to the image below. If you do not know the correct port and path for your application, you may use `Service Discovery` in the Prometheus UI to find the correct port and path for your application. + +![Prometheus GUI](../../assets/imgs/developer/metrics-server-scraping.png) + diff --git a/docs/guides/using-bigbang/network-policies.md b/docs/guides/using-bigbang/network-policies.md new file mode 100644 index 0000000000000000000000000000000000000000..66a75587673d104e39e119ee048eb1e713252024 --- /dev/null +++ b/docs/guides/using-bigbang/network-policies.md @@ -0,0 +1,116 @@ +# Using Network Policies in Big Bang + +## What are Network Policies + +Kubernetes allows Big Bang operators to utilize [Network Policies](https://kubernetes.io/docs/concepts/services-networking/network-policies/) to control the network traffic into or out of the various pods of a Kubernetes cluster. These network policies allow you to restrict incoming and outgoing traffic to or from a given set of pods using selectors. [Selectors](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/) allow you to select which pods a given networkPolicy will apply to. + +Network Policies are added as needed to supplement other good security practices; such as proper usage of TLS, only exposing necessary ports, and using other standard controls. However, Network Policies allow you to express additional control over what can connect to the pods in your cluster from outside; which pods in your kubernetes cluster can speak to each other internally; and which things those pods can initiate connections to outside of the cluster. + +## Package Types and Support Levels + +The mechanisms described in this document are natively available for: + +- all bigbang core packages (such as kyverno, monitoring, istio, etc) +- all bigbang supported addon packages (such as minio, etc) +- select community supported addons (jira, confluence) + +For the purposes of this document, "customer defined package" and "community supported package" may be used interchangably and the techniques for one will apply equally to the other. However, customer defined packages will need to implement support for the networkpolicy control mechanism themselves if they want to make use of this functionality. See the [developer guide](../../developer/package-integration/network-policies.md) for how to implement this functionality in a customer defined package. + +## Enabling or Disabling Network Policies + +BigBang core and addon packages ship with various network policies already configured. You can turn these networking policies on and off by setting a global flag and a per-component flag. Community supported packages may or may not provide the same mechanism for managing networking policies - check the documentation for the given community supported package for confirmation or additional instructions. + +``` +# This will turn support on or off for network policies writ-large across the bigbang suite +networkPolicies: + enabled: [true|false] + +# For bigbang core packages, this will turn on or off support for network policies in a core component +CORE_PACKAGE_NAME: + values: + networkPolicies: + enabled: [true|false] + +# For bigbang supported addon packages, this will turn on or off support for network policies in a specific addon +addons: + ADDON_PACKAGE_NAME: + values: + networkPolicies: + enabled: [true|false] + +# For user defined packages deployed using the wrapper chart, this will turn on or off support for network policies in that package +package: + PACKAGE_NAME: + values: + networkPolicies: + enabled: [true|false] +``` + +## Crafting and Delivering Additional Network Policies + +Sometimes you will want to apply additional [Network Policies](https://kubernetes.io/docs/concepts/services-networking/network-policies/) to further isolate certain pods in your deployment. BigBang has adopted standardized mechanisms for crafting and deploying these Network Policies through the values provided to your BigBang core, supported addon or packages deployed with the big bang wrapper chart. + +For BigBang core packages, you place these rules inside of the values for the given component: + +``` +CORE_PACKAGE_NAME: + values: + networkPolicies: + enabled: true + additionalPolicies: [] +``` + +For BigBang supported addon packages, you place these rules inside of the values for the given package: + +``` +addons: + ADDON_PACKAGE_NAME: + values: + networkPolicies: + enabled: true + additionalPolicies: [] +``` + +For packages deployed with the wrapper chart, you add these rules inside of the values for the package: + +``` +packages: + PACKAGE_NAME: + values: + networkPolicies: + enabled: true + additionalPolicies: [] +``` + +In all cases, the `additionalPolicies` entry should be a list of YAML objects, each describing a single [Network Policy](https://kubernetes.io/docs/concepts/services-networking/network-policies/). You can add as many of these as you like. Consult [the upstream Kubernetes documentation](https://kubernetes.io/docs/concepts/services-networking/network-policies/) for more information on Network Policies, and what you can do with them. + +``` +additionalPolicies: + - name: example-egress-policy-all-pods + spec: + podSelector: {} + policyTypes: + - Egress + egress: + - to: + - ipBlock: + cidr: 172.20.0.0/12 + - name: example-ingress-policy-all-pods + spec: + podSelector: {} + policyTypes: + - Ingress + ingress: + - from: + - ipBlock: + cidr: 172.20.0.0/12 +``` + +## References + +* [Kubernetes Network Policies Documentation](https://kubernetes.io/docs/concepts/services-networking/network-policies/) +* [Kubernetes Labels and Selectors Documentation](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/) +* [Big Bang Developer Guide for Package Implementation](../../developer/develop-package.md) +* [Big Bang Developer Guide for Package Integration regarding Network Policies](../../developer/package-integration/network-policies.md) + +For more information regarding the behavior of a specific core, supported addon or community supported package, you should always reference the documentation for the specific package in question. Information specific to any given package is outside the scope of this documentation. \ No newline at end of file diff --git a/docs/guides/using-bigbang/pod-usage-in-grafana.md b/docs/guides/using-bigbang/pod-usage-in-grafana.md new file mode 100644 index 0000000000000000000000000000000000000000..b3c70a075541dd3ade1502b7d0d11dbf0ff4fb69 --- /dev/null +++ b/docs/guides/using-bigbang/pod-usage-in-grafana.md @@ -0,0 +1,23 @@ +# How To Monitor Pod Resource Using Grafana + +1. Log in to Grafana url with credentials \ + To Get Grafana credentials: \ + Username: + + ```shell + kubectl get secret monitoring-monitoring-grafana -o jsonpath='{.data.admin-user}' | base64 -d + ``` + + Password: + + ```shell + kubectl get secret monitoring-monitoring-grafana -o jsonpath='{.data.admin-password}' | base64 -d + ``` + + Or [review password value within helm chart](https://repo1.dso.mil/big-bang/product/packages/monitoring/-/blob/main/chart/values.yaml#L708) + +1. Once logged in and directed to the home page, click the menu Dashboard and then select Manage. \ + ![Manage Dashboard Screenshot](../../assets/imgs/guides/grafana-dashboard-manage.jpeg) +1. From the Dashboard select Kubernetes/Compute Resource / Pod . \ + This creates a dashboard to monitor the pod resource CPU Usage, CPU Throttling, CPU quota, Memory Usage, Memory Quota, etc. \ + ![Pod Resource Grafana Screenshot](../../assets/imgs/guides/grafana-dashboard.jpeg) diff --git a/docs/guides/using-bigbang/signed-helm-repositories.md b/docs/guides/using-bigbang/signed-helm-repositories.md new file mode 100644 index 0000000000000000000000000000000000000000..35fd41e9af87ea22eec4973d0660354dfeffaad4 --- /dev/null +++ b/docs/guides/using-bigbang/signed-helm-repositories.md @@ -0,0 +1,89 @@ +# Deploying BigBang and BigBang packages using Signed HelmRepository artifacts + +## Artifact Signing Introduction + +Kubernetes and Flux2 both support ways to verify artifacts are signed according to the SigStore Cosign signature published with their Release Artifacts on Gitlab. + +As part of the existing BigBang Releases, packages and BigBang Release artifacts will now also have cosign signatures published to registry1. This is only available for use when your packages are set to use `sourceType: helmRepo` (default is "git"). Combined with `<package_name>.helmRepo.cosignVerify: true` flux2 will verify signatures of HelmRepositories installed in the cluster. + +The following example shows how to configure and enable public key verification for Helm Repositories: + +```yaml +helmRepositories: + - name: "registry1" + repository: "oci://registry1.dso.mil/bigbang" + existingSecret: "private-registry" + type: "oci" + username: "" + password: "" + email: "" + cosignPublicKeys: + key1: | + -----BEGIN PUBLIC KEY----- + MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIE7v9J6ttQus6itUoyfMCqMjaIqm + R8XrntaedsdEhPPchOQuFzqTyyAPGifV1SaEu8medVRi6mVICWbVwOteNg== + -----END PUBLIC KEY----- + - name: "registry2" + repository: "oci://registry1.dso.mil/bigbang" + existingSecret: "private-registry" + type: "oci" + username: "" + password: "" + email: "" + cosignPublicKeys: + registry2-key: | + -----BEGIN PUBLIC KEY----- + ... + -----END PUBLIC KEY----- + registry2-key2: | + -----BEGIN PUBLIC KEY----- + ... + -----END PUBLIC KEY----- + - name: "registry3" + repository: "oci://registry1.dso.mil/bigbang" + existingSecret: "private-registry" + type: "oci" + username: "" + password: "" + email: "" + cosignPublicKeys: [] + - name: "registry4" + repository: "oci://registry1.dso.mil/bigbang" + existingSecret: "private-registry" + type: "oci" + username: "" + password: "" + email: "" + cosignPublicKeys: + registry4-public: | + -----BEGIN PUBLIC KEY----- + ... + -----END PUBLIC KEY----- + +istio: + sourceType: "helmRepo" + helmRepo: + cosignVerify: true + +istioOperator: + sourceType: "helmRepo" + helmRepo: + cosignVerify: true + +kiali: + sourceType: "helmRepo" + helmRepo: + repoName: "registry2" + cosignVerify: true + +kyverno: + sourceType: "helmRepo" + helmRepo: + repoName: "registry3" + cosignVerify: true +``` + +## More Reading + +- [FluxCD Documentation on public key verification](https://fluxcd.io/flux/components/source/ocirepositories/#public-keys-verification) +- [Kubernetes.io Documenation on cosign signatures](https://kubernetes.io/docs/tasks/administer-cluster/verify-signed-artifacts/#verifying-image-signatures) diff --git a/docs/guides/using-bigbang/style.md b/docs/guides/using-bigbang/style.md new file mode 100644 index 0000000000000000000000000000000000000000..6dc6df21daa600e3de4df08c6aef2e647318037f --- /dev/null +++ b/docs/guides/using-bigbang/style.md @@ -0,0 +1,32 @@ +# General Conventions Style Guide +This style guide outlines the general conventions to follow for package names, structure standardization, version numbers, and YAML formatting focusing on the Big Bang Helm chart. Individual packages (e.g., core, addons, community) may not follow these exact standards. + +## Package Names +When creating package names, consider that different usages of the name will require different formats. For Helm values keys use camelCase to delineate multi-word package names. Avoid using . or - within values keys to simplify Helm templating. Kubernetes resources require translation to kebab-case as they do not support uppercase. Package naming for Kubernetes resources should be consistent across all resources (e.g., GitRepository, Namespace, HelmRelease, and/or labels). + +##### Notable Exceptions +> If a package name is two words and the additional words are less than four characters, consider it as part of the single name. Examples include "fluentbit" (technically "Fluent Bit") and "argocd" (technically "Argo CD"). + +> The "log storage" packages are deployed to the `logging` namespace rather than their respective names (`elasticsearch-kibana` and `loki`). This was primarily done to accommodate persistence of data for legacy deployments. + +## Formatting YAML +When formatting YAML files, follow these guidelines: + +* Indent using two spaces, not tabs. +* Use camelCase and alphanumeric keys, without any special characters. +* Ensure that all Kubernetes resource names, repository names, and namespaces are lowercase, alphanumeric, or hyphenated, using kebab-case. + +## Structure Standardization +For each package, ensure that the following items have the same name: + +* Folder: chart/templates/<package\> +* Top-level key: chart/templates/values.yaml +* Namespace: chart/templates/<package\>/namespace.yaml, unless targeting another package's namespace. +* Repo name: https://repo1.dso.mil/bigbang/packages/<package\> + + +## + +Consistency is key when it comes to formatting choices. Ensure that your changes to Big Bang follow these formatting guidelines consistently throughout. + +Remember that these conventions are meant to serve as a starting point, and it's always important to consider the specific needs and constraints of your contribution when making decisions about package names, structure, versioning, and formatting. diff --git a/docs/guides/using-bigbang/testing-deployments.md b/docs/guides/using-bigbang/testing-deployments.md new file mode 100644 index 0000000000000000000000000000000000000000..f3c70da3f4b4dddb1de642f2b88c1fb2a8c7da16 --- /dev/null +++ b/docs/guides/using-bigbang/testing-deployments.md @@ -0,0 +1,136 @@ +# Testing Deployments Using Cypress + +## Table of Contents +1. [Introduction](#introduction) +2. [Extending Cypress Tests](#extending-cypress-tests) +3. [Resources](#resources) + +## Introduction +Big Bang leverages a sub-chart called Gluon to perform both scripted and User Interface (UI) tests of deployed applications. This guide is designed to describe the basics of the UI testing portion of Gluon and how it can be extended to suit your needs. + +The UI testing is performed via a container running Cypress and can be enabled on a per-package level by setting the value of bbtests.enabled to true. Be sure to review the values for each package as there may be additional settings related to the Cypress test under the bbtests.cypress section. With the correct values in place, you can run a test by specifying the following command: + +`helm test kiali-kiali -n bigbang` + + > **NOTE:** You can run the following command to grab the proper names for each helm chart deployed in Big Bang: "helm list -n bigbang." + +Upon running the command, a new pod will be created in the same namespace as the package. This pod will install Cypress, download a Cypress configuration file, download a file that contains custom Cypress commands, and run any available tests. In order for the Cypress pod to run successfully, it needs to have external access to the internet and any resources it is attempting to reach out to for testing. This communication should be allowed by default. You may also need to add exceptions if using Kyverno or Gatekeeper within Big Bang. Links to these exceptions required can be found below in the Resources section. + +### Default Configuration Options +All Cypress tests use the same shared configuration file which can be found [here](https://repo1.dso.mil/big-bang/product/packages/gluon/-/blob/master/common/cypress.config.js?ref_type=heads). These values can be overridden by using additional environment variables under the bbtests.cypress.envs section for any given package. This [same process](https://docs.cypress.io/guides/guides/environment-variables#Option-4---env) can be used to specify and custom variables that may be need for custom Cypress tests you would like to deploy. + +Additionally, test isolation has been disabled by default within Big Bang's implementation of Cypress as each test is already isolated to a specific package. Disabling test isolation means that session and cookie information will persist within that Cypress pod from test to test instead of being wiped clean after each test. However, this behavior can be mitigated by leveraging a custom command that is available as part of the deployment: + +```cy.clearAllUserData()``` + +The above command can be executed either at the beginning to ensure a clean session or at the end of any given test to ensure everything is clean before the next test. + +## Extending Cypress Tests + +If the default provided Cypress tests are not enough for your installation of Big Bang, there are two options available to extend the behaviour to suit your needs: + +### Option 1: Augment Default Tests with Custom Cypress Tests +Adding your own Cypress tests can be done by creating a ConfigMap inside the namespace for the applicaiton that is being tested. As an example, let's assume you have the following contents in a file called myConfig.yaml: + +``` +apiVersion: v1 +data: + 10-custom.cy.js: |- + describe('Dummy Cypress Test', () => { + it('Custom Cypress Test', () => { + cy.wait(10000) + }) + }) +kind: ConfigMap +metadata: + labels: + app.kubernetes.io/component: server + name: custom-script +``` + +This ConfigMap could be deployed to the kiali namespace by executing the following command: + +``` +kubectl apply -f myConfig.yaml -n kiali +``` + +Once the ConfigMap has been created, you need to specify the name of the ConfigMap in values.bbtests.cypress.customTest as a string for the application: + +``` +values: + bbtests: + cypress: + customTest: "custom-script" +``` + +With the above in place, run the helm test command against the helm chart and the Cypress pod will pull in that ConfigMap as an additional Cypress test to run. It is recommended that any custom tests are prefixed with 10 or a higher number as our default tests start with 01. Some packages have multiple tests, but none of them go as high as 10, so this will guarantee your custom script runs after the default Cypress tests. If, for any reason, you need to make sure your custom test runs prior to our default tests, you can prefix the name of the file with 00. + +Additionally, you can create any variable you may need within your Cypress tests by specifying the value or values under the bbtests.cypress.envs section as mentioned previously. For example, if you want to store a url in a variable, your test may include the following: + +``` +cy.visit(Cypress.env('my_custom_url')) +``` + +The values portion including the variable would look like this: + +``` +values: + bbtests: + cypress: + customTest: "custom-script" + envs: + cypress_my_custom_url: "http://someurl.com" +``` + +### Option 2: Use Only Custom Cypress Tests +This option is the same as the above, but allows you to completely disable the default provided Cypress tests and use only custom Cypress tests. This may be useful if any of the default tests are testing functions that have been disabled in a given application or if the UI has been customized to a point where the default tests simply don't work. To use only a custom Cypress test with default tests disabled the application would need the following values specified: + +``` +values: + bbtests: + cypress: + customTest: "custom-script" + disableDefaultTests: true +``` + +When using this option, the names of the files can be whatever you want as ordering is no longer necessary. However, all custom Cypress test files must end with the .cy.js extension in order to be properly moved over to the Cypress pod. + +### Example Use Case +The easiest way to leverage custom Cypress tests in a Big Bang environment is to deploy the tests using Kustomize. Here is a sample folder structure of what that might look like: + +``` +|-- bigbang +| |-- kustomization.yaml +| |-- tests +| | -- 10-additional-neuvector-test.cy.js +| | -- 10-additional-tempo-test.cy.js +``` + +The contents of the kustomization.yaml file would be as follows: + +``` +generatorOptions: + disableNameSuffixHash: true +configMapGenerator: + - name: custom-script + namespace: neuvector + files: + - tests/10-additional-neuvector-test.cy.js + - name: custom-script + namespace: tempo + files: + - tests/10-additional-tempo-test.cy.js +``` + +The following command can be used to deploy prior to running any helm tests: + +``` +kubectl kustomize ../bigbang +``` + +## Resources +[Gluon Package](https://repo1.dso.mil/big-bang/product/packages/gluon) +[In Depth BB Test Documentation](https://repo1.dso.mil/big-bang/product/packages/gluon/-/blob/master/docs/bb-tests.md?ref_type=heads) +[Kyverno Exceptions for Cypress](https://repo1.dso.mil/big-bang/bigbang/-/blob/master/chart/templates/kyverno-policies/values.yaml) +[Gatekeeper Exceptions for Cypress](https://repo1.dso.mil/big-bang/bigbang/-/blob/master/chart/templates/gatekeeper/values.yaml) +[Cypress Environment Variables](https://docs.cypress.io/guides/guides/environment-variables#Option-4---env) diff --git a/docs/guides/using-bigbang/upgrading-bigbang.md b/docs/guides/using-bigbang/upgrading-bigbang.md new file mode 100644 index 0000000000000000000000000000000000000000..175602a685d158d3922a3f1fa9fdb4c6d4cfb52a --- /dev/null +++ b/docs/guides/using-bigbang/upgrading-bigbang.md @@ -0,0 +1,123 @@ +# Upgrading Big Bang + +## Before Upgrading +Before upgrading Big Bang, please first check the Release Notes and the Changelog to look for any notes that apply to Big Bang Updates and Package Updates. + +There are two important things to review when upgrading: +1. "Upgrade Notices" in the Big Bang release notes: + - These capture any critical notes that the Big Bang development team identified during the release process. + - This may be an update to Flux which requires a "manual" application, or a change to a specific package that we deem important to include. +2. Changelog entries for individual packages that you are deploying: + - Oftentimes individual packages could have breaking changes depending on your configuration. + - It is important to review the changes included with those packages and determine if your configuration needs to be adjusted as a result. + +## Supported Upgrades +Generally, we expect upgrades to be done one minor release at a time. If necessary, it is possible to jump past several versions provided there is careful review of the release notes in between the versions and there are no problems. + +NOTE: It is recommended that upgrades first be tested in a staging environment that mirrors the production environment so that errors are caught early. + +## Upgrading a Single Package +Packages in Big Bang can be updated one at a time. +Upgrading a single package in Big Bang is done by changing the tag in the values for that package. This should be done in the overriding values in the customer template. + +For a git repository: + +```yaml +istio: + sourceType: "git" + git: + repo: https://repo1.dso.mil/big-bang/product/packages/istio-controlplane.git + path: "./chart" + tag: "1.17.1-bb.1" + +``` + +For a helm repository: + +```yaml +istio: + sourceType: "helmRepo" + helmRepo: + repoName: "registry1" + chartName: "istio" + tag: "1.17.1-bb.1" +``` + +These values are in `chart/values.yaml` of the Big Bang helm chart. +When using the [Customer Template](https://repo1.dso.mil/big-bang/customers/template) you can make these changes in either the base values (`bigbang/base/values.yaml`) or in each environment's values file (ex: `bigbang/dev/configmap.yaml`). + +## Upgrading Big Bang umbrella deployment +To upgrade your umbrella deployment of Big Bang when using the [Customer Template](https://repo1.dso.mil/big-bang/customers/template) you have two options: +- Edit `base/kustomization.yaml` and change the value for the [base `ref`](https://repo1.dso.mil/big-bang/customers/template/-/blob/main/base/kustomization.yaml#L4) to the new version. This will update all environments leveraging this base (dev, prod, etc). +```yaml +namespace: bigbang +resources: + - git::https://repo1.dso.mil/big-bang/bigbang.git//base?ref=1.57.1 +``` + +- Edit the environment specific Kustomization (ex: `dev/kustomization.yaml`) to use the new version under the [ref/patch section](https://repo1.dso.mil/big-bang/customers/template/-/blob/main/dev/kustomization.yaml#L18-21). +```yaml + spec: + interval: 1m + ref: + $patch: replace + tag: "1.57.1" +``` + +## Verifying the Upgrade +After upgrading the cluster, there are some places to look to verify that the upgrade was completed successfully. + +### Verify Helm releases +Verify all the helm releases have succeeded + + If everything has updated successfully you should see `Release reconciliation succeeded` as the status for each HelmRelease. +```bash +⯠k get hr -A +NAMESPACE NAME AGE READY STATUS +bigbang kyverno 5h1m True Release reconciliation succeeded +bigbang kyvernopolicies 5h1m True Release reconciliation succeeded +bigbang istio-operator 5h1m True Release reconciliation succeeded +bigbang istio 5h1m True Release reconciliation succeeded +``` + +### Verify Pods + - Verify that there are all pods are either `Running` or `Completed.` + - Look for any pods that recently restarted (crashing recently). + - Below see an example of a pod that has restarted multiple times in a short time. +```bash +⯠k get pod -A +NAMESPACE NAME READY STATUS RESTARTS AGE +kube-system local-path-provisioner-5ff76fc89d-xd85h 1/1 Running 0 22m +... +monitoring alertmanager-monitoring-monitoring-kube-alertmanager-0 3/3 Running 7 3m +``` + +### Verify Image Versions for Specific Packages + - Check for specific package versions (image version on pods). + - There may be cases where you are hoping to use new features in a new package version, as such it can be beneficial to validate that package did update to the new version as expected. + - It can also be important to validate Istio sidecar versions, especially for packages outside of Big Bang core/addons. See an example of checking the image version of the running pod below: +```bash +⯠k get pod -n istio-system istiod-78c5bf85fc-68xv6 -o yaml +apiVersion: v1 +kind: Pod +spec: + affinity: {} + containers: + - args: + image: registry1.dso.mil/ironbank/opensource/istio/pilot:1.17.1 +... +status: + containerStatuses: + - containerID: containerd://451827d87a5209b4cb10ff074d986f00ec3bd7d36082cb49b8612e3a48eea9b7 + image: registry1.dso.mil/ironbank/opensource/istio/pilot:1.17.1 +``` +### Check Package Usability + - Validate the UI for web applications loads properly. + - This could be through a basic `curl` check or similar to confirm UIs are up and healthy. + - You may configure and use certain applications in unique ways. + - It is important to validate those specific applications/features are functioning as expected post-upgrade. + +## Upgrade Troubleshooting +Usually, a good place to start with troubleshooting is to identify which package had issues upgrading. After identifying the package that had problems it can be helpful to re-review the release notes and changelog for that specific package to see if any changes were missed that may have caused the upgrade issue you ran into. + +Specific troubleshooting steps for common issues will be added here in the future. diff --git a/docs/guides/using-bigbang/values-guide.md b/docs/guides/using-bigbang/values-guide.md new file mode 100644 index 0000000000000000000000000000000000000000..a024119cbf974b8969f1787560ef9b0e02575a26 --- /dev/null +++ b/docs/guides/using-bigbang/values-guide.md @@ -0,0 +1,103 @@ +# Values Guide + +Big Bang uses [Helm](https://helm.sh/) to handle configuration values for Big Bang, so in order to understand how Big Bang works it is first essential to understand Helm. Under the hood, Helm is essentially just a template rendering engine: template files are defined where variables are used as placeholders for values, Helm takes those values and interpolates them into the template, then outputs the rendered template file (for Kubernetes, this means YAML). For anyone that has experience with configuration management tools, it is similar in function to Jinja for Ansible and ERB templates for Puppet and Chef. + +Big Bang takes this basic functionality and uses it to create a somewhat complex set of layers that the values get passed through. Each layer includes a set of separate templates that are unique, yet share some standards, which receive values from the layer above and pass them through to the templates in the layer below. The purpose of this guide is to walk through how this works at a high level to increase the level of understanding amongst the community of Big Bang users. + +For additional information regarding Helm templates/values in general, read through the upstream [documentation](https://helm.sh/docs/topics/charts/#templates-and-values). + +## Hierarchy + +Big Bang is a slight variation from the typical "umbrella" helm chart pattern. Individual package charts are not direct subcharts within Big Bang, instead they are deployed by Flux custom resources. These individual package charts (istio, monitoring, gitlab, etc) can be considered "child" helm charts of the Big Bang chart. + +The variables in Big Bang's `values.yaml` file are either passed to Flux or Helm depending on the deployment methodology. Values specific to individual packages will be passed to Flux and used to deploy the package itself. Technically speaking, when you deploy Big Bang you are deploying a number of Flux objects and Flux does the heavy lifting to deploy the actual applications. For more information on Flux, see its official [documentation](https://fluxcd.io/docs/components/). + +A high level conceptual graph of how values flow through Big Bang is provided in the following: + +```mermaid +graph TD + subgraph "Package" + package_values("values.yaml") + end + + subgraph "Big Bang" + bb("values.yaml") --> values_secret("Package Values Secret") + bb("values.yaml") --> flux_hr + values_secret --> package_values + subgraph "Flux Components" + flux_hr("Package GitRepository/HelmRelease") + end + end + + subgraph "Flux/Helm Rendering" + manifests("Manifests applied to cluster") + package_values --> manifests + flux_hr --> manifests + end +``` + +## Values + +Variables defined in Big Bang's [values.yaml](../../../chart/values.yaml) are values that the Big Bang team has identified as ones which users will be most likely to want to set when installing or upgrading Big Bang. This provides a single, standard way to set the most deployment-specific values and many users may not need to do any more than customize these values for their environment. Beyond these the Big Bang team also provides additional ways to pass values through to specific packages or modify templates after rendering. + +### Big Bang Configuration Values + +There are a number of values in the Big Bang chart that are solely used for configuration of the Big Bang chart itself. Typically these values are used for the Flux templates (e.g., HelmRelease and/or GitRepository) or for secrets (e.g., registry credentials and/or git credentials). + +Some examples of these values include: +- `registryCredentials`: Used to configure the image pull secrets for every namespace +- `git`: Used to configure credentials (if required) for cloning the Big Bang package repos +- `flux`: Used for configuring Flux parameters for all HelmReleases +- `<package>.git`: Used for configuring the Flux GitRepository for each package + +### Global Configuration Values + + +Global values within Big Bang are used in cases where packages inherit a common configuration. These mainly include configuration for networking, common SSO provider config, and other common usability values. + +Some examples of these values are included in the following: +- `domain`: This value informs the VirtualService configurations for all packages +- `openshift`: This toggle provides for configuration of any OpenShift specific values across all packages +- `networkPolicies`: These values inform configuration of network policies (enabling, disabling, setting IP ranges) +- `imagePullPolicy`: When set this value is used to configure all packages (and their pods) with a common pull policy +- `sso` (top level value): The configuration set here is used to assist with packages' individual OIDC or SAML configuration, such as endpoints + +**NOTE**: While we use the term "global" here these values are NOT the exact same as a Helm global value. Helm globals are directly passed to all subcharts. Big Bang globals are in some cases passed directly to the package charts, but in other cases they are manipulated/customized to inform package values. + +### Abstracted Package Values + +Each package generally has some configuration that is commonly used for a production deployment. In these cases we try to abstract and simplify the configuration to make it easy for end users. Common use cases for this are database or object storage connections, SSO client ID/Secret, and license details. These values are all set under a `<package>` or `addons.<package>` key, since they are specific to one package in Big Bang. + +When these values are set they are passed through to the package itself. In some cases the Big Bang chart provides additional utility by creating any necessary secrets or toggling other values that are needed. + +Some examples of these values include: +- `<package>.database`: Simplified configuration for an external database connection (e.g., user, pass, host, and/or port) +- `<package>.objectStorage`: Similar configuration for external storage (i.e., S3) +- `<package>.sso.client_id`: Specific SSO client ID for the package +- `<package>.enterprise.license`: Enterprise license for the specific package + +### Package Values Passthrough + +Not every deployment need/configuration for a specific package will be represented by the globals or abstracted values. Although the values you need may not be listed explicitly in the Big Bang chart values, there are still options to set them. + +Every package has a `values: {}` section where you can set additional variables which are defined in the chart but not exposed in Big Bang's `values.yaml`. To see available values options for a specific package you can check the package repo and view its `chart/values.yaml` file. It is important to note that anything set via `<package>.values` will take precedence over the abstracted or global values configured by Big Bang. + +Indentation of these values WILL NOT match the same indentation as the package level. As an example, let's say you want to set the `replicaCount` value for the Kiali package. If you were to check the [Kiali values](https://repo1.dso.mil/big-bang/product/packages/kiali/-/blob/c1d7cfcde20b7778b34ef909f49fc9e7cd2f7ec7/chart/values.yaml#L41) you could override the value this way: + +```yaml +replicaCount: 3 +``` + +In Big Bang to override this value you will want to add this to your configuration: + +```yaml +kiali: + values: + replicaCount: 3 +``` + +### Post-renderers + +In some cases customers run into limitations that even values passthrough cannot solve. In cases where the package chart/template file itself does not provide a value for configuration you can make use of Post Renderers. + +These are an advanced capability within Helm and Flux that allows end users to make modifications to the chart after it has been rendered. For more information and specific on how to leverage this capability see [this document](../../understanding-bigbang/configuration/postrenderers.md). diff --git a/docs/packages.md b/docs/packages.md new file mode 100644 index 0000000000000000000000000000000000000000..c81fa54ca7d2cd647ca5bacb7299f11349b6b33c --- /dev/null +++ b/docs/packages.md @@ -0,0 +1,112 @@ +# Packages + +#### Columns + +1. Monitoring: `Metrics scraping with Prometheus and dedicated Grafana Dashboards/PrometheusRule alerts as appropriate` +2. Tracing: `Tempo or Jaeger connections for tracing application traffic` +3. Network Policies: `Network Policies for restricting network connectivity` +4. mTLS: `Istio Injected, with either a Strict or Permissive Mutual TLS Mode` + +#### Values + +1. N/A: `Feature doesn't exist` +2. No: `Feature exists, Not Implemented in Big Bang` +3. Yes: `Feature exists, Implemented in Big Bang` + +## Core + +| Package | Status | Monitoring | Tracing | Network Policies | mTLS | +|----|----|----|----|----|----| +| [Istio Operator](https://repo1.dso.mil/big-bang/product/packages/istio-operator) | ![Istio Operator Build](https://repo1.dso.mil/big-bang/product/packages/istio-operator/badges/main/pipeline.svg) | Yes | No | [Yes](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests/641) | Yes | +| [Istio Controlplane](https://repo1.dso.mil/big-bang/product/packages/istio-controlplane) | ![Istio Controlplane Build](https://repo1.dso.mil/big-bang/product/packages/istio-controlplane/badges/main/pipeline.svg) | Yes | No | [Yes](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests/632) | Yes | +| [Jaeger](https://repo1.dso.mil/big-bang/product/packages/jaeger) | ![Jaeger Build](https://repo1.dso.mil/big-bang/product/packages/jaeger/badges/main/pipeline.svg) | Yes | Yes | [Yes](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests/602) | [Yes (STRICT)](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests/1295) | +| [Kiali](https://repo1.dso.mil/big-bang/product/packages/kiali) | ![Kiali Build](https://repo1.dso.mil/big-bang/product/packages/kiali/badges/main/pipeline.svg) | No | Yes | [Yes](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests/589) | [Yes (STRICT)](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests/1296) | +| [Monitoring](https://repo1.dso.mil/big-bang/product/packages/monitoring) | ![Monitoring Build](https://repo1.dso.mil/big-bang/product/packages/monitoring/badges/main/pipeline.svg) | Yes | Yes | [Yes](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests/509) | [Yes (STRICT)](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests/1900) | +| [Grafana](https://repo1.dso.mil/big-bang/product/packages/grafana) | ![Grafana Build](https://repo1.dso.mil/big-bang/product/packages/grafana/badges/main/pipeline.svg) | Yes | Yes | [Yes](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests/2929) | [Yes (STRICT)](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests/2929) | +| [NeuVector](https://repo1.dso.mil/big-bang/product/packages/neuvector) | ![NeuVector Build](https://repo1.dso.mil/big-bang/product/packages/neuvector/badges/main/pipeline.svg) | Yes | No | [Yes](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests/2486) | [Yes (STRICT)](https://repo1.dso.mil/big-bang/product/packages/neuvector/-/blob/main/chart/templates/bigbang/peerauthentication/peerauthentication/peer-authentication.yaml) | +| [Twistlock](https://repo1.dso.mil/big-bang/product/packages/twistlock) | ![Twistlock Build](https://repo1.dso.mil/big-bang/product/packages/twistlock/badges/main/pipeline.svg) | Yes | Yes | [Yes](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests/498) | [Yes (STRICT)](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests/1396) | +| [ECK Operator](https://repo1.dso.mil/big-bang/product/packages/eck-operator) | ![ECK Operator Build](https://repo1.dso.mil/big-bang/product/packages/eck-operator/badges/main/pipeline.svg) | No | Yes | [Yes](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests/510) | [Yes (STRICT)](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests/1236) | +| [Elasticsearch Kibana](https://repo1.dso.mil/big-bang/product/packages/elasticsearch-kibana) | ![EK Operator Build](https://repo1.dso.mil/big-bang/product/packages/elasticsearch-kibana/badges/main/pipeline.svg) | Yes | Yes | [Yes](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests/527) | [Yes (STRICT)](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests/1537) | +| [Fluentbit](https://repo1.dso.mil/big-bang/product/packages/fluentbit) | ![Fluentbit Build](https://repo1.dso.mil/big-bang/product/packages/fluentbit/badges/main/pipeline.svg) | Yes | Yes | [Yes](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests/555/) | [Yes (STRICT)](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests/1537) | +| [OPA Gatekeeper](https://repo1.dso.mil/big-bang/product/packages/policy) | ![OPA Build](https://repo1.dso.mil/big-bang/product/packages/policy/badges/main/pipeline.svg) | No | N/A | [Yes](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests/626) | N/A | +| [Cluster Auditor](https://repo1.dso.mil/big-bang/product/packages/cluster-auditor) | ![Cluster Auditor Build](https://repo1.dso.mil/big-bang/product/packages/cluster-auditor/badges/main/pipeline.svg) | Yes | Yes | [Yes](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests/565) | [Yes (STRICT)](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests/1370) | +| [Kyverno](https://repo1.dso.mil/big-bang/product/packages/kyverno) | ![Kyverno Build](https://repo1.dso.mil/big-bang/product/packages/kyverno/badges/main/pipeline.svg) | Yes | N/A | [Yes](https://repo1.dso.mil/big-bang/product/packages/kyverno/-/merge_requests/2) | N/A | +| [Kyverno Policies](https://repo1.dso.mil/big-bang/product/packages/kyverno-policies) | ![Kyverno Build](https://repo1.dso.mil/big-bang/product/packages/kyverno-policies/badges/main/pipeline.svg) | N/A | N/A | Yes \* | N/A | +| [Kyverno Reporter](https://repo1.dso.mil/big-bang/product/packages/kyverno-reporter) | ![Kyverno Build](https://repo1.dso.mil/big-bang/product/packages/kyverno-reporter/badges/main/pipeline.svg) | Yes | No | [Yes](https://repo1.dso.mil/big-bang/product/packages/kyverno-reporter/-/merge_requests/1) | [Yes (STRICT)](https://repo1.dso.mil/big-bang/product/packages/kyverno-reporter/-/merge_requests/1) | +| [Promtail](https://repo1.dso.mil/big-bang/product/packages/promtail) | ![Promtail Build](https://repo1.dso.mil/big-bang/product/packages/promtail/badges/main/pipeline.svg) | [Yes](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests/1342) | Yes | [Yes](https://repo1.dso.mil/big-bang/product/packages/promtail/-/merge_requests/14) | [Yes (STRICT)](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests/1516) | +| [Loki](https://repo1.dso.mil/big-bang/product/packages/loki) | ![Loki Build](https://repo1.dso.mil/big-bang/product/packages/loki/badges/main/pipeline.svg) | [Yes](https://repo1.dso.mil/big-bang/product/packages/loki/-/merge_requests/8) | [Yes](https://repo1.dso.mil/big-bang/product/packages/loki/-/merge_requests/15) | [Yes](https://repo1.dso.mil/big-bang/product/packages/loki/-/merge_requests/1) | [Yes (STRICT)](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests/1516) | +| [Tempo](https://repo1.dso.mil/big-bang/product/packages/tempo) | ![Tempo Build](https://repo1.dso.mil/big-bang/product/packages/tempo/badges/main/pipeline.svg) | [Yes](https://repo1.dso.mil/big-bang/product/packages/tempo/-/merge_requests/2) | [Yes](https://repo1.dso.mil/big-bang/product/packages/tempo/-/merge_requests/3) | [Yes](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests/1253) | [Yes (STRICT)](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests/1762) | + +> `*` inherited from Kyverno when installed in the same namespace. + +# Supported Add-Ons + +## Security + +| Package | Status | Monitoring | Tracing | Network Policies | mTLS | +|----|----|----|----|----|----| +| [Keycloak](https://repo1.dso.mil/big-bang/product/packages/keycloak) | ![Keycloak Build](https://repo1.dso.mil/big-bang/product/packages/keycloak/badges/main/pipeline.svg) | [Yes](https://repo1.dso.mil/big-bang/bigbang/-/issues/291) | [Yes](https://repo1.dso.mil/big-bang/bigbang/-/issues/1204) | [Yes](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests/536) | [Yes (STRICT)](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests/1945) | +| [Anchore Enterprise](https://repo1.dso.mil/big-bang/product/packages/anchore-enterprise) | ![Anchore Build](https://repo1.dso.mil/big-bang/product/packages/anchore-enterprise/badges/main/pipeline.svg) | Yes | Yes | [Yes](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests/505) | [Yes (STRICT)](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests/1594) | +| [Authservice](https://repo1.dso.mil/big-bang/product/packages/authservice) | ![Authservice Build](https://repo1.dso.mil/big-bang/product/packages/authservice/badges/main/pipeline.svg) | Yes | No | [Yes](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests/511) | [Yes (STRICT)](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests/1329) | +| [Vault](https://repo1.dso.mil/big-bang/product/packages/vault) | ![Vault Build](https://repo1.dso.mil/big-bang/product/packages/vault/badges/main/pipeline.svg) | Yes | Yes | Yes | [Yes (STRICT)](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests/1781) | +| [External Secrets Operator](https://repo1.dso.mil/big-bang/product/packages/external-secrets) | ![External Secrets Operator Build](https://repo1.dso.mil/big-bang/product/packages/vault/badges/main/pipeline.svg) | Yes | No | Yes | [Yes (STRICT)](https://repo1.dso.mil/big-bang/product/packages/external-secrets/-/blob/main/chart/values.yaml?ref_type=heads#L580) | + +## Development Tools + +| Package | Status | Monitoring | Tracing | Network Policies | mTLS | +|----|----|----|----|----|----| +| [Gitlab](https://repo1.dso.mil/big-bang/product/packages/gitlab) | ![Gitlab Build](https://repo1.dso.mil/big-bang/product/packages/gitlab/badges/main/pipeline.svg) | Yes | Yes | [Yes](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests/504) | [Yes (STRICT)](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests/1724) | +| [Gitlab Runner](https://repo1.dso.mil/big-bang/product/packages/gitlab-runner) | ![Gitlab Runner Build](https://repo1.dso.mil/big-bang/product/packages/gitlab-runner/badges/main/pipeline.svg) | Yes | Yes \* | [Yes](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests/522) \* | [Yes (STRICT)](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests/1724) \* | +| [Nexus](https://repo1.dso.mil/big-bang/product/packages/nexus) | ![Nexus](https://repo1.dso.mil/big-bang/product/packages/nexus/badges/main/pipeline.svg) | Yes | Yes | [Yes](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests/544) | [Yes (STRICT)](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests/1605) | +| [Sonarqube](https://repo1.dso.mil/big-bang/product/packages/sonarqube) | ![Sonarqube](https://repo1.dso.mil/big-bang/product/packages/sonarqube/badges/main/pipeline.svg) | N/A | Yes | [Yes](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests/503) | [Yes (STRICT)](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests/1508) | +| [Harbor](https://repo1.dso.mil/big-bang/product/packages/harbor) | ![Harbor](https://repo1.dso.mil/big-bang/product/packages/harbor/badges/main/pipeline.svg) | Yes | Yes | [Yes](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests/2939) | [Yes (STRICT)](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests/2939) | +| [Fortify](https://repo1.dso.mil/big-bang/product/packages/fortify) | ![Fortify](https://repo1.dso.mil/big-bang/product/packages/fortify/badges/main/pipeline.svg) | No | Yes | [Yes](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests/3027) | [Yes (STRICT)](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests/3027) | +| [Holocron](https://repo1.dso.mil/big-bang/product/packages/holocron) | ![Holocron](https://repo1.dso.mil/big-bang/product/packages/holocron/badges/main/pipeline.svg) | No | No | [Yes](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests/3726) | [Yes (STRICT)](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests/3726) | + +> `*` inherited from Gitlab when installed in the same namespace. + +## Collaboration Tools + +| Package | Status | Monitoring | Tracing | Network Policies | mTLS | +|----|----|----|----|----|----| +| [Mattermost](https://repo1.dso.mil/big-bang/product/packages/mattermost) | ![Mattermost Build](https://repo1.dso.mil/big-bang/product/packages/mattermost/badges/main/pipeline.svg) | Yes \* | Yes | [Yes](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests/515) | [Yes (STRICT)](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests/2800) | +| [Mattermost Operator](https://repo1.dso.mil/big-bang/product/packages/mattermost-operator) | ![Mattermost Operator Build](https://repo1.dso.mil/big-bang/product/packages/mattermost-operator/badges/main/pipeline.svg) | No | No | [Yes](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests/499) | [Yes (STRICT)](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests/1531) | + +> `*` Monitoring/metrics are only available for enterprise (licensed) deployments of Mattermost + +## Application Utilities + +| Package | Status | Monitoring | Tracing | Network Policies | mTLS | +|----|----|----|----|----|----| +| [MinIO](https://repo1.dso.mil/big-bang/product/packages/minio) | ![MinIO Build](https://repo1.dso.mil/big-bang/product/packages/minio/badges/main/pipeline.svg) | Yes | Yes | [Yes](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests/550) | [Yes (STRICT)](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests/1566) | +| [MinIO Operator](https://repo1.dso.mil/big-bang/product/packages/minio-operator) | ![MinIO Operator Build](https://repo1.dso.mil/big-bang/product/packages/minio-operator/badges/main/pipeline.svg) | [N/A](https://repo1.dso.mil/big-bang/product/packages/minio-operator/-/blob/main/docs/prometheus.md) | Yes | [Yes](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests/685) | [Yes (STRICT)](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests/1554) | +| [Redis](https://repo1.dso.mil/big-bang/product/packages/redis) | ![Redis Build](https://repo1.dso.mil/big-bang/product/packages/redis/badges/main/pipeline.svg) | [Yes](https://repo1.dso.mil/big-bang/product/packages/minio-operator/-/blob/main/docs/prometheus.md) | Yes | [Yes](https://repo1.dso.mil/big-bang/product/packages/redis/-/blob/main/chart/values.yaml?ref_type=heads#L57) | Yes | +| [Renovate](https://repo1.dso.mil/big-bang/product/packages/renovate) | ![Renovate Build](https://repo1.dso.mil/big-bang/product/packages/renovate/badges/main/pipeline.svg) | No | No | [Yes](https://repo1.dso.mil/big-bang/product/packages/renovate/-/blob/main/chart/values.yaml?ref_type=heads#L305) | [Yes (STRICT)](https://repo1.dso.mil/big-bang/product/packages/renovate/-/blob/main/chart/values.yaml?ref_type=heads#L295) | +| [wrapper](https://repo1.dso.mil/big-bang/product/packages/wrapper) | ![Renovate Build](https://repo1.dso.mil/big-bang/product/packages/wrapper/badges/main/pipeline.svg) | Yes | No | [Yes](https://repo1.dso.mil/big-bang/product/packages/wrapper/-/blob/main/chart/values.yaml?ref_type=heads#L5) | [Yes (STRICT)](https://repo1.dso.mil/big-bang/product/packages/wrapper/-/blob/main/chart/values.yaml?ref_type=heads#L52) | + +## Cluster Utilities + +| Package | Status | Monitoring | Tracing | Network Policies | mTLS | +|----|----|----|----|----|----| +| [Argocd](https://repo1.dso.mil/big-bang/product/packages/argocd) | ![Argo Build](https://repo1.dso.mil/big-bang/product/packages/argocd/badges/main/pipeline.svg) | Yes | Yes | [Yes](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests/572) | [Yes (STRICT)](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests/1368) | +| [Velero](https://repo1.dso.mil/big-bang/product/packages/velero) | ![Velero Build](https://repo1.dso.mil/big-bang/product/packages/velero/badges/main/pipeline.svg) | Yes | Yes | [Yes](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests/552) | [Yes (STRICT)](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests/1451) | +| [Metrics Server](https://repo1.dso.mil/big-bang/product/packages/metrics-server) | ![Metrics Server Build](https://repo1.dso.mil/big-bang/product/packages/metrics-server/badges/main/pipeline.svg) | Yes | No | [Yes](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests/1738) | [Yes (STRICT)](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests/1968) | +| [Thanos](https://repo1.dso.mil/big-bang/product/packages/thanos) | ![Thanos Build](https://repo1.dso.mil/big-bang/product/packages/thanos/badges/main/pipeline.svg) | Yes | No | [Yes](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests/3113) | [Yes (STRICT)](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests/3113) | +| [Alloy](https://repo1.dso.mil/big-bang/product/packages/alloy) | ![Alloy Build](https://repo1.dso.mil/big-bang/product/packages/alloy/badges/main/pipeline.svg) | No | No | [Yes](https://repo1.dso.mil/big-bang/bigbang/-/merge_requests/5031) | [Yes (STRICT)](https://repo1.dso.mil/big-bang/product/packages/alloy/-/blob/main/chart/values.yaml?ref_type=heads#L202) | +| [bbctl](https://repo1.dso.mil/big-bang/product/packages/bbctl) | ![bbctl Build](https://repo1.dso.mil/big-bang/product/packages/bbctl/badges/main/pipeline.svg) | No | No | No | N/A | +| [haproxy](https://repo1.dso.mil/big-bang/product/packages/haproxy) | ![haproxy Build](https://repo1.dso.mil/big-bang/product/packages/haproxy/badges/main/pipeline.svg) | No | No | No | [Yes (STRICT)](https://repo1.dso.mil/big-bang/product/packages/haproxy/-/blob/main/chart/values.yaml?ref_type=heads#L569) | + +## Community + +| Package | Status | Monitoring | Tracing | Network Policies | mTLS | +|----|----|----|----|----|----| +| [coder-v2](https://repo1.dso.mil/big-bang/product/community/coder-v2) | ![Coder Build](https://repo1.dso.mil/big-bang/product/community/coder-v2/badges/main/pipeline.svg) | No | No | No | No | +| [Confluence](https://repo1.dso.mil/big-bang/product/community/confluence) | ![Confluence Build](https://repo1.dso.mil/big-bang/product/community/confluence/badges/main/pipeline.svg) | Yes | Yes | [Yes](https://repo1.dso.mil/big-bang/product/community/confluence/-/blob/main/chart/values.yaml?ref_type=heads#L1778) | [Yes (STRICT)](https://repo1.dso.mil/big-bang/product/community/confluence/-/blob/main/chart/values.yaml?ref_type=heads#L1726) | +| [Crossplane](https://repo1.dso.mil/big-bang/product/community/crossplane) | ![Crossplane Build](https://repo1.dso.mil/big-bang/product/community/crossplane/badges/main/pipeline.svg) | No | No | [Yes](https://repo1.dso.mil/big-bang/product/community/crossplane/-/blob/main/chart/values.yaml?ref_type=heads#L202) | [Yes (STRICT)](https://repo1.dso.mil/big-bang/product/community/crossplane/-/blob/main/chart/values.yaml?ref_type=heads#L200) | +| [Jenkins](https://repo1.dso.mil/big-bang/product/community/jenkins) | ![Jenkins Build](https://repo1.dso.mil/big-bang/product/community/jenkins/badges/main/pipeline.svg) | Yes | No | [Yes](https://repo1.dso.mil/big-bang/product/community/jenkins/-/blob/main/chart/values.yaml?ref_type=heads#L851) | [Yes (STRICT)](https://repo1.dso.mil/big-bang/product/community/jenkins/-/blob/main/chart/values.yaml?ref_type=heads#L992) | +| [Jira](https://repo1.dso.mil/big-bang/product/community/jira) | ![Jira Build](https://repo1.dso.mil/big-bang/product/community/jira/badges/main/pipeline.svg) | Yes | No | [Yes](https://repo1.dso.mil/big-bang/product/community/jira/-/blob/main/chart/values.yaml?ref_type=heads#L1292) | No | +| [JupyterHub](https://repo1.dso.mil/big-bang/product/community/jupyterhub) | ![JupyterHub Build](https://repo1.dso.mil/big-bang/product/community/jupyterhub/badges/main/pipeline.svg) | No | No | [Yes](https://repo1.dso.mil/big-bang/product/community/jupyterhub/-/blob/main/chart/values.yaml?ref_type=heads#L94) | No | +| [Kubecost](https://repo1.dso.mil/big-bang/product/community/kubecost) | ![Kubecost Build](https://repo1.dso.mil/big-bang/product/community/kubecost/badges/main/pipeline.svg) | Yes | Yes | [Yes](https://repo1.dso.mil/big-bang/product/community/kubecost/-/blob/main/chart/values.yaml?ref_type=heads#L729) | No | +| [Parabol](https://repo1.dso.mil/big-bang/product/community/parabol) | ![Parabol Build](https://repo1.dso.mil/big-bang/product/community/parabol/badges/main/pipeline.svg) | Yes | Yes | No | No | +| [Rapidfort](https://repo1.dso.mil/big-bang/product/community/rapidfort) | ![Rapidfort Build](https://repo1.dso.mil/big-bang/product/community/rapidfort/badges/main/pipeline.svg) | No | No | [Yes](https://repo1.dso.mil/big-bang/product/community/rapidfort/-/blob/main/chart/values.yaml?ref_type=heads#L972) | [Yes (STRICT)](https://repo1.dso.mil/big-bang/product/community/rapidfort/-/blob/main/chart/values.yaml?ref_type=heads#L960) | +| [sdelements](https://repo1.dso.mil/big-bang/product/community/sdelements) | ![sdelements Build](https://repo1.dso.mil/big-bang/product/community/sdelements/badges/main/pipeline.svg) | No | No | [Yes](https://repo1.dso.mil/big-bang/product/community/sdelements/-/blob/main/chart/values.yaml?ref_type=heads#L1265) | No | diff --git a/docs/prerequisites/.pages b/docs/prerequisites/.pages new file mode 100644 index 0000000000000000000000000000000000000000..ccc2e0ad118d6cc47033a9954b31ae198ada60af --- /dev/null +++ b/docs/prerequisites/.pages @@ -0,0 +1,7 @@ +nav: + - Overview: README.md + - Install Flux: install-flux.md + - OS Preconfiguration: os-preconfiguration.md + - Kubernetes Preconfiguration: kubernetes-preconfiguration.md + - Default Storageclass: default-storageclass.md + - Minimum Hardware Requirements: minimum-hardware-requirements.md diff --git a/docs/prerequisites/README.md b/docs/prerequisites/README.md new file mode 100644 index 0000000000000000000000000000000000000000..5ea90ac0e9a7b57f5bbad30701517234b35d7942 --- /dev/null +++ b/docs/prerequisites/README.md @@ -0,0 +1,18 @@ +# Prerequisites + +[[_TOC_]] + +## Hardware Requirements + +[Minimum Hardware](./minimum-hardware-requirements.md) + +## Software Requirements + +[Operating System Preconfiguration](./os-preconfiguration.md) | +[Kubernetes Preconfiguration](./kubernetes-preconfiguration.md) | +[Flux Installation](./install-flux.md) | +[Default Storageclass](./default-storageclass.md) + +## Licensing Requirements + +[Licensing Model](../understanding-bigbang/licensing-model.md) diff --git a/docs/prerequisites/default-storageclass.md b/docs/prerequisites/default-storageclass.md new file mode 100644 index 0000000000000000000000000000000000000000..a1a1825ed0467c60a75de524da951bf8b725eef1 --- /dev/null +++ b/docs/prerequisites/default-storageclass.md @@ -0,0 +1,77 @@ +# Default Storage Class Prerequisite + +* Big Bang assumes the cluster you're deploying to supports [dynamic volume provisioning](https://kubernetes.io/docs/concepts/storage/dynamic-provisioning/). +* A Big Bang cluster should have 1 Storage Class (SC) annotated as the default SC. +* For production deployments, it is recommended to leverage a SC that supports the creation of volumes that support ReadWriteMany [Access Mode](https://kubernetes.io/docs/concepts/storage/persistent-volumes/#access-modes), as there are a few Big Bang add-ons, where an HA application configuration requires a storage class that supports ReadWriteMany. + +## How Dynamic Volume Provisioning Works in a Nut Shell + +* StorageClass + PersistentVolumeClaim = Dynamically Created Persistent Volume +* A PersistentVolumeClaim that does not reference a specific SC will leverage the default SC, of which there should only be one, identified using Kubernetes annotations. Some helm charts allow a SC to be explicitly specified so that multiple SCs can be used simultaneously. + +## How To Check What Storage Classes Are Installed on Your Cluster + +* `kubectl get storageclass` can be used to see what storage classes are available on a cluster; the default will be marked accordingly. +**NOTE:** You can have multiple storage classes, but you should only have one default storage class. + +```shell +kubectl get storageclass +# NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE +# local-path (default) rancher.io/local-path Delete WaitForFirstConsumer false 47h +``` + +------------------------------------------------------ + +## AWS Specific Notes + +### Example AWS Storage Class Configuration + +```yaml +kind: StorageClass +apiVersion: storage.k8s.io/v1 +metadata: + name: gp2 + annotations: + storageclass.kubernetes.io/is-default-class: 'true' +provisioner: kubernetes.io/aws-ebs +parameters: + type: gp2 #gp3 isn't supported by the in-tree plugin + fsType: ext4 +# encrypted: 'true' #requires kubernetes nodes have IAM rights to a KMS key +# kmsKeyId: 'arn:aws-us-gov:kms:us-gov-west-1:110518024095:key/b6bf63f0-dc65-49b4-acb9-528308195fd6' +reclaimPolicy: Retain +allowVolumeExpansion: true +``` + +### AWS EBS Volumes + +* AWS EBS Volumes have the following limitations: + * An EBS volume can only be attached to a single Kubernetes Node at a time, thus ReadWriteMany Access Mode isn't supported. + * An EBS PersistentVolume in Availability Zone (AZ) 1, cannot be mounted by a worker node in AZ2. + +### AWS EFS Volumes + +* An AWS EFS Storage Class can be installed according to the [vendors docs](https://github.com/kubernetes-sigs/aws-efs-csi-driver#installation). +* AWS EFS Storage Class supports ReadWriteMany Access Mode. +* AWS EFS Persistent Volumes can be mounted by worker nodes in multiple AZs. +* AWS EFS is basically NetworkFileSystem (NFS) as a Service. NFS cons like latency apply equally to EFS, and therefore it's not a good fit for for databases. + +------------------------------------------------------ + +## Azure Specific Notes + +### Azure Disk Storage Class Notes + +* The Kubernetes Docs offer an example [Azure Disk Storage Class](https://kubernetes.io/docs/concepts/storage/storage-classes/#azure-disk) +* An Azure disk can only be mounted with Access mode type ReadWriteOnce, which makes it available to one node in AKS. +* An Azure Disk PersistentVolume in AZ1 can be mounted by a worker node in AZ2, although some additional lag is involved in such transitions. + +------------------------------------------------------ + +## Bare Metal/Cloud Agnostic Store Class Notes + +* The Big Bang Product team put together a [Comparison Matrix of a few Cloud Agnostic Storage Class offerings](../developer/k8s-storage.md#kubernetes-storage-options) + + **NOTE:** No storage class specific container images exist in IronBank at this time. + * Approved IronBank Images will show up in <https://registry1.dso.mil>. + * <https://repo1.dso.mil/dsop> can be used to check status of IronBank images. diff --git a/docs/prerequisites/install-flux.md b/docs/prerequisites/install-flux.md new file mode 100644 index 0000000000000000000000000000000000000000..e115e16e8976eed787b826578c795925288e1ef2 --- /dev/null +++ b/docs/prerequisites/install-flux.md @@ -0,0 +1,48 @@ +# Install the Flux CLI Tool + +```shell +sudo curl -s https://fluxcd.io/install.sh | sudo bash +``` + +> Fedora Note: kubectl is a prereq for flux, and flux expects it in `/usr/local/bin/kubectl` symlink it or copy the binary to fix errors. + +## Install flux.yaml to the Cluster + +```shell +export REGISTRY1_USER='REPLACE_ME' +export REGISTRY1_TOKEN='REPLACE_ME' +``` + +> In production use robot credentials, single quotes are important due to the '$' +`export REGISTRY1_USER='robot$bigbang-onboarding-imagepull'` + +```shell +kubectl create ns flux-system +kubectl create secret docker-registry private-registry \ + --docker-server=registry1.dso.mil \ + --docker-username=$REGISTRY1_USER \ + --docker-password=$REGISTRY1_TOKEN \ + --namespace flux-system +kubectl apply -k https://repo1.dso.mil/big-bang/bigbang.git//base/flux?ref=master +``` +**NOTE:** You can replace ```master``` in the ```kubectl apply -k``` command above with tag of the Big Bang release you need. For example: +``` +kubectl apply -k https://repo1.dso.mil/big-bang/bigbang/bigbang.git//base/flux?ref=2.14.0 +``` + +### Now You Can See New CRD Objects Types Inside the Cluster + +```shell +kubectl get crds | grep flux +``` + +## Advanced Installation + +Clone the Big Bang repo and use the awesome installation [scripts](https://repo1.dso.mil/big-bang/bigbang/-/tree/master/scripts) directory. + +```shell +git clone https://repo1.dso.mil/big-bang/bigbang.git +./bigbang/scripts/install_flux.sh +``` + +> **NOTE:** install_flux.sh requires arguments to run properly, calling it will print out a friendly USAGE message with required arguments needed to complete installation. diff --git a/docs/prerequisites/kubernetes-preconfiguration.md b/docs/prerequisites/kubernetes-preconfiguration.md new file mode 100644 index 0000000000000000000000000000000000000000..0d4de7980ce8e73772765bec91f99c75a1a60354 --- /dev/null +++ b/docs/prerequisites/kubernetes-preconfiguration.md @@ -0,0 +1,133 @@ +# Kubernetes Cluster Preconfiguration + +## Best Practices + +* A Container Network Interface (CNI) that supports Network Policies, which are basically firewalls for the Inner Cluster Network. +**NOTE:** k3d, which is recommended for the quickstart demo, defaults to flannel, which does not support network policies. +* All Kubernetes Nodes and the LB associated with the kube-apiserver should all use private IPs. +* In most case User Application Facing LBs should have Private IP Addresses and be paired with a defense in depth Ingress Protection mechanism like [P1's CNAP](https://p1.dso.mil/#/products/cnap/), a CNAP equivalent (e.g., Advanced Edge Firewall), VPN, VDI, port forwarding through a bastion, or air gap deployment. +* CoreDNS in the kube-system namespace should be HA with pod anti-affinity rules +* Master Nodes should be HA and tainted. +* Consider using a licensed Kubernetes Distribution with a support contract. +* [A default storage class should exist](default-storageclass.md) to support dynamic provisioning of persistent volumes. + +## Service of Type Load Balancer + +Big Bang's default configuration assumes the cluster you're deploying to supports dynamic load balancer provisioning. Specifically, Istio defaults to creating a Kubernetes Service of type Load Balancer, which usually creates an endpoint exposed outside of the cluster that can direct traffic inside the cluster to the istio ingress gateway. + +How Kubernetes service of type LB works depends on implementation details, there are many ways of getting it to work, common methods are listed in the following: + +* CSP API Method (Recommended option for Cloud Deployments): +The Kubernetes Control Plane has a --cloud-provider flag that can be set to aws and/or azure. If the Kubernetes Master Nodes have that flag set and CSP IAM rights. The control plane will auto provision and configure CSP LBs. +**NOTE:** A Vendors Kubernetes Distribution automation, may have IaC/CaC defaults that allow this to work turn key, but if you have issues when provisioning LBs, consult with the Vendor's support for the recommended way of configuring automatic LB provisioning. +* External LB Method (Good for bare metal and 0 IAM rights scenarios): +You can override bigbang's helm values so istio will provision a service of type NodePort instead of type LoadBalancer. Instead of randomly generating from the port range of 30000 - 32768, the NodePorts can be pinned to convention based port numbers like 30080 & 30443. If you're in a restricted cloud env or bare metal, you can ask someone to provision a CSP LB where LB:443 would map to Nodeport:30443 (of every worker node). +* No LB, Network Routing Methods (Good options for bare metal): + * [MetalLB](https://metallb.universe.tf/) + * [kubevip](https://kube-vip.io/) + * [kube-router](https://www.kube-router.io) + +## Big Bang Doesn’t Support Pod Security Policies (PSPs) + +* [PSPs are being removed from Kubernetes and will be gone by version 1.25.x](https://repo1.dso.mil/big-bang/bigbang/-/issues/10) +* [Open Policy Agent Gatekeeper can enforce the same security controls as PSPs](https://github.com/open-policy-agent/gatekeeper-library/tree/master/library/pod-security-policy#pod-security-policies), and is core component of BigBang, which operates as an elevated [validating admission controller](https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/) to audit and enforce various [constraints](https://github.com/open-policy-agent/frameworks/tree/master/constraint) on all requests sent to the kubernetes api server. +* We recommend users disable PSPs completely given they're being removed, we have a replacement, and PSPs can prevent OPA from deploying. If OPA is not able to deploy, nothing else gets deployed. +* Different ways of Disabling PSPs: + * Edit the kube-apiserver's flags; methods for doing this vary per distribution. + + * ```shell + kubectl patch psp system-unrestricted-psp -p '{"metadata": {"annotations":{"seccomp.security.alpha.kubernetes.io/allowedProfileNames": "*"}}}' + kubectl patch psp global-unrestricted-psp -p '{"metadata": {"annotations":{"seccomp.security.alpha.kubernetes.io/allowedProfileNames": "*"}}}' + kubectl patch psp global-restricted-psp -p '{"metadata": {"annotations":{"seccomp.security.alpha.kubernetes.io/allowedProfileNames": "*"}}}' + ``` +* [Kyverno can enforce similar security controls](https://kyverno.io/blog/2023/05/24/podsecuritypolicy-migration-with-kyverno/) + +## Kubernetes Distribution Specific Notes + +* **NOTE:** P1 has forks of various [Kubernetes Distribution Vendor Repos](https://repo1.dso.mil/platform-one/distros), there's nothing special about the P1 forks. +* We recommend you leverage the Vendors upstream docs in addition to any docs found in P1 Repos; in fact, the Vendor's upstream docs are far more likely to be up to date. + +### Kubernetes Version + +It is important to note that while Big Bang does not require/mandate usage of a specific Kubernetes Version, we also do not do extensive testing on every version. Our general stance on Kubernetes versions is provided in the following: +* Big Bang supports any non-EOL Kubernetes version listed under https://kubernetes.io/releases/. +* Big Bang release and CI testing will primarily be done on the `n-1` minor Kubernetes version (i.e. if 1.27.x is latest, we will test on 1.26.x). We will generally keep our testing environments on the latest patch for that minor version. +* New features added by Kubernetes will be kept behind feature gates until all non-EOL versions support those features. + +### VMWare Tanzu Kubernetes Grid + +[Prerequisites section of VMware Kubernetes Distribution Docs](https://repo1.dso.mil/platform-one/distros/vmware/tkg#prerequisites) + +### Cluster API + +**NOTE:** There are some OS hardening and VM Image Build automation tools in here, in addition to Cluster API. +* <https://repo1.dso.mil/platform-one/distros/clusterapi> +* <https://repo1.dso.mil/platform-one/distros/cluster-api/gov-image-builder> + +### OpenShift + +1. When deploying Big Bang, set the OpenShift flag to true. + + ```yaml + # inside a values.yaml being passed to the command installing bigbang + openshift: true + ``` + + ```shell + # OR inline with helm command + helm install bigbang chart --set openshift=true + ``` + +1. Patch the istio-cni daemonset to allow containers to run privileged (AFTER istio-cni daemonset exists). + + Note: it was unsuccessfully attempted to apply this setting via modifications to the helm chart. Online patching succeeded. + + ```shell + kubectl get daemonset istio-cni-node -n kube-system -o json | jq '.spec.template.spec.containers[] += {"securityContext":{"privileged":true}}' | kubectl replace -f - + ``` + +1. Modify the OpenShift cluster(s) with the following scripts based on <https://istio.io/v1.7/docs/setup/platform-setup/openshift/>. + + ```shell + # Istio Openshift configurations Post Install + oc -n istio-system expose svc/public-ingressgateway --port=http2 + oc adm policy add-scc-to-user privileged -z istio-cni -n kube-system + oc adm policy add-scc-to-group privileged system:serviceaccounts:logging + oc adm policy add-scc-to-group anyuid system:serviceaccounts:logging + oc adm policy add-scc-to-group privileged system:serviceaccounts:monitoring + oc adm policy add-scc-to-group anyuid system:serviceaccounts:monitoring + + cat <<\EOF >> NetworkAttachmentDefinition.yaml + apiVersion: "k8s.cni.cncf.io/v1" + kind: NetworkAttachmentDefinition + metadata: + name: istio-cni + EOF + oc -n logging create -f NetworkAttachmentDefinition.yaml + oc -n monitoring create -f NetworkAttachmentDefinition.yaml + ``` + +### Konvoy + +* [Prerequisites can be found here](https://repo1.dso.mil/platform-one/distros/d2iq/konvoy/konvoy/-/tree/master/docs/1.5.0#prerequisites) +* Konvoy clusters need a [Metrics API Endpoint](https://github.com/kubernetes/metrics#resource-metrics-api) available within the cluster to allow Horizontal Pod Autoscalers to correctly fetch pod/deployment metrics. +* [Different Deployment Scenarios have been documented here](https://repo1.dso.mil/platform-one/distros/d2iq/konvoy/konvoy/-/tree/master/docs/1.4.4/install) + +### RKE2 + +* RKE2 turns PSPs on by default (see above for tips on disabling). +* RKE2 sets selinux to enforcing by default ([see os-preconfiguration.md for selinux config](os-preconfiguration.md)). + +Since BigBang makes several assumptions about volume and load balancing provisioning by default, it's vital that the rke2 cluster must be properly configured. The easiest way to do this is through the in tree cloud providers, which can be configured through the `rke2` configuration file such as: + +```yaml +# aws, azure, gcp, etc... +cloud-provider-name: aws + +# additionally, set below configuration for private AWS endpoints, or custom regions such as (T)C2S (us-iso-east-1, us-iso-b-east-1) +cloud-provider-config: ... +``` + +For example, if using the aws terraform modules provided [on repo1](https://repo1.dso.mil/platform-one/distros/rancher-federal/rke2/rke2-aws-terraform), setting the variable: `enable_ccm = true` will ensure all the necessary resources tags. + +In the absence of an in-tree cloud provider (e.g., on-prem), the requirements can be met by ensuring a default storage class and automatic load balancer provisioning exist. diff --git a/docs/prerequisites/minimum-hardware-requirements.md b/docs/prerequisites/minimum-hardware-requirements.md new file mode 100644 index 0000000000000000000000000000000000000000..40f1cd1f5a4eea012139204e7e18e3541b647a97 --- /dev/null +++ b/docs/prerequisites/minimum-hardware-requirements.md @@ -0,0 +1,5 @@ +# Minimum Hardware Requirements + +To calculate the minimum Central Processing Unit (CPU), memory, and disk storage required to run Big Bang, open the [minimum hardware requirements Excel spreadsheet](./minimum-hardware-requirements.xlsx) and follow the instructions there. This will allow you to select exactly which packages and pods are enabled. In addition, it includes extra considerations to help you with sizing your cluster. The final values will be for the entire cluster and can be split between multiple nodes. + +When running across multiple availability zones, keep in mind that some of your nodes may be down for zone maintenance and the remaining nodes need to be able to handle the CPU, memory, and disk space for your cluster. diff --git a/docs/prerequisites/minimum-hardware-requirements.xlsx b/docs/prerequisites/minimum-hardware-requirements.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..ebd2f2a25b7662aee2c778cd7cf6122d48883a50 Binary files /dev/null and b/docs/prerequisites/minimum-hardware-requirements.xlsx differ diff --git a/docs/prerequisites/os-preconfiguration.md b/docs/prerequisites/os-preconfiguration.md new file mode 100644 index 0000000000000000000000000000000000000000..2a000d2d382f30c2151c6b6e0adb07366be05557 --- /dev/null +++ b/docs/prerequisites/os-preconfiguration.md @@ -0,0 +1,93 @@ +# OS Configuration Pre-Requisites + +## Disable Swap (Kubernetes Best Practice) + +1. Identify configured swap devices and files with cat /proc/swaps. +2. Turn off all swap devices and files with swapoff -a. +3. Remove any matching reference found in /etc/fstab. +(Credit: Above copy pasted from Aaron Copley of [Serverfault.com](https://serverfault.com/questions/684771/best-way-to-disable-swap-in-linux)) + +## ECK Specific Configuration (ECK Is a Core BB App) + +Elastic Cloud on Kubernetes (i.e., Elasticsearch Operator) deployed by Big Bang uses memory mapping by default. In most cases, the default address space is too low and must be configured. +To ensure unnecessary privileged escalation containers are not used, these kernel settings should be applied before BigB ang is deployed: + +```shell +sudo sysctl -w vm.max_map_count=262144 #(ECK crash loops without this) +``` +To verify that this setting is in place and check the current value, after Big Bang deployment run the following command: +```shell +kubectl exec $(kubectl get pod -n eck-operator -l app.kubernetes.io/name=elastic-operator -o name) --namespace eck-operator -it -- cat /proc/sys/vm/max_map_count +``` +This should return 262144 (or higher) + + +More information can be found from elasticsearch's documentation [here](https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-virtual-memory.html#k8s-virtual-memory) + +### AKS Configuration + +Ensure this block is present in the terraform configuration for the `azurerm_kubernetes_cluster_node_pool` resource section for your AKS cluster: + +```yaml +linux_os_config { + sysctl_config { + vm_max_map_count = 262144 + } +} +``` + +## SELinux Specific Configuration + +* If SELinux is enabled and the OS hasn't received additional pre-configuration, then users will see istio init-container crash loop. +* Depending on security requirements it may be possible to set selinux in permissive mode: `sudo setenforce 0`. +* Additional OS and Kubernetes specific configuration are required for istio to work on systems with selinux set to `Enforcing`. + +By default, Big Bang will deploy istio configured to use `istio-init` (read more [here](https://istio.io/latest/docs/setup/additional-setup/cni/)). To ensure istio can properly initialize envoy sidecars without container privileged escalation permissions, several system kernel modules must be pre-loaded before installing BigBang: + +```shell +modprobe xt_REDIRECT +modprobe xt_owner +modprobe xt_statistic +``` + +## Sonarqube Specific Configuration (Sonarqube Is a BB Addon App) + +Sonarqube requires the following kernel configurations set at the node level: + +```shell +sysctl -w vm.max_map_count=524288 +sysctl -w fs.file-max=131072 +ulimit -n 131072 +ulimit -u 8192 +``` +To verify these settings are in place (or check current values) run the following command: + +```shell +kubectl exec $(kubectl get pod -n sonarqube -l app=sonarqube -o name) --namespace sonarqube -it -- cat /proc/sys/vm/max_map_count + +This should return 524288 (or higher) + +kubectl exec $(kubectl get pod -n sonarqube -l app=sonarqube -o name) --namespace sonarqube -it -- cat /proc/sys/fs/file-max + +This should return 131072 (or higher) + +kubectl exec $(kubectl get pod -n sonarqube -l app=sonarqube -o name) --namespace sonarqube -it -- ulimit -n + +This should return 131072 (or higher) + +kubectl exec $(kubectl get pod -n sonarqube -l app=sonarqube -o name) --namespace sonarqube -it -- ulimit -u + +This should return 8192 (or higher) +``` + +Another option includes running the init container to modify the kernel values on the host (this requires a busybox container run as root): + +```yaml +addons: + sonarqube: + values: + initSysctl: + enabled: true +``` + +**This is not the recommended solution as it requires running an init container as privileged.** diff --git a/docs/training/training.md b/docs/training/training.md new file mode 100644 index 0000000000000000000000000000000000000000..760fe98995aa7f7401a7d5c5e3d4d5edaa90426f --- /dev/null +++ b/docs/training/training.md @@ -0,0 +1,3 @@ +# Big Bang User Training + +This page is under construction. diff --git a/docs/understanding-bigbang/.pages b/docs/understanding-bigbang/.pages new file mode 100644 index 0000000000000000000000000000000000000000..a3c60612f5b03c14984478290a5cb4261400ee73 --- /dev/null +++ b/docs/understanding-bigbang/.pages @@ -0,0 +1,7 @@ +nav: + - Overview: README.md + - Licensing Model: licensing-model.md + - Configuration: configuration + - Concepts: concepts + - Package Architecture: package-architecture + - Architecture Diagrams: architecture-diagrams \ No newline at end of file diff --git a/docs/understanding-bigbang/README.md b/docs/understanding-bigbang/README.md new file mode 100644 index 0000000000000000000000000000000000000000..1b88205c5b60d0f0a8c25d3e05a8f51b63349e57 --- /dev/null +++ b/docs/understanding-bigbang/README.md @@ -0,0 +1,45 @@ +# Useful Background Contextual Information + +Start with the [Documentation README](../README.md), which includes the following sections: + +* [What is Big Bang?](../README.md#what-is-big-bang) +* [What *isn't* Big Bang?](../README.md#what-big-bang-isnt) +* [Benefits of Big Bang](../README.md#benefits-of-using-big-bang) + +## Acronyms + +* **CSP**: Cloud Service Provider +* **L4 LB**: Layer 4 Load Balancer +* **KMS**: Key Management System/Encryption as a Service (AWS/GCP KMS, Azure Key Vault, HashiCorp Transient Secret Engine) +* **PGP**: Pretty Good Privacy (Asymmetric Encryption Key Pair, where public key is used to encrypt, private key used to decrypt) +* **SOPS**: "Secret Operations" CLI tool by Mozilla, leverages KMS or PGP to encrypt secrets in a Git Repo. (Flux and P1's modified ArgoCD can use SOPS to decrypt secrets stored in a Git Repo.) +* **ATO**: Authority to Operate +* **cATO**: continuous Authority to Operate +* **AO**: Authorizing Official (Government Official who determines OS and Kubernetes Cluster hardening requirements, that result in a level of acceptable remaining risk that they're willing to sign off on for a Kubernetes Cluster to receive an ATO, and a BigBang Cluster to receive a cATO) +* **IaC**: Infrastructure as Code +* **CaC**: Configuration as Code +* **CAC**: Common Access Card + +## Prerequisites + +* Prerequisites vary depending on deployment scenario. [Prerequisites can be found here.](../prerequisites/) + +## Additional Useful Background Contextual Information + +* Big Bang utilizes Documents as Code stored in the main [Big Bang Repo](https://repo1.dso.mil/big-bang/bigbang/docs). For a better experience, the documentation can also be found on the [Big Bang Documentation Website](https://docs-bigbang.dso.mil). + * All locations use the same source code and will include pointers between them. +* There are multiple implementations of Helm Charts (Helm repositories, `.tgz`, and files and folders in a git repo), whenever Platform One refers to a helm chart, it always referring to the files and folders in a git repo implementation, which is stored in the `/chart` folder within a git repo. +* Additional pre-reading materials to develop a better understanding of Big Bang before deploying can be found in this `understanding_bigbang` section. +* If you see an issue with docs or packages, please [open an issue against the main Big Bang Repo](https://repo1.dso.mil/big-bang/bigbang/-/issues), instead of the individual package repo. + +## Note about Snippets of Architecture Diagrams in this folder + +* The intent of sharing Architecture Diagrams is to: + * Act as a starting point upon which further understanding can be built. + * Improve a users understanding of how Big Bang components fit together. + * Provide insight on what it would take to modify components or workflows to fit specific use cases. + * Show potential use cases for some of BigBang's core components. +* These Architecture Diagrams are NOT intended to: + * Reflect an accurate default configuration. + * Prescriptively show the only possible solution of a Big Bang deployment +* These Architecture Diagrams should be taken with a grain of salt; it's difficult to make a generic diagram with high accuracy. Big Bang's Helm Values are variables, some values can produce significantly different workflows. Nuances specific to the deployment environment and hardened configurations like SELinux & Istio CNI can slightly effect parts of implementation details. diff --git a/docs/understanding-bigbang/architecture-diagrams/.pages b/docs/understanding-bigbang/architecture-diagrams/.pages new file mode 100644 index 0000000000000000000000000000000000000000..4a12957c88429873415dd6b3e740c394ef708e99 --- /dev/null +++ b/docs/understanding-bigbang/architecture-diagrams/.pages @@ -0,0 +1,5 @@ +nav: + - Kube API Server Webhooks: kube-apiserver-webhooks-diagram.md + - Logs Data Flow: logs-data-flow-diagram.md + - Metrics Data Flow: metrics-data-flow-diagram.md + - Network Encryption and Ingress: network-encryption-and-ingress-diagram.md \ No newline at end of file diff --git a/docs/understanding-bigbang/architecture-diagrams/kube-apiserver-webhooks-diagram.md b/docs/understanding-bigbang/architecture-diagrams/kube-apiserver-webhooks-diagram.md new file mode 100644 index 0000000000000000000000000000000000000000..30455c203c30070fb6461baf103ecb25508ca124 --- /dev/null +++ b/docs/understanding-bigbang/architecture-diagrams/kube-apiserver-webhooks-diagram.md @@ -0,0 +1,37 @@ +# Goals of this Architecture Diagram + +* Help new users understand how BigBang extends the kube-apiserver using webhooks to enable: + * Best practice security controls + * Abstractions that improve user experience for developers / maintainability +* Kubernetes Security Best Practice (per [kube-bench](https://github.com/aquasecurity/kube-bench)) for requests to the kube-apiserver is that requests should go through the following flow of controls: + 1. mTLS Authentication via x509 certs: + * This is baked into Kubernetes + 1. RBAC Authorization of users and Node Authentication for worker nodes + * `--authorization-mode=Node,RBAC` flag on kube-apiserver ensures this is set. + * Deployed applications contain YAML manifests with rbac rules to minimize the rights of the application's service account. + 1. Admission Controllers: These take effect after Authn and Authz have occurred and allow the functionality of the api-server to be extended to enable additional security controls and advanced features. + * There are apiserver plugins baked into Kubernetes that just need to be turned on like `--enable-admission-plugins=NodeRestriction` per kube-bench. + * There's also webhooks that allow extending the apiserver with custom logic, this will be overviewed in the diagram below. + +## BigBang Kubernetes API Server Webhooks Diagram + +![kube-apiserver_webhooks_diagram.app.diagrams.net.png](../../assets/imgs/understanding-bigbang/kube-apiserver-webhooks-diagram.app.diagrams.net.png) + +### Notes + +#### 1. Git Repo + +* Can be HTTPS or SSH based, can exist on the Internet or in Private IP Space +* Airgap deployments are recommended to use SSH based Git Repo in Private IP Space +* Argo CD / Flux CD need network connectivity to and in most cases read only credentials to view the contents of the git repo. + +#### 2. Mutating Admission Controllers + +* This improves user experience for developers. If a namespace is labeled `istio-injection=enabled`, then a developer can submit a YAML manifest where the pod only needs to reference 1 container image/the application. After the request is authenticated and authorized against the kube-apiserver, it's admission controller will see a mutating admission webhook exists and the manifest will be sent to the `istiod` pod in the `istio-system` namespace to mutate the manifest and inject an Istio init container and Istio envoy proxy sidecar container into the YAML manifest. This allows the developer's pod to be integrated into the service mesh with minimal configuration / effort on their part/no adjustments to their YAMLs were needed. +* Note: It's possible to use Istio CNI Plugin to eliminate the need for Istio Init Containers. + +#### 3. Validating Admission Controllers + +* As of BigBang >= 2.0.0 Kyerno is used instead of Gatekeeper. See [Kyverno overview](../package-architecture/kyverno.md) +* As of BigBang 1.7.0 OPA GK defaults to dry-run/warn and not blocking/enforcing mode, [there are plans to change the default behavior to blocking/enforcing mode.](https://repo1.dso.mil/big-bang/bigbang/-/issues/468) +* OPA GK can enforce security policy such as only allowing whitelisted container registries, PodSecurityPolicies equivalent functionality, and more. diff --git a/docs/understanding-bigbang/architecture-diagrams/logs-data-flow-diagram.md b/docs/understanding-bigbang/architecture-diagrams/logs-data-flow-diagram.md new file mode 100644 index 0000000000000000000000000000000000000000..1037410aa3a78174434f3b3cad034960f94214f6 --- /dev/null +++ b/docs/understanding-bigbang/architecture-diagrams/logs-data-flow-diagram.md @@ -0,0 +1,17 @@ +# Goals of this Diagram + +* Help new users understand the data flow of pod logs + +## Kubernetes Pod Logs Data Flow Diagram + +![logs_data_flow_diagram.app.diagrams.net.png](../../assets/imgs/understanding-bigbang/logs-data-flow-diagram.app.diagrams.net.png) + +| Line Number | Protocol | Port | Description | +| --- | --- | --- | --- | +| N1 | Volume Mount | NA | Fluent Bit reads pod logs from a host node volume mount | +| N2 | HTTPS | TCP:9200 | Fluent Bit sends logs to Elastic Search over the URL: <https://logging-ek-es-http:9200> (This URL is only exposed over the Kubernetes Inner Cluster Network, and because Fluent Bit and ElasticSearch have Istio Envoy Proxy sidecar containers the network traffic is protected by the service mesh.) | + +## Notes + +1. The Fluent Bit log shipper is configured to send pod logs to the ElasticSearch Cluster in the logstash data format. Logstash_Format On +2. By default: The log index logstash-%Y.%m.%d will create a new log index everyday, because %d will increment by one everyday. There are no default Index Lifecycle Management Policies that are created or applied to these indexes. It is recommended that customers create a Index Lifecycle policy to prevent disk space from filling up. (Example: Archive to s3 and then delete from PVC logs older than N days.) diff --git a/docs/understanding-bigbang/architecture-diagrams/metrics-data-flow-diagram.md b/docs/understanding-bigbang/architecture-diagrams/metrics-data-flow-diagram.md new file mode 100644 index 0000000000000000000000000000000000000000..590ec947f3b9bf86acc2bca15141f130669c456f --- /dev/null +++ b/docs/understanding-bigbang/architecture-diagrams/metrics-data-flow-diagram.md @@ -0,0 +1,11 @@ +# Goals of this Diagram + +* Help new users understand the data flow of prometheus metrics + +## Prometheus Metrics Data Flow Diagram + +![metrics_data_flow_diagram.app.diagrams.net.png](../../assets/imgs/understanding-bigbang/metrics-data-flow-diagram.app.diagrams.net.png) + +| Line Number | Protocol | Port | Description | +| --- | --- | --- | --- | +| N1 | HTTP | varies* | *A standard port number for prometheus metric endpoint URLs doesn't exist. The Prometheus Operator is able to use ServiceMonitors and Kubernetes Services to automatically discover IP addresses of pods and these varying prometheus metric endpoint ports. Once a minute the prometheus Operator dynamically regenerates a metric collection config file that the Prometheus Server continuously uses to collect metrics. In the majority of cases prometheus metric endpoints, are read over HTTP, and are only reachable over the Kubernetes Inner Cluster Network. | diff --git a/docs/understanding-bigbang/architecture-diagrams/network-encryption-and-ingress-diagram.md b/docs/understanding-bigbang/architecture-diagrams/network-encryption-and-ingress-diagram.md new file mode 100644 index 0000000000000000000000000000000000000000..2dc71415680b11bd0f465229ef7896fecdf04bac --- /dev/null +++ b/docs/understanding-bigbang/architecture-diagrams/network-encryption-and-ingress-diagram.md @@ -0,0 +1,77 @@ +# Goals of this Architecture Diagram + +* Help new users better understand: + * That the CNI component of Kubernetes creates an Inner Cluster Network. + * Kubernetes Ingress (How network traffic flows from LAN to Inner Cluster Network) + * How Big Bang is leveraging Istio Operator + * Network Encryption in the context of Big Bang (HTTPS, mTLS, and spots where Network Encryption is not present by default.) + +## Big Bang Network Ingress Diagram + +![network_encryption_and_ingress_diagram.app.diagrams.net.png](../../assets/imgs/understanding-bigbang/network-encryption-and-ingress-diagram.app.diagrams.net.png) + +### Notes + +#### 1. CNAP (Cloud Native Access Point) or Equivalent + +* CNAP is a P1 service offering separate from Big Bang, that bundles several technologies together: Palo Alto Firewall, AppGate Software Defined Perimeter, and P1's Keycloak Implementation which has a plugin baked in that allows SSO using Common Access Cards, by leveraging the x509 certs/PKI associated with the cards and DoD CAs as an federated identity provider. +* CNAP is basically an advanced edge firewall that can do many things. In terms of Network Encryption it can act as a trusted MITM (Terminating HTTPS, inspecting the decrypted traffic for WAF (Web Application Firewall) protection purposes, and then re-encrypting traffic before forwarding to it's intended destination (usually a private IP Address of an Ingress LB of a Big Bang Cluster.) +* More details on CNAP can be found on the [Ask Me Anything Slides located here](https://software.af.mil/dsop/documents/). +* If your DoD command is interested in leveraging CNAP to protect a Big Bang Cluster [this page has instructions on how to ask for more details.](https://p1.dso.mil/#/services) +* `There is no hard requirement that consumers of Big Bang must leverage CNAP`. + * P1 uses CNAP to add defense in depth security for many of it's public internet facing services. + * A consumer of Big Bang can decide not to use CNAP if their AO allows; which could be due to: risk acceptance, alternatives, other compensating controls / circumstances like: users only connecting through trusted networks like NIPRNet, airgap, etc. that are accessed via bastion, VPN, VDI, etc. + +#### 2. Ingress LB Provisioning Logic + +* If an admin runs the following command against a Big Bang Cluster `kubectl get istiooperator -n=istio-system -o yaml`, they will see that this CR (custom resource) has a YAML array / list of Ingress Gateways. +* Each Ingress Gateway in the list will (by default) spawn: + * A Kubernetes Service of type Load Balancer, which spawns a CSP LB. + * A Kubernetes Deployment of pods acting as an Istio Ingress Gateway. +* A Big Bang Cluster can end up with more than 1 LB if the list (in the istiooperator CR) contains multiple Ingress Gateways OR if there is more than 1 istiooperator CR (which could contain it's own additional list of Ingress Gateways). (The easy creation of multiple Ingress Gateways was added to Big Bang's helm values, in v1.13.0) +* A Production Deployment of Big Bang should (in most cases): + * Set the Big Bang values.yaml file to leverage Kubernetes service annotations to ensure the provisioned CSP LBs are provisioned with Private IP Addresses. + * Separate traffic destined for admin management GUIs from user facing applications. + * One way of doing this is to edit the helm values to create multiple Ingress Gateways (which would create multiple CSP LBs) and map admin management GUIs to a LB for admins to access, and user services to a LB for users to access. Then a firewall / network access control list could be used to limit traffic to the admin management GUI's CSP LB as a KISS solution. + * Another way is to have user and admin traffic enter the cluster via the same CSP LB, and use Big Bang's Auth Service SSO Proxy to filter webpage access based on a user's group membership defined by the backend identity provider. + * Combining both of these is an additional option if defense in depth is desired. + +#### 3. Network Ingress Traffic Flow + +1. Port 443 of the CSP LB gets load balanced between a NodePort of the Kubernetes Nodes. (The NodePort can be randomly generated or static, depending on helm values.) +2. Kube Proxy (in most cases) is responsible for mapping/forwarding traffic from the NodePort, which is accessible on the Private IP Space Network, to port 443 of the istio-ingressgateway service which is accessible on the Kubernetes Inner Cluster Network. (So Kube Proxy and Node Ports are how traffic crosses the boundary from Private IP Space to Kubernetes Inner Cluster Network Space.) +3. Istio-ingressgateway service port 443 then maps to port 8443 of istio-ingressgateway pods associated with the deployment (they use the non-privileged port 8443, because they've gone through the IronBank Container hardening process. (From the end users perspective the end user only sees 443, and an http --> https redirect is also configured.) +4. The Istio Ingress Gateway pods are basically Envoy Proxies / Layer 7 Load Balancers that are dynamically configured using declarative Kubernetes Custom Resources managed via GitOps. These Ingress Gateway pods terminate HTTPS (in most cases) and then forward traffic to web services hosted in a Big Bang Cluster. + +#### 4. Ingress HTTPS Certificates + +* A Gateway CR will reference a HTTPS Certificate stored in a Kubernetes secret of type TLS. +* Some environments will mandate 1 HTTPS Certificate per DNS name. In this scenario you'll need 1 gateway CR and secret of type TLS for each virtual service. +* In order for Ingress to work correctly DNS names must match in 4 places: + 1. DNS needs to point to the correct CSP Ingress LB + 2. DNS name associated with HTTPS Certificate in a Kubernetes Secret of type TLS + 3. DNS name referenced in Virtual Service CR + 4. DNS name referenced in Gateway CR +* Additionally if Big Bang is configured to leverage multiple Ingress Gateways the Virtual Service CR much reference the correct Gateway CR and the Gateway CR must reference the correct HTTPS cert in a Kubernetes Secret of type TLS. + +#### 5. Network Encryption of Ingress Traffic + +* Traffic from the user through a CSP Layer 4/TCP LB to the Istio Ingress Gateway pods is encrypted in transit in 100% of cases per default settings. +* Usually HTTPS is terminated at the Istio Ingress Gateway, using an HTTPS Certificate embedded in a Kubernetes secret of type TLS. +* One exception is if the Keycloak addon is enabled then the gateway CR is configured to have traffic destined for the Keycloak DNS name to leverage TLS Passthrough, and the Keycloak pod terminates the HTTPS connection. + +#### 6. Network Encryption of Node to Node Traffic + +* CNIs (Container Network Interfaces) create Inner Cluster Networks that allow pods and services to talk to each other and usually set up network routing rules/filters that make it so external traffic can only initiate a connection to by going through explicitly opened NodePorts. +* Different CNIs create an Inner Cluster Network in different ways. Some CNIs uses BGP. Others make use of VXLANs. +* Some CNIs support encrypting 100% of the CNI traffic and others don't. +* Installation and configuration of CNI is outside the scope of Big Bang and is considered a prerequisite, consult with your AO to determine their requirements for encryption of traffic in transit. + +#### 7. Network Encryption of Traffic on the Inner Cluster Network + +* HTTPS for Ingress Traffic is terminated at the Istio Ingress Gateway, but network encryption from the Istio Ingress Gateway to the final destination can vary depending on if they're integrated into the service mesh or not. +* If the app is part of the service mesh (which can usually be seen by checking if the namespace is labeled istio-injection=enabled and verifying an istio-proxy sidecar container exists), then it's using mTLS or HTTPS (in the case of ElasticSearch, which is done for compatibility). +* If the app isn't part of the service mesh (which as of Big Bang 1.8.0 is the case for Grafana, Prometheus, and AlertManager) then traffic from the Istio Ingress Gateway to the destination pod won't be encrypted, unless the application provides it's own encryption like in the case of Keycloak and Twistlock. +* Kubernetes Operators have their own built in HTTPS. +* Kubernetes Control Plane Components have built in mTLS. +* CoreDNS that ships with Kubernetes doesn't leverage encrypted DNS. diff --git a/docs/understanding-bigbang/concepts/deployment.md b/docs/understanding-bigbang/concepts/deployment.md new file mode 100644 index 0000000000000000000000000000000000000000..68f490498e375fce9c3beb87eb23ea3e97a8167c --- /dev/null +++ b/docs/understanding-bigbang/concepts/deployment.md @@ -0,0 +1,193 @@ +# Deployment + +[[_TOC_]] + +## GitOps + +Big Bang follows a [GitOps](https://www.weave.works/blog/what-is-gitops-really) approach to deployment. All configuration changes will be pulled and reconciled with what is stored in the Git repository. The only exception to this is the initial manifests (e.g., `dev.yaml`) which points to the Git repository and path. + +## Installation + +1. Before pushing changes to Git, validate all configuration is syntactically correct. + + ```shell + # If everything is successful, YAML should be output + kustomize build ./dev + ``` + +1. If you have not already done so, push configuration changes to Git. + + ```shell + git push + ``` + +1. Validate the Kubernetes context is correct. + + ```shell + # This should match the environment you intend to deploy + kubectl config current-context + ``` + +1. Deploy the Big Bang manifest to the cluster. + + ```shell + kubectl apply -f dev.yaml + ``` + +1. [Monitor the deployment](#monitor). + +## Upgrade + +All changes to the Big Bang cluster should be made through Git. After changes are pushed, Big Bang will automatically reconcile the difference with the cluster. + +> It may take Big Bang up to 10 minutes to recognize your changes and start to deploy them. This is based on the `interval` value set for polling. You can force Big Bang to immediately check for changes by running the [sync.sh](../../..//scripts/sync.sh) script. + +Changes to values can be tested in each environment using the named folders to override values and/or point to specific repo branches or tags. After testing, the changes can be placed into the `./base` folder if the change is shared between all environments. + +## Monitor + +The commands detailed in this section will help you monitor the progress of the Big Bang deployment. Review the [flowchart](./glossary.md#Diagram), if needed, to understand the progression. Use the [Troubleshooting Guide](./troubleshooting.md) if you have failures. + +1. Verify Flux is running. + + ```shell + kubectl get deploy -n flux-system + + # All resources should be in the 'Ready' state + NAME READY UP-TO-DATE AVAILABLE AGE + source-controller 1/1 1 1 106s + kustomize-controller 1/1 1 1 106s + notification-controller 1/1 1 1 105s + helm-controller 1/1 1 1 106s + ``` + +1. Verify the environment was pulled from the Git repo. + + ```shell + kubectl get gitrepository -A + + # `environment-repo`: STATUS should be True + NAMESPACE NAME URL READY STATUS AGE + bigbang environment-repo https://repo1.dso.mil/big-bang/customers/template.git True Fetched revision: main/185e252f4452d897531ab0314adc7a189562be31 2m7s + ``` + +1. Verify the environment Kustomization properly worked. + + ```shell + kubectl get kustomizations -A + + # `environment`: READY should be True + NAMESPACE NAME READY STATUS AGE + bigbang environment True Applied revision: main/185e252f4452d897531ab0314adc7a189562be31 6m41s + ``` + +1. Verify the ConfigMaps were deployed. + + ```shell + kubectl get configmap -l kustomize.toolkit.fluxcd.io/namespace -A + + # 'common' and 'environment' should exist + NAMESPACE NAME DATA AGE + bigbang common-cch6942dk9 1 19m + bigbang environment-d2tgb27f56 1 19m + ``` + +1. Verify the Secrets were deployed. + + ```shell + kubectl get secrets -l kustomize.toolkit.fluxcd.io/namespace -A + + # 'common-bb' and 'environment-bb' should exist + NAMESPACE NAME TYPE DATA AGE + bigbang common-bb-kc5t8dbdfh Opaque 1 18m + bigbang environment-bb-mhddkt46bd Opaque 1 18m + ``` + +1. Verify the Big Bang Helm Chart was pulled. + + ```shell + kubectl get gitrepositories -A + + # 'bigbang' READY should be True + NAME URL READY STATUS AGE + bigbang https://repo1.dso.mil/big-bang/bigbang.git True Fetched revision: master/8a4a1ddd0c9edf316f5362680cf2921baf0c3451 25m + ``` + +1. Verify the Big Bang Helm Chart was deployed. + + ```shell + kubectl get hr -A + + # 'bigbang' READY should be True + NAMESPACE NAME READY STATUS AGE + bigbang bigbang True Release reconciliation succeeded 28m + ``` + +1. Verify Big Bang package Helm charts are pulled. + + ```shell + kubectl get gitrepository -A + + # The Git repository holding the Helm charts for each package can be seen in the URL column. + # The STATUS column shows the branch and tag of the revision being used. + NAMESPACE NAME URL READY STATUS AGE + bigbang bigbang https://repo1.dso.mil/big-bang/bigbang.git True Fetched revision: master/3a44686520152e576a8c2c6f264876efff497c4b 8m25s + bigbang logging https://repo1.dso.mil/big-bang/product/packages/logging.git True Fetched revision: release-v0.2.x/9cfe1e14c12098464ee89eb877614f781cd78fb7 8m23s + bigbang certmanager https://repo1.dso.mil/big-bang/product/packages/cert-manager.git True Fetched revision: release-v1.0.x/1247135baf145dcfad4a4a02ef679c48fb76d9fb 8m23s + bigbang istio https://repo1.dso.mil/big-bang/product/packages/servicemesh.git True Fetched revision: chart-release/2b02a51b7950ce21bac26403fa25d09e7e3f86c3 8m23s + bigbang twistlock https://repo1.dso.mil/big-bang/product/packages/twistlock.git True Fetched revision: chart-release/faf038197291915713e0f213a4e35991e72f73f6 8m23s + bigbang gatekeeper https://repo1.dso.mil/big-bang/product/packages/policy.git True Fetched revision: chart-release/1a5f32c8e7f672c3b5937b604e5f38eaa08ce246 8m23s + bigbang monitoring https://repo1.dso.mil/big-bang/product/packages/monitoring.git True Fetched revision: release-v0.2.x/ca60bedcc106b95beb0bf9ccdc6e0e759e6fd6bf 8m23s + bigbang cluster-auditor https://repo1.dso.mil/big-bang/product/packages/cluster-auditor.git True Fetched revision: chart-release/598c35670db0cbdb3a48063b2d558965afe73185 8m23s + ``` + +1. Verify the packages get deployed. + + ```shell + # Use watch since it take a long time to deploy + watch kubectl get hr,deployments,po -A + + # Flux will not attempt to deploy a package until its dependencies are ready + # All Helm Release resources and Pods + Every 2.0s: kubectl get hr,deployments,po -A localhost: Mon Nov 9 10:14:56 2020 + + NAMESPACE NAME READY STATUS AGE + bigbang helmrelease.helm.toolkit.fluxcd.io/bigbang True Release reconciliation succeeded 64s + bigbang helmrelease.helm.toolkit.fluxcd.io/gatekeeper True Release reconciliation succeeded 62s + bigbang helmrelease.helm.toolkit.fluxcd.io/eck-operator False dependency 'bigbang/gatekeeper' is not ready 62s + bigbang helmrelease.helm.toolkit.fluxcd.io/istio-operator Unknown Reconciliation in progress 62s + bigbang helmrelease.helm.toolkit.fluxcd.io/istio False dependency 'bigbang/istio-operator' is not ready 62s + bigbang helmrelease.helm.toolkit.fluxcd.io/efk False dependency 'bigbang/eck-operator' is not ready 62s + bigbang helmrelease.helm.toolkit.fluxcd.io/logging-operator False dependency 'bigbang/gatekeeper' is not ready 62s + bigbang helmrelease.helm.toolkit.fluxcd.io/twistlock False dependency 'bigbang/gatekeeper' is not ready 62s + bigbang helmrelease.helm.toolkit.fluxcd.io/cluster-auditor-policies False dependency 'bigbang/gatekeeper' is not ready 62s + bigbang helmrelease.helm.toolkit.fluxcd.io/cluster-auditor False dependency 'bigbang/gatekeeper' is not ready 62s + bigbang helmrelease.helm.toolkit.fluxcd.io/certmanager True Release reconciliation succeeded 62s + bigbang helmrelease.helm.toolkit.fluxcd.io/monitoring False dependency 'bigbang/gatekeeper' is not ready 62s + + NAMESPACE NAME READY UP-TO-DATE AVAILABLE AGE + kube-system deployment.apps/local-path-provisioner 1/1 1 1 4m48s + kube-system deployment.product/packagesdns 1/1 1 1 4m48s + flux-system deployment.apps/helm-controller 1/1 1 1 4m6s + flux-system deployment.apps/notification-controller 1/1 1 1 4m6s + flux-system deployment.apps/source-controller 1/1 1 1 4m7s + flux-system deployment.apps/kustomize-controller 1/1 1 1 4m7s + gatekeeper-system deployment.apps/gatekeeper-controller-manager 1/1 1 1 2m8s + gatekeeper-system deployment.apps/gatekeeper-audit 1/1 1 1 2m8s + istio-operator deployment.apps/istio-operator 0/1 1 0 8s + + NAMESPACE NAME READY STATUS RESTARTS AGE + kube-system pod/local-path-provisioner-6d59f47c7-s6rln 1/1 Running 0 4m36s + kube-system pod/coredns-7944c66d8d-flk4p 1/1 Running 0 4m36s + flux-system pod/helm-controller-578cdbcd8b-tjzs7 1/1 Running 0 4m6s + flux-system pod/notification-controller-7c59d85f77-92ckv 1/1 Running 0 4m6s + flux-system pod/source-controller-7d6f889df9-f888j 1/1 Running 0 4m7s + flux-system pod/kustomize-controller-5cfb78859c-n85xn 1/1 Running 0 4m6s + gatekeeper-system pod/gatekeeper-controller-manager-5b9cf6c85d-cqd8t 1/1 Running 0 2m8s + gatekeeper-system pod/gatekeeper-audit-7db49c54d5-pwzwh 1/1 Running 0 2m8s + istio-operator pod/istio-operator-79f966cfc-rjhhc 0/1 ContainerCreating 0 8s + ``` + +1. Wait until all Helm Releases, Deployments, and Pods are ready. Be patient, this can take 15-30 minutes. + + > The Git repositories are monitored periodically (default is 10m) for changes. If a change is detected, the configuration will be reconciled using Flux. The monitoring techniques above can be used to monitor the reconciliation. diff --git a/docs/understanding-bigbang/concepts/encryption.md b/docs/understanding-bigbang/concepts/encryption.md new file mode 100644 index 0000000000000000000000000000000000000000..966b889f14fe3ddea02b7a3f3ed8e239e150e576 --- /dev/null +++ b/docs/understanding-bigbang/concepts/encryption.md @@ -0,0 +1,202 @@ +# Encryption + +[[_TOC_]] + +Big Bang follows a [GitOps](https://www.weave.works/technologies/gitops/) approach to managing the Big Bang Kubernetes cluster configuration. Using GitOps, we must securely store secrets in Git using encryption. The private key, which is stored in key storage, is used by the continuous deployment tool to decrypt and deploy the secrets for use in the cluster. + +## SOPS + +[Secrets Operations (SOPS)](https://github.com/mozilla/sops) is used to securely encrypt values in YAML, JSON, ENV, INI and BINARY formats. Secrets, such as pull credentials or certificates, should be encrypted with SOPS prior to committing into a Git repository. + +> The private key used in SOPS should **NEVER** be stored in Git along side the encrypted secrets. + +SOPS supports the ability to [add multiple keys](https://dev.to/stack-labs/manage-your-secrets-in-git-with-sops-common-operations-118g) to the same file so multiple key pairs can use the same secret. This is useful for environments which may have different keys, but use the same secrets. For each key used, SOPS writes the public key, used to encrypt, and an encrypted copy of the data to the file. Decryption requires use of one of the private keys used. After editing, the embedded public keys are used to re-encrypt the file for all key pairs. + +## Create Encryption Keys + +To set up Big Bang with SOPS, a key pair must be created. The private key is used for decryption and must be securely stored but accessible to the cluster. The public key is used for encryption. Follow the appropriate instructions provided below to create your key pair. + +| Key Management | Key Pair Instructions | Notes | +|--|--|--| +| [GNU Privacy Guard (GPG)*](https://gnupg.org/) | `gpg --full-generate-key` | Use `key type` = `RSA and RSA`, `keysize` = `4096`, `expiration` = `0` | +| [Amazon Web Services (AWS) Key Management Service (KMS)](https://aws.amazon.com/kms/) | [Link](https://github.com/mozilla/sops#2usage) | [Advanced setup help](https://github.com/mozilla/sops#26kms-aws-profiles) (e.g. roles, profiles, contexts) +| [Google Cloud Platform (GCP) Key Management Service (KMS)](https://cloud.google.com/security-key-management) | [Link](https://github.com/mozilla/sops#encrypting-using-gcp-kms) | +| [HashiCorp Vault](https://www.vaultproject.io/) | [Link](https://github.com/mozilla/sops#23encrypting-using-azure-key-vault) | + +> GPG is not recommended for production use because the private key can be misplaced or compromised too easily. + +## Configure SOPS + +SOPS uses `.sops.yaml` as a configuration file for which keys to use for newly created files. Once a file is created, the key fingerprints are stored in the file and must be re-keyed to use any changes to `.sops.yaml`. + +1. Follow the [SOPS instructions](https://github.com/mozilla/sops#210using-sopsyaml-conf-to-select-kmspgp-for-new-files) to configure `.sops.yaml` based on the encryption method you used. Multiple keys of the same type can be added using the block scalar yaml construct, `>-`, and separating them by a comma and newline. + + > If you are using the Big Bang sample files, make sure to remove the development Big Bang key. + +2. Add the following regex to only encrypt data in the yaml files: + + ```yaml + creation_rules: + - encrypted_regex: "^(data|stringData)$" + ``` + +3. Save `.sops.yaml` in the root of folder of your configuration. +4. If you have existing secrets, use the following to re-key them with the configuration in `.sops.yaml`. + + ```shell + # You must have the old private key to rekey the file + sops updatekeys <encrypted file> + ``` + +## Deploy Private Key + +> This must be completed before deploying Big Bang or else deploying secrets will fail. + +### GPG + +1. Deploy your SOPS private key to a secret named `sops-gpg` in the cluster. + + ```shell + gpg --export-secret-keys --armor <new key fingerprint> | kubectl create secret generic sops-gpg -n bigbang --from-file=yourkey.asc=/dev/stdin + ``` + +### AWS KMS + +1. Configure your KMS key(s) in your `.sops.yaml` by adding the target key's ARN to the `kms` field within each creation rule. + + ```yaml + creation_rules: + - encrypted_regex: "^(data|stringData)$" + path_regex: ./dev/.* + kms: "<kms_key_arn>" + ``` + +1. Ensure your cluster (specifically the `flux-system/flux-controller`) has access to the specified key. + + 1. For AWS deployments, this can be managed via IAM roles as described in the [SOPS documentation](https://github.com/mozilla/sops#28assuming-roles-and-using-kms-in-various-aws-accounts). + 1. For non-AWS deployments + + 1. Create an AWS user with appropriate permissions as described in the [SOPS documentation](https://github.com/mozilla/sops#28assuming-roles-and-using-kms-in-various-aws-accounts). + 1. Create a secret named `sops-aws-creds` in the cluster using the access creds from the target user: + + ```shell + k create secret generic -n flux-system sops-aws-creds --from-literal=access_key_id=<key_id> --from-literal=access_key_secret=<key> + ``` + +### GCP KMS + - If using a GCP KMS key, you can skip the section: "Create GPG Encryption Key". Instead, in your .sops.yaml file (note - this is a hidden file at the root of this directory) use this configuration instead + of the GPG config: + ```yaml + creation_rules: + - encrypted_regex: '^(data|stringData)$' + gcp_kms: <gcp resource name of key> + ``` + Key resource name should look like: ```projects/{PROJECT_ID}/locations/global/keyRings/{KEY_RING_NAME}/cryptoKeys/{KEY_NAME}_**``` + + If you get errors about the key not working, try re-logging in to GCP: + + ```gcloud auth application-default login``` + + And make sure you have the right project set: + + ```gcloud config set project <project_id>``` + + + Also make sure you have these IAM roles on your GCP account: + ```shell + roles/container.admin + roles/iam.serviceAccountAdmin + ``` + + The KMS key also needs IAM permissions, and needs to be linked back to the flux-controller in the cluster. You need to create a service account and role binding, then manually annotate it: + + ```kubectl annotate serviceaccount kustomize-controller --namespace flux-system iam.gke.io/gcp-service-account=flux-service-account@<project_id>.iam.gserviceaccount.com``` + + GCP uses Workload Identity to allow the flux-controller to use the service account, good references for this setup are here. Make sure you enable Workload Identity on the cluster nodes: + [GCP Docs](https://cloud.google.com/kubernetes-engine/docs/how-to/workload-identity) + [Medium Article](https://medium.com/the-telegraph-engineering/binding-gcp-accounts-to-gke-service-accounts-with-terraform-dfca4e81d2a0) + + +### Azure KeyVault + +TBD - [This article](https://blog.doit-intl.com/injecting-secrets-from-aws-gcp-or-vault-into-a-kubernetes-pod-d5a0e84ba892) may help to automate secret consumption in Kubernetes. + +### HashiCorp Vault + +TBD - [This article](https://blog.doit-intl.com/injecting-secrets-from-aws-gcp-or-vault-into-a-kubernetes-pod-d5a0e84ba892) may help to automate secret consumption in Kubernetes. + +## Configure Big Bang + +Big Bang needs to know how to retrieve the private key so it can deploy the encrypted secrets from Git. Decryption configuration is placed in the top-level manifest (e.g. `dev.yaml`, `prod.yaml`) from the [Big Bang template](https://repo1.dso.mil/big-bang/customers/template). + +### GPG + +By default, the `Kustomization` resource uses a Secret named `sops-gpg` for the private key as shown in the following: + +```yaml +apiVersion: kustomize.toolkit.fluxcd.io/v1 +kind: Kustomization +metadata: + name: environment +spec: + decryption: + provider: sops + secretRef: + name: sops-gpg +``` + +### AWS KMS + +Configure the `Kustomization` resource to use SOPS for decryption. + +```yaml +apiVersion: kustomize.toolkit.fluxcd.io/v1 +kind: Kustomization +metadata: + name: environment +spec: + decryption: + provider: sops +``` + +> Note, we are not providing the `secretRef` field, which is specific to GPG + +If Big Bang is deployed within AWS, KMS key access can be handled via IAM roles and permissions on the cluster resources themselves. +However, if the deployment is in a different environment from the KMS keys, AWS credentials may need to be provided via a secret as follows. + +Configure the flux-system `kustomize-controller` component with AWS credential environment variables using `kustomize`. Specific instructions for doing this may vary by deployment and environment but [an example](https://repo1.dso.mil/big-bang/customers/template/-/tree/main) is covered in the bigbang template repo. Broadly speaking, adding environment variables to the `kustomize-controller` component can be accomplished by adding a patch to the `flux/kustomization.yaml` for the target deployment or environment. An example of such a `kustomization.yaml` is shown in the following: + +```yaml +bases: + - ../../base/flux + +patchesStrategicMerge: + - |- + apiVersion: apps/v1 + kind: Deployment + metadata: + name: kustomize-controller + namespace: flux-system + spec: + template: + spec: + containers: + - name: manager + env: + - name: AWS_ACCESS_KEY_ID + valueFrom: + secretKeyRef: + name: sops-aws-creds + key: access_key_id + - name: AWS_SECRET_ACCESS_KEY + valueFrom: + secretKeyRef: + name: sops-aws-creds + key: access_key_secret +``` + +> Values should come from the `sops-aws-creds` secret created in [AWS KMS](#aws-kms) above. + +## Instructions on how to update for GCP and Vault + +TBD diff --git a/docs/understanding-bigbang/concepts/git-ops-engine.md b/docs/understanding-bigbang/concepts/git-ops-engine.md new file mode 100644 index 0000000000000000000000000000000000000000..bd7bbcc270d5608b3584acfd48a6e508ca4c1121 --- /dev/null +++ b/docs/understanding-bigbang/concepts/git-ops-engine.md @@ -0,0 +1,31 @@ +# GitOps Engines + +## Management of Big Bang + +Big Bang will be deployed and managed with [Flux 2](https://github.com/fluxcd/flux2) and provide [Argo](https://github.com/argoproj/argo-cd/) for application developers to use for managing custom applications built on a Big Bang cluster. Big Bang will **not** advocate for use of Flux by mission app owners. + +### Big Bang and Flux + +Big Bang is composed of Open Source and licensed products. [Helm](https://helm.sh/), as a member of the [CNCF](https://www.cncf.io/), is the de facto standard for packaging applications for Kubernetes. As a result, several vendors support the release of their product **as helm charts** and have built their packaging and lifecycle management to expect to be the engine for driving that management. As a result, Big Bang has adopted Helm as its internal deployment framework for Big Bang packages and requires Helm to be treated as a first class citizen. + +The Flux 2 Engine has native Helm support, meaning the controller deployed as part of "Flux 2" leverages the same Helm code as the CLI. + +### Limitations of Argo + +#### Helm Support + +Argo, has taken the ownership of rendering and managing the lifecycle of applications that does not work exactly as expected by helm. As a result, there are several vendor Helm Charts that **do not deploy successfully** with Argo because of how Argo shims Helm Hooks to Argo specific sync phases. + +* GitLab initial secret creation is performed via a [subchart](https://gitlab.com/gitlab-org/charts/gitlab/-/tree/master/charts/shared-secrets) +* Kube Prometheus Stack: [prometheusrule admission webhook](https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack#prometheusrules-admission-webhooks) is created via a helm `install` hook +* Confluent: A deletion hook is part of a subchart gets run at different point in the lifecycle + +As new features of Helm get developed and leveraged by the community, we would need to lean on the time and availability of the Argo developers to re-implement the capabilities. + +#### App of App Pattern and Secrets + +Argo requires all configuration options to be embedded into the Application CR. Because of this, sensitive values that need to be passed into "inner" packages are forced to reside in the Custom Resource rather than referenced as a Secret. + +## Argo Is Still A Package + +As defined in the list of [Big Bang Packages](../../packages.md), Big Bang comes deployed with Argo for use by mission applications to continue to deploy and manage their applications. Similarly, even though Big Bang uses Helm internally for management of Big Bang packages, Big Bang does not advocate for Helm for use by applications run on clusters with Big Bang. diff --git a/docs/understanding-bigbang/concepts/glossary.md b/docs/understanding-bigbang/concepts/glossary.md new file mode 100644 index 0000000000000000000000000000000000000000..b7bd181a565db7e3c6fa7eee134a676231873547 --- /dev/null +++ b/docs/understanding-bigbang/concepts/glossary.md @@ -0,0 +1,131 @@ +# Glossary + +[[_TOC_]] + +--- + +## Key Concepts + +### Big Bang + +Big Bang is a declarative, continuous delivery tool for core DoD hardened and approved [packages](#packages) into a Kubernetes cluster. Big Bang follows a [GitOps](#gitops) approach to configuration management, using [Flux v2](#flux-v2) to reconcile Git with the cluster. Environments (e.g., dev and/or prod) and packages (e.g., istio) can be fully configured to suit the deployment needs. + +### Big Bang Components + +Big Bang is made of several components that operate together. These include a [base Kustomize](../../../base/), a [Helm chart](../../../chart), [packages](../../../chart/templates), and an [environment](https://repo1.dso.mil/big-bang/customers/bigbang). The environment and base Kustomize are used together to deploy the Big Bang configuration and Helm chart. The Helm chart is then used to facilitate deployment of the packages. + +### Flux v2 + +[Flux v2](https://toolkit.fluxcd.io/) is the tool used by Big Bang to reconcile sources of configuration in Git with actual code deployment. Flux includes resources to reconcile Git repositories, [Kustomizations](https://kustomize.io/) to Kubernetes manifests, and [Helm Chart](https://helm.sh/docs/topics/charts/) releases. Flux automatically monitors changes in these items and reconciles with the Kubernetes cluster. + +### GitOps + +[GitOps](https://www.weave.works/technologies/gitops/) is a way to declaratively manage a Kubernetes cluster using a single source of truth in Git. All Kubernetes configuration is stored in Git. A tool (e.g. [Flux](#flux-v2) is used to automatically monitor and reconcile the configuration with the running Kubernetes cluster. This allows all changes to the cluster to be version controlled and pipelined. + +### SOPS + +[SOPS](https://github.com/mozilla/sops) is a way to encrypt values in YAML, JSON, ENV, INI, or BINARY files so that sensitive data can be securely shared. Big Bang uses SOPS to encrypt pull secrets, certificates, and other secrets so that it can be stored into the Git repository securely. Big Bang (via Flux) uses the private key, stored in a secure area (e.g., KMS) to decrypt the secrets and deploy them into the cluster for use. + +### Kustomize + +[Kustomize](https://kustomize.io/) is a tool that assists with configuration management for Kubernetes manifest files. It uses overlays and patching to customize a base set of manifests for deployment. Big Bang uses Kustomize to setup the environment (e.g., dev and/or prod) configuration. + +### Helm + +[Helm](https://helm.sh/) is a tool that assists with configuration management for Kubernetes manifest files. It uses charts, which includes templates and values, to create a set of manifests for deployment. Big Bang uses Helm charts to deploy all of its packages. + +--- + +## Packages + +The following packages are included in a default deployment of Big Bang: + +|Name|Description|Helm Chart Repo| +|--|--|--| +|[Istio](https://istio.io/)|[Service Mesh](https://www.redhat.com/en/topics/microservices/what-is-a-service-mesh)|[Link](https://repo1.dso.mil/big-bang/product/packages/servicemesh.git)| +|Cluster Auditor| |[Link](https://repo1.dso.mil/big-bang/product/packages/cluster-auditor.git)| +|[Open Policy Agent Gatekeeper](https://github.com/open-policy-agent/gatekeeper)| Policy Management | [Link](https://repo1.dso.mil/big-bang/product/packages/policy.git)| +|[Elastic Cloud on Kubernetes (ECK)](https://www.elastic.co/guide/en/cloud-on-k8s/current/index.html)| Logging; Incl. Elasticsearch & Kibana |[Link](https://repo1.dso.mil/big-bang/product/packages/elasticsearch-kibana.git)| +|[Prometheus](https://prometheus.io/) and [Grafana](https://grafana.com/)| Monitoring |[Link](https://repo1.dso.mil/big-bang/product/packages/monitoring.git)| +|[Twistlock](https://www.paloaltonetworks.com/prisma/cloud)| Security Scanning |[Link](https://repo1.dso.mil/big-bang/product/packages/twistlock.git)| + +In addition, the following packages can be added onto the default deployment: + +|Name|Description|Helm Chart Repo| +|--|--|--| +|[Argo CD](https://argoproj.github.io/argo-cd/)| Continuous Delivery |[Link](https://repo1.dso.mil/big-bang/product/packages/argocd.git)| +|Auth Service|Single Sign On|[Link](https://repo1.dso.mil/big-bang/product/packages/authservice.git) + +--- + +## Architecture + +The diagram provided in this section shows a typical deployment of Big Bang into a Kubernetes cluster. The items in blue require user interaction. The remaining items are automated by Big Bang. + +### Configuration + +1. The user must [setup an encryption key pair](./encryption.md) for SOPS and store the private key securely (e.g., KMS). This should **NOT** be stored in Git. +1. The user should then [configure Big Bang](../configuration/configuration.md) values and secrets for the targeted Kubernetes cluster. +1. All secrets should be encrypted with SOPS to protect them. +1. Once all of the configuration has been completed, it must be pushed to a Git repository. + +### Deployment + +1. With everything in Git, the user can [deploy Big Bang](./deployment.md) using a Kubernetes manifest. +1. The manifest holds two Flux resources, one pointing to the Git repository holding the custom environment, and one telling Flux to run Kustomize on a targeted folder within the repo. + + a. The repository is reconciled first, pulling the files from Git. + b. Next, Kustomize is run on the environment configuration. + + - The Kustomize files use Big Bang's Git repo as a base before applying overlays and patches for the configuration. + - Flux uses SOPS to decrypt any secrets before deploying the manifests. + - After completing the Kustomization process, Flux deploys two ConfigMaps, two Secrets, and flux resources for Big Bang. +1. Big Bang's flux resources include a Git repository holding the Helm chart and a Helm Release resource that tells Flux how to deploy the Helm chart. + + a. The repository is reconciled first, pulling the Helm chart from Git. + b. The Helm Release will check for the Helm chart and the Secrets/ConfigMaps deployed before performing a Helm install. +1. Once the Helm release deploys the Helm chart for Big Bang, each package that is enabled will have a Flux Git Repository and Helm Release resource deployed. +1. All of the package Git repositories containing Helm charts will be pulled so that Flux can reconcile dependencies. +1. Each package's Helm Release has dependencies built in. Flux will reconcile these dependencies and deploy the Helm chart for the package once all of the dependencies are ready. +1. Once all of the packages are ready, Big Bang will monitor Git periodically for changes and reconcile using the methods above. + +### Diagram + +```mermaid +graph TD + style SetupSOPS fill:#00758f + style CustomSecrets fill:#00758f + style CustomVals fill:#00758f + style EncryptSecrets fill:#00758f + style PushToGit fill:#00758f + style DeployMan fill:#00758f + + SetupSOPS(Setup SOPS keys) --> EncryptSecrets(Encrypt secrets) + SetupSOPS --> CustomVals(Customize values) + CustomSecrets(Customize secrets) --> EncryptSecrets + CustomVals --> PushToGit(Push customization to Git) + EncryptSecrets --> PushToGit + PushToGit --> DeployMan(Deploy BigBang Manifest) + + DeployMan --> KustResEnv[[Deploy Environment Kustomization Resource]] + KustResEnv --> HelmResBB[[Deploy Big Bang Helm Release Resource]] + DeployMan --> GitResEnv[[Deploy Environment Git Repository Resource]] + KustResEnv --> GitResBB[[Deploy Big Bang Git Repository Resource]] + KustResEnv --> SOPS + + GitResEnv --> PullEnv[[Pull environment]] + PullEnv --> SOPS[[SOPS Decrypt secrets]] + SOPS --> DeployVals[[Deploy ConfigMap and Secrets]] + + GitResBB --> PullBB[[Pull Big Bang Helm Chart]] + PullBB --> DeployBB[[Deploy Big Bang Helm Chart]] + HelmResBB --> DeployBB + DeployVals --> DeployBB + + DeployBB --> PackGit[[Deploy Package Git Repository Resources]] + PackGit --> PackPull[[Pull Package Helm Charts]] + PackPull --> PackDep[[Resolve Package Dependencies]] + PackDep --> PackReady{Package Ready?} + PackReady --Yes--> PackDeploy[[Deploy Package w/ Helm Chart]] + PackReady --No--> PackDep +``` diff --git a/docs/understanding-bigbang/concepts/troubleshooting.md b/docs/understanding-bigbang/concepts/troubleshooting.md new file mode 100644 index 0000000000000000000000000000000000000000..f33b065a18872aa7695e63650ee603f0f32c64a1 --- /dev/null +++ b/docs/understanding-bigbang/concepts/troubleshooting.md @@ -0,0 +1,117 @@ +# Troubleshooting + +Big Bang can take a long time to run. After making changes, it could take 10-15 minutes to take effect. Use the [sync.sh](../../../scripts/sync.sh) script to speed this up. + +Big Bang is configured to retry failed package installations and upgrades. Before concluding you have a failure, make sure you allow Big Bang to attempt to resolve dependencies and retry. + +## Iron Bank Authentication + +| Symptom | Cause | Resolution | +|--|--|--| +| Despite entering correct credentials, get `unauthorized: authentication required` from Iron Bank. | Using a non-robot account with an expired token. | Login with the non-robot account manually at `registry1.dso.mil`, then retry. For production, contact the Iron Bank team to obtain a robot account and update pull credentials to use it in your environment. | + +## Flux Install + +Helpful debugging commands: + +```shell +# Get the status +kubectl get pods -n flux-system + +# Get the logs +kubectl get events -n flux-system +``` + +| Symptom | Cause | Resolution | +|--|--|--| +| Install script timed and pods are still pulling the image | Slow connection to docker registry | Adjust `--timeout` value in `flux install` to wait longer | +| Pod status is `ImagePullBackOff` or `ErrImagePull` | Bad registry, version, or credentials | Fix the `--registry`, `--version`, or `--image-pull secret` options or use the `./scripts/install_flux.sh` script for pulling from Iron Bank | + +## Git Repository + +Helpful debugging commands: + +```shell +# Get the status +kubectl get gitrepositories -A + +# Get the logs +kubectl get events --field-selector involvedObject.kind=GitRepository -A +``` + +| Symptom | Cause | Resolution | +|--|--|--| +| `unable to clone ... error: authentication required` | Pull credentials for Git invalid or not provided | Add credentials to a `Secret` and reference it in `GitRepository.spec.secretRef.name`. If possible, encrypt the secret and include it in the Kustomization deployment for your environment. +| `auth secret error: Secret ... not found` | `GitRepository` is trying to use credentials but cannot find the `Secret` | Make sure the secret exists and is in the same namespace as the `GitRepository` resource. If possible, encrypt the secret and include it in the Kustomization deployment for your environment. +| `unable to clone ... error: repository not found` | Invalid Git url | Fix url for Git repository and redeploy | +| `unable to clone ... error: couldn't find remote ref` | Invalid branch or tag | Fix branch or tag for Git repository and redeploy | + +## ConfigMap or Secrets + +| Symptom | Cause | Resolution | +|--|--|--| +|`ConfigMap` or `Secret` does not exist| GitRepository or Kustomization failed. Namespace was incorrect. | Use [GitRepository](#git-repository) and [Kustomization](#kustomization) sections to troubleshoot. Use `kubectl get secrets,configmaps -A` to verify resource was not in the wrong Namespace. | + +## Helm Release + +Helpful debugging commands: + +```shell +# Get the status +kubectl get hr -A + +# Get the logs +kubectl get events --field-selector involvedObject.kind=HelmRelease -A + +# Describe the HelmRelease to get more information +kubectl describe hr <NAME> -n bigbang + +# Get all logs/events for a specific HelmRelease object +flux logs --kind=HelmRelease --namespace bigbang --name <NAME> +``` + +| Symptom | Cause | Resolution | +|--|--|--| +| `Reconciliation in Progress` | This is normal and indicates flux is currently applying updates | Wait | +| `dependency ... is not ready` | This is normal and indicates flux is currently waiting on another resource to complete | Wait | +| `Error: YAML parse error on ...` | Syntax error in helm chart | Use `helm template` to narrow down the problem. Fix it and commit to Git | +| `Helm install failed: failed to create resource ... unable to create new content in namespace because it is being terminated` | This seems to happen when a re-deploy of Big Bang occurs to early after a Big Bang delete. | Try to remove the namespace using `kubectl get ns <stuck namespace> -o json | jq '.spec.finalizers = []' | kubectl replace --raw "/api/v1/namespaces/$NS/finalize" -f`. If this does not work, a cluster restart may be necessary. | +| `Error: failed to download ...` | Path to Helm chart is incorrect | Find the HelmRelease configuration and update `spec.path` to the correct path of the helm chart | +| `Helm uninstall failed: uninstall: Release not loaded: ____: release: not found` | Helm install failed because of an error and a rollback/uninstall is attempted but release has not been installed. | Describe the HelmRelease in question or use flux to get the logs to get more info abut why it failed to install. | +| `reconciliation failed: Helm rollback failed: an error occurred while cleaning up resources. original rollback error: no XXXX with the name "XXXX" found: unable to cleanup resources: object not found, skipping delete` | This error happens when an upgrade fails and flux attempts a rollback but there are templates that have been renamed/removed. | Describe the HelmRelease in question or use flux to get the logs to get more info abut why exactly the upgrade failed. | + +## Kustomization + +Helpful debugging commands: + +```shell +# Get the status +kubectl get kustomizations -A + +# Get the logs +kubectl get events --field-selector involvedObject.kind=Kustomization -A +``` + +| Symptom | Cause | Resolution | +|--|--|--| +| `kustomization path not found` | `spec.path` in Kustomization resource in is incorrect | Fix `spec.path` and redeploy | +| `Source not found` | `spec.sourceRef` in Kustomization resource is incorrect | Fix `spec.sourceRef` to point to repository resource and redeploy | +| `decryption secret error: Secret ... not found` | SOPS private key secret is missing or misconfigured | Check `decryption` settings in the Kustomization resource to make sure `secretRef` is pointing to the correct secret. Make sure the `Secret` holding the private key is deployed in the cluster. | +| `kustomize build failed: json: unknown field` | There is a syntax error with the kustomization files. | Use `kustomize build` on the `<env>` folder or `base` folder to narrow down the problem. Fix the error and push to Git. | +| `evalsymlink failure ... no such file or directory` | A reference to a file in `kustomization.yaml` is incorrect | Use `kustomize build` on the `<env>` folder or `base` folder to narrow down the problem. Fix the error and push to Git. | +| `Error: accumulating resources ...` | A reference to a base is incorrect | Use `kustomize build` on the `<env>` folder or `base` folder to narrow down the problem.Review the `bases:` section for correct paths to find the error. Fix the error and push to Git. | +| `Error fetchingref: fatal: couldn't find remote ref ...` | The branch, tag, or sha used for a remote base is incorrect | Use `kustomize build` on the `<env>` folder or `base` folder to narrow down the problem. It is likely the remote reference to the Big Bang's Kustomize in the `base` folder. Review the `bases:` section for correct paths to find the error. Fix the error and push to Git. | +| `Error: merging from generator ...` | Kustomize is trying to merge with a resource that is non-existent. This is usually due to naming the merging `ConfigMap` or `Secret` incorrectly compared to a base `ConfigMap` or `Secret`. | Use `kustomize build` on the `<env>` folder or `base` folder to narrow down the problem. Look for the keyword `merge` in the `kustomization.yaml` files and verify the `name` is correctly set. | + +## Packages + +Helpful debugging commands: + +```shell +# Get the status +kubectl get deployments,po -n <namespace of package> + +# Get the logs +kubectl get events --field-selector involvedObject.kind=Deployment -n <namespace of package> +kubectl get events --field-selector involvedObject.kind=Pod -n <namespace of package> +``` diff --git a/docs/understanding-bigbang/configuration/.pages b/docs/understanding-bigbang/configuration/.pages new file mode 100644 index 0000000000000000000000000000000000000000..68b106df43074d96ec858900226d8240a7675dbf --- /dev/null +++ b/docs/understanding-bigbang/configuration/.pages @@ -0,0 +1,5 @@ +nav: + - Base Config: base-config.md + - Sample Production Config: sample-prod-config.md + - Overall Configuration: configuration.md + - Post Renderers: postrenderers.md diff --git a/docs/understanding-bigbang/configuration/base-config.md b/docs/understanding-bigbang/configuration/base-config.md new file mode 100644 index 0000000000000000000000000000000000000000..249daff215c50b5c652dd539535e2576b7bc3ef1 --- /dev/null +++ b/docs/understanding-bigbang/configuration/base-config.md @@ -0,0 +1,764 @@ +# bigbang + +![Version: 2.44.0](https://img.shields.io/badge/Version-2.44.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) + +Big Bang is a declarative, continuous delivery tool for core DoD hardened and approved packages into a Kubernetes cluster. + +## Getting Started + +To start using Big Bang, you will need to create your own Big Bang environment tailored to your needs. The [Big Bang customer template](https://repo1.dso.mil/big-bang/customers/template) is provided for you to copy into your own Git repository and begin modifications. + +## Maintainers + +| Name | Email | Url | +| ---- | ------ | --- | +| Michael Martin | michaelmartin@seed-innovations.com | | +| Chris O'Connell | coconnell@bridgephase.com | | +| Andrew Shoell | a.shoell@wearemetronome.com | | + +## Source Code + +* <https://repo1.dso.mil/big-bang/bigbang> + +## Requirements + +Kubernetes: `>=1.29.0-0` + +## Values + +| Key | Type | Default | Description | +|-----|------|---------|-------------| +| domain | string | `"dev.bigbang.mil"` | Domain used for BigBang created exposed services, can be overridden by individual packages. | +| offline | bool | `false` | (experimental) Toggle sourcing from external repos. All this does right now is toggle GitRepositories, it is _not_ fully functional | +| helmRepositories | list | `[]` | List of Helm repositories/credentials to pull helm charts from. OCI Type: Must specify username/password or existingSecret if repository requires auth. Using "private-registry" for existingSecret will reuse credentials from registryCredentials above. Default Type: Must specify existingSecret with auth - see https://fluxcd.io/flux/components/source/helmrepositories/#secret-reference for details on secret data required. | +| registryCredentials | object | `{"email":"","password":"","registry":"registry1.dso.mil","username":""}` | Single set of registry credentials used to pull all images deployed by BigBang. | +| openshift | bool | `false` | Multiple sets of registry credentials used to pull all images deployed by BigBang. Credentials will only be created when a valid combination exists, registry, username, and password (email is optional) Or a list of registires: - registry: registry1.dso.mil username: "" password: "" email: "" - registry: registry.dso.mil username: "" password: "" email: "" Openshift Container Platform Feature Toggle | +| git | object | `{"credentials":{"caFile":"","knownHosts":"","password":"","privateKey":"","publicKey":"","username":""},"existingSecret":""}` | Git credential settings for accessing private repositories Order of precedence is: 1. existingSecret 2. http credentials (username/password/caFile) 3. ssh credentials (privateKey/publicKey/knownHosts) | +| git.existingSecret | string | `""` | Existing secret to use for git credentials, must be in the appropriate format: https://toolkit.fluxcd.io/components/source/gitrepositories/#https-authentication | +| git.credentials | object | `{"caFile":"","knownHosts":"","password":"","privateKey":"","publicKey":"","username":""}` | Chart created secrets with user defined values | +| git.credentials.username | string | `""` | HTTP git credentials, both username and password must be provided | +| git.credentials.caFile | string | `""` | HTTPS certificate authority file. Required for any repo with a self signed certificate | +| git.credentials.privateKey | string | `""` | SSH git credentials, privateKey, publicKey, and knownHosts must be provided | +| sso | object | `{"certificateAuthority":{"cert":"","secretName":"tls-ca-sso"},"name":"SSO","oidc":{"authorization":"{{ .Values.sso.url }}/protocol/openid-connect/auth","claims":{"email":"email","groups":"groups","name":"name","username":"preferred_username"},"endSession":"{{ .Values.sso.url }}/protocol/openid-connect/logout","jwks":"","jwksUri":"{{ .Values.sso.url }}/protocol/openid-connect/certs","token":"{{ .Values.sso.url }}/protocol/openid-connect/token","userinfo":"{{ .Values.sso.url }}/protocol/openid-connect/userinfo"},"saml":{"entityDescriptor":"{{ .Values.sso.url }}/protocol/saml/descriptor","metadata":"","service":"{{ .Values.sso.url }}/protocol/saml"},"url":"https://login.dso.mil/auth/realms/baby-yoda"}` | Global SSO values used for BigBang deployments when sso is enabled | +| sso.name | string | `"SSO"` | Name of the identity provider. This is used by some packages as the SSO login label. | +| sso.url | string | `"https://login.dso.mil/auth/realms/baby-yoda"` | Base URL for the identity provider. For OIDC, this is the issuer. For SAML this is the entityID. | +| sso.certificateAuthority | object | `{"cert":"","secretName":"tls-ca-sso"}` | Certificate authority for the identity provider's certificates | +| sso.certificateAuthority.cert | string | `""` | The certificate authority public certificate in .pem format. Populating this will create a secret in each namespace that enables SSO. | +| sso.certificateAuthority.secretName | string | `"tls-ca-sso"` | The secret name to use for the certificate authority. Can be manually populated if cert is blank. | +| sso.saml.entityDescriptor | string | `"{{ .Values.sso.url }}/protocol/saml/descriptor"` | SAML entityDescriptor (metadata) path | +| sso.saml.service | string | `"{{ .Values.sso.url }}/protocol/saml"` | SAML SSO Service path | +| sso.saml.metadata | string | `""` | Literal SAML XML metadata retrieved from `{{ .Values.sso.saml.entityDescriptor }}`. Required for SSO in Nexus, Twistlock, or Sonarqube. | +| sso.oidc | object | `{"authorization":"{{ .Values.sso.url }}/protocol/openid-connect/auth","claims":{"email":"email","groups":"groups","name":"name","username":"preferred_username"},"endSession":"{{ .Values.sso.url }}/protocol/openid-connect/logout","jwks":"","jwksUri":"{{ .Values.sso.url }}/protocol/openid-connect/certs","token":"{{ .Values.sso.url }}/protocol/openid-connect/token","userinfo":"{{ .Values.sso.url }}/protocol/openid-connect/userinfo"}` | OIDC endpoints can be retrieved from `{{ .Values.sso.url }}/.well-known/openid-configuration` | +| sso.oidc.authorization | string | `"{{ .Values.sso.url }}/protocol/openid-connect/auth"` | OIDC authorization path | +| sso.oidc.endSession | string | `"{{ .Values.sso.url }}/protocol/openid-connect/logout"` | OIDC logout / end session path | +| sso.oidc.jwksUri | string | `"{{ .Values.sso.url }}/protocol/openid-connect/certs"` | OIDC JSON Web Key Set (JWKS) path | +| sso.oidc.token | string | `"{{ .Values.sso.url }}/protocol/openid-connect/token"` | OIDC token path | +| sso.oidc.userinfo | string | `"{{ .Values.sso.url }}/protocol/openid-connect/userinfo"` | OIDC user information path | +| sso.oidc.jwks | string | `""` | Literal OIDC JWKS data retrieved from JWKS Uri. Only needed if `jwsksUri` is not defined. | +| sso.oidc.claims | object | `{"email":"email","groups":"groups","name":"name","username":"preferred_username"}` | Identity provider claim names that store metadata about the authenticated user. | +| sso.oidc.claims.email | string | `"email"` | IdP's claim name used for the user's email address. | +| sso.oidc.claims.name | string | `"name"` | IdP's claim name used for the user's full name | +| sso.oidc.claims.username | string | `"preferred_username"` | IdP's claim name used for the username | +| sso.oidc.claims.groups | string | `"groups"` | IdP's claim name used for the user's groups or roles | +| flux | object | `{"install":{"remediation":{"retries":-1}},"interval":"2m","rollback":{"cleanupOnFail":true,"timeout":"10m"},"test":{"enable":false},"timeout":"10m","upgrade":{"cleanupOnFail":true,"remediation":{"remediateLastFailure":true,"retries":3}}}` | (Advanced) Flux reconciliation parameters. The default values provided will be sufficient for the majority of workloads. | +| networkPolicies | object | `{"controlPlaneCidr":"0.0.0.0/0","enabled":true,"nodeCidr":"","vpcCidr":"0.0.0.0/0"}` | Global NetworkPolicies settings | +| networkPolicies.enabled | bool | `true` | Toggle all package NetworkPolicies, can disable specific packages with `package.values.networkPolicies.enabled` | +| networkPolicies.controlPlaneCidr | string | `"0.0.0.0/0"` | Control Plane CIDR, defaults to 0.0.0.0/0, use `kubectl get endpoints -n default kubernetes` to get the CIDR range needed for your cluster Must be an IP CIDR range (x.x.x.x/x - ideally with /32 for the specific IP of a single endpoint, broader range for multiple masters/endpoints) Used by package NetworkPolicies to allow Kube API access | +| networkPolicies.nodeCidr | string | `""` | Node CIDR, defaults to allowing "10.0.0.0/8" "172.16.0.0/12" "192.168.0.0/16" "100.64.0.0/10" networks. use `kubectl get nodes -owide` and review the `INTERNAL-IP` column to derive CIDR range. Must be an IP CIDR range (x.x.x.x/x - ideally a /16 or /24 to include multiple IPs) | +| networkPolicies.vpcCidr | string | `"0.0.0.0/0"` | VPC CIDR, defaults to 0.0.0.0/0 In a production environment, it is recommended to setup a Private Endpoint for your AWS services like KMS or S3. Please review https://docs.aws.amazon.com/kms/latest/developerguide/kms-vpc-endpoint.html to setup routing to AWS services that never leave the AWS network. Once created update `networkPolicies.vpcCidr` to match the CIDR of your VPC so Vault will be able to reach your VPCs DNS and new KMS endpoint. | +| imagePullPolicy | string | `"IfNotPresent"` | Global ImagePullPolicy value for all packages Permitted values are: None, Always, IfNotPresent | +| istio.enabled | bool | `true` | Toggle deployment of Istio. | +| istio.mtls.mode | string | `"STRICT"` | STRICT = Allow only mutual TLS traffic, PERMISSIVE = Allow both plain text and mutual TLS traffic | +| istio.sourceType | string | `"git"` | Choose source type of "git" or "helmRepo" | +| istio.git.repo | string | `"https://repo1.dso.mil/big-bang/product/packages/istio-controlplane.git"` | | +| istio.git.path | string | `"./chart"` | | +| istio.git.tag | string | `"1.23.3-bb.2"` | | +| istio.helmRepo.repoName | string | `"registry1"` | | +| istio.helmRepo.chartName | string | `"istio"` | | +| istio.helmRepo.tag | string | `"1.23.3-bb.2"` | | +| istio.enterprise | bool | `false` | Tetrate Istio Distribution - Tetrate provides FIPs verified Istio and Envoy software and support, validated through the FIPs Boring Crypto module. Find out more from Tetrate - https://www.tetrate.io/tetrate-istio-subscription | +| istio.ingressGateways.public-ingressgateway.type | string | `"LoadBalancer"` | | +| istio.ingressGateways.public-ingressgateway.kubernetesResourceSpec | object | `{}` | | +| istio.gateways.public.ingressGateway | string | `"public-ingressgateway"` | | +| istio.gateways.public.hosts[0] | string | `"*.{{ .Values.domain }}"` | | +| istio.gateways.public.autoHttpRedirect | object | `{"enabled":true}` | Controls default HTTP/8080 server entry with HTTP to HTTPS Redirect. | +| istio.gateways.public.tls.key | string | `""` | | +| istio.gateways.public.tls.cert | string | `""` | | +| istio.gateways.public.tls.minProtocolVersion | string | `""` | | +| istio.flux | object | `{}` | Flux reconciliation overrides specifically for the Istio Package | +| istio.values | object | `{}` | Values to passthrough to the istio-controlplane chart: https://repo1.dso.mil/big-bang/product/packages/istio-controlplane.git | +| istio.postRenderers | list | `[]` | Post Renderers. See docs/postrenders.md | +| istioOperator.enabled | bool | `true` | Toggle deployment of Istio Operator. | +| istioOperator.sourceType | string | `"git"` | Choose source type of "git" or "helmRepo" | +| istioOperator.git.repo | string | `"https://repo1.dso.mil/big-bang/product/packages/istio-operator.git"` | | +| istioOperator.git.path | string | `"./chart"` | | +| istioOperator.git.tag | string | `"1.23.3-bb.0"` | | +| istioOperator.helmRepo.repoName | string | `"registry1"` | | +| istioOperator.helmRepo.chartName | string | `"istio-operator"` | | +| istioOperator.helmRepo.tag | string | `"1.23.3-bb.0"` | | +| istioOperator.flux | object | `{}` | Flux reconciliation overrides specifically for the Istio Operator Package | +| istioOperator.values | object | `{}` | Values to passthrough to the istio-operator chart: https://repo1.dso.mil/big-bang/product/packages/istio-operator.git | +| istioOperator.postRenderers | list | `[]` | Post Renderers. See docs/postrenders.md | +| jaeger.enabled | bool | `false` | Toggle deployment of Jaeger. | +| jaeger.sourceType | string | `"git"` | Choose source type of "git" or "helmRepo" | +| jaeger.git.repo | string | `"https://repo1.dso.mil/big-bang/product/packages/jaeger.git"` | | +| jaeger.git.path | string | `"./chart"` | | +| jaeger.git.tag | string | `"2.57.0-bb.0"` | | +| jaeger.helmRepo.repoName | string | `"registry1"` | | +| jaeger.helmRepo.chartName | string | `"jaeger"` | | +| jaeger.helmRepo.tag | string | `"2.57.0-bb.0"` | | +| jaeger.flux | object | `{"install":{"crds":"CreateReplace"},"upgrade":{"crds":"CreateReplace"}}` | Flux reconciliation overrides specifically for the Jaeger Package | +| jaeger.ingress | object | `{"gateway":""}` | Redirect the package ingress to a specific Istio Gateway (listed in `istio.gateways`). The default is "public". | +| jaeger.sso.enabled | bool | `false` | Toggle SSO for Jaeger on and off | +| jaeger.sso.client_id | string | `""` | OIDC Client ID to use for Jaeger | +| jaeger.sso.client_secret | string | `""` | OIDC Client Secret to use for Jaeger | +| jaeger.values | object | `{}` | Values to pass through to Jaeger chart: https://repo1.dso.mil/big-bang/product/packages/jaeger.git | +| jaeger.postRenderers | list | `[]` | Post Renderers. See docs/postrenders.md | +| kiali.enabled | bool | `true` | Toggle deployment of Kiali. | +| kiali.sourceType | string | `"git"` | Choose source type of "git" or "helmRepo" | +| kiali.git.repo | string | `"https://repo1.dso.mil/big-bang/product/packages/kiali.git"` | | +| kiali.git.path | string | `"./chart"` | | +| kiali.git.tag | string | `"2.2.0-bb.0"` | | +| kiali.helmRepo.repoName | string | `"registry1"` | | +| kiali.helmRepo.chartName | string | `"kiali"` | | +| kiali.helmRepo.tag | string | `"2.2.0-bb.0"` | | +| kiali.flux | object | `{}` | Flux reconciliation overrides specifically for the Kiali Package | +| kiali.ingress | object | `{"gateway":""}` | Redirect the package ingress to a specific Istio Gateway (listed in `istio.gateways`). The default is "public". | +| kiali.sso.enabled | bool | `false` | Toggle SSO for Kiali on and off | +| kiali.sso.client_id | string | `""` | OIDC Client ID to use for Kiali | +| kiali.sso.client_secret | string | `""` | OIDC Client Secret to use for Kiali | +| kiali.values | object | `{}` | Values to pass through to Kiali chart: https://repo1.dso.mil/big-bang/product/packages/kiali | +| kiali.postRenderers | list | `[]` | Post Renderers. See docs/postrenders.md | +| clusterAuditor.enabled | bool | `false` | Toggle deployment of Cluster Auditor. | +| clusterAuditor.sourceType | string | `"git"` | Choose source type of "git" or "helmRepo" | +| clusterAuditor.git.repo | string | `"https://repo1.dso.mil/big-bang/product/packages/cluster-auditor.git"` | | +| clusterAuditor.git.path | string | `"./chart"` | | +| clusterAuditor.git.tag | string | `"1.5.0-bb.22"` | | +| clusterAuditor.helmRepo.repoName | string | `"registry1"` | | +| clusterAuditor.helmRepo.chartName | string | `"cluster-auditor"` | | +| clusterAuditor.helmRepo.tag | string | `"1.5.0-bb.22"` | | +| clusterAuditor.flux | object | `{}` | Flux reconciliation overrides specifically for the Cluster Auditor Package | +| clusterAuditor.values | object | `{}` | Values to passthrough to the cluster auditor chart: https://repo1.dso.mil/big-bang/product/packages/cluster-auditor.git | +| clusterAuditor.postRenderers | list | `[]` | Post Renderers. See docs/postrenders.md | +| gatekeeper.enabled | bool | `false` | Toggle deployment of OPA Gatekeeper. | +| gatekeeper.sourceType | string | `"git"` | Choose source type of "git" or "helmRepo" | +| gatekeeper.git.repo | string | `"https://repo1.dso.mil/big-bang/product/packages/policy.git"` | | +| gatekeeper.git.path | string | `"./chart"` | | +| gatekeeper.git.tag | string | `"3.18.1-bb.0"` | | +| gatekeeper.helmRepo.repoName | string | `"registry1"` | | +| gatekeeper.helmRepo.chartName | string | `"gatekeeper"` | | +| gatekeeper.helmRepo.tag | string | `"3.18.1-bb.0"` | | +| gatekeeper.flux | object | `{"install":{"crds":"CreateReplace"},"upgrade":{"crds":"CreateReplace"}}` | Flux reconciliation overrides specifically for the OPA Gatekeeper Package | +| gatekeeper.values | object | `{}` | Values to passthrough to the gatekeeper chart: https://repo1.dso.mil/big-bang/product/packages/policy.git | +| gatekeeper.postRenderers | list | `[]` | Post Renderers. See docs/postrenders.md | +| kyverno.enabled | bool | `true` | Toggle deployment of Kyverno. | +| kyverno.sourceType | string | `"git"` | Choose source type of "git" or "helmRepo" | +| kyverno.git.repo | string | `"https://repo1.dso.mil/big-bang/product/packages/kyverno.git"` | | +| kyverno.git.path | string | `"./chart"` | | +| kyverno.git.tag | string | `"3.3.4-bb.0"` | | +| kyverno.helmRepo.repoName | string | `"registry1"` | | +| kyverno.helmRepo.chartName | string | `"kyverno"` | | +| kyverno.helmRepo.tag | string | `"3.3.4-bb.0"` | | +| kyverno.flux | object | `{}` | Flux reconciliation overrides specifically for the Kyverno Package | +| kyverno.values | object | `{}` | Values to passthrough to the kyverno chart: https://repo1.dso.mil/big-bang/product/packages/kyverno.git | +| kyverno.postRenderers | list | `[]` | Post Renderers. See docs/postrenders.md | +| kyvernoPolicies.enabled | bool | `true` | Toggle deployment of Kyverno policies | +| kyvernoPolicies.sourceType | string | `"git"` | Choose source type of "git" or "helmRepo" | +| kyvernoPolicies.git.repo | string | `"https://repo1.dso.mil/big-bang/product/packages/kyverno-policies.git"` | | +| kyvernoPolicies.git.path | string | `"./chart"` | | +| kyvernoPolicies.git.tag | string | `"3.3.4-bb.0"` | | +| kyvernoPolicies.helmRepo.repoName | string | `"registry1"` | | +| kyvernoPolicies.helmRepo.chartName | string | `"kyverno-policies"` | | +| kyvernoPolicies.helmRepo.tag | string | `"3.3.4-bb.0"` | | +| kyvernoPolicies.flux | object | `{}` | Flux reconciliation overrides specifically for the Kyverno Package | +| kyvernoPolicies.values | object | `{}` | Values to passthrough to the kyverno policies chart: https://repo1.dso.mil/big-bang/product/packages/kyverno-policies.git | +| kyvernoPolicies.postRenderers | list | `[]` | Post Renderers. See docs/postrenders.md | +| kyvernoReporter.enabled | bool | `true` | Toggle deployment of Kyverno Reporter | +| kyvernoReporter.sourceType | string | `"git"` | Choose source type of "git" or "helmRepo" | +| kyvernoReporter.git.repo | string | `"https://repo1.dso.mil/big-bang/product/packages/kyverno-reporter.git"` | | +| kyvernoReporter.git.path | string | `"./chart"` | | +| kyvernoReporter.git.tag | string | `"2.24.2-bb.1"` | | +| kyvernoReporter.helmRepo.repoName | string | `"registry1"` | | +| kyvernoReporter.helmRepo.chartName | string | `"kyverno-reporter"` | | +| kyvernoReporter.helmRepo.tag | string | `"2.24.2-bb.1"` | | +| kyvernoReporter.flux | object | `{}` | Flux reconciliation overrides specifically for the Kyverno Reporter Package | +| kyvernoReporter.values | object | `{}` | Values to passthrough to the kyverno reporter chart: https://repo1.dso.mil/big-bang/product/packages/kyverno-reporter.git | +| kyvernoReporter.postRenderers | list | `[]` | Post Renderers. See docs/postrenders.md | +| elasticsearchKibana.enabled | bool | `false` | Toggle deployment of Logging (EFK). | +| elasticsearchKibana.sourceType | string | `"git"` | Choose source type of "git" or "helmRepo" | +| elasticsearchKibana.git.repo | string | `"https://repo1.dso.mil/big-bang/product/packages/elasticsearch-kibana.git"` | | +| elasticsearchKibana.git.path | string | `"./chart"` | | +| elasticsearchKibana.git.tag | string | `"1.24.0-bb.2"` | | +| elasticsearchKibana.helmRepo.repoName | string | `"registry1"` | | +| elasticsearchKibana.helmRepo.chartName | string | `"elasticsearch-kibana"` | | +| elasticsearchKibana.helmRepo.tag | string | `"1.24.0-bb.2"` | | +| elasticsearchKibana.flux | object | `{"timeout":"20m"}` | Flux reconciliation overrides specifically for the Logging (EFK) Package | +| elasticsearchKibana.ingress | object | `{"gateway":""}` | Redirect the package ingress to a specific Istio Gateway (listed in `istio.gateways`). The default is "public". | +| elasticsearchKibana.sso.enabled | bool | `false` | Toggle OIDC SSO for Kibana/Elasticsearch on and off. Enabling this option will auto-create any required secrets. | +| elasticsearchKibana.sso.client_id | string | `""` | Elasticsearch/Kibana OIDC client ID | +| elasticsearchKibana.sso.client_secret | string | `""` | Elasticsearch/Kibana OIDC client secret | +| elasticsearchKibana.serviceAccountAnnotations | object | `{"elasticsearch":{},"kibana":{}}` | Elasticsearch/Kibana Service Account Annotations | +| elasticsearchKibana.license.trial | bool | `false` | Toggle trial license installation of elasticsearch. Note that enterprise (non trial) is required for SSO to work. | +| elasticsearchKibana.license.keyJSON | string | `""` | Elasticsearch license in json format seen here: https://repo1.dso.mil/big-bang/product/packages/elasticsearch-kibana#enterprise-license | +| elasticsearchKibana.values | object | `{}` | Values to passthrough to the elasticsearch-kibana chart: https://repo1.dso.mil/big-bang/product/packages/elasticsearch-kibana.git | +| elasticsearchKibana.postRenderers | list | `[]` | Post Renderers. See docs/postrenders.md | +| eckOperator.enabled | bool | `false` | Toggle deployment of ECK Operator. | +| eckOperator.sourceType | string | `"git"` | Choose source type of "git" or "helmRepo" | +| eckOperator.git.repo | string | `"https://repo1.dso.mil/big-bang/product/packages/eck-operator.git"` | | +| eckOperator.git.path | string | `"./chart"` | | +| eckOperator.git.tag | string | `"2.16.0-bb.0"` | | +| eckOperator.helmRepo.repoName | string | `"registry1"` | | +| eckOperator.helmRepo.chartName | string | `"eck-operator"` | | +| eckOperator.helmRepo.tag | string | `"2.16.0-bb.0"` | | +| eckOperator.flux | object | `{}` | Flux reconciliation overrides specifically for the ECK Operator Package | +| eckOperator.values | object | `{}` | Values to passthrough to the eck-operator chart: https://repo1.dso.mil/big-bang/product/packages/eck-operator.git | +| eckOperator.postRenderers | list | `[]` | Post Renderers. See docs/postrenders.md | +| fluentbit.enabled | bool | `false` | Toggle deployment of Fluent-Bit. | +| fluentbit.sourceType | string | `"git"` | Choose source type of "git" or "helmRepo" | +| fluentbit.git.repo | string | `"https://repo1.dso.mil/big-bang/product/packages/fluentbit.git"` | | +| fluentbit.git.path | string | `"./chart"` | | +| fluentbit.git.tag | string | `"0.48.4-bb.0"` | | +| fluentbit.helmRepo.repoName | string | `"registry1"` | | +| fluentbit.helmRepo.chartName | string | `"fluentbit"` | | +| fluentbit.helmRepo.tag | string | `"0.48.4-bb.0"` | | +| fluentbit.flux | object | `{}` | Flux reconciliation overrides specifically for the Fluent-Bit Package | +| fluentbit.values | object | `{}` | Values to passthrough to the fluentbit chart: https://repo1.dso.mil/big-bang/product/packages/fluentbit.git | +| fluentbit.postRenderers | list | `[]` | Post Renderers. See docs/postrenders.md | +| promtail.enabled | bool | `true` | Toggle deployment of Promtail. | +| promtail.sourceType | string | `"git"` | Choose source type of "git" or "helmRepo" | +| promtail.git.repo | string | `"https://repo1.dso.mil/big-bang/product/packages/promtail.git"` | | +| promtail.git.path | string | `"./chart"` | | +| promtail.git.tag | string | `"6.16.2-bb.4"` | | +| promtail.helmRepo.repoName | string | `"registry1"` | | +| promtail.helmRepo.chartName | string | `"promtail"` | | +| promtail.helmRepo.tag | string | `"6.16.2-bb.4"` | | +| promtail.flux | object | `{}` | Flux reconciliation overrides specifically for the Promtail Package | +| promtail.values | object | `{}` | Values to passthrough to the promtail chart: https://repo1.dso.mil/big-bang/product/packages/fluentbit.git | +| promtail.postRenderers | list | `[]` | Post Renderers. See docs/postrenders.md | +| loki.enabled | bool | `true` | Toggle deployment of Loki. | +| loki.sourceType | string | `"git"` | Choose source type of "git" or "helmRepo" | +| loki.git.repo | string | `"https://repo1.dso.mil/big-bang/product/packages/loki.git"` | | +| loki.git.path | string | `"./chart"` | | +| loki.git.tag | string | `"6.24.0-bb.0"` | | +| loki.helmRepo.repoName | string | `"registry1"` | | +| loki.helmRepo.chartName | string | `"loki"` | | +| loki.helmRepo.tag | string | `"6.24.0-bb.0"` | | +| loki.flux | object | `{}` | Flux reconciliation overrides specifically for the Loki Package | +| loki.strategy | string | `"monolith"` | Loki architecture. Options are monolith and scalable | +| loki.clusterName | string | `""` | Loki clusterName identifier for Promtail and Dashboards | +| loki.objectStorage.endpoint | string | `""` | S3 compatible endpoint to use for connection information. examples: "https://s3.amazonaws.com" "https://s3.us-gov-west-1.amazonaws.com" "http://minio.minio.svc.cluster.local:9000" | +| loki.objectStorage.region | string | `""` | S3 compatible region to use for connection information. | +| loki.objectStorage.accessKey | string | `""` | Access key for connecting to object storage endpoint. | +| loki.objectStorage.accessSecret | string | `""` | Secret key for connecting to object storage endpoint. Unencoded string data. This should be placed in the secret values and then encrypted | +| loki.objectStorage.bucketNames | object | `{}` | Bucket Names for the Loki buckets as YAML chunks: loki-logs ruler: loki-ruler admin: loki-admin | +| loki.values | object | `{}` | Values to passthrough to the Loki chart: https://repo1.dso.mil/big-bang/product/packages/loki.git | +| loki.postRenderers | list | `[]` | Post Renderers. See docs/postrenders.md | +| neuvector.enabled | bool | `true` | Toggle deployment of Neuvector. | +| neuvector.sourceType | string | `"git"` | Choose source type of "git" or "helmRepo" | +| neuvector.git.repo | string | `"https://repo1.dso.mil/big-bang/product/packages/neuvector.git"` | | +| neuvector.git.path | string | `"./chart"` | | +| neuvector.git.tag | string | `"2.8.3-bb.0"` | | +| neuvector.helmRepo.repoName | string | `"registry1"` | | +| neuvector.helmRepo.chartName | string | `"neuvector"` | | +| neuvector.helmRepo.tag | string | `"2.8.3-bb.0"` | | +| neuvector.ingress | object | `{"gateway":""}` | Redirect the package ingress to a specific Istio Gateway (listed in `istio.gateways`). The default is "public". | +| neuvector.sso.enabled | bool | `false` | Toggle SSO for Neuvector on and off | +| neuvector.sso.client_id | string | `""` | OIDC Client ID to use for Neuvector | +| neuvector.sso.client_secret | string | `""` | OIDC Client Secret to use for Neuvector | +| neuvector.sso.default_role | string | `""` | Default role to use for Neuvector OIDC users. Supports admin, reader, or no default | +| neuvector.sso.group_claim | string | `""` | Default role to use for Neuvector OIDC users. Supports admin, reader, or no default | +| neuvector.sso.group_mapped_roles | list | `[]` | Default role to use for Neuvector OIDC users. Supports admin, reader, or no default | +| neuvector.flux | object | `{}` | Flux reconciliation overrides specifically for the Neuvector Package | +| neuvector.values | object | `{}` | Values to passthrough to the Neuvector chart: https://repo1.dso.mil/big-bang/product/packages/neuvector.git | +| neuvector.postRenderers | list | `[]` | Post Renderers. See docs/postrenders.md | +| tempo.enabled | bool | `true` | Toggle deployment of Tempo. | +| tempo.sourceType | string | `"git"` | Choose source type of "git" or "helmRepo" | +| tempo.git.repo | string | `"https://repo1.dso.mil/big-bang/product/packages/tempo.git"` | | +| tempo.git.path | string | `"./chart"` | | +| tempo.git.tag | string | `"1.11.0-bb.1"` | | +| tempo.helmRepo.repoName | string | `"registry1"` | | +| tempo.helmRepo.chartName | string | `"tempo"` | | +| tempo.helmRepo.tag | string | `"1.11.0-bb.1"` | | +| tempo.ingress | object | `{"gateway":""}` | Redirect the package ingress to a specific Istio Gateway (listed in `istio.gateways`). The default is "public". | +| tempo.flux | object | `{}` | Flux reconciliation overrides specifically for the Tempo Package | +| tempo.sso.enabled | bool | `false` | Toggle SSO for Tempo on and off | +| tempo.sso.client_id | string | `""` | OIDC Client ID to use for Tempo | +| tempo.sso.client_secret | string | `""` | OIDC Client Secret to use for Tempo | +| tempo.objectStorage.endpoint | string | `""` | S3 compatible endpoint to use for connection information. examples: "s3.amazonaws.com" "s3.us-gov-west-1.amazonaws.com" "minio.minio.svc.cluster.local:9000" Note: tempo does not require protocol prefix for URL. | +| tempo.objectStorage.region | string | `""` | S3 compatible region to use for connection information. | +| tempo.objectStorage.accessKey | string | `""` | Access key for connecting to object storage endpoint. | +| tempo.objectStorage.accessSecret | string | `""` | Secret key for connecting to object storage endpoint. Unencoded string data. This should be placed in the secret values and then encrypted | +| tempo.objectStorage.bucket | string | `""` | Bucket Name for Tempo examples: "tempo-traces" | +| tempo.objectStorage.insecure | bool | `false` | Whether or not objectStorage connection should require HTTPS, if connecting to in-cluster object storage on port 80/9000 set this value to true. | +| tempo.values | object | `{}` | Values to passthrough to the Tempo chart: https://repo1.dso.mil/big-bang/product/packages/tempo.git | +| tempo.postRenderers | list | `[]` | Post Renderers. See docs/postrenders.md | +| monitoring.enabled | bool | `true` | Toggle deployment of Monitoring (Prometheus, Grafana, and Alertmanager). | +| monitoring.sourceType | string | `"git"` | Choose source type of "git" or "helmRepo" | +| monitoring.git.repo | string | `"https://repo1.dso.mil/big-bang/product/packages/monitoring.git"` | | +| monitoring.git.path | string | `"./chart"` | | +| monitoring.git.tag | string | `"66.3.1-bb.0"` | | +| monitoring.helmRepo.repoName | string | `"registry1"` | | +| monitoring.helmRepo.chartName | string | `"monitoring"` | | +| monitoring.helmRepo.tag | string | `"66.3.1-bb.0"` | | +| monitoring.flux | object | `{"install":{"crds":"CreateReplace"},"upgrade":{"crds":"CreateReplace"}}` | Flux reconciliation overrides specifically for the Monitoring Package | +| monitoring.ingress | object | `{"gateway":""}` | Redirect the package ingress to a specific Istio Gateway (listed in `istio.gateways`). The default is "public". | +| monitoring.sso.enabled | bool | `false` | Toggle SSO for monitoring components on and off | +| monitoring.sso.prometheus.client_id | string | `""` | Prometheus OIDC client ID | +| monitoring.sso.prometheus.client_secret | string | `""` | Prometheus OIDC client secret | +| monitoring.sso.alertmanager.client_id | string | `""` | Alertmanager OIDC client ID | +| monitoring.sso.alertmanager.client_secret | string | `""` | Alertmanager OIDC client secret | +| monitoring.values | object | `{}` | Values to passthrough to the monitoring chart: https://repo1.dso.mil/big-bang/product/packages/monitoring.git | +| monitoring.postRenderers | list | `[]` | Post Renderers. See docs/postrenders.md | +| grafana.enabled | bool | `true` | Toggle deployment of Grafana | +| grafana.sourceType | string | `"git"` | Choose source type of "git" or "helmRepo" | +| grafana.git.repo | string | `"https://repo1.dso.mil/big-bang/product/packages/grafana.git"` | | +| grafana.git.path | string | `"./chart"` | | +| grafana.git.tag | string | `"8.8.2-bb.0"` | | +| grafana.helmRepo.repoName | string | `"registry1"` | | +| grafana.helmRepo.chartName | string | `"grafana"` | | +| grafana.helmRepo.tag | string | `"8.8.2-bb.0"` | | +| grafana.flux | object | `{}` | Flux reconciliation overrides specifically for the Monitoring Package | +| grafana.ingress | object | `{"gateway":""}` | Redirect the package ingress to a specific Istio Gateway (listed in `istio.gateways`). The default is "public". | +| grafana.sso.enabled | bool | `false` | Toggle SSO for grafana components on and off | +| grafana.sso.grafana.client_id | string | `""` | Grafana OIDC client ID | +| grafana.sso.grafana.client_secret | string | `""` | Grafana OIDC client secret | +| grafana.sso.grafana.scopes | string | `""` | Grafana OIDC client scopes, comma separated, see https://grafana.com/docs/grafana/latest/auth/generic-oauth/ | +| grafana.sso.grafana.allow_sign_up | bool | `true` | | +| grafana.sso.grafana.role_attribute_path | string | `"Viewer"` | | +| grafana.values | object | `{}` | Values to passthrough to the grafana chart: https://repo1.dso.mil/big-bang/product/packages/grafana.git | +| grafana.postRenderers | list | `[]` | Post Renderers. See docs/postrenders.md | +| twistlock.enabled | bool | `false` | Toggle deployment of Twistlock. | +| twistlock.sourceType | string | `"git"` | Choose source type of "git" or "helmRepo" | +| twistlock.git.repo | string | `"https://repo1.dso.mil/big-bang/product/packages/twistlock.git"` | | +| twistlock.git.path | string | `"./chart"` | | +| twistlock.git.tag | string | `"0.18.0-bb.0"` | | +| twistlock.helmRepo.repoName | string | `"registry1"` | | +| twistlock.helmRepo.chartName | string | `"twistlock"` | | +| twistlock.helmRepo.tag | string | `"0.18.0-bb.0"` | | +| twistlock.flux | object | `{}` | Flux reconciliation overrides specifically for the Twistlock Package | +| twistlock.ingress | object | `{"gateway":""}` | Redirect the package ingress to a specific Istio Gateway (listed in `istio.gateways`). The default is "public". | +| twistlock.sso.enabled | bool | `false` | Toggle SAML SSO, requires a license and enabling the init job - see https://repo1.dso.mil/big-bang/product/packages/initialization.md | +| twistlock.sso.client_id | string | `""` | SAML client ID | +| twistlock.sso.provider_type | string | `"shibboleth"` | SAML Identity Provider. `shibboleth` is recommended by Twistlock support for Keycloak Possible values: okta, gsuite, ping, shibboleth, azure, adfs | +| twistlock.sso.groups | string | `""` | Groups attribute (optional) | +| twistlock.values | object | `{}` | Values to passthrough to the twistlock chart: https://repo1.dso.mil/big-bang/product/packages/twistlock.git | +| twistlock.postRenderers | list | `[]` | Post Renderers. See docs/postrenders.md | +| addons.argocd.enabled | bool | `false` | Toggle deployment of ArgoCD. | +| addons.argocd.sourceType | string | `"git"` | Choose source type of "git" or "helmRepo" | +| addons.argocd.git.repo | string | `"https://repo1.dso.mil/big-bang/product/packages/argocd.git"` | | +| addons.argocd.git.path | string | `"./chart"` | | +| addons.argocd.git.tag | string | `"7.7.5-bb.1"` | | +| addons.argocd.helmRepo.repoName | string | `"registry1"` | | +| addons.argocd.helmRepo.chartName | string | `"argocd"` | | +| addons.argocd.helmRepo.tag | string | `"7.7.5-bb.1"` | | +| addons.argocd.flux | object | `{}` | Flux reconciliation overrides specifically for the ArgoCD Package | +| addons.argocd.ingress | object | `{"gateway":""}` | Redirect the package ingress to a specific Istio Gateway (listed in `istio.gateways`). The default is "public". | +| addons.argocd.redis.host | string | `""` | Hostname of a pre-existing Redis to use for ArgoCD. Entering connection info will enable external Redis and will auto-create any required secrets. | +| addons.argocd.redis.port | string | `""` | Port of a pre-existing Redis to use for ArgoCD. | +| addons.argocd.sso.enabled | bool | `false` | Toggle SSO for ArgoCD on and off | +| addons.argocd.sso.client_id | string | `""` | ArgoCD OIDC client ID | +| addons.argocd.sso.client_secret | string | `""` | ArgoCD OIDC client secret | +| addons.argocd.sso.groups | string | `"g, Impact Level 2 Authorized, role:admin\n"` | ArgoCD SSO group roles, see docs for more details: https://argo-cd.readthedocs.io/en/stable/operator-manual/rbac/ | +| addons.argocd.values | object | `{}` | Values to passthrough to the argocd chart: https://repo1.dso.mil/big-bang/product/packages/argocd.git | +| addons.argocd.postRenderers | list | `[]` | Post Renderers. See docs/postrenders.md | +| addons.authservice.enabled | bool | `false` | Toggle deployment of Authservice. if enabling authservice, a filter needs to be provided by either enabling sso for monitoring or istio, or manually adding a filter chain in the values here: values: chain: minimal: callback_uri: "https://somecallback" | +| addons.authservice.sourceType | string | `"git"` | Choose source type of "git" or "helmRepo" | +| addons.authservice.git.repo | string | `"https://repo1.dso.mil/big-bang/product/packages/authservice.git"` | | +| addons.authservice.git.path | string | `"./chart"` | | +| addons.authservice.git.tag | string | `"1.0.3-bb.0"` | | +| addons.authservice.helmRepo.repoName | string | `"registry1"` | | +| addons.authservice.helmRepo.chartName | string | `"authservice"` | | +| addons.authservice.helmRepo.tag | string | `"1.0.3-bb.0"` | | +| addons.authservice.flux | object | `{}` | Flux reconciliation overrides specifically for the Authservice Package | +| addons.authservice.values | object | `{}` | Values to passthrough to the authservice chart: https://repo1.dso.mil/big-bang/product/packages/authservice.git | +| addons.authservice.postRenderers | list | `[]` | Post Renderers. See docs/postrenders.md | +| addons.authservice.chains | object | `{}` | Additional authservice chain configurations. | +| addons.minioOperator.enabled | bool | `false` | Toggle deployment of minio operator and instance. | +| addons.minioOperator.sourceType | string | `"git"` | Choose source type of "git" or "helmRepo" | +| addons.minioOperator.git.repo | string | `"https://repo1.dso.mil/big-bang/product/packages/minio-operator.git"` | | +| addons.minioOperator.git.path | string | `"./chart"` | | +| addons.minioOperator.git.tag | string | `"6.0.4-bb.0"` | | +| addons.minioOperator.helmRepo.repoName | string | `"registry1"` | | +| addons.minioOperator.helmRepo.chartName | string | `"minio-operator"` | | +| addons.minioOperator.helmRepo.tag | string | `"6.0.4-bb.0"` | | +| addons.minioOperator.flux | object | `{}` | Flux reconciliation overrides specifically for the Minio Operator Package | +| addons.minioOperator.ingress | object | `{"gateway":""}` | Redirect the package ingress to a specific Istio Gateway (listed in `istio.gateways`). The default is "public". | +| addons.minioOperator.values | object | `{}` | Values to passthrough to the minio operator chart: https://repo1.dso.mil/big-bang/product/packages/minio-operator.git | +| addons.minioOperator.postRenderers | list | `[]` | Post Renderers. See docs/postrenders.md | +| addons.minio.enabled | bool | `false` | Toggle deployment of minio. | +| addons.minio.sourceType | string | `"git"` | Choose source type of "git" or "helmRepo" | +| addons.minio.git.repo | string | `"https://repo1.dso.mil/big-bang/product/packages/minio.git"` | | +| addons.minio.git.path | string | `"./chart"` | | +| addons.minio.git.tag | string | `"6.0.4-bb.5"` | | +| addons.minio.helmRepo.repoName | string | `"registry1"` | | +| addons.minio.helmRepo.chartName | string | `"minio-instance"` | | +| addons.minio.helmRepo.tag | string | `"6.0.4-bb.5"` | | +| addons.minio.flux | object | `{}` | Flux reconciliation overrides specifically for the Minio Package | +| addons.minio.ingress | object | `{"gateway":""}` | Redirect the package ingress to a specific Istio Gateway (listed in `istio.gateways`). The default is "public". | +| addons.minio.accesskey | string | `""` | Default access key to use for minio. | +| addons.minio.secretkey | string | `""` | Default secret key to intstantiate with minio, you should change/delete this after installation. | +| addons.minio.values | object | `{}` | Values to passthrough to the minio instance chart: https://repo1.dso.mil/big-bang/product/packages/minio.git | +| addons.minio.postRenderers | list | `[]` | Post Renderers. See docs/postrenders.md | +| addons.gitlab.enabled | bool | `false` | Toggle deployment of Gitlab | +| addons.gitlab.hostnames.gitlab | string | `"gitlab"` | | +| addons.gitlab.hostnames.registry | string | `"registry"` | | +| addons.gitlab.sourceType | string | `"git"` | Choose source type of "git" or "helmRepo" | +| addons.gitlab.git.repo | string | `"https://repo1.dso.mil/big-bang/product/packages/gitlab.git"` | | +| addons.gitlab.git.path | string | `"./chart"` | | +| addons.gitlab.git.tag | string | `"8.6.2-bb.0"` | | +| addons.gitlab.helmRepo.repoName | string | `"registry1"` | | +| addons.gitlab.helmRepo.chartName | string | `"gitlab"` | | +| addons.gitlab.helmRepo.tag | string | `"8.6.2-bb.0"` | | +| addons.gitlab.flux | object | `{}` | Flux reconciliation overrides specifically for the Gitlab Package | +| addons.gitlab.ingress | object | `{"gateway":""}` | Redirect the package ingress to a specific Istio Gateway (listed in `istio.gateways`). The default is "public". | +| addons.gitlab.sso.enabled | bool | `false` | Toggle OIDC SSO for Gitlab on and off. Enabling this option will auto-create any required secrets. | +| addons.gitlab.sso.client_id | string | `""` | Gitlab OIDC client ID | +| addons.gitlab.sso.client_secret | string | `""` | Gitlab OIDC client secret | +| addons.gitlab.sso.scopes | list | `["Gitlab"]` | Gitlab SSO Scopes, default is ["Gitlab"] | +| addons.gitlab.sso.groups | list | `[]` | Fill out the groups block below and populate with Keycloak groups according to your desired Gitlab membership requirements. The default groupsAttribute is "groups". Full documentation: https://docs.gitlab.com/ee/administration/auth/oidc.html?tab=Linux+package+%28Omnibus%29#configure-users-based-on-oidc-group-membership | +| addons.gitlab.database.host | string | `""` | Hostname of a pre-existing PostgreSQL database to use for Gitlab. Entering connection info will disable the deployment of an internal database and will auto-create any required secrets. | +| addons.gitlab.database.port | int | `5432` | Port of a pre-existing PostgreSQL database to use for Gitlab. | +| addons.gitlab.database.database | string | `""` | Database name to connect to on host. | +| addons.gitlab.database.username | string | `""` | Username to connect as to external database, the user must have all privileges on the database. | +| addons.gitlab.database.password | string | `""` | Database password for the username used to connect to the existing database. | +| addons.gitlab.objectStorage.type | string | `""` | Type of object storage to use for Gitlab, setting to s3 will assume an external, pre-existing object storage is to be used. Entering connection info will enable this option and will auto-create any required secrets | +| addons.gitlab.objectStorage.endpoint | string | `""` | S3 compatible endpoint to use for connection information. examples: "https://s3.amazonaws.com" "https://s3.us-gov-west-1.amazonaws.com" "http://minio.minio.svc.cluster.local:9000" | +| addons.gitlab.objectStorage.region | string | `""` | S3 compatible region to use for connection information. | +| addons.gitlab.objectStorage.accessKey | string | `""` | Access key for connecting to object storage endpoint. -- If using accessKey and accessSecret, the iamProfile must be left as an empty string: "" | +| addons.gitlab.objectStorage.accessSecret | string | `""` | Secret key for connecting to object storage endpoint. Unencoded string data. This should be placed in the secret values and then encrypted | +| addons.gitlab.objectStorage.bucketPrefix | string | `""` | Bucket prefix to use for identifying buckets. Example: "prod" will produce "prod-gitlab-bucket" | +| addons.gitlab.objectStorage.iamProfile | string | `""` | NOTE: Current bug with AWS IAM Profiles and Object Storage where only artifacts are stored. Fixed in Gitlab 14.5 -- Name of AWS IAM profile to use. -- If using an AWS IAM profile, the accessKey and accessSecret values must be left as empty strings eg: "" | +| addons.gitlab.smtp.password | string | `""` | Passwords should be placed in an encrypted file. Example: environment-bb-secret.enc.yaml If a value is provided BigBang will create a k8s secret named gitlab-smtp-password in the gitlab namespace | +| addons.gitlab.redis.password | string | `""` | Redis plain text password to connect to the redis server. If empty (""), the gitlab charts will create the gitlab-redis-secret with a random password. -- This needs to be set to a non-empty value in order for the Grafana Redis Datasource and Dashboards to be installed. | +| addons.gitlab.railsSecret | string | `""` | Rails plain text secret to define. If empty (""), the gitlab charts will create the gitlab-rails-secret with randomized data. Read the following for more information on setting Gitlab rails secrets: https://docs.gitlab.com/charts/installation/secrets#gitlab-rails-secret | +| addons.gitlab.values | object | `{}` | Values to passthrough to the gitlab chart: https://repo1.dso.mil/big-bang/product/packages/gitlab.git | +| addons.gitlab.postRenderers | list | `[]` | Post Renderers. See docs/postrenders.md | +| addons.gitlabRunner.enabled | bool | `false` | Toggle deployment of Gitlab Runner | +| addons.gitlabRunner.sourceType | string | `"git"` | Choose source type of "git" or "helmRepo" | +| addons.gitlabRunner.git.repo | string | `"https://repo1.dso.mil/big-bang/product/packages/gitlab-runner.git"` | | +| addons.gitlabRunner.git.path | string | `"./chart"` | | +| addons.gitlabRunner.git.tag | string | `"0.70.4-bb.1"` | | +| addons.gitlabRunner.helmRepo.repoName | string | `"registry1"` | | +| addons.gitlabRunner.helmRepo.chartName | string | `"gitlab-runner"` | | +| addons.gitlabRunner.helmRepo.tag | string | `"0.70.4-bb.1"` | | +| addons.gitlabRunner.flux | object | `{}` | Flux reconciliation overrides specifically for the Gitlab Runner Package | +| addons.gitlabRunner.values | object | `{}` | Values to passthrough to the gitlab runner chart: https://repo1.dso.mil/big-bang/product/packages/gitlab-runner.git | +| addons.gitlabRunner.postRenderers | list | `[]` | Post Renderers. See docs/postrenders.md | +| addons.nexusRepositoryManager.enabled | bool | `false` | Toggle deployment of Nexus Repository Manager. | +| addons.nexusRepositoryManager.sourceType | string | `"git"` | Choose source type of "git" or "helmRepo" | +| addons.nexusRepositoryManager.git.repo | string | `"https://repo1.dso.mil/big-bang/product/packages/nexus.git"` | | +| addons.nexusRepositoryManager.git.path | string | `"./chart"` | | +| addons.nexusRepositoryManager.git.tag | string | `"75.0.0-bb.1"` | | +| addons.nexusRepositoryManager.helmRepo.repoName | string | `"registry1"` | | +| addons.nexusRepositoryManager.helmRepo.chartName | string | `"nexus-repository-manager"` | | +| addons.nexusRepositoryManager.helmRepo.tag | string | `"75.0.0-bb.1"` | | +| addons.nexusRepositoryManager.license_key | string | `""` | Base64 encoded license file. | +| addons.nexusRepositoryManager.ingress | object | `{"gateway":""}` | Redirect the package ingress to a specific Istio Gateway (listed in `istio.gateways`). The default is "public". | +| addons.nexusRepositoryManager.sso.enabled | bool | `false` | Toggle SAML SSO for NXRM. -- handles SAML SSO, a Client must be configured in Keycloak or IdP -- to complete setup. -- https://support.sonatype.com/hc/en-us/articles/1500000976522-SAML-integration-for-Nexus-Repository-Manager-Pro-3-and-Nexus-IQ-Server-with-Keycloak#h_01EV7CWCYH3YKAPMAHG8XMQ599 | +| addons.nexusRepositoryManager.sso.idp_data | object | `{"email":"","entityId":"","firstName":"","groups":"","lastName":"","username":""}` | NXRM SAML SSO Integration data | +| addons.nexusRepositoryManager.sso.idp_data.username | string | `""` | IdP Field Mappings -- NXRM username attribute | +| addons.nexusRepositoryManager.sso.idp_data.firstName | string | `""` | NXRM firstname attribute (optional) | +| addons.nexusRepositoryManager.sso.idp_data.lastName | string | `""` | NXRM lastname attribute (optional) | +| addons.nexusRepositoryManager.sso.idp_data.email | string | `""` | NXRM email attribute (optional) | +| addons.nexusRepositoryManager.sso.idp_data.groups | string | `""` | NXRM groups attribute (optional) | +| addons.nexusRepositoryManager.sso.role | list | `[{"description":"","id":"","name":"","privileges":[],"roles":[]}]` | NXRM Role | +| addons.nexusRepositoryManager.flux | object | `{}` | Flux reconciliation overrides specifically for the Nexus Repository Manager Package | +| addons.nexusRepositoryManager.values | object | `{}` | Values to passthrough to the nxrm chart: https://repo1.dso.mil/big-bang/product/packages/nexus.git | +| addons.nexusRepositoryManager.postRenderers | list | `[]` | Post Renderers. See docs/postrenders.md | +| addons.sonarqube.enabled | bool | `false` | Toggle deployment of SonarQube. | +| addons.sonarqube.sourceType | string | `"git"` | Choose source type of "git" or "helmRepo" | +| addons.sonarqube.git.repo | string | `"https://repo1.dso.mil/big-bang/product/packages/sonarqube.git"` | | +| addons.sonarqube.git.path | string | `"./chart"` | | +| addons.sonarqube.git.tag | string | `"10.6.1-bb.5"` | | +| addons.sonarqube.helmRepo.repoName | string | `"registry1"` | | +| addons.sonarqube.helmRepo.chartName | string | `"sonarqube"` | | +| addons.sonarqube.helmRepo.tag | string | `"10.6.1-bb.5"` | | +| addons.sonarqube.flux | object | `{}` | Flux reconciliation overrides specifically for the Sonarqube Package | +| addons.sonarqube.ingress | object | `{"gateway":""}` | Redirect the package ingress to a specific Istio Gateway (listed in `istio.gateways`). The default is "public". | +| addons.sonarqube.sso.enabled | bool | `false` | Toggle SAML SSO for SonarQube. Enabling this option will auto-create any required secrets. | +| addons.sonarqube.sso.client_id | string | `""` | SonarQube SAML client ID | +| addons.sonarqube.sso.login | string | `"login"` | SonarQube login sso attribute. | +| addons.sonarqube.sso.name | string | `"name"` | SonarQube name sso attribute. | +| addons.sonarqube.sso.email | string | `"email"` | SonarQube email sso attribute. | +| addons.sonarqube.sso.group | string | `"group"` | (optional) SonarQube group sso attribute. | +| addons.sonarqube.database.host | string | `""` | Hostname of a pre-existing PostgreSQL database to use for SonarQube. | +| addons.sonarqube.database.port | int | `5432` | Port of a pre-existing PostgreSQL database to use for SonarQube. | +| addons.sonarqube.database.database | string | `""` | Database name to connect to on host. | +| addons.sonarqube.database.username | string | `""` | Username to connect as to external database, the user must have all privileges on the database. | +| addons.sonarqube.database.password | string | `""` | Database password for the username used to connect to the existing database. | +| addons.sonarqube.values | object | `{}` | Values to passthrough to the sonarqube chart: https://repo1.dso.mil/big-bang/product/packages/sonarqube.git | +| addons.sonarqube.postRenderers | list | `[]` | Post Renderers. See docs/postrenders.md | +| addons.fortify.enabled | bool | `false` | Toggle deployment of Fortify. | +| addons.fortify.sourceType | string | `"git"` | Choose source type of "git" or "helmRepo" | +| addons.fortify.git.repo | string | `"https://repo1.dso.mil/big-bang/product/packages/fortify.git"` | | +| addons.fortify.git.path | string | `"./chart"` | | +| addons.fortify.git.tag | string | `"1.1.2320154-bb.21"` | | +| addons.fortify.helmRepo.repoName | string | `"registry1"` | | +| addons.fortify.helmRepo.chartName | string | `"fortify-ssc"` | | +| addons.fortify.helmRepo.tag | string | `"1.1.2320154-bb.21"` | | +| addons.fortify.flux | object | `{}` | Flux reconciliation overrides specifically for the Fortify Package | +| addons.fortify.ingress | object | `{"gateway":""}` | Redirect the package ingress to a specific Istio Gateway (listed in `istio.gateways`). The default is "public". | +| addons.fortify.sso.enabled | bool | `false` | Toggle SSO for Fortify on and off | +| addons.fortify.sso.client_id | string | `""` | SAML Client ID to use for Fortify | +| addons.fortify.sso.client_secret | string | `""` | SAML Client Secret to use for Fortify | +| addons.fortify.values | object | `{}` | Values to passthrough to the fortify chart: https://repo1.dso.mil/big-bang/product/packages/fortify.git | +| addons.fortify.postRenderers | list | `[]` | Post Renderers. See docs/postrenders.md | +| addons.haproxy.sourceType | string | `"git"` | Choose source type of "git" or "helmRepo" | +| addons.haproxy.git.repo | string | `"https://repo1.dso.mil/big-bang/product/packages/haproxy.git"` | | +| addons.haproxy.git.path | string | `"./chart"` | | +| addons.haproxy.git.tag | string | `"1.19.3-bb.8"` | | +| addons.haproxy.helmRepo.repoName | string | `"registry1"` | | +| addons.haproxy.helmRepo.chartName | string | `"haproxy"` | | +| addons.haproxy.helmRepo.tag | string | `"1.19.3-bb.8"` | | +| addons.haproxy.flux | object | `{}` | Flux reconciliation overrides specifically for the HAProxy Package | +| addons.haproxy.ingress | object | `{"gateway":""}` | Redirect the package ingress to a specific Istio Gateway (listed in `istio.gateways`). The default is "public". | +| addons.haproxy.values | object | `{}` | Values to passthrough to the haproxy chart: https://repo1.dso.mil/big-bang/product/packages/haproxy.git | +| addons.haproxy.postRenderers | list | `[]` | Post Renderers. See docs/postrenders.md | +| addons.anchore.enabled | bool | `false` | Toggle deployment of Anchore. | +| addons.anchore.sourceType | string | `"git"` | Choose source type of "git" or "helmRepo" | +| addons.anchore.git.repo | string | `"https://repo1.dso.mil/big-bang/product/packages/anchore-enterprise.git"` | | +| addons.anchore.git.path | string | `"./chart"` | | +| addons.anchore.git.tag | string | `"3.2.0-bb.1"` | | +| addons.anchore.helmRepo.repoName | string | `"registry1"` | | +| addons.anchore.helmRepo.chartName | string | `"anchore"` | | +| addons.anchore.helmRepo.tag | string | `"3.2.0-bb.1"` | | +| addons.anchore.flux | object | `{"upgrade":{"disableWait":true}}` | Flux reconciliation overrides specifically for the Anchore Package | +| addons.anchore.adminPassword | string | `""` | Initial admin password used to authenticate to Anchore. | +| addons.anchore.enterprise | object | `{"licenseYaml":"FULL LICENSE\n"}` | Anchore Enterprise functionality. | +| addons.anchore.enterprise.licenseYaml | string | `"FULL LICENSE\n"` | License for Anchore Enterprise. Enterprise is the only option available for the chart starting with chart major version 2.X. For formatting examples see https://repo1.dso.mil/big-bang/product/packages/CHART.md#enabling-enterprise-services | +| addons.anchore.ingress | object | `{"gateway":""}` | Redirect the package ingress to a specific Istio Gateway (listed in `istio.gateways`). The default is "public". | +| addons.anchore.sso.enabled | bool | `false` | Toggle SAML SSO for Anchore on and off. Enabling this option will auto-create any required secrets (Note: SSO requires an Enterprise license). | +| addons.anchore.sso.client_id | string | `""` | Anchore SAML client ID | +| addons.anchore.sso.role_attribute | string | `""` | Anchore SAML client role attribute | +| addons.anchore.database.host | string | `""` | Hostname of a pre-existing PostgreSQL database to use for Anchore. Entering connection info will disable the deployment of an internal database and will auto-create any required secrets. | +| addons.anchore.database.port | string | `""` | Port of a pre-existing PostgreSQL database to use for Anchore. | +| addons.anchore.database.username | string | `""` | Username to connect as to external database, the user must have all privileges on the database. | +| addons.anchore.database.password | string | `""` | Database password for the username used to connect to the existing database. | +| addons.anchore.database.database | string | `""` | Database name to connect to on host (Note: database name CANNOT contain hyphens). | +| addons.anchore.database.feeds_database | string | `""` | Feeds database name to connect to on host (Note: feeds database name CANNOT contain hyphens). Only required for enterprise edition of anchore. By default, feeds database will be configured with the same username and password as the main database. For formatting examples on how to use a separate username and password for the feeds database see https://repo1.dso.mil/big-bang/product/packages/CHART.md#handling-dependencies | +| addons.anchore.redis.host | string | `""` | Hostname of a pre-existing Redis to use for Anchore Enterprise. Entering connection info will enable external redis and will auto-create any required secrets. Anchore only requires redis for enterprise deployments and will not provision an instance if using external | +| addons.anchore.redis.port | string | `""` | Port of a pre-existing Redis to use for Anchore Enterprise. | +| addons.anchore.redis.username | string | `""` | OPTIONAL: Username to connect to a pre-existing Redis (for password-only auth leave empty) | +| addons.anchore.redis.password | string | `""` | Password to connect to pre-existing Redis. | +| addons.anchore.values | object | `{}` | Values to passthrough to the anchore chart: https://repo1.dso.mil/big-bang/product/packages/anchore-enterprise.git | +| addons.anchore.postRenderers | list | `[]` | Post Renderers. See docs/postrenders.md | +| addons.mattermostOperator.enabled | bool | `false` | Toggle deployment of Mattermost Operator. | +| addons.mattermostOperator.sourceType | string | `"git"` | Choose source type of "git" or "helmRepo" | +| addons.mattermostOperator.git.repo | string | `"https://repo1.dso.mil/big-bang/product/packages/mattermost-operator.git"` | | +| addons.mattermostOperator.git.path | string | `"./chart"` | | +| addons.mattermostOperator.git.tag | string | `"1.22.1-bb.1"` | | +| addons.mattermostOperator.helmRepo.repoName | string | `"registry1"` | | +| addons.mattermostOperator.helmRepo.chartName | string | `"mattermost-operator"` | | +| addons.mattermostOperator.helmRepo.tag | string | `"1.22.1-bb.1"` | | +| addons.mattermostOperator.flux | object | `{}` | Flux reconciliation overrides specifically for the Mattermost Operator Package | +| addons.mattermostOperator.values | object | `{}` | Values to passthrough to the mattermost operator chart: https://repo1.dso.mil/big-bang/product/packages/values.yaml | +| addons.mattermostOperator.postRenderers | list | `[]` | Post Renderers. See docs/postrenders.md | +| addons.mattermost.enabled | bool | `false` | Toggle deployment of Mattermost. | +| addons.mattermost.sourceType | string | `"git"` | Choose source type of "git" or "helmRepo" | +| addons.mattermost.git.repo | string | `"https://repo1.dso.mil/big-bang/product/packages/mattermost.git"` | | +| addons.mattermost.git.path | string | `"./chart"` | | +| addons.mattermost.git.tag | string | `"10.2.0-bb.1"` | | +| addons.mattermost.helmRepo.repoName | string | `"registry1"` | | +| addons.mattermost.helmRepo.chartName | string | `"mattermost"` | | +| addons.mattermost.helmRepo.tag | string | `"10.2.0-bb.1"` | | +| addons.mattermost.flux | object | `{}` | Flux reconciliation overrides specifically for the Mattermost Package | +| addons.mattermost.enterprise | object | `{"enabled":false,"license":""}` | Mattermost Enterprise functionality. | +| addons.mattermost.enterprise.enabled | bool | `false` | Toggle the Mattermost Enterprise. This must be accompanied by a valid license unless you plan to start a trial post-install. | +| addons.mattermost.enterprise.license | string | `""` | License for Mattermost. This should be the entire contents of the license file from Mattermost (should be one line), example below license: "eyJpZCI6InIxM205bjR3eTdkYjludG95Z3RiOD---REST---IS---HIDDEN | +| addons.mattermost.ingress | object | `{"gateway":""}` | Redirect the package ingress to a specific Istio Gateway (listed in `istio.gateways`). The default is "public". | +| addons.mattermost.sso.enabled | bool | `false` | Toggle OIDC SSO for Mattermost on and off. Enabling this option will auto-create any required secrets. | +| addons.mattermost.sso.client_id | string | `""` | Mattermost OIDC client ID | +| addons.mattermost.sso.client_secret | string | `""` | Mattermost OIDC client secret | +| addons.mattermost.database.host | string | `""` | Hostname of a pre-existing PostgreSQL database to use for Mattermost. Entering connection info will disable the deployment of an internal database and will auto-create any required secrets. | +| addons.mattermost.database.port | string | `""` | Port of a pre-existing PostgreSQL database to use for Mattermost. | +| addons.mattermost.database.username | string | `""` | Username to connect as to external database, the user must have all privileges on the database. | +| addons.mattermost.database.password | string | `""` | Database password for the username used to connect to the existing database. | +| addons.mattermost.database.database | string | `""` | Database name to connect to on host. | +| addons.mattermost.database.ssl_mode | string | `""` | SSL Mode to use when connecting to the database. Allowable values for this are viewable in the postgres documentation: https://www.postgresql.org/docs/current/libpq-ssl.html#LIBPQ-SSL-SSLMODE-STATEMENTS | +| addons.mattermost.objectStorage.endpoint | string | `""` | S3 compatible endpoint to use for connection information. Entering connection info will enable this option and will auto-create any required secrets. examples: "s3.amazonaws.com" "s3.us-gov-west-1.amazonaws.com" "minio.minio.svc.cluster.local:9000" | +| addons.mattermost.objectStorage.accessKey | string | `""` | Access key for connecting to object storage endpoint. | +| addons.mattermost.objectStorage.accessSecret | string | `""` | Secret key for connecting to object storage endpoint. Unencoded string data. This should be placed in the secret values and then encrypted | +| addons.mattermost.objectStorage.bucket | string | `""` | Bucket name to use for Mattermost - will be auto-created. | +| addons.mattermost.elasticsearch | object | `{"enabled":false}` | Mattermost Elasticsearch integration - requires enterprise E20 license - https://docs.mattermost.com/deployment/elasticsearch.html Connection info defaults to the BB deployed Elastic, all values can be overridden via the "values" passthrough for other connections. See values spec in MM chart "elasticsearch" yaml block - https://repo1.dso.mil/big-bang/product/packages/values.yaml | +| addons.mattermost.elasticsearch.enabled | bool | `false` | Toggle interaction with Elastic for optimized search indexing | +| addons.mattermost.values | object | `{}` | Values to passthrough to the Mattermost chart: https://repo1.dso.mil/big-bang/product/packages/values.yaml | +| addons.mattermost.postRenderers | list | `[]` | Post Renderers. See docs/postrenders.md | +| addons.velero.enabled | bool | `false` | Toggle deployment of Velero. | +| addons.velero.sourceType | string | `"git"` | Choose source type of "git" or "helmRepo" | +| addons.velero.git.repo | string | `"https://repo1.dso.mil/big-bang/product/packages/velero.git"` | | +| addons.velero.git.path | string | `"./chart"` | | +| addons.velero.git.tag | string | `"8.1.0-bb.0"` | | +| addons.velero.helmRepo.repoName | string | `"registry1"` | | +| addons.velero.helmRepo.chartName | string | `"velero"` | | +| addons.velero.helmRepo.tag | string | `"8.1.0-bb.0"` | | +| addons.velero.flux | object | `{}` | Flux reconciliation overrides specifically for the Velero Package | +| addons.velero.plugins | list | `[]` | Plugin provider for Velero - requires at least one plugin installed. Current supported values: aws, azure, csi | +| addons.velero.values | object | `{}` | Values to passthrough to the Velero chart: https://repo1.dso.mil/big-bang/product/packages/values.yaml | +| addons.velero.postRenderers | list | `[]` | Post Renderers. See docs/postrenders.md | +| addons.keycloak.enabled | bool | `false` | Toggle deployment of Keycloak. if you enable Keycloak you should uncomment the istio passthrough configurations above istio.ingressGateways.passthrough-ingressgateway and istio.gateways.passthrough | +| addons.keycloak.sourceType | string | `"git"` | Choose source type of "git" or "helmRepo" | +| addons.keycloak.git.repo | string | `"https://repo1.dso.mil/big-bang/product/packages/keycloak.git"` | | +| addons.keycloak.git.path | string | `"./chart"` | | +| addons.keycloak.git.tag | string | `"2.5.1-bb.3"` | | +| addons.keycloak.helmRepo.repoName | string | `"registry1"` | | +| addons.keycloak.helmRepo.chartName | string | `"keycloak"` | | +| addons.keycloak.helmRepo.tag | string | `"2.5.1-bb.3"` | | +| addons.keycloak.database.host | string | `""` | Hostname of a pre-existing database to use for Keycloak. Entering connection info will disable the deployment of an internal database and will auto-create any required secrets. | +| addons.keycloak.database.type | string | `"postgres"` | Pre-existing database type (e.g. postgres) to use for Keycloak. | +| addons.keycloak.database.port | int | `5432` | Port of a pre-existing database to use for Keycloak. | +| addons.keycloak.database.database | string | `""` | Database name to connect to on host. | +| addons.keycloak.database.username | string | `""` | Username to connect as to external database, the user must have all privileges on the database. | +| addons.keycloak.database.password | string | `""` | Database password for the username used to connect to the existing database. | +| addons.keycloak.flux | object | `{}` | Flux reconciliation overrides specifically for the OPA Gatekeeper Package | +| addons.keycloak.ingress | object | `{"cert":"","gateway":"passthrough","key":""}` | Redirect the package ingress to a specific Istio Gateway (listed in `istio.gateways`). The default is "public". | +| addons.keycloak.ingress.key | string | `""` | Certificate/Key pair to use as the certificate for exposing Keycloak Setting the ingress cert here will automatically create the volume and volumemounts in the Keycloak Package chart | +| addons.keycloak.values | object | `{}` | Values to passthrough to the keycloak chart: https://repo1.dso.mil/big-bang/product/packages/keycloak.git | +| addons.keycloak.postRenderers | list | `[]` | Post Renderers. See docs/postrenders.md | +| addons.vault.enabled | bool | `false` | Toggle deployment of Vault. | +| addons.vault.sourceType | string | `"git"` | Choose source type of "git" or "helmRepo" | +| addons.vault.git.repo | string | `"https://repo1.dso.mil/big-bang/product/packages/vault.git"` | | +| addons.vault.git.path | string | `"./chart"` | | +| addons.vault.git.tag | string | `"0.29.1-bb.2"` | | +| addons.vault.helmRepo.repoName | string | `"registry1"` | | +| addons.vault.helmRepo.chartName | string | `"vault"` | | +| addons.vault.helmRepo.tag | string | `"0.29.1-bb.2"` | | +| addons.vault.flux | object | `{}` | Flux reconciliation overrides specifically for the Vault Package | +| addons.vault.ingress | object | `{"cert":"","gateway":"","key":""}` | Redirect the package ingress to a specific Istio Gateway (listed in `istio.gateways`). The default is "public". | +| addons.vault.ingress.key | string | `""` | Certificate/Key pair to use as the certificate for exposing Vault Setting the ingress cert here will automatically create the volume and volumemounts in the Vault package chart | +| addons.vault.values | object | `{}` | Values to passthrough to the vault chart: https://repo1.dso.mil/big-bang/product/packages/vault.git | +| addons.vault.postRenderers | list | `[]` | Post Renderers. See docs/postrenders.md | +| addons.metricsServer.enabled | string | `"auto"` | Toggle deployment of metrics server Acceptable options are enabled: true, enabled: false, enabled: auto true = enabled / false = disabled / auto = automatic (Installs only if metrics API endpoint is not present) | +| addons.metricsServer.sourceType | string | `"git"` | Choose source type of "git" or "helmRepo" | +| addons.metricsServer.git.repo | string | `"https://repo1.dso.mil/big-bang/product/packages/metrics-server.git"` | | +| addons.metricsServer.git.path | string | `"./chart"` | | +| addons.metricsServer.git.tag | string | `"3.12.2-bb.1"` | | +| addons.metricsServer.helmRepo.repoName | string | `"registry1"` | | +| addons.metricsServer.helmRepo.chartName | string | `"metrics-server"` | | +| addons.metricsServer.helmRepo.tag | string | `"3.12.2-bb.1"` | | +| addons.metricsServer.flux | object | `{}` | Flux reconciliation overrides specifically for the metrics server Package | +| addons.metricsServer.values | object | `{}` | Values to passthrough to the metrics server chart: https://repo1.dso.mil/big-bang/product/packages/metrics-server.git | +| addons.metricsServer.postRenderers | list | `[]` | Post Renderers. See docs/postrenders.md | +| addons.harbor.enabled | bool | `false` | Toggle deployment of harbor | +| addons.harbor.sourceType | string | `"git"` | Choose source type of "git" or "helmRepo" | +| addons.harbor.git.repo | string | `"https://repo1.dso.mil/platform-one/big-bang/apps/sandbox/harbor.git"` | | +| addons.harbor.git.tag | string | `"1.16.0-bb.2"` | | +| addons.harbor.git.path | string | `"./chart"` | | +| addons.harbor.helmRepo.repoName | string | `"registry1"` | | +| addons.harbor.helmRepo.chartName | string | `"harbor"` | | +| addons.harbor.helmRepo.tag | string | `"1.16.0-bb.2"` | | +| addons.harbor.flux | object | `{}` | Flux reconciliation overrides specifically for the Jaeger Package | +| addons.harbor.ingress | object | `{"gateway":""}` | Redirect the package ingress to a specific Istio Gateway (listed in `istio.gateways`). The default is "public". | +| addons.harbor.values | object | `{}` | Values to pass through to Habor chart: https://repo1.dso.mil/big-bang/product/packages/harbor.git | +| addons.harbor.postRenderers | list | `[]` | Post Renderers. See docs/postrenders.md | +| addons.holocron.enabled | bool | `false` | Toggle deployment of Holocron. | +| addons.holocron.sourceType | string | `"git"` | Choose source type of "git" or "helmRepo" | +| addons.holocron.git.repo | string | `"https://repo1.dso.mil/big-bang/product/packages/holocron.git"` | | +| addons.holocron.git.tag | string | `"1.0.12"` | | +| addons.holocron.git.path | string | `"./chart"` | | +| addons.holocron.helmRepo.repoName | string | `"registry1"` | | +| addons.holocron.helmRepo.chartName | string | `"holocron"` | | +| addons.holocron.helmRepo.tag | string | `"1.0.12"` | | +| addons.holocron.collectorAuth.existingSecret | string | `""` | Name of existing secret with auth tokens for collector services: https://repo1.dso.mil/groups/big-bang/apps/sandbox/holocron/-/wikis/Administrator-Guide -- Default keys for secret are: -- gitlab-scm-0, gitlab-workflow-0, gitlab-build-0, jira-workflow-0, sonarqube-project-analysis-0 -- If not provided, one will be created | +| addons.holocron.collectorAuth.gitlabToken | string | `"mygitlabtoken"` | Tokens for the secret to be created | +| addons.holocron.collectorAuth.jiraToken | string | `"myjiratoken"` | | +| addons.holocron.collectorAuth.sonarToken | string | `"mysonartoken"` | | +| addons.holocron.jira.enabled | bool | `false` | If there is a Jira deployment, enable a collector for it | +| addons.holocron.jira.service.name | string | `""` | The service name to communicate with | +| addons.holocron.jira.service.label | object | `{"key":"value"}` | If network policies are enabled, a label to match the namespace for egress policy | +| addons.holocron.flux | object | `{}` | Flux reconciliation overrides specifically for the Holocron Package | +| addons.holocron.ingress | object | `{"gateway":""}` | Redirect the package ingress to a specific Istio Gateway (listed in `istio.gateways`). The default is "public". | +| addons.holocron.sso.enabled | bool | `false` | Toggle SSO for Holocron on and off | +| addons.holocron.sso.client_id | string | `""` | OIDC Client ID to use for Holocron | +| addons.holocron.sso.client_secret | string | `""` | OIDC Client Secret to use for Holocron | +| addons.holocron.sso.groups | object | `{"admin":"","leadership":""}` | Holocron SSO group roles: https://repo1.dso.mil/groups/big-bang/apps/sandbox/holocron/-/wikis/Administrator-Guide | +| addons.holocron.database.host | string | `""` | Hostname of a pre-existing PostgreSQL database to use for Gitlab. -- Entering connection info will disable the deployment of an internal database and will auto-create any required secrets. | +| addons.holocron.database.port | int | `5432` | Port of a pre-existing PostgreSQL database to use for Gitlab. | +| addons.holocron.database.database | string | `"holocron"` | Database name to connect to on host. | +| addons.holocron.database.username | string | `"holocron"` | Username to connect as to external database, the user must have all privileges on the database. | +| addons.holocron.database.password | string | `"holocron"` | Database password for the username used to connect to the existing database. | +| addons.holocron.postRenderers | list | `[]` | Post Renderers. See docs/postrenders.md | +| addons.holocron.values | object | `{}` | Values to passthrough to the Holocron chart: https://repo1.dso.mil/big-bang/product/packages/holocron.git | +| addons.thanos.enabled | bool | `false` | Toggle deployment of thanos | +| addons.thanos.sso.enabled | bool | `false` | Toggle SSO for Thanos on and off | +| addons.thanos.sso.client_id | string | `""` | OIDC Client ID to use for Thanos | +| addons.thanos.sso.client_secret | string | `""` | OIDC Client Secret to use for Thanos | +| addons.thanos.objectStorage.endpoint | string | `""` | S3 compatible endpoint to use for connection information. examples: "s3.amazonaws.com" "s3.us-gov-west-1.amazonaws.com" "minio.minio.svc.cluster.local:9000" Note: Thanos does not require protocol prefix for URL. | +| addons.thanos.objectStorage.region | string | `""` | S3 compatible region to use for connection information. | +| addons.thanos.objectStorage.accessKey | string | `""` | Access key for connecting to object storage endpoint. | +| addons.thanos.objectStorage.accessSecret | string | `""` | Secret key for connecting to object storage endpoint. Unencoded string data. This should be placed in the secret values and then encrypted | +| addons.thanos.objectStorage.bucket | string | `""` | Bucket Name for Thanos examples: "Thanos-metrics" | +| addons.thanos.objectStorage.insecure | bool | `false` | Whether or not objectStorage connection should require HTTPS, if connecting to in-cluster object | +| addons.thanos.sourceType | string | `"git"` | Choose source type of "git" or "helmRepo" | +| addons.thanos.git.repo | string | `"https://repo1.dso.mil/big-bang/product/packages/thanos.git"` | | +| addons.thanos.git.tag | string | `"15.8.1-bb.0"` | | +| addons.thanos.git.path | string | `"./chart"` | | +| addons.thanos.helmRepo.repoName | string | `"registry1"` | | +| addons.thanos.helmRepo.chartName | string | `"thanos"` | | +| addons.thanos.helmRepo.tag | string | `"15.8.1-bb.0"` | | +| addons.thanos.flux | object | `{}` | Flux reconciliation overrides specifically for the Thanos Package | +| addons.thanos.ingress | object | `{"gateway":""}` | Redirect the package ingress to a specific Istio Gateway (listed in `istio.gateways`). The default is "public". | +| addons.thanos.values | object | `{}` | | +| addons.thanos.postRenderers | list | `[]` | | +| addons.externalSecrets.enabled | bool | `false` | Toggle deployment of external secrets | +| addons.externalSecrets.sourceType | string | `"git"` | Choose source type of "git" or "helmRepo" | +| addons.externalSecrets.git.repo | string | `"https://repo1.dso.mil/big-bang/product/packages/external-secrets.git"` | | +| addons.externalSecrets.git.tag | string | `"0.11.0-bb.2"` | | +| addons.externalSecrets.git.path | string | `"./chart"` | | +| addons.externalSecrets.helmRepo.repoName | string | `"registry1"` | | +| addons.externalSecrets.helmRepo.chartName | string | `"external-secrets"` | | +| addons.externalSecrets.helmRepo.tag | string | `"0.11.0-bb.2"` | | +| addons.externalSecrets.flux | object | `{}` | Override flux settings for this package | +| addons.externalSecrets.ingress | object | `{"gateway":""}` | Redirect the package ingress to a specific Istio Gateway (listed in `istio.gateways`). The default is "public". | +| addons.externalSecrets.values | object | `{}` | | +| addons.externalSecrets.postRenderers | list | `[]` | | +| addons.alloy.enabled | bool | `false` | Toggle deployment of grafana alloy | +| addons.alloy.sourceType | string | `"git"` | Choose source type of "git" or "helmRepo" | +| addons.alloy.git.repo | string | `"https://repo1.dso.mil/big-bang/product/packages/alloy.git"` | | +| addons.alloy.git.tag | string | `"1.6.16-bb.0"` | | +| addons.alloy.git.path | string | `"./chart"` | | +| addons.alloy.helmRepo.repoName | string | `"registry1"` | | +| addons.alloy.helmRepo.chartName | string | `"k8s-monitoring"` | | +| addons.alloy.helmRepo.tag | string | `"1.6.16-bb.0"` | | +| addons.alloy.values | object | `{}` | | +| addons.alloy.postRenderers | list | `[]` | | +| addons.alloy.flux | object | `{}` | Flux reconciliation overrides specifically for the alloy package | +| wrapper | object | `{"git":{"path":"chart","repo":"https://repo1.dso.mil/big-bang/product/packages/wrapper.git","tag":"0.4.11"},"helmRepo":{"chartName":"wrapper","repoName":"registry1","tag":"0.4.11"},"sourceType":"git"}` | Wrapper chart for integrating Big Bang components alongside a package | +| wrapper.sourceType | string | `"git"` | Choose source type of "git" or "helmRepo" | +| wrapper.helmRepo.repoName | string | `"registry1"` | Repository holding OCI chart, corresponding to `helmRepositories` name | +| wrapper.helmRepo.chartName | string | `"wrapper"` | Name of the OCI chart in `repo` | +| wrapper.helmRepo.tag | string | `"0.4.11"` | Tag of the OCI chart in `repo` | +| wrapper.git.repo | string | `"https://repo1.dso.mil/big-bang/product/packages/wrapper.git"` | Git repo holding the wrapper helm chart, example: https://repo1.dso.mil/big-bang/product/packages/wrapper | +| wrapper.git.path | string | `"chart"` | Path inside of the git repo to find the helm chart, example: chart | +| wrapper.git.tag | string | `"0.4.11"` | Git tag to check out. Takes precedence over branch. [More info](https://fluxcd.io/flux/components/source/gitrepositories/#reference), example: 0.0.2 | +| packages | object | `{"sample":{"configMaps":{},"dependsOn":[],"enabled":false,"flux":{},"git":{"branch":null,"commit":null,"credentials":{"caFile":"","knownHosts":"","password":"","privateKey":"","publicKey":"","username":""},"existingSecret":"","path":null,"repo":null,"semver":null,"tag":null},"helmRepo":{"chartName":null,"repoName":null,"tag":null},"istio":{},"kustomize":false,"monitor":{},"network":{},"postRenderers":[],"secrets":{},"sourceType":"git","values":{},"wrapper":{"enabled":false,"postRenderers":[]}}}` | Packages to deploy with Big Bang @default - '{}' | +| packages.sample | object | Uses `defaults/<package name>.yaml` for defaults. See `package` Helm chart for additional values that can be set. | Package name. Each package will be independently wrapped for Big Bang integration. | +| packages.sample.enabled | bool | true | Toggle deployment of this package | +| packages.sample.sourceType | string | `"git"` | Choose source type of "git" or "helmRepo" | +| packages.sample.wrapper | object | false | Toggle wrapper functionality. See https://docs-bigbang.dso.mil/latest/docs/guides/deployment-scenarios/extra-package-deployment/#Wrapper-Deployment for more details. | +| packages.sample.wrapper.postRenderers | list | `[]` | After deployment, patch wrapper resources. [More info](https://fluxcd.io/flux/components/helm/helmreleases/#post-renderers) | +| packages.sample.kustomize | bool | `false` | Use a kustomize deployment rather than Helm | +| packages.sample.helmRepo | object | `{"chartName":null,"repoName":null,"tag":null}` | HelmRepo source is supported as an option for Helm deployments. If both `git` and `helmRepo` are provided `git` will take precedence. | +| packages.sample.helmRepo.repoName | string | `nil` | Name of the HelmRepo specified in `helmRepositories` | +| packages.sample.helmRepo.chartName | string | `nil` | Name of the chart stored in the Helm repository | +| packages.sample.helmRepo.tag | string | `nil` | Tag of the chart in the Helm repo, required | +| packages.sample.git | object | `{"branch":null,"commit":null,"credentials":{"caFile":"","knownHosts":"","password":"","privateKey":"","publicKey":"","username":""},"existingSecret":"","path":null,"repo":null,"semver":null,"tag":null}` | Git source is supported for both Helm and Kustomize deployments. If both `git` and `helmRepo` are provided `git` will take precedence. | +| packages.sample.git.repo | string | `nil` | Git repo URL holding the helm chart for this package, required if using git | +| packages.sample.git.commit | string | `nil` | Git commit to check out. Takes precedence over semver, tag, and branch. [More info](https://fluxcd.io/flux/components/source/gitrepositories/#reference) | +| packages.sample.git.semver | string | `nil` | Git semVer tag expression to check out. Takes precedence over tag. [More info](https://fluxcd.io/flux/components/source/gitrepositories/#reference) | +| packages.sample.git.tag | string | `nil` | Git tag to check out. Takes precedence over branch. [More info](https://fluxcd.io/flux/components/source/gitrepositories/#reference) | +| packages.sample.git.branch | string | `nil` | Git branch to check out. [More info](https://fluxcd.io/flux/components/source/gitrepositories/#reference). | +| packages.sample.git.path | string | `nil` | Path inside of the git repo to find the helm chart or kustomize | +| packages.sample.git.existingSecret | string | `""` | Optional, alternative existing secret to use for git credentials, must be in the appropriate format: https://toolkit.fluxcd.io/components/source/gitrepositories/#https-authentication | +| packages.sample.git.credentials | object | `{"caFile":"","knownHosts":"","password":"","privateKey":"","publicKey":"","username":""}` | Optional, alternative Chart created secrets with user defined values | +| packages.sample.git.credentials.username | string | `""` | HTTP git credentials, both username and password must be provided | +| packages.sample.git.credentials.caFile | string | `""` | HTTPS certificate authority file. Required for any repo with a self signed certificate | +| packages.sample.git.credentials.privateKey | string | `""` | SSH git credentials, privateKey, publicKey, and knownHosts must be provided | +| packages.sample.flux | object | `{}` | Override flux settings for this package | +| packages.sample.postRenderers | list | `[]` | After deployment, patch package resources. [More info](https://fluxcd.io/flux/components/helm/helmreleases/#post-renderers) | +| packages.sample.dependsOn | list | `[]` | Specify dependencies for the package. Only used for HelmRelease, does not effect Kustomization. See [here](https://fluxcd.io/flux/components/helm/helmreleases/#helmrelease-dependencies) for a reference. | +| packages.sample.istio | object | `{}` | Package details for Istio. See [wrapper values](https://repo1.dso.mil/big-bang/product/packages/wrapper/-/blob/main/chart/values.yaml) for settings. | +| packages.sample.monitor | object | `{}` | Package details for monitoring. See [wrapper values](https://repo1.dso.mil/big-bang/product/packages/wrapper/-/blob/main/chart/values.yaml) for settings. | +| packages.sample.network | object | `{}` | Package details for network policies. See [wrapper values](https://repo1.dso.mil/big-bang/product/packages/wrapper/-/blob/main/chart/values.yaml) for settings. | +| packages.sample.secrets | object | `{}` | Secrets that should be created prior to package installation. See [wrapper values](https://repo1.dso.mil/big-bang/product/packages/wrapper/-/blob/main/chart/values.yaml) for settings. | +| packages.sample.configMaps | object | `{}` | ConfigMaps that should be created prior to package installation. See [wrapper values](https://repo1.dso.mil/big-bang/product/packages/wrapper/-/blob/main/chart/values.yaml) for settings. | +| packages.sample.values | object | `{}` | Values to pass through to package Helm chart | diff --git a/docs/understanding-bigbang/configuration/configuration.md b/docs/understanding-bigbang/configuration/configuration.md new file mode 100644 index 0000000000000000000000000000000000000000..7c617a48fd40bd7124ac3d5a72cabf7760a0d9c3 --- /dev/null +++ b/docs/understanding-bigbang/configuration/configuration.md @@ -0,0 +1,232 @@ +# Configuration + +[[_TOC_]] + +## Overview + +Configuration of Big Bang is achieved by overriding default values set in the package or Big Bang using the [environment template](https://repo1.dso.mil/big-bang/customers/template). The template has a 4 potential locations for setting values: `base/secrets.enc.yaml`, `base/configmap.yaml`, `<env>/secrets.enc.yaml`, and `<env>/configmap.yaml`. Overrides proceed as follows, with `<env>/configmap.yaml` having the highest precedence. + +```mermaid +graph TD + pkg[Package values] + -->bb[Big Bang values] + -->base-s[*base/secrets.enc.yaml* values] + -->base-c[*base/configmap.yaml* values] + -->env-s[*<env>/secrets.enc.yaml* values] + -->env-c[*<env>/configmap.yaml* values] +``` + +In all four cases, Big Bang reads a single key named `values.yaml` that contains the data to override. See the [Big Bang environment template](https://repo1.dso.mil/big-bang/customers/template) for examples on how to use these files to override values. + +## Pre-configuration + +Before configuring Big Bang, it is expected that you have already setup: + +- A Kubernetes cluster +- A [SOPS key pair](../concepts/encryption.md) +- A Git repository to hold your configuration + - Pull credentials for the Git repository (if not public) +- An Iron Bank robot account for production, or a non-robot account for testing. Reference [Iron Bank authentication](../concepts/troubleshooting.md#iron-bank-authentication) for additional details. +- Certificates specific to your environment (if needed) + +## Minimum Viable Configuration + +At a minimum, the following items must be configured for a default Big Bang deployment: + +- [Big Bang version](#big-bang-version) +- [Environment Git repository](#environment-location) +- [Hostname](#hostname) +- [SOPS private key reference](../concepts/encryption.md). +- [Registry pull credentials](#registry-pull-credentials) + +The Big Bang [Environment Template](https://repo1.dso.mil/big-bang/customers/template) has placeholders for all of the above. + +## Big Bang Globals + +### `hostname` + +Hostname is used to override the domain of deployed packages. This allows you to go to the DNS name of a server using the domain. For example, if the domain is `bigbang.dev`, Kiali can be reached at `kiali.bigbang.dev`. + +| Key | Description | Type | Default | +| ---------- | ---------------------------------- | ----------- | ------------- | +| `hostname` | Domain to use for deployed servers | Domain Name | `bigbang.dev` | + +### `registryCredentials` + +Registry credentials are used to pull images for Big Bang. By default, it points to Iron Bank, but can be modified to use a private registry. These credentials are passed down to all relevant namespaces as an image pull secret. + +| Key | Description | Type | Default | +| ------------ | --------------------------- | ----------- | ------------------- | +| `registry` | Container registry location | Domain Name | `registry1.dso.mil` | +| `username`\* | Container registry username | String | "" | +| `password`\* | User's password | String | "" | +| `email` | User's email | Email | "" | + +> \*Credentials should be SOPS encrypted + +### `flux` + +Flux settings are used to setup the default continuous deployment configuration for Big Bang packages. + +| Key | Description | Type | Default | +|--|--|--|--| +| `interval` | Polling interval to check for Git or Helm chart updates | ##m##s (ex. 5m30s) | 2m | +| `install.retries` | The number of retries that should be attempted on Helm chart installation failures before bailing. | int | 3 | +| `upgrade.retries` | The number of retries that should be attempted on Helm chart upgrade failures before bailing. | int | 3 | +| `rollback.timeout` | The time to wait for any individual Kubernetes operation (like Jobs for hooks) during the performance of a Helm rollback action. | ##m##s | 5m | +| `rollback.cleanupOnFail` | Allows deletion of new resources created during the Helm rollback action when it fails. | Boolean | `true` | + +### Package + +Each package (e.g. `istio`, `clusterAuditor`) has configuration to control how Big Bang deploys the package + +| Key | Description | Type | Default | +|--|--|--|--| +| `enabled` | Determines if the package will get deployed or skipped | Boolean | `true` (unless its an `addon`) | +| `git.repo` | Location of the Git repo holding the package deployment resources | URL | `https://repo1.dso.mil/big-bang/apps/...` +| `git.branch` | Branch to use for package deployment resources | string | `chart-release` or `release-vx.x.x` | +| `git.commit` | SHA of specific commit to use in Git for package deployment resources | SHA | null | +| `git.tag` | Git tag to use for package deployment resources | string | null | +| `ingress.gateway` | Name of Istio Gateway to use for ingress (if supported) | string | "public" | +| `sso.*` | Single sign on configuration (if supported) | | | +| `database.*` | External database connection configuration (if supported) | | | +| `objectStorage.*` | Object storage configuration (if supported) | | | +| `values` | Package specific values to configure | List of key/values pairs | {} | +| `postRenderers` | See [docs/postrenderers.md](./postrenderers.md) | list | [] | + +## Flux Resources + +Big Bang deploys four flux resources that can be customized: + +| Resource | Controls | Location | +| ------------- | ----------- | ------------------------------------------------- | +| GitRepository | Environment | Top-level manifest (e.g. `dev.yaml`, `prod.yaml`) | +| Kustomization | Environment | Top-level manifest (e.g. `dev.yaml`, `prod.yaml`) | +| GitRepository | Big Bang | [Link](../../../base/gitrepository.yaml) | +| HelmRelease | Big Bang | [Link](../../../base/helmrelease.yaml) | + +In addition, each package contains its own GitRepository and HelmRelease resource that can be customized. Look in the [Helm chart templates](../../../chart/templates) for the these resources. + +Settings for any of these resources can be overridden by [patching](https://kubectl.docs.kubernetes.io/references/kustomize/kustomization/patches/) the resource in your environment's kustomization files. Use Flux's documentation for [GitRepository](https://toolkit.fluxcd.io/components/source/gitrepositories/), [HelmRelease](https://toolkit.fluxcd.io/components/helm/helmreleases/), and [Kustomization](https://toolkit.fluxcd.io/components/kustomize/kustomization/) to find settings for these resources. The following are examples of commonly requested custom patches covered in the [bigbang template repo]<https://repo1.dso.mil/big-bang/customers/template/-/tree/main#flux-components>): + +- Updating flux-system component resource usage + - [Example `kustomization.yaml`](https://repo1.dso.mil/big-bang/customers/template/-/tree/main#adjust-resource-allocation-for-a-flux-system-component) + - This patch could be used to adjust the resources requested by the `flux-system/helm-controller` resource. A similar patch could be used to adjust the resources required by the other flux components. + > NOTE: If flux is under-resourced, occasionally requests can fail in a manner that looks like a network connectivity issue (use with caution) +- Adding environment variables to flux-system components + - [Example `kustomization.yaml`](https://repo1.dso.mil/big-bang/customers/template/-/tree/main#adjust-resource-allocation-for-a-flux-system-component) + - This patch could be used to add AWS credential environment variables into the `flux-system/kustomize-controller` resource to enable SOPS decryption using a KMS key from outside of AWS. +- Changing the image name / version + - [Example `kustomization.yaml`](https://repo1.dso.mil/big-bang/customers/template/-/tree/main#updating-a-flux-system-component-image-tag) + - This patch could be used to update the tag of the flux-system component image to be deployed. + +> NOTE: Multiple patches could be applied within a single kustomization.yaml + +## Big Bang Version + +In your `kustomization.yaml` under your environment, here is an example of how to override the version of Big Bang you will use. You can also use a tag or branch if desired. + +```yaml +bases: + - https://repo1.dso.mil/big-bang/bigbang.git/base/?ref=v1.2.* +patchesStrategicMerge: + - |- + apiVersion: source.toolkit.fluxcd.io/v1 + kind: GitRepository + metadata: + name: bigbang + spec: + ref: + $patch: replace + semver: "1.2.x" +``` + +> Note: You must put the version in two places, once for Kustomize to pull the right configuration base and two for Git Repository to pull the right Helm Chart. + +## Environment Location + +In your top-level `<env>.yaml` Kubernetes manifest, you would place configuration for the location of your environment. Here is an example: + +```yaml +apiVersion: source.toolkit.fluxcd.io/v1 +kind: GitRepository +metadata: + name: environment-repo + namespace: bigbang +spec: + interval: 1m + url: https://repo1.dso.mil/big-bang/customers/template.git + ref: + branch: main +--- +apiVersion: kustomize.toolkit.fluxcd.io/v1 +kind: Kustomization +metadata: + name: environment + namespace: bigbang +spec: + interval: 1m + sourceRef: + kind: GitRepository + name: environment-repo + path: ./dev + prune: true + decryption: + provider: sops + secretRef: + name: sops-gpg +``` + +## Registry Pull Credentials + +If you have pull credentials for your docker registry, add them to `secrets.enc.yaml`. Here is an example: + +> The name of the Secret must be `common-bb` or `environment-bb` for Big Bang to read values from it. + +```yaml +apiVersion: v1 +kind: Secret +metadata: + name: common-bb +stringData: + values.yaml: |- + registryCredentials: + username: iron-bank-user + password: iron-bank-password +``` + +You will also need to update your `kustomization.yaml` to merge with the existing secret: + +```yaml +namespace: bigbang +patchesStrategicMerge: + - secrets.enc.yaml +``` + +## Package settings + +Besides the [global settings](#big-bang-globals), package settings are defined by the individual packet's helm charts. You can find these by reviewing the `git.registry` setting for the package in Big Bang's [default values.yaml](../../../chart/values.yaml). + +To modify a non-sensitive package setting, add it to your `configmap.yaml`. For sensitive information, follow the pattern for setting [registry pull credentials](#registry-pull-credentials). Here we disable `twistlock` and set `gatekeeper`'s replicas to `1`: + +```yaml +twistlock: + enabled: false + +gatekeeper: + values: + replicas: 1 +``` + +You will also need to merge this file with the existing configmaps in `kustomization.yaml`. + +> The name of the ConfigMap must be `common` or `environment` for Big Bang to read values from it. + +```yaml +namespace: bigbang +configMapGenerator: + - name: common + behavior: merge + files: + - values.yaml=configmap.yaml +``` diff --git a/docs/understanding-bigbang/configuration/postrenderers.md b/docs/understanding-bigbang/configuration/postrenderers.md new file mode 100644 index 0000000000000000000000000000000000000000..c6be3e47364ba2f2bb20c92ddf17d4c312324e1d --- /dev/null +++ b/docs/understanding-bigbang/configuration/postrenderers.md @@ -0,0 +1,39 @@ +# Post Renderers + +Post rendering gives chart installers the ability to manually manipulate, configure, and/or validate rendered manifests before they are installed by Helm. + +[Flux V2](https://toolkit.fluxcd.io/) provides the ability to apply kustomizations on a Helm Release after rendering using a [Post Renderer](https://toolkit.fluxcd.io/components/helm/helmreleases/#post-renderers). This feature provides significant flexibility to the Helm objects, and allows for adjusting values inside of Helm that are not exposed explicitly as part of the values file. Each `HelmRelease` is configured with a `postRenderer` pass through: + +```yaml +... +jaeger: + postRenderers: + - kustomize: + # Array of inline strategic merge patch definitions as YAML object. + # Note, this is a YAML object and not a string, to avoid syntax + # indention errors. + patchesStrategicMerge: + # Change operator deployment to be a rolling update + - kind: Deployment + apiVersion: apps/v1 + metadata: + name: jaeger-operator + spec: + strategy: + type: RollingUpdate + patchesJson6902: + # change priorityClassName + - target: + version: v1 + kind: Deployment + name: jaeger-operator + patch: + - op: add + path: /spec/template/priorityClassName + value: system-cluster-critical + images: + # update image to a new tag + - name: registry1.dso.mil/ironbank/opensource/jaegertracing/jaeger-operator + newName: registry1.dso.mil/ironbank/opensource/jaegertracing/jaeger-operator + newTag: 1.23.0 +``` diff --git a/docs/understanding-bigbang/configuration/sample-prod-config.md b/docs/understanding-bigbang/configuration/sample-prod-config.md new file mode 100644 index 0000000000000000000000000000000000000000..6b4fa3dae59b71d90cef26f25ed8a88a1630ef02 --- /dev/null +++ b/docs/understanding-bigbang/configuration/sample-prod-config.md @@ -0,0 +1,292 @@ +# Production Configuration + +[[_TOC_]] + +## Gitlab + +This section provides suggested settings for Gitlab operational/production environments. + +### Use external database service + +For production deployments you must externalize the database service. BigBang will pass through the most common value overrides to the Gitlab Package chart. +Disable the internal postgres by configuring an external database in the BigBang values. + +```yaml +addons: + gitlab: + database: + host: + port: + database: + username: + password: +``` + +### Use external object storage + +For production deployments you must externalize object storage service. BigBang will pass through the most common value overrides to the Gitlab Package chart. +Disable the internal MinIO instance by configuring an external object storage service. + +```yaml +addons: + gitlab: + objectStorage: + type: + endpoint: + region: + accessKey: + accessSecret: + bucketPrefix: + iamProfile: +``` + +### Flux settings + +Large Gitlab installations should increase the Gitlab specific HelmRelease timeout value to around 30m to 45m and the Gitlab specific HelmRelease retries value should be adjusted to around 8 to 10. + +```yaml +addons: + gitlab: + flux: + timeout: 30m + upgrade: + remediation: + retries: 8 +``` + +### Kubernetes resource request/limit settings + +K8s resource requests/limits for webservice and gitaly workloads should be increased from the defaults. Gitlab engineers state predicting Gitaly's resource consumption is very difficult, and will require testing to find the applicable limits/requests for each individual installation. See this [Gitlab Epic](https://gitlab.com/groups/gitlab-org/-/epics/6127) for more information. See the [gitlab/docs/k8s-resources.md](https://repo1.dso.mil/big-bang/product/packages/gitlab/-/blob/main/docs/k8s-resources.md) for a list of all possible configuration values. Use BigBang values overrides to change the Gitlab resource settings. +Recommended starting point: + +```yaml +addons: + gitlab: + values: + gitlab: + webservice: + resources: + limits: + cpu: 2 + memory: 4G + requests: + cpu: 2 + memory: 4G + gitaly: + resources: + limits: + cpu: 2 + memory: 4G + requests: + cpu: 2 + memory: 4G +``` + +### Backup and rename gitlab-rails-secret + +An operational deployment of Gitlab should backup and re-create the Gitlab Rails Encryption information as a secret with a different name as [documented here](https://docs.gitlab.com/charts/installation/secrets.html#gitlab-rails-secret). Using a custom secret name can help prevent accidental overwriting. +The existing secret can be copied and modified with a different name and is recommended to be stored in your environments GitOps configuration as a SOPS encrypted secret. + +```bash +kubectl get secret/gitlab-rails-secret -n gitlab -o yaml > gitlab-rails-custom-secret.yaml +``` + +Edit the file and change the name of the secret. Example: + +```yaml +apiVersion: v1 +kind: Secret +metadata: + name: gitlab-rails-custom-secret +``` + +Use GitOps configuration as code (CaC) and commit the custom rails secret to your GitOps repository. You should SOPs encrypt the custom rails secret keys in the GitOps repository to preserve security. + +To make the secret creation easier, BigBang has a value `addons.gitlab.railsSecret` where a chomp modifier can be used to have the data from the `gitlab-rails-secret` placed into a secret as part of the umbrella: + +```yaml +addons: + gitlab: + ... + railsSecret: | + production: + secret_key_base: XXXXXX + otp_key_base: XXXXXX + ... +``` + +This `railsSecret` value should be committed to a SOPs encrypted values file as the data is very sensitive. + +Once the secret is pushed up to GitOps, the following Gitlab helm chart value `global.railsSecrets.secret` can be overridden to point to the custom rails secret or if using the `railsSecret` value BigBang will auto point to the secret it controls via the value above. + +```yaml +addons: + gitlab: + values: + global: + railsSecrets: + secret: gitlab-rails-custom-secret +``` + +The custom rails secret should be backed up somewhere secure outside the cluster if not included in your GitOps code repository. + +**If the Kubernetes gitlab-rails-secret happens to get overwritten Gitlab will no longer be able to access the encrypted data in the database.** + +You will get errors like this in the logs. + +```text +OpenSSL::Cipher::CipherError () +``` + +Many things break when this happens and the recovery is ugly with serious user impacts. + +At a minimum an operational deployment of Gitlab should export and save the gitlab-rails-secret somewhere secure outside the cluster. + +```bash +kubectl get secret/gitlab-rails-secret -n gitlab -o yaml > cya.yaml +``` + +## Vault + +This section provides suggested settings for Vault operational/production environments. Vault is a large complicated application and has many options that cannot adequately be covered here. Vault has significant security risks if not properly configured and administrated. Please consult the upstream [Vault documentation](https://learn.hashicorp.com/tutorials/vault/kubernetes-raft-deployment-guide?in=vault/kubernetes#configure-vault-helm-chart) as the ultimate authority. The following is an example operational/production config using a passthrough istio ingress gateway, high availability, auto-unseal, and raft for distributed filesystem persistence. Consult the BigBang Vault Package helm repo [/docs/production.md](https://repo1.dso.mil/big-bang/product/packages/vault/-/blob/main/docs/production.md) for more information. + +```yaml +istio: + enabled: true + + ingressGateways: + passthrough-ingressgateway: + type: "LoadBalancer" + # nodePortBase: 30200 + + gateways: + passthrough: + ingressGateway: "passthrough-ingressgateway" + hosts: + - "*.{{ .Values.domain }}" + tls: + mode: "PASSTHROUGH" + +addons: + vault: + enabled: true + ingress: + gateway: "passthrough" + # provide the Vault TLS cert and key. BigBang will create the secret and volumemount for you + # Leave blank to create your own secret and provide values for your own volume and volumemount + key: | + -----BEGIN PRIVATE KEY----- + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + -----END PRIVATE KEY----- + cert: | + -----BEGIN CERTIFICATE----- + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + -----END CERTIFICATE----- + + values: + # disable autoInit. It should not be used for operations. + autoInit: + enabled: false + + global: + # this is a double negative. Put "false" to enable TLS for passthrough ingress + tlsDisable: false + + injector: + extraEnvironmentVars: + AGENT_INJECT_VAULT_ADDR: "https://vault.bigbang.dev" + + server: + # Increase default resources + resources: + requests: + memory: 8Gi + cpu: 2000m + limits: + memory: 8Gi + cpu: 2000m + + # disable the Vault provided ingress so that Istio ingress can be used. + ingress: + enabled: false + + # Extra environment variable to support high availability + extraEnvironmentVars: + # the istio gateway domain + VAULT_API_ADDR: https://vault.bigbang.dev + VAULT_SKIP_VERIFY: "true" + VAULT_LOG_FORMAT: "json" + VAULT_LICENSE: "your-license-key-goes-here" + + ha: + # enable high availability. + enabled: true + replicas: 3 + + # raft is the license free most simple solution for a distributed filesystem + raft: + enabled: true + setNodeId: true + + # these values should be encrypted to prevent the kms_key_id from being revealed + config: | + ui = true + + listener "tcp" { + tls_disable = false + address = "[::]:8200" + cluster_address = "[::]:8201" + tls_cert_file = "/vault/tls/tls.crt" + tls_key_file = "/vault/tls/tls.key" + telemetry { + unauthenticated_metrics_access = true + } + } + + storage "raft" { + path = "/vault/data" + + retry_join { + leader_api_addr = "https://vault-vault-0.vault-vault-internal:8200" + leader_client_cert_file = "/vault/tls/tls.crt" + leader_client_key_file = "/vault/tls/tls.key" + leader_tls_servername = "vault.bigbang.dev" + } + + retry_join { + leader_api_addr = "https://vault-vault-1.vault-vault-internal:8200" + leader_client_cert_file = "/vault/tls/tls.crt" + leader_client_key_file = "/vault/tls/tls.key" + leader_tls_servername = "vault.bigbang.dev" + } + + retry_join { + leader_api_addr = "https://vault-vault-2.vault-vault-internal:8200" + leader_client_cert_file = "/vault/tls/tls.crt" + leader_client_key_file = "/vault/tls/tls.key" + leader_tls_servername = "vault.bigbang.dev" + } + } + + seal "awskms" { + region = "us-gov-west-1" + kms_key_id = "your-kms-key-goes-here" + endpoint = "https://kms.us-gov-west-1.amazonaws.com" + } + + telemetry { + prometheus_retention_time = "24h" + disable_hostname = true + } + + service_registration "kubernetes" {} +``` + +## Keycloak +See the [production configuration example](../../../docs/assets/configs/example/keycloak-prod-values.yaml). + +## High Availability (HA) + +Each package in Big Bang includes documentation of its own High Availability configuration independently in [Package Architecture](../package-architecture). diff --git a/docs/understanding-bigbang/licensing-model.md b/docs/understanding-bigbang/licensing-model.md new file mode 100644 index 0000000000000000000000000000000000000000..d548920c0eef423b2d54a8717099375441de0655 --- /dev/null +++ b/docs/understanding-bigbang/licensing-model.md @@ -0,0 +1,74 @@ +# Big Bang Licensing Model Overview + +While Big Bang is open source and free to use, the same cannot be said of its components. The licensing requirements of components requires a nuanced explanation. The intent of this document is to be a self-service resource to help consumers of Big Bang make an informed decision regarding licenses they may need to successfully deploy an Authority to Operate (ATO)-capable DevSecOps Platform using Big Bang. + +## What Licenses Do I Need for Big Bang? + +There are two issues that make it difficult to figure out Big Bang's license requirements: + +1. The modular (and in some cases, swappable) componentized nature of Big Bang means choices affect license requirements. OS, Kubernetes Distribution, and Application decisions need to be made before license requirements can be sorted out. +1. Freemium applications often require a license to unlock features like High Availability (HA), advanced SSO functionality with authn, authz, and audit logging of federated users, or advanced compliance controls, including FIPS 140-2 mode, compliance reporting, or audit logs. + +## What Components Could Have Licenses? + +1. OS/Cloud Service Providers (CSP) VM Images: + * RHEL requires a subscription and comes with vendor support. + * CSPs often offer licensed VM Images at additional per hour cost. These add features like offloading STIG/CIS OS hardening. + * Several free Linux OS Distributions exist, including Ubuntu and free RHEL alternatives (e.g., Amazon Linux 2). There are also tools such as [openscap](https://www.open-scap.org/), which has ansible and bash scripts to automate STIG/CIS benchmark compliance for OS security to help automate DIY hardening of the OS. +2. Kubernetes Distributions: + * RedHat OpenShift, VMware TKG, and D2IQ Konvoy each require a license, that comes with support and additional features, they each offer 30-90 day trial licenses. + * There are free options like kubeadm, k0s, k3s, RKE2, talos-systems, and many other CNCF compliant distributions. + * k0s, RKE2, and talos-systems are free options with optional paid Vendor Support. +3. Big Bang's Core Applications: + * Many of the core applications are free open source software. + * The default deployment of Big Bang does not require any licenses. + * Twistlock is a core component that requires a license. + * ElasticSearch is a core component that requires a license to unlock additional features, that could be considered required in some cases; more information on this nuance is provided below. +4. Big Bang's Supported AddOn Applications: + * Includes a mix of free, freemium, and licensed products. +5. Big Bang Integration Support: + * Big Bang is free, but support tiers are available for purchase through Platform One. + +## Who Purchases the Licenses? + +Licensing of products deployable by Big Bang are not covered by Big Bang or Platform One. As a general rule of thumb the acquisition of licenses is the responsibility of the end-user's organization, and product vendors should be contacted for support of their respective products. Party Bus is an example of an exception to the rule of thumb. + +## Who Decides If a Licenced Feature in a Freemium Application Is a Hard Requirement? + +* The Consumer of Big Bang, their security team, and their Authorizing Official (AO) need to decide if licensed features constitute a hard requirement or if free tier functionality can be considered at lower impact levels or unique use cases. +* In most cases, licenses will be required due to security controls only being available in the fully licensed version. However, users may be able to hold off on licensed versions for non-ATO'd proof of concept deployments or risk acceptance by an AO for unique scenarios. +* Even without a hard requirement for a license (like in the case of a Kubernetes Cluster), consumers of Big Bang may still want to consider purchasing licenses or support contracts. + +## Table to Help Elaborate on Nuances of Application Licensing + +| Package | Purpose | Licenses | Notes about Licensed Features and Support | +|-----------------------------------------------------------------------|---------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| FluxCD | GitOps (Prerequisite App) | Apache License 2.0 (Free/OSS) | | +| Open Policy Agent Gatekeeper | Policy Enforcement (Core App) | Apache License 2.0 (Free/OSS) | * [Styra](https://www.openpolicyagent.org/support) is the original creator of OPA and can offer commercial support. | +| Kyverno | Policy Enforcement (Core App) | Apache License 2.0 (Free/OSS) | * Kyverno is a fully open-source product, however there are [multiple companies](https://kyverno.io/support/) which provide paid support services for it. | +| Istio Controlplane, Istio Operator, and Kiali | Service Mesh, Operator, and Service Mesh Dashboard (Core App) | Apache License 2.0 (Free/OSS) | * [Tetrate](https://www.tetrate.io/) is an Istio Vendor that can offer commercial support. | +| Jaeger | APM (Application Performance Monitoring) / Tracing (Core App) | Apache License 2.0 (Free/OSS) | | | +| Prometheus | Metrics and monitoring. (Core App) | Apache License 2.0 (Free/OSS) | | +| AlertManager | Alerting. (Core App) | Apache License 2.0 (Free/OSS) | | +| Loki | Log aggregation. (Core App) | GNU Affero General Public License v3. | | +| Grafana | Dashboard. (Core App) | GNU Affero General Public License v3. | | +| Harbor | Container and chart registry. (AddOn App) | Apache License 2.0 (Free/OSS) | | +| Tempo (Grafana) | Service-mesh trace collector. (AddOn App) | GNU Affero General Public License v3. | | +| Fluentbit | Log Shipper (Core App) | Apache License 2.0 (Free/OSS) | | +| ECK (Elastic Cloud on Kubernetes) (ElasticSearch and Kibana) | Log Storage and Log Dashboard (Core App) | [Elastic License](https://github.com/elastic/cloud-on-k8s/blob/master/LICENSE.txt) (Freemium) | **Enterprise features of note:** Kibana SSO, authn, authz, FIPS 140-2 mode, audit logging require an enterprise tier license. **Free tier notes:** BigBang's Authservice/Authentication Proxy could be put in front of Kibana to achieve basic SSO with all or nothing access. PartyBus uses licensed ElasticSearch <https://www.elastic.co/subscriptions> [licensing](package-architecture/elasticsearch-kibana.md#licensing) | +| Cluster Auditor | Collects OPA GK events and sends them to ElasticSearch for Review (Core App) | Apache License 2.0 (Free/OSS) | | +| Twistlock / Prisma Cloud Compute | Runtime Security, Security Dashboard, Intrusion Prevention (Core App) | Prisma Cloud Compute License (Paid Product requiring a license) | **Prisma Cloud License is required for an ATO'd cluster.** [Considering investigating alternatives](https://repo1.dso.mil/groups/platform-one/big-bang/-/epics/74) Licenses are sold per node. Each defender on a node uses 7 credits and the credits are purchased in bundles of 100 credits. <https://docs.paloaltonetworks.com/prisma/prisma-cloud/prisma-cloud-admin-compute/welcome/licensing> <https://docs.paloaltonetworks.com/prisma/prisma-cloud/20-09/prisma-cloud-compute-edition-admin/install/install_kubernetes.html> [licensing](package-architecture/twistlock.md#licensing) | +| ArgoCD | GitOps (AddOn App) | Apache License 2.0 (Free/OSS) | | +| Velero | Backup and Recovery of Persistent Volumes (AddOn App) | Apache License 2.0 (Free/OSS) | | +| Keycloak | SSO (Single Sign On) and Federated Authn. (AddOn App) | Apache License 2.0 (Free/OSS) | | +| Authservice (and HA Proxy) | SSO Authentication Proxy (AddOn App) | Apache License 2.0 & GNU General Public License Version 2(Free/OSS) | | +| Mattermost, Mattermost Operator | Self Hosted Chat (AddOn App) | [Mattermost is comprised of Multiple Licenses](<https://mattermost.org/licensing/>) | **Enterprise features of note:** HA, Additional SSO options, prometheus metrics integration, Elasticsearch integration to optimize searching/indexing, Compliance Reporting, Audit Logs, Advanced roles and permissions. **Free tier notes:** A non-HA deployment can quickly auto heal thanks to Kubernetes, the free tier can use Gitlab or P1's Keycloak implementation for Federated SSO. (MM Plugins don't need the paid version, but the need a single node instance or the paid HA for cluster awareness to prevent duplicate triggering of functions.) PartyBus uses the Enterprise E20 licensed version. [licensing](package-architecture/mattermost.md#licensing) <https://mattermost.org/licensing/> <https://mattermost.com/pricing-self-managed/> | +| Minio, Minio Operator | Self Hosted S3 API compatible object storage (AddOn App) | Affero General Public License Version 3 (Free/OSS) | Commercial Support is Available: <https://min.io/pricing> | +| Nexus | Generic Artifact Repository (AddOn App) | Nexus Repository OSS: Eclipse Public License v1.0 Nexus Repository Pro: Paid Licensed product | **Enterprise features of note:** HA, SAML SSO, Auth Token Support **Free tier notes:** A non-HA deployment can quickly auto heal thanks to Kubernetes, AWS S3 blob storage. <https://www.sonatype.com/products/repository-oss-vs-pro-features> <https://www.sonatype.com/products/pricing> | +| Gitlab, Gitlab Runners | GitRepo, Container Registry, and CICD Software Factory (AddOn App) | Gitlab Community Edition: MIT Expat license Gitlab Enterprise Edition: (multiple tiers) | **Premium features of note:** Release Controls, Project Management **Ultimate features of note:** Unlimited Guest Users, Advanced Security Testing (Note this functionality comes from container images that may not yet be in Iron Bank) **Free tier notes:** Free tier is fine for Proof of Concepts, but the Release Controls in Premium tier contain security controls that would be necessary for a cATO pipeline. Party Bus has multiple instances of Gitlab, most use Premium, a few use Ultimate. Party Bus's Gitlab pipelines integrate with additional licensed apps: Twistlock, Anchore, [Fortify](https://repo1.dso.mil/big-bang/product/packages/fortify), [SD Elements](https://www.securitycompass.com/sdelements/), and others. (This is offered as a data point, it doesn't mean these are required for a cATO pipeline, the Consumer of Big Bang's AO makes that call.) <https://about.gitlab.com/pricing/#self-managed> <https://gitlab.com/gitlab-org/gitlab-foss/-/tree/master#editions> | +| SonarQube Community Edition | Static Code Analysis (AddOn App) | SonarQube CE: GNU Lesser GPL License v3 (Community Edition is Free/OSS) | An Enterprise Edition Exists, but is not bundled by Big Bang | +| Vault | Secret management (AddOn App) | Mozilla Public License 2.0 | | +| Metrics Server | Scalable, efficient source of container resource metrics. (AddOn App) | Apache License 2.0 (Free/OSS) | | +| NeuVector | Zero-trust container security. (AddOn App) | Apache License 2.0 (Free/OSS) + | | +| Fortify | Software security center. (AddOn App) | Helm Chart: MIT Expat license SSC: Proprietary license provided by Micro Focus | | diff --git a/docs/understanding-bigbang/package-architecture/.pages b/docs/understanding-bigbang/package-architecture/.pages new file mode 100644 index 0000000000000000000000000000000000000000..c23d4e09a4c2589b41c9d5a2544601f57c924928 --- /dev/null +++ b/docs/understanding-bigbang/package-architecture/.pages @@ -0,0 +1,4 @@ +nav: + - Overview: README.md + - ... + - Template MD: ref-package.md diff --git a/docs/understanding-bigbang/package-architecture/README.md b/docs/understanding-bigbang/package-architecture/README.md new file mode 100644 index 0000000000000000000000000000000000000000..9996dec39441ec013cd677b6fdb8ae4fe9d29222 --- /dev/null +++ b/docs/understanding-bigbang/package-architecture/README.md @@ -0,0 +1,236 @@ +# Packages + +Big Bang includes many different packages that provide services to the ecosystem. Each of these packages is deployed by a Helm chart located in a repository under [Big Bang's Universe Group](https://repo1.dso.mil/big-bang/product). The packages are broken up into several categories listed below. Sometimes packages are tightly coupled and grouped together in a stack. When using a stack, all packages in the stack will be deployed. + +[[_TOC_]] + +## Technical Oversight Committee (TOC) + +The Big Bang TOC supports users and contributors of the Big Bang ecosystem. If you would like to add, modify, or remove packages in Big Bang, we encourage you to attend the TOC to discuss your ideas. You can find details in [the BBTOC repository](https://repo1.dso.mil/big-bang/product/bbtoc), specifically in the [Package Maintenance Tracks](https://repo1.dso.mil/big-bang/product/bbtoc/-/blob/main/process/Package%20Maintenance%20Tracks.md) document. + +## Dependency Tree + +Several of Big Bang's packages have dependencies on other packages. A Dependency exists if the package would have a significant (or total) loss in functionality if the dependency was not present. + +```mermaid +flowchart LR + subgraph Core + direction BT + + subgraph L[Logging] + subgraph EFK[Default] + Kibana & Fluentbit --> Elastic + end + subgraph PLG[Alternative] + style PLG stroke-dasharray: 10 10 + Promtail[Promtail*] --> Loki[Loki*] + end + end + + subgraph M[Monitoring] + Grafana --> Prometheus + Grafana -.-> Loki + end + + subgraph PE[Policy Enforcement] + subgraph KyvernoStack[Default] + direction BT + KyvernoReporter[Kyverno Reporter*] --> Kyverno[Kyverno*] + end + subgraph CA[Alternative] + style CA stroke-dasharray: 10 10 + direction BT + ClusterAuditor --> OPA[OPA Gatekeeper] + end + end + + subgraph RS[Runtime Security] + subgraph TL[Default] + Twistlock[Prisma Cloud Compute] + end + end + + subgraph DT[Distributed Tracing] + subgraph J[Default] + Jaeger ----> Elastic + end + subgraph T[Alternative] + style T stroke-dasharray: 10 10 + Tempo[Tempo*] -.-> Grafana + end + end + + subgraph SM[Service Mesh] + Jaeger --> Istio + Tempo -.-> Istio + Kiali --> Jaeger & Istio & Prometheus + end + end +``` + +```mermaid +flowchart LR + subgraph AddOns + subgraph AppUtils[Application Utilities] + MinIO + end + + subgraph ClusterUtils[Cluster Utilities] + direction BT + ArgoCD + Metrics[Metrics Server] + Velero + end + + subgraph "Security" + direction BT + Anchore + Authservice --> I[Istio] + Keycloak + Vault[Vault*] + end + + subgraph "Collaboration" + direction BT + Mattermost + end + + subgraph "Developer Tools" + direction BT + GLRunners[GitLab Runners] --> GitLab + Nexus[Nexus Repository] + Sonarqube + end + end +``` + +> Footnotes: +> +> - Dotted lines in `Core` indicate a package that is not enabled by default +> - The following were left off the chart to keep it simple +> - Most packages depend on Istio for encrypted traffic and ingress to interfaces. +> - Some packages have operators that are deployed prior to the package and manage the package's state. + +## Core + +Core packages make up the foundation of Big Bang. At least one of the supported stacks listed in each category must be enabled to be considered a Big Bang cluster. These packages are designed to provide administrative support for other packages. + +### Service Mesh + +A service mesh is a dedicated infrastructure layer for making service-to-service communication safe, fast, and reliable. It provides fine-grained control and enforcement of network routing into, out of, and within the cluster. It can also supply end-to-end traffic encryption, authentication, and authorization. + +|Default|Stack|Package|Function|Repositories| +|--|--|--|--|--| +|X|Istio|Istio Operator|Operator|[istio-operator](https://repo1.dso.mil/big-bang/product/packages/istio-operator)| +|X|Istio|[Istio](./istio.md)|Control Plane|[istio-controlplane](https://repo1.dso.mil/big-bang/product/packages/istio-controlplane)| +|X|Istio|[Kiali](./kiali.md)|Management Console|[kiali](https://repo1.dso.mil/big-bang/product/packages/kiali)| + +### Logging + +A logging stack is a set of scalable tools that can aggregate logs from cluster services and provide real-time queries and analysis. Logging is typically comprised of three components: a forwarder, storage, and a visualizer. + +|Default|Stack|Package|Function|Repositories| +|--|--|--|--|--| +| |EFK|Elastic Cloud on Kubernetes (ECK) Operator|Operator|[eck-operator](https://repo1.dso.mil/big-bang/product/packages/eck-operator) +| |EFK|[Elasticsearch / Kibana](./elasticsearch-kibana.md)|Storage & Visualization|[policy](https://repo1.dso.mil/big-bang/product/packages/policy)| +| |EFK|[Fluentbit](./fluentbit.md)|Forwarder|[fluentbit](https://repo1.dso.mil/big-bang/product/packages/fluentbit)| +|X|PLG|[Loki](./loki.md)|Storage|[loki](https://repo1.dso.mil/big-bang/product/packages/loki)| +|X|PLG|[Promtail](./promtail.md)|Forwarder|[promtail](https://repo1.dso.mil/big-bang/product/packages/promtail)| +> PLG stack uses Grafana, deployed in [monitoring](#monitoring), for visualization. + +### Policy Enforcement + +Policy Enforcement is the ability to validate Kubernetes resources against compliance, security, and best-practice policies. If a resource violates a policy, the enforcement tool can deny access to the cluster, dynamically modify the resource to force compliance, or simply record the violation in an audit report. Usually, a reporting tool accompanies the engine to help with analyzing and visualizing policy violations. + +|Default|Stack|Package|Function|Repositories| +|--|--|--|--|--| +| |Gatekeeper|[OPA Gatekeeper](./opa-gatekeeper.md)|Engine & Policies|[policy](https://repo1.dso.mil/big-bang/product/packages/policy)| +| |Gatekeeper|[Cluster Auditor](./cluster-auditor.md)|Reporting|[cluster-auditor](https://repo1.dso.mil/big-bang/product/packages/cluster-auditor)| +|X|Kyverno|[Kyverno](./kyverno.md)|Engine|[kyverno](https://repo1.dso.mil/big-bang/product/packages/kyverno)| +|X|Kyverno|Kyverno Policies|Policies|[kyverno-policies](https://repo1.dso.mil/big-bang/product/packages/kyverno-policies)| +|X|Kyverno|Kyverno Reporter|Reporting|[kyverno-reporter](https://repo1.dso.mil/big-bang/product/packages/kyverno-reporter)| + +### Monitoring + +A monitoring stack is used to collect, visualize, and alert on time-series metrics from cluster resources. Metrics are quantitative measurements that provide insight into the cluster. Some examples of metrics include memory utilization, disk utilization, network latency, number of web queries, or number of database transactions. + +|Default|Stack|Package|Function|Repositories| +|--|--|--|--|--| +|X|Monitoring|[Prometheus](./monitoring.md)|Collection & Alerting|[monitoring](https://repo1.dso.mil/big-bang/product/packages/monitoring)| +|X|Monitoring|[Grafana](./monitoring.md)|Visualization|[monitoring](https://repo1.dso.mil/big-bang/product/packages/monitoring)| + +### Distributed Tracing + +Distributed tracing is a method of tracking application transactions as they flows through cluster services. It is a diagnosing technique to help characterize and troubleshoot problems from the user's perspective. + +|Default|Package|Repositories| +|--|--|--| +| |[Jaeger](./jaeger.md)|[jaeger](https://repo1.dso.mil/big-bang/product/packages/jaeger)| +|X|[Tempo](./tempo.md)|[tempo](https://repo1.dso.mil/big-bang/product/packages/tempo)| + +### Runtime Security + +Runtime security is the active protection of containers running in the cluster. This type of tool includes scanning for vulnerabilities, checking compliance, detecting threats, and preventing intrusions. Many of these tools also include forensics and incident response features. + +|Default|Package|Repositories| +|--|--|--| +| |[Prisma Cloud Compute](./twistlock.md) (AKA Twistlock) ![License Required](https://img.shields.io/badge/License_Required-orange)|[twistlock](https://repo1.dso.mil/big-bang/product/packages/twistlock)| +|X|[Neuvector](./neuvector.md)|[neuvector](https://repo1.dso.mil/big-bang/product/packages/neuvector)| + +## Addons + +End users can extend Big Bang services beyond the core packages by enabling any of the many team-supported addon packages. Addons are supported by the Big Bang team and integrated with the core platform (Istio, Kyverno, Prometheus etc..) There are additional community-supported Big Bang packages that are not listed as addons. + +### Storage Utilities + +For non-critical or on-prem deployments where data loss is an acceptable risk, these utilities offer a simple and low-cost solution for in-cluster data persistence (databases, object / blob storage, and caches). However, if scalability, availability, and resiliency (e.g. backup and restore) are requirements, it is generally advantageous to instead use a managed, cloud based offering. + +|Stack|Package|Function|Repository| +|--|--|--|--| +|MinIO|MinIO Operator|Operator|[minio-operator](https://repo1.dso.mil/big-bang/product/packages/minio-operator)| +|MinIO|[MinIO](./minio.md)|S3 Object Storage|[minio](https://repo1.dso.mil/big-bang/product/packages/minio)| + +### Cluster Utilities + +Cluster utilities add functionality to Kubernetes clusters rather than applications. Examples include resource utilization, cluster backup and restore, continuos deployment, or load balancers. + +|Package|Function|Repository| +|--|--|--| +|[ArgoCD](./argocd.md)|Continuous Deployment|[argocd](https://repo1.dso.mil/big-bang/product/packages/argocd) +|Metrics Server|Monitors pod CPU & memory utilization|[metrics-server](https://repo1.dso.mil/big-bang/product/packages/metrics-server)| +|[Velero](./velero.md)|Cluster Backup & Restore|[velero](https://repo1.dso.mil/big-bang/product/packages/velero)| + +### Security + +Security packages add additional security features for protecting services or data from unauthorized access or exploitation. This includes things like identity providers (IdP), identity brokers, authentication (AuthN), authorization (AuthZ), single sign-on (SSO), security scanning, intrusion detection/prevention, and sensitive data protection. + +|Package|Function|Repository| +|--|--|--| +|[Anchore](./anchore.md)|Vulnerability Scanner|[anchore-enterprise](https://repo1.dso.mil/big-bang/product/packages/anchore-enterprise)| +|[Authservice](./authservice.md)|Istio extension for Single Sign-On (SSO)|[authservice](https://repo1.dso.mil/big-bang/product/packages/authservice)| +|[Keycloak](./keycloak.md)|IdP, Identity Broker, AuthN/Z|[keycloak](https://repo1.dso.mil/big-bang/product/packages/keycloak)| +|[Vault](./vault.md)|Sensitive Data Access Control|[vault](https://repo1.dso.mil/big-bang/product/packages/vault)| + +### Collaboration + +Collaboration tools provide environments to help teams work together online. Chatting, video conferencing, file sharing, and whiteboards are all examples of collaboration tools. + +|Stack|Package|Function|Repository| +|--|--|--|--| +|Mattermost|Mattermost Operator|Operator|[mattermost-operator](https://repo1.dso.mil/big-bang/product/packages/mattermost-operator)| +|Mattermost|[Mattermost](./mattermost.md)|Chat|[mattermost](https://repo1.dso.mil/big-bang/product/packages/mattermost)| + +### Developer Tools + +Developer tools include packages that a programmer would use to plan, author, test, debug, or control code. This includes repositories, bug / feature tracking, pipelines, code analysis, automated tests, and development environments. + +|Stack|Package|Function|Repository| +|--|--|--|--| +|GitLab|[GitLab](./gitlab.md)|Code repository, issue tracking, release planning, security and compliance scanning, pipelines, artifact repository, wiki|[gitLab](https://repo1.dso.mil/big-bang/product/packages/gitlab)| +|GitLab|GitLab Runner|Executor for GitLab pipelines|[gitlab-runner](https://repo1.dso.mil/big-bang/product/packages/gitlab-runner)| +|Nexus|[Nexus Repository Manager](./nexusRepositoryManager.md)|Artifact repository|[nexus](https://repo1.dso.mil/big-bang/product/packages/nexus) +|Sonarqube|[Sonarqube](./sonarqube.md)|Static code analysis|[sonarqube](https://repo1.dso.mil/big-bang/product/packages/sonarqube) + +## Further Information + +You can find some additional details about features supported by each package by visiting [this document](../../packages.md). diff --git a/docs/understanding-bigbang/package-architecture/alloy.md b/docs/understanding-bigbang/package-architecture/alloy.md new file mode 100644 index 0000000000000000000000000000000000000000..0182688dd22d5d0c57a944dbe311bfd42e81381b --- /dev/null +++ b/docs/understanding-bigbang/package-architecture/alloy.md @@ -0,0 +1,83 @@ +# Grafana Alloy + +## Overview + +[Grafana Alloy](https://grafana.com/docs/alloy/latest/), formerly known as +Grafana Agent, is Grafana's opinionated spin of the OpenTelemetry collector. It +combines many open-source projects in the cloud-native observability space with +the goal of being the only observability component necessary to collect and +distribute telemetry signals within a cluster. + +```mermaid +flowchart TD + subgraph Monitoring + Prometheus/Thanos + Loki + end + + subgraph DT[Distributed Tracing] + Tempo + end + + subgraph A[Alloy] + Alloy + Alloy ==> |Traces| Tempo + Alloy ==> |Metrics| Prometheus/Thanos + Alloy ==> |Logs| Loki + end + + style EU stroke-dasharray: 10 10 + subgraph EU[End-User Applications] + App-A -->|OpenTelemetry| Alloy + App-B -->|OpenTelemetry| Alloy + App-C -->|OpenTelemetry| Alloy + end + + subgraph N[K8s Node] + CL[Container Logs]-->|Logs|Alloy + NE[Node Exporter]-->|Metrics|Alloy + end + + subgraph ServiceMonitors + Service-A<-->|Metrics|Alloy + Service-B<-->|Metrics|Alloy + Service-C<-->|Metrics|Alloy + end +``` + +## Big Bang Touchpoints + +### Licensing + +Grafana Alloy is open-source, +[licensed under Apache 2.0](https://github.com/grafana/alloy/blob/main/LICENSE). + +### UI + +While Grafana Alloy does expose a +[UI for visualizing its configuration status](https://grafana.com/docs/alloy/latest/troubleshoot/debug/), +it is not necessary for use and is not exposed by default within Big Bang. + +### Storage + +Grafana Alloy requires no storage itself, opting instead to push telemetry +signals to other cluster components like Loki and Tempo, which have their own +storage needs. + +### Logging + +Grafana Alloy writes its logs to stderr. These logs will be picked up by the +logging collector configured within the cluster. + +### High Availability + +Grafana Alloy supports multiple deployment modes with built-in clustering. +Depending on which features are enabled in the `k8s-monitoring` chart, Alloy +may be deployed as a `StatefulSet`, `DaemonSet`, or `Deployment`. + +### Health Checks + +Grafana Alloy is configured with standard liveness and readiness probes. In +addition to the health of Alloy itself, cluster administrators can view the UI +mentioned above for specific health statuses of individual Alloy +[components](https://grafana.com/docs/alloy/latest/get-started/components/). diff --git a/docs/understanding-bigbang/package-architecture/anchore.md b/docs/understanding-bigbang/package-architecture/anchore.md new file mode 100644 index 0000000000000000000000000000000000000000..136ca094c33a6ec51d4065fcae3cbfeb32dd47a9 --- /dev/null +++ b/docs/understanding-bigbang/package-architecture/anchore.md @@ -0,0 +1,155 @@ +# Anchore + +## Overview + +[Anchore](https://anchore.com/) is a Docker container static analysis and policy-based compliance system that automates the inspection, analysis, and evaluation of images against user-defined checks to allow high confidence in container deployments by ensuring workload content meets the required criteria. + +Anchore offers several [open source tools](https://anchore.com/opensource/) and products, however, this document will cover the architectural touch points for the Big Bang Anchore package, which includes Anchore Engine (open source) and Anchore Enterprise (requires enterprise license). For more information on the differentiators between Anchore's open source and commercial offerings, see [here](https://anchore.com/pricing/). + +### Anchore Engine + +```mermaid +graph LR + subgraph "Anchore Engine" + anchorepods("Anchore Pods") + anchoreservice{{"API Service"}} --> anchorepods("Anchore Pods") + end + + subgraph "Ingress" + ig(Ingress Gateway) --> anchoreservice + end + + subgraph "Database Storage (Postgres)" + anchorepods("Anchore Pods") --> database[(Anchore DB)] + end + + subgraph "Object Storage (S3/Swift)" + anchorepods("Anchore Pods") --> bucket[(Anchore Bucket)] + end +``` + +### Anchore Enterprise + +```mermaid +graph LR + subgraph "Anchore Enterprise" + anchorepods("Anchore Pods") + anchoreservice1{{"API Service"}} --> anchorepods("Anchore Pods") + anchoreservice2{{"Enterprise UI Service"}} --> anchorepods("Anchore Pods") + end + + subgraph "Session Storage (Redis)" + anchoreservice2 --> database3[("Enterprise UI DB")] + end + + subgraph "Ingress" + ig(Ingress Gateway) --> anchoreservice1 + ig(Ingress Gateway) --> anchoreservice2 + end + + subgraph "Database Storage (Postgres)" + anchorepods("Anchore Pods") --> database1[(Anchore DB)] + anchorepods("Anchore Pods") --> database2[(Enterprise Feeds DB)] + end + + subgraph "Object Storage (S3/Swift)" + anchorepods("Anchore Pods") --> bucket[(Anchore Bucket)] + end + + subgraph "Logging" + anchorepods("Anchore Pods") --> fluent(Fluentbit) --> logging-ek-es-http + logging-ek-es-http{{Elastic Service<br />logging-ek-es-http}} --> elastic[(Elastic Storage)] + end + + subgraph "Monitoring" + svcmonitor("Service Monitor") --> anchoreservice1 + Prometheus --> svcmonitor("Service Monitor") + end +``` + +For more information on the Anchore Enterprise architecture, see [Enterprise Service Overview and Architecture](https://docs.anchore.com/current/docs/overview/architecture/). + +## Big Bang Touch Points + +### Licensing + +The Big Bang Anchore Enterprise services require a valid Anchore Enterprise license as well as credentials with access to Registry1 hosting the hardened images. + +To be onboarded and provided with a trial or production license, please send an email to publicsector@anchore.com including program name and contact details. + +Once you have obtained a license this can be added to your values in Big Bang to automatically set up your Anchore deployment with the license (replacing the `licenseYaml:` value with your full license): + +```yaml +addons: + anchore: + enterprise: + enabled: true + licenseYaml: | + ehjgjhh... +``` + +### Single Sign On + +Anchore Enterprise 2.1+ can be configured to support user login to the UI using identities from external identity providers that support SAML 2.0. In such a configuration, Anchore never stores any credentials for the users, only their usernames and Anchore permissions, and all UI access is gated through a user’s valid login into the identity provider. Anchore uses the external provider to verify username identity and initialize a username, account, and roles on first login for a new user. Once a user’s identity is initialized in Anchore, the Anchore administrator may manage user permissions by managing the roles associated with the user’s identity in Anchore itself. For more information, see [Anchore Enterprise SSO Support](https://docs.anchore.com/current/docs/configuration/sso/). + +See below for an example of the values to provide to Anchore Enterprise for SSO setup: + +```yaml +addons: + anchore: + sso: + enabled: true + client_id: platform1_a8604cc9-f5e9-4656-802d-d05624370245_bb8-anchore + role_attribute: "" +``` + +### Storage + +Anchore relies on a PostgreSQL database as its primary data store. By default, Anchore will deploy an in-cluster PostgreSQL database, but it is recommended that an external PostgreSQL 9.6+ database be used, which can be configured in the Big Bang values.yaml. For more information, see [Anchore Enterprise Storage Overview](https://docs.anchore.com/current/docs/configuration/storage/). + +### High Availability + +Since Anchore relies on a PostgreSQL database, it is recommended that production users utilize their database service's HA and scaling capabilities (e.g. Amazon Aurora, Google Cloud SQL, etc.). For users who need scaling or redundancy for their object storage, S3 or Swift are recommended. By default, Anchore Enterprise will utilize an HA redis deployment, but it can also be configured to use an external redis such as Elasticache). + +Anchore Enterprise can run one or more analyzer services to scale out the processing of images. There may be many of these analyzers but best practice is to not have more than one per node since analysis is very IO intensive (see [Affinity](https://repo1.dso.mil/big-bang/product/packages/anchore-enterprise/-/blob/main/docs/Affinity.md) for an example of how to specify nodeSelector/affinity/anti-affinity). By specifying a `replicaCount` for the analyzers, the number of analysis pods can be scaled up or down: + +```yaml +addons: + anchore: + values: + anchoreAnalyzer: + replicaCount: 2 +``` + +As of the anchore-engine Chart version 0.9.0, all services can be scaled-out, so the above example can be modified for the `anchoreApi:`, `anchoreCatalog:`, `anchorePolicyEngine:`, and `anchoreSimpleQueue:` components as well. + +### UI + +Anchore Enterprise includes a UI, which can be used to scan repositories and images, edit policy bundles, manage users accounts and roles via RBAC, and view and generate security vulnerability and policy evaluation reports. For more information, see [Using the Anchore Enterprise UI](https://docs.anchore.com/current/docs/using/ui_usage/). + +### Logging + +Anchore services produce detailed logs that contain information about user interactions, internal processes, warnings and errors. The verbosity of the logs is controlled using the log_level setting in config.yaml (for manual installations) or the corresponding ANCHORE_LOG_LEVEL environment variable (for Helm installations) for each service. The log levels are DEBUG, INFO, WARN, ERROR, and FATAL, where the default is INFO. Most of the time, the default level is sufficient as the logs will contain warn, error and fatal messages as well, but for deep troubleshooting, it is always recommended to increase the log level to DEBUG in order to ensure the availability of the maximum amount of information. For more information, see [Anchore Enterprise Logs](https://docs.anchore.com/current/docs/troubleshooting/#logs). + +_Note:_ within Big Bang, logs are captured by fluentbit and shipped to elastic by default. + +### Monitoring + +Anchore Engine and Enterprise expose prometheus metrics in the API of each service if the config.yaml used by that service has the metrics.enabled key set to true. Each service exports its own metrics and is typically scraped by a Prometheus installation to gather the metrics. Anchore does not aggregate or distribute metrics between services. You should configure your Prometheus deployment or integration to check each Anchore service’s api (using the same port it exports), for the /metrics route. For more information, see [Anchore Enterprise Monitoring](https://docs.anchore.com/current/docs/configuration/monitoring/#monitoring-in-kubernetes-andor-helm-chart). + +The Big Bang Anchore Helm chart has been modified to use your `monitoring:` values in Big Bang to automatically toggle metrics on/off. + +### Health Checks + +Liveness and readiness probes are included in the Anchore Helm chart for all deployments. System health can also be retrieved via the CLI, API, or UI. For example, to see the health of the Anchore services after a Helm install via the CLI: + +```shell +kubectl -n anchore exec -it <ANCHORE_ENGINE_API_POD> -- anchore-cli --u <USERNAME> --p <PASSWORD> system status +``` + +For more information, see [Anchore Enterprise System Health](https://docs.anchore.com/current/docs/using/ui_usage/system_health/). + +### Dependent Packages + +- PostgreSQL 9.6+ (in-cluster by default; can be configured to use an external postgres) +- Redis (in-cluster by default; can be configured to use an external redis) diff --git a/docs/understanding-bigbang/package-architecture/argocd.md b/docs/understanding-bigbang/package-architecture/argocd.md new file mode 100644 index 0000000000000000000000000000000000000000..72ed21800bfdc04ed966d315cd0fa3d81c91dc67 --- /dev/null +++ b/docs/understanding-bigbang/package-architecture/argocd.md @@ -0,0 +1,180 @@ +# Argocd + +## Overview + +Argo CD is a declarative, [GitOps](https://www.gitops.tech/) continuous delivery tool for Kubernetes. + +ArgoCD is a kubernetes native tool that enables the delivery of GitOps practices. It uses a git repository as a source of truth in defining the desired state. It is implemented as a kubernetes controller continuously monitoring running applications and reconciling it against the desired state in the source git repository. + + +Argo CD uses an Application Controller component to continuously watch applications that are executing. Argo CD then differentiates the applications live state against the target state that resides in the Git repository. It supports a range of configuration management tools such as [Helm](https://helm.sh/), [kustomize](https://kustomize.io/), [ksonnet](https://ksonnet.io/get-started/), and [jsonnet](https://jsonnet.org/). + +### Argocd + +```mermaid +graph LR + subgraph "ArgoCD" + argocdservice1("argocd") + end + + subgraph "Kubernetes Cluster 1" + argocdservice1("argocd") --> k8scluster1("K8s Cluster 1") + end + + subgraph "Kubernetes Cluster 2" + argocdservice1("argocd") --> k8scluster2("K8s Cluster 2") + end + + subgraph "Logging" + argocdservice1("argocd") --> fluent(Fluentbit) --> logging-ek-es-http + logging-ek-es-http{{Elastic Service<br />logging-ek-es-http}} --> elastic[(Elastic Storage)] + end + + subgraph "Monitoring" + svcmonitor("Service Monitor") --> argocdservice1("argocd") + Prometheus --> svcmonitor("Service Monitor") + end +``` + +For more information on the Argocd architecture, see [Argocd Architectural Overview](https://argo-cd.readthedocs.io/en/stable/operator-manual/architecture/). + +## Big Bang Touch Points + +### Licensing + +The Big Bang Argocd deployment uses a permissive license (i.e., a free-software license which instead of copyleft protections, carries only minimal restrictions on how the software can be used, modified, and redistributed.) whose main conditions require preservation of copyright and license notices. Contributors provide an express grant of patent rights. Licensed works, modifications, and larger works may be distributed under different terms and without source code. + +### Single Sign On + +ArgoCD an be configured to support user login to the UI using identities from external identity providers that support SAML 2.0. + +See below for an example of the values to provide to argocd for SSO setup: + +```yaml +addons: + argocd: + sso: + enabled: true + client_id: + client_secret: "" + groups: | + g, Impact Level 2 Authorized, role:admin +``` + +### Storage + +Argo CD is largely stateless, all data is persisted as Kubernetes objects, which in turn is stored in Kubernetes' etcd. Redis is only used as a throw-away cache and can be lost. When lost, it will be rebuilt without loss of service. + +### High Availability + +Upstream provides methods and [documentation](https://argo-cd.readthedocs.io/en/stable/operator-manual/high_availability/#argocd-dex-server-argocd-redis) for deploying argocd in HA. + +Requirements: +- HA installation will require at least three different nodes due to pod anti-affinity roles in the specs. +- `controller.replicas` and the `ARGOCD_CONTROLLER_REPLICAS` controller environment variable must have matching values (see below). +- ArgoCD is pre-configured with the understanding of only three total redis servers. The package deploys a master with 3 replicas by default. + +Caveats: +- The argocd-dex-server uses an in-memory database, and two or more instances would have inconsistent data. + +The following is an example of how to modify the Big Bang values to accommodate a HA deployment. + +```yaml +addons: + argocd: + values: + controller: + replicas: 3 + env: + - name: "ARGOCD_CONTROLLER_REPLICAS" + value: "3" + server: + replicas: 3 + repoServer: + replicas: 3 +``` + +For additional information about an ArgoCD high availability deployment visit [ArgoCD High Availability](https://argo-cd.readthedocs.io/en/stable/operator-manual/installation/#high-availability) + +### UI + +ArgoCD includes a UI, which is accessible at a configurable URL. The UI can be used to view, manage, and create applications. + +ArgoCD is Istio injected and the VirtualService resource is accessible externally from the cluster at "argocd.{{ .Values.domain }}" but can be configured via the following values in the bigbang chart: + +```yaml +domain: bigbang.dev +istio: + enabled: true + argocd: + # -- Toggle Istio VirtualService creation + enabled: true + # -- Set Annotations for VirtualService + annotations: {} + # -- Set Labels for VirtualService + labels: {} + # -- Set Gateway for VirtualService + gateways: + - istio-system/main + # -- Set Hosts for VirtualService + hosts: + - argocd.{{ .Values.domain }} + +``` + +If you need to alter the VirtualService host out of band you will also need to configure the argocd `config.url` to match: + +```yaml +addons: + argocd: + values: + # -- Manage Argo CD configmap (Declarative Setup) + ## Ref: https://github.com/argoproj/argo-cd/blob/master/docs/operator-manual/argocd-cm.yaml + configEnabled: true + # -- [General Argo CD configuration] + # @default -- See [values.yaml] + config: + # Argo CD's externally facing base URL (optional). Required when configuring SSO + url: https://argocd.bigbang.dev +``` + +### Logging + +Argo CD logs payloads of most API requests except request that are considered sensitive, such as /cluster.ClusterService/Create, /session.SessionService/Create etc. The full list of method can be found in server/server.go For more information, see [ArgoCD Logs](https://argo-cd.readthedocs.io/en/stable/operator-manual/security/#logging). + +An example of how to modify the argocd logging values within Big Bang is as follows: + +```yaml +addons: + argocd: + values: + controller: + # -- Set the logging level. (One of: `debug`, `info`, `warn`, `error`) + logLevel: debug + # -- Application controller log format. Either `text` or `json` + logFormat: text + server: + # -- Set the logging level. (One of: `debug`, `info`, `warn`, `error`) + logLevel: debug + # -- Application controller log format. Either `text` or `json` + logFormat: text + repoServer: + # -- Set the logging level. (One of: `debug`, `info`, `warn`, `error`) + logLevel: debug + # -- Application controller log format. Either `text` or `json` + logFormat: text +``` + +_Note:_ within Big Bang, logs are captured by fluentbit or promtail and shipped to your enabled logging stack (ECK by default, PLG is also available). + +### Monitoring + +ArgoCD exposes prometheus metrics in the API of each service if the config.yaml used by that service has the metrics.enabled keys set to enabled and `metrics.servicemonitor` keys set to true. Each service exports its own metrics and is typically scraped by a Prometheus installation to gather the metrics. + +The Big Bang ArgoCD Helm chart has been modified to use your `monitoring:` values in Big Bang to automatically toggle metrics on/off. + +### Health Checks + +Argo CD provides built-in health assessment for several standard Kubernetes types, which is then surfaced to the overall application health status as a whole. + +For more information, see [ArgoCD Resource Health](https://argo-cd.readthedocs.io/en/stable/operator-manual/health/). diff --git a/docs/understanding-bigbang/package-architecture/authservice.md b/docs/understanding-bigbang/package-architecture/authservice.md new file mode 100644 index 0000000000000000000000000000000000000000..2045c183ed8054f4b329dbe3c26b3eb0e2abb28b --- /dev/null +++ b/docs/understanding-bigbang/package-architecture/authservice.md @@ -0,0 +1,165 @@ +# Authservice + +An implementation of [Envoy](https://envoyproxy.io) [External Authorization](https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/ext_authz_filter), +focused on delivering authN/Z solutions for [Istio](https://istio.io) and [Kubernetes](https://kubernetes.io). + +## Overview + +`authservice` helps delegate the [OIDC Authorization Code Grant Flow](https://openid.net/specs/openid-connect-core-1_0.html#CodeFlowAuth) +to the Istio mesh. `authservice` is compatible with any standard OIDC Provider as well as other Istio End-user Auth features, +including [Authentication Policy](https://istio.io/docs/tasks/security/authn-policy/) and [RBAC](https://istio.io/docs/tasks/security/rbac-groups/). +Together, they allow developers to protect their APIs and web apps without any application code required. + +```mermaid +graph LR + pod("URL") --> authservice + envoyfilter --> |redirect| pod2("IdP") + pod2 --> |token| apppods + + subgraph "Authservice" + subgraph "Any Namespace" + apppods("Application Pod(s)") + end + + subgraph "istio-system Namespace" + envoyfilter{{"Envoy Filter"}} + end + + subgraph "Authservice Namespace" + authservice{{"Authservice Service"}} --> envoyfilter + end + + end + + subgraph "Session Storage (Redis)" + authservice --> database3[("Authservice DB")] + end + + subgraph "Logging" + authservice --> fluent(Fluentbit) --> logging-ek-es-http + logging-ek-es-http{{Elastic Service<br />logging-ek-es-http}} --> elastic[(Elastic Storage)] + end +``` + +## Big Bang Touch Points + +### Licensing + +[Authservice](https://github.com/istio-ecosystem/authservice) utilizes an Apache-2.0 License. The Iron Bank repo for the hardened authservice image can be found [here](https://repo1.dso.mil/dsop/istio-ecosystem/authservice) and the Big Bang repo for the authservice Helm Chart can be found [here](https://repo1.dso.mil/big-bang/product/packages/authservice). + +### Single Sign On + +Authservice provides OIDC Single Sign On capabilities for apps that don't have native support. + +Pods just need to have istio-injection, a single label which by default is `protect=keycloak` applied to the pods, and a corresponding chain to load into authservice. + +```yaml +spec: + template: + metadata: + labels: + protect: keycloak +``` + +If you need to guarantee that authservice protects everything behind istio-ingressgateway, you can label ingressgateway instead of individual applications. + +```yaml +istio: + ingressGateways: + public-ingressgateway: + extraLabels: + protect: keycloak +``` + +This label can be adjusted via following values in the Big Bang chart: + +```yaml +addons: + authservice: + values: + selector: + key: protect + value: keycloak +``` + +The corresponding chain loaded in to authservice via the values in the Big Bang chart: +For more information see the [README.md](https://repo1.dso.mil/big-bang/product/packages/authservice/-/blob/main/README.md) in the Authservice package. + +```yaml +addons: + authservice: + chains: + example: + callback_uri: ... + match: ... + client_id: ... + client_secret: ... +``` + +### Storage + +Authservice can be configured to use a local redis deployment (disabled by default) for distributed state storage. This Redis instance is used cache session data. + +```yaml +addons: + authservice: + values: + redis: + enabled: true +``` + +Authservice can also be configured to communicate with external redis serivces such as Elasticache. + +```yaml +addons: + authservice: + values: + global: + redis_server_uri: "tcp://redis-01.7abc2d.0001.usw2.cache.amazonaws.com:6379" +``` + +### High Availability + +When setting `replicaCount` above `1`, Authservice will require an HA redis deployment (see above) in order to function. + +Authservice also utilizes a horizontal pod autoscaler, which can be configured with min & max replicas and target CPU & memory utilization: + +```yaml +addons: + authservice: + values: + replicaCount: 2 + redis: + enabled: true + autoscaling: + enabled: false + minReplicas: 1 + maxReplicas: 3 + targetCPUUtilizationPercentage: 80 + targetMemoryUtilizationPercentage: 80 +``` + +### UI + +There is no UI feature for authservice. + +### Logging + +Within Big Bang, logs are captured by fluentbit and shipped to elastic by default. + +### Health Checks + +The authservice Dockerfile includes a [healthcheck](https://repo1.dso.mil/dsop/istio-ecosystem/authservice/-/blob/master/Dockerfile#L23-24) and the authservice Helm Chart includes [liveness & readiness probes](https://repo1.dso.mil/big-bang/product/packages/authservice/-/blob/main/chart/templates/deployment.yaml#L42-47) in its deployment: + +```yaml +livenessProbe: + tcpSocket: + port: 10003 +readinessProbe: + tcpSocket: + port: 10003 +``` + +### Dependent Packages + +When setting `replicaCount` above `1`, a redis configuration is required. diff --git a/docs/understanding-bigbang/package-architecture/cluster-auditor.md b/docs/understanding-bigbang/package-architecture/cluster-auditor.md new file mode 100644 index 0000000000000000000000000000000000000000..136151d054e657739602e286259117527c2a7f5d --- /dev/null +++ b/docs/understanding-bigbang/package-architecture/cluster-auditor.md @@ -0,0 +1,39 @@ +# Cluster Auditor + +## Overview + +Cluster Auditor(CA) pulls constraints from the kubernetes API, transforms them and inserts them into Prometheus to be displayed in a Grafana Dashboard. Cluster Auditor uses OPA Gatekeeper CRDs and native kubernetes [objects](https://repo1.dso.mil/big-bang/product/packages/cluster-auditor/-/blob/main/chart/templates/clusterRole.yaml). + +## Big Bang Touch Points + +```mermaid +graph TB + subgraph "Cluster Auditor" + clusterauditor + end + + subgraph "Prometheus" + clusterauditor --> prometheus + end +``` + +## High Availability + +CA currently does not support HA. + +## Storage + +It uses the currently deployed Prometheus that's deployed as part of the monitoring stack. + +## Single Sign On (SSO) + +CA does not have SSO Integration. + +## Licensing + +CA is based off of the OPA Scorecard which uses the [Apache License 2.0](https://github.com/mcelep/opa-scorecard/blob/master/LICENSE). + +## Dependant Packages + +- Monitoring +- OPA Gatekeeper diff --git a/docs/understanding-bigbang/package-architecture/elasticsearch-kibana.md b/docs/understanding-bigbang/package-architecture/elasticsearch-kibana.md new file mode 100644 index 0000000000000000000000000000000000000000..1d88756e27fb1f084d3c66c3e16bb05006813a16 --- /dev/null +++ b/docs/understanding-bigbang/package-architecture/elasticsearch-kibana.md @@ -0,0 +1,136 @@ +# Elasticsearch-Kibana + +## Overview + +[Elasticsearch-Kibana](https://www.elastic.co/elastic-stack) Elasticsearch is a search engine based on the Lucene library. It provides a distributed, multi-tenant-capable full-text search engine with an HTTP web interface and schema-free JSON documents. Kibana is a data visualization dashboard for Elasticsearch. It provides visualization capabilities on top of the content indexed on an Elasticsearch cluster. Users can create bar, line and scatter plots, or pie charts and maps on top of large volumes of data. + +## Big Bang Touch Points + +```mermaid +graph TB + subgraph "Ingress" + ingressgateway + end + + subgraph "Operator" + eck-operator + end + + subgraph "Kibana" + ingressgateway --> kibana + eck-operator --> kibana + end + + subgraph "Elasticsearch" + kibana --> elasticsearch + eck-operator --> elasticsearch + end + + subgraph "Metrics" + kibana --> prometheus + end +``` + +### Storage + +Persistent storage for both Elasticsearch Master and Data nodes can be configured with the following values: + +```yaml +elasticsearchKibana: + values: + elasticsearch: + master: + persistence: + storageClassName: "" + size: 10Gi + data: + persistence: + storageClassName: "" + size: 20Gi +``` + +### Istio Configuration + +Istio is disabled in the elasticsearch-kibana chart by default and can be enabled with the following values in the bigbang chart: + +```yaml +hostname: bigbang.dev +istio: + enabled: true +``` + +These values get passed into the logging chart [here](https://repo1.dso.mil/big-bang/bigbang/-/blob/master/chart/templates/elasticsearch-kibana/values.yaml#L6). This creates the Istio virtual service and maps to the main istio gateway for bigbang. The Kibana GUI is available behind this Istio VirtualService that is configured automatically at "kibana.{{ .Values.hostname }}" (value set above) and can be configured with the following values: + +```yaml +elasticsearchKibana: + values: + istio: + kibana: + # Toggle vs creation + enabled: true + annotations: {} + labels: {} + gateways: + - istio-system/main + hosts: + - kibana.{{ .Values.hostname }} +``` + +## High Availability + +This can be accomplished by increasing the "count" or number of replicas in each deployment in the stack: + +```yaml +elasticsearchKibana: + values: + kibana: + count: 1 + elasticsearch: + master: + count: 3 + data: + count: 4 +``` + +## Single Sign On (SSO) + +SSO integration for the eck stack requires a license (see below) and can be configured with the following values: + +```yaml +elasticsearchKibana: + sso: + # -- Toggle OIDC SSO for Kibana/Elasticsearch on and off. + # Enabling this option will auto-create any required secrets. + enabled: true + # -- Elasticsearch/Kibana OIDC client ID + client_id: "EXAMPLE_OIDC_CLIENT" + # -- Elasticsearch/Kibana OIDC client secret + client_secret: "EXAMPLE_OIDC_CLIENT_SECRET" +``` + +## Licensing + +Features like SSO integration, email/slack/Pagerduty alerting, FIPS 140-2 mode, encryption at rest, and more for the eck stack requires a platinum or enterprise license. Information about licensing and all features is available [here](https://www.elastic.co/pricing/). A Trial license can be enabled by setting `trial: true` in the below settings to enable a 30-day trial of enterprise settings. +Licensing can be configured with the following values: + +```yaml +elasticsearchKibana: + license: + trial: false + keyJSON: | + {"license":{"uid":....}} +``` + +## Health Checks + +Licensed ECK comes with [built in Health monitoring for Kibana and Elasticsearch](https://www.elastic.co/guide/en/kibana/current/monitoring-kibana.html). This is called self-monitoring within the Kibana UI available at the Stack Monitoring settings <https://KIBANA_URL/app/monitoring>#. + +Outside of the UI it is possible to check the health of Elasticsearch cluster via port-forward via doing the following: + +```shell +kubectl get secrets -n logging logging-ek-es-elastic-user -o go-template='{{.data.elastic | base64decode}}' + +kubectl port-forward svc/logging-ek-es-http -n logging 9200:9200 + +curl -ku "elastic:ELASTIC_PASSWORD" "https://localhost:9200/_cluster/health?pretty" +``` diff --git a/docs/understanding-bigbang/package-architecture/external-secrets-operator.md b/docs/understanding-bigbang/package-architecture/external-secrets-operator.md new file mode 100644 index 0000000000000000000000000000000000000000..549c2c9529d3812153ebdb7e352f6ae2513cf900 --- /dev/null +++ b/docs/understanding-bigbang/package-architecture/external-secrets-operator.md @@ -0,0 +1,76 @@ +# External Secrets Operator + +## Overview + +[External Secrets Operator](https://github.com/external-secrets/external-secrets) reads information from a third-party service (such as AWS Secrets Manager, or Vault) and automatically injects the values into the Kubernetes cluster as Kubernetes secrets. + +### External Secrets Operator + +```mermaid +graph LR + vault("Vault") + awssm("AWS Secrets Manager") + kubeapi("kube-apiserver") --> esocmp2 + k8secret1("Kubernetes Secret A") <--> extsecret1 + k8secret2("Kubernetes Secret B") <--> extsecret2 + extsecret1("Ext Secret A") <--> secretstore1 + extsecret2("Ext Secret B") <--> secretstore2 + secretstore1("ESO Store A") <--> esocmp1 --> awssm + secretstore2("ESO Store B") <--> esocmp1 --> vault + esocmp1("ESO Controller") --> extsecret1 + esocmp1("ESO Controller") --> extsecret2 + esocmp2("ESO Webhook") --> k8secret1 + esocmp2("ESO Webhook") --> k8secret2 + esocmp3("ESO Cert Manager") --> k8secret1 + esocmp3("ESO Cert Manager") --> k8secret2 + app1("Big Bang Package") --> k8secret1 + app1("Big Bang Package") --> k8secret2 +``` + +## Big Bang Touch Points + +### Licensing + +External Secrets Operator is [licensed under the Apache License](https://github.com/external-secrets/external-secrets/blob/main/LICENSE). No additional licensing is necessary for use or redistribution. + +### Storage + +The external secrets operator adds no new storage mechanisms of its own, but allows for the integration of various external secrets providers (like AWS Secrets Manager, or Vault) to Kubernetes secrets. + +The only storage to configure is the [SecretStore](https://external-secrets.io/latest/api/secretstore/) and [ClusterSecretStore](https://external-secrets.io/latest/api/clustersecretstore/) objects which perform this integration. + +### UI + +The external secrets operator has no user interface. It is an operator that enhances and modifies other objects, it is not a service that stands on its own. + +### Logging + +The External Secrets Operator produces logs that contain information about the internal state of the controller, webhook and cert controller. This information is currently logged by the default pod logging mechanism. + +_Note:_ within Big Bang, logs are captured by fluentbit and shipped to elastic by default. + +External Secrets Operator loglevels are controllable through the values passed to the addon. Here is an example of configuring debug log levels for the ESO controller, certificate controller and webhook: + +```yaml +addons: + vault: + values: + extraArgs: + loglevel: debug + certController: + extraArgs: + loglevel: debug + webhook: + extraArgs: + loglevel: debug +``` + +### Monitoring + +The external secrets operator provides the ability to monitor the status and performance of secret stores, external secret providers, and individual secrets. These external secrets are provided through the `/metrics` endpoint. + +Additional steps are required to display the collected metrics in Grafana. A sample dashboard is provided in [the upstream documentation](https://external-secrets.io/main/api/metrics/). + +### Health Checks + +Liveness and readiness probes are included in the external secrets operator chart for all deployments. The `/healthz/ready` endpoint is used on port 8081 (by default). \ No newline at end of file diff --git a/docs/understanding-bigbang/package-architecture/fluentbit.md b/docs/understanding-bigbang/package-architecture/fluentbit.md new file mode 100644 index 0000000000000000000000000000000000000000..096124729950e5cde2a6df075e3937664dc7ef19 --- /dev/null +++ b/docs/understanding-bigbang/package-architecture/fluentbit.md @@ -0,0 +1,78 @@ +# Fluentbit + +## Overview + +[FluentBit](https://fluentbit.io/) is an open source Log Processor and Forwarder which allows you to collect any data like metrics and logs from different sources, enrich them with filters and send them to multiple destinations. It's the preferred choice for containerized environments like Kubernetes. + +## Big Bang Touch Points + +```mermaid +graph TB + subgraph "Fluent-Bit" + fluentbit + end + + subgraph "Elasticsearch" + fluentbit --> elasticsearch + end +``` + +### Storage + +Fluentbit itself does not use or require any persistent storage, however it does need hostPath mounts to the kubernetes nodes to tail and process log data. These hostPath volumes are for `/var/log/containers` to tail logs from containers running on the nodes, and `/var/log/flb-storage` which is a configurable [storage buffer](https://docs.fluentbit.io/manual/administration/buffering-and-storage) path in use for Big Bang production environments. +This storage buffer is configurable via the following values in Big Bang: + +```yaml +fluentbit: + values: + storage_buffer: + path: /var/log/flb-storage/ + + extraVolumes: + - hostPath: + path: /var/log/flb-storage/ + type: DirectoryOrCreate + name: flb-storage + + extraVolumeMounts: + - mountPath: /var/log/flb-storage/ + name: flb-storage +``` + +This storage buffer hostPath mount, in conjunction with the hostPath mount of `/var/log/containers/` used to fetch logs requires a securityContext of `privileged` to be set if SELinux is set to `Enforcing` on the kubernetes nodes. To set this securityContext for the fluentbit pods, add the following values in Big Bang: + +```yaml +fluentbit: + values: + securityContext: + privileged: true +``` + +## Logging + +Since Fluentbit is the method for shipping cluster logs to the ECK stack, to reduce the amount of logs fluentbit and ECK has to process, fluentbit container logs are excluded from being processed and shipped to ECK. However, if you would like to enable fluentbit container logs being sent to ECK you just have to remove the "Excluded_Path" portion of this INPUT block (requires presence of entire block even when changing a single line): + +```yaml +fluentbit: + values: + config: + inputs: | + [INPUT] + Name tail + Path /var/log/containers/*.log + Exclude_Path /var/log/containers/*fluent*.log,/var/log/containers/*gatekeeper-audit*.log + Parser containerd + Tag kube.* + Mem_Buf_Limit 50MB + Skip_Long_Lines On + storage.type filesystem +``` + +## High Availability + +Fluent-bit by default runs as a [Kubernetes DaemonSet with a single pod on each node in the cluster](https://docs.fluentbit.io/manual/installation/kubernetes#concepts). There is no need to run multiple pods per node as only one is required to maintain the state of logs that appear on that node. The Big Bang fluent-bit package also comes with default values to enable and configure [a storage buffer](https://docs.fluentbit.io/manual/installation/kubernetes#concepts) to better index and process records on your Kubernetes nodes in the event of pod restarts or pods becoming unhealthy. + +## Health Checks + +Fluentbit is able to be configured with a service port for the container, which is able to expose [all kinds of metrics](https://docs.fluentbit.io/manual/administration/monitoring) including metrics for Prometheus. +Starting with Chart version 0.15.X fluentbit comes packaged (when monitoring is enabled) with a ServiceMonitor for the prometheus-operator also bundled with Big Bang so that metrics are available in the Prometheus and Grafana UIs, the latter thanks to this [Grafana Dashboard](https://docs.fluentbit.io/manual/administration/monitoring#grafana-dashboard). diff --git a/docs/understanding-bigbang/package-architecture/fortify.md b/docs/understanding-bigbang/package-architecture/fortify.md new file mode 100644 index 0000000000000000000000000000000000000000..7f468114381c6d794c3fa0db48d6f77ab66c6408 --- /dev/null +++ b/docs/understanding-bigbang/package-architecture/fortify.md @@ -0,0 +1,51 @@ + +# Fortify +## Overview +Micro Focus Fortify Software Security Center(SSC) or simply "**[Fortify](https://www.microfocus.com/en-us/cyberres/application-security/software-security-center)"**, is a centralized management and analysis facility for application data gathered and processed using Fortify analysis products and tools(**Fortify Static Code Analyzer, Fortify WebInspect, and Audit WorkBench**, etc), providing visibility to an organization's entire application security program to help resolve security vulnerabilities across the software portfolio. It is a platform where users can review, audit, prioritize, and manage remediation efforts, track software security testing activities, and measure improvements via the management dashboard and reports to optimize static and dynamic application security test results. Fortify SSC helps to provide an accurate picture and scope of the application security posture across the enterprises. +### Architecture +- [Fortify Architecture](https://www.microfocus.com/documentation/fortify-software-security-center/2310/SSC_Help_23.1.0/index.htm#SSC_UG/A_Install_Env.htm?TocPath=Part%2520I%253A%2520Deploying%2520Fortify%2520Software%2520Security%2520Center%257CPreparing%2520for%2520%2520Fortify%2520Software%2520Security%2520Center%2520Deployment%257C_____2) + +The following table provides descriptions of the required and optional Fortify Software Security Center installation components in the illustration. + +| Component | Description | +| --- | --- | +| Fortify SSC Server | Fortify Software Security Center is delivered as a Web Archive (WAR) file run by Tomcat Server or as a Helm chart for Kubernetes deployment. | +| SSC database |Third‑party database that Fortify Software Security Center requires to store user and artifact data. Before you put Fortify Software Security Center into production, you must install a supported third‑party database. | +| Third‑party LDAP authentication server | (Optional) You can configure Fortify Software Security Center to use LDAP authentication. | +| Defect‑tracking server |(Optional) You can configure Fortify Software Security Center to enable bug submission directly to Bugzilla, Jira, ALM, Azure DevOps Server, or a customized bug‑tracking system. For information about how to create a customized bug-tracking system, see [Authoring Bug Tracker Plugins](https://www.microfocus.com/documentation/fortify-software-security-center/2310/SSC_Help_23.1.0/Content/SSC_UG/Author_Plugins.htm). | +| Third‑party email server |(Optional) You can configure Fortify Software Security Center to use an external SMTP email server to send alerts to application collaborators. | +| Fortify Static Code Analyzer analysis agent |(Optional) Fortify Static Code Analyzer scans source code and identifies issues. | +| Audit Workbench and IDE plugins |Audit Workbench and Fortify IDE plugins can be used as alternative source‑code auditing tools. | +| Jenkins\ Azure DevOps\ Bamboo |Use these plugins to scan source code (using Fortify Static Code Analyzer) and upload scan results. | +| Fortify ScanCentral SAST |(Optional) Fortify Static Code Analyzer users can use ScanCentral SAST to offload processor-intensive code analysis tasks from their build machines to a group of machines (sensors) provided for this purpose. | +| Fortify ScanCentral DAST |(Optional) A dynamic application security testing tool that you can use to configure and run dynamic scans of your web applications from Fortify Software Security Center. | +| Fortify WebInspect |(Optional) Analysis agent that connects with Fortify WebInspect agents to retrieve potential dynamic issues. | +| Fortify Security Content update server |Used to acquire and update Security Content. | + +**Important! **Fortify does not support load balancing across multiple Fortify Software Security Center servers. + +## Big Bang Touchpoints + +### KyvernoPolicies + +When deploying to k3d, the `validationFailureAction` for the `restrict-host-path-mount-pv` policy should be set to `audit`. This can be done by modifying `chart/values.yaml` file or passing an override file with the values set as seen below. This is for development purposes only: production should use the default setting of `enforce`. + +```yaml +kyvernoPolicies: + values: + policies: + restrict-host-path-mount-pv: + validationFailureAction: audit +``` + +## Licensing +By default, Big Bang will deploy Fortify without a license. if you have a license, you can add your license via the values file as shown below: + +```yaml +addons: + fortify: + fortify_license: | + <license> +``` + +**Note**: This should be added via encrypted values to protect the license diff --git a/docs/understanding-bigbang/package-architecture/gitlab.md b/docs/understanding-bigbang/package-architecture/gitlab.md new file mode 100644 index 0000000000000000000000000000000000000000..11c4b86c2e80d396cd7e9a19c95289f0be101515 --- /dev/null +++ b/docs/understanding-bigbang/package-architecture/gitlab.md @@ -0,0 +1,190 @@ +# Gitlab + +## Overview + +[Gitlab](https://about.gitlab.com/) is an open-source with premium offering, self-hostable Git repository, build system and container registry. + +Big Bang's implementation uses the [Gitlab Helm Chart](https://docs.gitlab.com/charts/) to provide custom resources and manage the application. + +A more detail view of Big Bang's implementation of Gitlab can be found in the [package docs](https://repo1.dso.mil/big-bang/product/packages/gitlab/-/tree/main/chart/doc). + +## Big Bang Touch Points + +### UI + +The Gitlab UI is the primary way of interacting with Gitlab. The UI is accessible via a web application on the cluster at the DNS name "gitlab" (e.g. gitlab.bigbang.com). The UI provides access to all Gitlab features. + +### Logging + +Gitlab has a logging mechanism built in that logs all relevant events in a json format. More detailed information can be found in their [logging docs](https://docs.gitlab.com/ee/administration/logs.html). + +### Monitoring + +Monitoring has been configured to use the Bigbang monitoring package (Prometheus and Grafana). This is automatically enabled by having monitoring enabled in the main values file. + +```yaml +# Monitoring +# +monitoring: + # -- Toggle deployment of Monitoring (Prometheus, Grafana, and Alertmanager). + enabled: true + +``` + +### Health Checks + +Gitlab provides built in health checks. + +```shell +GET /-/health +``` + +Example request + +```shell +curl "https://gitlab.example.com/-/health" +``` + +Gitlab also provides a separate liveness and readiness probes. + +```shell +GET /-/readiness +GET /-/readiness?all=1 +``` + +Example request + +```shell +curl "https://gitlab.example.com/-/readiness" +``` + +```shell +GET /-/liveness +``` + +Example request + +```shell +curl "https://gitlab.example.com/-/liveness" +``` + +More information can be found in the gitlab documentation [here](https://docs.gitlab.com/ee/user/admin_area/monitoring/health_check.html). + +## High Availability + +GitLab deployed on a Kubernetes(K8S) cluster can achieve “self healingâ€. In other words, if a container goes down, K8S replaces it with a new one. K8S can also provide rolling upgrades. However, a K8S deployment by itself does not provide full high availablity(HA). Refer to the upstream [Gitlab HA reference achitectures](https://docs.gitlab.com/ee/administration/reference_architectures/). The Gitlab helm chart provides the ability to set replica counts for some of the services as shown in the BigBang values override example below. + +Note that the gitaly service requires a significant and non-trivial amout of configuration to acheive HA. Gitaly provides high-level RPC access to Git repositories. It is used by GitLab to read and write Git data. A Gitaly cluster must be created on Praefect nodes. The Big Bang Product Team has not yet tested use of a Gitaly cluster and will not be able to provide support. If you require Gitaly HA refer to the upstream [Gitaly Cluster documentation](https://docs.gitlab.com/ee/administration/gitaly/praefect.html) and leverage a support contact with Gitlab. For small to medum sized deployments you can simply increase the gitaly resources as shown in the example below. +```yaml +addons: + gitlab: + values: + gitlab: + webservice: + minReplicas: 3 + maxReplicas: 3 + gitlab-shell: + minReplicas: 3 + maxReplicas: 3 + sidekiq: + minReplicas: 3 + maxReplicas: 3 + gitaly: + resources: + limits: + cpu: 2 + memory: 4G + requests: + cpu: 2 + memory: 4G + registry: + hpa: + minReplicas: 3 + maxReplicas: 3 +``` + +## Single Sign On (SSO) + +Gitlab can be integrated with Keycloak for single sign on. Full documentation can be found in the package docs [here](https://repo1.dso.mil/big-bang/product/packages/gitlab/-/blob/main/docs/keycloak.md). + +## Licensing + +GitLab is built on an open core model. GitLab Community Edition is open source, with an MIT Expat license. GitLab Enterprise Edition is built on top of Community Edition. + +GitLab Enterprise Edition uses the same core, but adds additional features and functionality on top of that. These additional features are under a proprietary license that makes the code published source-available. + +Bigbang currently used the community edition. This can be overwritten in the values.yaml file. + +```yaml +## doc/installation/deployment.md#deploy-the-community-edition + edition: ce +``` + +More information about GitLab licensing can be found [here](https://about.gitlab.com/install/ce-or-ee/) for the information page and [here](https://gitlab.com/gitlab-org/gitlab/blob/master/LICENSE) for the actual license. + +## Storage + +### Database Storage + +Gitlab uses a Postgresql database to store all metadata for git repositories as well as all business logic around the UI and workflows within the application. By default Bigbang will install a internal Postgres instance to support Gitlab. The recommended approach is to provision and use an external Postgres instance. + +You can configure an external database by providing the values needed in the Bigbang values.yaml file under the Gitlab section. Entering connection info will automatically disable the deployment of an internal database and will deploy using the external instance. + +```yaml + database: + # -- Hostname of a pre-existing PostgreSQL database to use for Gitlab. + # Entering connection info will disable the deployment of an internal database and will auto-create any required secrets. + host: "" + + # -- Port of a pre-existing PostgreSQL database to use for Gitlab. + port: 5432 + + # -- Database name to connect to on host. + database: "" # example: gitlab + + # -- Username to connect as to external database, the user must have all privileges on the database. + username: "" + + # -- Database password for the username used to connect to the existing database. + password: "" + +``` + +### File Storage + +Gitlab uses S3, Minio, or another S3-style storage for file storage. By default Big Bang deploys an in-cluster Minio instance for this purpose, but you have the option to point to an external Minio or S3 if desired. See the below example for the values to supply: + +```yaml + objectStorage: + # -- Type of object storage to use for Gitlab, setting to s3 will assume an external, pre-existing object storage is to be used. + # Entering connection info will enable this option and will auto-create any required secrets + type: "" # supported types are "s3" or "minio" + + # -- S3 compatible endpoint to use for connection information. + # examples: "https://s3.amazonaws.com" "https://s3.us-gov-west-1.amazonaws.com" "http://minio.minio.svc.cluster.local:9000" + endpoint: "" + + # -- S3 compatible region to use for connection information. + region: "" + + # -- Access key for connecting to object storage endpoint. + accessKey: "" + + # -- Secret key for connecting to object storage endpoint. + # Unencoded string data. This should be placed in the secret values and then encrypted + accessSecret: "" + + # -- Bucket prefix to use for identifying buckets. + # Example: "prod" will produce "prod-gitlab-bucket" + bucketPrefix: "" + +``` + +## Dependencies + +Additional pass-throughs for dependencies that deviate from rationalized standards can be passed using the values: tag in the main Bigbang values.yaml. + +```yaml +# -- Values to passthrough to the gitlab runner chart: https://repo1.dso.mil/big-bang/product/packages/gitlab-runner.git + values: {} +``` diff --git a/docs/understanding-bigbang/package-architecture/harbor.md b/docs/understanding-bigbang/package-architecture/harbor.md new file mode 100644 index 0000000000000000000000000000000000000000..89c236740e00c05d847543766371bb831375bc95 --- /dev/null +++ b/docs/understanding-bigbang/package-architecture/harbor.md @@ -0,0 +1,125 @@ +# Harbor + +## Overview + +[Harbor](https://goharbor.io/) is an open source registry that secures artifacts with policies and role-based access control, ensures images are scanned and free from vulnerabilities, and signs images as trusted. + +### Harbor + +```mermaid +graph LR + subgraph "Harbor" + harborpods("Harbor Pods") + end + + subgraph "Ingress" + ig(Ingress Gateway) --> harborpods("Harbor Pods") + end + + subgraph "External Databases" + harborpods("Harbor Pods") --> database1[(PostgreSQL DB)] + harborpods("Harbor Pods") --> database2[(Redis DB)] + end + + subgraph "Object Storage (S3/Swift)" + harborpods("Harbor Pods") --> bucket[(Harbor Bucket)] + end + + subgraph "Image Scanner" + harborpods("Harbor Pods") --> Trivy("Trivy") + end + + subgraph "Logging" + harborpods("Harbor Pods") --> fluent(Fluentbit) --> logging-ek-es-http + logging-ek-es-http{{Elastic Service<br />logging-ek-es-http}} --> plg[(PLG Storage)] + end + + subgraph "Monitoring" + svcmonitor("Service Monitor") --> harborpods("Harbor Pods") + Prometheus --> svcmonitor("Service Monitor") + end +``` + + + +For more information on the Harbor architecture, see [Harbor Overview and Architecture](https://github.com/goharbor/harbor/wiki/Architecture-Overview-of-Harbor). + +## Harbor Touch Points + +### Storage + +By default Harbor uses local storage for the registry, but you can optionally configure the storage_service setting so that Harbor uses external storage. + +See below for an example of the values to provide an external storage backend for Harbor: + +```yaml +persistence: + imageChartStorage: + # Specify the type of storage: "filesystem", "azure", "gcs", "s3", "swift", + # "oss" and fill the information needed in the corresponding section. The type + # must be "filesystem" if you want to use persistent volumes for registry + type: s3 + s3: + # Set an existing secret for S3 accesskey and secretkey + # keys in the secret should be REGISTRY_STORAGE_S3_ACCESSKEY and REGISTRY_STORAGE_S3_SECRETKEY for registry + #existingSecret: "" + region: us-west-1 + bucket: bucketname + #accesskey: awsaccesskey + #secretkey: awssecretkey + #regionendpoint: http://myobjects.local + #encrypt: false + #keyid: mykeyid + #secure: true +``` + +### High Availability + +Reference the [Harbor High Availability Guide](https://repo1.dso.mil/big-bang/apps/sandbox/harbor/-/blob/main/chart/docs/High%20Availability.md) for an overview of a harbor high availability deployment. + +See below for an example of the values to provide high availability within harbor: + +```yaml +portal: + replicas: 2 +core: + replicas: 2 +jobservice: + replicas: 2 +registry: + replicas: 2 +``` + +### UI + +Harbor is accessible via extensible API and web UI. Within the values you are able to configure the URL that harbor is able to be accessed. + +See below for an example of how to set the values to set the URL for UI within Harbor: + +```yaml +externalURL: https://core.harbor.domain +core: + secretName: "name_of_secret" +``` + +For additional information reference [Deploying Harbor in Production](https://repo1.dso.mil/big-bang/apps/sandbox/harbor/-/blob/harbor-architecture/docs/production.md) + +### Logging + +Harbor keeps a log of all of the operations that users perform in a project. You can apply filters to help you to search the logs. By default, Harbor tracks all image pull, push, and delete operations performed and keeps a record of these actions in a database. Harbor offers the ability to manage audit logs by configuring an audit log retention window and setting a syslog endpoint to forward audit logs. + +### Monitoring + +Harbor exposes prometheus metrics in the API of each service if the config.yaml used by that service has the metrics.enabled keys set to enabled. Each service exports its own metrics and can be scraped by the monitoring package within a BigBang installation. + +See below for an example of how to set the values to enable metrics for Harbor: + +```yaml +metrics: + enabled: true +``` + +### Dependent Packages + +- PostgreSQL (in-cluster by default; can be configured to use an external postgres) +- Redis (in-cluster by default; can be configured to use an external redis) diff --git a/docs/understanding-bigbang/package-architecture/holocron.md b/docs/understanding-bigbang/package-architecture/holocron.md new file mode 100644 index 0000000000000000000000000000000000000000..692d2e038e2e0ccebee527cd85029c20c3820d34 --- /dev/null +++ b/docs/understanding-bigbang/package-architecture/holocron.md @@ -0,0 +1,20 @@ +# Holocron + +## Overview +Holocron is a software delivery metrics tracker and aggregator. It is designed to provide key insights into potential pain points for software delivery teams and help facilitate more efficient development. Holocron is an opinionated tool displaying goals for work in progress, continuous integration, and keeping piplines, branches, and merge requests from becoming stale. It also tracks how much effort is spent on different types of work, how often bugs are introduced, and how quickly tickets are resolved. It is an open-source project developed in-house at Platform One. + +### Architecture + +| Component | Description | +| --- | --- | +| Holocron Dashboard | Frontend allowing communication with the API to configure teams, value streams, and organizations and view their collected metrics. | +| Holocron API | Backend server connecting to the database, receives requests from the frontend and can potentially be integrated with a custom UI solution. | +| Postgresql Database | Holocron requires a Postgresql database for persistence. | +| SSO | (Optional) Holocron can utilize RBAC if there is an SSO service enabled. | +| Collector GitLab Build | (Optional) Periodically collects build data (pipelines) from a targeted GitLab instance. | +| Collector GitLab SCM |(Optional) Periodically collects SCM data (commits, branches, etc.) from a targeted GitLab instance. | +| Collector GitLab Workflow | (Optional) Periodically collects workflow data (tickets) from a targeted GitLab instance. | +| Collector Jira Workflow | (Optional) Periodically collects workflow data (tickets) from a targeted Jira instance. | +| Collector SonarQube Project Analysis | (Optional) Periodically collects project issue data (code smells, vulnerabilities, etc.) from a targeted SonarQube instance. | + +**Note: While all collectors are optional, Holocron won't have any metrics and as such no value if none are utilized.** diff --git a/docs/understanding-bigbang/package-architecture/istio.md b/docs/understanding-bigbang/package-architecture/istio.md new file mode 100644 index 0000000000000000000000000000000000000000..ac06c89b80f9dc8de6138881143b624ce5a0aafd --- /dev/null +++ b/docs/understanding-bigbang/package-architecture/istio.md @@ -0,0 +1,100 @@ +# Istio + +## Overview + +[Istio](https://istio.io/latest/docs/concepts/what-is-istio/) is an open platform for providing a uniform way to [integrate microservices](https://istio.io/latest/docs/examples/microservices-istio/), manage [traffic flow](https://istio.io/latest/docs/concepts/traffic-management/) across microservices, enforce policies and aggregate telemetry data. Istio's control plane provides an abstraction +layer over the underlying cluster management platform, such as Kubernetes. + +```mermaid +graph LR + subgraph "Istio" + dataplane("Data Plane<br/>AKA Gateway") + controlplane{{"Control Plane"}} --> dataplane + igw("Ingress Gateway") --"http 8080<br/>https 8443<br/>istiod 15012<br/>status 15021<br/>tls 15443"--> dataplane + end + + ig("Ingress") --> igw + + subgraph "Monitoring" + svcmonitor("Service Monitor") --> controlplane + Prometheus --> svcmonitor("Service Monitor") + end + + subgraph "App" + dataplane --"app.bigbang.dev"<br/>port redirects--> appvs{{"Virtual Service"}} --> appsvc{{"App Service"}} + end + + subgraph "Logging" + controlplane --> fluent(Fluentbit) --> logging-ek-es-http + logging-ek-es-http{{Elastic Service<br />logging-ek-es-http}} --> elastic[(Elastic Storage)] + end +``` + +## Big Bang Touchpoints + +### Licensing + +Istio is an open source tool that utilizes an Apache-2.0 License. + +### Storage + +Aside from the packages that it can integrate with, Istio provides no storage requirements. + +### High Availability + +By default, Istio is configured with 1 istiod replica, but it can be configured in the Big Bang values to use horizontal pod autoscaling: + +```yaml +istio: + values: + istiod: + replicaCount: 1 + hpaSpec: + minReplicas: 1 + maxReplicas: 3 +``` + +Likewise, the ingress gateway replicas can be specified and extra ingress gateways can be configured: + +```yaml +istio: + values: + ingressGateway: + minReplicas: 1 + maxReplicas: 5 + extraIngressGateways: + # ... +``` + +### UI + +Big Bang can be configured to deploy [Kiali](https://repo1.dso.mil/big-bang/product/packages/kiali) (a management console that provides dashboards, observability, and other robust capabilities) and [Jaeger](https://repo1.dso.mil/big-bang/product/packages/jaeger) (an end-to-end distributed tracing system), both of which include UI features to help you visualize your Istio mesh. To enable Kialia and Jaeger, simply update the Big Bang values.yaml: + +```yaml +istio: + enabled: true +jaeger: + enabled: true +kiali: + enabled: true +``` + +### Logging + +Within Big Bang, logs are captured by fluentbit and shipped to elastic by default. + +### Monitoring + +Monitoring can be enabled to automatically capture metrics for Istio when `monitoring.enabled` is set to `true` in the Big Bang values.yaml. Since Istio 1.5, standard metrics are directly exported by the Envoy proxy. For a list of metrics, see [Istio Standard Metrics](https://istio.io/latest/docs/reference/config/metrics/#metrics) and [Istio Observability](https://istio.io/latest/docs/ops/best-practices/observability/). + +Grafana (part of the monitoring packages) is a standalone component of Big Bang that can provide dashboards to show monitoring data. For more information, see Big Bang's [Grafana docs](https://repo1.dso.mil/big-bang/product/packages/monitoring/-/tree/main/docs#grafana) and [Visualizing Metrics with Grafana](https://istio.io/latest/docs/tasks/observability/metrics/using-istio-dashboard/). + +### Healthchecks + +There are standard readiness probes built into the envoy sidecars and istio containers. See [here](https://istio.io/latest/docs/reference/config/istio.operator.v1alpha1/#ReadinessProbe) for more info. + +You can get events in an istio-injected namespace to see if your sidecars are unhealthy or having issues. To check the health/status of the istio installation, run `kubectl get istiooperators -n istio-system`. + +### Dependant Packages + +- istio-operator \ No newline at end of file diff --git a/docs/understanding-bigbang/package-architecture/jaeger.md b/docs/understanding-bigbang/package-architecture/jaeger.md new file mode 100644 index 0000000000000000000000000000000000000000..655286b869587fe6001816c551eba196098808d9 --- /dev/null +++ b/docs/understanding-bigbang/package-architecture/jaeger.md @@ -0,0 +1,107 @@ +# Jaeger + +## Overview + +[Jaeger](https://www.jaegertracing.io/) is an open source implementation of Zipkin that can be used to collect and visualize traces. + +## Big Bang Touch Points + +```mermaid +graph TB + subgraph "jaeger" + jaegerpods("Jaeger-AllInOne") + elasticcredentials --> jaegerpods("Jaeger-AllInOne") + end + + subgraph "ingress" + ingressgateway --> jaegerpods("Jaeger-AllInOne") + end + + subgraph "logging" + subgraph "elasticsearch" + + credentials --> elasticcredentials + jaegerpods("Jaeger-AllInOne") --> logging-ek-es-http + logging-ek-es-http --> LoggingElastic(Elasticsearch Storage ) + end + end + + subgraph "workloads" + sidecar --> jaegerpods("Jaeger-AllInOne") + end +``` + +### Storage + +When Jaeger receives traces, it needs a location to store them. The default configuration in the Helm Chart is to use in memory storage. This, of course, doesn't provide High Availability. To provide storage, the chart uses the deployed Elasticsearch instance deployed in the logging namespace. + +### Istio Configuration + +Istio is configured with knowledge of the jaeger ingest service so istio sidecars attached to workloads can send trace data. This is done via the `meshconfig`: + +```yaml + meshConfig: + accessLogFile: /dev/stdout + defaultConfig: + tracing: + sampling: 100 + zipkinAddress: jaeger-jaeger-operator-jaeger-collector.istio-system.svc:9411 + enableTracing: false +``` + +## High Availability + +Jaeger is deployed with HorizonalPodAutoscalers for the collector and the querying pods. Use the below yaml to update the `maxReplicas` on the HPA: + +```yaml +jaeger: + values: + jaeger: + spec: + query: + maxReplicas: 5 + collector: + maxReplicas: 5 +``` + +## Single Sign on (SSO) + +Jaeger does not have built in SSO. In order to provide SSO, this deployment leverages [Authservice](https://github.com/istio-ecosystem/authservice). + +```mermaid +flowchart LR + +A --> K[(Keycloak)] + +subgraph external +K +end + +subgraph auth["authservice namespace"] + A(authservice) --> K +end + + + +ingress --> IP + + +subgraph "jaeger namespace" + subgraph "jaeger pod" + J["jaeger"] + IP["istio proxy"] --> A + IP --> J + end +end + +``` + +## Licencing + +Jaeger has no licensing options nor requirements. + +For production workloads, Jaeger uses Elasticsearch to store and query for traces. + +## Dependencies + +Jaeger can be run without dependencies, but to ensure resiliency of data, it uses Elasticsearch for its span and trace database. diff --git a/docs/understanding-bigbang/package-architecture/keycloak.md b/docs/understanding-bigbang/package-architecture/keycloak.md new file mode 100644 index 0000000000000000000000000000000000000000..82cd411096c23f60c1770633aa12e8e7188d815c --- /dev/null +++ b/docs/understanding-bigbang/package-architecture/keycloak.md @@ -0,0 +1,150 @@ +# Keycloak + +## Overview + +[Keycloak](https://www.keycloak.org/) provides open source identity and access management for modern applications and services. This document will cover the architectural touchpoints for the Big Bang Keycloak package, which has been extended to include customizable registration and group segmentation. + +### Keycloak Architecture + +```mermaid +graph LR + urlkc(Keycloak URL) -->|HTTPS| pg + urlpr(Prometheus URL) -->|HTTPS| ig + + subgraph "Istio System" + ig(Public Gateway) + pg(Passthrough Gateway) + end + + subgraph "Monitoring" + ig --> servpr("Service<BR>Prometheus") --> prom + prom(Prometheus) + end + + subgraph "Keycloak" + pg --> servkc("Service<BR>Keycloak") --> pod0("Keycloak Pod 0") + prom --> monitor(Service Monitor CRD) --> servkc + end + + pod0("Keycloak Pod 0") --> db[(Keycloak DB)] +``` + +## Integration with Big Bang + +Big Bang's integration with Keycloak requires special considerations and configuration compared to other applications. This document will help you set it up. + +## Configuration + +See [Keycloak Configuration](https://repo1.dso.mil/big-bang/product/packages/keycloak/-/blob/main/docs/configuration.md) in the Big Bang Keycloak Helm chart repo for help configuring the following: + +* TLS Certificates +* Custom Admin Password +* Registration Plugin +* Keycloak Helm values + +## Big Bang Touch-points + +### GUI + +Keycloak has two main end point URLs: +<https://keycloak.yourdomain.com> for authentication. +<https://keycloak.yourdomain.com/auth/admin> for administration. + +The `yourdomain.com` domain name can be customized by setting the value `domain` in Big Bang's `values.yaml` + +### Database + +An external shared database is required for Keycloak operation in production. It should be setup according to [the Keycloak database configuration documentation](https://www.keycloak.org/server/db). + +> For development and testing, a Postgres database is provided inside the cluster. This should **NOT** be used in production. + +The following values can be customized in Big Bang's `values.yaml` to connect to your external database: + +```yaml +addons: + keycloak: + values: + database: + hostname: yourdb.yourdomain.com + vendor: postgres + port: 5432 + database: keycloak + username: kcuser + password: p@ssw0rd +``` + +### Logging + +Logging is automatic for Keycloak when the Logging package is enabled in Big Bang. Fluentbit captures the logs and ships them to Elastic. + +### Monitoring + +When the Monitoring package is enabled, Big Bang will turn on Keycloak's production of Prometheus metrics and set up a Service Monitor to scrape those metrics. By default, metrics for the `datasources` (db), `undertow` (http), and `jgroup` subsystems are enabled. + +### Health Checks + +Liveness and readiness probes are included in the Keycloak Helm chart for all deployments. The probes check the endpoint at `/auth/realm/master/` on port 8080 of the pods. This means the probes will still succeed even if you have an invalid certificate loaded into Keycloak. + +If you wish to adjust the probes, you can override the values in `values.yaml`: + +```yaml +addons: + keycloak: + values: + livenessProbe: | + httpGet: + path: /auth/realms/master + port: http + scheme: HTTP + initialDelaySeconds: 120 + failureThreshold: 15 + periodSeconds: 15 + readinessProbe: | + httpGet: + path: /auth/realms/master + port: http + scheme: HTTP + initialDelaySeconds: 120 + failureThreshold: 15 + timeoutSeconds: 2 +``` + +## Licensing + +Keycloak is available under the [Apache License 2.0](https://github.com/keycloak/keycloak/blob/master/LICENSE.txt) for free. + +## High Availability + +By default, Big Bang deploys Keycloak via a stateful set with one replica. It is already configured to support cache sharing, anti-affinity, fail-overs, and rolling updates. If you wish to increase the number of replicas you must first make sure you are pointed to an external database, and then the replicas can be increased, all of which can be set in `values.yaml`: + +```yaml +addons: + keycloak: + values: + replicas: 3 # Override the default + database: + host: "" + type: "" + port: "" + database: "" + username: "" + password: "in-encrypted-values" +``` + +The Keycloak package also comes with a HorizontalPodAutoscaler resource which can be enabled. Enabling the HPA will overwrite the `replicas` key shown above: + +```yaml +addons: + keycloak: + values: + autoscaling: + enabled: true + minReplicas: 2 + maxReplicas: 4 +``` + +## Dependent Packages + +- Istio for ingress +- (Optional) Monitoring for metrics +- PostgreSQL database (development/test only) diff --git a/docs/understanding-bigbang/package-architecture/kiali.md b/docs/understanding-bigbang/package-architecture/kiali.md new file mode 100644 index 0000000000000000000000000000000000000000..77c738d58c235f36694f9012f4b47ea6b43770ef --- /dev/null +++ b/docs/understanding-bigbang/package-architecture/kiali.md @@ -0,0 +1,167 @@ +# Kiali + +## Overview + +[Kiali](https://kiali.io/) is a console for managing your Istio service mesh. It provides graphical views of networking interactions, metrics, and configuration options for the mesh. To aggregate this data it interacts with Prometheus, Grafana, and Jaeger. + +Big Bang's implementation uses the [Kiali operator](https://github.com/kiali/kiali-operator) to provide custom resources and manage the deployment. + +## Big Bang Touch Points + +```mermaid +graph LR + subgraph "Kiali" + Operator("Kiali Operator<br />(manages/deploys Kiali)") + Kialipods("Kiali Pod(s)") + kialiservice{{Kiali Service}} --> Kialipods("Kiali Pod(s)") + + end + + subgraph "Ingress" + ig(Ingress Gateway) --"App Port"--> kialiservice + end + + subgraph "Monitoring" + Kialipods("Kiali Pod(s)") --> prometheusservice{{Prometheus Service<br />monitoring-monitoring-kube-prometheus}} --> Prometheus("Prometheus") + Kialipods("Kiali Pod(s)") --> grafanaservice{{Grafana Service<br />monitoring-monitoring-grafana}} --> Grafana("Grafana") + end + + subgraph "Tracing" + Kialipods("Kiali Pod(s)") --> queryservice{{Query Service<br />jaeger-query}} --> jaeger(Jaeger) + end +``` + +NOTE: Prometheus is required for Kiali to function properly; Jaeger and Grafana are optional (although all are part of Big Bang Core). + +### Storage + +Kiali does not have any persistent storage, all data is accessed live/directly from Jaeger/Monitoring services. + +### Istio Configuration + +The Istio VirtualService is created automatically (hosted at `kiali.{{ .Values.hostname }}`) and can be configured with the following values: + +```yaml +kiali: + # Gateway override + ingress: + gateway: "private" + values: + istio: + kiali: + # Hostname override + hosts: + - kiali.{{ .Values.hostname }} +``` + +Kiali is also pre-configured with knowledge of the BB Istio stack for monitoring purposes. Kiali will monitor the status of all ingressGateways and istiod and display a status "bubble" when a component is unreachable or down. + +### External Service Configuration + +Kiali in Big Bang is preconfigured with the service information to connect to Big Bang's deployments of Prometheus, Grafana, and Jaeger. If you wish to configure Kiali with different external services rather than the BB provided ones, you can do that via values overrides: + +```yaml +kiali: + values: + cr: + spec: + external_services: + ... + # Fill in with your custom overrides + # See https://github.com/kiali/kiali-operator/blob/master/deploy/kiali/kiali_cr.yaml#L422 for available options + ... +``` + +Since both Prometheus and Jaeger are open to Kiali via the service address there is no authentication needed for them. Grafana authentication will be set up automatically using the admin account for Grafana. + +Important note: If you modify the Grafana admin username/password via the UI or another method besides Helm values (`monitoring.values.grafana.adminPassword` or `monitoring.values.grafana.admin.existingSecret`), Kiali will not be autoconfigured with this knowledge. This is due to limitations in where/how Grafana stores the "live" password. If you do modify your Grafana username/password in one of these ways, it is recommended to pass these values to your Grafana install via one of the below methods where they will also be picked up by Kiali: + +```yaml +monitoring: + values: + grafana: + # Direct passing via values (method 1) + adminUser: myadminuser + adminPassword: myadminpassword + # Passing via secret (method 2) + admin: + existingSecret: mygrafanasecret + userKey: myusernamekey + passwordKey: mypasswordkey +``` + +## High Availability + +HA can be accomplished for Kiali via two methods. You can directly control the replicas required or have Kiali create and use a horizontal pod autoscaler and set a min/max number of replicas for the deployment. + +Big Bang uses the horizontal pod autoscaler by default with `minReplicas: 1` and `maxReplicas: 2`. + +Both methods are shown below: + +- Specific number of replicas +```yaml +kiali: + values: + cr: + spec: + deployment: + replicas: 3 +``` + +- HPA with min/max replicas +```yaml +kiali: + values: + cr: + spec: + deployment: + hpa: + spec: + maxReplicas: 5 + minReplicas: 3 +``` + +## Single Sign on (SSO) + +SSO for Kiali is done via [built in OIDC](https://kiali.io/docs/configuration/authentication/openid/). Big Bang abstracts and simplifies the settings required for SSO setup. The following values can be used to configure SSO for Kiali: + +```yaml +kiali: + sso: + enabled: true + client_id: platform1_a8604cc9-f5e9-4656-802d-d05624370245_bb8-kiali + client_secret: your_client_secret_or_empty_string +# Kiali inherits/uses the global SSO settings at .sso +``` + +If you require a more advanced SSO configuration there are additional ways to customize that are detailed in the [upstream OIDC docs](https://kiali.io/docs/configuration/authentication/openid/). This doc includes details on how to configure username, scope, timeout, proxies, and more. It also lists some [SSO provider specifics](https://kiali.io/docs/configuration/authentication/openid/#_provider_specific_instructions) which may be needed for configuring with different providers. If you want to provide any further configuration than what is included in the `kiali.sso` block, you can override the BB pre-configured SSO and pass values via `kiali.values.cr.spec.auth`. + +## Non-SSO Login + +If you do not configure Kiali with SSO you will have [4 options](https://kiali.io/docs/configuration/authentication/) for authentication. Big Bang will default to using the token method. + +- Token: Uses the Kubernetes service account token for authentication. This method makes use of your cluster's RBAC and you can create additional service accounts/tokens to restrict access. In general Kiali gives the same access as whatever is granted to the token used for login (additional [details provided upstream](https://kiali.io/docs/configuration/rbac/)). + - To get the default Kiali SA token for login: `kubectl get secret -n kiali | grep kiali-service-account-token | awk '{print $1}' | xargs kubectl get secret -n kiali -o go-template='{{.data.token | base64decode}}'` +- OpenShift: This method will redirect users to the OpenShift console login page for authentication (and is only available for use on OpenShift). Details and setup can be seen in the [upstream docs](https://kiali.io/docs/configuration/authentication/openshift/). +- Header: Requires use of reverse proxy to inject token into the header of the request. More details and considerations are noted [upstream](https://kiali.io/docs/configuration/authentication/header/). +- Anonymous: No authentication, Kiali is open to whoever can access the URL. + +Example of how to override the authentication method: +```yaml +kiali: + values: + cr: + spec: + auth: + strategy: "anonymous" +``` + +## Licensing + +Kiali is open source and released under [Apache License v2](https://www.apache.org/licenses/LICENSE-2.0.txt). There are no paid options for licensing or support. + +## Dependencies + +Since Kiali is used to observe the Istio service mesh it is tightly coupled with Istio and dependent on Istio being deployed. + +Big Bang's implementation of Kiali is dependent on Monitoring (Prometheus and Grafana) and Jaeger as well. While these services are not required for setup, Kiali will be missing information if one or more of them are not deployed (note that all are part of the core BB stack). diff --git a/docs/understanding-bigbang/package-architecture/kyverno.md b/docs/understanding-bigbang/package-architecture/kyverno.md new file mode 100644 index 0000000000000000000000000000000000000000..1f2f4d3f6bb9669b45e3bc2fb91bc4f3550b55e2 --- /dev/null +++ b/docs/understanding-bigbang/package-architecture/kyverno.md @@ -0,0 +1,84 @@ +# Kyverno + +## Overview + +Kyverno is a policy engine designed for Kubernetes, where policies are managed as Kubernetes resources rather than with some domain-specific language. Kyverno policies can be managed by kubectl, git, and kustomize just like app deployments. Kyverno policies can validate, mutate, and generate Kubernetes resources plus ensure OCI image supply chain security, among other things. + +## Big Bang Touch Points + +### Architecture: +- [How Kyverno works](https://kyverno.io/docs/introduction/#how-kyverno-works) + +### Storage + +Data from Kyverno is not stored by the app directly, it is stored as objects in the Kubernetes API. + +### Istio Configuration + +When deploying to k3d, istio-system should be added from `excludedNamespaces` under the `allowedDockerRegistries` violations. This can be done by modifying `chart/values.yaml` file or passing an override file with the values set as seen below. This is for development purposes only: production should not allow containers in the `istio-system` namespace to be pulled from outside of Registry1. + +```yaml +kyvernoPolicies: + values: + exclude: + any: + # Allows k3d load balancer to bypass policies. + - resources: + namespaces: + - istio-system + names: + - svclb-* +``` + +## High Availability + +High availability is accomplished by increasing the replicas in the values file of this helm chart. The recommended replica counts for HA is at least 3 which is enabled by default in BigBang chart. + +```yaml +kyverno: + values: + replicaCount: 3 +``` + +## Kyverno Reporter + +Kyverno Reporter is an optional component providing two main reporting functions: +* Providing a metrics endpoint which can be used to observe in monitoring tools like Grafana. +* Reporting Kyverno policy violations to various configurable `targets`, including Grafana Loki, Elasticsearch, Slack, Discord or MS Teams. + + +```yaml +kyvernoReporter: + enabled: true +``` + +### Kyverno Reporter UI +While not yet officially supported by BigBang the Kyverno Reporter can be useful for inspecting policy results when other tools like Grafana are not available or in debugging scenarios. +```yaml +kyvernoReporter: + enabled: true + + values: + global: + plugins: + kyverno: + enabled: true + + ui: + enabled: true + + kyvernoPlugin: + enabled: true +``` + +## Single Sign on (SSO) + +None. This service doesn't have a web interface. + +## Licencing + +[Apache 2.0 License](https://github.com/kyverno/kyverno/blob/main/LICENSE) + +## Dependencies + +`kyverno` is a dependency of `kyvernoPolicies`. KyvernoPolicies is a collection of Kyverno security and best-practice policies for Kyverno diff --git a/docs/understanding-bigbang/package-architecture/loki.md b/docs/understanding-bigbang/package-architecture/loki.md new file mode 100644 index 0000000000000000000000000000000000000000..aff81a41696fb5176118e5af13e0a011f15a1dfc --- /dev/null +++ b/docs/understanding-bigbang/package-architecture/loki.md @@ -0,0 +1,136 @@ +# Loki + +Loki is a horizontally-scalable, highly-available, multi-tenant log aggregation system inspired by Prometheus. It is designed to be very cost effective and easy to operate. It does not index the contents of the logs, but rather a set of labels for each log stream. Loki is like Prometheus, but for logs: we prefer a multidimensional label-based approach to indexing, and want a single-binary, easy to operate system with no dependencies. Loki does require a forwarder to ship logs into it's database. + +## Monolith + +```mermaid +flowchart TD + S3[(S3)] + Promtail/FluentBit--> Loki + Grafana --> Loki --> S3 +``` + +## (Simple) Scalable +```mermaid +flowchart TD + S3[(S3)] + read[Loki Read] --> S3 + write[Loki Write] + Promtail/FluentBit--> write --> S3 + Grafana --> read +``` + +## Monolith with Grafana Enterprise Logging (GEL) +```mermaid +flowchart TD + subgraph Enterprise + g[GEL Gateway] --> a[Admin API] + a[Admin API] + end + Promtail/FluentBit--> g[GEL Gateway] --> Loki --> S3 + Grafana --> g[GEL Gateway] +``` + +## Simple Scalable Enterprise with Grafana Enterprise Logging (GEL) +```mermaid +flowchart TD + subgraph Enterprise + g[GEL Gateway] --> a[Admin API] + a[Admin API] + end + S3[(S3)] + read[Loki Read] --> S3 + write[Loki Write] + Logs--> g[GEL Gateway] --> gateway + gateway[Loki Gateway] --> read + gateway --> write --> S3 + Grafana --> g[GEL Gateway] +``` + + +## Big Bang Touch Points + +### Licensing + +Loki utilizes an AGPLv3 License for it's code and binaries. By default the application does not need a license out of the box but can be utilized with [Grafana Enterprise Logs](https://grafana.com/products/enterprise/logs/) that can be deployed in the Grafana Cloud or in-cluster. Big Bang will be adding in support for both implementations of Grafana Enterprise Logs. + +### Single Sign On + +Loki utilizes Grafana as the frontend for searching and viewing logs, please refer to the [monitoring package for Single Sign On capabilities](monitoring.md). + +### High Availability + +Since Big Bang release 1.32.0 a Big Bang value `loki.strategy` has been available. When set to `scalable` Loki is configured to run with multiple replicas of what are called read and write nodes. The read nodes are what schedule, process and return queries to/from the Loki API while the write nodes is where your configured log forwarder will send the logs to and process write/create operations against the API and storage. + +```yaml +loki: + + strategy: scalable + + values: + # Configuration for the write node(s) + write: + # -- Number of replicas for the write + replicas: 2 + # Configuration for the read node(s) + read: + # -- Number of replicas for the read + replicas: 2 +``` + +You can also optionally use HPA with Loki for each component. There are additional options for the target memory and scaling behavior that you can reference in the [package chart values](https://repo1.dso.mil/big-bang/product/packages/loki/-/blob/main/chart/values.yaml). + +```yaml +loki: + values: + write: + autoscaling: + enabled: true + # -- Minimum autoscaling replicas for the write. + minReplicas: 1 + # -- Maximum autoscaling replicas for the write. + maxReplicas: 3 + # -- Target CPU utilization percentage for the write. + targetCPUUtilizationPercentage: 80 + read: + autoscaling: + enabled: true + # -- Minimum autoscaling replicas for the write. + minReplicas: 1 + # -- Maximum autoscaling replicas for the write. + maxReplicas: 3 + # -- Target CPU utilization percentage for the write. + targetCPUUtilizationPercentage: 80 + backend: + autoscaling: + enabled: true + # -- Minimum autoscaling replicas for the write. + minReplicas: 1 + # -- Maximum autoscaling replicas for the write. + maxReplicas: 3 + # -- Target CPU utilization percentage for the write. + targetCPUUtilizationPercentage: 80 +``` + +### UI + +Loki has no UI packaged with it. Grafana is the frontend to view logs which are ingested by Loki. + +### Logging + +Within Big Bang, logs are captured by fluentbit or promtail and shipped to your logging engine (Loki when ECK not installed, ECK when it's installed or both). + +### Health Checks + +Loki pods come with a pre-configured Readiness probe to query `:3100/ready` for the pod to ensure it's healthy. + +Loki package also comes bundled with a ServiceMonitor so it will show up as a Prometheus target assuming monitoring is installed and the `coreos` CRDs/APIs are available. + +### Dependent Packages + +When using the `scalable` deployment strategy without filling in `loki.objectStorage` values, minioOperator is required as a minio tenant will be auto-created and configured as the object storage backend. + +Loki can be deployed by itself but since it's so closely tied with Grafana, the monitoring package is set as a required dependency within Big Bang so both are setup and auto-configured. + +As mentioned above, Loki requires a log forwarder in the cluster to receive logs. You can use either one of fluentbit or promtail but Loki will not fail to install if neither one are installed via Big Bang. \ No newline at end of file diff --git a/docs/understanding-bigbang/package-architecture/mattermost.md b/docs/understanding-bigbang/package-architecture/mattermost.md new file mode 100644 index 0000000000000000000000000000000000000000..22abc30fe7107ba67c7f41bc1ae681492e704c57 --- /dev/null +++ b/docs/understanding-bigbang/package-architecture/mattermost.md @@ -0,0 +1,208 @@ +# Mattermost + +## Overview + +[Mattermost](https://mattermost.com/) is an open-source, self-hostable online chat service with file sharing, search, and integrations. + +Big Bang's implementation uses the [Mattermost operator](https://github.com/mattermost/mattermost-operator) to provide custom resources and manage the application. + +### Basic Tier + +```mermaid +graph LR + subgraph "Mattermost" + mattermostpods("Mattermost Pod(s)") + mmservice{{Mattermost Service}} --> mattermostpods("Mattermost Pod(s)") + end + + subgraph "Ingress" + ig(Ingress Gateway) --"App Port"--> mmservice + end + + subgraph "Database Storage (Postgres)" + mattermostpods("Mattermost Pod(s)") --"Chats/Config"--> database[(Mattermost DB)] + end + + subgraph "File Storage (S3/Minio)" + mattermostpods("Mattermost Pod(s)") --"Files"--> bucket[(Mattermost Bucket)] + end + + subgraph "Logging" + mattermostpods("Mattermost Pod(s)") --"Logs"--> fluent(Fluentbit) --> logging-ek-es-http + logging-ek-es-http{{Elastic Service<br />logging-ek-es-http}} --> elastic[(Elastic Storage)] + end +``` + +### Enterprise Tier with Integrations + +```mermaid +graph LR + subgraph "Mattermost" + mattermostpods("Mattermost Pod(s)") + mmservice{{Mattermost Service}} --> mattermostpods("Mattermost Pod(s)") + end + + subgraph "Ingress" + ig(Ingress Gateway) --"App Port"--> mmservice + end + + subgraph "Database Storage (Postgres)" + mattermostpods("Mattermost Pod(s)") --"Chats/Config"--> database[(Mattermost DB)] + end + + subgraph "File Storage (S3/Minio)" + mattermostpods("Mattermost Pod(s)") --"Files"--> bucket[(Mattermost Bucket)] + end + + subgraph "Logging" + mattermostpods("Mattermost Pod(s)") --"Logs"--> fluent(Fluentbit) --> logging-ek-es-http + logging-ek-es-http{{Elastic Service<br />logging-ek-es-http}} --> elastic[(Elastic Storage)] + mattermostpods("Mattermost Pod(s)") --"Chat Indexing"--> logging-ek-es-http + end + + subgraph "Monitoring" + svcmonitor("Service Monitor") --"Metrics Port"--> mmservice + Prometheus --> svcmonitor("Service Monitor") + end +``` + +## Big Bang Touch Points + +### UI + +The Mattermost UI is the primary way of interacting with Mattermost. The UI is accessible via a web browser, desktop client, and mobile apps. The UI provides access to all mattermost features as well as configuration of the instance via the settings (or "System Console"). + +### Logging + +Mattermost provides access to the system logs via the "System Console" (under "Server Logs"). The UI provides a basic search functionality as well for these logs + +By default logs are also shipped to Elastic via Fluentbit for advanced searching/indexing. The filter `kubernetes.namespace_name` set to `mattermost` can provide easy viewing of Mattermost only logs. + +Optional Enterprise Feature: Mattermost can make use of Elastic for improved performance with indexing of posts (which provides optimized search queries). For more details see the [dependencies section](#dependencies). + +### Monitoring + +Monitoring is available within Mattermost as a paid (E20) feature. If you have both `addons.mattermost.enterprise` and `monitoring` enabled within Big Bang values a service monitor will be deployed to automatically ship metrics data to Prometheus for consumption. + +### Health Checks + +The Mattermost Operator ships by default with health checks on the address `/api/v4/system/ping` port 8065 to verify that the system is healthy. Kubernetes will handle cycling unhealthy pods and all data will persist on the DB and File Storage. + +## High Availability + +**To allow for defining replica count and resource requests/limits, `users` is set to `null` by default. Changing this will negate these values and mattermost may not run due to OPA Gatekeeper constraints.** + +To set a replica count greater than 1 requires an enterprise license, and can be configured like the following example: + +```yaml +addons: + mattermost: + values: + enterprise: + enabled: true + replicaCount: 3 +``` + +**Setting a user value is not supported due to OPA constraint issues** + +If you want to use Mattermost's user/size value you will need to handle OPA violations and exceptions yourself since this is **not BB supported.** If all of these considerations have been accounted for and you still want to deploy with Mattermost's user sizing it can be done by setting the value as in this example: + +```yaml +addons: + mattermost: + values: + users: 1000 +``` + + +## Single Sign On (SSO) + +SSO is built in for Mattermost and Big Bang uses the [Gitlab SSO integration](https://docs.mattermost.com/deployment/sso-gitlab.html) as its implementation since this option is available at the free tier. Mattermost also provides OAuth and SAML integration as paid features for its [enterprise tiers](#licensing) if you wish to use those. + +If using Big Bang's SSO implementation, Keycloak is used behind the scenes to "spoof" the way Gitlab interaction works for SSO. The set up for how to configure Keycloak to handle this is well documented via the [Mattermost docs](https://repo1.dso.mil/big-bang/product/packages/mattermost/-/blob/main/docs/keycloak.md). + +See below for an example of the values to provide to Mattermost for SSO setup: + +```yaml +addons: + mattermost: + sso: + enabled: true + client_id: platform1_a8604cc9-f5e9-4656-802d-d05624370245_bb8-mattermost + client_secret: no-secret +``` + +## Licensing + +Big Bang deploys the free version of Mattermost by default, but there are two additional tiers of paid licenses for additional features. Pricing for these licenses is typically based upon number of users. Full details can be viewed on [Mattermost's tier page](https://docs.mattermost.com/overview/product.html). If you want to trial the E20 features you can request a trial via Mattermost's [request page](https://mattermost.com/trial/) or after deploying via the System Console you can begin a 30 day trial under the "Edition and License" page. + +### Mattermost E10 Additional Features + +- Active Directory/LDAP Single Sign-on +- OAuth 2.0 authentication for team creation, account creation, and user sign-in +- Encrypted push notifications with service level agreements (SLAs) via HPNS +- Advanced access control policy +- Next business day support via online ticketing system +- Scale to handle hundreds of users per team + +### Mattermost E20 Additional Features + +- Advanced SAML 2.0 authentication with Okta, OneLogin, and Active Directory Federation Services +- Active Directory/LDAP group sync +- OpenID Connect authentication for team creation, account creation, and user sign-in +- Compliance exports of message histories with oversight protection +- Custom retention policies for messages and files +- High Availability support with multi-node database deployment +- Horizontal scaling through cluster-based deployment +- Elasticsearch support for highly efficient database searches in a cluster environment +- Advanced performance monitoring +- Eligibility for Premier Support add-on + +### License Values + +Once you have obtained a license this can be added to your values in Big Bang to automatically set up your Mattermost instance with the license (replacing the `license:` value with your full license string): + +```yaml +addons: + mattermost: + enterprise: + enabled: true + license: "ehjgjhh..." +``` + +## Storage + +### Database Storage + +Mattermost makes use of a database to store all chat information as well as persistent configuration for all of Mattermost. By default Big Bang deploys an in-cluster Postgresql instance for this purpose, but it is recommended to point to an external DB instance for HA. Currently Big Bang supports pointing to any external Postgres instance via values config. See the below example for values to point your database connection to an external instance: + +```yaml +addons: + mattermost: + database: + host: "mypostgreshost" + port: "5432" + username: "myusername" + password: "mypassword" + database: "mattermost" + # OPTIONAL: Provide the postgres SSL mode + ssl_mode: "" +``` + +### File Storage + +Mattermost uses S3, Minio, or another S3-style storage for file storage. By default Big Bang deploys an in-cluster Minio instance for this purpose, but you have the option to point to an external Minio or S3 if desired. See the below example for the values to supply: + +```yaml +addons: + mattermost: + objectStorage: + endpoint: "s3.amazonaws.com" + accessKey: "myAccessKey" + accessSecret: "myAccessSecret" + bucket: "myMattermostBucket" +``` + +## Dependencies + +Mattermost requires only database storage, file storage, and the mattermost operator by default the operator is bundled in Big Bang, and the database/file storage can also be provided in cluster via Big Bang or externalized (see the [storage section](#storage) above). No additional external dependencies are required, everything can be done via Big Bang. There is an optional dependency on Elasticsearch to provide optimized searches rather than using DB queries (E20 Enterprise license required) - see the official [Mattermost doc](https://docs.mattermost.com/deployment/elasticsearch.html) for more details. diff --git a/docs/understanding-bigbang/package-architecture/metricserver.md b/docs/understanding-bigbang/package-architecture/metricserver.md new file mode 100644 index 0000000000000000000000000000000000000000..87f1f2646b986ebfcdc5d95588bff735c02e8b1a --- /dev/null +++ b/docs/understanding-bigbang/package-architecture/metricserver.md @@ -0,0 +1,110 @@ +# Metrics Server + +## Overview + +> Metrics Server is an addon cluster utility that adds functionality to Kubernetes clusters rather than applications. It is used for monitoring pod CPU & memory utilization for use with autoscaling pods horizontally and vertically. + +Metrics Server collects resource metrics from Kubelets and exposes them in Kubernetes apiserver through [Metrics API] for use by [Horizontal Pod Autoscaler] and [Vertical Pod Autoscaler]. Metrics API can also be accessed by `kubectl top`, making it easier to debug autoscaling pipelines. + +Metrics Server is not meant for non-autoscaling purposes. For example, don't use it to forward metrics to monitoring solutions, or as a source of monitoring solution metrics. In such cases please collect metrics from Kubelet `/metrics/resource` endpoint directly. + +Metrics Server offers: + +- A single deployment that works on most clusters (see [Requirements](#requirements)) +- Fast autoscaling, collecting metrics every 15 seconds. +- Resource efficiency, using 1 mili core of CPU and 2 MB of memory for each node in a cluster. +- Scalable support up to 5,000 node clusters. + +[Metrics API]: https://github.com/kubernetes/metrics +[Horizontal Pod Autoscaler]: https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/ +[Vertical Pod Autoscaler]: https://github.com/kubernetes/autoscaler/tree/master/vertical-pod-autoscaler/ + +## Use cases + +You can use Metrics Server for: + +- CPU/Memory based horizontal autoscaling (learn more about [Horizontal Autoscaling](https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/)) +- Automatically adjusting/suggesting resources needed by containers (learn more about [Vertical Autoscaling](https://github.com/kubernetes/autoscaler/tree/master/vertical-pod-autoscaler/)) + +Don't use Metrics Server when you need: + +- Non-Kubernetes clusters +- An accurate source of resource usage metrics +- Horizontal autoscaling based on other resources than CPU/Memory + +For unsupported use cases, check out full monitoring solutions like Prometheus (also deployed by default within the BigBang [monitoring package](https://repo1.dso.mil/big-bang/product/packages/monitoring)). + +### Deployment + +Since Metrics Server is prerequisite for a number of Kubernetes components (HPA, scheduler, kubectl top) +it typically will run by default in most Kubernetes clusters. By default within a BigBang deployment, the enabled value is set to `auto`, which installs only if metrics API endpoint is not present. + +## Big Bang Touch Points + +### Architecture: + +Metrics Server collects resource metrics from Kubelets (the primary "node agent" that runs on each node) and exposes them in Kubernetes apiserver through [Metrics API](https://github.com/kubernetes/metrics) for use by [Horizontal Pod Autoscaler](https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/) and [Vertical Pod Autoscaler](https://github.com/kubernetes/autoscaler/tree/master/vertical-pod-autoscaler/). Metrics API can also be accessed by `kubectl top`, making it easier to debug autoscaling pipelines. + +- [Kubernetes Metrics Server](https://github.com/kubernetes-sigs/metrics-server?tab=readme-ov-file#kubernetes-metrics-server) +- [Horizontal Pod Autoscaling](https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/) + - [How does Horizontal Pod Autoscaling Work?](https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/#how-does-a-horizontalpodautoscaler-work) + +### Storage + +To store data in memory Metric Server will replace the default storage layer (etcd) by introducing in-memory store which will implement [Storage interface](https://github.com/kubernetes/apiserver/blob/master/pkg/registry/rest/rest.go). + +Only the most recent value of each metric will be remembered. + +Users looking to access historical data should look into Prometheus and Grafana packages as part of BigBang's [monitoring stack](https://repo1.dso.mil/big-bang/product/packages/monitoring). + +### Istio Configuration + +Istio is disabled in the metric server chart by default and can be enabled by setting the following values in the bigbang chart: + +```yaml +istio: + enabled: true +``` + +These values get passed into the metric server chart [here](https://repo1.dso.mil/big-bang/product/packages/metrics-server/-/blob/main/chart/values.yaml). + +### High Availability + +Metrics Server is simply installed in high availability mode by setting the `replicas` chart value greater than `1`. The default configuration within BigBang is a 2 replica deployment. + +Additional Metric Server High Availability documentation can be found [here](https://github.com/kubernetes-sigs/metrics-server/blob/master/README.md#high-availability). + +## Requirements + +Metrics Server has specific requirements for cluster and network configuration. These requirements aren't the default for all cluster +distributions. Please ensure that your cluster distribution supports these requirements before using Metrics Server: + +- The kube-apiserver must [enable an aggregation layer]. +- Nodes must have Webhook [authentication and authorization] enabled. +- Kubelet certificate needs to be signed by cluster Certificate Authority (or disable certificate validation by passing `--kubelet-insecure-tls` to Metrics Server) +- Container runtime must implement a [container metrics RPCs] (or have [cAdvisor] support) +- Network should support following communication: + - Control plane to Metrics Server. Control plane node needs to reach Metrics Server's pod IP and port 10250 (or node IP and custom port if `hostNetwork` is enabled). Read more about [control plane to node communication](https://kubernetes.io/docs/concepts/architecture/control-plane-node-communication/#control-plane-to-node). + - Metrics Server to Kubelet on all nodes. Metrics server needs to reach node address and Kubelet port. Addresses and ports are configured in Kubelet and published as part of Node object. Addresses in `.status.addresses` and port in `.status.daemonEndpoints.kubeletEndpoint.port` field (default 10250). Metrics Server will pick first node address based on the list provided by `kubelet-preferred-address-types` command line flag (default `InternalIP,ExternalIP,Hostname` in manifests). + +[reachable from kube-apiserver]: https://kubernetes.io/docs/concepts/architecture/master-node-communication/#master-to-cluster +[enable an aggregation layer]: https://kubernetes.io/docs/tasks/access-kubernetes-api/configure-aggregation-layer/ +[authentication and authorization]: https://kubernetes.io/docs/reference/access-authn-authz/kubelet-authn-authz/ +[container metrics RPCs]: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-node/cri-container-stats.md +[cAdvisor]: https://github.com/google/cadvisor + +Resource footprint on nodes within cluster are minimal at: 1 mili core of CPU and 2 MB of memory per node. + +- [Metric Server Requirements](https://github.com/kubernetes-sigs/metrics-server/blob/master/README.md#requirements) + +## Single Sign on (SSO) + +None. This service doesn't have a web interface. + +## Other Resources + +- [Metric Server Design Proposal](https://github.com/kubernetes/design-proposals-archive/blob/main/instrumentation/metrics-server.md) + +## Licensing + +Metric Server utilizes an [Apache 2.0](https://github.com/kubernetes-sigs/metrics-server/blob/master/LICENSE) license. \ No newline at end of file diff --git a/docs/understanding-bigbang/package-architecture/minio.md b/docs/understanding-bigbang/package-architecture/minio.md new file mode 100644 index 0000000000000000000000000000000000000000..64501c64567020d55fd94902f8f54bd2c0d51f7a --- /dev/null +++ b/docs/understanding-bigbang/package-architecture/minio.md @@ -0,0 +1,109 @@ +# MinIO + +## Overview + +[MinIO](https://min.io/) is an open source high performance, Kubernetes-native object storage suite is +built for the demands of the hybrid cloud. + +The package is offered up as three individual packages that make up the MinIO ecosystem. + +Big Bang's implementation uses the [MinIO operator](https://github.com/minio/operator) to provide custom resources and manage the different tenents of MinIO. The official package for MinIO Operator can be found [here](https://repo1.dso.mil/big-bang/product/packages/minio-operator) + +The MinIO tenants are created using the [MinIO package](https://repo1.dso.mil/big-bang/product/packages/minio). This package is used to set up individual MinIO instances for applications to use (e.g. Gitlab). + +The final package is the MinIO console. This is a graphical user interface that allows management of an individual tenant. The official package can be found [here](https://repo1.dso.mil/big-bang/product/packages/minio). + +[Tenant Architecture](https://raw.githubusercontent.com/minio/operator/master/docs/images/architecture.png) + +Note: The Minio Operator needs to be able to reach out to the minio instances. This is to ensure that on an upgrade all existing pools are shut down before starting new ones. If you run into issues with upgrades ensure that networkPolicies allow ingress to the minio pods in your namespace on port 9000. + +## Big Bang Touchpoints + +### UI + +The MinIO Console UI is the primary way of interacting with a MinIO tenant. The UI is accessible via a web browser. The UI provides access to all of a tenants features. This includes access to features very similar to what you would see in AWS S3, setting up buckets, controlling access, etc. + + +### Logging + +MinIO supports configuring audit logs through both the MinIO Console UI and the MinIO `mc` command line tool. For Kubernetes environments, the MinIO Operator automatically configures the Console with a LogSearch integration for visual inspection of collected audit logs. + +By default logs are also shipped to Elastic via Fluentbit for advanced searching/indexing. The filter `kubernetes.namespace_name` set to your MinIO tenant namespace can provide easy viewing of MinIO only logs. + +### Monitoring + +Monitoring is provided via a Prometheus capable endpoint. MinIO also provides a Grafana dashboard for use in viewing metrics. Monitoring in the Big Bang config can be enabled using the following format. + +```yaml +monitoring: + enabled: false + namespace: monitoring +``` + +### Health Checks + +MinIO server exposes three un-authenticated, healthcheck endpoints [liveness probe](https://github.com/minio/minio/blob/master/docs/metrics/healthcheck/README.md#liveness-probe) and a [cluster probe](https://github.com/minio/minio/blob/master/docs/metrics/healthcheck/README.md#cluster-probe) at /minio/health/live and /minio/health/cluster respectively. + + +## High Availability + +The default is to run in high availability. The default number of servers is 4, but can be changed by changing the values in the base Big Bang cofiguration. + +```yaml +addons: + minio: + values: + tenants: + pools: + - servers: 8 + volumesPerServer: 4 + size: 256Mi + resources: + requests: + cpu: 250m + memory: 2Gi + limits: + cpu: 250m + memory: 2Gi + securityContext: + runAsUser: 1001 + runAsGroup: 1001 + fsGroup: 1001 +``` + +Note that due to the list used for the pool value you may need to include resources, requests, and securityContext so that you don't run into issues. + +You can also set things like the number of volumes per server and affinity rules for the MinIO tenant. + +## Single Sign On (SSO) + +No current SSO is available via Keycloak. + +## Configuring access to Minio without SSO + +Initial access to the MinIO server is via the accessKey and secretKey values in the top level values file. + +```yaml +addons: + minio: + accesskey: "myaccesskey" + secretkey: "mysecretkey" +``` + + +## Licensing + +MinIO has recently updated its license to the GNU AFFERO General Public License. This requires that any product containing usage of their product to also release their code as open source. + +License can be found [here](https://github.com/minio/minio/blob/master/LICENSE) + +## Storage + +### File Storage + +MinIO is dependent on a default storage class being configured. This is a core prereq for Big Bang itself so this should already in place when starting up the Big Bang framework. The MinIO process will need to create PersistentVolumes and PersistentVolumeClaims for its storage. The requirement for these are that they have a volumeBindingMode: WaitForFirstConsumer. The MinIO operator should take care of creating these at tenant start up. + + +## Dependencies + +As mentioned above, MinIO needs to have access to create the needed PersistentVolumes needed for its storage. This can be EBSs in an AWS environment or a similar storage solution in place. diff --git a/docs/understanding-bigbang/package-architecture/monitoring.md b/docs/understanding-bigbang/package-architecture/monitoring.md new file mode 100644 index 0000000000000000000000000000000000000000..efa5c8139766a79f5d9a79054538b34c5b8f6da0 --- /dev/null +++ b/docs/understanding-bigbang/package-architecture/monitoring.md @@ -0,0 +1,277 @@ +# Monitoring + +## Overview + +Monitoring in Bigbang is deployed using the upstream chart [kube-prometheus-stack](https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack) + +Installs the kube-prometheus stack, a collection of Kubernetes manifests, Grafana dashboards, and Prometheus rules combined with documentation and scripts to provide easy to operate end-to-end Kubernetes cluster monitoring with Prometheus using the Prometheus Operator. + +```mermaid +graph LR + subgraph "Monitoring" + alertmanagerpods("AlertManager Pod(s)") --> monitoringpods("Monitoring Pod(s)") + alertmanagerservice{{AlertManager Service}} --> alertmanagerpods("AlertManager Pod(s)") + alertmanagersvcmonitor("Service Monitor") --"Metrics Port"--> alertmanagerservice + Prometheus --> alertmanagersvcmonitor("Service Monitor") + grafanapods("Grafana Pod(s)") --> monitoringpods("Monitoring Pod(s)") + grafanaservice{{Grafana Service}} --> grafanapods("Grafana Pod(s)") + grafanasvcmonitor("Service Monitor") --"Metrics Port"--> grafanaservice + Prometheus --> grafanasvcmonitor("Service Monitor") + nodeexporterpods("Node-Exporter Pod(s)") --> monitoringpods("Monitoring Pod(s)") + nodeexporterservice{{Node-Exporter Service}} --> nodeexporterpods("Node-Exporter Pod(s)") + nodeexportersvcmonitor("Service Monitor") --"Metrics Port"--> nodeexporterservice + Prometheus --> nodeexportersvcmonitor("Service Monitor") + kubestatemetricspods("Kube-State-Metrics Pod(s)") --> monitoringpods("Monitoring Pod(s)") + kubestatemetricsservice{{Kube-State-Metrics Service}} --> kubestatemetricspods("Kube-State-Metrics Pod(s)") + kubestatemetricssvcmonitor("Service Monitor") --"Metrics Port"--> kubestatemetricsservice + Prometheus --> kubestatemetricssvcmonitor("Service Monitor") + Prometheus --> prometheussvcmonitor("Service Monitor") + prometheussvcmonitor("Service Monitor") --"Metrics Port"--> prmetheussservice{{Prometheus Service}} + prmetheussservice{{Prometheus Service}} --> Prometheus + PromOperator ---|Manages/Creates| Prometheus + VirtualServices --"App Port"--> alertmanagerservice + VirtualServices --"App Port"--> grafanaservice + VirtualServices --"App Port"--> Prometheus + end + subgraph "Logging" + monitoringpods("Monitoring Pod(s)") ---|Logs|fluent(Fluentbit) --> logging-ek-es-http + logging-ek-es-http{{Elastic Service<br />logging-ek-es-http}} --> elastic[(Elastic Storage)] + end + subgraph "Istio-system (Ingress)" + ig(Ingress Gateway, Gateway) --> VirtualServices + end +``` + +## Big Bang Touchpoints + +### UI + +Alertmanager, Prometheus and Grafana within the monitoring Package have UIs that are accessible and configurable. By default they are externally available behind an Istio installation. + +### Storage + +#### Alertmanager + +Persistent storage values for Alert Manager can be set/modified in the Big Bang chart: + +```yaml +monitoring: + values: + alertmanager: + alertmanagerSpec: + storage: + volumeClaimTemplate: + spec: + storageClassName: + accessModes: ["ReadWriteOnce"] + resources: + requests: + storage: 50Gi + selector: {} +``` + +#### Prometheus-Operator + +Persistent storage values for Prometheus-Operator can be set/modified in the Big Bang chart: + +```yaml +monitoring: + values: + prometheus: + prometheusSpec: + storageSpec: + volumeClaimTemplate: + spec: + storageClassName: + accessModes: ["ReadWriteOnce"] + resources: + requests: + storage: 50Gi + selector: {} +``` + +#### Grafana + +Persistent storage values for Grafana can be set/modified in the Big Bang chart: + +```yaml +monitoring: + values: + grafana: + persistence: + type: pvc + enabled: false + # storageClassName: default + accessModes: + - ReadWriteOnce + size: 10Gi + # annotations: {} + finalizers: + - kubernetes.io/pvc-protection + # selectorLabels: {} + # subPath: "" + # existingClaim: +``` + +### Logging + +Within the kube-prometheus-stack chart, you can customize both the LogFormat and LogLevel for the following components: +Note: within Big Bang, logs are captured by fluentbit and shipped to elastic by default. + +#### Prometheus-Operator + +LogFormat and LogLevel can be set for Prometheus-Operator via the following values in the Big Bang chart: + +```yaml +monitoring: + values: + prometheusOperator: + logFormat: logfmt + logLevel: info +``` + +#### Prometheus + +LogFormat and LogLevel can be set for Prometheus via the following values in the Big Bang chart: + +```yaml +monitoring: + values: + prometheus: + prometheusSpec: + logFormat: logfmt + logLevel: info +``` + +#### Alertmanager + +LogFormat and LogLevel can be set for Alertmanager via the following values in the Big Bang chart: + +```yaml +monitoring: + values: + alertmanager: + alertmanagerSpec: + logFormat: logfmt + logLevel: info +``` + +#### Grafana + +LogLevel can be set for Grafana via the following values in the Big Bang chart: + +```yaml +monitoring: + values: + grafana: + grafana.ini: + log: + mode: console +``` + +## Single Sign on (SSO) + +SSO can be configured for monitoring through Authservice, more info is included in the following documentation: +[Monitoring SSO Integration](https://repo1.dso.mil/big-bang/product/packages/monitoring/-/blob/main/docs/KEYCLOAK.md) + +## Monitoring + +Monitoring deployment has serviceMonitors enabled for + +* core-dns +* kube-api-server +* kube-controller-manager +* kube-dns +* kube-etcd +* kube-proxy +* kube-scheduler +* kube-state-metrics +* kubelet +* node-exporter +* alert manager +* grafana +* prometheus +* prometheus-operator +* node-exporter + +Note: Other packages are responsible for deploying Service Monitors for their components as needed. + +### HA + +Support for Prometheus and other apps within the package are being researched and section will be updated: + +#### Alertmanager + +High Availability can be accomplished by increasing the number of replicas for the deployment of Alertmanager; +```yaml +monitoring: + values: + alertmanager: + alertmanagerSpec: + replicas: 3 +``` + +#### Prometheus + +High Availability can be accomplished by increasing the number of replicas for the deployment of Prometheus. [Thanos](https://repo1.dso.mil/big-bang/product/packages/thanos/-/tree/main) must also be installed in the same namespace as the monitoring package in order for data to replicate across pods. An example of a Thanos object storage config using minIO [is located here](https://repo1.dso.mil/big-bang/product/packages/thanos/-/blob/main/tests/test-values.yaml). Thanos also supports cloud object storage endpoints. +```yaml +monitoring: + values: + thanosRuler: + enabled: true + prometheusOperator: + clusterDomain: "cluster.local" + prometheus: + thanosService: + enabled: true + thanosServiceMonitor: + enabled: true + prometheusSpec: + replicas: 3 + thanos: + baseImage: registry1.dso.mil/ironbank/opensource/thanos/thanos + version: v0.29.0 + objectStorageConfig: + key: objstore.yml + name: thanos-objstore-secret +``` + +#### Grafana + +High Availability can be accomplished by increasing the number of replicas for the deployment of Grafana and configuring an external database connection (postgresql/mysql) so users and dashboard information can be centrally located for the replicas to have a source of truth. See Grafana's [upstream documentation](https://grafana.com/docs/grafana/v9.0/setup-grafana/configure-grafana/#database) +```yaml +monitoring: + values: + grafana: + replicas: 3 + grafana.ini: + ... + database: + type: [postgres|mysql] + host: external-db:5432 + name: grafana + user: "" + password: "" +``` + +### Dependency Packages + +When deploying BigBang, monitoring depends on gatekeeper/kyverno and istio being installed prior. + +```yaml + {{- if or .Values.gatekeeper.enabled .Values.istio.enabled .Values.kyvernoPolicies.enabled }} + dependsOn: + {{- if .Values.istio.enabled }} + - name: istio + namespace: {{ .Release.Namespace }} + {{- end }} + {{- if .Values.gatekeeper.enabled }} + - name: gatekeeper + namespace: {{ .Release.Namespace }} + {{- end }} + {{- if .Values.kyvernoPolicies.enabled }} + - name: kyverno-policies + namespace: {{ .Release.Namespace }} + {{- end }} + {{- end }} +``` diff --git a/docs/understanding-bigbang/package-architecture/neuvector.md b/docs/understanding-bigbang/package-architecture/neuvector.md new file mode 100644 index 0000000000000000000000000000000000000000..cb5ca0901032c87f0cd4accaf9255fbd8e632b88 --- /dev/null +++ b/docs/understanding-bigbang/package-architecture/neuvector.md @@ -0,0 +1,72 @@ +# NeuVector + +## Overview + +[NeuVector](https://neuvector.com/) is an open-source, full lifecycle container security platform. This includes vulnerability scanning (both in pipelines and in live production clusters), network visibility, compliance tracking and much more. [NeuVector core helm chart](https://github.com/neuvector/neuvector-helm/tree/master/charts/core) + +[NeuVector Architecture](https://open-docs.neuvector.com/basics/overview#architecture) + +## Big Bang Touchpoints + +### UI + +The Neuvector UI runs on the manager, a simple pod that provides the primary way of accessing and managing NeuVector. The UI is accessible via a web application on the cluster at the DNS name "neuvector" (e.g. neuvector.bigbang.dev/). UI access is exposed through the Istio Virtual Service. For more information, see [Using the NeuVector UI](https://open-docs.neuvector.com/navigation/navigation). + +### Dependency Packages + +When deploying BigBang, neuvector depends on monitoring, gatekeeper/kyverno, and istio being installed prior. + +```yaml + {{- if or .Values.gatekeeper.enabled .Values.istio.enabled .Values.kyvernoPolicies.enabled .Values.monitoring.enabled }} + dependsOn: + {{- if .Values.gatekeeper.enabled }} + - name: gatekeeper + namespace: {{ .Release.Namespace }} + {{- end }} + {{- if .Values.istio.enabled }} + - name: istio + namespace: {{ .Release.Namespace }} + {{- end }} + {{- if .Values.kyvernoPolicies.enabled }} + - name: kyverno-policies + namespace: {{ .Release.Namespace }} + {{- end }} + {{- if .Values.monitoring.enabled }} + - name: monitoring + namespace: {{ .Release.Namespace }} + {{- end }} + {{- end }} +``` + +## High Availability + +NeuVector provides High Availability for the controller and scanner deployments with `3` replicas and a default `podAntiAffinity` in order to attempt installation of replicas to separate nodes if possible. These can be modified by providing new values to `controller.replicas` and `scanner.replicas` accordingly. + +```yaml +neuvector: + values: + controller: + replicas: 3 + + scanner: + replicas: 3 +``` + +The enforcer pods are part of a daemonset that will be based upon the number of cluster nodes - with default tolerations for standard control-plane taints. Addition tolerations can be set for nodes by appending to the existing set: + +**Note:** The controller, manager, and cve.scanner deployments can also have their tolerations updated by mirroring this process. + +```yaml +neuvector: + values: + enforcer: # controller, manager, cve.scanner also have tolerations + tolerations: + - effect: NoSchedule + key: node-role.kubernetes.io/master + - effect: NoSchedule + key: node-role.kubernetes.io/control-plane + - effect: NoSchedule + key: custom-example-taint +``` + +The manager deployment houses the Security Center Admin Console and is explicitly set to `1` replica and cannot be scaled. diff --git a/docs/understanding-bigbang/package-architecture/nexusRepositoryManager.md b/docs/understanding-bigbang/package-architecture/nexusRepositoryManager.md new file mode 100644 index 0000000000000000000000000000000000000000..fe435287cb5ae1dbfd18a6f112950b6109ba5866 --- /dev/null +++ b/docs/understanding-bigbang/package-architecture/nexusRepositoryManager.md @@ -0,0 +1,99 @@ +# Nexus + +## Overview + +Nexus repository manager is used to store build artifacts and provide features to push and pull artifacts using integration tools. Nexus provides a wealth of documentation [here](https://help.sonatype.com/repomanager3) with details about supported artifact formats, use cases, and more. + +## Big Bang Touch Points + +The below diagram includes the main Big Bang touchpoints to Nexus as well as a basic workflow for using Nexus. + +```mermaid +graph LR + subgraph "Workflow" + sourcecontrol("Source Control") --> build("Build") --> repository1("Repository") --> release("Release") + end + + subgraph "Nexus Repository Manager" + nexusrepositorymanager("Nexus Repository Manager") --> repository1("Repository") + end + + subgraph "Environment" + release("Release") --> stage1(dev) + release("Release") --> stage2(staging) + release("Release") --> stage3(prod) + end + + subgraph "Monitoring" + prometheus("Prometheus") --> servicemonitor("Service Monitor") + servicemonitor("Service Monitor") --> nexusrepositorymanager("Nexus Repository Manager") + end + + subgraph "Logging" + nexusrepositorymanager("Nexus Repository Manager") --> fluent(Fluentbit) --> logging-ek-es-http + logging-ek-es-http{{Elastic Service<br />logging-ek-es-http}} --> elastic[(Elastic Storage)] + end +``` + +### UI + +Nexus Repository Manager serves as the user interface for Nexus. Nexus Repository Manager provides optional anonymous access for users who need to search repositories, browse repositories and look through the system feeds. UI access is exposed through the Istio Virtual Service. + +### Logging + +You can configure the level of logging for the repository manager and all plugins as well as inspect the current log using the user interface. +Logging can be enabled by clicking on the Logging menu item in the Administration submenu in the main menu. Logs are auto-scraped and shipped via your chosen logging stack when deployed with bigbang. + +### Storage + +Nexus requires access to persistent storage for storing repos, docker registries, etc. Persistent storage values can be set/modified in the bigbang chart: + +```yaml +addons: + nexusRepositoryManager: + values: + persistence: + storageSize: 8Gi + accessMode: ReadWriteOnce +``` + +### Istio Configuration + +Istio interaction with Nexus will be automatically toggled dependent on whether you have enabled Istio. + +When enabled an Istio VirtualService will be deployed, along with other configuration for Nexus' interaction in the service mesh. + +## Monitoring + +Monitoring interaction with Nexus will be automatically toggled dependent on whether you have enabled monitoring. + +When enabled a servicemonitor is deployed for automatic scraping of exposed metrics by prometheus. + +## Resiliency + +Nexus provides a helpful upstream guide on resiliency and high availability [here](https://help.sonatype.com/repomanager3/planning-your-implementation/resiliency-and-high-availability). Nexus does not support a traditional HA setup (more than 1 replica) so backups for resiliency are recommended. + +## Single Sign on (SSO) + +SSO can be configured for Nexus by the following the instructions from the package documentation [here](https://repo1.dso.mil/big-bang/product/packages/nexus/-/blob/main/docs/keycloak.md) + +## Licensing + +By default, Big Bang will deploy the unlicensed version of Nexus. If you need some of the license features, such as SSO, you can add your license via values and it will be added to the deployment: + +```yaml +addons: + nexusRepositoryManager: + enabled: true + license_key: | + ehjgjhh... +``` + +NOTE: This should be added via encrypted values to protect the license. + +### Health Checks + +Nexus Repository Manager uses Repository Health Check (RHC) for health checking. Repository Health Check (RHC) allows Nexus Repository users to identify open source security risks in proxy repositories at the earliest stages of their DevOps pipeline by providing the following key capabilities: + +- A summary of components with security vulnerabilities categorized by severity. +- A count of license warnings per component categorized by severity. diff --git a/docs/understanding-bigbang/package-architecture/opa-gatekeeper.md b/docs/understanding-bigbang/package-architecture/opa-gatekeeper.md new file mode 100644 index 0000000000000000000000000000000000000000..24e4fd89c14bc9080e74524558b979c6554f4fad --- /dev/null +++ b/docs/understanding-bigbang/package-architecture/opa-gatekeeper.md @@ -0,0 +1,74 @@ +# OPA-Gatekeeper + +# **DEPRECATED**: Kyverno is the preferred method to enforce policies within Big Bang as of version >=2.0.0 + +## Overview + +Gatekeeper is an auditing tool that allows administrators to see what resources are currently violating any given policy. + +## Big Bang Touch Points + +```mermaid +graph LR + subgraph "OPA Gatekeeper" + collector("Collector") --> auditor{{Auditor}} + end + + subgraph "Metrics" + auditor{{Auditor}} --> metrics("Metrics") + end + + subgraph "Kubernetes API" + api("Kubernetes API") --> collector("Collector") + auditor{{Auditor}} --> api("Kubernetes API") + end + + subgraph "kubectl" + ctl("kubectl") --> api("Kubernetes API") + end + +``` + +### Storage + +Data from gatekeeper is not stored is provided via [metrics](https://open-policy-agent.github.io/gatekeeper/website/docs/metrics/). + +### Database + +Gatekeeper doesn't have a database. + +### Istio Configuration + +When deploying to k3d, istio-system should be added from `excludedNamespaces` under the `allowedDockerRegistries` violations. This can be done by modifying `chart/values.yaml` file or passing an override file with the values set as seen below. This is for development purposes only: production should not allow containers in the `istio-system` namespace to be pulled from outside of Registry1. + +```yaml +gatekeeper: + values: + violations: + allowedDockerRegistries: + match: + excludedNamespaces: + - istio-system # allows creation for loadbalancer pods for various ports and various vendor loadbalancers +``` + +## High Availability + +High availability is accomplished by ensuring the replicas in the values file of this helm chart are > 1. By default, this chart is configured for high availability with `replicas: 3`. + +```yaml +gatekeeper: + values: + replicas: 3 +``` + +## Single Sign on (SSO) + +None. This service doesn't have a web interface. + +## Licensing + +[Apache License](https://github.com/open-policy-agent/gatekeeper/blob/master/LICENSE) + +## Dependencies + +None. diff --git a/docs/understanding-bigbang/package-architecture/promtail.md b/docs/understanding-bigbang/package-architecture/promtail.md new file mode 100644 index 0000000000000000000000000000000000000000..8221d89eeba0f785e7231dfa8119e2eaf8fbbba9 --- /dev/null +++ b/docs/understanding-bigbang/package-architecture/promtail.md @@ -0,0 +1,51 @@ +# Promtail + +## Overview + +> Promtail is an agent which reads log files and sends streams of log data to the centralised Loki instances along with a set of labels. + +## Big Bang Touch Points + +```mermaid +graph TB + + subgraph "Promtail" + promtail + end + + subgraph "Loki" + promtail --> loki + end + +``` + +### Architecture: + +- [Promtail Client](https://grafana.com/docs/loki/latest/clients/promtail/) + +### Storage + +Promtail does not persist data, and instead reads log files and streams the data to a log aggregation system. + +### Istio Configuration + +Istio is disabled in the promtail chart by default and can be enabled by setting the following values in the bigbang chart: + +```yaml +istio: + enabled: true +``` + +These values get passed into the promtail chart [here](https://repo1.dso.mil/big-bang/product/packages/promtail/-/blob/main/chart/values.yaml#L428). + +## High Availability + +By default, Promtail runs as a `daemonset` with a pod on each node. + +## Single Sign on (SSO) + +None. This service doesn't have a web interface. + +## Licensing + +Promtail utilizes an [AGPLv3 License](https://github.com/grafana/loki/blob/main/LICENSE) for it's code and binaries. \ No newline at end of file diff --git a/docs/understanding-bigbang/package-architecture/ref-package.md b/docs/understanding-bigbang/package-architecture/ref-package.md new file mode 100644 index 0000000000000000000000000000000000000000..b9731ec9fe02b7da87b68476648407d7a5af62f4 --- /dev/null +++ b/docs/understanding-bigbang/package-architecture/ref-package.md @@ -0,0 +1,8 @@ +# Package Architecture Review + +- Big Bang to Package touch points / interactions - does the package have a GUI, storage needs, logging, monitoring, health checks, etc +- HA - What is required for HA +- SSO - does the package have SSO, is it a licensed feature, if not - is there a strategy to provide rudimentary SSO capability vis AuthService? +- Licensing - describe the licensing model and any tiers of capability that are impacted +- Storage - describe any package specific storage or database requirements +- Dependent packages - list any included dependent packages that will not be elevated to a BB Addon diff --git a/docs/understanding-bigbang/package-architecture/sonarqube.md b/docs/understanding-bigbang/package-architecture/sonarqube.md new file mode 100644 index 0000000000000000000000000000000000000000..2727d00742e29b5e6d10648a760c9c4700cc27ea --- /dev/null +++ b/docs/understanding-bigbang/package-architecture/sonarqube.md @@ -0,0 +1,125 @@ +# Sonarqube + +## Overview + +[Sonarqube](https://www.sonarqube.org/) is an open-source platform for continuous inspection of code quality to perform automatic reviews with static analysis of code to detect bugs, code smells, and security vulnerabilities. + +## Big Bang Touch Points + +```mermaid +graph TB + subgraph "Ingress" + ingressgateway + end + + subgraph "Sonarqube" + ingressgateway --> sonarqube + end + + subgraph "Metrics" + sonarqube --> prometheus + end + + subgraph "Database" + sonarqube --- postgres + end +``` + +### Storage + +Persistent storage can be enabled by setting the following values in the bigbang chart: + +```yaml +addons: + sonarqube: + values: + persistence: + enabled: true + annotations: {} + storageClass: + accessMode: ReadWriteOnce + size: 10Gi +``` + +### Database + +Sonarqube needs a postgres database to function. If one is not specified in the bigbang chart Sonarqube will deploy one internally within the namespace it is deployed to. + +```yaml +addons: + sonarqube: + database: + host: "" + port: 5432 + database: "" + username: "" + password: "" +``` + +### Istio Configuration + +Istio is disabled in the sonarqube chart by default and can be enabled by setting the following values in the bigbang chart: + +```yaml +hostname: bigbang.dev +istio: + enabled: true +``` + +These values get passed into the sonarqube chart [here](https://repo1.dso.mil/big-bang/product/packages/sonarqube/-/blob/main/chart/values.yaml#L358). This creates the virtual service and maps to the istio gateway. + +## High Availability + +This can be accomplished by increasing the number of replicas in the deployment. + +```yaml +addons: + sonarqube: + values: + replicaCount: 2 +``` + +## Single Sign on (SSO) + +SSO integration can be configured by modifying the following settings in the bigbang chart. + +```yaml +addons: + sonarqube: + enabled: true + sso: + enabled: true + client_id: "" + login: login + name: name + email: email +``` + +```mermaid +flowchart LR + +S --> K[(Keycloak)] + +subgraph external +K +end + +ingress --> IP + +subgraph "Sonarqube namespace" + subgraph "Sonarqube pod" + S["sonarqube"] + IP["istio proxy"] --> K + IP --> S + end +end +``` + +## Licencing + +Sonarqube is released under the [Lesser GNU General Public License](https://en.wikipedia.org/wiki/Lesser_GNU_General_Public_License). The Bigbang chart utilizes the community edition of Sonarqube, but there are are also paid supported versions. Upgrades from community edition to enterprise or developer editions are possible via the [upgrade path](https://docs.sonarqube.org/latest/setup/upgrading/). Here is a link to their [Feature Comparison](https://www.sonarsource.com/plans-and-pricing/) + +## Dependencies + +Node kernel mods: +<https://repo1.dso.mil/big-bang/bigbang/-/blob/master/docs/guides/prerequisites/os_preconfiguration.md#sonarqube-specific-configuration-sonarqube-is-a-bb-addon-app> diff --git a/docs/understanding-bigbang/package-architecture/tempo.md b/docs/understanding-bigbang/package-architecture/tempo.md new file mode 100644 index 0000000000000000000000000000000000000000..cf379ad378ad8b1687d391040403749ef3adf9f9 --- /dev/null +++ b/docs/understanding-bigbang/package-architecture/tempo.md @@ -0,0 +1,139 @@ +# Tempo + +## Overview + +This package contains an extensible and configurable installation of Grafana Tempo based on the upstream chart provided by grafana. Tempo can be used to collect traces from your cluster service-mesh. Grafana has a built-in data source that can be used to query Tempo and visualize traces. For production workloads, Grafana has a built in Tempo data source that can be used to query Tempo and visualize traces. + +[Tempo](https://grafana.com/docs/tempo/latest/) is an open source, easy-to-use, and high-scale distributed tracing backend. With Tempo, the only dependency is object storage (e.g., S3, Azure Blob, etc.). Tempo can ingest common open source tracing protocols, including Jaeger, Zipkin, and OpenTelemetry. + + +### Grafana Tempo + +```mermaid +flowchart LR + +subgraph external +O[(Object Storage)] +end + +grafana --> T["tempo"] + + +subgraph "tempo namespace" + subgraph "tempo pod" + T --> O + Q["tempo-query"] --> T + end +end + +``` + +## Big Bang Touch Points + +### Licensing + +Tempo has no licensing options nor requirements. + +### UI + +Grafana is the primary frontend used to view traces. However, another option is to utilize tempo which comes with a UI package which is a jaeger frontend option in order to view traces. + +### Single Sign On + +Tempo-Query does not have built in SSO. In order to provide SSO, this deployment leverages Authservice + +1. Create a Tempo client + - Change the following configuration items + - access type: confidential _this will enable a "Credentials" tab within the client configuration page_ + - Direct Access Grants Enabled: Off + - Valid Redirect URIs: https://tracing.${DOMAIN}/login + - If you want to deploy both Jaeger and Tempo at the same time you should set this to https://tempo.${DOMAIN}/login + - Base URL: https://tracing.${DOMAIN} + - If you want to deploy both Jaeger and Tempo at the same time you should set this to https://tempo.${DOMAIN} + - Take note of the client secret in the credentials tab + +2. Deploy from Big Bang with the SSO values set: + ```yaml + tempo: + sso: + enabled: true + client_id: <id for client you created> + client_secret: <client secret from the credentials tab> + ``` + +3. Tempo will be deployed with Authservice protecting the UI behind your SSO provider. + +```mermaid +flowchart LR + +A --> K[(Keycloak)] + +subgraph external +K +end + +subgraph auth["authservice namespace"] + A(authservice) --> K +end + + + +ingress --> IP + + +subgraph "tempo namespace" + subgraph "tempo pod" + T["tempo-query"] + IP["istio proxy"] --> A + IP --> T + end +end + +``` +### Storage + +Tempo can utilize a local PVC for storage, but for production it is recommended to utilize in-cluster or external object-storage (e.g., GCS, S3, Azure Blob). To set a preferred object storage option in the bigang values reference the values below: + +```yaml +tempo: + enabled: true + objectstorage: + # -- S3 compatible endpoint to use for connection information. + # examples: "s3.amazonaws.com" "s3.us-gov-west-1.amazonaws.com" "minio.minio.svc.cluster.local:9000" + # Note: tempo does not require protocol prefix for URL. + endpoint: "" + + # -- S3 compatible region to use for connection information. + region: "" + + # -- Access key for connecting to object storage endpoint. + accessKey: "" + + # -- Secret key for connecting to object storage endpoint. + # Unencoded string data. This should be placed in the secret values and then encrypted + accessSecret: "" + + # -- Bucket Names for Tempo + # examples: "tempo-traces" + bucket: "" + + # -- Whether or not objectStorage connection should require HTTPS, if connecting to in-cluster object + # storage on port 80/9000 set this value to true. + insecure: false +``` + +### Logging + +Within Big Bang, logs are captured by fluentbit or promtail and shipped to your logging engine (Loki when ECK not installed, ECK when it's installed or both). + +### Health Checks + +When the global override strategy endpoint is configured within Tempo [Consistent Hash Rings](https://grafana.com/docs/tempo/latest/operations/consistent_hash_ring/) (e.g., distributor, ingester, metrics-generator, and compactor) will display web pages with the individual hash ring status, including the state, health, and last heartbeat time of each metrics-generator. + +### Dependent Packages + +When enabling `minio` for Tempo without filling in `loki.objectStorage` values, minioOperator is required as a minio tenant will be auto-created and configured as the object storage backend. + +Tempo can be deployed by itself but since it's so closely tied with Grafana, the monitoring package is set as a required dependency within Big Bang so both are setup and auto-configured. + +As mentioned above, Tempo requires a service mesh within the cluster to generate and track traces. Istio is set as a dependency for tempo as a result. diff --git a/docs/understanding-bigbang/package-architecture/twistlock.md b/docs/understanding-bigbang/package-architecture/twistlock.md new file mode 100644 index 0000000000000000000000000000000000000000..5b1f9c8a26cee628efb3a24fc48e7ac252604274 --- /dev/null +++ b/docs/understanding-bigbang/package-architecture/twistlock.md @@ -0,0 +1,101 @@ +# Twistlock + +## Overview + +[Twistlock Administration Guide](https://docs.paloaltonetworks.com/prisma/prisma-cloud/20-04/prisma-cloud-compute-edition-admin/welcome/getting_started.html) + +## Big Bang Touch Points + +```mermaid +graph LR + subgraph "Twistlock" + twistlockpods("Twistlock Pod(s)") + twistlockservice{{Twistlock Console}} --> twistlockpods("TwistlockPod(s)") + end + subgraph "Ingress" + ig(Ingress Gateway) --"App Port"--> twistlockservice + end + subgraph "Logging" + twistlockpods("Twistlock Pod(s)") --"Logs"--> fluent(Fluentbit) --> logging-ek-es-http + logging-ek-es-http{{Elastic Service<br />logging-ek-es-http}} --> elastic[(Elastic Storage)] + end + subgraph "Monitoring" + svcmonitor("Service Monitor") --"Metrics Port"--> twistlockservice + Prometheus --> svcmonitor("Service Monitor") + end + +``` + +### UI + +Twistlock Console serves as the user interface within Twistlock. The graphical +user interface (GUI) lets you define policy, configure and control your Twistlock deployment, and view the overall health (from a security perspective) of your container environment + +### Logging +In order to enable logging this can only be done via the console UI. Logging can be enabled by clicking on the `Manage` dropdown and click `Alerts`. Under the `Logging` tab the option for `Stdout` can be set to Enabled. This allows for options for logging to stdout to be scraped by fluentbit/promtail OR log to the underlying hosts. + + +### Install Defender + +In Bigbang the twistlock defender is installed manual. +Follow the document to install defender as a daemonset. +<https://repo1.dso.mil/big-bang/product/packages/twistlock/-/blob/main/README.md> + +### Storage + +Twistlock Console requires access to persistent storage \ +Persistent storage values can be set/modified in the bigbang chart: + +```yaml +console: + persistence: + size: 100Gi + accessMode: ReadWriteOnce +``` + +### Database + +N/A + +### Istio Configuration + +Istio is disabled in the twistlock chart by default and can be enabled by setting the following values in the bigbang chart: + +```yaml +hostname: bigbang.dev +istio: + enabled: true +``` + +NOTE: In BigBang twistlock istio.enabled : true only exposes twistlock console to VirtualService. The defender installation for twistlock in BigBang is manual. By default, all traffic between the twistlock Defender and the console is TLS encrypted. + +## Monitoring + +Twistlock Prometheus metrics collection is implemented following the documentation: +[Twistlock Prometheus Integration]<https://docs.paloaltonetworks.com/prisma/prisma-cloud/prisma-cloud-admin-compute/audit/prometheus.html>\ + +Monitoring is disabled in the twistlock chart by default and can be enabled by setting the following values in the bigbang chart: + +```yaml +monitoring: + enabled: true +``` + +## High Availability + +Twistlock uses orchestrators built-in high availability capabilities. + +## Single Sign on (SSO) + +SSO can be configured for twistlock manually using the documentation provided. \ +[Twistlock SSO Integration](https://repo1.dso.mil/big-bang/product/packages/twistlock/-/blob/main/docs/KEYCLOAK.md) + +## Licensing + +Twistlock deployment requires license to operate. Enter your license key in the twistlock console. \ +[TwistLock License Documentation](https://docs.paloaltonetworks.com/prisma/prisma-cloud/20-04/prisma-cloud-compute-edition-admin/welcome/licensing.html) + +### Health Checks + +Twistlock provides API endpoints to monitor the health and availability of deployed components at `/api/v1/_ping` \ +Example command: `curl -u admin:Password ‘https:<console-ip>:8083/api/ v1/_ping` diff --git a/docs/understanding-bigbang/package-architecture/vault.md b/docs/understanding-bigbang/package-architecture/vault.md new file mode 100644 index 0000000000000000000000000000000000000000..973d3b549aed3da6322453880fce3917ceda1e1e --- /dev/null +++ b/docs/understanding-bigbang/package-architecture/vault.md @@ -0,0 +1,154 @@ +# Vault + +## Overview + +[Vault](https://www.vaultproject.io/) provides secret management and protects sensitive data. Hashicorp Vault secure, stores and tightly controls access to tokens, passwords, certificates, encryption keys for protecting secrets and other sensitive data using a UI, CLI, or HTTP API. +Docker container static analysis and policy-based compliance system that automates the inspection, analysis, and evaluation of images against user-defined checks to allow high confidence in container deployments by ensuring workload content meets the required criteria. + +### Vault + +```mermaid +graph LR + subgraph "Vault" + vaultservice1("vault") + end + + subgraph "Secrets Management" + vaultservice1("vault") --> secret1("Secret") + secret1("Secret") --> vaultservice1("vault") + end + + subgraph "Authentication" + vaultservice1("vault") --> authenticationservice1("Keycloak") + authenticationservice1("Keycloak") --> vaultservice1("vault") + end + + subgraph "Logging" + vaultservice1("vault") --> fluent(Fluentbit) --> logging-ek-es-http + logging-ek-es-http{{Elastic Service<br />logging-ek-es-http}} --> elastic[(Elastic Storage)] + end + + subgraph "Monitoring" + svcmonitor("Service Monitor") --> vaultservice1("vault") + Prometheus --> svcmonitor("Service Monitor") + end +``` + +For more information on the Hashicorp Vault architecture, see [Hashicorp Vault](https://www.vaultproject.io/docs/internals/architecture). + +## Big Bang Touch Points + +### Licensing + +The Big Bang Vault deployment uses a Mozilla Public License. The license is an open source copyleft license. The MPL's "file-level" copyleft is designed to encourage contributors to share modifications they make to your code, while still allowing them to combine your code with code under other licenses (open or proprietary) with minimal restrictions. + +Additionally, to enable add a license to enable enterprise Vault features and support the following is an example of how to modify the values within Big Bang: + +```yaml +addons: + vault: + values: + enterpriseLicense: + # The name of the Kubernetes secret that holds the enterprise license. The + # secret must be in the same namespace that Vault is installed into. + secretName: "" + # The key within the Kubernetes secret that holds the enterprise license. + secretKey: "license" +``` + +### Storage + +Vault supports several storage options for the durable storage of Vault's information. As of Vault 1.4, an Integrated Storage option is offered. This storage backend does not rely on any third party systems; it implements high availability, supports Enterprise Replication features, and provides backup/restore workflows. + +The following is an example of how to size the storage within the Big Bang values: + +```yaml +addons: + vault: + values: + dataStorage: + enabled: true + # Size of the PVC created + size: 10Gi + # Location where the PVC will be mounted. + mountPath: "/vault/data" + # Name of the storage class to use. If null it will use the + # configured default Storage Class. + storageClass: null + # Access Mode of the storage device being used for the PVC + accessMode: ReadWriteOnce + # Annotations to apply to the PVC + annotations: {} + + # This configures the Vault Statefulset to create a PVC for audit + # logs. Once Vault is deployed, initialized and unsealed, Vault must + # be configured to use this for audit logs. This will be mounted to + # /vault/audit + # See https://www.vaultproject.io/docs/audit/index.html to know more + auditStorage: + enabled: true + # Size of the PVC created + size: 10Gi + # Location where the PVC will be mounted. + mountPath: "/vault/audit" + # Name of the storage class to use. If null it will use the + # configured default Storage Class. + storageClass: null + # Access Mode of the storage device being used for the PVC + accessMode: ReadWriteOnce + # Annotations to apply to the PVC + annotations: {} +``` + +### High Availability + +Vault supports a multi-server mode for high availability. This mode protects against outages by running multiple Vault servers. High availability mode is automatically enabled when using a data store that supports it. +Vault supports one or more servers to scale out the deployment. + +To scale the deployment in Big Bang, the following is recommended: + +```yaml +addons: + vault: + values: + server: + ha: + enabled: true + replicas: 3 +``` + +For additional information for Vault configuration for High Availability within Big Bang reference the following, [Vault HA](https://repo1.dso.mil/big-bang/product/packages/vault/-/blob/main/docs/production.md) + +### UI + +Vault features a web interface for interacting with Vault. Through the UI you are able to create, read, update, and delete secrets, authenticate, unseal, and more. The Vault UI is enabled by default at the package level. + +### Logging + +Vault produces detailed logs that contain information about user interactions, internal processes, warnings and errors. The verbosity of the logs is controlled using the /sys/loggers endpoint. The log levels are DEBUG, INFO, WARN, ERROR, and TRACE. It is always recommended to increase the log level to DEBUG in order to ensure the availability of the maximum amount of information. + +The following is an example to enable debug level logging for the vault deployment in Big Bang: + +```yaml +addons: + vault: + values: + # Enables debug logging. + debug: true +``` + +_Note:_ within Big Bang, logs are captured by fluentbit and shipped to elastic by default. + +For more information, see [Vault Loggers](https://www.vaultproject.io/api-docs/system/loggers). + +### Monitoring + +The `/sys/metrics` endpoint is used to get telemetry metrics for Vault. This endpoint returns the telemetry metrics for Vault. It can be used by metrics collections systems like Prometheus that use a pull model for metrics collection. The Big Bang Vault Helm chart has been modified to use your `monitoring:` values in Big Bang to automatically toggle metrics on/off. + +Within Big Bang there is additional setup required to configure Vault and monitoring. For more information see, [Vault with Prometheus](https://repo1.dso.mil/big-bang/product/packages/vault/-/blob/main/docs/PROMETHEUS.md) + +### Health Checks + +Liveness and readiness probes are included in the Vault Helm chart for all deployments. The `/sys/health` endpoint is used to check the health status of Vault. This endpoint returns the health status of Vault. This matches the semantics of a Consul HTTP health check and provides a simple way to monitor the health of a Vault instance. + +For more information, see [Vault System Health](https://www.vaultproject.io/api-docs/system/health). diff --git a/docs/understanding-bigbang/package-architecture/velero.md b/docs/understanding-bigbang/package-architecture/velero.md new file mode 100644 index 0000000000000000000000000000000000000000..4946eabed086e542f0a7a5f935ea23ea8994c006 --- /dev/null +++ b/docs/understanding-bigbang/package-architecture/velero.md @@ -0,0 +1,57 @@ +# Velero + +## Overview + +Velero is an open source tool to safely backup and restore, perform disaster recovery, and migrate Kubernetes cluster resources and persistent volumes. + +## Big Bang Touch Points + +```mermaid +graph TB + + subgraph "Velero" + velero + end + + subgraph "Metrics" + velero --> prometheus + end + + subgraph "Object Storage" + velero --> minio/s3 + end +``` + +### Architecture: +- [How Velero works](https://velero.io/docs/main/how-velero-works/) + +### Storage + +Data from velero is stored in object storage and configuration is based upon the [provider](https://repo1.dso.mil/big-bang/product/packages/velero/-/blob/main/chart/values.yaml#L226). + +### Istio Configuration + +Istio is disabled in the velero chart by default and can be enabled by setting the following values in the bigbang chart: + +```yaml +istio: + enabled: true +``` + +These values get passed into the velero chart [here](https://repo1.dso.mil/big-bang/product/packages/velero/-/blob/main/chart/values.yaml#L477). + +## High Availability + +Velero does not have configurations for high availability. + +## Single Sign on (SSO) + +None. This service doesn't have a web interface. + +## Licensing + +[Apache 2.0 License](https://github.com/vmware-tanzu/velero/blob/main/LICENSE) + +## Dependencies + +Velero requires an object storage service available with the bucket details pre-configured. This can be block storage from block storage from AWS, Azure or other providers. `minio` and `minioOperator` can be enabled to provide this storage local to the cluster under the `addon` packages. \ No newline at end of file diff --git a/examples/bigbang packages/.gitlab-ci.yml b/examples/bigbang packages/.gitlab-ci.yml deleted file mode 100644 index 633e572895a7aceb62d34c5338d98f16e026e0d8..0000000000000000000000000000000000000000 --- a/examples/bigbang packages/.gitlab-ci.yml +++ /dev/null @@ -1,12 +0,0 @@ -include: - - project: 'big-bang/pipeline-templates/pipeline-templates' - ref: 'pipeline-template-branch' - file: '/pipelines/bigbang-package.yaml' -variables: - PIPELINE_REPO_BRANCH: 'pipeline-template-branch' - DEBUG_ENABLED: "true" - MULTI_NODE: "true" - BB_REPO: repo1.dso.mil/<username>/<bigbang_fork> - BB_PROJECT_ID: 12985 - CI_PROJECT_NAME: "istio" - BB_AUTO_MR_TOKEN: ${USERNAME_FORK_TOKEN} diff --git a/oscal-component.yaml b/oscal-component.yaml new file mode 100644 index 0000000000000000000000000000000000000000..f2d8c2bac1df3845a4f6206de46054973847093e --- /dev/null +++ b/oscal-component.yaml @@ -0,0 +1,1069 @@ +component-definition: + uuid: "4DEDC09C-B2ED-407B-82C6-229F77DDDC8C" + metadata: + title: Big Bang + last-modified: '2022-06-06T15:26:59.676009+00:00' + version: 1.39.0 + oscal-version: 1.0.4 + parties: + - uuid: 72134592-08C2-4A77-ABAD-C880F109367A + type: organization + name: Platform One + links: + - href: https://p1.dso.mil + rel: website + components: + - uuid: 81F6EC5D-9B8D-408F-8477-F8A04F493690 + type: software + title: Istio Controlplane + description: | + Istio Service Mesh + purpose: Istio Service Mesh + responsible-roles: + - role-id: provider + party-uuids: + - 72134592-08C2-4A77-8BAD-C880F109367A + control-implementations: + - uuid: 06717F3D-CE1E-494C-8F36-99D1316E0D13 + source: https://raw.githubusercontent.com/usnistgov/oscal-content/master/nist.gov/SP800-53/rev5/json/NIST_SP-800-53_rev5_catalog.json + description: + Controls implemented by authservice for inheritance by applications + implemented-requirements: + - uuid: 1822457D-461B-482F-8564-8929C85C04DB + control-id: ac-3 + description: >- + Istio RequestAuthentication and AuthorizationPolicies are applied after Authservice. Istio is configured to only allow access to applications if they have a valid JWT, denying access by default. Applications that do not use Authservice do not have these + policies. + - uuid: D7717A9B-7604-45EF-8DCF-EE4DF0417F9C + control-id: ac-4 + description: >- + All HTTP(S) connections into the system via Istio ingress gateways + and throughout the system with Istio sidecars. + - uuid: 1D1E8705-F6EB-4A21-A24F-1DF7427BA491 + control-id: ac-4.4 + description: >- + All encrypted HTTPS connections are terminated at the istio ingress + gateway. + - uuid: CD1315BF-91FE-490A-B6A6-5616690D78A8 + control-id: ac-6.3 + description: >- + Can be configured with an "admin" gateway to restrict access + to applications that only need sysadmin access. Not standard in BB itself + though. + - uuid: 6109E09A-8279-44AB-8CA4-2051AF895648 + control-id: ac-14 + description: >- + Istio RequestAuthentication and AuthorizationPolicies are applied + after Authservice. Istio is configured to only allow access to applications + if they have a valid JWT, denying access by default. Applications that do + not use Authservice do not have these policies. + - uuid: 9B6BA674-E6ED-4FB6-B216-3C8733F36411 + control-id: au-2 + description: >- + Istio provides access logs for all HTTP network requests, including + mission applications. + - uuid: D3CBC898-F938-4FAA-B1B1-2597A69B5600 + control-id: au-3 + description: >- + By default, Istio uses the Common Log Format with additional information for access logs. + The default configuration does not include the identity of individuals associated with the event. + - uuid: D01F6B2D-F18E-47E9-94DC-95C0B5675E13 + control-id: cm-5 + description: >- + Configured via Kubernetes resources. Inherited from cluster and + flux/ArgoCD. + - uuid: 6370B2DA-1E35-4916-8591-91FB9EDBE72B + control-id: cm-8 + description: >- + Provides an inventory of all workloads (including mission apps) + in the service mesh, viewable in Kiali. + - uuid: AB9189FF-34E2-4D7E-8018-EB346C7AE967 + control-id: cm-8.1 + description: >- + Provides an inventory of all workloads (including mission apps) + in the service mesh, viewable in Kiali. The inventory is automatically and + continuously updated. + - uuid: A740C741-23B4-4ED9-937C-E0276A9B92EE + control-id: cm-8.2 + description: >- + Provides an inventory of all workloads (including mission apps) + in the service mesh, viewable in Kiali. The inventory is automatically and + continuously updated. + - uuid: 61615706-5395-4168-8AD0-5C4ACBCC5D7E + control-id: ia-2 + description: >- + Istio RequestAuthentication and AuthorizationPolicies are applied + after Authservice. Istio is configured to only allow access to applications + if they have a valid JWT, denying access by default. Applications that do + not use Authservice do not have these policies. + - uuid: 3004BB1D-0F50-48F1-ABFE-40CC522B1C15 + control-id: ia-4 + description: >- + Istio uses Kubernetes namespaces and resource names to identifiy + workloads in the service mesh. This provides management of identifiers for + all services in the cluster. + - uuid: FE110D6B-CCB5-41E8-B2DE-287ED843D417 + control-id: ia-9 + description: >- + Istio registers all workload identities in the service mesh. + The identity is transmitted in the mTLS certificate when establishing communication + between services, and is validated by Istio sidecars. + - uuid: 50EE9EB1-0DA4-411C-8771-AA1725B27E22 + type: software + title: Jaeger + description: | + An open source, end-to-end distributed tracing system + purpose: Implementation of Service Mesh + responsible-roles: + - role-id: provider + party-uuids: + - 72134592-08C2-4A77-ABAD-C880F109367A + control-implementations: + - uuid: 5108E5FC-C45F-477B-8542-9C5611A92485 + source: https://raw.githubusercontent.com/usnistgov/oscal-content/master/nist.gov/SP800-53/rev5/json/NIST_SP-800-53_rev5_catalog.json + description: Controls implemented by jaeger for inheritance by applications + implemented-requirements: + - uuid: 1822457D-461B-482F-8564-8929C85C04DA + control-id: si-4.4 + description: Jaeger is used, in conjunction with Istio configurations, to + collect and aggregate network communications within the system. This allows + the moniotiring of inbound/outbound traffic and payloads within the deployed + environment. + - uuid: A97D1364-BA7F-46AA-ADE6-1998E846E125 + type: software + title: Kiali + description: | + A management console for Istio Service Mesh + purpose: Observibility into Istio Service Mesh + responsible-roles: + - role-id: provider + party-uuids: + - 72134592-08C2-4A77-ABAD-C880F109367A + control-implementations: + - uuid: 5108E5FC-C45F-477B-A542-9C5611A92485 + source: https://raw.githubusercontent.com/usnistgov/oscal-content/master/nist.gov/SP800-53/rev5/json/NIST_SP-800-53_rev5_catalog.json + description: Controls implemented by authservice for inheritance by applications + implemented-requirements: + - uuid: 6EC9C476-9C9D-4EF6-854B-A5B799D8AED1 + control-id: si-4.10 + description: Kiali provides visibility into mTLS settings of all Istio traffic + in the cluster. + - uuid: 4045FB97-C11A-4F3B-A021-FD94538F0356 + type: software + title: Cluster Auditor + description: | + Aggregator of policy violtions in environment + purpose: Display policy violations + responsible-roles: + - role-id: provider + party-uuids: + - 72134592-08C2-4A77-ABAD-C880F109367A + control-implementations: + - uuid: 5108E5FC-C45F-477B-A542-9C5611A92485 + source: https://raw.githubusercontent.com/usnistgov/oscal-content/master/nist.gov/SP800-53/rev5/json/NIST_SP-800-53_rev5_catalog.json + description: Controls implemented by authservice for inheritance by applications + implemented-requirements: + - uuid: FD81FE18-FF28-4150-B05D-8001488282BC + control-id: ac-6.9 + description: Cluster Auditor provides a record of policy violiations identified + by OPA Gatekeeper to the Monitoring stack + - uuid: CDA82D9B-70DC-469A-BE63-43DDA26DE6F2 + control-id: au-2 + description: Cluster Auditor has identified policy violations as events that + are recorded. + - uuid: B381423A-46E9-4E39-8B72-3ABBC46DE4B9 + control-id: ca-7 + description: 'Continuous monitoring of controls/violations of the system in + accordance with the Control Assessment Plan ' + - uuid: 8078c070-2d5b-44b8-8fd1-47797fa12c6d + type: software + title: OPA Gatekeeper + description: "An application which assists in enforcing, monitoring, and remediating + policies in Kubernetes while strengthening governance of an environment. \n" + purpose: Monitors existing clusters, detects policy violations, and also acts + as a customizable Kubernetes Admission Webhook + responsible-roles: + - role-id: provider + party-uuids: + - 72134592-08C2-4A77-ABAD-C880F109367A + control-implementations: + - uuid: 5108E5FC-C45F-477B-A542-9C5611A92485 + source: https://raw.githubusercontent.com/usnistgov/oscal-content/master/nist.gov/SP800-53/rev5/json/NIST_SP-800-53_rev5_catalog.json + description: Controls implemented by <component> for inheritance by applications + implemented-requirements: + - uuid: c89a52f1-4d60-4d4e-9c4c-7c5eb04fe21a + control-id: au-2 + description: OPA Gatekeeper provides policy violations events to Cluster Auditor + for event logging. The list of policies being audited is/will be captured + by the Policy Document in Gatekeeper's chart + - uuid: c38f765f-b706-4810-96b6-2971f37122df + control-id: au-3 + description: 'Gatekeeper provides the policy being violated, the timestamp + of when it occured, the location (cluster/namespace), the object causing + the violation and whether it was in warn or deny mode. ' + - uuid: f856dc53-1c3a-428e-83ff-65723c325dac + control-id: au-8 + description: Gatekeeper policies have timestamps assoicated to when the violation + was found and identified. By logging policy violations into log messages + (via logDenies=true ), these logs are also available in the logging framework + - uuid: 41b6ce08-5827-4e08-8ff4-1a61a2e378f8 + control-id: au-9 + description: Access to the Gatekeeper violations are managed by/inherited + from the Kubernetes cluster + - uuid: da7ff1f0-2a16-491c-8854-788cc46cef3c + control-id: cm-1 + description: Provides enforcement of configuration management policy + - uuid: ffb9f4b5-0bfe-4053-9e12-5657a1ceb0b9 + control-id: cm-7.5 + description: OPA Gatekeeper can prevent by default unauthorized changes to + the system. + - uuid: 07a4e16a-944b-4989-a6d8-057b545748d0 + control-id: cm-11 + description: Gatekeeper can provide the ability for end users to control the + policies that allow for the installation of end-user software. It also provides + the enforcement and monitoring + - uuid: 72d2434e-0dac-4267-8594-d2df5da6b22a + control-id: sa-9 + description: Gatekeeper can ensure applications installed on the kubernetes + cluster meet policy requirements for manfiests + - uuid: BE039F48-F418-4D86-BD5F-8CE8CBEAD91E + type: software + title: Elasticsearch and Kibana + description: | + Deployment of Elasticsearch and Kibana for logging stack + purpose: Provides storage and UI for log aggregation in the cluster + responsible-roles: + - role-id: provider + party-uuids: + - 72134592-08C2-4A77-ABAD-C880F109367A + control-implementations: + - uuid: 5108E5FC-C45F-477B-A542-9C5611A92485 + source: https://raw.githubusercontent.com/usnistgov/oscal-content/master/nist.gov/SP800-53/rev5/json/NIST_SP-800-53_rev5_catalog.json + description: Controls implemented by authservice for inheritance by applications + implemented-requirements: + - uuid: 31ED9374-C146-4B40-ABD5-537B24DBDCEF + control-id: ac-6.9 + description: Elasticsearch stores and aggregates privilege function calls + collected by fluentbt. + - uuid: 373074CC-F1EA-40CB-AD17-DB8F199D0600 + control-id: au-4 + description: Underlying log storage is elastically scaleable. + - uuid: 90FFF3BA-3E88-47AD-88B7-B50A92833A45 + control-id: au-5 + description: Kibana has the ability to alert based on events discovered in + Elastic indecies + - uuid: 3230D443-A18C-4F9B-A0DE-DC89CE5D01C8 + control-id: au-5.1 + description: Authservice allows the use of an extenrral idtntiy OIDC provider + for application login by configuring filter chain matching for hostname + (headers) for applications. This control can then be inherited by the Identity + Provider + - uuid: 98DE555D-1B90-475F-9C2E-954438172B39 + control-id: au-9 + description: Kibana provides ability to use Role Based Access Control to allow + for the indexes that store audit logs to be restricted to just cluster administrators + - uuid: 6ED4D692-F65F-40AB-AC3F-C056C2F41BD9 + control-id: au-9.4 + description: Kibana provides ability to use Role Based Access Control to allow + for the indexes that store audit logs to be restricted to just cluster administrators + - uuid: BE039F48-F418-4D86-BD5F-8CE8CBEAD91E + type: software + title: Fluentbit + description: | + Log collector + purpose: Collects logs from the cluster + responsible-roles: + - role-id: provider + party-uuids: + - 72134592-08C2-4A77-ABAD-C880F109367A + control-implementations: + - uuid: 6358159C-2710-46EF-ACC5-39FD3117391D + source: https://raw.githubusercontent.com/usnistgov/oscal-content/master/nist.gov/SP800-53/rev5/json/NIST_SP-800-53_rev5_catalog.json + description: Controls implemented by authservice for inheritance by applications + implemented-requirements: + - uuid: D9D09567-C4C7-4DEA-921C-6318DF2F9331 + control-id: ac-6.9 + description: Fluentbit can be configured to collect all logs from Kubernetes + and underlying operating systems, allowing the aggregation of privileged + function calls. + - uuid: 373074CC-F1EA-40CB-AD17-DB8F199D0600 + control-id: au-2 + description: |- + Logging daemons are present on each node that BigBang is installed on. Out of the box, the following events are captured: + * all containers emitting to STDOUT or STDERR (captured by container runtime translating container logs to /var/log/containers) * all kubernetes api server requests * all events emitted by the kubelet + - uuid: 90FFF3BA-3E88-47AD-88B7-B50A92833A45 + control-id: au-3 + description: |- + Records captured by the logging daemon are enriched to ensure the following are always present: + * time of the event (UTC) * source of event (pod, namespace, container id) + Applications are responsible for providing all other information. + - uuid: 3230D443-A18C-4F9B-A0DE-DC89CE5D01C8 + control-id: au-8 + description: |- + Records captured by the logging daemon are enriched to ensure the following are always present: + * time of the event (UTC) * source of event (pod, namespace, container id) + Applications are responsible for providing all other information. + - uuid: 4045FB97-C11A-4F3B-A021-FD94538F0356 + type: software + title: Monitoring + description: | + Aggregator of policy violtions in environment + purpose: Display policy violations + responsible-roles: + - role-id: provider + party-uuids: + - 72134592-08C2-4A77-ABAD-C880F109367A + control-implementations: + - uuid: 5108E5FC-C45F-477B-A542-9C5611A92485 + source: https://raw.githubusercontent.com/usnistgov/oscal-content/master/nist.gov/SP800-53/rev5/json/NIST_SP-800-53_rev5_catalog.json + description: Controls implemented by authservice for inheritance by applications + implemented-requirements: + - uuid: B5B39044-B02A-4655-B466-7586B24963A1 + control-id: ac-6.9 + description: 'Privileged events, including updating the deployment of an application, + or use of privileged containers are collected as metrics by prometheus and + displayed by Grafana ' + - uuid: 8AE237CE-E7FF-42FE-B79F-2DF106B0CC09 + control-id: au-2 + description: "API endpoints suitable for capturing application level metrics + are present on each of the supported applications running as containers. + \ In addition, system and cluster level metrics are emitted by containers + with read only access to host level information.\nMetrics are captured and + stored by Prometheus, an web server capable of scraping endpoints formatted + in the appropriate dimensional data format. Metrics information is stored + on disk in a time series data base, and later queried through a separate + component providing a web interface for the query language: PromQL. " + - uuid: F2FFC2FD-6826-43EE-9922-705A76FE63CC + control-id: au-3.1 + description: Grafana has pre-configured dashboards showing the audit records + from Cluster Auditor saved in Prometheus. + - uuid: B958C179-EE1F-40FC-BA2A-03B0072B20E6 + control-id: au-4 + description: Prometheus is the log aggregator for audit logs since it is used + to scrape/collect violations from ClusterAuditor. The storage capability + can be configured in prometheus to use PVCs to ensure metrics have log retention + complioance with the org-defined audit-log retention requirements + - uuid: 01975AD9-8F46-48EB-81F1-1DDEB6DB0882 + control-id: au-5 + description: Grafana and Alertmanager can both alert on prometheus metrics + and alerts can be created in either to support this control + - uuid: FA95745B-E13E-4153-ABEE-1970C315A381 + control-id: au-5.1 + description: Alertmanager has pre-built alerts for PVC storage thresholds + that would fire for PVCs supporting prometheus metrics storage + - uuid: 5D45F4A3-A37F-451D-9670-8FA9DFD1355F + control-id: au-5.2 + description: |- + Alertmanager has pre-build alerts for failed pods that would show when ClusterAuditor is not processeing events, or prometheus is unable to scrape events. + Prometheus also has a deadman's alert to ensure end users are seeing events from prometheus as part of its configuration + - uuid: 603A45C9-E730-4321-B8AE-60D048E14BAB + control-id: au-6.1 + description: Cluster Audtitor Events/Alerts could be exported from Prometheus + to an external system. Integration for specific tooling would need to be + completed by end user + - uuid: 92D322C1-B4D3-4842-8B06-538218AECA7D + control-id: au-6.3 + description: Aggregating cluster auditor events across multiple sources (clusters) + is possible with a multi-cluster deployment of prometheus/grafana + - uuid: BB0DF859-827F-4E3A-8C61-DEDCE4A9B3EB + control-id: au-6.5 + description: Cluster Auditor's audit data is consolidated with system monitoring + tooling (node exporters) for consolidated view to enhance inappropriate + or unusual activity + - uuid: 77C00727-4195-45A8-8BB6-534AE5889E71 + control-id: au-6.6 + description: Cluster Auditor data in prometheus would enable this, but would + require prometheus to also obtain access to physical metrics. + - uuid: 6F291DF6-5613-46DF-9D9A-AC7CEDFF4A7B + control-id: au-7 + description: Grafana is configured with a pre-built dashboard for policy violations + that displays data collected by Cluster Auditor + - uuid: 54D583CE-DB4A-4C03-902D-9A37949F4820 + control-id: au-7.1 + description: Grafana is configured with a pre-built dashboard for policy violations + that displays data collected by Cluster Auditor + - uuid: 91D9D559-1666-420B-9F2B-240BC7CD1A3E + control-id: au-8 + description: Prometheus stores all data as timeseries data, so the timestamps + of when those violitions were present is part of the datastream + - uuid: 2D7AB4A4-1AE7-45A6-BC56-9FBB6402AD98 + control-id: au-9 + description: Grafana has the ability to provide Role Based Access Control + to limit the data sources that end users can view by leveraging an identity + provider. Grafana can also limit users to subsets of metrics within a datasource + by the use of Label Based Acces Control when using Grafana Enterprise. + - uuid: 58B88EBD-ABAD-4505-9243-809D8DEFAEF7 + control-id: au-9.2 + description: Prometheus can scrape external components outside of the system, + but this configuration is not easily supported as part of the current big + bang configuration of ClusterAuditor since external access to ClusterAuditor + metrics is not exposed via Istio + - uuid: 8178202C-6E6C-415A-8B0D-C486AAC85B3A + control-id: au-9.4 + description: Grafana has the ability to provide Role Based Access Control + to limit the data sources that end users can view by leveraging an identity + provider. Grafana can also limit users to subsets of metrics within a datasource + by the use of Label Based Acces Control when using Grafana Enterprise. + - uuid: A471F648-C22C-4217-A3BA-1063E80B4BA3 + control-id: au-12.1 + description: Compatible metrics endpoints emitted from each application is + compiled by Prometheus and displayed through Grafana with associated timestamps + of when the data was collected + - uuid: 660B7C27-2997-4EB7-BA61-C66FEC2D1602 + type: software + title: ArgoCD + description: | + A declarative GitOps continuous delivery tool for Kubernetes + purpose: GitOps continuous delivery + responsible-roles: + - role-id: provider + party-uuids: + - 72134592-08C2-4A77-ABAD-C880F109367A + control-implementations: + - uuid: 909C0D05-5BF7-4D89-B82F-38488A02CC85 + source: https://raw.githubusercontent.com/usnistgov/oscal-content/master/nist.gov/SP800-53/rev5/json/NIST_SP-800-53_rev5_catalog.json + description: Controls implemented by ArgoCD for inheritance by applications + implemented-requirements: + - uuid: 4F924345-FED4-496B-91E3-5361F2B2F2DA + control-id: AC-5 + description: ArgoCD can be configured for granular user access to certain + application deployments. + - uuid: 27C176A6-BF99-4BE9-9748-63C99C75328E + control-id: AC-6 + description: ArgoCD can be configured per user with the least privilige needed. + - uuid: EC3BC1CA-4E31-4130-A246-D15857F1A6E7 + control-id: AU-2 + description: ArgoCD logs events related to the applicaction state itself, + i.e. start/stop failures. + - uuid: ACC00F83-5C88-44FA-A6CA-0AD68AD9E09F + control-id: AU-3 + description: ArgoCD has a natural audit log for what changes were made to + an applications configuration, when they were made, and by who. This is + provided by the Git commit history in the GitOps workflow. + - uuid: C4E89AE2-3959-4828-B15F-7D4AD1BDB4BC + control-id: AC-7 + description: ArgoCD rejects login attemps after too many failed in order to + prevent passsword brute-forcing. Proceted by the following components, + max fail count, failure window, max entry cache size, and max concurrent + login requests. + - uuid: 8B181052-6E36-4A12-A58B-4049F035021D + control-id: CM-2.2 + description: ArgoCD provides the configuration management engine to ensure + CM-2 is met + - uuid: 48DBC6A1-28E4-4AF0-95F1-CB70EB818B3C + control-id: CM-2.3 + description: ArgoCD / Git provides history for releases + - uuid: 21F72DBE-EA11-4E27-9AE3-82B08C4E16EA + control-id: CM-3 + description: ArgoCD / Git enable teams to do this as part of their workflow + - uuid: A89D4C6B-C885-43A4-85A0-7BB1B33E20DF + control-id: CM-3.1 + description: ArgoCD / Git provide automation of documentation, notifications + of upgrades to BB + - uuid: E3C277C6-A058-4595-B034-3BEE1D74AE51 + control-id: CM-3.2 + description: ArgoCD allows for workflows to be created by end users to deploy + exact configurations into stage/dev environment that mirror production. + - uuid: ADF0F06E-F773-43A2-BA91-109D4C3B8AF5 + control-id: CM-4 + description: BB/Git provides changelogs which identify changes to system via + upgrades + - uuid: A202F34E-1689-47A2-A55C-406C0437C7DD + control-id: CM-4.2 + description: This current effort will provide controls explicitly as part + of the product to track how controls will change with upgrades + - uuid: 373DC91F-E590-44B5-B4B1-8DF8453EB9B9 + control-id: CM-5.1 + description: Use of ArgoCD/GitOps allows this to be inherited by management + in GitLab + - uuid: D2B04238-01DB-49B0-A787-069BE6D962C7 + control-id: CM-6 + description: ArgoCD manages application configuration settings controlled + in GitLab and ensures they match the expected state. + - uuid: 4EC8B133-3118-4429-A4F7-A1AF3737F5AD + control-id: CM-6.1 + description: ArgoCD manages/applies and verifies configuration as code + - uuid: 8B027EED-6484-473A-B4F6-BADF9F55978D + control-id: CM-8 + description: ArgoCD provides visualization of the deployed application and + configurations. + - uuid: 0323639F-85B3-4858-99A8-C69C0D6DA16F + control-id: CM-8.1 + description: ArgoCD automatically updates its inventory when changes occur + to cluster resources. + - uuid: 53E65314-43DB-4464-B9B8-6075AA6B96AB + control-id: CM-8.2 + description: ArgoCD maintains the currency, completeness, accuracy, and availability + of cluster resources by continuously reconciling the desired state in Git + to the actual state in Kubernetes. + - uuid: 593D198A-E5DF-429F-9BCB-EE5561B50522 + control-id: CM-8.4 + description: ArgoCD displays the name of an individual who made a Git commit + that resulted in changes to the system component inventory + - uuid: 6379A5B5-C5AC-4A30-AAC1-A40BB7AAABFC + control-id: CP-2 + description: ArgoCD will restore applications it manages to the known GitOps + state in GitLab + - uuid: 4753C850-EC7C-47F2-AE55-541B73D3D957 + control-id: CP-10 + description: ArgoCD will restore applications it manages to the known GitOps + state in GitLab + - uuid: CBCC3D5C-03FE-4F6F-A587-6776813AA87B + control-id: CP-10.2 + description: ArgoCD will restore applications it manages to the known GitOps + state in GitLab + - uuid: 28D7704A-7859-4A7E-9967-4E564D94BA93 + control-id: CP-10.4 + description: ArgoCD will restore applications it manages to the known GitOps + state in GitLab + - uuid: E70A5057-3BA4-4E62-8C74-ED19122BBA9E + type: software + title: Authservice + description: "an implementation of thee Envoy External Authorization focused on + handling AuthN/AuthZ \nfor Istio and Kubernetes.\n" + purpose: Provides authn/authz capabilites to applications via Istio Service Mesh + responsible-roles: + - role-id: provider + party-uuids: + - 72134592-08C2-4A77-ABAD-C880F109367A + control-implementations: + - uuid: 5108E5FC-C45F-477B-A542-9C5611A92485 + source: https://raw.githubusercontent.com/usnistgov/oscal-content/master/nist.gov/SP800-53/rev5/json/NIST_SP-800-53_rev5_catalog.json + description: Controls implemented by authservice for inheritance by applications + implemented-requirements: + - uuid: 6EC9C476-9C9D-4EF6-854B-A5B799D8AED1 + control-id: ac-2.1 + description: Authservice allows the use of an extenrral idtntiy OIDC provider + for application login by configuring filter chain matching for hostname + (headers) for applications. This control can then be inherited by the Identity + Provider + - uuid: 373074CC-F1EA-40CB-AD17-DB8F199D0600 + control-id: ac-2.2 + description: Authservice allows the use of an extenrral idtntiy OIDC provider + for application login by configuring filter chain matching for hostname + (headers) for applications. This control can then be inherited by the Identity + Provider + - uuid: 90FFF3BA-3E88-47AD-88B7-B50A92833A45 + control-id: ac-2.3 + description: Authservice allows the use of an extenrral idtntiy OIDC provider + for application login by configuring filter chain matching for hostname + (headers) for applications. This control can then be inherited by the Identity + Provider + - uuid: 3230D443-A18C-4F9B-A0DE-DC89CE5D01C8 + control-id: ac-2.4 + description: Authservice allows the use of an extenrral idtntiy OIDC provider + for application login by configuring filter chain matching for hostname + (headers) for applications. This control can then be inherited by the Identity + Provider + - uuid: 98DE555D-1B90-475F-9C2E-954438172B39 + control-id: ac-8 + description: Authservice allows the use of an extenrral idtntiy OIDC provider + for application login by configuring filter chain matching for hostname + (headers) for applications. This control can then be inherited by the Identity + Provider + - uuid: 6ED4D692-F65F-40AB-AC3F-C056C2F41BD9 + control-id: ac-10 + description: "Allows the use of an external identiy OIDC provider for application + login by configuring filter chain matching hostname for application.\nBy + restricting the lifetime of the JWT, Authservice will reauthenticate the + user when it expires. The IdP can then implement concurrent session control, + enforced during reauthentication. This control can then be inherited from + the IdP. " + - uuid: 5D737AC5-0841-480E-87C0-DBBDE4F61F8E + control-id: ac-12 + description: "Allows the use of an external identiy OIDC provider for application + login by configuring filter chain matching hostname for application.\nBy + restricting the lifetime of the JWT, Authservice will reauthenticate the + user when it expires. The IdP can then implement concurrent session control, + enforced during reauthentication. This control can then be inherited from + the IdP. " + - uuid: CBBAA8D3-276F-40C2-8E55-02C883201123 + control-id: ac-14 + description: "Allows the use of an external identiy OIDC provider for application + login by configuring filter chain matching hostname for application.\nBy + restricting the lifetime of the JWT, Authservice will reauthenticate the + user when it expires. The IdP can then implement concurrent session control, + enforced during reauthentication. This control can then be inherited from + the IdP. " + - uuid: 085E711D-A3E8-4CC2-B2E4-F1F0D1E9CE87 + control-id: ia-2 + description: Authservice maps user sessions to user identities in an IdP. + - uuid: FB487DED-D360-4988-BD1B-4FCFA351258A + control-id: ia-2.1 + description: 'Allows the use of an external identiy OIDC provider for application + login by configuring filter chain matching hostname for application. The + IdP can enforce multi-factor authentication for the client used by authservice. + This control can then be inherited from the IdP. ' + - uuid: EC6FF902-2E29-4FEC-A5B7-F3DD1573F61A + control-id: ia-2.2 + description: 'Allows the use of an external identiy OIDC provider for application + login by configuring filter chain matching hostname for application. The + IdP can enforce multi-factor authentication for the client used by authservice. + This control can then be inherited from the IdP. ' + - uuid: B41B29FF-131D-4CD8-9275-9E0391BA35C5 + control-id: ia-2.8 + description: 'Allows the use of an external identiy OIDC provider for application + login by configuring filter chain matching hostname for application. The + IdP and OIDC protocol use "nonce" and "state" fields for replay resistance. + This control can then be inherited from the IdP. ' + - uuid: 8BD41F8B-3072-4AAD-A7E2-1DFC24F6D0C5 + control-id: ia-3 + description: 'Allows the use of an external identiy OIDC provider for application + login by configuring filter chain matching hostname for application. The + IdP can be configured to uniquely idenfify and authenticate devices before + establishing connections. This control can then be inherited from the IdP. ' + - uuid: 2519BEBB-327B-4E03-BA47-423D96114EE4 + control-id: ia-4 + description: 'Authservice retreives JWT identfiers from the IdP which include + various "claims" including the username of individuals, and a list of "groups" + (roles) the user has access to. This control can then be inherited from + the IdP. ' + - uuid: F391AA9E-5EDB-483E-8EC2-60CA9602B1EF + control-id: ia-4.4 + description: 'Authservice retreives JWT identfiers from the IdP, which include + various "claims" and such as a list of "groups" (status) that apply to + the user. This control can then be inherited from the IdP. ' + - uuid: 59AECD61-0244-4930-897C-EAFA9D423F7F + control-id: ia-5 + description: 'Authservice does not manage authenticators, they are managed + by the IdP. This control can then be inherited from the IdP. ' + - uuid: FF69FC29-C3E0-4B02-948E-CF375F93AF05 + control-id: ia-5.1 + description: "Authservice does not manage authenticators, they are managed + by the IdP. This control can then be inherited from the IdP. \nAuthservice + does NOT use the OAuth Resource Owner Password Credentials Flow, no passwords + are transmitted by Authservice." + - uuid: 1489616B-8A08-437A-8EE8-E86E10C64D94 + control-id: ia-5.2 + description: 'Authservice does not manage authenticators, they are managed + by the IdP. This control can then be inherited from the IdP. ' + - uuid: 2B01945F-2793-4CA1-BD40-B236A190EE66 + control-id: ia-5.6 + description: 'Authservice does not manage authenticators, they are managed + by the IdP. This control can then be inherited from the IdP. ' + - uuid: B48BD91F-5A89-4653-89C5-45EC55267049 + control-id: ia-6 + description: 'Authservice does not manage authenticators, they are managed + by the IdP. This control can then be inherited from the IdP. ' + - uuid: BC78A59A-7E43-4F27-8961-7DD8957499D7 + control-id: ia-8.1 + description: 'Authservice does not manage authenticators, they are managed + by the IdP. This control can then be inherited from the IdP. ' + - uuid: 13E81A49-24C1-4E05-8E5F-F50402FEEE54 + control-id: ia-8.2 + description: 'Authservice does not manage authenticators, they are managed + by the IdP. This control can then be inherited from the IdP. ' + - uuid: 475636F6-74AC-4E12-938C-BA92999A34AF + control-id: ia-8.5 + description: 'Authservice does not manage authenticators, they are managed + by the IdP. This control can then be inherited from the IdP. ' + - uuid: 63130DA3-52C8-402A-9CB9-1DE9AF62DE5E + control-id: ia-10 + description: 'Authservice does not manage authenticators, they are managed + by the IdP. This control can then be inherited from the IdP. ' + - uuid: 9DA88C51-E81D-4D02-8B51-33CF15F5C46C + control-id: ia-11 + description: "Allows the use of an external identiy OIDC provider for application + login by configuring filter chain matching hostname for application.\nBy + restricting the lifetime of the JWT, Authservice will reauthenticate the + user when it expires. The IdP can then implement concurrent session control, + enforced during reauthentication. This control can then be inherited from + the IdP. " + - uuid: 86C613C9-D6AC-4DF1-B8A2-5C51654CB933 + control-id: ia-12 + description: 'Authservice does not manage authenticators, they are managed + by the IdP. This control can then be inherited from the IdP. ' + - uuid: FA83073D-77E5-4DAA-A1A3-88FAD126ED50 + control-id: ia-12.2 + description: 'Authservice does not manage authenticators, they are managed + by the IdP. This control can then be inherited from the IdP. ' + - uuid: AFA5160F-11C1-471E-94E0-8B8E5D2C9050 + control-id: ia-12.3 + description: 'Authservice does not manage authenticators, they are managed + by the IdP. This control can then be inherited from the IdP. ' + - uuid: 4284CA32-4CB9-484B-A769-34D6C1364F22 + control-id: ia-12.4 + description: 'Authservice does not manage authenticators, they are managed + by the IdP. This control can then be inherited from the IdP. ' + - uuid: 1906F9E4-6E82-46A5-A575-70FA0F2E131E + control-id: ia-12.4 + description: 'Authservice does not manage authenticators, they are managed + by the IdP. This control can then be inherited from the IdP. ' + - uuid: C9C67A58-CBA4-4F9D-92A6-B73068C7F3AD + control-id: ia-12.5 + description: 'Authservice does not manage authenticators, they are managed + by the IdP. This control can then be inherited from the IdP. ' + - uuid: 3127D34A-517B-473B-83B0-6536179ABE38 + type: software + title: Velero + description: | + Velero is an open source tool to safely backup and restore, perform disaster recovery, and migrate Kubernetes cluster resources and persistent volumes + purpose: Provides backup and restore capabilities to a Kubernetes cluster + responsible-roles: + - role-id: provider + party-uuids: + - 72134592-08C2-4A77-ABAD-C880F109367A + control-implementations: + - uuid: 5108E5FC-C45F-477B-8542-9C5611A92485 + source: https://raw.githubusercontent.com/usnistgov/oscal-content/master/nist.gov/SP800-53/rev5/json/NIST_SP-800-53_rev5_catalog.json + description: Controls implemented by velero for inheritance by applications + implemented-requirements: + - uuid: 2ADA7512-E0D5-4CAE-81BC-C889C640AF93 + control-id: cp-6 + description: Velero can take backups of your application configuration/data + and store them off-site in either an approved cloud environment or on-premise + location. + - uuid: 6C3339A0-9636-4E35-8FA8-731CF900B326 + control-id: cp-6.1 + description: Velero can take backups of your application configuration/data + and store them off-site in either an approved cloud environment or on-premise + location. + - uuid: 2799CCBF-C48D-4451-85BA-EBD9B949C361 + control-id: cp-6.2 + description: Velero can restore application configuration/data from an approved + cloud provider or on-premise location on-demand. + - uuid: 0AE59B43-50A7-4420-881B-E0635CCB8424 + control-id: cp-6.3 + description: Velero supports back-ups to multiple cloud environments (including + geo-separated locations for high availibility) and on-premise environments + in the event of an accessibility disruptions. + - uuid: B11B38B8-8744-4DFD-8C1A-4A4EDD7F9574 + control-id: cp-7 + description: Velero can restore application configuration/data from an approved + cloud provider or on-premise location to an alternative deployment environment + on-demand. + - uuid: D74C3A8C-E5B0-4F81-895D-FB2A318D723B + control-id: cp-7.1 + description: Velero supports back-ups to and restores from multiple cloud + environments (including geo-separated locations for high availibility) and + on-premise environments in the event of an accessibility disruptions. + - uuid: 72D7145F-7A3F-47AF-835F-7E3D6EFAE1CC + control-id: cp-7.2 + description: Velero supports back-ups to and restores from multiple cloud + environments (including geo-separated locations for high availibility) and + on-premise environments in the event of an accessibility disruptions. + - uuid: 5B0AA4CB-9C49-4D32-8242-5631788BD941 + control-id: cp-9 + description: |- + "Velero gives you tools to back up and restore your Kubernetes cluster resources and persistent volumes. You can run Velero with a cloud provider or on-premises. This includes: + - System components/data. + - User-level information/application metadata. + - User-level storage/data. + - Scheduled back-ups with configurable scopes. + - Multi-cloud and on-premise support for availability of backup." + - uuid: 8E5917F3-3E45-46C1-8585-48550E19AFFB + control-id: cp-9.1 + description: Velero provides feedback/logging of back-up status for configuration/data + via kubectl or the Velero CLI tool. Velero can restore your production configuration/data + to validation environment to ensure reliability/integrity. + - uuid: 51191D0E-0C7B-4D2D-861D-202AC8C505CF + control-id: cp-9.2 + description: Velero can be configured to restore only certain components of + a back-up when necessary. + - uuid: C650411C-33FD-4B59-8899-AC34B43C860F + control-id: cp-9.3 + description: Velero supports back-ups to multiple cloud environments (including + geo-separated locations for high availibility) and on-premise environments. + - uuid: 8AB09B17-301B-4836-835B-9CE22A9E2300 + control-id: cp-9.5 + description: 'Velero gives you tools to back up and restore your Kubernetes + cluster resources and persistent volumes. You can run Velero with a cloud + provider or on-premises. This includes: - System components/data. - User-level + information/application metadata. - User-level storage/data. - Scheduled + back-ups with configurable scopes. - Multi-cloud and on-premise support + for availability of backup.' + - uuid: 7FACB782-C183-4585-8C0B-17824438FEA6 + control-id: cp-9.8 + description: Velero supports encryption of backups via its supported providers' + encryption support/mechanisms. + - uuid: 26B3D98B-0C9D-434B-8DE5-06CBBC46A38C + control-id: cp-10 + description: Velero can restore application configuration/data from an approved + cloud provider or on-premise location on-demand. + - uuid: 3EA444B7-61ED-43DD-8B3D-24B55F286E59 + control-id: cp-10.4 + description: 'Velero gives you tools to back up and restore your Kubernetes + cluster resources and persistent volumes. You can run Velero with a cloud + provider or on-premises. This includes: - System components/data. - User-level + information/application metadata. - User-level storage/data. - Scheduled + back-ups with configurable scopes. - Multi-cloud and on-premise support + for availability of backup.' + - uuid: 13936e92-24bd-4948-abe6-af88422174aa + type: software + title: Keycloak + description: | + An implementation of a customizable Keycloak for single sign-on (SSO) with Identity and Access Management + purpose: Provides user federation, strong authentication, user management, fine-grained + authorization. + responsible-roles: + - role-id: provider + party-uuids: + - 72134592-08C2-4A77-ABAD-C880F109367A + control-implementations: + - uuid: 44bb0268-355d-455b-be33-7fc6ecc89668 + source: https://raw.githubusercontent.com/usnistgov/oscal-content/master/nist.gov/SP800-53/rev5/json/NIST_SP-800-53_rev5_catalog.json + description: Controls implemented by Keycloak for inheritance by applications + implemented-requirements: + - uuid: 045bbf72-d7d1-4763-a997-caf62785b2aa + control-id: ac-1 + description: |- + System-level access controls + Keycloak supports fine-grained authorization policies and is able to combine different access control mechanisms such as: + + - Attribute-based access control (ABAC) + - Role-based access control (RBAC) + - User-based access control (UBAC) + - Context-based access control (CBAC) + - Rule-based access control + - Using JavaScript + - Time-based access control + - Support for custom access control mechanisms (ACMs) through a Policy Provider Service Provider Interface (SPI) + + Keycloak is based on a set of administrative UIs and a RESTful API, and provides the necessary means to create permissions for your protected resources and scopes, associate those permissions with authorization policies, and enforce authorization decisions in your applications and services. + Resource servers (applications or services serving protected resources) usually rely on some kind of information to decide if access should be granted to a protected resource. For RESTful-based resource servers, that information is usually obtained from a security token, usually sent as a bearer token on every request to the server. For web applications that rely on a session to authenticate users, that information is usually stored in a user’s session and retrieved from there for each request. + Permissions can be created to protect two main types of objects: + + - Resources: resource-based permission defines a set of one or more resources to protect using a set of one or more authorization policies. + - Scopes: scope-based permissions defines a set of one or more scopes to protect using a set of one or more authorization policies. Unlike resource-based permissions, you can use this permission type to create permissions not only for a resource, but also for the scopes associated with it, providing more granularity when defining the permissions that govern your resources and the actions that can be performed on them. + + https://www.keycloak.org/docs/latest/authorization_services/ + + Organizational access controls + Organizational roles could be broken down into cluster admins, resource owners / administrators, clients / users + - uuid: 86815b87-fc12-432b-9d0a-77492186ad6e + control-id: ac-2 + description: |- + Big Bang implements a custom plugin to handle account managment, found here (https://repo1.dso.mil/big-bang/product/packages/keycloak/-/tree/main/development). Through this plugin logic is implemented to control automated registration and ties into DoD PKI validation/verification. Additionally, this plugin validates group membership in conjunction with Keycloak Clients to prohibit/allow access to various resources behind the single sign on solution. + + a/c. non-privileged users are prohibited by the keycloak plugin and declarative group structure defined here (https://repo1.dso.mil/big-bang/product/packages/keycloak/-/tree/main/development). Privileged users follow a similar posture combined with other solutions to prohibit access to resources based on group membership. + b. Keycloak can be configured for fine grain permissions to assign account managers, additionally the custom plugin allows configuration of groups with specific permissions within the keycloak web UI console. + d (1-3). Declarative groups specify authorized users, groups, and roles. Access authorizations and assignment is related to Day 2 operations of keycloak and may vary between organizations. + e. Handled by Day 2 operations of keycloak. + f. declarative groups assist in the handling of accounts, but ultimate is is a day 2 operation. + g. Keycloak web UI has a queryable audit logging feature and backend logs can be monitored. + h. Handled by Day 2 operations of keycloak. + i. Handled by Day 2 operations of keycloak. + j. Mostly, handled by Day 2 operations of keycloak. However, built in registration flow validates and verifies DoD level authorization. + k. Handled by Day 2 operations of keycloak. + l. Handled by Day 2 operations of keycloak. + - uuid: 477fbb45-8837-4755-a1f2-6d1843b7bedb + control-id: ac-2.1 + description: Keycloak allows the creation of clients that provide login to + app via Keycloak, allowing account management to be inherited from keycloak. + There are roughly 30 different event types in keycloak and an event listener + can be configured to notify when an account is created, enabled, modified, + disabled, or removed, or when users are terminated or transferred. + - uuid: 440ef311-2711-4bb0-9dd8-438d196e84e5 + control-id: ac-2.2 + description: Keycloak allows the creation of clients that provide login to + app via Keycloak, allowing account management to be inherited from keycloak. + There are roughly 30 different event types in keycloak and an event listener + can be configured to notify when an account is created, enabled, modified, + disabled, or removed, or when users are terminated or transferred. + - uuid: 9a76f468-1daa-49ca-9582-7c17751f41bc + control-id: ac-2.3 + description: Keycloak allows the creation of clients that provide login to + app via Keycloak, allowing account management to be inherited from keycloak. + There are roughly 30 different event types in keycloak and an event listener + can be configured to notify when an account is created, enabled, modified, + disabled, or removed, or when users are terminated or transferred. + - uuid: 93d0b28b-bcf4-4e45-a5e0-f5d1b0ce9d26 + control-id: ac-2.4 + description: Keycloak allows the creation of clients that provide login to + app via Keycloak, allowing account management to be inherited from keycloak. + There are roughly 30 different event types in keycloak and an event listener + can be configured to notify when an account is created, enabled, modified, + disabled, or removed, or when users are terminated or transferred. + - uuid: 6c10ca0e-7b91-45ab-b066-949bdfba126a + control-id: ac-2.5 + description: Keycloak is configured with login timeout, session tokens, etc. + and are managed in realm settings/tokens + - uuid: 473ce520-ed39-4d88-9433-2a04cc451b16 + control-id: ac-2.12 + description: Keycloak allows the creation of clients that provide login to + app via Keycloak, allowing account management to be inherited from keycloak. + There are roughly 30 different event types in keycloak and an event listener + can be configured and automated via email, external webhook, and logging + stack monitored by admins to notify when an account is created, enabled, + modified, disabled, or removed, or when users are terminated or transferred. + - uuid: cb4929fc-3685-45e4-8720-405dc5ed9ea3 + control-id: ac-2.13 + description: Keycloak allows the creation of clients that provide login to + app via Keycloak, allowing account management to be inherited from keycloak. + There are roughly 30 different event types in keycloak and an event listener + can be configured and automated via email, external webhook, and logging + stack monitored by admins to notify when an account is created, enabled, + modified, disabled, or removed, or when users are terminated or transferred. + - uuid: b704526e-e18f-46ec-8072-2e361115265a + control-id: ac-3 + description: Keycloak allows the creation of clients that provide login to + app via Keycloak, allowing account management to be inherited from keycloak + and the enforcement of approved authorizaions for logical access to information + and system resources. + - uuid: ef73dc31-ab9a-4d67-b5b8-c042e47aba25 + control-id: ac-4 + description: Keycloak is designed and recommended to be deployed in a stand-alone + BB cluster with TLS passthrough for OIDC/SAML integration. Controls are + inherited from istio via network policies, virtual services and gateway + configs. + - uuid: 34ea5ae5-3525-4a81-974f-a73e1999610f + control-id: ac-4.4 + description: Keycloak is designed and recommended to be deployed in a stand-alone + BB cluster with TLS passthrough for OIDC/SAML integration. Controls are + inherited from istio via network policies, virtual services and gateway + configs. + - uuid: 25a717a7-3f1f-4d24-9cc1-701be6f97df9 + control-id: ac-5 + description: Keycloak is designed and recommended to be deployed in a stand-alone + BB cluster with TLS passthrough for OIDC/SAML integration. Controls are + inherited from istio via network policies, virtual services and gateway + configs. + - uuid: 28fba4bc-e1ae-4164-9673-6ed90d93a7c0 + control-id: ac-6 + description: Keycloak as an IDM / IAM provider supports least privilege through + user / group management (ABAC / RBAC) service offerings + - uuid: 2f8de149-d07f-4e8a-8baf-5bdbace0cf8d + control-id: ac-6.1 + description: Keycloak as an IDM / IAM provider supports least privilege through + user / group management (ABAC / RBAC) service offerings + - uuid: 5a04932c-05cf-489a-932c-cb31b9480b73 + control-id: ac-6.2 + description: Keycloak as an IDM / IAM provider supports least privilege through + user / group management (ABAC / RBAC) service offerings + - uuid: 337a9b7f-71d0-46ef-aaa2-af5367d9b371 + control-id: ac-6.5 + description: Keycloak as an IDM / IAM provider supports least privilege through + user / group management (ABAC / RBAC) service offerings + - uuid: 6de217bb-f767-4af0-b813-b54df9baf173 + control-id: ac-6.7 + description: Keycloak as an IDM / IAM provider supports least privilege through + user / group management (ABAC / RBAC) service offerings + - uuid: 59032e55-f51e-4a0d-9394-7474631005ec + control-id: ac-6.9 + description: Keycloak as an IDM / IAM provider supports least privilege through + user / group management (ABAC / RBAC) service offerings + - uuid: ad95419d-4506-48b0-a736-723724acea34 + control-id: ac-6.10 + description: Keycloak as an IDM / IAM provider supports least privilege through + user / group management (ABAC / RBAC) service offerings + - uuid: 16088314-7668-41a2-9ee1-a7128d6c209e + control-id: ac-7 + description: 'Keycloak has brute force protection which has three components: + max login failures, quick login check (time between failures) & minimum + quick login check wait (time user will be disabled when multiple login failures + are detected)' + - uuid: 35992922-7375-45fc-bac1-1a6b551a76b9 + control-id: ac-8 + description: Keycloak has a standard DOD login banner see https://login.dso.mil + - uuid: 2a99e48f-6631-4ff7-b955-b73caafdedac + control-id: ac-10 + description: Keycloak does not suffice this control natively; however, you + can implement a “only one session per user†behavior with an ```EventListenerProvider```. + On every LOGIN event, delete all the sessions of a user, except the current + one. + - uuid: 77c2aa64-ab6b-4508-b6f6-fcca929de9ab + control-id: ac-12 + description: Keycloak does not suffice this control natively; however, you + can implement a session behaviors with an ```EventListenerProvider```. + - uuid: 3b38e765-41f8-4ea6-90dc-b4a1845b62cc + control-id: ac-14 + description: Keycloak has the ability to allow anonymous access to resource + if Client Access Type is set to public. + - uuid: 9bd24189-a9f7-4ddb-98fb-ba259b46b459 + control-id: ac-17.1 + description: Keycloak manages remote access to other applications through + IAM. + - uuid: 3e901895-d5da-48a0-8317-56b456371243 + control-id: ac-17.2 + description: Through EventListeners Keycloak can either ship logs to a SIEM + which could alert on remote session events, or with custom SPIs Keycloak + can perform an action directly on events. A VPN client would need to use + Keycloak as an SSO to generate these events. + - uuid: 66bc3835-8369-48ec-b54f-ca5ca034e2fd + control-id: ac-17.3 + description: Keycloak can restrict access to control points through IAM, but + a VPN solution like Appgate would be better suited working with Keycloak. + - uuid: f6e0f2a4-c729-4335-97f4-b16fb49d27f9 + control-id: ac-17.4 + description: Keycloak can support a VPN or other remote management system + as its IAM to support remote access control. + - uuid: 6a948220-d3ef-4357-989a-38e25f27eb3f + control-id: au-2 + description: Keycloak captures user and admin events and can ship them out + to a logging server for analysis or trigger an action on specific event + via customizable EventListeners. + - uuid: 4b4d19b0-b8e1-4fdd-b57b-448f4e163342 + control-id: au-3 + description: Keycloak events contain what, when, where, source, and objects/entities + for policy violations. + - uuid: 35b33698-d3c5-496e-9cb4-4524c63e2fac + control-id: au-3.1 + description: Keycloak event logs include Time, Event Type, Details (Client, + User, IP Address). Events are shipped to logging. + - uuid: ab565bfa-78a5-43e6-98cc-ba801a16b980 + control-id: au-4 + description: Keycloak events can be both saved to database and shipped to + logging server. Both systems are external to Keycloaks application server. + - uuid: 24b14c71-b4bd-402f-aba6-80056e1b6fec + control-id: au-7 + description: Keycloak provides audit records for compliance that qualify for + this control. + - uuid: e528b2ec-6895-432d-acf1-b33e0f8455f5 + control-id: au-7.1 + description: Within Keycloak records, sorting and searching are supported. + - uuid: ed7026d7-4257-44e6-919c-73e5f8a86be5 + control-id: au-8 + description: Keycloak saves timestamps in event logs + - uuid: 92b5e2c1-cb7c-4f38-ba5b-22b617b15020 + control-id: au-9 + description: Keycloak provides RBAC to restrict management of logs. + - uuid: 71c0d1c7-f9a5-4439-829b-8976749481eb + control-id: au-9.4 + description: Keycloak provides RBAC to restrict management of logs. + - uuid: 0b7b466e-e33c-4fa0-8979-a82da5fadc32 + control-id: ia-2 + description: Keycloak supports control through its IAM/SSO service. + - uuid: ff98831e-de87-4f0d-b42f-3af08a6caff6 + control-id: ia-2.1 + description: Keycloak supports MFA using mobile and x509 mTLS for both privileged + and non-privileged account management. + - uuid: e0fbd222-d6ae-4729-a262-7c795dd6a628 + control-id: ia-2.2 + description: Keycloak supports MFA using mobile and x509 mTLS for both privileged + and non-privileged account management. + - uuid: 441d2bbd-b7ee-46e9-8110-f0fda67a2c90 + control-id: ia-2.5 + description: Keycloak provides build-in functionality to support control. + - uuid: 5c163729-a954-43ca-a035-6040b0526ccd + control-id: ia-2.12 + description: Keycloak supports PIV credentials + - uuid: 084779e8-542d-4def-936b-69fd1fb7f266 + control-id: ia-3 + description: Keycloak provides built-in functionality to support control. + - uuid: 7a4c2837-a205-4b9c-b850-a8afec580275 + control-id: ia-4 + description: Keycloak provides built-in functionality to support control. + - uuid: ce397926-ec86-491c-82f6-db7e2e164a0d + control-id: ia-4.4 + description: Keycloak provides built-in functionality to support control. + - uuid: 7cee87f8-165f-4631-96f5-b2876df0e88a + control-id: ia-5.1 + description: Keycloak provides password-policies to support control. https://github.com/keycloak/keycloak-documentation/blob/main/server_admin/topics/authentication/password-policies.adoc + - uuid: 56d5209f-e279-4f67-b6e9-9a814695dda9 + control-id: ia-5.2 + description: Keycloak supports OCSP checking, and truststore/chain validation + for x509 PKI access. + - uuid: 8d858e85-710e-46aa-b6fd-98013480c2b6 + control-id: ia-8.1 + description: Keycloak supports authenicating non-orgaizational users through + supporting mTLS signed by external certificate authorities. + - uuid: c2976939-842a-4efc-afd3-11dc9892fb86 + control-id: ia-11 + description: Keycloak supports OIDC/SAML which support expiration dates in + tokens/assertions. + back-matter: + resources: + - uuid: C322D234-BD2A-4332-B8A9-54D45E7148B8 + title: Big Bang + rlinks: + - href: https://repo1.dso.mil/big-bang/bigbang diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000000000000000000000000000000000000..e38dfedd97f2e91b338ebec51c3da8954733f4e8 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,2037 @@ +{ + "name": "bigbang", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "devDependencies": { + "cypress": "^13.4.0" + } + }, + "node_modules/@colors/colors": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", + "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", + "dev": true, + "optional": true, + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/@cypress/request": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@cypress/request/-/request-3.0.1.tgz", + "integrity": "sha512-TWivJlJi8ZDx2wGOw1dbLuHJKUYX7bWySw377nlnGOW3hP9/MUKIsEdXT/YngWxVdgNCHRBmFlBipE+5/2ZZlQ==", + "dev": true, + "dependencies": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "http-signature": "~1.3.6", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "performance-now": "^2.1.0", + "qs": "6.10.4", + "safe-buffer": "^5.1.2", + "tough-cookie": "^4.1.3", + "tunnel-agent": "^0.6.0", + "uuid": "^8.3.2" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@cypress/xvfb": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@cypress/xvfb/-/xvfb-1.2.4.tgz", + "integrity": "sha512-skbBzPggOVYCbnGgV+0dmBdW/s77ZkAOXIC1knS8NagwDjBrNC1LuXtQJeiN6l+m7lzmHtaoUw/ctJKdqkG57Q==", + "dev": true, + "dependencies": { + "debug": "^3.1.0", + "lodash.once": "^4.1.1" + } + }, + "node_modules/@cypress/xvfb/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/@types/node": { + "version": "18.18.8", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.18.8.tgz", + "integrity": "sha512-OLGBaaK5V3VRBS1bAkMVP2/W9B+H8meUfl866OrMNQqt7wDgdpWPp5o6gmIc9pB+lIQHSq4ZL8ypeH1vPxcPaQ==", + "dev": true, + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/@types/sinonjs__fake-timers": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.1.tgz", + "integrity": "sha512-0kSuKjAS0TrGLJ0M/+8MaFkGsQhZpB6pxOmvS3K8FYI72K//YmdfoW9X2qPsAKh1mkwxGD5zib9s1FIFed6E8g==", + "dev": true + }, + "node_modules/@types/sizzle": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.5.tgz", + "integrity": "sha512-tAe4Q+OLFOA/AMD+0lq8ovp8t3ysxAOeaScnfNdZpUxaGl51ZMDEITxkvFl1STudQ58mz6gzVGl9VhMKhwRnZQ==", + "dev": true + }, + "node_modules/@types/yauzl": { + "version": "2.10.2", + "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.2.tgz", + "integrity": "sha512-Km7XAtUIduROw7QPgvcft0lIupeG8a8rdKL8RiSyKvlE7dYY31fEn41HVuQsRFDuROA8tA4K2UVL+WdfFmErBA==", + "dev": true, + "optional": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dev": true, + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-colors": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", + "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/arch": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/arch/-/arch-2.2.0.tgz", + "integrity": "sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/asn1": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", + "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", + "dev": true, + "dependencies": { + "safer-buffer": "~2.1.0" + } + }, + "node_modules/assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", + "dev": true, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/async": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", + "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==", + "dev": true + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "dev": true + }, + "node_modules/at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "dev": true, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/aws4": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.12.0.tgz", + "integrity": "sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg==", + "dev": true + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", + "dev": true, + "dependencies": { + "tweetnacl": "^0.14.3" + } + }, + "node_modules/blob-util": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/blob-util/-/blob-util-2.0.2.tgz", + "integrity": "sha512-T7JQa+zsXXEa6/8ZhHcQEW1UFfVM49Ts65uBkFL6fz2QmrElqmbajIDJvuA0tEhRe5eIjpV9ZF+0RfZR9voJFQ==", + "dev": true + }, + "node_modules/bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "dev": true + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/cachedir": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/cachedir/-/cachedir-2.4.0.tgz", + "integrity": "sha512-9EtFOZR8g22CL7BWjJ9BUx1+A/djkofnyW3aOXZORNW2kxoUpx2h+uN2cOqwPmFhnpVmxg+KW2OjOSgChTEvsQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/call-bind": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz", + "integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.1", + "set-function-length": "^1.1.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", + "dev": true + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chalk/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/check-more-types": { + "version": "2.24.0", + "resolved": "https://registry.npmjs.org/check-more-types/-/check-more-types-2.24.0.tgz", + "integrity": "sha512-Pj779qHxV2tuapviy1bSZNEL1maXr13bPYpsvSDB68HlYcYuhlDrmGd63i0JHMCLKzc7rUSNIrpdJlhVlNwrxA==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/ci-info": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "engines": { + "node": ">=8" + } + }, + "node_modules/clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "dependencies": { + "restore-cursor": "^3.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-table3": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.3.tgz", + "integrity": "sha512-w5Jac5SykAeZJKntOxJCrm63Eg5/4dhMWIcuTbo9rpE+brgaSZo0RuNJZeOyMgsUdhDeojvgyQLmjI+K50ZGyg==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0" + }, + "engines": { + "node": "10.* || >= 12.*" + }, + "optionalDependencies": { + "@colors/colors": "1.5.0" + } + }, + "node_modules/cli-truncate": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz", + "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==", + "dev": true, + "dependencies": { + "slice-ansi": "^3.0.0", + "string-width": "^4.2.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/colorette": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", + "dev": true + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/commander": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", + "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/common-tags": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.2.tgz", + "integrity": "sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==", + "dev": true, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "node_modules/core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", + "dev": true + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/cypress": { + "version": "13.4.0", + "resolved": "https://registry.npmjs.org/cypress/-/cypress-13.4.0.tgz", + "integrity": "sha512-KeWNC9xSHG/ewZURVbaQsBQg2mOKw4XhjJZFKjWbEjgZCdxpPXLpJnfq5Jns1Gvnjp6AlnIfpZfWFlDgVKXdWQ==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "@cypress/request": "^3.0.0", + "@cypress/xvfb": "^1.2.4", + "@types/node": "^18.17.5", + "@types/sinonjs__fake-timers": "8.1.1", + "@types/sizzle": "^2.3.2", + "arch": "^2.2.0", + "blob-util": "^2.0.2", + "bluebird": "^3.7.2", + "buffer": "^5.6.0", + "cachedir": "^2.3.0", + "chalk": "^4.1.0", + "check-more-types": "^2.24.0", + "cli-cursor": "^3.1.0", + "cli-table3": "~0.6.1", + "commander": "^6.2.1", + "common-tags": "^1.8.0", + "dayjs": "^1.10.4", + "debug": "^4.3.4", + "enquirer": "^2.3.6", + "eventemitter2": "6.4.7", + "execa": "4.1.0", + "executable": "^4.1.1", + "extract-zip": "2.0.1", + "figures": "^3.2.0", + "fs-extra": "^9.1.0", + "getos": "^3.2.1", + "is-ci": "^3.0.0", + "is-installed-globally": "~0.4.0", + "lazy-ass": "^1.6.0", + "listr2": "^3.8.3", + "lodash": "^4.17.21", + "log-symbols": "^4.0.0", + "minimist": "^1.2.8", + "ospath": "^1.2.2", + "pretty-bytes": "^5.6.0", + "process": "^0.11.10", + "proxy-from-env": "1.0.0", + "request-progress": "^3.0.0", + "semver": "^7.5.3", + "supports-color": "^8.1.1", + "tmp": "~0.2.1", + "untildify": "^4.0.0", + "yauzl": "^2.10.0" + }, + "bin": { + "cypress": "bin/cypress" + }, + "engines": { + "node": "^16.0.0 || ^18.0.0 || >=20.0.0" + } + }, + "node_modules/dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", + "dev": true, + "dependencies": { + "assert-plus": "^1.0.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/dayjs": { + "version": "1.11.10", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.10.tgz", + "integrity": "sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==", + "dev": true + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/define-data-property": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz", + "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.1", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", + "dev": true, + "dependencies": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/enquirer": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz", + "integrity": "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==", + "dev": true, + "dependencies": { + "ansi-colors": "^4.1.1", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/eventemitter2": { + "version": "6.4.7", + "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.7.tgz", + "integrity": "sha512-tYUSVOGeQPKt/eC1ABfhHy5Xd96N3oIijJvN3O9+TsC28T5V9yX9oEfEK5faP0EFSNVOG97qtAS68GBrQB2hDg==", + "dev": true + }, + "node_modules/execa": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz", + "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.0", + "get-stream": "^5.0.0", + "human-signals": "^1.1.1", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.0", + "onetime": "^5.1.0", + "signal-exit": "^3.0.2", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/executable": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/executable/-/executable-4.1.1.tgz", + "integrity": "sha512-8iA79xD3uAch729dUG8xaaBBFGaEa0wdD2VkYLFHwlqosEj/jT66AzcreRDSgV7ehnNLBW2WR5jIXwGKjVdTLg==", + "dev": true, + "dependencies": { + "pify": "^2.2.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, + "node_modules/extract-zip": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", + "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "get-stream": "^5.1.0", + "yauzl": "^2.10.0" + }, + "bin": { + "extract-zip": "cli.js" + }, + "engines": { + "node": ">= 10.17.0" + }, + "optionalDependencies": { + "@types/yauzl": "^2.9.1" + } + }, + "node_modules/extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==", + "dev": true, + "engines": [ + "node >=0.6.0" + ] + }, + "node_modules/fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", + "dev": true, + "dependencies": { + "pend": "~1.2.0" + } + }, + "node_modules/figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "dev": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" + } + }, + "node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dev": true, + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz", + "integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/getos": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/getos/-/getos-3.2.1.tgz", + "integrity": "sha512-U56CfOK17OKgTVqozZjUKNdkfEv6jk5WISBJ8SHoagjE6L69zOwl3Z+O8myjY9MEW3i2HPWQBt/LTbCgcC973Q==", + "dev": true, + "dependencies": { + "async": "^3.2.0" + } + }, + "node_modules/getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", + "dev": true, + "dependencies": { + "assert-plus": "^1.0.0" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/global-dirs": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.1.tgz", + "integrity": "sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA==", + "dev": true, + "dependencies": { + "ini": "2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz", + "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", + "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", + "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/http-signature": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.3.6.tgz", + "integrity": "sha512-3adrsD6zqo4GsTqtO7FyrejHNv+NgiIfAfv68+jVlFmSr9OGy7zrxONceFRLKvnnZA5jbxQBX1u9PpB6Wi32Gw==", + "dev": true, + "dependencies": { + "assert-plus": "^1.0.0", + "jsprim": "^2.0.2", + "sshpk": "^1.14.1" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/human-signals": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", + "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", + "dev": true, + "engines": { + "node": ">=8.12.0" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/ini": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz", + "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/is-ci": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.1.tgz", + "integrity": "sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==", + "dev": true, + "dependencies": { + "ci-info": "^3.2.0" + }, + "bin": { + "is-ci": "bin.js" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-installed-globally": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz", + "integrity": "sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==", + "dev": true, + "dependencies": { + "global-dirs": "^3.0.0", + "is-path-inside": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", + "dev": true + }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==", + "dev": true + }, + "node_modules/jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", + "dev": true + }, + "node_modules/json-schema": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", + "dev": true + }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", + "dev": true + }, + "node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jsprim": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-2.0.2.tgz", + "integrity": "sha512-gqXddjPqQ6G40VdnI6T6yObEC+pDNvyP95wdQhkWkg7crHH3km5qP1FsOXEkzEQwnz6gz5qGTn1c2Y52wP3OyQ==", + "dev": true, + "engines": [ + "node >=0.6.0" + ], + "dependencies": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.4.0", + "verror": "1.10.0" + } + }, + "node_modules/lazy-ass": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/lazy-ass/-/lazy-ass-1.6.0.tgz", + "integrity": "sha512-cc8oEVoctTvsFZ/Oje/kGnHbpWHYBe8IAJe4C0QNc3t8uM/0Y8+erSz/7Y1ALuXTEZTMvxXwO6YbX1ey3ujiZw==", + "dev": true, + "engines": { + "node": "> 0.8" + } + }, + "node_modules/listr2": { + "version": "3.14.0", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-3.14.0.tgz", + "integrity": "sha512-TyWI8G99GX9GjE54cJ+RrNMcIFBfwMPxc3XTFiAYGN4s10hWROGtOg7+O6u6LE3mNkyld7RSLE6nrKBvTfcs3g==", + "dev": true, + "dependencies": { + "cli-truncate": "^2.1.0", + "colorette": "^2.0.16", + "log-update": "^4.0.0", + "p-map": "^4.0.0", + "rfdc": "^1.3.0", + "rxjs": "^7.5.1", + "through": "^2.3.8", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "enquirer": ">= 2.3.0 < 3" + }, + "peerDependenciesMeta": { + "enquirer": { + "optional": true + } + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "node_modules/lodash.once": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==", + "dev": true + }, + "node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz", + "integrity": "sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==", + "dev": true, + "dependencies": { + "ansi-escapes": "^4.3.0", + "cli-cursor": "^3.1.0", + "slice-ansi": "^4.0.0", + "wrap-ansi": "^6.2.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/log-update/node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/object-inspect": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ospath": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/ospath/-/ospath-1.2.2.tgz", + "integrity": "sha512-o6E5qJV5zkAbIDNhGSIlyOhScKXgQrSRMilfph0clDfM0nEnBOlKlH4sWDmG95BW/CvwNz0vmm7dJVtU2KlMiA==", + "dev": true + }, + "node_modules/p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "dev": true, + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", + "dev": true + }, + "node_modules/performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==", + "dev": true + }, + "node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pretty-bytes": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", + "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==", + "dev": true, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", + "dev": true, + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/proxy-from-env": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.0.0.tgz", + "integrity": "sha512-F2JHgJQ1iqwnHDcQjVBsq3n/uoaFL+iPW/eAeL7kVxy/2RrWaN4WroKjjvbsoRtv0ftelNyC01bjRhn/bhcf4A==", + "dev": true + }, + "node_modules/psl": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", + "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", + "dev": true + }, + "node_modules/pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/qs": { + "version": "6.10.4", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.4.tgz", + "integrity": "sha512-OQiU+C+Ds5qiH91qh/mg0w+8nwQuLjM4F4M/PbmhDOoYehPh+Fb0bDjtR1sOvy7YKxvj28Y/M0PhP5uVX0kB+g==", + "dev": true, + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/querystringify": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", + "dev": true + }, + "node_modules/request-progress": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/request-progress/-/request-progress-3.0.0.tgz", + "integrity": "sha512-MnWzEHHaxHO2iWiQuHrUPBi/1WeBf5PkxQqNyNvLl9VAYSdXkP8tQ3pBSeCPD+yw0v0Aq1zosWLz0BdeXpWwZg==", + "dev": true, + "dependencies": { + "throttleit": "^1.0.0" + } + }, + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", + "dev": true + }, + "node_modules/restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/rfdc": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz", + "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==", + "dev": true + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rxjs": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", + "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", + "dev": true, + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/set-function-length": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.1.1.tgz", + "integrity": "sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==", + "dev": true, + "dependencies": { + "define-data-property": "^1.1.1", + "get-intrinsic": "^1.2.1", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "node_modules/slice-ansi": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz", + "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/sshpk": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.18.0.tgz", + "integrity": "sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ==", + "dev": true, + "dependencies": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + }, + "bin": { + "sshpk-conv": "bin/sshpk-conv", + "sshpk-sign": "bin/sshpk-sign", + "sshpk-verify": "bin/sshpk-verify" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/throttleit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-1.0.0.tgz", + "integrity": "sha512-rkTVqu6IjfQ/6+uNuuc3sZek4CEYxTJom3IktzgdSxcZqdARuebbA/f4QmAxMQIxqq9ZLEUkSYqvuk1I6VKq4g==", + "dev": true + }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", + "dev": true + }, + "node_modules/tmp": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", + "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", + "dev": true, + "dependencies": { + "rimraf": "^3.0.0" + }, + "engines": { + "node": ">=8.17.0" + } + }, + "node_modules/tough-cookie": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.3.tgz", + "integrity": "sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==", + "dev": true, + "dependencies": { + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.2.0", + "url-parse": "^1.5.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tough-cookie/node_modules/universalify": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", + "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", + "dev": true, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/tslib": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", + "dev": true + }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", + "dev": true + }, + "node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true + }, + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/untildify": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz", + "integrity": "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/url-parse": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", + "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", + "dev": true, + "dependencies": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "dev": true, + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", + "dev": true, + "engines": [ + "node >=0.6.0" + ], + "dependencies": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", + "dev": true, + "dependencies": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000000000000000000000000000000000000..3421c37387972755cf2267c2a0b3131823340139 --- /dev/null +++ b/package.json @@ -0,0 +1,5 @@ +{ + "devDependencies": { + "cypress": "^13.4.0" + } +} diff --git a/renovate.json b/renovate.json new file mode 100644 index 0000000000000000000000000000000000000000..e3ba56bff58ab26fc3cadcef1bbb6b75120b7ca8 --- /dev/null +++ b/renovate.json @@ -0,0 +1,40 @@ +{ + "baseBranches": ["master"], + "configWarningReuseIssue": false, + "dependencyDashboard": true, + "dependencyDashboardHeader": "- [ ] If there are Flux updates: Update your Flux CLI to the latest version possible based on available IB images, then from the root of the bigbang repository, run `flux install --components source-controller,kustomize-controller,helm-controller,notification-controller --export > base/flux/gotk-components.yaml` to generate the latest manifests", + "dependencyDashboardTitle": "Renovate: Update Dependencies", + "draftPR": true, + "enabledManagers": ["helm-values","regex"], + "labels": ["renovate","kind::maintenance","kind::Tools & Automation"], + "packageRules": [ + { + "matchDatasources": ["docker"], + "groupName": "Ironbank", + "registryUrls": ["https://registry1.dso.mil"] + }, + { + "matchPackagePatterns": ["flux"], + "additionalBranchPrefix": "flux-", + "addLabels": ["flux"], + "groupName": "Flux" + } + ], + "regexManagers": [ + { + "fileMatch": ["^base/flux/kustomization\\.yaml"], + "matchStrings": [ + "newName\\S*:\\s*(?<depName>\\S+).*\n\\s+newTag:\\s*(?<currentValue>.+)" + ], + "datasourceTemplate": "docker" + }, + { + "fileMatch": ["^tests/images\\.txt$"], + "matchStrings": [ + "s*(?<depName>.+):(?<currentValue>.+)" + ], + "datasourceTemplate": "docker" + } + ], + "separateMajorMinor": false +} diff --git a/schema/.gitignore b/schema/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..25c8fdbaba62c31aacfa2307975b06fbfd017485 --- /dev/null +++ b/schema/.gitignore @@ -0,0 +1,2 @@ +node_modules +package-lock.json \ No newline at end of file diff --git a/schema/Makefile b/schema/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..e79f1265971ad1aea0dd008aa8f06af93d9a63c7 --- /dev/null +++ b/schema/Makefile @@ -0,0 +1,6 @@ +install: + npm install +test: install + npx bats schema.bats +refresh: + ./schema-refresh.sh diff --git a/schema/package.json b/schema/package.json new file mode 100644 index 0000000000000000000000000000000000000000..2799bb6415fd69fbea5d892f5a8a12182fbc5350 --- /dev/null +++ b/schema/package.json @@ -0,0 +1,7 @@ +{ + "name": "schema", + "dependencies": { + "bats": "^1.9.0", + "bats-assert": "^2.0.0" + } +} diff --git a/schema/schema-refresh.sh b/schema/schema-refresh.sh new file mode 100755 index 0000000000000000000000000000000000000000..93805000be6b39ef218aa06a2b91222562291541 --- /dev/null +++ b/schema/schema-refresh.sh @@ -0,0 +1,18 @@ +#!/bin/bash + +# Must have a running cluster with Flux CRDs installed +kubectl proxy --port 8080 & +proxy_pid=$! +sleep 5 + +VALUES_FILE="../chart/values.schema.json" + +# Fetch schema from Kube API for flux + postRenderers +POST_RENDERERS=$(curl http://localhost:8080/openapi/v3/apis/helm.toolkit.fluxcd.io/v2beta1 | jq '.components.schemas["io.fluxcd.toolkit.helm.v2beta1.HelmRelease"].properties.spec.properties' | jq '.postRenderers') +FLUX=$(curl http://localhost:8080/openapi/v3/apis/helm.toolkit.fluxcd.io/v2beta1 | jq '.components.schemas["io.fluxcd.toolkit.helm.v2beta1.HelmRelease"].properties.spec.properties' | jq 'del('.postRenderers', '.dependsOn', '.valuesFrom', '.targetNamespace', '.chart')') + +# Substitute existing values +jq --argjson subs "$POST_RENDERERS" '.["$defs"].postRenderers = $subs' $VALUES_FILE | sponge $VALUES_FILE +jq --argjson subs "$FLUX" '.["$defs"].flux = $subs' $VALUES_FILE | sponge $VALUES_FILE + +kill $proxy_pid \ No newline at end of file diff --git a/schema/schema.bats b/schema/schema.bats new file mode 100644 index 0000000000000000000000000000000000000000..df492f009f036071ab746dd96917f716c420286c --- /dev/null +++ b/schema/schema.bats @@ -0,0 +1,114 @@ +#!/usr/bin/env bats + +# Load the bats-assert library +load 'node_modules/bats-assert/load.bash' +load 'node_modules/bats-support/load.bash' + +BIGBANG_HOME=../ + +diag() { + echo "# $@" >&3 +} + +valid() { + TEST_DIR=test-values/$1/valid + + find $TEST_DIR -type f | while read file; do + diag "Testing $file" + run helm template $BIGBANG_HOME/chart --values=$file + assert_equal "$status" "0" + done +} + +invalid() { + TEST_DIR=test-values/$1/invalid + + find $TEST_DIR -type f | while read file; do + diag "Testing $file" + run helm template $BIGBANG_HOME/chart --values=$file + assert_equal "$status" "1" + done +} + +# Test basic schema validation +@test "helm template validate schema" { + run helm template $BIGBANG_HOME/chart + assert_equal "$status" "0" +} + +# Test basic schema validation failure +@test "helm template validate schema failure" { + run helm template $BIGBANG_HOME/chart --set=neuvector.sso.foo=true + assert_equal "$status" "1" +} + +# Test umbrella validation +@test "helm template validate umbrella schema" { + valid umbrella + invalid umbrella +} + +# Test git schema validation +@test "helm template validate schema git" { + valid git + invalid git +} + +# Test registryCredentials schema validation +@test "helm template validate schema registryCredentials" { + valid registry-credentials + invalid registry-credentials +} + +# Test basePackage git schema validation +@test "helm template validate basePackage schema" { + valid base-package + invalid base-package +} + +# Test basePackage git schema validation +@test "helm template validate git basePackage schema" { + valid base-package-git + invalid base-package-git +} + +# Test basePackage sso schema validation +@test "helm template validate sso schema" { + valid base-package-sso + invalid base-package-sso +} + +# Test basePackage helmRepo schema validation +@test "helm template validate helmRepo schema" { + valid base-package-helm-repo + invalid base-package-helm-repo +} + +# Test basePackage source type schema validation +@test "helm template validate source type schema" { + valid base-package-source-type + invalid base-package-source-type +} + +# Test basePackage source type schema validation +@test "helm template validate addons schema" { + valid addons + invalid addons +} + +# Ensure core packages cannot have extra keys +@test "helm template validate core package no extra keys" { + local PACKAGES=$(yq e '.[] | select(. | (has("git") or has("oci"))) | path | .[-1]' $BIGBANG_HOME/chart/values.yaml) + + for package in $PACKAGES; do + run helm template $BIGBANG_HOME/chart --set=$package.extra=key --values=$file + diag "Testing extra keys for core package $package" + assert_equal "$status" "1" + done +} + +# Test monitoring schema validation +@test "helm template validate monitoring schema" { + valid monitoring + invalid monitoring +} \ No newline at end of file diff --git a/schema/test-values/addons/invalid/values.yaml b/schema/test-values/addons/invalid/values.yaml new file mode 100644 index 0000000000000000000000000000000000000000..7d612f4660c4388c9d68356187fd63ce7e83d4ed --- /dev/null +++ b/schema/test-values/addons/invalid/values.yaml @@ -0,0 +1,6 @@ +addons: + gitlab: + sourceType: "git" + + git: + tag: null \ No newline at end of file diff --git a/schema/test-values/addons/valid/values.yaml b/schema/test-values/addons/valid/values.yaml new file mode 100644 index 0000000000000000000000000000000000000000..27131d7df60c46baa0007f5b73f3ea9b161c357c --- /dev/null +++ b/schema/test-values/addons/valid/values.yaml @@ -0,0 +1,3 @@ +addons: + gitlab: + extra: key \ No newline at end of file diff --git a/schema/test-values/base-package-git/invalid/commit-no-branch.yaml b/schema/test-values/base-package-git/invalid/commit-no-branch.yaml new file mode 100644 index 0000000000000000000000000000000000000000..7a5c36d4360496501fea6446e1b28091662186e3 --- /dev/null +++ b/schema/test-values/base-package-git/invalid/commit-no-branch.yaml @@ -0,0 +1,5 @@ +kiali: + git: + repo: https://repo1.dso.mil/big-bang/product/packages/kiali.git + path: "./chart" + commit: "1234" \ No newline at end of file diff --git a/schema/test-values/base-package-git/invalid/extra-key.yaml b/schema/test-values/base-package-git/invalid/extra-key.yaml new file mode 100644 index 0000000000000000000000000000000000000000..f2a54def92b8ec57ac5437c7d7b7c7a64b870932 --- /dev/null +++ b/schema/test-values/base-package-git/invalid/extra-key.yaml @@ -0,0 +1,6 @@ +kiali: + git: + repo: https://repo1.dso.mil/big-bang/product/packages/kiali.git + path: "./chart" + tag: "1.65.0-bb.0" + extra: "failure" \ No newline at end of file diff --git a/schema/test-values/base-package-git/invalid/semver-extra.yaml b/schema/test-values/base-package-git/invalid/semver-extra.yaml new file mode 100644 index 0000000000000000000000000000000000000000..ccf632a4bb40cb105be091056817990fd16b391b --- /dev/null +++ b/schema/test-values/base-package-git/invalid/semver-extra.yaml @@ -0,0 +1,7 @@ +kiali: + git: + repo: https://repo1.dso.mil/big-bang/product/packages/kiali.git + path: "./chart" + semver: "1.65.^" + branch: "foobar" + commit: "foo" \ No newline at end of file diff --git a/schema/test-values/base-package-git/invalid/tag-and-branch.yaml b/schema/test-values/base-package-git/invalid/tag-and-branch.yaml new file mode 100644 index 0000000000000000000000000000000000000000..6ecc4afe6bd1244f014970577203656edc0f107a --- /dev/null +++ b/schema/test-values/base-package-git/invalid/tag-and-branch.yaml @@ -0,0 +1,6 @@ +kiali: + git: + repo: https://repo1.dso.mil/big-bang/product/packages/kiali.git + path: "./chart" + tag: "1.65.0-bb.0" + branch: "extra" diff --git a/schema/test-values/base-package-git/valid/branch-no-tag.yaml b/schema/test-values/base-package-git/valid/branch-no-tag.yaml new file mode 100644 index 0000000000000000000000000000000000000000..2615b13a02228fc0e02854d55926b7777ca74920 --- /dev/null +++ b/schema/test-values/base-package-git/valid/branch-no-tag.yaml @@ -0,0 +1,13 @@ +kiali: + git: + repo: https://repo1.dso.mil/big-bang/product/packages/kiali.git + path: "./chart" + branch: "foo" + tag: null + +neuvector: + git: + repo: https://repo1.dso.mil/big-bang/product/packages/neuvector.git + path: "./chart" + branch: "foo" + tag: "" diff --git a/schema/test-values/base-package-git/valid/branch.yaml b/schema/test-values/base-package-git/valid/branch.yaml new file mode 100644 index 0000000000000000000000000000000000000000..a1cbb6ba1574de8d887edc72d3c6fa091849b018 --- /dev/null +++ b/schema/test-values/base-package-git/valid/branch.yaml @@ -0,0 +1,13 @@ +kiali: + git: + repo: https://repo1.dso.mil/big-bang/product/packages/kiali.git + path: "./chart" + tag: null + branch: branch + +neuvector: + git: + repo: https://repo1.dso.mil/big-bang/product/packages/neuvector.git + path: "./chart" + tag: "" + branch: branch diff --git a/schema/test-values/base-package-git/valid/commit-with-branch.yaml b/schema/test-values/base-package-git/valid/commit-with-branch.yaml new file mode 100644 index 0000000000000000000000000000000000000000..da6dd480d323e4375986620065a0a6d24111268c --- /dev/null +++ b/schema/test-values/base-package-git/valid/commit-with-branch.yaml @@ -0,0 +1,15 @@ +kiali: + git: + repo: https://repo1.dso.mil/big-bang/product/packages/kiali.git + path: "./chart" + commit: "1234" + branch: "foo" + tag: null + +neuvector: + git: + repo: https://repo1.dso.mil/big-bang/product/packages/neuvector.git + path: "./chart" + commit: "1234" + branch: "foo" + tag: "" \ No newline at end of file diff --git a/schema/test-values/base-package-git/valid/default.yaml b/schema/test-values/base-package-git/valid/default.yaml new file mode 100644 index 0000000000000000000000000000000000000000..54dc8d4b2ba4576d146b2ae22c28c0219fcb096b --- /dev/null +++ b/schema/test-values/base-package-git/valid/default.yaml @@ -0,0 +1,5 @@ +kiali: + git: + repo: https://repo1.dso.mil/big-bang/product/packages/kiali.git + path: "./chart" + tag: "1.65.0-bb.0" diff --git a/schema/test-values/base-package-git/valid/semver.yaml b/schema/test-values/base-package-git/valid/semver.yaml new file mode 100644 index 0000000000000000000000000000000000000000..79bc76ae072b38a7680611441d6ccadc10227294 --- /dev/null +++ b/schema/test-values/base-package-git/valid/semver.yaml @@ -0,0 +1,5 @@ +kiali: + git: + repo: https://repo1.dso.mil/big-bang/product/packages/kiali.git + path: "./chart" + semver: "1.65.^" \ No newline at end of file diff --git a/schema/test-values/base-package-helm-repo/invalid/oci-missing-extra.yaml b/schema/test-values/base-package-helm-repo/invalid/oci-missing-extra.yaml new file mode 100644 index 0000000000000000000000000000000000000000..7fd5c38003946af50fae390aca94ee0be27efa9f --- /dev/null +++ b/schema/test-values/base-package-helm-repo/invalid/oci-missing-extra.yaml @@ -0,0 +1,10 @@ +kiali: + enabled: true + + sourceType: "helmRepo" + + helmRepo: + repoName: null + chartName: "kiali" + tag: "1.65.0-bb.0" + extra: key \ No newline at end of file diff --git a/schema/test-values/base-package-helm-repo/invalid/oci-missing.yaml b/schema/test-values/base-package-helm-repo/invalid/oci-missing.yaml new file mode 100644 index 0000000000000000000000000000000000000000..3b745a14218ed3a2c3d71d04dee6694d71009027 --- /dev/null +++ b/schema/test-values/base-package-helm-repo/invalid/oci-missing.yaml @@ -0,0 +1,10 @@ +kiali: + # -- Toggle deployment of Kiali. + enabled: true + + sourceType: "helmRepo" + + helmRepo: + repoName: null + chartName: "kiali" + tag: "1.65.0-bb.0" \ No newline at end of file diff --git a/schema/test-values/base-package-helm-repo/valid/invalid-git-but-valid-helm-repo.yaml b/schema/test-values/base-package-helm-repo/valid/invalid-git-but-valid-helm-repo.yaml new file mode 100644 index 0000000000000000000000000000000000000000..5950aaa6ffd681d13722714eb31b778ff0f498ea --- /dev/null +++ b/schema/test-values/base-package-helm-repo/valid/invalid-git-but-valid-helm-repo.yaml @@ -0,0 +1,13 @@ +kiali: + sourceType: "helmRepo" + + helmRepo: + repoName: "registry1" + chartName: "kiali" + tag: "1.65.0-bb.0" + + git: + repo: https://repo1.dso.mil/big-bang/product/packages/kiali.git + path: "./chart" + tag: null + commit: "1234" \ No newline at end of file diff --git a/schema/test-values/base-package-helm-repo/valid/values.yaml b/schema/test-values/base-package-helm-repo/valid/values.yaml new file mode 100644 index 0000000000000000000000000000000000000000..a55c29d93bbbdfd02d62a9e9c347edd29107a17a --- /dev/null +++ b/schema/test-values/base-package-helm-repo/valid/values.yaml @@ -0,0 +1,9 @@ +kiali: + enabled: true + + sourceType: "helmRepo" + + helmRepo: + repoName: "repo" + chartName: "kiali" + tag: "1.65.0-bb.0" \ No newline at end of file diff --git a/schema/test-values/base-package-source-type/invalid/values-wrong-source-type-git.yaml b/schema/test-values/base-package-source-type/invalid/values-wrong-source-type-git.yaml new file mode 100644 index 0000000000000000000000000000000000000000..aff7cb69b167c9180f5c2ced113886bf69a3201f --- /dev/null +++ b/schema/test-values/base-package-source-type/invalid/values-wrong-source-type-git.yaml @@ -0,0 +1,12 @@ +kiali: + # -- Toggle deployment of Kiali. + enabled: true + + sourceType: "git" + + git: null + + helmRepo: + repoName: "registry1" + chartName: "kiali" + tag: "1.65.0-bb.0" \ No newline at end of file diff --git a/schema/test-values/base-package-source-type/invalid/values-wrong-source-type-oci.yaml b/schema/test-values/base-package-source-type/invalid/values-wrong-source-type-oci.yaml new file mode 100644 index 0000000000000000000000000000000000000000..7b7cf5fe5bc4eb990c36a9af6525c91c9938c281 --- /dev/null +++ b/schema/test-values/base-package-source-type/invalid/values-wrong-source-type-oci.yaml @@ -0,0 +1,12 @@ +kiali: + # -- Toggle deployment of Kiali. + enabled: true + + sourceType: "helmRepo" + + git: + repo: https://repo1.dso.mil/big-bang/product/packages/kiali.git + path: "./chart" + tag: "1.65.0-bb.0" + + helmRepo: null \ No newline at end of file diff --git a/schema/test-values/base-package-source-type/invalid/values.yaml b/schema/test-values/base-package-source-type/invalid/values.yaml new file mode 100644 index 0000000000000000000000000000000000000000..45457f2fcdddb75c86b28f14133108a394aac243 --- /dev/null +++ b/schema/test-values/base-package-source-type/invalid/values.yaml @@ -0,0 +1,2 @@ +kiali: + sourceType: "foo" diff --git a/schema/test-values/base-package-source-type/valid/values-git.yaml b/schema/test-values/base-package-source-type/valid/values-git.yaml new file mode 100644 index 0000000000000000000000000000000000000000..15cdc3f67584cd34613698820d4f3c2361793bf3 --- /dev/null +++ b/schema/test-values/base-package-source-type/valid/values-git.yaml @@ -0,0 +1,12 @@ +kiali: + # -- Toggle deployment of Kiali. + enabled: true + + sourceType: "git" + + git: + repo: https://repo1.dso.mil/big-bang/product/packages/kiali.git + path: "./chart" + tag: "1.65.0-bb.0" + + helmRepo: null \ No newline at end of file diff --git a/schema/test-values/base-package-source-type/valid/values-helm-repo.yaml b/schema/test-values/base-package-source-type/valid/values-helm-repo.yaml new file mode 100644 index 0000000000000000000000000000000000000000..ccc469ee8e5c21b3771bcb03b3ab81e6c27f3634 --- /dev/null +++ b/schema/test-values/base-package-source-type/valid/values-helm-repo.yaml @@ -0,0 +1,12 @@ +kiali: + # -- Toggle deployment of Kiali. + enabled: true + + sourceType: "helmRepo" + + git: null + + helmRepo: + repoName: "registry1" + chartName: "kiali" + tag: "1.65.0-bb.0" \ No newline at end of file diff --git a/schema/test-values/base-package-sso/invalid/extra-key-monitoring.yaml b/schema/test-values/base-package-sso/invalid/extra-key-monitoring.yaml new file mode 100644 index 0000000000000000000000000000000000000000..0f0e4f971744f0130957fced11fa6eecd8e0b2bf --- /dev/null +++ b/schema/test-values/base-package-sso/invalid/extra-key-monitoring.yaml @@ -0,0 +1,3 @@ +monitoring: + sso: + extra: key diff --git a/schema/test-values/base-package-sso/invalid/extra-key-twistlock.yaml b/schema/test-values/base-package-sso/invalid/extra-key-twistlock.yaml new file mode 100644 index 0000000000000000000000000000000000000000..9661ce8994c6a179f9a85a61f532f6da8b488385 --- /dev/null +++ b/schema/test-values/base-package-sso/invalid/extra-key-twistlock.yaml @@ -0,0 +1,6 @@ +twistlock: + sso: + enabled: true + client_id: "id" + provider_type: "string" + extra: "key" \ No newline at end of file diff --git a/schema/test-values/base-package-sso/invalid/extra-key.yaml b/schema/test-values/base-package-sso/invalid/extra-key.yaml new file mode 100644 index 0000000000000000000000000000000000000000..7f8bcbc6b34a8962f646c97145b096261626b342 --- /dev/null +++ b/schema/test-values/base-package-sso/invalid/extra-key.yaml @@ -0,0 +1,12 @@ +jaeger: + sso: + enabled: true + client_id: "id" + client_secret: "1234" + +neuvector: + sso: + enabled: true + client_id: "id" + client_secret: "string" + extra: "key" \ No newline at end of file diff --git a/schema/test-values/base-package-sso/valid/extended.yaml b/schema/test-values/base-package-sso/valid/extended.yaml new file mode 100644 index 0000000000000000000000000000000000000000..ad0bdf0ca402e86b80dc4a33d2e41a1c0e9d3210 --- /dev/null +++ b/schema/test-values/base-package-sso/valid/extended.yaml @@ -0,0 +1,12 @@ + sso: + enabled: true + client_id: client + client_secret: secret + default_role: admin + issuer: https://login.dso.mil/auth/realms/baby-yoda + group_claim: roles + group_mapped_roles: + - group: admin + global_role: admin + - group: reader + global_role: reader \ No newline at end of file diff --git a/schema/test-values/base-package-sso/valid/sso.yaml b/schema/test-values/base-package-sso/valid/sso.yaml new file mode 100644 index 0000000000000000000000000000000000000000..42581d717229fe5f13a0814e8fd8e6556c10b8ee --- /dev/null +++ b/schema/test-values/base-package-sso/valid/sso.yaml @@ -0,0 +1,11 @@ +jaeger: + sso: + enabled: true + client_id: "id" + client_secret: "1234" + +neuvector: + sso: + enabled: true + client_id: "id" + client_secret: "string" \ No newline at end of file diff --git a/schema/test-values/base-package/invalid/extra-istio-operator.yaml b/schema/test-values/base-package/invalid/extra-istio-operator.yaml new file mode 100644 index 0000000000000000000000000000000000000000..16c560259102c5c18cff35942e369e4e886489a0 --- /dev/null +++ b/schema/test-values/base-package/invalid/extra-istio-operator.yaml @@ -0,0 +1,2 @@ +istioOperator: + extra: field \ No newline at end of file diff --git a/schema/test-values/base-package/invalid/extra.yaml b/schema/test-values/base-package/invalid/extra.yaml new file mode 100644 index 0000000000000000000000000000000000000000..2929f0be50a20f6ef3d9dcdec0bf0206d8d51b47 --- /dev/null +++ b/schema/test-values/base-package/invalid/extra.yaml @@ -0,0 +1,2 @@ +kiali: + extra: field \ No newline at end of file diff --git a/schema/test-values/base-package/invalid/neuvector-invalid-injection.yaml b/schema/test-values/base-package/invalid/neuvector-invalid-injection.yaml new file mode 100644 index 0000000000000000000000000000000000000000..ed6298bad5cc272492d4ec277beed1d0519aad45 --- /dev/null +++ b/schema/test-values/base-package/invalid/neuvector-invalid-injection.yaml @@ -0,0 +1,4 @@ +neuvector: + enabled: true + istio: + injection: foo \ No newline at end of file diff --git a/schema/test-values/base-package/valid/base.yaml b/schema/test-values/base-package/valid/base.yaml new file mode 100644 index 0000000000000000000000000000000000000000..81684b690f81c60c0f822eeb4139873bc02570e2 --- /dev/null +++ b/schema/test-values/base-package/valid/base.yaml @@ -0,0 +1,30 @@ +kiali: + # -- Toggle deployment of Kiali. + enabled: true + git: + repo: https://repo1.dso.mil/big-bang/product/packages/kiali.git + path: "./chart" + tag: "1.65.0-bb.0" + + # -- Flux reconciliation overrides specifically for the Kiali Package + flux: {} + + # -- Redirect the package ingress to a specific Istio Gateway (listed in `istio.gateways`). The default is "public". + ingress: + gateway: "" + + sso: + # -- Toggle SSO for Kiali on and off + enabled: false + + # -- OIDC Client ID to use for Kiali + client_id: "" + + # -- OIDC Client Secret to use for Kiali + client_secret: "" + + # -- Values to pass through to Kiali chart: https://repo1.dso.mil/big-bang/product/packages/kiali + values: {} + + # -- Post Renderers. See docs/postrenders.md + postRenderers: [] \ No newline at end of file diff --git a/schema/test-values/base-package/valid/neuvector-injection.yaml b/schema/test-values/base-package/valid/neuvector-injection.yaml new file mode 100644 index 0000000000000000000000000000000000000000..fcfe49e4958894c4acf2604924da835d0d624bf8 --- /dev/null +++ b/schema/test-values/base-package/valid/neuvector-injection.yaml @@ -0,0 +1,4 @@ +neuvector: + enabled: true + istio: + injection: "enabled" \ No newline at end of file diff --git a/schema/test-values/git/invalid/invalid1.yaml b/schema/test-values/git/invalid/invalid1.yaml new file mode 100644 index 0000000000000000000000000000000000000000..ac2fca54db11b22bb7ca45b09e108b852d5d74f1 --- /dev/null +++ b/schema/test-values/git/invalid/invalid1.yaml @@ -0,0 +1,4 @@ +git: + credentials: + username: "p1" + password: null diff --git a/schema/test-values/git/valid/base.yaml b/schema/test-values/git/valid/base.yaml new file mode 100644 index 0000000000000000000000000000000000000000..dada025d2cabaa99f8fe9eb52da5ecad4823294f --- /dev/null +++ b/schema/test-values/git/valid/base.yaml @@ -0,0 +1,16 @@ +# 3. ssh credentials (privateKey/publicKey/knownHosts) +git: + # -- Existing secret to use for git credentials, must be in the appropriate format: https://toolkit.fluxcd.io/components/source/gitrepositories/#https-authentication + existingSecret: "" + + # -- Chart created secrets with user defined values + credentials: + # -- HTTP git credentials, both username and password must be provided + username: "" + password: "" + # -- HTTPS certificate authority file. Required for any repo with a self signed certificate + caFile: "" + # -- SSH git credentials, privateKey, publicKey, and knownHosts must be provided + privateKey: "" + publicKey: "" + knownHosts: "" \ No newline at end of file diff --git a/schema/test-values/git/valid/pass1.yaml b/schema/test-values/git/valid/pass1.yaml new file mode 100644 index 0000000000000000000000000000000000000000..46c9ee37f94fecdec407cfc5dd198c478219f4fd --- /dev/null +++ b/schema/test-values/git/valid/pass1.yaml @@ -0,0 +1,2 @@ +git: + existingSecret: "foo" \ No newline at end of file diff --git a/schema/test-values/git/valid/pass2.yaml b/schema/test-values/git/valid/pass2.yaml new file mode 100644 index 0000000000000000000000000000000000000000..c96561f15a1d35fd87b2cbfd4c3a0d1d56112a13 --- /dev/null +++ b/schema/test-values/git/valid/pass2.yaml @@ -0,0 +1,5 @@ +git: + credentials: + privateKey: "key" + publicKey: "key" + knownHosts: "host" \ No newline at end of file diff --git a/schema/test-values/git/valid/pass3.yaml b/schema/test-values/git/valid/pass3.yaml new file mode 100644 index 0000000000000000000000000000000000000000..fff64c1cc4ce701e5397ccbfdcb52461113570a0 --- /dev/null +++ b/schema/test-values/git/valid/pass3.yaml @@ -0,0 +1,5 @@ +git: + credentials: + username: "p1" + password: "pass" + caFile: "" \ No newline at end of file diff --git a/schema/test-values/monitoring/invalid/sso.yaml b/schema/test-values/monitoring/invalid/sso.yaml new file mode 100644 index 0000000000000000000000000000000000000000..726267573f1f7a6bfbe28a48e0b308b6e716f7c8 --- /dev/null +++ b/schema/test-values/monitoring/invalid/sso.yaml @@ -0,0 +1,4 @@ +monitoring: + sso: + grafana: + foo: bar diff --git a/schema/test-values/monitoring/valid/sso.yaml b/schema/test-values/monitoring/valid/sso.yaml new file mode 100644 index 0000000000000000000000000000000000000000..3c3f53ba459dcbb0a70e85911c6980a4e79b9d03 --- /dev/null +++ b/schema/test-values/monitoring/valid/sso.yaml @@ -0,0 +1,16 @@ +monitoring: + sso: + grafana: + client_id: grafana + client_secret: secret + scopes: Grafana + allow_sign_up: true + role_attribute_path: Viewer + auth_url: https://login.dso.mil/auth/realms/baby-yoda/protocol/openid-connect/auth + token_url: https://login.dso.mil/auth/realms/baby-yoda/protocol/openid-connect/token + api_url: https://login.dso.mil/auth/realms/baby-yoda/protocol/openid-connect/userinfo + allowed_domains: foo.com bar.com + tls_client_ca: "" + tls_skip_verify_insecure: false + tls_client_cert: "" + tls_client_key: "" \ No newline at end of file diff --git a/schema/test-values/registry-credentials/invalid/invalid1.yaml b/schema/test-values/registry-credentials/invalid/invalid1.yaml new file mode 100644 index 0000000000000000000000000000000000000000..cedff7c55e7c565f6365cda0f17a10307199eabe --- /dev/null +++ b/schema/test-values/registry-credentials/invalid/invalid1.yaml @@ -0,0 +1,5 @@ +registryCredentials: + - registry: registry1.dso.mil + username: "" + password: null + email: "" \ No newline at end of file diff --git a/schema/test-values/registry-credentials/valid/complicated-values.yaml b/schema/test-values/registry-credentials/valid/complicated-values.yaml new file mode 100644 index 0000000000000000000000000000000000000000..f8a494bd72139ffa9bfe85e79760d406878aad9e --- /dev/null +++ b/schema/test-values/registry-credentials/valid/complicated-values.yaml @@ -0,0 +1,5 @@ +registryCredentials: + - registry: registry1.dso.mil + username: "" + password: "" + email: "" \ No newline at end of file diff --git a/schema/test-values/umbrella/invalid/extra.yaml b/schema/test-values/umbrella/invalid/extra.yaml new file mode 100644 index 0000000000000000000000000000000000000000..7daacd5db8d36bc6df962d1d01cb98d8713fe5c4 --- /dev/null +++ b/schema/test-values/umbrella/invalid/extra.yaml @@ -0,0 +1 @@ +foo: bar \ No newline at end of file diff --git a/schema/test-values/umbrella/valid/values.yaml b/schema/test-values/umbrella/valid/values.yaml new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/scripts/install_flux.sh b/scripts/install_flux.sh new file mode 100755 index 0000000000000000000000000000000000000000..e00d7cd42bd82ba0a2be1cf58e1354217b392d08 --- /dev/null +++ b/scripts/install_flux.sh @@ -0,0 +1,196 @@ +#!/usr/bin/env bash + +set -e +trap 'echo ⌠exit at ${0}:${LINENO}, command was: ${BASH_COMMAND} 1>&2' ERR + +# +# global defaults +# +FLUX_SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)" +FLUX_KUSTOMIZATION="${FLUX_SCRIPT_DIR}/../base/flux" +REGISTRY_URL=registry1.dso.mil +FLUX_SECRET=private-registry +WAIT_TIMEOUT=300 + +# +# helper functions +# + +# script help message +function help { + cat <<EOF +usage: $(basename "$0") <arguments> +-h|--help - print this help message and exit +-r|--registry-url - (optional, default: registry1.dso.mil) registry url to use for flux installation +-s|--use-existing-secret - (optional) use existing private-registry secret +-u|--registry-username - (required) registry username to use for flux installation +-p|--registry-password - (optional, prompted if no existing secret) registry password to use for flux installation +-w|--wait-timeout - (optional, default: 120) how long to wait; in seconds, for each key flux resource component +EOF +} + +# check for existing pull secret +function check_secrets { + if kubectl get secrets/"$FLUX_SECRET" -n flux-system >/dev/null 2>&1; then + #the secret exists + FLUX_SECRET_EXISTS=0 + else + #the secret does not exist + FLUX_SECRET_EXISTS=1 + fi +} + +# securely prompt for the Registry1 password +function get_password { + until [[ $REGISTRY_PASSWORD ]]; do + read -s -p "Please enter your Registry1 password: " REGISTRY_PASSWORD + done +} + +# prompt for the Registry1 username +function get_username { + until [[ $REGISTRY_USERNAME ]]; do + read -p "Please enter your Registry1 username: " REGISTRY_USERNAME + done +} +# +# cli parsing +# + +PARAMS="" +while (("$#")); do + case "$1" in + # registry username required argument + -u | --registry-username) + if [ -n "$2" ] && [ "${2:0:1}" != "-" ]; then + REGISTRY_USERNAME=$2 + shift 2 + else + get_username + shift + fi + ;; + # registry password required argument + -p | --registry-password) + if [ -n "$2" ] && [ "${2:0:1}" != "-" ]; then + REGISTRY_PASSWORD=$2 + shift 2 + else + get_password + shift + fi + ;; + # registry email required argument + -e | --registry-email) + if [ -n "$2" ] && [ "${2:0:1}" != "-" ]; then + REGISTRY_EMAIL=$2 + shift 2 + else + echo "Error: Argument for $1 is missing" >&2 + help + exit 1 + fi + ;; + # registry url optional argument + -r | --registry-url) + if [ -n "$2" ] && [ "${2:0:1}" != "-" ]; then + REGISTRY_URL=$2 + shift 2 + else + echo "Error: Argument for $1 is missing" >&2 + help + exit 1 + fi + ;; + # wait timeout optional argument + -w | --wait-timeout) + if [ -n "$2" ] && [ "${2:0:1}" != "-" ]; then + WAIT_TIMEOUT=$2 + shift 2 + else + echo "Error: Argument for $1 is missing" >&2 + help + exit 1 + fi + ;; + # help flag + -h | --help) + help + exit 0 + ;; + # Check if private-registry secret exists + -s | --use-existing-secret) + check_secrets + shift + ;; + # unsupported flags + -* | --*=) + echo "Error: Unsupported flag $1" >&2 + help + exit 1 + ;; + # preserve positional arguments + *) + PARAMS="$PARAMS $1" + shift + ;; + esac +done + +# if secret doesn't exist, create it +if [ -z "$FLUX_SECRET_EXISTS" ] || [ "$FLUX_SECRET_EXISTS" -eq 1 ]; then + + # check required arguments + if [ -z "$REGISTRY_USERNAME" ]; then + get_username + fi + if [ -z "$REGISTRY_PASSWORD" ]; then + get_password + fi + + # debug print cli args + echo "REGISTRY_URL: $REGISTRY_URL" + echo "REGISTRY_USERNAME: $REGISTRY_USERNAME" + + echo "Creating flux-system namespace so that the docker-registry secret can be added first." + kubectl apply -f - <<EOF +apiVersion: v1 +kind: Namespace +metadata: + name: flux-system +EOF + + echo "Creating secret $FLUX_SECRET in namespace flux-system" + kubectl create secret docker-registry "$FLUX_SECRET" -n flux-system \ + --docker-server="$REGISTRY_URL" \ + --docker-username="$REGISTRY_USERNAME" \ + --docker-password="$REGISTRY_PASSWORD" \ + --docker-email="$REGISTRY_EMAIL" \ + --dry-run=client -o yaml | kubectl apply -n flux-system -f - +fi + +# +# install flux +# +echo "Installing flux from kustomization" +KUBECTL_VERSION=$(kubectl version --client --output=yaml | awk '/gitVersion:/ {print $2}' | cut -c2-) +KUBECTL_MIN_VERSION="1.26.0" + +if [ "$(printf '%s\n' "$KUBECTL_MIN_VERSION" "$KUBECTL_VERSION" | sort -V | head -n1)" = "$KUBECTL_MIN_VERSION" ]; then + kubectl kustomize "$FLUX_KUSTOMIZATION" | sed "s/registry1.dso.mil/${REGISTRY_URL}/g" | kubectl apply -f - +else + if [ command -v kustomize ] >/dev/null 2>&1; then + echo "Kustomize not found" + exit 1 + else + kustomize build "$FLUX_KUSTOMIZATION" | sed "s/registry1.dso.mil/${REGISTRY_URL}/g" | kubectl apply -f - + fi +fi + +# +# verify flux +# +kubectl wait --for=condition=available --timeout "${WAIT_TIMEOUT}s" -n "flux-system" "deployment/helm-controller" +kubectl wait --for=condition=available --timeout "${WAIT_TIMEOUT}s" -n "flux-system" "deployment/source-controller" +kubectl wait --for=condition=available --timeout "${WAIT_TIMEOUT}s" -n "flux-system" "deployment/kustomize-controller" +kubectl wait --for=condition=available --timeout "${WAIT_TIMEOUT}s" -n "flux-system" "deployment/notification-controller" diff --git a/scripts/remove-ns-finalizer.sh b/scripts/remove-ns-finalizer.sh new file mode 100755 index 0000000000000000000000000000000000000000..58dba90b332f8f05be14dd4a73d3ea771f141688 --- /dev/null +++ b/scripts/remove-ns-finalizer.sh @@ -0,0 +1,6 @@ +#!/bin/sh + +NS=$1 +shift + +kubectl get ns $NS -o json | jq '.spec.finalizers = []' | kubectl replace --raw "/api/v1/namespaces/$NS/finalize" -f - diff --git a/scripts/sync.sh b/scripts/sync.sh new file mode 100755 index 0000000000000000000000000000000000000000..281995e1c35b2a6a10fa11dca32162367277ad08 --- /dev/null +++ b/scripts/sync.sh @@ -0,0 +1,7 @@ +#!/bin/bash + + +for hr in `kubectl get hr --no-headers -n bigbang | awk '{ print $1 }'` +do + flux reconcile hr -n bigbang --with-source $hr +done diff --git a/scripts/values-translate-2-0.sh b/scripts/values-translate-2-0.sh new file mode 100755 index 0000000000000000000000000000000000000000..c0879634c91dd64666028df21c2106877a00d82a --- /dev/null +++ b/scripts/values-translate-2-0.sh @@ -0,0 +1,51 @@ +values_file=$1 + +if [ -z $values_file ]; then + echo "This script requires one parameter, the path to your values file. Rerun the script with that parameter, ex: './scripts/values-translate-2-0.sh my-values-file.yaml'." + exit 1 +fi + +if [ ! -f $values_file ]; then + echo "Values file not found, verify that the correct path was provided for your values." + exit 1 +fi + +sed_gsed="sed" +# Verify sed version if on macOS +if [ "$(uname -s)" == "Darwin" ]; then + if command -v gsed >/dev/null 2>&1; then + sed_gsed="gsed" + else + echo "The 'gnu-sed' tool is not installed, but if required when running on macOS. 'gnu-sed' can be installed with 'brew install gnu-sed'." + exit 1 + fi +fi + +if ! command -v $sed_gsed >/dev/null 2>&1; then + echo "The 'sed' tool is required to run this script. Please install 'sed' then re-run this script." + exit 1 +fi + +# Update core packages +$sed_gsed -i 's/^istiooperator:$/istioOperator:/' $values_file +$sed_gsed -i 's/^kyvernopolicies:$/kyvernoPolicies:/' $values_file +$sed_gsed -i 's/^kyvernoreporter:$/kyvernoReporter:/' $values_file +$sed_gsed -i 's/^logging:$/elasticsearchKibana:/' $values_file +$sed_gsed -i 's/^eckoperator:$/eckOperator:/' $values_file +# Update addon packages +$sed_gsed -i 's/^\(\s*\)mattermostoperator:$/\1mattermostOperator:/' $values_file +$sed_gsed -i 's/^\(\s*\)nexus:$/\1nexusRepositoryManager:/' $values_file + +echo "Values translation completed successfully - validate that the below translations were completed as expected:" +cat << EOF + Core Packages: + istiooperator -> istioOperator + kyvernopolicies -> kyvernoPolicies + kyvernoreporter -> kyvernoReporter + logging -> elasticsearchKibana + eckoperator -> eckOperator + Addon Packages: + mattermostoperator -> mattermostOperator + nexus -> nexusRepositoryManager +EOF +echo "It is important to validate these and confirm that no other keys were affected." diff --git a/tests/eks-test-values.yaml b/tests/eks-test-values.yaml new file mode 100644 index 0000000000000000000000000000000000000000..3524d840a3f5b3e9b230caceff67939f7cf48ced --- /dev/null +++ b/tests/eks-test-values.yaml @@ -0,0 +1,600 @@ +# Values overrides for EKS pipelines +# These values inherit and override values from tests/test-values.yaml +networkPolicies: + controlPlaneCidr: 10.0.0.0/8 + +istio: + values: + global: + proxy: + resources: + requests: + cpu: 100m + memory: 256Mi + limits: null + defaultConfig: + proxyMetadata: + ISTIO_META_DNS_CAPTURE: "true" + ISTIO_META_DNS_AUTO_ALLOCATE: "true" + bbtests: + cypress: + artifacts: false + +neuvector: + values: + k3s: + enabled: false + containerd: + enabled: true + bbtests: + cypress: + artifacts: false + +clusterAuditor: + values: + resources: + requests: + cpu: 300m + memory: 300Mi + limits: null + bbtests: + cypress: + artifacts: false + +gatekeeper: + values: + replicas: 1 + controllerManager: + resources: + limits: null + requests: + cpu: 175m + memory: 512Mi + bbtests: + cypress: + artifacts: false + +kyverno: + values: + replicaCount: 3 + resources: + limits: null + requests: + cpu: 500m + memory: 384Mi + bbtests: + cypress: + artifacts: false + +elasticsearchKibana: + values: + bbtests: + cypress: + artifacts: false + elasticsearch: + master: + count: 1 + persistence: + size: 256Mi + resources: + requests: + cpu: .5 + limits: null + data: + count: 2 + persistence: + size: 256Mi + resources: + requests: + cpu: .5 + limits: null + +loki: + values: + bbtests: + cypress: + artifacts: false + loki-simple-scalable: + write: + resources: + limits: null + read: + resources: + limits: null + +tempo: + values: + bbtests: + cypress: + artifacts: false + tempo: + resources: + limits: null + requests: + cpu: 500m + memory: 1024Mi + persistence: + size: 5Gi + tempoQuery: + resources: + limits: null + requests: + cpu: 300m + memory: 256Mi + opentelemetryCollector: + resources: + limits: null + requests: + cpu: 300m + memory: 256Mi + +monitoring: + values: + bbtests: + cypress: + artifacts: false + prometheus: + prometheusSpec: + additionalScrapeConfigs: [] + podMetadata: + annotations: + vault.hashicorp.com/agent-inject: "false" + vault.hashicorp.com/agent-init-first: "true" + vault.hashicorp.com/agent-inject-token: "true" + vault.hashicorp.com/role: "prometheus" + vault.hashicorp.com/agent-pre-populate: "false" +### COMMENTED OUT DUE TO ISSUES WITH THANOS-SIDECAR CONTAINER AND PROMETHEUS ### +# proxy.istio.io/config: | +# holdApplicationUntilProxyStarts: true + resources: + requests: + cpu: 300m + memory: 5Gi + limits: null + kube-state-metrics: + resources: + requests: + cpu: 100m + memory: 128Mi + limits: null + prometheus-node-exporter: + resources: + requests: + cpu: 200m + memory: 50Mi + limits: null + grafana: + downloadDashboards: + resources: + limits: null + requests: + cpu: 20m + memory: 20Mi + +twistlock: + values: + bbtests: + cypress: + artifacts: false + console: + persistence: + size: 5Gi + +jaeger: + values: + bbtests: + cypress: + artifacts: false + +kiali: + values: + bbtests: + cypress: + artifacts: false + +grafana: + values: + bbtests: + cypress: + artifacts: false + +# Addons are toggled based on labels in CI +addons: + argocd: + values: + bbtests: + cypress: + artifacts: false + controller: + resources: + requests: + cpu: 500m + memory: 2Gi + limits: null + dex: + resources: + requests: + cpu: 10m + memory: 128Mi + limits: null + redis-bb: + master: + persistence: + size: 512Mi + replica: + persistence: + size: 512Mi + redis: + resources: + requests: + cpu: 50m + memory: 256Mi + limits: null + server: + resources: + requests: + cpu: 20m + memory: 128Mi + limits: null + repoServer: + resources: + requests: + cpu: 100m + memory: 256Mi + limits: null + + authservice: + values: + bbtests: + cypress: + artifacts: false + resources: + requests: + cpu: 100m + memory: 256Mi + limits: null + redis: + master: + persistence: + size: 256Mi + replica: + persistence: + size: 256Mi + + gitlab: + flux: + timeout: 30m + values: + bbtests: + cypress: + artifacts: false + gitlab-runner: + resources: + requests: + cpu: 20m + limits: null + gitlab: + gitaly: + persistence: + size: 256Mi + resources: + ## values raised to help pass CI after default values for gitaly are fixed then can revert to original request. + #requests: + # cpu: 50m + #limits: null + requests: + cpu: 400m + memory: 600Mi + limits: null + shared-secrets: + resources: + requests: + cpu: 30m + limits: null + migrations: + resources: + requests: + cpu: 30m + limits: null + toolbox: + persistence: + size: 256Mi + resources: + requests: + cpu: 20m + limits: null + postgresql: + persistence: + size: 256Mi + metrics: + resources: + requests: + cpu: 50m + limits: null + minio: + persistence: + size: 256Mi + resources: + requests: + cpu: 100m + limits: null + redis: + master: + persistence: + size: 256Mi + slave: + persistence: + size: 256Mi + + gitlabRunner: + values: + bbtests: + cypress: + artifacts: false + resources: + requests: + memory: 128Mi + cpu: 100m + limits: null + + anchore: + values: + bbtests: + cypress: + artifacts: false + ensureDbJobs: + resources: + requests: + cpu: 100m + memory: 256Mi + limits: null + sso: + resources: + requests: + cpu: 100m + memory: 256Mi + limits: null + postgresql: + persistence: + size: 256Mi + resources: + requests: + cpu: 100m + memory: 256Mi + limits: null + metrics: + resources: + requests: + cpu: 100m + memory: 256Mi + limits: null + anchoreAnalyzer: + resources: + requests: + cpu: 200m + memory: 512Mi + limits: null + anchoreApi: + resources: + requests: + cpu: 200m + memory: 512Mi + limits: null + anchoreCatalog: + resources: + requests: + cpu: 200m + memory: 512Mi + limits: null + anchorePolicyEngine: + resources: + requests: + cpu: 200m + memory: 512Mi + limits: null + anchoreSimpleQueue: + resources: + requests: + cpu: 200m + memory: 512Mi + limits: null + anchoreEngineUpgradeJob: + resources: + requests: + cpu: 200m + memory: 512Mi + limits: null + anchore-feeds-db: + resources: + requests: + cpu: 100m + memory: 256Mi + limits: null + metrics: + resources: + requests: + cpu: 100m + memory: 256Mi + limits: null + anchoreEnterpriseFeeds: + resources: + requests: + cpu: 200m + memory: 512Mi + limits: null + anchoreEnterpriseFeedsUpgradeJob: + resources: + requests: + cpu: 200m + memory: 512Mi + limits: null + anchoreEnterpriseRbac: + authResources: + requests: + cpu: 200m + memory: 512Mi + limits: null + managerResources: + requests: + cpu: 200m + memory: 512Mi + limits: null + anchoreEnterpriseReports: + resources: + requests: + cpu: 200m + memory: 512Mi + limits: null + anchoreEnterpriseNotifications: + resources: + requests: + cpu: 200m + memory: 512Mi + limits: null + anchoreEntperpiseUi: + resources: + requests: + cpu: 200m + memory: 512Mi + limits: null + anchoreEnterpriseEngineUpgradeJob: + resources: + requests: + cpu: 200m + memory: 512Mi + limits: null + + sonarqube: + values: + bbtests: + cypress: + artifacts: false + resources: + requests: + cpu: 200m + memory: 512Mi + limits: null + persistence: + size: 5Gi + postgresql: + persistence: + size: 256Mi + resources: + requests: + cpu: 100m + memory: 200Mi + limits: null + + minio: + values: + bbtests: + cypress: + artifacts: false + tenant: + pools: + - name: pool-0 + servers: 3 + volumesPerServer: 4 + size: 256Mi + resources: + requests: + cpu: 250m + memory: 512Mi + limits: null + securityContext: + runAsUser: 1001 + runAsGroup: 1001 + fsGroup: 1001 + runAsNonRoot: true + containerSecurityContext: + runAsUser: 1001 + runAsGroup: 1001 + runAsNonRoot: true + capabilities: + drop: + - ALL + + mattermost: + values: + bbtests: + cypress: + artifacts: false + postgresql: + persistence: + size: 256Mi + resources: + requests: + cpu: 200m + memory: 256Mi + limits: null + minio: + tenants: + pools: + - name: pool-0 + servers: 1 + volumesPerServer: 4 + size: 256Mi + resources: + requests: + cpu: 250m + memory: 512Mi + limits: null + securityContext: + runAsUser: 1001 + runAsGroup: 1001 + fsGroup: 1001 + runAsNonRoot: true + containerSecurityContext: + runAsUser: 1001 + runAsGroup: 1001 + runAsNonRoot: true + + nexusRepositoryManager: + values: + bbtests: + cypress: + artifacts: false + persistence: + # Do NOT set this below 5Gi, nexus will fail to boot + storageSize: 5Gi + nexus: + resources: + requests: + cpu: 100m + memory: 1500Mi + limits: null + + keycloak: + values: + bbtests: + cypress: + artifacts: false + resources: + requests: + cpu: 100m + memory: 256Mi + limits: null + + harbor: + values: + bbtests: + cypress: + artifacts: false + + holocron: + values: + bbtests: + cypress: + artifacts: false + + fortify: + values: + bbtests: + cypress: + artifacts: false + + minioOperator: + values: + bbtests: + cypress: + artifacts: false \ No newline at end of file diff --git a/tests/fips-test-values.yaml b/tests/fips-test-values.yaml new file mode 100644 index 0000000000000000000000000000000000000000..d82c8de3c17859a4c018581d2b4fe56de05ef499 --- /dev/null +++ b/tests/fips-test-values.yaml @@ -0,0 +1,3 @@ +# use fips-enabled MR label to include these values in addtion to test-values and rke/eks overrides (if applicable) +istio: + enterprise: true \ No newline at end of file diff --git a/tests/images.txt b/tests/images.txt new file mode 100644 index 0000000000000000000000000000000000000000..6a86dceb320364200f9451d536522449167c9f11 --- /dev/null +++ b/tests/images.txt @@ -0,0 +1,4 @@ +registry1.dso.mil/ironbank/big-bang/base:2.1.0 +registry1.dso.mil/ironbank/big-bang/utilities:1.0.3 +registry1.dso.mil/ironbank/opensource/kubernetes-1.21/kubectl:v1.21.14 +registry1.dso.mil/ironbank/opensource/kyverno/kyvernocli:v1.13.2 \ No newline at end of file diff --git a/tests/oci-values.yaml b/tests/oci-values.yaml new file mode 100644 index 0000000000000000000000000000000000000000..9f63e5699d2995c0f68d560a944c706ddfdf9dd2 --- /dev/null +++ b/tests/oci-values.yaml @@ -0,0 +1,210 @@ +helmRepositories: + - name: "registry1" + repository: "oci://registry1.dso.mil/bigbang" + existingSecret: "private-registry" + type: "oci" + username: "" + password: "" + email: "" + cosignPublicKeys: + key1: | + -----BEGIN PUBLIC KEY----- + MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIE7v9J6ttQus6itUoyfMCqMjaIqm + R8XrntaedsdEhPPchOQuFzqTyyAPGifV1SaEu8medVRi6mVICWbVwOteNg== + -----END PUBLIC KEY----- + +istio: + sourceType: "helmRepo" + helmRepo: + cosignVerify: false + +istioOperator: + sourceType: "helmRepo" + helmRepo: + cosignVerify: false + +kiali: + sourceType: "helmRepo" + helmRepo: + cosignVerify: false + +kyverno: + sourceType: "helmRepo" + helmRepo: + cosignVerify: false + +kyvernoPolicies: + sourceType: "helmRepo" + helmRepo: + cosignVerify: false + +kyvernoReporter: + sourceType: "helmRepo" + helmRepo: + cosignVerify: false + +promtail: + sourceType: "helmRepo" + helmRepo: + cosignVerify: false + +loki: + sourceType: "helmRepo" + helmRepo: + cosignVerify: false + +neuvector: + sourceType: "helmRepo" + helmRepo: + cosignVerify: false + +tempo: + sourceType: "helmRepo" + helmRepo: + cosignVerify: false + +monitoring: + sourceType: "helmRepo" + helmRepo: + cosignVerify: false + +grafana: + sourceType: "helmRepo" + helmRepo: + cosignVerify: false + +twistlock: + sourceType: "helmRepo" + helmRepo: + cosignVerify: false + +fluentbit: + sourceType: "helmRepo" + helmRepo: + cosignVerify: false + +jaeger: + sourceType: "helmRepo" + helmRepo: + cosignVerify: false + +eckOperator: + sourceType: "helmRepo" + helmRepo: + cosignVerify: false + +elasticsearchKibana: + sourceType: "helmRepo" + helmRepo: + cosignVerify: false + +clusterAuditor: + sourceType: "helmRepo" + helmRepo: + cosignVerify: false + +gatekeeper: + sourceType: "helmRepo" + helmRepo: + cosignVerify: false + +addons: + argocd: + sourceType: "helmRepo" + helmRepo: + cosignVerify: false + + authservice: + sourceType: "helmRepo" + helmRepo: + cosignVerify: false + + minioOperator: + sourceType: "helmRepo" + helmRepo: + cosignVerify: false + + minio: + sourceType: "helmRepo" + helmRepo: + cosignVerify: false + + gitlab: + sourceType: "helmRepo" + helmRepo: + cosignVerify: false + + gitlabRunner: + sourceType: "helmRepo" + helmRepo: + cosignVerify: false + + nexusRepositoryManager: + sourceType: "helmRepo" + helmRepo: + cosignVerify: false + + sonarqube: + sourceType: "helmRepo" + helmRepo: + cosignVerify: false + + haproxy: + sourceType: "helmRepo" + helmRepo: + cosignVerify: false + + anchore: + sourceType: "helmRepo" + helmRepo: + cosignVerify: false + + mattermostOperator: + sourceType: "helmRepo" + helmRepo: + cosignVerify: false + + mattermost: + sourceType: "helmRepo" + helmRepo: + cosignVerify: false + + velero: + sourceType: "helmRepo" + helmRepo: + cosignVerify: false + + keycloak: + sourceType: "helmRepo" + helmRepo: + cosignVerify: false + + vault: + sourceType: "helmRepo" + helmRepo: + cosignVerify: false + + metricsServer: + sourceType: "helmRepo" + helmRepo: + cosignVerify: false + + harbor: + sourceType: "helmRepo" + helmRepo: + cosignVerify: false + + thanos: + sourceType: "helmRepo" + helmRepo: + cosignVerify: false + + fortify: + sourceType: "helmRepo" + helmRepo: + cosignVerify: false + + holocron: + sourceType: "helmRepo" + helmRepo: + cosignVerify: false diff --git a/tests/openshift-test-values.yaml b/tests/openshift-test-values.yaml new file mode 100644 index 0000000000000000000000000000000000000000..8a7bfd5bccaa5ecd98fe6c8f524554e0c4c33f4f --- /dev/null +++ b/tests/openshift-test-values.yaml @@ -0,0 +1,459 @@ +openshift: true +istio: + values: + profile: "openshift" + ingressGateways: + public-ingressgateway: + k8s: + hpaSpec: + minReplicas: 3 + maxReplicas: 5 + values: + pilot: + env: + "ENABLE_NATIVE_SIDECARS": "false" +gatekeeper: + values: + violations: + selinuxPolicy: + enforcementAction: dryrun + parameters: + excludedResources: + # Allow kyverno pods + - kyverno/kyverno-.* + - istio-operator/istio-operator-.* + - istio-operator/istiod-hook-.* + - istio-system/istiod-.* + - istio-system/public-ingressgateway-.* + - istio-system/passthrough-ingressgateway-.* + - eck-operator/elastic-operator-.* + - minio-operator/minio-operator-.* + - minio-operator/console-.* + - fortify/fortify-mysql-.* + - fortify/fortify-ssc-webapp-.* + - gitlab/webservice-test-runner-.* + - gitlab/gitlab-minio-.* + - gitlab-runner/runner-.* + - twistlock/twistlock-defender-.* + - neuvector/neuvector-.* + - argocd/guestbook-ui-.* + - keycloak/keycloak-.* + - holocron/holocron-postgresql-0 + - velero/velero-backup-restore-test.* + - vault/vault-vault.* + - monitoring/monitoring-monitoring-kube-admission-create-.* +monitoring: + values: + prometheus: + prometheusSpec: + additionalScrapeConfigs: [] + podMetadata: + annotations: + vault.hashicorp.com/agent-inject: "false" + vault.hashicorp.com/agent-init-first: "true" + vault.hashicorp.com/agent-inject-token: "true" + vault.hashicorp.com/role: "prometheus" + vault.hashicorp.com/agent-pre-populate: "false" + resources: + requests: + cpu: 300m + memory: 5Gi + limits: null + grafana: + downloadDashboards: + resources: + limits: null + requests: + cpu: 20m + memory: 20Mi +neuvector: + values: + k3s: + enabled: false + crio: + enabled: true + path: /var/run/crio/crio.sock + istio: + enabled: true + hardened: + enabled: false + tempo: + enabled: false + console: + enabled: false + openshift: true + bbtests: + cypress: + openshift: true +kyvernoPolicies: + values: + policies: + disallow-privileged-containers: + exclude: + any: + - resources: + namespaces: + - openshift-etcd + names: + - installer-* + disallow-privilege-escalation: + exclude: + any: + - resources: + namespaces: + - anchore + names: + - anchore-enterprise-migrate-db + - resources: + namespaces: + - authservice + names: + - authservice-authservice-redis-bb-master-* + - resources: + namespaces: + - sonarqube + names: + - sonarqube-postgresql-* + - sonarqube-sonarqube-* + restrict-image-registries: + exclude: + any: + # ArgoCD deploys a test app as part of its Cypress test + - resources: + namespaces: + - argocd + names: + - guestbook-ui-* + - resources: + namespaces: + - openshift-marketplace + names: + - certified-operators-* + - community-operators-* + - redhat-* + - resources: + namespaces: + - openshift-operator-lifecycle-manager + names: + - collect-profiles-* + - resources: + namespaces: + - openshift-etcd + names: + - installer-* + - resources: + namespaces: + - openshift-monitoring + names: + - prometheus-k8s-* + require-non-root-group: + exclude: + any: + # Gitlab Minio sub-chart does not have configurable securityContext values from upstream. Minio installation + # is only recommended for Dev/CI environments. + - resources: + namespaces: + - authservice + names: + - authservice-authservice-redis-bb-master-* + - resources: + namespaces: + - gitlab + names: + - gitlab-minio-* + - resources: + namespaces: + - fortify + names: + - fortify-mysql-* # mysql breaks if you give it a different group + - resources: + namespaces: + - metallb-system + names: + - speaker-* + - controller-* + - resources: + namespaces: + - harbor + names: + - harbor-redis-bb-* + - resources: + namespaces: + - argocd + names: + - argocd-argocd-redis-* + - resources: + namespaces: + - velero + names: + - velero-backup-restore-test* + - resources: + namespaces: + - openshift-operator-lifecycle-manager + names: + - collect-profiles-* + - resources: + namespaces: + - openshift-marketplace + names: + - certified-operators-* + - community-operators-* + - redhat-* + - resources: + namespaces: + - openshift-etcd + names: + - installer-* + - resources: + namespaces: + - istio-system + names: + - passthrough-ingressgateway-* + - public-ingressgateway-* + - resources: + namespaces: + - openshift-monitoring + names: + - prometheus-k8s-* + require-non-root-user: + exclude: + any: + # Gitlab Minio sub-chart does not have configurable securityContext values from upstream. Minio installation + # is only recommended for Dev/CI environments. + - resources: + namespaces: + - authservice + names: + - authservice-authservice-redis-bb-master-* + - resources: + namespaces: + - gitlab + names: + - gitlab-minio-* + - resources: + namespaces: + - gitlab + names: + - gitlab-minio-* + - resources: + namespaces: + - metallb-system + names: + - speaker-* + - resources: + namespaces: + - argocd + names: + - guestbook* + - argocd-argocd-redis-* + - resources: + namespaces: + - harbor + names: + - harbor-redis-bb-* + - resources: + namespaces: + - velero + names: + - velero-backup-restore-test* + - resources: + namespaces: + - twistlock + names: + - volume-upgrade-job* + - resources: + namespaces: + - openshift-operator-lifecycle-manager + names: + - collect-profiles-* + - resources: + namespaces: + - openshift-marketplace + names: + - certified-operators-* + - community-operators-* + - redhat-* + - resources: + namespaces: + - openshift-etcd + names: + - installer-* + - resources: + namespaces: + - istio-system + names: + - passthrough-ingressgateway-* + - public-ingressgateway-* + - resources: + namespaces: + - openshift-monitoring + names: + - prometheus-k8s-* + require-drop-all-capabilities: + exclude: + any: + # Gitlab Minio sub-chart does not have configurable securityContext values from upstream. Minio installation + # is only recommended for Dev/CI environments. + - resources: + namespaces: + - gitlab + names: + - gitlab-minio-* + # Twistlock Defenders run as root to perform real time scanning on the nodes/cluster + - resources: + namespaces: + - twistlock + names: + - twistlock-defender-ds* + # Neuvector needs access to host to inspect network traffic + - resources: + namespaces: + - neuvector + names: + - neuvector-enforcer-pod* + - neuvector-controller-pod* + - neuvector-prometheus-exporter-pod* + - resources: + namespaces: + - argocd + names: + - guestbook-ui-* + - resources: + namespaces: + - openshift-etcd + names: + - installer-* + - resources: + namespaces: + - openshift-monitoring + names: + - prometheus-k8s-* + restrict-volume-types: + exclude: + any: + - resources: + namespaces: + - gitlab + - gitlab-runner + - kiali + - cluster-auditor + - mattermost + - nexus-repository-manager + - keycloak + - kyverno-reporter + - jaeger + - monitoring + - vault + - logging + - twistlock + - sonarqube + - logging + - tempo + - argocd + - minio + - minio-operator + - neuvector + - harbor + - fortify + - thanos + - holocron + names: + - "*-cypress-test*" + - resources: + namespaces: + - openshift-etcd + names: + - installer-* + restrict-host-path-mount: + exclude: + any: + - resources: + namespaces: + - gitlab + - gitlab-runner + - kiali + - cluster-auditor + - mattermost + - nexus-repository-manager + - keycloak + - jaeger + - kyverno-reporter + - monitoring + - vault + - logging + - twistlock + - sonarqube + - logging + - tempo + - argocd + - minio + - minio-operator + - neuvector + - harbor + - fortify + - thanos + - holocron + names: + - "*-cypress-test*" + - resources: + namespaces: + - openshift-etcd + names: + - installer-* + restrict-host-path-write: + exclude: + any: + - resources: + namespaces: + - gitlab + - gitlab-runner + - kiali + - cluster-auditor + - mattermost + - nexus-repository-manager + - keycloak + - kyverno-reporter + - jaeger + - monitoring + - vault + - logging + - twistlock + - sonarqube + - logging + - tempo + - argocd + - minio + - minio-operator + - neuvector + - harbor + - fortify + - thanos + - holocron + names: + - "*-cypress-test*" + - resources: + namespaces: + - neuvector + names: + - "neuvector-enforcer-*" + - "neuvector-manager-*" + - resources: + namespaces: + - openshift-etcd + names: + - installer-* + parameters: + allow: + - /tmp/allowed +# Addons are toggled based on labels in CI +addons: + minioOperator: + values: + openshift: true + minio: + values: + annotations: + traffic.sidecar.istio.io/excludeOutboundPorts: "443" + istio: + enabled: true + openshift: true \ No newline at end of file diff --git a/tests/package-mapping.yaml b/tests/package-mapping.yaml new file mode 100644 index 0000000000000000000000000000000000000000..b98854f2604d4ce50dccc66761905f22cd60d6d9 --- /dev/null +++ b/tests/package-mapping.yaml @@ -0,0 +1,93 @@ +# Each package in `chart/values.yaml` should be present in this file. The top level key should match the values key in values.yaml, all other keys should follow the guide below. +# package: +# repoName: A string matching the `CI_PROJECT_NAME` in repo1. Typically this is the URL/path for the repo. +# hrName: A string matching the helmrelease name in `chart/templates/package/helmrelease.yaml`. +# filePath: A string matching the filePath for the package directory in `chart/templates`. This is typically just `package`. +# dependencies: A list of all packages that should also be deployed in CI if this one is enabled. These names should match the other package(s) values keys. +# Note: For any locations where the value matches the top level key, these can be left blank. + +istio: + repoName: "istio-controlplane" +istioOperator: + repoName: "istio-operator" + hrName: "istio-operator" + filePath: "istio-operator" +clusterAuditor: + repoName: "cluster-auditor" + hrName: "cluster-auditor" + filePath: "cluster-auditor" +gatekeeper: + repoName: "policy" +kyvernoPolicies: + repoName: "kyverno-policies" + hrName: "kyverno-policies" + filePath: "kyverno-policies" +kyvernoReporter: + repoName: "kyverno-reporter" + hrName: "kyverno-reporter" + filePath: "kyverno-reporter" + dependencies: + - "kyvernoPolicies" +elasticsearchKibana: + repoName: "elasticsearch-kibana" + hrName: "ek" + filePath: "elasticsearch-kibana" +eckOperator: + repoName: "eck-operator" + hrName: "eck-operator" + filePath: "eck-operator" +fluentbit: + hrName: "fluentbit" + filePath: "fluentbit" +promtail: + dependencies: + - "loki" +loki: + dependencies: + - "minioOperator" + - "promtail" +minioOperator: + repoName: "minio-operator" + hrName: "minio-operator" + filePath: "minio-operator" +minio: + dependencies: + - "minioOperator" +gitlabRunner: + repoName: "gitlab-runner" + hrName: "gitlab-runner" + filePath: "gitlab-runner" + dependencies: + - "gitlab" +nexusRepositoryManager: + repoName: "nexus" + hrName: "nexus-repository-manager" + filePath: "nexus-repository-manager" +haproxy: + hrName: "haproxy-sso" +anchore: + repoName: "anchore-enterprise" +mattermostOperator: + repoName: "mattermost-operator" + hrName: "mattermost-operator" + filePath: "mattermost-operator" +mattermost: + dependencies: + - "mattermostOperator" + - "minioOperator" + - "elasticsearchKibana" +velero: + dependencies: + - "minio" + - "minioOperator" +vault: + dependencies: + - "minioOperator" +metricsServer: + repoName: "metrics-server" + hrName: "metrics-server" + filePath: "metrics-server" +externalSecrets: + repoName: "external-secrets" + hrName: "external-secrets" + filePath: "external-secrets" \ No newline at end of file diff --git a/tests/rke2-test-values.yaml b/tests/rke2-test-values.yaml new file mode 100644 index 0000000000000000000000000000000000000000..9ba6fba140eb7eb439de62b6105ffdb16766ebd0 --- /dev/null +++ b/tests/rke2-test-values.yaml @@ -0,0 +1,584 @@ +# Values overrides for RKE2 pipelines +# These values inherit and override values from tests/test-values.yaml +networkPolicies: + controlPlaneCidr: 10.0.0.0/8 + +istio: + values: + values: + global: + proxy: + resources: + requests: + cpu: 100m + memory: 256Mi + limits: null + +clusterAuditor: + values: + bbtests: + cypress: + artifacts: false + resources: + requests: + cpu: 300m + memory: 300Mi + limits: null + +gatekeeper: + values: + bbtests: + cypress: + artifacts: false + replicas: 1 + controllerManager: + resources: + limits: null + requests: + cpu: 175m + memory: 512Mi + +kyverno: + values: + bbtests: + cypress: + artifacts: false + networkPolicies: + externalRegistries: + allowEgress: true + replicaCount: 3 + resources: + limits: null + requests: + cpu: 500m + memory: 384Mi + +elasticsearchKibana: + values: + bbtests: + cypress: + artifacts: false + elasticsearch: + master: + count: 1 + persistence: + size: 256Mi + resources: + requests: + cpu: .5 + limits: null + data: + count: 2 + persistence: + size: 256Mi + resources: + requests: + cpu: .5 + limits: null + +loki: + values: + global: + dnsService: rke2-coredns-rke2-coredns + bbtests: + cypress: + artifacts: false + loki-simple-scalable: + write: + resources: + limits: null + read: + resources: + limits: null + +tempo: + values: + bbtests: + cypress: + artifacts: false + tempo: + resources: + limits: null + requests: + cpu: 500m + memory: 1024Mi + persistence: + size: 5Gi + tempoQuery: + resources: + limits: null + requests: + cpu: 300m + memory: 256Mi + opentelemetryCollector: + resources: + limits: null + requests: + cpu: 300m + memory: 256Mi + +monitoring: + values: + bbtests: + cypress: + artifacts: false + prometheus: + prometheusSpec: + additionalScrapeConfigs: [] + podMetadata: + annotations: + vault.hashicorp.com/agent-inject: "false" + vault.hashicorp.com/agent-init-first: "false" + vault.hashicorp.com/agent-inject-token: "false" + resources: + requests: + cpu: 300m + memory: 5Gi + limits: null + kube-state-metrics: + resources: + requests: + cpu: 100m + memory: 128Mi + limits: null + prometheus-node-exporter: + resources: + requests: + cpu: 200m + memory: 50Mi + limits: null + grafana: + downloadDashboards: + resources: + limits: null + requests: + cpu: 20m + memory: 20Mi + +twistlock: + values: + bbtests: + cypress: + artifacts: false + console: + persistence: + size: 5Gi + +jaeger: + values: + bbtests: + cypress: + artifacts: false + +kiali: + values: + bbtests: + cypress: + artifacts: false + +grafana: + values: + bbtests: + cypress: + artifacts: false + +# Addons are toggled based on labels in CI +addons: + argocd: + values: + bbtests: + cypress: + artifacts: false + controller: + resources: + requests: + cpu: 500m + memory: 2Gi + limits: null + dex: + resources: + requests: + cpu: 10m + memory: 128Mi + limits: null + redis-bb: + master: + persistence: + size: 512Mi + replica: + persistence: + size: 512Mi + redis: + resources: + requests: + cpu: 50m + memory: 256Mi + limits: null + server: + resources: + requests: + cpu: 20m + memory: 128Mi + limits: null + repoServer: + resources: + requests: + cpu: 100m + memory: 256Mi + limits: null + + authservice: + values: + bbtests: + cypress: + artifacts: false + resources: + requests: + cpu: 100m + memory: 256Mi + limits: null + redis: + master: + persistence: + size: 256Mi + replica: + persistence: + size: 256Mi + + gitlab: + flux: + timeout: 30m + values: + bbtests: + cypress: + artifacts: false + gitlab-runner: + resources: + requests: + cpu: 20m + limits: null + gitlab: + gitaly: + persistence: + size: 256Mi + resources: + ## values raised to help pass CI after default values for gitaly are fixed then can revert to original request. + #requests: + # cpu: 50m + #limits: null + requests: + cpu: 400m + memory: 600Mi + limits: null + shared-secrets: + resources: + requests: + cpu: 30m + limits: null + migrations: + resources: + requests: + cpu: 30m + limits: null + toolbox: + persistence: + size: 256Mi + resources: + requests: + cpu: 20m + limits: null + postgresql: + persistence: + size: 256Mi + metrics: + resources: + requests: + cpu: 50m + limits: null + minio: + persistence: + size: 256Mi + resources: + requests: + cpu: 100m + limits: null + redis: + master: + persistence: + size: 256Mi + slave: + persistence: + size: 256Mi + + gitlabRunner: + values: + bbtests: + cypress: + artifacts: false + resources: + requests: + memory: 128Mi + cpu: 100m + limits: null + + anchore: + values: + bbtests: + cypress: + artifacts: false + ensureDbJobs: + resources: + requests: + cpu: 100m + memory: 256Mi + limits: null + sso: + resources: + requests: + cpu: 100m + memory: 256Mi + limits: null + postgresql: + persistence: + size: 256Mi + resources: + requests: + cpu: 100m + memory: 256Mi + limits: null + metrics: + resources: + requests: + cpu: 100m + memory: 256Mi + limits: null + anchoreAnalyzer: + resources: + requests: + cpu: 200m + memory: 512Mi + limits: null + anchoreApi: + resources: + requests: + cpu: 200m + memory: 512Mi + limits: null + anchoreCatalog: + resources: + requests: + cpu: 200m + memory: 512Mi + limits: null + anchorePolicyEngine: + resources: + requests: + cpu: 200m + memory: 512Mi + limits: null + anchoreSimpleQueue: + resources: + requests: + cpu: 200m + memory: 512Mi + limits: null + anchoreEngineUpgradeJob: + resources: + requests: + cpu: 200m + memory: 512Mi + limits: null + anchore-feeds-db: + resources: + requests: + cpu: 100m + memory: 256Mi + limits: null + metrics: + resources: + requests: + cpu: 100m + memory: 256Mi + limits: null + anchoreEnterpriseFeeds: + resources: + requests: + cpu: 200m + memory: 512Mi + limits: null + anchoreEnterpriseFeedsUpgradeJob: + resources: + requests: + cpu: 200m + memory: 512Mi + limits: null + anchoreEnterpriseRbac: + authResources: + requests: + cpu: 200m + memory: 512Mi + limits: null + managerResources: + requests: + cpu: 200m + memory: 512Mi + limits: null + anchoreEnterpriseReports: + resources: + requests: + cpu: 200m + memory: 512Mi + limits: null + anchoreEnterpriseNotifications: + resources: + requests: + cpu: 200m + memory: 512Mi + limits: null + anchoreEntperpiseUi: + resources: + requests: + cpu: 200m + memory: 512Mi + limits: null + anchoreEnterpriseEngineUpgradeJob: + resources: + requests: + cpu: 200m + memory: 512Mi + limits: null + + sonarqube: + values: + bbtests: + cypress: + artifacts: false + resources: + requests: + cpu: 200m + memory: 512Mi + limits: null + persistence: + size: 5Gi + postgresql: + persistence: + size: 256Mi + resources: + requests: + cpu: 100m + memory: 200Mi + limits: null + + minio: + values: + bbtests: + cypress: + artifacts: false + tenant: + pools: + - name: pool-0 + servers: 3 + volumesPerServer: 4 + size: 256Mi + resources: + requests: + cpu: 250m + memory: 512Mi + limits: null + securityContext: + runAsUser: 1001 + runAsGroup: 1001 + fsGroup: 1001 + runAsNonRoot: true + containerSecurityContext: + runAsUser: 1001 + runAsGroup: 1001 + runAsNonRoot: true + capabilities: + drop: + - ALL + mattermost: + values: + bbtests: + cypress: + artifacts: false + postgresql: + persistence: + size: 256Mi + resources: + requests: + cpu: 200m + memory: 256Mi + limits: null + minio: + tenant: + pools: + - name: pool-0 + servers: 1 + volumesPerServer: 4 + size: 256Mi + resources: + requests: + cpu: 250m + memory: 512Mi + limits: null + securityContext: + runAsUser: 1001 + runAsGroup: 1001 + fsGroup: 1001 + runAsNonRoot: true + containerSecurityContext: + runAsUser: 1001 + runAsGroup: 1001 + runAsNonRoot: true + + nexusRepositoryManager: + values: + bbtests: + cypress: + artifacts: false + persistence: + # Do NOT set this below 5Gi, nexus will fail to boot + storageSize: 5Gi + nexus: + resources: + requests: + cpu: 100m + memory: 1500Mi + limits: null + + keycloak: + values: + bbtests: + cypress: + artifacts: false + resources: + requests: + cpu: 100m + memory: 256Mi + limits: null + + harbor: + values: + bbtests: + cypress: + artifacts: false + + holocron: + values: + bbtests: + cypress: + artifacts: false + + fortify: + values: + bbtests: + cypress: + artifacts: false + + minioOperator: + values: + bbtests: + cypress: + artifacts: false + diff --git a/tests/test-values.yaml b/tests/test-values.yaml new file mode 100644 index 0000000000000000000000000000000000000000..7dd0b81547799b95585dbed7e8a26ca5375fc6e3 --- /dev/null +++ b/tests/test-values.yaml @@ -0,0 +1,2569 @@ +domain: dev.bigbang.mil + +sso: + url: https://keycloak.dev.bigbang.mil/auth/realms/baby-yoda + + # LetsEncrypt certificate authority + certificateAuthority: + cert: | + -----BEGIN CERTIFICATE----- + MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw + TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh + cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4 + WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJu + ZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY + MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54rVygc + h77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+ + 0TM8ukj13Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6U + A5/TR5d8mUgjU+g4rk8Kb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sW + T8KOEUt+zwvo/7V3LvSye0rgTBIlDHCNAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyH + B5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ4Q7e2RCOFvu396j3x+UC + B5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf1b0SHzUv + KBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWn + OlFuhjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTn + jh8BCNAw1FtxNrQHusEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbw + qHyGO0aoSCqI3Haadr8faqU9GY/rOPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CI + rU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV + HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY9umbbjANBgkq + hkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL + ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ + 3BebYhtF8GaV0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KK + NFtY2PwByVS5uCbMiogziUwthDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5 + ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJwTdwJx4nLCgdNbOhdjsnvzqvHu7Ur + TkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nxe5AW0wdeRlN8NwdC + jNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZAJzVc + oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq + 4RgqsahDYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPA + mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d + emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc= + -----END CERTIFICATE----- + saml: + # Retrieve from {{ .Values.sso.url }}/protocol/saml/descriptor + metadata: <md:EntityDescriptor xmlns="urn:oasis:names:tc:SAML:2.0:metadata" xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" entityID="https://keycloak.dev.bigbang.mil/auth/realms/baby-yoda"><md:IDPSSODescriptor WantAuthnRequestsSigned="true" protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol"><md:KeyDescriptor use="signing"><ds:KeyInfo><ds:KeyName>4CK69bW66HE2wph9VuBs0fTc1MaETSTpU1iflEkBHR4</ds:KeyName><ds:X509Data><ds:X509Certificate>MIICoTCCAYkCBgF/iYn0azANBgkqhkiG9w0BAQsFADAUMRIwEAYDVQQDDAliYWJ5LXlvZGEwHhcNMjIwMzE0MTc0NDUzWhcNMzIwMzE0MTc0NjMzWjAUMRIwEAYDVQQDDAliYWJ5LXlvZGEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCoCX4G1TCnZlWXvCLH/z6m5y/6NMrUv1AYVVbTaQ9iUWLR+uD44v1exIHUywkgQV+cMhn+my+9ZihmRWfOJuBWV8CM5BfIh685YulKVQrcGlYWcB877SjJBZKxyXITz7GnNOJ8vvlK9tK8OncldUFrhR2BXaqw2zvG733CKlDtyujaWmd7kQge/p4okx4bV4VBLYMmsjrJ004uvMcU4DekCFlGmEh3p3FhZorMf+1xHfi5DaCD4iCYZqRgsWEb8/Zmsx0+qi56P9YWhz1j2GUfHw0At8Dq5h7hoMJtYJMvVXWxkmPNVHtaJMOHt8iiBO7/a6SkI6ddf9Jotp2i6XEvAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAJwSLJ0eybbeBYPvXnawqpy6JSXJ/MnnRvSGN9tXJ2+d/QXMOEPwJaAaOrvFtpUQxyPELJ8nU/Ukf7AL2zWltsCLiwtTrJkC+BpbZYkb1UsByveBS5wTPfiNkFzHeGg+MxBjiju2y04P4kEngXhQh4ZIUdi+WJjew721nJa/tjrMfnuEsMjxY/tWnzkk8xkGgaApZpGyaj1tOmVH4GR6CeBU6459m/GXmGH5TCGwT3EyfpZ189te+xV73WZR/r2nDlGuuy//w/P4JGHh4lcCwLfPcOOH30otcPAgctyX9Takk4MkVjva+b9S88sGaWPg075bxA2sysmkuqEOULjdXjU=</ds:X509Certificate></ds:X509Data></ds:KeyInfo></md:KeyDescriptor><md:ArtifactResolutionService Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP" Location="https://keycloak.dev.bigbang.mil/auth/realms/baby-yoda/protocol/saml/resolve" index="0"></md:ArtifactResolutionService><md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://keycloak.dev.bigbang.mil/auth/realms/baby-yoda/protocol/saml"></md:SingleLogoutService><md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://keycloak.dev.bigbang.mil/auth/realms/baby-yoda/protocol/saml"></md:SingleLogoutService><md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact" Location="https://keycloak.dev.bigbang.mil/auth/realms/baby-yoda/protocol/saml"></md:SingleLogoutService><md:NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:persistent</md:NameIDFormat><md:NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:transient</md:NameIDFormat><md:NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified</md:NameIDFormat><md:NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress</md:NameIDFormat><md:SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://keycloak.dev.bigbang.mil/auth/realms/baby-yoda/protocol/saml"></md:SingleSignOnService><md:SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://keycloak.dev.bigbang.mil/auth/realms/baby-yoda/protocol/saml"></md:SingleSignOnService><md:SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP" Location="https://keycloak.dev.bigbang.mil/auth/realms/baby-yoda/protocol/saml"></md:SingleSignOnService><md:SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact" Location="https://keycloak.dev.bigbang.mil/auth/realms/baby-yoda/protocol/saml"></md:SingleSignOnService></md:IDPSSODescriptor></md:EntityDescriptor> + +flux: + interval: 1m + install: + remediation: + retries: 3 + rollback: + cleanupOnFail: false + ## override cleanup on upgrade to allow artifacts to upload + upgrade: + cleanupOnFail: false + +networkPolicies: + enabled: true + #controlPlaneCidr: 172.16.0.0/12 + +istio: + enabled: true + ingressGateways: + passthrough-ingressgateway: + type: "LoadBalancer" + gateways: + passthrough: + ingressGateway: "passthrough-ingressgateway" + hosts: + - "*.{{ .Values.domain }}" + tls: + mode: "PASSTHROUGH" + public: + tls: + key: "" # Gets added via chart/ingress-certs.yaml + cert: "" # Gets added via chart/ingress-certs.yaml + values: + hardened: + enabled: true + kiali: + dashboard: + auth: + strategy: "anonymous" + +jaeger: + enabled: false + sso: + enabled: false + client_id: dev_00eb8904-5b88-4c68-ad67-cec0d2e07aa6_jaeger + values: + istio: + hardened: + customAuthorizationPolicies: + - name: "allow-intranamespace-jaeger" + enabled: true + spec: + action: ALLOW + rules: + - from: + - source: + namespaces: + - jaeger + customServiceEntries: + - name: "cypress-service-entries-jaeger" + enabled: true + spec: + hosts: + - 'registry.npmjs.org' + - 'download.cypress.io' + - 'cdn.cypress.io' + - 'repo1.dso.mil' + - 'tracing.dev.bigbang.mil' + location: MESH_EXTERNAL + ports: + - number: 443 + protocol: TLS + name: https + resolution: DNS + bbtests: + enabled: true + cypress: + envs: + cypress_url: "https://tracing.dev.bigbang.mil" + # uncomment following variables for sso keycloak testing in bb + # cypress_tnr_username: "cypress" + # cypress_tnr_password: "tnr_w!G33ZyAt@C8" + # cypress_keycloak_test_enable: "true" + +kiali: + sso: + client_id: dev_00eb8904-5b88-4c68-ad67-cec0d2e07aa6_kiali + values: + istio: + hardened: + customServiceEntries: + - name: "cypress-service-entries-kiali" + enabled: true + spec: + hosts: + - 'kiali.dev.bigbang.mil' + - 'registry.npmjs.org' + - 'download.cypress.io' + - 'cdn.cypress.io' + - 'repo1.dso.mil' + location: MESH_EXTERNAL + ports: + - number: 443 + protocol: TLS + name: https + resolution: DNS + cr: + spec: + auth: + # if enabling the keycloak SSO integration test, comment out or change strategy to "openid". + # strategy defaults to "openid" + strategy: "anonymous" + resources: + limits: + cpu: "1" + bbtests: + enabled: true + cypress: + envs: + cypress_url: 'https://kiali.dev.bigbang.mil' + cypress_check_data: 'true' + # uncomment these next 3 lines if enabling the keycloak SSO integration test + #cypress_keycloak_test_enable: "true" + #cypress_keycloak_username: "cypress" + #cypress_keycloak_password: "tnr_w!G33ZyAt@C8" + resources: + requests: + cpu: 3 + memory: 4Gi + limits: + cpu: 3 + memory: 4Gi + + +clusterAuditor: + enabled: false + values: + resources: + requests: + cpu: 100m + memory: 256Mi + limits: {} + bbtests: + enabled: true + cypress: + envs: + cypress_grafana_url: 'https://grafana.dev.bigbang.mil' + cypress_prometheus_url: 'https://prometheus.dev.bigbang.mil' + cypress_url: 'https://grafana.dev.bigbang.mil/d/YBgRZG6Mz/opa-violations?orgId=1' + istio: + hardened: + customServiceEntries: + - name: "cypress-service-entries-cluster-auditor" + enabled: true + spec: + hosts: + - 'registry.npmjs.org' + - 'download.cypress.io' + - 'cdn.cypress.io' + - 'repo1.dso.mil' + - 'grafana.dev.bigbang.mil' + - 'prometheus.dev.bigbang.mil' + location: MESH_EXTERNAL + ports: + - number: 443 + protocol: TLS + name: https + resolution: DNS + +gatekeeper: + enabled: false + values: + replicas: 1 + controllerManager: + resources: + limits: {} + requests: + cpu: 100m + memory: 256Mi + + violations: + allowedCapabilities: + parameters: + excludedResources: + # Allows k3d load balancer containers to not drop capabilities + - istio-system/lb-port-.* + # Allow kyverno test vectors for Helm test + - default/c.? + - default/i.? + allowedDockerRegistries: + parameters: + excludedResources: + # Allows k3d load balancer containers to pull from public repos + - istio-system/lb-port-.* + # Allow argocd to deploy a test app in its cypress test + - argocd/guestbook-ui + # Allow kyverno test vectors for Helm test + - default/c.? + - default/i.? + allowedHostFilesystem: + parameters: + excludedResources: + - anchore/anchore-cypress-test + - argocd/argocd-cypress-test + - cluster-auditor/cluster-auditor-cypress-test + - fortify/fortify-cypress-test + - fortify/fortify-ssc-cypress-test + - gitlab/gitlab-cypress-test + - gitlab/gitlab-runner-cypress-test + - gitlab-runner/gitlab-runner-cypress-test + - harbor/harbor-cypress-test + - holocron/holocron-cypress-test + - jaeger/jaeger-cypress-test + - keycloak/keycloak-cypress-test + - kiali/kiali-cypress-test + - kyverno-reporter/kyverno-reporter-cypress-test + - logging/elasticsearch-kibana-cypress-test + - logging/loki-cypress-test + - mattermost/mattermost-cypress-test + - minio/minio-instance-cypress-test + - minio-operator/minio-operator-cypress-test + - monitoring/grafana-cypress-test + - monitoring/monitoring-cypress-test + - neuvector/neuvector-cypress-test + - nexus-repository-manager/nexus-repository-manager-cypress-test + - sonarqube/sonarqube-cypress-test + - tempo/tempo-cypress-test + - thanos/thanos-cypress-test + - twistlock/twistlock-cypress-test + - vault/vault-cypress-test + # Allow kyverno test vectors for Helm test + - default/restrict-host-path-mount-.? + - default/restrict-host-path-write-.? + - default/restrict-volume-types-.? + allowedIPs: + parameters: + excludedResources: + # Allow kyverno test vectors for Helm test + - default/restrict-external-ips-.? + allowedSecCompProfiles: + parameters: + excludedResources: + # Allows k3d load balancer containers to have an undefined defined seccomp + - istio-system/lb-port-.* + # Allow kyverno test vectors for Helm test + - default/c.? + - default/i.? + allowedUsers: + parameters: + excludedResources: + # Allows k3d load balancer containers to run as any user/group + - istio-system/lb-port-.* + # Allow kyverno test vectors for Helm test + - default/c.? + - default/i.? + bannedImageTags: + parameters: + excludedResources: + # Allow kyverno test vectors for Helm test + - default/c.? + - default/i.? + - default/not-me + containerRatio: + parameters: + excludedResources: + # Allows k3d load balancer containers to have undefined limits/requests + - istio-system/lb-port-.* + hostNetworking: + parameters: + excludedResources: + # Allows k3d load balancer containers to mount host ports + - istio-system/lb-port-.* + # Allow kyverno test vectors for Helm test + - default/disallow-host-namespaces-.? + - default/c.? + - default/i.? + noBigContainers: + parameters: + excludedResources: + # Allows k3d load balancer containers to have undefined limits/requests + - istio-system/lb-port-.* + noHostNamespace: + parameters: + excludedResources: + # Allow kyverno test vectors for Helm test + - default/disallow-host-namespaces-.? + noPrivilegedContainers: + parameters: + excludedResources: + # Allow kyverno test vectors for Helm test + - default/c.? + - default/i.? + noPrivilegedEscalation: + parameters: + excludedResources: + # Allows k3d load balancer containers to have undefined security context + - istio-system/lb-port-.* + # Allow kyverno test vectors for Helm test + - default/c.? + - default/i.? + noSysctls: + parameters: + excludedResources: + # Allow kyverno test vectors for Helm test + - default/restrict-sysctls-.? + readOnlyRoot: + parameters: + excludedResources: + # Allows k3d load balancer containers to mount filesystems read/write + - istio-system/lb-port-.* + # Allow kyverno test vectors for Helm test + - default/c.? + - default/i.? + requiredLabels: + parameters: + excludedResources: + # Allows k3d load balancer pods to not have required labels + - istio-system/svclb-.* + # Allow kyverno test vectors for Helm test + - default/require-labels-.? + requiredProbes: + parameters: + excludedResources: + # Allows k3d load balancer containers to not have readiness/liveness probes + - istio-system/lb-port-.* + # Allow kyverno test vectors for Helm test + - default/c.? + - default/i.? + restrictedTaint: + parameters: + excludedResources: + # Allow kyverno test vectors for Helm test + - default/disallow-tolerations-.? + selinuxPolicy: + parameters: + excludedResources: + # Allow kyverno test vectors for Helm test + - default/c.? + - default/i.? + - default/disallow-selinux-options-.? + - default/restrict-selinux-type-.? + - default/not-me + volumeTypes: + parameters: + excludedResources: + - anchore/anchore-cypress-test + - argocd/argocd-cypress-test + - cluster-auditor/cluster-auditor-cypress-test + - fortify/fortify-ssc-cypress-test + - gitlab/gitlab-cypress-test + - gitlab/gitlab-runner-cypress-test + - gitlab-runner/gitlab-runner-cypress-test + - harbor/harbor-cypress-test + - holocron/holocron-cypress-test + - jaeger/jaeger-cypress-test + - keycloak/keycloak-cypress-test + - kiali/kiali-cypress-test + - kyverno-reporter/kyverno-reporter-cypress-test + - logging/elasticsearch-kibana-cypress-test + - logging/loki-cypress-test + - mattermost/mattermost-cypress-test + - minio/minio-instance-cypress-test + - minio-operator/minio-operator-cypress-test + - monitoring/grafana-cypress-test + - monitoring/monitoring-cypress-test + - neuvector/neuvector-cypress-test + - nexus-repository-manager/nexus-repository-manager-cypress-test + - sonarqube/sonarqube-cypress-test + - tempo/tempo-cypress-test + - thanos/thanos-cypress-test + - twistlock/twistlock-cypress-test + - vault/vault-cypress-test + # Allow kyverno test vectors for Helm test + - default/restrict-host-path-mount-.? + - default/restrict-host-path-write-.? + - default/restrict-volume-types-.? + +kyverno: + values: + networkPolicies: + externalRegistries: + allowEgress: true + admissionController: + container: + extraArgs: + webhookTimeout: 30 + resources: + limits: + cpu: 1 + memory: 768Mi + requests: + cpu: 1 + memory: 768Mi + bbtests: + enabled: true + +kyvernoReporter: + values: + bbtests: + enabled: true + cypress: + envs: + cypress_grafana_url: https://grafana.dev.bigbang.mil + cypress_prometheus_url: https://prometheus.dev.bigbang.mil + cypress_check_datasource: 'true' + resources: + requests: + cpu: 2 + memory: 3Gi + limits: + cpu: 2 + memory: 3Gi + istio: + hardened: + customServiceEntries: + - name: "cypress-service-entries-kyvernoreporter" + enabled: true + spec: + hosts: + - 'registry.npmjs.org' + - 'download.cypress.io' + - 'cdn.cypress.io' + - 'repo1.dso.mil' + - 'prometheus.dev.bigbang.mil' + location: MESH_EXTERNAL + exportTo: + - "." + ports: + - number: 443 + protocol: TLS + name: https + resolution: DNS + + +kyvernoPolicies: + values: + bbtests: + enabled: true + excludeContainers: + - not-me + - or-me + exclude: + any: + # Allows k3d load balancer to bypass policies. + - resources: + namespaces: + - istio-system + names: + - svclb-* + # Exclude gatekeeper test resources so Helm tests will work + - resources: + namespaces: + - default + names: + - bad-test* + - good-test* + # Parameters are copied from kyverno policies for test vectors + # Exclusions are for allowing other helm tests to function + policies: + clone-configs: + parameters: + clone: + - name: clone-configs-1 + kind: ConfigMap + namespace: "{{ .Release.Namespace }}" + - name: clone-configs-2 + kind: Secret + namespace: "{{ .Release.Namespace }}" + disallow-annotations: + parameters: + disallow: + - 'kyverno-policies-bbtest/test: disallowed' + - kyverno-policies-bbtest/disallowed + disallow-labels: + parameters: + disallow: + - 'kyverno-policies-bbtest/test: disallowed' + - kyverno-policies-bbtest/disallowed + disallow-tolerations: + parameters: + disallow: + - effect: NoSchedule + key: notallowed + value: 'false' + - effect: '*NoSchedule' + key: disa??owed + value: 'true' + require-annotations: + parameters: + require: + - 'kyverno-policies-bbtest/test: required' + - kyverno-policies-bbtest/required + require-image-signature: + enabled: false + # set to Audit for now -- having signature issues with registry1.dso.mil/ironbank/bitnami/redis:7.0.0-debian-10-r3 + validationFailureAction: Audit + parameters: + require: + - imageReferences: + - "ghcr.io/kyverno/test-verify-image:*" + attestors: + - count: 1 + entries: + - keys: + publicKeys: |- + -----BEGIN PUBLIC KEY----- + MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE8nXRh950IZbRj8Ra/N9sbqOPZrfM + 5/KAQN0/KjHcorm/J5yctVd7iEcnessRQjU917hmKO6JWVGHpDguIyakZA== + -----END PUBLIC KEY----- + # Skip Rekor Transparency log check + rekor: + ignoreTlog: true + url: "" + mutateDigest: false + verifyDigest: false + - imageReferences: + - "registry1.dso.mil/ironbank/*" + attestors: + - count: 1 + entries: + - keys: + publicKeys: |- + -----BEGIN PUBLIC KEY----- + MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE7CjMGH005DFFz6mffqTIGurBt6fL + UfTZxuEDFRBS8mFJx1xw8DEVvjMibLTtqmAoJxUmzmGFgzz+LV875syVEg== + -----END PUBLIC KEY----- + # Skip Rekor Transparency log check + rekor: + ignoreTlog: true + url: "" + # Ironbank images are rebuilt nightly and tags are not immutable + mutateDigest: false + verifyDigest: false + require-labels: + parameters: + require: + - 'kyverno-policies-bbtest/test: required' + - kyverno-policies-bbtest/required + restrict-external-ips: + parameters: + allow: + - 192.168.0.1 + restrict-external-names: + parameters: + allow: + - allowed + restrict-host-path-mount: + exclude: + any: + - resources: + namespaces: + - anchore + - gitlab + - gitlab-runner + - kiali + - cluster-auditor + - mattermost + - nexus-repository-manager + - keycloak + - jaeger + - kyverno-reporter + - monitoring + - vault + - logging + - twistlock + - sonarqube + - logging + - tempo + - argocd + - minio + - minio-operator + - neuvector + - harbor + - fortify + - thanos + - holocron + - alloy + names: + - "*-cypress-test*" + parameters: + allow: + - /tmp/allowed + restrict-host-path-mount-pv: + parameters: + allow: + - /tmp/allowed + - /var/lib/rancher/k3s/storage/pvc-* + restrict-host-path-write: + exclude: + any: + - resources: + namespaces: + - anchore + - gitlab + - gitlab-runner + - kiali + - cluster-auditor + - mattermost + - nexus-repository-manager + - keycloak + - kyverno-reporter + - jaeger + - monitoring + - vault + - logging + - twistlock + - sonarqube + - logging + - tempo + - argocd + - minio + - minio-operator + - neuvector + - harbor + - fortify + - thanos + - holocron + - alloy + names: + - "*-cypress-test*" + - resources: + namespaces: + - neuvector + names: + - "neuvector-enforcer-*" + - "neuvector-manager-*" + parameters: + allow: + - /tmp/allowed + restrict-host-ports: + parameters: + allow: + - '63999' + - '>= 64000 & < 65000' + - '> 65000' + restrict-volume-types: + exclude: + any: + - resources: + namespaces: + - anchore + - gitlab + - gitlab-runner + - kiali + - cluster-auditor + - mattermost + - nexus-repository-manager + - keycloak + - kyverno-reporter + - jaeger + - monitoring + - vault + - logging + - twistlock + - sonarqube + - logging + - tempo + - argocd + - minio + - minio-operator + - neuvector + - harbor + - fortify + - thanos + - holocron + - alloy + names: + - "*-cypress-test*" + update-image-registry: + parameters: + update: + - from: replace.image.registry + to: registry1.dso.mil + require-drop-all-capabilities: + exclude: + any: + # Twistlock Defenders run as root to perform real time scanning on the nodes/cluster + - resources: + namespaces: + - twistlock + names: + - twistlock-defender-ds* + # Neuvector needs access to host to inspect network traffic + - resources: + namespaces: + - neuvector + names: + - neuvector-enforcer-pod* + - neuvector-controller-pod* + - neuvector-prometheus-exporter-pod* + - resources: + namespaces: + - argocd + names: + - guestbook-ui-* + require-non-root-group: + exclude: + any: + - resources: + namespaces: + - fortify + names: + - fortify-mysql-* # mysql breaks if you give it a different group + - resources: + namespaces: + - metallb-system + names: + - speaker-* + - controller-* + - resources: + namespaces: + - velero + names: + - velero-backup-restore-test* + - resources: + namespaces: + - alloy + names: + - alloy-config-validator* + - alloy-config-analysis* + - alloy-test* + require-non-root-user: + exclude: + any: + - resources: + namespaces: + - metallb-system + names: + - speaker-* + - resources: + namespaces: + - argocd + names: + - guestbook* + - resources: + namespaces: + - velero + names: + - velero-backup-restore-test* + - resources: + namespaces: + - twistlock + names: + - volume-upgrade-job* + - resources: + namespaces: + - alloy + names: + - alloy-config-validator* + - alloy-config-analysis* + - alloy-test* + require-non-root-user: + disallow-namespaces: + parameters: + disallow: + - bigbang + +eckOperator: + # -- Toggle deployment of ECK Operator. + enabled: false + values: + istio: + hardened: + customServiceEntries: + - name: "cypress-service-entries-eckoperator" + enabled: true + spec: + hosts: + - 'registry.npmjs.org' + - 'download.cypress.io' + - 'cdn.cypress.io' + - 'repo1.dso.mil' + location: MESH_EXTERNAL + ports: + - number: 443 + protocol: TLS + name: https + resolution: DNS + +elasticsearchKibana: + enabled: false + sso: + enabled: false + client_id: dev_00eb8904-5b88-4c68-ad67-cec0d2e07aa6_kibana + license: + trial: false + values: + istio: + hardened: + customServiceEntries: + - name: "cypress-service-entries-elasticsearchkibana" + enabled: true + spec: + hosts: + - 'kibana.dev.bigbang.mil' + location: MESH_EXTERNAL + ports: + - number: 443 + protocol: TLS + name: https + resolution: DNS + elasticsearch: + master: + count: 1 + persistence: + size: 256Mi + resources: + requests: + cpu: .5 + limits: {} + heap: + min: 1g + max: 1g + data: + count: 2 + persistence: + size: 256Mi + resources: + requests: + cpu: .5 + limits: {} + heap: + min: 1g + max: 1g + kibana: + count: 1 + bbtests: + enabled: true + cypress: + envs: + cypress_kibana_url: "https://kibana.dev.bigbang.mil" + resources: + requests: + cpu: "2" + memory: "4Gi" + limits: + cpu: "2" + memory: "4Gi" + +fluentbit: + enabled: false + values: + istio: + hardened: + customServiceEntries: + - name: "cypress-service-entries-fluentbit" + enabled: true + spec: + hosts: + - 'registry.npmjs.org' + - 'download.cypress.io' + - 'cdn.cypress.io' + - 'repo1.dso.mil' + location: MESH_EXTERNAL + ports: + - number: 443 + protocol: TLS + name: https + + securityContext: + privileged: true + bbtests: + enabled: true + + +loki: + strategy: scalable + values: + istio: + loki: + enabled: true + hardened: + customServiceEntries: + - name: "cypress-service-entries-loki" + enabled: true + spec: + hosts: + - 'registry.npmjs.org' + - 'download.cypress.io' + - 'cdn.cypress.io' + - 'repo1.dso.mil' + - 'grafana.dev.bigbang.mil' + - 'optimizationguide-pa.googleapis.com' + - 'clientservices.googleapis.com' + - 'accounts.google.com' + - 'redirector.gvt1.com' + - 'content-autofill.googleapis.com' + - 'safebrowsing.googleapis.com' + location: MESH_EXTERNAL + ports: + - number: 443 + protocol: TLS + name: https + resolution: DNS + + minio: + enabled: true + write: + replicas: 3 + persistence: + size: 2Gi + resources: + limits: + cpu: 1 + memory: 1G + requests: + cpu: 1 + memory: 1G + backend: + replicas: 3 + persistence: + size: 2Gi + resources: + limits: + cpu: 500m + memory: 1G + requests: + cpu: 500m + memory: 1G + read: + replicas: 3 + persistence: + size: 2Gi + resources: + limits: + cpu: 400m + memory: 500Mi + requests: + cpu: 400m + memory: 500Mi + bbtests: + enabled: true + cypress: + envs: + cypress_check_datasource: 'true' + cypress_grafana_url: 'https://grafana.dev.bigbang.mil' + scripts: + envs: + LOKI_URL: 'http://logging-loki-write.logging.svc:3100' + +tempo: + sso: + enabled: false + client_id: dev_00eb8904-5b88-4c68-ad67-cec0d2e07aa6_tempo + values: + istio: + tempoQuery: + hosts: + - "tempo.{{ .Values.domain }}" + enabled: true + hardened: + customServiceEntries: + - name: "cypress-service-entries-tempo" + enabled: true + spec: + hosts: + - 'registry.npmjs.org' + - 'download.cypress.io' + - 'cdn.cypress.io' + - 'repo1.dso.mil' + - 'tempo.dev.bigbang.mil' + - 'grafana.dev.bigbang.mil' + - 'grafana.com' + location: MESH_EXTERNAL + ports: + - number: 443 + protocol: TLS + name: https + resolution: DNS + + tempo: + resources: + limits: null + requests: + cpu: 200m + memory: 128Mi + bbtests: + enabled: true + cypress: + envs: + cypress_url: 'https://tempo.dev.bigbang.mil' + cypress_tempo_datasource: 'http://tempo-tempo.tempo.svc:3100' + cypress_check_datasource: 'true' + cypress_grafana_url: 'https://grafana.dev.bigbang.mil' + # uncomment following variables for sso keycloak testing in bb + #cypress_tnr_username: "cypress" + #cypress_tnr_password: "tnr_w!G33ZyAt@C8" + #cypress_keycloak_test_enable: "true" + scripts: + enabled: false + envs: + TEMPO_METRICS_URL: 'http://tempo-tempo.tempo.svc:3100' + + persistence: + size: 5Gi + + tempoQuery: + resources: + limits: null + requests: + cpu: 200m + memory: 128Mi + +promtail: + enabled: true + +monitoring: + flux: + timeout: 20m + install: + disableOpenAPIValidation: true + crds: CreateReplace + upgrade: + disableOpenAPIValidation: true + crds: CreateReplace + sso: + prometheus: + client_id: dev_00eb8904-5b88-4c68-ad67-cec0d2e07aa6_prometheus + alertmanager: + client_id: dev_00eb8904-5b88-4c68-ad67-cec0d2e07aa6_alertmanager + values: + istio: + hardened: + customServiceEntries: + - name: "cypress-service-entries-monitoring" + enabled: true + spec: + hosts: + - 'registry.npmjs.org' + - 'download.cypress.io' + - 'cdn.cypress.io' + - 'repo1.dso.mil' + - 'prometheus.dev.bigbang.mil' + - 'grafana.dev.bigbang.mil' + - 'alertmanager.dev.bigbang.mil' + location: MESH_EXTERNAL + ports: + - number: 443 + protocol: TLS + name: https + resolution: DNS + + kube-state-metrics: + resources: + requests: + cpu: 10m + memory: 32Mi + limits: {} + prometheus-node-exporter: + resources: + requests: + cpu: 100m + memory: 30Mi + limits: {} + bbtests: + enabled: true + cypress: + envs: + cypress_bigbang_integration: 'true' + cypress_prometheus_url: 'https://prometheus.dev.bigbang.mil' + cypress_grafana_url: 'https://grafana.dev.bigbang.mil' + cypress_alertmanager_url: 'https://alertmanager.dev.bigbang.mil' + cypress_check_istio_dashboards: 'true' + cypress_keycloak_test_enable: 'false' + cypress_tnr_username: "cypress" + cypress_tnr_password: "tnr_w!G33ZyAt@C8" + +grafana: + sso: + grafana: + client_id: dev_00eb8904-5b88-4c68-ad67-cec0d2e07aa6_grafana + scopes: "openid Grafana" + values: + istio: + hardened: + customServiceEntries: + - name: "cypress-service-entries-grafana" + enabled: true + spec: + hosts: + - 'registry.npmjs.org' + - 'download.cypress.io' + - 'cdn.cypress.io' + - 'repo1.dso.mil' + - 'grafana.dev.bigbang.mil' + location: MESH_EXTERNAL + ports: + - number: 443 + protocol: TLS + name: https + resolution: DNS + dashboards: + default: + k8s-deployment: + gnetId: 741 + revision: 1 + datasource: Prometheus + dashboardProviders: + dashboardproviders.yaml: + apiVersion: 1 + providers: + - name: 'default' + orgId: 1 + folder: '' + type: file + disableDeletion: false + editable: true + options: + path: /var/lib/grafana/dashboards + bbtests: + enabled: true + cypress: + envs: + cypress_grafana_url: 'https://grafana.dev.bigbang.mil' + +neuvector: + values: + enforcer: + podAnnotations: + sidecar.istio.io/proxyMemoryLimit: "2Gi" + k3s: + enabled: true + istio: + enabled: true + hardened: + customServiceEntries: + - name: "cypress-service-entries-neuvector" + enabled: true + spec: + hosts: + - 'registry.npmjs.org' + - 'download.cypress.io' + - 'cdn.cypress.io' + - 'repo1.dso.mil' + - 'neuvector.dev.bigbang.mil' + location: MESH_EXTERNAL + ports: + - number: 443 + protocol: TLS + name: https + resolution: DNS + bbtests: + enabled: true + cypress: + envs: + cypress_url: https://neuvector.dev.bigbang.mil + +twistlock: + enabled: false + sso: + enabled: false + client_id: dev_00eb8904-5b88-4c68-ad67-cec0d2e07aa6_twistlock-saml + values: + istio: + hardened: + customServiceEntries: + - name: "cypress-service-entries-twistlock" + enabled: true + spec: + hosts: + - 'registry.npmjs.org' + - 'download.cypress.io' + - 'cdn.cypress.io' + - 'repo1.dso.mil' + - 'twistlock.dev.bigbang.mil' + location: MESH_EXTERNAL + exportTo: + - "." + ports: + - number: 443 + protocol: TLS + name: https + resolution: DNS + console: + persistence: + size: 5Gi + localVolumeUpgrade: true + defender: + dockerSocket: "/run/k3s/containerd/containerd.sock" + selinux: false + bbtests: + enabled: true + scripts: + envs: + twistlock_host: "https://twistlock.dev.bigbang.mil" + +# Addons are toggled based on labels in CI +addons: + argocd: + enabled: false + sso: + enabled: false + client_id: dev_00eb8904-5b88-4c68-ad67-cec0d2e07aa6_argocd + client_secret: anything-for-dev + groups: | + g, Impact Level 2 Authorized, role:admin + values: + sso: + rbac: + policy.default: role:admin + controller: + resources: + requests: + memory: 2Gi + redis-bb: + master: + persistence: + size: 512Mi + replica: + replicaCount: 0 + autoscaling: + enabled: false + persistence: + size: 512Mi + redis: + resources: + requests: + memory: 256Mi + repoServer: + resources: + requests: + cpu: 50m + memory: 128Mi + configs: + secret: + argocdServerAdminPassword: '$2a$10$rUDZDckdDZ2TEwk9PDs3QuqjkL58qR1IHE1Kj4MwDx.7/m5dytZJm' + bbtests: + enabled: true + cypress: + envs: + cypress_url: "https://argocd.dev.bigbang.mil" + resources: + limits: + memory: 12Gi + scripts: + envs: + ARGOCD_SERVER: "https://argocd.dev.bigbang.mil" + istio: + sidecar: + resources: + cpu: + requests: 100m + limits: 2000m + memory: + requests: 512Mi + limits: 2048Mi + istio: + hardened: + customServiceEntries: + - name: "cypress-service-entries-argocd" + enabled: true + spec: + hosts: + - 'registry.npmjs.org' + - 'download.cypress.io' + - 'cdn.cypress.io' + - 'repo1.dso.mil' + - 'argocd.dev.bigbang.mil' + location: MESH_EXTERNAL + ports: + - number: 443 + protocol: HTTPS + name: https + - number: 80 + protocol: HTTP + name: http + resolution: DNS + + authservice: + enabled: false + chains: + minimal: + callback_uri: "https://minimal.dev.bigbang.mil/login" + values: + resources: + requests: + memory: 100Mi + redis: + enabled: true + redis-bb: + master: + persistence: + size: 256Mi + replica: + replicaCount: 0 + autoscaling: + enabled: false + persistence: + size: 256Mi + + fortify: + enabled: false + flux: + timeout: 15m + ingress: + gateway: "" + sso: + enabled: false + values: + istio: + hardened: + customServiceEntries: + - name: "cypress-service-entries-fortify" + enabled: true + spec: + hosts: + - 'registry.npmjs.org' + - 'download.cypress.io' + - 'cdn.cypress.io' + - 'fortify.dev.bigbang.mil' + - 'repo1.dso.mil' + location: MESH_EXTERNAL + ports: + - number: 443 + protocol: TLS + name: https + resolution: DNS + storage: + volume: 5Gi + jvmMaxRAMPercentage: 85 + databaseSecret: + useRoot: true + initContainer: + resources: + limits: + cpu: 1 + memory: 500Mi + fortify_autoconfig: | + appProperties: + host.validation: false + datasourceProperties: + db.username: root + db.password: password + jdbc.url: 'jdbc:mysql://fortify-mysql:3306/ssc_db?sessionVariables=collation_connection=latin1_general_cs&rewriteBatchedStatements=true' + dbMigrationProperties: + migration.enabled: true + migration.username: root + migration.password: password + mysql: + primary: + resources: + limits: + cpu: 2 + memory: 2Gi + requests: + cpu: 100m + memory: 500Mi + secondary: + resources: + limits: + cpu: 100m + memory: 500Mi + requests: + cpu: 100m + memory: 500Mi + metrics: + resources: + limits: + cpu: 100m + memory: 500Mi + bbtests: + enabled: true + cypress: # note `cypress:*`` is different than in the fortify chart test-values.yaml + envs: + cypress_url: "https://fortify.dev.bigbang.mil" + + gitlab: + enabled: false + sso: + enabled: false + client_id: dev_00eb8904-5b88-4c68-ad67-cec0d2e07aa6_gitlab + flux: + timeout: 30m + values: + istio: + enabled: true + hardened: + customServiceEntries: + - name: "cypress-service-entries-gitlab" + enabled: true + spec: + hosts: + - 'registry.npmjs.org' + - 'download.cypress.io' + - 'cdn.cypress.io' + - 'gitlab.dev.bigbang.mil' + - "registry.dev.bigbang.mil" + - 'keycloak.dev.bigbang.mil' + - 'repo1.dso.mil' + - 'registry1.dso.mil' + - 'ib-prod-harbor-storage.s3.us-gov-west-1.amazonaws.com' + - 'ib-prod-harbor-storage.s3.us-gov-east-1.amazonaws.com' + location: MESH_EXTERNAL + ports: + - number: 443 + protocol: TLS + name: https + resolution: DNS + global: + rails: + bootstrap: + enabled: false + gitlab-runner: + resources: + requests: + cpu: 10m + gitlab: + webservice: + minReplicas: 1 + maxReplicas: 1 + sidekiq: + minReplicas: 1 + maxReplicas: 1 + gitlab-shell: + minReplicas: 1 + maxReplicas: 1 + gitaly: + persistence: + size: 256Mi + shared-secrets: + resources: + requests: + cpu: 10m + migrations: + resources: + requests: + cpu: 10m + toolbox: + persistence: + size: 256Mi + resources: + requests: + cpu: 10m + registry: + hpa: + minReplicas: 1 + maxReplicas: 1 + postgresql: + persistence: + size: 256Mi + metrics: + resources: + requests: + cpu: 10m + minio: + persistence: + size: 256Mi + resources: + requests: + cpu: 50m + redis: + master: + persistence: + size: 256Mi + slave: + persistence: + size: 256Mi + bbtests: + # TODO: turn these back on once we get 2.39.0 out the door, provided we've managed to fix or remove the failing gitlab script tests + enabled: false + #cypress: + # envs: + # cypress_url: https://gitlab.dev.bigbang.mil + # scripts: + # envs: + # GITLAB_REPOSITORY: https://gitlab.dev.bigbang.mil + # GITLAB_ORIGIN: https://testuser:Password123h56a78@gitlab.dev.bigbang.mil + # GITLAB_REGISTRY: registry.dev.bigbang.mil + + gitlabRunner: + enabled: false + values: + istio: + enabled: true + hardened: + customServiceEntries: + - name: "cypress-service-entries-gitlab-runner" + enabled: true + spec: + hosts: + - 'registry.npmjs.org' + - 'download.cypress.io' + - 'cdn.cypress.io' + - 'gitlab.dev.bigbang.mil' + - 'repo1.dso.mil' + location: MESH_EXTERNAL + ports: + - number: 443 + protocol: TLS + name: https + resolution: DNS + resources: + requests: + memory: 64Mi + cpu: 50m + limits: {} + runners: + protected: false + networkPolicies: + additionalPolicies: + - name: egress-runner-jobs + spec: + podSelector: {} + policyTypes: + - Egress + egress: + - to: + - ipBlock: + cidr: 0.0.0.0/0 + bbtests: + enabled: true + cypress: + resources: + requests: + cpu: 2 + memory: 4Gi + limits: + cpu: 4 + memory: 6Gi + envs: + cypress_url: "https://gitlab.dev.bigbang.mil" + cypress_gitlab_first_name: "testrunner" + cypress_gitlab_last_name: "userrunner" + cypress_gitlab_email: "gitlab@dev.bigbang.mil" + cypress_gitlab_username: "gitlabrunner_user" + cypress_gitlab_password: "Runner_PaSsw0rd123" + + anchore: + enabled: false + sso: + enabled: false + client_id: dev_00eb8904-5b88-4c68-ad67-cec0d2e07aa6_anchore + enterprise: + licenseYaml: | + "TBD" + values: + istio: + enabled: true + hardened: + customServiceEntries: + - name: "anchore-allow-cypress-tests" + enabled: true + spec: + hosts: + - 'registry.npmjs.org' + - 'download.cypress.io' + - 'cdn.cypress.io' + - 'repo1.dso.mil' + - 'auth.docker.io' + - 'registry-1.docker.io' + - 'anchore.dev.bigbang.mil' + location: MESH_EXTERNAL + ports: + - number: 443 + protocol: TLS + name: https + resolution: DNS + ensureDbJobs: + resources: + requests: + cpu: 100m + memory: 200Mi + sso: + resources: + requests: + memory: 200Mi + postgresql: + persistence: + size: 256Mi + resources: + requests: + memory: 1024Mi + metrics: + resources: + requests: + memory: 200Mi + analyzer: + replicaCount: 1 + resources: + requests: + cpu: 100m + memory: 200Mi + api: + resources: + requests: + cpu: 100m + memory: 200Mi + catalog: + resources: + requests: + cpu: 100m + memory: 200Mi + policyEngine: + resources: + requests: + cpu: 100m + memory: 200Mi + simpleQueue: + resources: + requests: + cpu: 100m + memory: 200Mi + upgradeJob: + resources: + requests: + cpu: 100m + memory: 200Mi + feeds: + resources: + requests: + cpu: 100m + memory: 200Mi + feeds-db: + resources: + requests: + memory: 200Mi + metrics: + resources: + requests: + memory: 200Mi + feedsUpgradeJob: + resources: + requests: + cpu: 100m + memory: 200Mi + rbacManager: + resources: + requests: + cpu: 100m + memory: 200Mi + reports: + resources: + requests: + cpu: 100m + memory: 200Mi + notifications: + resources: + requests: + cpu: 100m + memory: 200Mi + ui: + resources: + requests: + cpu: 100m + memory: 200Mi + ui-redis: + replica: + replicaCount: 0 + autoscaling: + enabled: false + bbtests: + enabled: true + scripts: + envs: + ANCHORE_CLI_URL: "https://anchore-api.dev.bigbang.mil/v1" + cypress: + envs: + cypress_url: "https://anchore.dev.bigbang.mil" + + + sonarqube: + enabled: false + sso: + enabled: false + client_id: dev_00eb8904-5b88-4c68-ad67-cec0d2e07aa6_saml-sonarqube + login: login + name: name + email: email + values: + istio: + hardened: + customAuthorizationPolicies: + - name: "allow-intranamespace-sonarqube" + enabled: true + spec: + action: ALLOW + rules: + - from: + - source: + namespaces: + - sonarqube + customServiceEntries: + - name: "sonarqube-allow-cypress-tests" + enabled: true + spec: + hosts: + - 'registry.npmjs.org' + - 'download.cypress.io' + - 'cdn.cypress.io' + - 'repo1.dso.mil' + - 'sonarqube.dev.bigbang.mil' + location: MESH_EXTERNAL + ports: + - number: 443 + protocol: TLS + name: https + resolution: DNS + plugins: + install: [] + resources: + requests: + cpu: 100m + memory: 200Mi + persistence: + size: 5Gi + postgresql: + persistence: + size: 256Mi + bbtests: + enabled: true + cypress: + envs: + cypress_url: "https://sonarqube.dev.bigbang.mil" + cypress_url_setup: "https://sonarqube.dev.bigbang.mil/setup" + account: + adminPassword: new_admin_password + currentAdminPassword: admin + curlContainerImage: registry1.dso.mil/ironbank/big-bang/base:2.0.0 + + minioOperator: + enabled: true # Minio Operator is required for Loki in default core + values: + console: + enabled: true + bbtests: + enabled: true + istio: + console: + enabled: false + hardened: + customAuthorizationPolicies: + - name: "allow-intranamespace-minio-operator" + enabled: true + spec: + action: ALLOW + rules: + - from: + - source: + namespaces: + - minio-operator + customServiceEntries: + - name: "cypress-service-entries-minio-operator" + enabled: true + spec: + hosts: + - 'registry.npmjs.org' + - 'download.cypress.io' + - 'cdn.cypress.io' + - 'repo1.dso.mil' + - 'minio-operator.dev.bigbang.mil' + location: MESH_EXTERNAL + exportTo: + - "." + ports: + - number: 443 + protocol: TLS + name: https + resolution: DNS + + minio: + enabled: false + values: + istio: + hardened: + customAuthorizationPolicies: + - name: "allow-intranamespace-minio" + enabled: true + spec: + action: ALLOW + rules: + - from: + - source: + namespaces: + - minio + - minio-operator + customServiceEntries: + - name: "cypress-service-entries-minio" + enabled: true + spec: + hosts: + - 'registry.npmjs.org' + - 'download.cypress.io' + - 'cdn.cypress.io' + - 'repo1.dso.mil' + - 'minio.dev.bigbang.mil' + - 'minio-api.dev.bigbang.mil' + location: MESH_EXTERNAL + exportTo: + - "." + ports: + - number: 443 + protocol: TLS + name: https + resolution: DNS + tenant: + pools: + - name: pool-0 + servers: 3 + volumesPerServer: 4 + size: 256Mi + resources: + requests: + cpu: 250m + memory: 2Gi + limits: + cpu: 250m + memory: 2Gi + securityContext: + runAsUser: 1001 + runAsGroup: 1001 + fsGroup: 1001 + runAsNonRoot: true + containerSecurityContext: + runAsUser: 1001 + runAsGroup: 1001 + runAsNonRoot: true + capabilities: + drop: + - ALL + + bbtests: + # There have been intermittent failures of the tests in the past. The issue is tracked in the below issue. + # https://repo1.dso.mil/big-bang/product/packages/minio/-/issues/7 + # This issue can be reopened if problems reappear. + enabled: true + cypress: + envs: + cypress_url: 'https://minio.dev.bigbang.mil/login' + scripts: + envs: + MINIO_PORT: '' + MINIO_HOST: 'https://minio-api.dev.bigbang.mil' + + mattermostOperator: + enabled: false + + mattermost: + enabled: false + sso: + enabled: false + client_id: dev_00eb8904-5b88-4c68-ad67-cec0d2e07aa6_mattermost + client_secret: "no-secret" + elasticsearch: + enabled: true + values: + enterprise: + enabled: true + monitoring: + enabled: true + istio: + hardened: + customServiceEntries: + - name: "cypress-service-entries-mattermost" + enabled: true + spec: + hosts: + - 'kiali.dev.bigbang.mil' + - 'registry.npmjs.org' + - 'download.cypress.io' + - 'cdn.cypress.io' + - 'repo1.dso.mil' + - 'grafana.dev.bigbang.mil' + - 'prometheus.dev.bigbang.mil' + location: MESH_EXTERNAL + ports: + - number: 443 + protocol: TLS + name: https + resolution: DNS + + postgresql: + persistence: + size: 256Mi + resources: + requests: + cpu: 100m + memory: 128Mi + limits: {} + minio: + tenant: + pools: + - name: pool-0 + servers: 1 + volumesPerServer: 4 + size: 256Mi + resources: + requests: + cpu: 250m + memory: 2Gi + limits: + cpu: 250m + memory: 2Gi + securityContext: + runAsUser: 1001 + runAsGroup: 1001 + fsGroup: 1001 + fsGroupChangePolicy: "OnRootMismatch" + runAsNonRoot: true + containerSecurityContext: + runAsUser: 1001 + runAsGroup: 1001 + runAsNonRoot: true + capabilities: + drop: + - ALL + bbtests: + enabled: true + cypress: + envs: + cypress_url: https://chat.dev.bigbang.mil + + nexusRepositoryManager: + enabled: false + # Nexus requires manual configuration in Keycloak client and cannot be tested with + # you must test with your own dev deployment. Example: keycloak.dev.bigbang.mil + # See more info in Nexus Package docs /docs/keycloak.md + # Nexus SSO is behind a paywall. You must have a valid license to enable SSO + # -- Base64 encoded license file. + # cat ~/Downloads/sonatype-license-YYYY-MM-ddTnnnnnnZ.lic | base64 -w 0 ; echo + #license_key: "enter-single-line-base64-encoded-string-here" + sso: + # -- https://support.sonatype.com/hc/en-us/articles/1500000976522-SAML-integration-for-Nexus-Repository-Manager-Pro-3-and-Nexus-IQ-Server-with-Keycloak#h_01EV7CWCYH3YKAPMAHG8XMQ599 + enabled: false + idp_data: + entityId: "https://nexus.dev.bigbang.mil/service/rest/v1/security/saml/metadata" + # -- IdP Field Mappings + # -- NXRM username attribute + username: "username" + firstName: "firstName" + lastName: "lastName" + email: "email" + groups: "groups" + role: + # id is the name of the Keycloak group (case sensitive) + - id: "Nexus" + name: "Keycloak Nexus Group" + description: "unprivilaged users" + privileges: [] + roles: [] + - id: "Nexus-Admin" + name: "Keycloak Nexus Admin Group" + description: "keycloak users as admins" + privileges: + - "nx-all" + roles: + - "nx-admin" + # NexusNotes: | + # Login to Nexus Admin UI and then get the x509 certificate from this path + # https://nexus.dev.bigbang.mil/service/rest/v1/security/saml/metadata + # copy and paste the nexus single line certificate into a text file and save it + # vi nexus-x509.txt + # -----BEGIN CERTIFICATE----- + # put-single-line-nexus-x509-certificate-here + # -----END CERTIFICATE----- + # make a valid pem file with proper wrapping at 64 characters per line + # fold -w 64 nexus-x509.txt > nexus.pem + # In Keycloak go to the nexus client and on the Keys tab import the nexus.pem file in two places + values: + persistence: + # Do NOT set this below 5Gi, nexus will fail to boot + storageSize: 5Gi + nexus: + # https://help.sonatype.com/repomanager3/installation/system-requirements#SystemRequirements-JVMDirectMemory + env: + - name: INSTALL4J_ADD_VM_PARAMS + value: "-Dcom.redhat.fips=false -Xms1024M -Xmx1024M -XX:MaxDirectMemorySize=1024M -XX:+UnlockExperimentalVMOptions -XX:+UseContainerSupport -Djava.util.prefs.userRoot=/nexus-data/javaprefs" + - name: NEXUS_SECURITY_RANDOMPASSWORD + value: "true" + resources: + requests: + cpu: 100m + memory: 1500Mi + docker: + enabled: true + registries: + - host: containers.dev.bigbang.mil + port: 5000 + repository: + enabled: true + repo: + - name: "containers" + format: "docker" + type: "hosted" + repo_data: + name: "containers" + online: true + storage: + blobStoreName: "default" + strictContentTypeValidation: true + writePolicy: "allow_once" + cleanup: + policyNames: + - "string" + component: + proprietaryComponents: true + docker: + v1Enabled: false + forceBasicAuth: true + httpPort: 5000 + istio: + enabled: true + hardened: + customServiceEntries: + - name: "cypress-service-entries-nexus" + enabled: true + spec: + exportTo: + - "." + hosts: + - 'registry.npmjs.org' + - 'download.cypress.io' + - 'cdn.cypress.io' + - 'repo1.dso.mil' + - 'registry1.dso.mil' + - 'ib-prod-harbor-storage.s3.us-gov-west-1.amazonaws.com' + - 'ib-prod-harbor-storage.s3.us-gov-east-1.amazonaws.com' + - 'nexus.dev.bigbang.mil' + - 'containers.dev.bigbang.mil' + location: MESH_EXTERNAL + ports: + - number: 443 + protocol: TLS + name: https + resolution: DNS + bbtests: + enabled: true + cypress: + envs: + cypress_nexus_url: "https://nexus.dev.bigbang.mil" + scripts: + envs: + docker_host: "containers.dev.bigbang.mil" + + velero: + enabled: false + plugins: + - aws + values: + istio: + hardened: + customServiceEntries: + - name: "cypress-service-entries-velero" + enabled: true + spec: + hosts: + - 'registry.npmjs.org' + - 'download.cypress.io' + - 'cdn.cypress.io' + - 'repo1.dso.mil' + exportTo: + - "." + location: MESH_EXTERNAL + ports: + - number: 443 + protocol: TLS + name: https + resolution: DNS + serviceAccount: + server: + name: velero + configuration: + backupStorageLocation: + - bucket: velero + provider: aws + default: true + config: + region: velero + s3ForcePathStyle: "true" + s3Url: https://minio-api.dev.bigbang.mil + volumeSnapshotLocation: + - name: default + provider: aws + config: + region: velero + credentials: + secretContents: + cloud: | + [default] + aws_access_key_id = minio + aws_secret_access_key = minio123 + cleanUpCRDs: true + bbtests: + enabled: true + scripts: + envs: + MINIO_HOST: https://minio-api.dev.bigbang.mil + + keycloak: + enabled: false + ingress: + gateway: "passthrough" + key: "" # Gets added via chart/ingress-certs.yaml + cert: "" # Gets added via chart/ingress-certs.yaml + values: + istio: + enabled: true + hardened: + customAuthorizationPolicies: + - name: "allow-intranamespace-keycloak" + enabled: true + spec: + action: ALLOW + rules: + - from: + - source: + namespaces: + - keycloak + resources: + requests: + cpu: 250m + memory: 250Mi + limits: {} + bbtests: + enabled: true + cypress: + envs: + cypress_url: "https://keycloak.dev.bigbang.mil" + command: + - "/opt/keycloak/bin/kc.sh" + args: + - "start" + - "--import-realm" + extraEnv: |- + - name: KC_HTTPS_CERTIFICATE_FILE + value: /opt/keycloak/conf/tls.crt + - name: KC_HTTPS_CERTIFICATE_KEY_FILE + value: /opt/keycloak/conf/tls.key + - name: KC_HTTPS_CLIENT_AUTH + value: request + - name: KC_HTTPS_TRUST_STORE_FILE + value: /opt/keycloak/conf/truststore.jks + - name: KC_HTTPS_TRUST_STORE_PASSWORD + value: password + - name: KC_HOSTNAME + value: keycloak.dev.bigbang.mil + - name: KC_HOSTNAME_STRICT + value: "true" + - name: KC_LOG_LEVEL + value: "org.keycloak.events:DEBUG,org.infinispan:INFO,org.jgroups:INFO" + secrets: + env: + stringData: + CUSTOM_REGISTRATION_CONFIG: /opt/keycloak/conf/customreg.yaml + customreg: + stringData: + customreg.yaml: '{{ .Files.Get "resources/dev/baby-yoda.yaml" }}' + realm: + stringData: + realm.json: '{{ .Files.Get "resources/dev/baby-yoda-bb-ci.json" }}' + truststore: + data: + truststore.jks: |- + {{ .Files.Get "resources/dev/truststore.jks" | b64enc }} + quarkusproperties: + stringData: + quarkus.properties: '{{ .Files.Get "resources/dev/quarkus.properties" }}' + extraInitContainers: |- + - name: plugin + image: registry1.dso.mil/ironbank/big-bang/p1-keycloak-plugin:3.5.7 + imagePullPolicy: Always + command: + - sh + - -c + - | + cp /app/p1-keycloak-plugin.jar /init + ls -l /init + volumeMounts: + - name: plugin + mountPath: "/init" + securityContext: + capabilities: + drop: + - ALL + extraVolumes: |- + - name: customreg + secret: + secretName: {{ include "keycloak.fullname" . }}-customreg + - name: realm + secret: + secretName: {{ include "keycloak.fullname" . }}-realm + - name: plugin + emptyDir: {} + - name: truststore + secret: + secretName: {{ include "keycloak.fullname" . }}-truststore + - name: quarkusproperties + secret: + secretName: {{ include "keycloak.fullname" . }}-quarkusproperties + defaultMode: 0777 + extraVolumeMounts: |- + - name: customreg + mountPath: /opt/keycloak/conf/customreg.yaml + subPath: customreg.yaml + readOnly: true + - name: realm + mountPath: /opt/keycloak/data/import/realm.json + subPath: realm.json + - name: plugin + mountPath: /opt/keycloak/providers/p1-keycloak-plugin.jar + subPath: p1-keycloak-plugin.jar + - name: truststore + mountPath: /opt/keycloak/conf/truststore.jks + subPath: truststore.jks + - name: quarkusproperties + mountPath: /opt/keycloak/conf/quarkus.properties + subPath: quarkus.properties + + vault: + enabled: false + ingress: + gateway: "passthrough" + key: "" # Gets added via chart/ingress-certs.yaml + cert: "" # Gets added via chart/ingress-certs.yaml + sso: + enabled: false + client_id: dev_00eb8904-5b88-4c68-ad67-cec0d2e07aa6_vault + values: + global: + tlsDisable: false + injector: + affinity: | + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 100 + podAffinityTerm: + labelSelector: + matchLabels: + app.kubernetes.io/name: {{ template "vault.name" . }}-agent-injector + app.kubernetes.io/instance: "{{ .Release.Name }}" + component: webhook + topologyKey: kubernetes.io/hostname + server: + extraEnvironmentVars: + VAULT_SKIP_VERIFY: "true" + VAULT_LOG_FORMAT: "json" + dataStorage: + size: 256Mi + auditStorage: + size: 256Mi + ha: + enabled: true + replicas: 1 + apiAddr: "https://vault.dev.bigbang.mil" + raft: + config: | + ui = true + + listener "tcp" { + tls_disable = false + address = "[::]:8200" + cluster_address = "[::]:8201" + tls_cert_file = "/vault/tls/tls.crt" + tls_key_file = "/vault/tls/tls.key" + telemetry { + unauthenticated_metrics_access = true + } + } + + storage "raft" { + path = "/vault/data" + + retry_join { + leader_api_addr = "https://vault-vault-0.vault-vault-internal:8200" + leader_client_cert_file = "/vault/tls/tls.crt" + leader_client_key_file = "/vault/tls/tls.key" + leader_tls_servername = "vault.dev.bigbang.mil" + } + } + + service_registration "kubernetes" {} + + config: | + ui = true + + listener "tcp" { + tls_disable = false + address = "[::]:8200" + cluster_address = "[::]:8201" + tls_cert_file = "/vault/tls/tls.crt" + tls_key_file = "/vault/tls/tls.key" + telemetry { + unauthenticated_metrics_access = true + } + } + + seal "awskms" { + region = "us-gov-west-1" + kms_key_id = "mrk-ff723da024254ea2b7f490c68fbc9b9b" + endpoint = "https://kms.us-gov-west-1.amazonaws.com" + } + + telemetry { + prometheus_retention_time = "24h" + disable_hostname = true + } + service_registration "kubernetes" {} + istio: + hardened: + customAuthorizationPolicies: + - name: allow-egress-instance-metadata + enabled: true + spec: + action: ALLOW + rules: + - from: + - source: + ipBlocks: + - 169.254.169.254/32 + bbtests: + enabled: true + cypress: + envs: + cypress_vault_url: "https://vault.dev.bigbang.mil" + + metricsServer: + enabled: false + values: + replicas: 1 + bbtests: + enabled: true + + # ---------------------------------------------------------------------------------------------------------------------- + # Harbor + # + harbor: + # -- Toggle deployment of harbor + enabled: false + + # -- Values to pass through to Harbor chart: https://repo1.dso.mil/big-bang/product/packages/harbor.git + values: + istio: + enabled: true + hardened: + customServiceEntries: + - name: "allow-npm-for-cypress-tests" + enabled: true + spec: + hosts: + - 'registry.npmjs.org' + - 'registry1.dso.mil' + - 'ib-prod-harbor-storage.s3.us-gov-west-1.amazonaws.com' + - 'ib-prod-harbor-storage.s3.us-gov-east-1.amazonaws.com' + - 'download.cypress.io' + - 'cdn.cypress.io' + - 'repo1.dso.mil' + - 'index.docker.io' + - 'auth.docker.io' + - 'production.cloudflare.docker.com' + location: MESH_EXTERNAL + ports: + - number: 443 + protocol: TLS + name: https + resolution: DNS + expose: + type: clusterIP + tls: + enabled: false + internalTLS: + enabled: false + externalURL: https://harbor.dev.bigbang.mil + nginx: + replicas: 2 + portal: + replicas: 2 + core: + replicas: 2 + secretName: "ci-only" + #jobservice: + #registry: + #registry: + #controller: + #chartmuseum: + trivy: + resources: + requests: + cpu: 160m + memory: 300Mi + limits: + cpu: 300m + memory: 500Mi + #notary: + #server: + #signer: + #database: + #internal: + #postgresql: + #redis: + exporter: + replicas: 2 + bbtests: + enabled: true + cypress: + artifacts: true + envs: + cypress_url: "https://harbor.dev.bigbang.mil" + scripts: + image: "registry1.dso.mil/bigbang-ci/devops-tester:1.1.1" + envs: + HARBOR_REGISTRY: "harbor.dev.bigbang.mil" + + # ---------------------------------------------------------------------------------------------------------------------- + # Thanos + # + thanos: + # -- Toggle deployment of thanos + enabled: false + sso: + enabled: false + client_id: dev_00eb8904-5b88-4c68-ad67-cec0d2e07aa6_thanos + values: + istio: + hardened: + customServiceEntries: + - name: "cypress-service-entries-thanos" + enabled: true + spec: + hosts: + - 'registry.npmjs.org' + - 'download.cypress.io' + - 'cdn.cypress.io' + - 'repo1.dso.mil' + - 'thanos.dev.bigbang.mil' + - 'grafana.dev.bigbang.mil' + location: MESH_EXTERNAL + ports: + - number: 443 + protocol: TLS + name: https + resolution: DNS + customAuthorizationPolicies: + - name: "allow-intranamespace-thanos" + enabled: true + spec: + action: ALLOW + rules: + - from: + - source: + namespaces: + - thanos + - monitoring + minio: + enabled: true + tenant: + pools: + - name: pool-0 + servers: 1 + volumesPerServer: 4 + size: 256Mi + resources: + requests: + cpu: 250m + memory: 2Gi + limits: + cpu: 250m + memory: 2Gi + securityContext: + runAsUser: 1001 + runAsGroup: 1001 + fsGroup: 1001 + runAsNonRoot: true + containerSecurityContext: + runAsUser: 1001 + runAsGroup: 1001 + runAsNonRoot: true + capabilities: + drop: + - ALL + storegateway: + enabled: true + compactor: + enabled: true + retentionResolutionRaw: 30d + retentionResolution5m: 30d + retentionResolution1h: 30d + bbtests: + enabled: true + cypress: + envs: + cypress_url: "https://thanos.dev.bigbang.mil" + cypress_prometheus_integration_enabled: "true" + cypress_objstorage_integration_enabled: "true" + scripts: + image: "registry1.dso.mil/bigbang-ci/gitlab-tester:0.0.4" + envs: + THANOS_REGISTRY: "thanos.dev.bigbang.mil" + objstoreConfig: |- + type: s3 + config: + bucket: "thanos" + endpoint: minio.thanos.svc.cluster.local:80 + access_key: "minio" + secret_key: "minio123" + insecure: true + trace: + enable: true + + # ---------------------------------------------------------------------------------------------------------------------- + # Holocron + # + holocron: + # -- Toggle deployment of holocron + enabled: false + sso: + enabled: false + client_id: dev_00eb8904-5b88-4c68-ad67-cec0d2e07aa6_holocron + values: + bbtests: + enabled: true + cypress: + resources: + requests: + cpu: "2" + memory: "2G" + limits: + cpu: "2" + memory: "2G" + + externalSecrets: + values: + istio: + hardened: + enabled: true + bbtests: + enabled: true + cypress: + artifacts: true