├── .gitignore ├── .gitlab-ci.yml ├── Makefile ├── Makefile-nordmart ├── README.md ├── configs ├── alertmanager.yaml ├── flux ├── flux.pub ├── imc.yaml ├── jenkins-maven-config.xml ├── jenkins.json ├── keycloak.json ├── nexus-admin-account.json ├── nexus-cluster-account.json ├── proxyinjector.yaml ├── sealed-secret-tls.cert ├── sealed-secret-tls.key └── secret-sealed-secret-tls-cert.yaml ├── docs ├── default-passwords.md ├── detailed-config.md └── images │ └── forecastle.png ├── images ├── aks.png ├── eks.png ├── forecastle.png ├── pipeline-flow.png └── rsz_aws.png ├── platform ├── control │ ├── descheduler.yaml │ ├── external-dns.yaml │ ├── external-ingress.yaml │ ├── forecastle.yaml │ ├── gitlabwebhookproxy.yaml │ ├── gitwebhookproxy.yaml │ ├── imc.yaml │ ├── internal-ingress.yaml │ ├── kubernetes-dashboard.yaml │ ├── reloader.yaml │ ├── secrets │ │ ├── secret-aws-creds.yaml │ │ ├── secret-imc-config.yaml │ │ └── secret-tls-cert.yaml │ └── xposer.yaml ├── crds │ ├── cr-uptimerobot.yaml │ ├── crd-alert-manager.yaml │ ├── crd-forecastle.yaml │ ├── crd-konfigurator.yaml │ ├── crd-prometheus-rules.yaml │ ├── crd-prometheus.yaml │ ├── crd-sealed-secrets.yaml │ └── crd-servicemonitor.yaml ├── delivery │ ├── jenkins-mvnstorage.yaml │ ├── jenkins-rbac-master.yaml │ ├── jenkins-rbac-slave.yaml │ ├── jenkins.yaml │ ├── nexus.yaml │ ├── pvc │ │ ├── jenkins-pvc.yaml │ │ └── nexus-pvc.yaml │ ├── rdlm.yaml │ └── secrets │ │ ├── secret-jenkins-dockercfg.yaml │ │ ├── secret-jenkins-maven.yaml │ │ ├── secret-jenkins-vc-api-tokens.yaml │ │ └── secret-slack-hook.yaml ├── flux │ ├── flux.yaml │ └── secrets │ │ └── secret-flux-key.yaml ├── istio │ ├── istio-config.yaml │ ├── istio-operator.yaml │ ├── jaeger-ingress.yaml │ ├── kiali-ingress.yaml │ └── secrets │ │ └── secret-kiali.yaml ├── logging │ ├── cerebro.yaml │ ├── elasticsearch-cluster-client.yaml │ ├── elasticsearch-cluster-data.yaml │ ├── elasticsearch-cluster-master.yaml │ ├── elasticsearch-curator.yaml │ ├── eventrouter.yaml │ ├── fluentd-es.yaml │ ├── kibana.yaml │ ├── konfigurator-template.yaml │ ├── konfigurator.yaml │ └── logrotate.yaml ├── monitoring │ ├── clusterrole.yaml │ ├── clusterrolebindings.yaml │ ├── grafana-cluster-health.yaml │ ├── grafana-deployment.yaml │ ├── grafana-ingress.yaml │ ├── grafana-jvm.yaml │ ├── grafana-micrometer.yaml │ ├── metrics-server.yaml │ ├── prometheus-operator.yaml │ ├── secrets │ │ ├── secret-alertmanager-config.yaml │ │ └── secret-grafana-creds.yaml │ └── service-account.yaml └── security │ ├── keycloak.yaml │ ├── postgresql.yaml │ ├── proxyinjector.yaml │ ├── sealed-secrets.yaml │ └── secrets │ ├── secret-keycloak-config.yaml │ ├── secret-keycloak-secrets.yaml │ ├── secret-postgres.yaml │ └── secret-proxyinjector-config.yaml ├── scripts ├── configure-nordmart.sh ├── configure.sh ├── destroy-nordmart.sh ├── destroy.sh ├── install.sh ├── run-tests.sh └── tests │ ├── control-stack.sh │ ├── delivery-stack.sh │ ├── logging-stack.sh │ ├── monitoring-stack.sh │ ├── security-stack.sh │ └── tracing-stack.sh ├── storageclass ├── aws.yaml ├── azure.yaml └── ibm.yaml ├── tiller-rbac.yaml └── variables.config /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/** 2 | configs/** 3 | variables.config 4 | -------------------------------------------------------------------------------- /.gitlab-ci.yml: -------------------------------------------------------------------------------- 1 | # pipeline base image 2 | image: 3 | name: stakater/builder-tool:terraform-0.12.7-v0.0.19 4 | 5 | # Configuring CI/CD environment variables 6 | variables: 7 | KUBE_CONFIG: "" 8 | REPO_ACCESS_TOKEN: "REPO_ACCESS_TOKEN" 9 | TARGET: "TARGET" 10 | USER_MAIL: "stakater@gmail.com" 11 | USER_NAME: "stakater-user" 12 | 13 | 14 | before_script: 15 | # Configuring kubernetes cluster access 16 | - echo "configuration kubernetes access in pipeline" 17 | - mkdir ~/.kube/ 18 | - if [ -n "$KUBE_CONFIG" ]; then 19 | - echo $KUBE_CONFIG | base64 -d > ~/.kube/config 20 | - else 21 | - echo "Using kubeconfig from configs" 22 | - cat configs/kube_config.yaml > ~/.kube/config 23 | - fi 24 | - export KUBECONFIG=~/.kube/config 25 | # Configure git access 26 | - git remote set-url origin https://$USER_NAME:$REPO_ACCESS_TOKEN@${CI_PROJECT_URL:8} 27 | - git config --global user.email $USER_MAIL 28 | - git config --global user.name $USER_NAME 29 | 30 | # pipeline stages 31 | stages: 32 | - execute 33 | 34 | execute: 35 | stage: execute 36 | script: 37 | - make $TARGET -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # Use this Makefile if you want to setup/deploy/destroy StakaterPlatform from devstation(local workstation;laptop, computer etc.) 2 | 3 | .ONESHELL: 4 | SHELL= /bin/bash 5 | 6 | include variables.config 7 | 8 | 9 | configure: 10 | git checkout $(STAKATER_PLATFORM_BRANCH) 2>/dev/null || git checkout -b $(STAKATER_PLATFORM_BRANCH) && \ 11 | yes | ssh-keygen -q -N "" -f ./configs/flux >/dev/null && \ 12 | openssl req -new -newkey rsa:4096 -days 365 -nodes -x509 -subj "/C=SE/ST=StakaterUser/L=Stockholm/O=Stakater/CN=www.example.com" -keyout ./configs/sealed-secret-tls.key -out ./configs/sealed-secret-tls.cert 2>/dev/null && \ 13 | bash scripts/configure.sh 14 | 15 | commit: un-track-secrets 16 | git add . && \ 17 | git commit -a -m "[skip ci] update vars for deployment" && \ 18 | git push -u origin $(STAKATER_PLATFORM_BRANCH) || true 19 | 20 | deploy: 21 | bash scripts/install.sh $(CLOUD_PROVIDER) 22 | 23 | deploy-flux: configure commit deploy 24 | 25 | pipeline-deploy: configure commit deploy 26 | 27 | verify: 28 | bash scripts/run-tests.sh 29 | 30 | destroy: 31 | bash scripts/destroy.sh 32 | 33 | destroy-nordmart: 34 | make -f Makefile-nordmart destroy 35 | 36 | deploy-nordmart-with-istio: 37 | make -f Makefile-nordmart deploy-nordmart-with-istio 38 | 39 | deploy-nordmart-without-istio: 40 | make -f Makefile-nordmart deploy-nordmart-without-istio 41 | 42 | track-secrets: 43 | git update-index --no-skip-worktree variables.config && \ 44 | git update-index --no-skip-worktree $(git ls-files | grep 'configs/') 45 | 46 | un-track-secrets: 47 | git update-index --skip-worktree variables.config && \ 48 | git update-index --skip-worktree $(git ls-files | grep 'configs/') 49 | 50 | .PHONY: configure deploy verify destroy -------------------------------------------------------------------------------- /Makefile-nordmart: -------------------------------------------------------------------------------- 1 | # Use this Makefile if you want to setup/deploy/destroy Nordmart on StakaterPlatform 2 | 3 | .ONESHELL: 4 | SHELL= /bin/bash 5 | 6 | include variables.config 7 | 8 | 9 | commit: 10 | git add platform/nordmart && \ 11 | git commit -a -m "[skip ci] add Nordmart deployment" && \ 12 | git push -u origin $(STAKATER_PLATFORM_BRANCH) || true 13 | 14 | clone-dev-apps: create-namespaces 15 | git checkout $(STAKATER_PLATFORM_BRANCH) && \ 16 | rm -rf platform/nordmart && \ 17 | git clone https://github.com/stakater-lab/nordmart-dev-apps.git platform/nordmart/ && \ 18 | rm -rf platform/nordmart/.git platform/nordmart/Makefile platform/nordmart/README.md platform/nordmart/.gitignore 19 | 20 | create-namespaces: 21 | kubectl apply -f https://raw.githubusercontent.com/stakater-lab/nordmart-dev-tools/master/tools/namespaces/nordmart-dev-apps.yaml 22 | kubectl apply -f https://raw.githubusercontent.com/stakater-lab/nordmart-dev-tools/master/tools/namespaces/nordmart-dev-tools.yaml 23 | 24 | configure: 25 | bash scripts/configure-nordmart.sh 26 | 27 | apply: 28 | kubectl apply -R -f platform/nordmart/ 29 | 30 | configure-with-istio: 31 | rm -rf platform/nordmart/releases 32 | wget https://raw.githubusercontent.com/stakater-lab/nordmart-dev-tools/master/tools-istio/external-dns.yaml -P platform/nordmart/releases-istio/ 33 | wget https://raw.githubusercontent.com/stakater-lab/nordmart-dev-tools/master/tools-istio/secrets/secret-external-dns.yaml -P platform/nordmart/releases-istio/ 34 | 35 | configure-without-istio: clone-dev-apps configure 36 | rm -rf platform/nordmart/releases-istio 37 | 38 | deploy-nordmart-with-istio: clone-dev-apps configure-with-istio configure commit apply 39 | 40 | deploy-nordmart-without-istio: clone-dev-apps configure-without-istio configure commit apply 41 | 42 | destroy: 43 | bash scripts/destroy-nordmart.sh 44 | 45 | .PHONY: commit clone-dev-apps create-namespaces configure apply configure-with-istio configure-without-istio deploy-nordmart-with-istio deploy-nordmart-without-istio destroy -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # StakaterPlatform 2 | 3 | ## Problem Statement 4 | 5 | When an individual or a company deploys a kubernetes cluster for workload management. *What is the next thing required*. Security, Monitoring, Logging, Tracing, Alerting and CI/CD for workloads, a lot of great opensource tools exist for these processes and selecting a tools based on industry's standards and recommendations is quite a hard & duanting task as it requires a lot of research that fulfill the requirements. 6 | 7 | ## Solution 8 | 9 | We at Stakater understand the industry's problem and keeping that in mind we have developed a consolidated solution named `StakaterPlatform` that will help the community to adopt Security, Monitoring, Logging, Tracing, Alerting and CI/CD processes for thier workloads. 10 | 11 | ## Introduction 12 | 13 | `StakaterPlatform` gives a head-start to individuals and companies with a set of seven stacks containing best of the breed opensource tools based on industry's recommendation and best practices for `monitoring`, `logging`, `security`, `tracing` and `alerting` of Kubernetes cluster. End-users only need to focus on developing their application while everything else will be managed by `StakaterPlatform`! 14 | 15 | `StakaterPlatform` uses community managed helm charts and docker images. 16 | 17 | For detailed walk-through please visit [StakaterPlatform on Stakater Playbook](https://playbook.stakater.com/content/stakaterplatform/stakaterplatform.html) 18 | 19 | StakaterPlatform consist of 7 stacks: 20 | 21 | - [Control](https://playbook.stakater.com/content/stakaterplatform/stakaterplatform.html#control-stack) 22 | - [Delivery](https://playbook.stakater.com/content/stakaterplatform/stakaterplatform.html#delivery-stack) 23 | - [Logging](https://playbook.stakater.com/content/stakaterplatform/stakaterplatform.html#logging-stack) 24 | - [Monitoring](https://playbook.stakater.com/content/stakaterplatform/stakaterplatform.html#monitoring-stack) 25 | - [Security](https://playbook.stakater.com/content/stakaterplatform/stakaterplatform.html#security-stack) 26 | - [Alerting](https://playbook.stakater.com/content/stakaterplatform/stakaterplatform.html#alerting-stack) 27 | - [Tracing](https://playbook.stakater.com/content/stakaterplatform/stakaterplatform.html#tracing-stack) 28 | 29 | Table for Stacks tools: 30 | 31 | | Control | Delivery | Logging | Monitoring | Security | Alerting | Tracing | 32 | |---|---|---|---|---|---|---| 33 | | [External DNS](https://github.com/kubernetes-sigs/external-dns) | [Jenkins](https://github.com/jenkinsci/jenkins) | Elasticsearch | [Prometheus Operator](https://github.com/coreos/prometheus-operator) | [Keycloak](https://github.com/keycloak/keycloak) | Uptime Robot | [Istio](https://istio.io/docs/reference/config/installation-options/) | 34 | | [Nginx Ingress](https://github.com/kubernetes/ingress-nginx) | [Sonatype-Nexus](https://github.com/sonatype/nexus-public) | Fluentd | [Metrics Server](https://github.com/coreos/prometheus-operator) | [Proxy Injector](https://github.com/stakater/proxyinjector) | Slack || 35 | | [Descheduler](https://github.com/kubernetes-sigs/descheduler) | RDLM | Eventrouter ||||| 36 | | [Forecastle](https://github.com/stakater/forecastle) || Kibana ||||| 37 | | [Reloader](https://github.com/stakater/Reloader) || Cerebro ||||| 38 | | [Sealed Secret Controller](https://github.com/bitnami-labs/sealed-secrets) || Elasticsearch Curator ||||| 39 | | [K8S Dashboard](https://github.com/kubernetes/dashboard) || Logrotate ||||| 40 | | [Gitwebhookproxy](https://github.com/stakater/GitWebhookProxy) || [Konfigurator](https://github.com/stakater/Konfigurator) ||||| 41 | | [Ingress Monitor Controller](https://github.com/stakater/IngressMonitorController) ||||||| 42 | | [Xposer](https://github.com/stakater/Xposer) ||||||| 43 | 44 | ## Prerequisites 45 | 46 | - Kubernetes cluster with at least 8 VCPUS & 32 GB of RAM 47 | - A working domain (e.g. `stakaterplatform.com` ) 48 | - SSL Certificate for that domain. [Creating & using custom SSL certificates](https://playbook.stakater.com/content/processes/exposing/create-use-tls-custom-cert.html) 49 | 50 | ## Tools/Terms 51 | 52 | - **Flux:** You define the entire desired state of your cluster in git and flux ensures that the current state matches the one declared in repo. 53 | - **Kubeseal:** Required to encrypt base64 encoded secrets to commit-able(git) [sealed-secrets](https://playbook.stakater.com/content/workshop/sealed-secrets/introduction.html) 54 | 55 | ## Install from local machine 56 | 57 | ## Video Tutorial 58 | 59 | Installation tutorial for local machine can be seen [here](https://youtu.be/92qIaqJgaLw) 60 | 61 | ### Prerequisites 62 | 63 | - kubectl (between v1.11 & v1.15.3) 64 | - helm (v2.15.0 or lower) 65 | - [kubeseal](https://github.com/bitnami-labs/sealed-secrets/releases) 66 | 67 | 68 | 1. [Duplicate](https://help.github.com/en/github/creating-cloning-and-archiving-repositories/duplicating-a-repository#mirroring-a-repository) this [repository](https://github.com/stakater/stakaterplatform). 69 | 2. Update [configuration variables](#Basic-Configuration) in `variables.config` file and provide the relevant values. 70 | 3. [Recommended but optional] To take full advantage of the tool stack configure [Additional Variables](docs/detailed-config.md) as well. 71 | 4. Ensure that correct context is set for kubectl & helm. 72 | 5. run `make configure`, this will make all required substitutions based on configuration variables in the repository. When prompted commit those changes, don't commit them if you want to run everything from your local machine i.e. No flux hence no GitOps. 73 | 6. For deployment there are two options: 74 | 75 | a. Using [flux](https://playbook.stakater.com/content/processes/gitops/gitops-with-flux.html), [Add the public SSH key](https://help.github.com/en/github/authenticating-to-github/adding-a-new-ssh-key-to-your-github-account) of flux(configs/flux.pub) to your Git repository with **write access**. For flux run `make deploy-flux` and provide git credentials on prompt. 76 | 77 | b. Without flux, just don't add flux key and this will remove the process of GitOps(using flux) from your cluster. It removes the need of having your repository available remotely. Run `make deploy` 78 | 79 | 7. Estimated time for everything to be up and running is 5-10. Use the printed dashboard token to access the Kubernetes dashboard at `dashboard-control.YOURDOMAINNAME` 80 | 8. Visit `https://forecastle-control.YOURDOMAINNAME` and you'll be able to view all applications deployed by StakaterPlatform. 81 | 82 | 83 | **Note:** Since `variables.config` file and `configs/` directory contains private information those files are not being 84 | tracked in git and won't/shouldn't be committed. In case you want to commit those changes run `make track-secrets`. 85 | 86 | ## Install via GitLab CI Pipeline 87 | 88 | 1. [Duplicate](https://help.github.com/en/github/creating-cloning-and-archiving-repositories/duplicating-a-repository#mirroring-a-repository) this [repository](https://github.com/stakater/stakaterplatform) in a GitLab account. 89 | 2. Update [configuration variables](#Basic-Configuration) in `variables.config` file and provide the relevant values. 90 | 3. Create a [Personal Access Token](https://docs.gitlab.com/ee/user/profile/personal_access_tokens.html#creating-a-personal-access-token) on GitLab and note down Personal Access Token (Available only when created) 91 | 4. Configure CI/CD Environment variables in ` -> Settings -> CI/CD`. 92 | 5. Add Following variables for the pipeline 93 | 94 | | Pipeline Variables | Description | 95 | |:---|:---| 96 | | KUBE_CONFIG | `Base64 encoded` KubeConfig of the kubernetes cluster you want to deploy on | 97 | | REPO_ACCESS_TOKEN | Personal access token generated in Step 3 | 98 | | TARGET | Make file target. Value: `pipeline-deploy` | 99 | | AWS_ACCESS_KEY_ID | (Define only if `CLOUD_PROVIDER` is `aws`) AWS Access Key Id. | 100 | | AWS_SECRET_ACCESS_KEY | (Define only if `CLOUD_PROVIDER` is `aws`) AWS Secret Access Key. | 101 | 102 | 6. [Add the public SSH key](https://docs.gitlab.com/ee/ssh/#per-repository-deploy-keys)(Deploy Keys) to your GitLab account with **write access** printed at the end of pipeline logs. 103 | 7. Once key is added StakaterPlatform will deploy on your cluster (Estimated time: 5-10 minutes). :confetti_ball: 104 | 8. Use the printed dashboard token to access the Kubernetes dashboard at `dashboard-control.DOMAIN` 105 | 106 | ### Flow Diagram for Deployment via GitLab CI Pipeline 107 | 108 |

109 | 110 |

111 | 112 | ## Verification 113 | 114 | ### Locally 115 | Run `make verify` to run tests to ensure that all the relevant endpoints are up and running. 116 | 117 | ### GitLab CI 118 | Run pipeline with Pipeline variable: `TARGET` = verify 119 | 120 | StakaterPlatform offers a tool [Forecastle](https://github.com/stakater/forecastle) to access tools from a single panel. Go to `forecastle-control.DOMAIN` to access forecastle after complete deployment where you can access all the tools offered by StakaterPlatform and verify if working fine 121 | 122 | ![Diagram](./images/forecastle.png) 123 | 124 | ## Default Credentials 125 | 126 | See default username and passwords set for tools [here](./docs/default-passwords.md) 127 | 128 | ## Basic Configuration 129 | | Variables | Description | Default | 130 | |:---|:---|:---:| 131 | | CLOUD_PROVIDER | Name of the k8s cloud provider | `nil`
(`aws` \| `azure`) | 132 | | DNS_PROVIDER | Cloud DNS Provider | `aws` (Route53) | 133 | | EXTERNAL_DNS_AWS_ACCESS_KEY_ID | AWS Access Key Id having access to create/delete/update Route53 HostedZone entries | `nil` | 134 | | EXTERNAL_DNS_AWS_SECRET_ACCESS_KEY | AWS Secret Access Key having access to create/delete/update Route53 HostedZone entries | `nil` | 135 | | DOMAIN | Domain to use for StakaterPlatform | `nil` | 136 | | BASE64_ENCODED_SSL_CERTIFICATE_CA_CRT | Base64 encoded Intermediate Certificate value | `nil` | 137 | | BASE64_ENCODED_SSL_CERTIFICATE_TLS_CRT | Base64 encoded Server Certificate value |`nil` | 138 | | BASE64_ENCODED_SSL_CERTIFICATE_TLS_KEY | Base64 encoded Certificate Key value |`nil` | 139 | | STAKATER_PLATFORM_SSH_GIT_URL | SSH URL for your Github repo. | `nil`
(e.g `git@github.com/stakater/StakaterPlatform.git`. Notice `:` is replaced with `/` in the URL ) | 140 | | STAKATER_PLATFORM_BRANCH | Branch to use for `STAKATER_PLATFORM_SSH_GIT_URL` | `master` | 141 | 142 | 143 | For generating certificates view: [Creating & using custom SSL certificates](https://playbook.stakater.com/content/processes/exposing/create-use-tls-custom-cert.html) 144 | 145 | ## Detailed Configuration and Stack definitions 146 | 147 | See [Detailed Configurations](docs/detailed-config.md) for configuring available tools in the stacks. 148 | 149 | See [Stakater Playbook](https://playbook.stakater.com/content/stacks/stakaterplatform.html#overview) for stack definitions and configuration options. 150 | 151 | ## Uninstall 152 | 153 | Run `make destroy` to remove StakaterPlatform from your cluster. 154 | 155 | ## Production Configuration and Hardening 156 | 157 | - Replace all secrets with sealed-secrets. [Stakater Workshop - Sealed Secrets](https://playbook.stakater.com/content/workshop/sealed-secrets/introduction.html) In coming updates for StakaterPlatform this will be followed by default 158 | - Change default usernames and passwords for all tools (`variables.config`) 159 | - Add your own SSH keys for flux 160 | - Use Identity Providers (e.g. Google, Active Directory etc.) and configure keyCloak to use that. [KeyCloak with Identity Providers](https://playbook.stakater.com/content/processes/security/keycloak.html#keycloak-with-identity-providers) 161 | - Use keycloak for SSO over all exposed applications 162 | - Enable mTLS between microservices to prevent unauthorized connections between pods 163 | - Only allow restricted access to users other than the administrator for dashboard 164 | - Don't share your kubeconfig file and other secrets, it's suggested to keep such things in [vault](https://github.com/hashicorp/hands-on-with-vault-on-kubernetes) 165 | 166 | 167 | ## Compatibility Matrix 168 | 169 | StakaterPlatform has been tested on following kubernetes flavors: 170 | 171 | | Cloud | Kubernetes Version | Stakater Platform Version | 172 | |---|---|---| 173 | | AWS [![image](./images/eks.png)](https://aws.amazon.com/eks/) EKS | 1.14.6 | v0.0.1 | 174 | | Azure [![image](./images/aks.png)](https://docs.microsoft.com/en-us/azure/aks/) AKS | 1.14.8 | v0.0.1 | 175 | 176 | 177 | ## Community 178 | 179 | If you have questions, check the [Documentation](https://playbook.stakater.com/content/stacks/stakaterplatform.html) and 180 | talk to us on slack [#community on Stakater Slack](https://stakater-community.slack.com/messages/community). 181 | 182 | Click [here](https://slack-inviter.stakater.com) to join [Stakater](https://stakater.com) on Slack. 183 | -------------------------------------------------------------------------------- /configs/alertmanager.yaml: -------------------------------------------------------------------------------- 1 | # For more details: https://github.com/prometheus/alertmanager 2 | global: 3 | resolve_timeout: 5m 4 | inhibit_rules: 5 | - target_match: 6 | alertname: 'CPUThrottlingHigh' 7 | source_match: 8 | alertname: 'Watchdog' 9 | equal: ['prometheus'] 10 | receivers: 11 | - name: alerts-null 12 | - name: default-infra-alerts 13 | slack_configs: 14 | - api_url: SLACK_INFRA_ALERTS_WEBHOOK_URL 15 | channel: 'SLACK_INFRA_ALERTS_CHANNEL' 16 | send_resolved: true 17 | text: |2- 18 | 19 | {{ range .Alerts }} 20 | *Alert:* {{ .Annotations.summary }} - `{{ .Labels.severity }}` 21 | 22 | *Description:* {{ .Annotations.description }} 23 | 24 | *Graph:* <{{ .GeneratorURL }}|:chart_with_upwards_trend:> *Runbook:* <{{ .Annotations.runbook }}|:spiral_note_pad:> 25 | 26 | *Details:* 27 | 28 | {{ range .Labels.SortedPairs }} *{{ .Name }}:* `{{ .Value }}` 29 | 30 | {{ end }} 31 | 32 | {{ end }} 33 | title: '[{{ .Status | toUpper }}{{ if eq .Status "firing" }}:{{ .Alerts.Firing | len }}{{ end }}] Prometheus Event Notification' 34 | title_link: |2 35 | 36 | https://alertmanager-monitoring.DOMAIN 37 | - name: apps-alerts 38 | slack_configs: 39 | - api_url: SLACK_APPS_ALERTS_WEBHOOK_URL 40 | channel: 'SLACK_APPS_ALERTS_CHANNEL' 41 | send_resolved: true 42 | text: |2- 43 | 44 | {{ range .Alerts }} 45 | *Alert:* {{ .Annotations.summary }} - `{{ .Labels.severity }}` 46 | 47 | *Description:* {{ .Annotations.description }} 48 | 49 | *Graph:* <{{ .GeneratorURL }}|:chart_with_upwards_trend:> *Runbook:* <{{ .Annotations.runbook }}|:spiral_note_pad:> 50 | 51 | *Details:* 52 | 53 | {{ range .Labels.SortedPairs }} *{{ .Name }}:* `{{ .Value }}` 54 | 55 | {{ end }} 56 | 57 | {{ end }} 58 | title: '[{{ .Status | toUpper }}{{ if eq .Status "firing" }}:{{ .Alerts.Firing| len }}{{ end }}] Prometheus Event Notification' 59 | title_link: |2 60 | 61 | https://alertmanager-monitoring.DOMAIN 62 | route: 63 | group_by: 64 | - alertname 65 | - cluster 66 | - service 67 | group_interval: 5m 68 | group_wait: 30s 69 | repeat_interval: 1h 70 | receiver: default-infra-alerts 71 | routes: 72 | - match: 73 | kind: apps 74 | receiver: apps-alerts 75 | - match: 76 | alertname: Watchdog 77 | receiver: alerts-null -------------------------------------------------------------------------------- /configs/flux: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /configs/flux.pub: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /configs/imc.yaml: -------------------------------------------------------------------------------- 1 | # For more details: https://github.com/stakater/IngressMonitorController 2 | providers: 3 | - name: UptimeRobot 4 | apiKey: IMC_API_KEY 5 | apiURL: https://api.uptimerobot.com/v2/ 6 | alertContacts: "IMC_ALERT_CONTACTS" 7 | enableMonitorDeletion: true 8 | monitorNameTemplate: "{{.IngressName}}-{{.Namespace}}" 9 | resyncPeriod: 0 # how often (in seconds) monitors should be synced to their Kubernetes resources (0 = disabled) -------------------------------------------------------------------------------- /configs/jenkins-maven-config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | ${user.home}/.mvnrepository 4 | 5 | 6 | nexus 7 | external:* 8 | http://nexus.release/repository/public/ 9 | 10 | 11 | 12 | 13 | false 14 | 15 | 16 | 17 | docker-delivery.DOMAIN:443 18 | JENKINS_DOCKER_MAVEN_USERNAME 19 | JENKINS_DOCKER_MAVEN_PASSWORD 20 | 21 | 22 | local-nexus 23 | JENKINS_LOCAL_NEXUS_USERNAME 24 | JENKINS_LOCAL_NEXUS_PASSWORD 25 | 26 | 27 | nexus 28 | JENKINS_NEXUS_USERNAME 29 | JENKINS_NEXUS_PASSWORD 30 | 31 | 32 | oss-sonatype-staging 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | nexus 41 | 42 | local-nexus::default::http://nexus.release/repository/maven-releases/ 43 | local-nexus::default::http://nexus.release/repository/maven-releases/ 44 | local-nexus::default::http://nexus.release/repository/maven-snapshots/ 45 | 46 | 47 | 48 | central 49 | http://central 50 | true 51 | true 52 | 53 | 54 | 55 | 56 | central 57 | http://central 58 | true 59 | true 60 | 61 | 62 | 63 | 64 | release 65 | 66 | gpg 67 | mysecretpassphrase 68 | 69 | 70 | 71 | 72 | 73 | nexus 74 | 75 | -------------------------------------------------------------------------------- /configs/jenkins.json: -------------------------------------------------------------------------------- 1 | { 2 | "auths": { 3 | "docker-delivery.DOMAIN:443": { 4 | "auth": "JENKINS_NEXUS_AUTH" 5 | } 6 | } 7 | } -------------------------------------------------------------------------------- /configs/nexus-admin-account.json: -------------------------------------------------------------------------------- 1 | {"name": "NEXUS_ADMIN_ACCOUNT_USER","type": "groovy","content": "security.addUser('NEXUS_ADMIN_ACCOUNT_USER', 'Stakater', 'Admin', 'user@gmail.com', true, 'NEXUS_ADMIN_ACCOUNT_PASSWORD', ['nx-admin'])"} 2 | -------------------------------------------------------------------------------- /configs/nexus-cluster-account.json: -------------------------------------------------------------------------------- 1 | {"name": "NEXUS_CLUSTER_ACCOUNT_USER","type": "groovy","content": "security.addRole('cluster', 'cluster', 'User with privileges to allow read access to repo content and healtcheck', ['nx-healthcheck-read','nx-repository-view-docker-stakater-docker-browse','nx-repository-view-docker-stakater-docker-read','nx-search-read'], ['nx-anonymous']); security.addUser('NEXUS_CLUSTER_ACCOUNT_USER', 'Cluster', 'Cluster', 'user@gmail.com', true, 'NEXUS_CLUSTER_ACCOUNT_PASSWORD', ['cluster'])"} 2 | -------------------------------------------------------------------------------- /configs/proxyinjector.yaml: -------------------------------------------------------------------------------- 1 | gatekeeper-image : "keycloak/keycloak-gatekeeper:5.0.0" 2 | client-id: KEYCLOAK_CLIENT_ID 3 | client-secret: KEYCLOAK_CLIENT_SECRET 4 | discovery-url: "https://keycloak-security.DOMAIN/auth/realms/stakater" 5 | enable-default-deny: true 6 | secure-cookie: false 7 | verbose: true 8 | enable-logging: true 9 | cors-origins: 10 | - '*' 11 | cors-methods: 12 | - GET 13 | - POST 14 | resources: 15 | - uri: '/*' 16 | scopes: 17 | - 'good-service' -------------------------------------------------------------------------------- /configs/sealed-secret-tls.cert: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /configs/sealed-secret-tls.key: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /configs/secret-sealed-secret-tls-cert.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | data: 3 | tls.key: "BASE64_ENCODED_SEALED_SECRETS_TLS_KEY" 4 | tls.crt: "BASE64_ENCODED_SEALED_SECRETS_TLS_CRT" 5 | kind: Secret 6 | metadata: 7 | name: sealed-secrets-key 8 | namespace: security 9 | labels: 10 | sealedsecrets.bitnami.com/sealed-secrets-key: active 11 | type: kubernetes.io/tls -------------------------------------------------------------------------------- /docs/default-passwords.md: -------------------------------------------------------------------------------- 1 | # Default Credentials 2 | 3 | Following are the default credentials used by StakaterPlatform tools 4 | 5 | | Tool | SSO | Username | Password | 6 | |:----|:----:|:--------:|:---------:| 7 | | Forecastle | Yes | `user` | `zUPaZnEfmYpcdd6X` | 8 | | Kubernetes Dashboard | No | `nil` | `Login token printed at the time of deployment`| 9 | | Nexus | No |`nexus-admin` | `L8TcnrwMytCFpAFe` | 10 | | Jenkins | Yes | `user` | `zUPaZnEfmYpcdd6X`| 11 | | Prometheus | No | `nil`| `nil` | 12 | | Grafana | No | `admin` | `CN3B6uY998kpBFDd` | 13 | | AlertManager | No | `nil` | `nil` | 14 | | Kibana | Yes | `user` | `zUPaZnEfmYpcdd6X` | 15 | | Cerebro | Yes | `user` | `zUPaZnEfmYpcdd6X` | 16 | | Jaeger | No | `nil` | `nil` | 17 | | Kiali | No | `admin` | `fDNzLSFkr7zvHAQP` | 18 | | KeyCloak | No | `stakater` | `vuHBBDaVsS35jvF9`| -------------------------------------------------------------------------------- /docs/detailed-config.md: -------------------------------------------------------------------------------- 1 | # Detailed Configuration 2 | 3 | For detailed walk-through please visit [StakaterPlatform](https://playbook.stakater.com/content/stacks/stakaterplatform.html) 4 | 5 | ## Requirements 6 | 7 | To take full advantage of our tool stack, it is recommended to have the following things set-up: 8 | 1. 3 Slack channels with [webhook's](https://slack.com/intl/en-pk/help/articles/115005265063-Incoming-WebHooks-for-Slack) added. These are required for: 9 | * Dev-notifications: Notifications regarding up/down time and regarding new builds from jenkins 10 | * infra-alerts: Alerts from infrastructure 11 | * apps-alerts: Alerts for apps 12 | 2. An account at (Uptime Robot)[https://uptimerobot.com/] for (IMC)[https://github.com/stakater/IngressMonitorController] 13 | to work and provide you with up/down time alerts. For other supported down time monitors visit https://github.com/stakater/IngressMonitorController#supported-uptime-checkers 14 | 15 | 16 | ## Global Variables 17 | | Variables | Description | Default | 18 | |---|---|---| 19 | | CLOUD_PROVIDER | Name of the k8s cloud provider | `nil`
(`aws` \| `azure`) | 20 | | DNS_PROVIDER | Cloud DNS Provider | `aws` (Route53) | 21 | | EXTERNAL_DNS_AWS_ACCESS_KEY_ID | AWS Access Key Id | `nil` | 22 | | EXTERNAL_DNS_AWS_SECRET_ACCESS_KEY | AWS Secret Access Key | `nil` | 23 | | DOMAIN | Domain to expose StakaterPlatform | `nil` | 24 | | BASE64_ENCODED_SSL_CERTIFICATE_CA_CRT | Base64 encoded Intermediate Certificate value | `nil` | 25 | | BASE64_ENCODED_SSL_CERTIFICATE_TLS_CRT | Base64 encoded Server Certificate value |`nil` | 26 | | BASE64_ENCODED_SSL_CERTIFICATE_TLS_KEY | Base64 encoded Certificate Key value |`nil` | 27 | | STAKATER_PLATFORM_SSH_GIT_URL | SSH URL for your Github repo. | `nil`
(e.g `git@github.com/stakater/StakaterPlatform.git`. Notice `:` is replaced with `/` in the URL ) | 28 | | STAKATER_PLATFORM_BRANCH | Branch to use for `STAKATER_PLATFORM_SSH_GIT_URL` | `master` | 29 | 30 | ## KeyCloak 31 | | Variables | Description | Default | 32 | |---|---|---| 33 | | KEYCLOAK_CLIENT_ID | Client ID for KeyCloak Gatekeeper | `stakater-online-platform` | 34 | | KEYCLOAK_CLIENT_SECRET | Client Secret for KeyCloak Gatekeeper | `1ce66f91-2068-4f3d-9578-f03fa8259230` | 35 | | KEYCLOAK_DEFAULT_USERNAME | Username for the default user created |`stakater-user` | 36 | | KEYCLOAK_DEFAULT_PASSWORD | Password for the default user created |`zUPaZnEfmYpcdd6X` | 37 | | KEYCLOAK_DB_USER | KeyCloak DB (Postgresql) username |`admin` | 38 | | KEYCLOAK_DB_PASSWORD | KeyCloak DB (Postgresql) password |`L3VT3hBysLGtsJaZ` | 39 | | KEYCLOAK_PASSWORD | Password for the admin user `stakater` |`vuHBBDaVsS35jvF9` | 40 | 41 | ## IngressMonitorController IMC 42 | 43 | | Variables | Description | Default | 44 | |---|---|---| 45 | | IMC_API_KEY | API key of the monitor service provider |`nil` | 46 | | IMC_ALERT_CONTACTS | Alert contacts for the monitor service provider |`nil` | 47 | 48 | ## Nexus 49 | | Variables | Description | Default | 50 | |---|---|---| 51 | | NEXUS_ADMIN_ACCOUNT_USER | Username for admin account |`nexus-admin` | 52 | | NEXUS_ADMIN_ACCOUNT_PASSWORD | Password for admin account |`L8TcnrwMytCFpAFe` | 53 | | NEXUS_CLUSTER_ACCOUNT_USER | Username for cluster admin account |`nexus-cluster-admin` | 54 | | NEXUS_CLUSTER_ACCOUNT_PASSWORD | Password for cluster admin account |`mrzUGWrD9buDYhMF` | 55 | 56 | ## Jenkins 57 | | Variables | Description | Default | 58 | |---|---|---| 59 | | JENKINS_NOTIFICATIONS_SLACK_CHANNEL | Slack channel name to notify for jenkins pipeline result |`OPTIONAL` (e.g. `#slack-channel-name`) | 60 | | JENKINS_NOTIFICATIONS_SLACK_WEBHOOK_URL | Slack webhook URL to notify for jenkins pipeline result |`OPTIONAL` | 61 | | JENKINS_PIPELINE_GITHUB_TOKEN | GitHub API token. If configured Pipeline will comment on Pull Requests |`OPTIONAL` | 62 | | JENKINS_PIPELINE_GITLAB_TOKEN | GitLab API token. If configured Pipeline will comment on Pull Requests |`OPTIONAL` | 63 | | JENKINS_PIPELINE_BITBUCKET_TOKEN | BitBuckt API token. If configured Pipeline will comment on Pull Requests |`OPTIONAL` | 64 | | JENKINS_DOCKER_MAVEN_USERNAME | Maven repository used by Jenkins to store maven artifiacts |`admin` | 65 | | JENKINS_DOCKER_MAVEN_PASSWORD | Maven repository used by Jenkins to store maven artifiacts |`xJuAWjG4GzrCkPJU` | 66 | | JENKINS_LOCAL_NEXUS_USERNAME | Local repository used by Jenkins to store artifiacts |`admin` | 67 | | JENKINS_LOCAL_NEXUS_PASSWORD | Local repository used by Jenkins to store artifiacts | `LXwEkC4jZzQj3DHY` | 68 | | JENKINS_NEXUS_USERNAME | Nexus Username. Used by docker command in Jenkins Pipeline | `admin` | 69 | | JENKINS_NEXUS_PASSWORD | Nexus Password. Used by docker command in Jenkins Pipeline | `CN3B6uY998kpBFDd` | 70 | 71 | ## AlertManager 72 | | Variables | Description | Default | 73 | |---|---|---| 74 | | SLACK_INFRA_ALERTS_CHANNEL | Slack channel name to send Alertmanager infrastructure alerts |`#stakater-platform-infra-alerts` | 75 | | SLACK_INFRA_ALERTS_WEBHOOK_URL | Slack channel webhook URL to send Alertmanager infrastructure alerts |`OPTIONAL` | 76 | | SLACK_APPS_ALERTS_CHANNEL | Slack channel webhook URL to send Alertmanager application alerts |`#stakater-platform-apps-alerts` | 77 | | SLACK_APPS_ALERTS_WEBHOOK_URL | Slack channel name to send Alertmanager application alerts |`OPTIONAL` | 78 | 79 | ## Grafana 80 | | Variables | Description | Default | 81 | |---|---|---| 82 | | GRAFANA_USERNAME | Grafana dashboard username |`admin` | 83 | | GRAFANA_PASSWORD | Grafana dashboard password |`CN3B6uY998kpBFDd` | 84 | 85 | 86 | ## Flux 87 | In directory `configs`, SSH keys flux(private) & flux.pub(public) exist which flux uses for GitOps. You can provide, paste content of, your own SSH keys there. Else, a new unique key pair will be generated every time for you. 88 | 89 | ## Useful Resources 90 | 91 | [Stakater Platform](https://playbook.stakater.com/content/stacks/stakaterplatform.html) 92 | 93 | [Create Slack Webhook](https://playbook.stakater.com/content/processes/monitoring/creating-hooks-slack.html) 94 | 95 | [Configuring Kibana](https://playbook.stakater.com/content/processes/logging/configure-kibana.html) 96 | 97 | [Keycloak](https://playbook.stakater.com/content/processes/security/keycloak.html) 98 | 99 | [Creating & using custom SSL certificates](https://playbook.stakater.com/content/processes/exposing/create-use-tls-custom-cert.html) 100 | -------------------------------------------------------------------------------- /docs/images/forecastle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stakater/StakaterPlatform/0864442f378377f3191d4b8876de14818e3d9ef3/docs/images/forecastle.png -------------------------------------------------------------------------------- /images/aks.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stakater/StakaterPlatform/0864442f378377f3191d4b8876de14818e3d9ef3/images/aks.png -------------------------------------------------------------------------------- /images/eks.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stakater/StakaterPlatform/0864442f378377f3191d4b8876de14818e3d9ef3/images/eks.png -------------------------------------------------------------------------------- /images/forecastle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stakater/StakaterPlatform/0864442f378377f3191d4b8876de14818e3d9ef3/images/forecastle.png -------------------------------------------------------------------------------- /images/pipeline-flow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stakater/StakaterPlatform/0864442f378377f3191d4b8876de14818e3d9ef3/images/pipeline-flow.png -------------------------------------------------------------------------------- /images/rsz_aws.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stakater/StakaterPlatform/0864442f378377f3191d4b8876de14818e3d9ef3/images/rsz_aws.png -------------------------------------------------------------------------------- /platform/control/descheduler.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: helm.fluxcd.io/v1 2 | kind: HelmRelease 3 | metadata: 4 | name: stakater-control-descheduler 5 | namespace: control 6 | spec: 7 | releaseName: stakater-control-descheduler 8 | chart: 9 | repository: https://stakater.github.io/stakater-charts/ 10 | name: descheduler 11 | version: 1.0.10 12 | values: 13 | descheduler: 14 | namespace: control 15 | job: 16 | schedule: 0 */6 * * * 17 | parallelism: 1 18 | completions: 1 19 | restartPolicy: Never 20 | config: 21 | policy: |- 22 | apiVersion: "descheduler/v1alpha1" 23 | kind: "DeschedulerPolicy" 24 | strategies: 25 | "RemoveDuplicates": 26 | enabled: true 27 | "LowNodeUtilization": 28 | enabled: true 29 | params: 30 | nodeResourceUtilizationThresholds: 31 | thresholds: 32 | "cpu" : 30 33 | "memory": 30 34 | "pods": 30 35 | targetThresholds: 36 | "cpu" : 50 37 | "memory": 70 38 | "pods": 70 39 | -------------------------------------------------------------------------------- /platform/control/external-dns.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: helm.fluxcd.io/v1 2 | kind: HelmRelease 3 | metadata: 4 | name: stakater-control-external-dns 5 | namespace: control 6 | spec: 7 | releaseName: stakater-control-external-dns 8 | chart: 9 | repository: https://kubernetes-charts.storage.googleapis.com 10 | name: external-dns 11 | version: 2.4.2 12 | values: 13 | image: 14 | name: bitnami/external-dns 15 | pullPolicy: IfNotPresent 16 | sources: 17 | - ingress 18 | domainFilters: 19 | - DOMAIN 20 | txtOwnerId: stakater-platform 21 | registry: txt 22 | provider: DNS_PROVIDER 23 | extraEnv: 24 | - name: AWS_ACCESS_KEY_ID 25 | valueFrom: 26 | secretKeyRef: 27 | name: aws-creds 28 | key: AWS_ACCESS_KEY_ID 29 | - name: AWS_SECRET_ACCESS_KEY 30 | valueFrom: 31 | secretKeyRef: 32 | name: aws-creds 33 | key: AWS_SECRET_ACCESS_KEY 34 | policy: sync 35 | rbac: 36 | create: true 37 | apiVersion: v1beta1 38 | tolerations: 39 | - key: "dedicated" 40 | operator: "Equal" 41 | value: "app" 42 | effect: "NoSchedule" 43 | resources: 44 | limits: 45 | cpu: 50m 46 | memory: 100Mi 47 | requests: 48 | memory: 50Mi 49 | cpu: 10m -------------------------------------------------------------------------------- /platform/control/external-ingress.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | kind: ConfigMap 3 | apiVersion: v1 4 | metadata: 5 | name: nginx-configuration-external 6 | namespace: control 7 | data: 8 | ssl-protocols: TLSv1.2 9 | proxy-connect-timeout: "300" 10 | proxy-read-timeout: "1200" 11 | proxy-send-timeout: "300" 12 | use-http2: "false" 13 | worker-processes: "24" 14 | worker-connections: "100000" 15 | worker-rlimit-nofile: "102400" 16 | worker-cpu-affinity: "auto" 17 | keepalive: "200" 18 | hsts-preload: "true" 19 | hsts-max-age: "31536000" 20 | proxy-buffer-size: "256k" 21 | client-body-buffer-size: "256k" 22 | ssl-buffer-size: "32k" 23 | proxy-body-size: "100m" 24 | --- 25 | apiVersion: helm.fluxcd.io/v1 26 | kind: HelmRelease 27 | metadata: 28 | name: stakater-control-external-ingress 29 | namespace: control 30 | spec: 31 | releaseName: stakater-control-external-ingress 32 | chart: 33 | repository: https://kubernetes-charts.storage.googleapis.com 34 | name: nginx-ingress 35 | version: 1.6.10 36 | values: 37 | nameOverride: stakater-control-external 38 | fullnameOverride: stakater-control-external 39 | revisionHistoryLimit: 3 40 | controller: 41 | name: nginx-ingress 42 | publishService: 43 | enabled: true 44 | pathOverride: "control/stakater-control-external-nginx-ingress" 45 | ingressClass: external-ingress 46 | stats: 47 | enabled: "true" 48 | metrics: 49 | enabled: "true" 50 | service: 51 | annotations: 52 | prometheus.io/scrape: "true" 53 | prometheus.io/port: "10254" 54 | labels: 55 | k8s-app: external-ingress 56 | config: 57 | use-proxy-protocol: "false" 58 | enable-opentracing: "false" 59 | replicaCount: 2 60 | podAnnotations: 61 | scheduler.alpha.kubernetes.io/critical-pod: "true" 62 | image: 63 | pullPolicy: Always 64 | extraArgs: 65 | configmap: control/nginx-configuration-external 66 | annotations-prefix: ingress.kubernetes.io 67 | default-ssl-certificate: "control/tls-cert" 68 | enable-ssl-chain-completion: true 69 | enable-dynamic-certificates: "false" 70 | resources: 71 | limits: 72 | cpu: 200m 73 | memory: 512Mi 74 | requests: 75 | cpu: 100m 76 | memory: 256Mi -------------------------------------------------------------------------------- /platform/control/forecastle.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: helm.fluxcd.io/v1 2 | kind: HelmRelease 3 | metadata: 4 | name: stakater-control-forecastle 5 | namespace: control 6 | spec: 7 | releaseName: stakater-control-forecastle 8 | chart: 9 | repository: https://stakater.github.io/stakater-charts/ 10 | name: forecastle 11 | version: 1.0.36 12 | values: 13 | forecastle: 14 | createCustomResource: false 15 | namespace: control 16 | deployment: 17 | replicas: 1 18 | revisionHistoryLimit: 2 19 | annotations: 20 | configmap.reloader.stakater.com/reload: forecastle 21 | authproxy.stakater.com/enabled: "true" 22 | authproxy.stakater.com/upstream-url: "http://127.0.0.1:3000" 23 | authproxy.stakater.com/source-service-name: forecastle 24 | authproxy.stakater.com/redirection-url: "https://forecastle-control.DOMAIN" 25 | authproxy.stakater.com/listen: "0.0.0.0:80" 26 | service: 27 | expose: "true" 28 | annotations: 29 | config.xposer.stakater.com/IngressURLPath: "/" 30 | config.xposer.stakater.com/Domain: "DOMAIN" 31 | config.xposer.stakater.com/IngressNameTemplate: "{{.Service}}" 32 | config.xposer.stakater.com/IngressURLTemplate: "{{.Service}}-{{.Namespace}}.{{.Domain}}" 33 | config.xposer.stakater.com/TLS: "true" 34 | config.xposer.stakater.com/TLSSecretNameTemplate: "tls-cert" 35 | xposer.stakater.com/annotations: |- 36 | kubernetes.io/ingress.class: external-ingress 37 | ingress.kubernetes.io/rewrite-target: / 38 | ingress.kubernetes.io/force-ssl-redirect: true 39 | exposeIngressUrl: globally 40 | config: 41 | namespaceSelector: 42 | any: true 43 | headerBackground: "#173F5F" 44 | headerForeground: "white" 45 | title: "Forecastle - Stakater" 46 | crdEnabled: true -------------------------------------------------------------------------------- /platform/control/gitlabwebhookproxy.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: helm.fluxcd.io/v1 2 | kind: HelmRelease 3 | metadata: 4 | name: stakater-control-gitlabwebhookproxy 5 | namespace: control 6 | spec: 7 | releaseName: stakater-control-gitlabwebhookproxy 8 | chart: 9 | repository: https://stakater.github.io/stakater-charts/ 10 | name: gitwebhookproxy 11 | version: 0.2.64 12 | values: 13 | gitWebhookProxy: 14 | useCustomName: true 15 | customName: gitlabwebhookproxy 16 | image: 17 | name: stakater/gitwebhookproxy 18 | tag: "v0.2.64" 19 | pullPolicy: IfNotPresent 20 | config: 21 | provider: gitlab 22 | upstreamURL: "https://jenkins-delivery.DOMAIN" 23 | allowedPaths: "/github-webhook,/project" 24 | secret: "" 25 | ignoredUsers: "carbook.bot" 26 | service: 27 | labels: 28 | expose: "true" 29 | annotations: 30 | configmap.reloader.stakater.com/reload: gitlabwebhookproxy 31 | config.xposer.stakater.com/Domain: DOMAIN 32 | config.xposer.stakater.com/IngressNameTemplate: '{{.Service}}-{{.Namespace}}' 33 | config.xposer.stakater.com/IngressURLTemplate: '{{.Service}}-{{.Namespace}}.{{.Domain}}' 34 | xposer.stakater.com/annotations: |- 35 | kubernetes.io/ingress.class: external-ingress 36 | ingress.kubernetes.io/force-ssl-redirect: true 37 | monitor.stakater.com/enabled: true 38 | exposeIngressUrl: locally 39 | ports: 40 | - name: http 41 | port: 80 42 | protocol: TCP 43 | targetPort: 8080 -------------------------------------------------------------------------------- /platform/control/gitwebhookproxy.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: helm.fluxcd.io/v1 2 | kind: HelmRelease 3 | metadata: 4 | name: stakater-control-gitwebhookproxy 5 | namespace: control 6 | spec: 7 | releaseName: stakater-control-gitwebhookproxy 8 | chart: 9 | repository: https://stakater.github.io/stakater-charts/ 10 | name: gitwebhookproxy 11 | version: 0.2.64 12 | values: 13 | gitWebhookProxy: 14 | useCustomName: false 15 | customName: gitwebhookproxy 16 | image: 17 | name: stakater/gitwebhookproxy 18 | tag: "v0.2.64" 19 | pullPolicy: IfNotPresent 20 | config: 21 | provider: github 22 | upstreamURL: "https://jenkins-delivery.DOMAIN" 23 | allowedPaths: "/github-webhook,/project" 24 | secret: "dummysecret" 25 | ignoredUsers: "stakater-user" 26 | service: 27 | labels: 28 | expose: "true" 29 | annotations: 30 | configmap.reloader.stakater.com/reload: gitwebhookproxy 31 | config.xposer.stakater.com/Domain: DOMAIN 32 | config.xposer.stakater.com/IngressNameTemplate: '{{.Service}}' 33 | config.xposer.stakater.com/IngressURLTemplate: '{{.Service}}-{{.Namespace}}.{{.Domain}}' 34 | xposer.stakater.com/annotations: |- 35 | kubernetes.io/ingress.class: external-ingress 36 | ingress.kubernetes.io/force-ssl-redirect: true 37 | monitor.stakater.com/enabled: true 38 | exposeIngressUrl: locally 39 | ports: 40 | - name: http 41 | port: 80 42 | protocol: TCP 43 | targetPort: 8080 44 | -------------------------------------------------------------------------------- /platform/control/imc.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: helm.fluxcd.io/v1 2 | kind: HelmRelease 3 | metadata: 4 | name: stakater-control-imc 5 | namespace: control 6 | spec: 7 | releaseName: stakater-control-imc 8 | chart: 9 | repository: https://stakater.github.io/stakater-charts/ 10 | name: ingressmonitorcontroller 11 | version: 1.0.91 12 | values: 13 | ingressMonitorController: 14 | watchNamespace: "control" 15 | mount: "secret" 16 | existingSecret: "imc-config" 17 | logLevel: info 18 | logFormat: text 19 | matchLabels: 20 | group: com.stakater.platform 21 | provider: stakater 22 | deployment: 23 | labels: 24 | version: "v1.0.91" 25 | annotations: 26 | configmap.reloader.stakater.com/reload: ingressmonitorcontroller 27 | image: 28 | name: stakater/ingressmonitorcontroller 29 | tag: "v1.0.91" 30 | pullPolicy: IfNotPresent 31 | configFilePath: /etc/IngressMonitorController/config.yaml -------------------------------------------------------------------------------- /platform/control/internal-ingress.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | kind: ConfigMap 3 | apiVersion: v1 4 | metadata: 5 | name: nginx-configuration-internal 6 | namespace: control 7 | data: 8 | ssl-protocols: TLSv1.2 9 | proxy-connect-timeout: "300" 10 | proxy-read-timeout: "1200" 11 | proxy-send-timeout: "300" 12 | use-http2: "false" 13 | worker-processes: "24" 14 | worker-connections: "100000" 15 | worker-rlimit-nofile: "102400" 16 | worker-cpu-affinity: "auto" 17 | keepalive: "200" 18 | hsts-preload: "true" 19 | hsts-max-age: "31536000" 20 | proxy-buffer-size: "256k" 21 | client-body-buffer-size: "256k" 22 | ssl-buffer-size: "32k" 23 | proxy-body-size: "100m" 24 | --- 25 | apiVersion: helm.fluxcd.io/v1 26 | kind: HelmRelease 27 | metadata: 28 | name: stakater-control-internal-ingress 29 | namespace: control 30 | spec: 31 | releaseName: stakater-control-internal-ingress 32 | chart: 33 | repository: https://kubernetes-charts.storage.googleapis.com 34 | name: nginx-ingress 35 | version: 1.6.11 36 | values: 37 | nameOverride: stakater-control-internal 38 | fullnameOverride: stakater-control-internal 39 | revisionHistoryLimit: 3 40 | defaultBackend: 41 | enabled: false 42 | controller: 43 | name: nginx-ingress 44 | defaultBackendService: "control/stakater-control-external-default-backend" 45 | publishService: 46 | enabled: true 47 | pathOverride: "control/stakater-control-internal-nginx-ingress" 48 | ingressClass: internal-ingress 49 | stats: 50 | enabled: "true" 51 | metrics: 52 | enabled: "true" 53 | service: 54 | annotations: 55 | prometheus.io/scrape: "true" 56 | prometheus.io/port: "10254" 57 | labels: 58 | k8s-app: internal-ingress 59 | config: 60 | use-proxy-protocol: "false" 61 | enable-opentracing: "false" 62 | replicaCount: 2 63 | podAnnotations: 64 | scheduler.alpha.kubernetes.io/critical-pod: "true" 65 | image: 66 | pullPolicy: Always 67 | extraArgs: 68 | configmap: control/nginx-configuration-internal 69 | annotations-prefix: ingress.kubernetes.io 70 | enable-dynamic-certificates: "false" 71 | enable-ssl-chain-completion: true 72 | default-ssl-certificate: "control/tls-cert" 73 | resources: 74 | limits: 75 | cpu: 200m 76 | memory: 512Mi 77 | requests: 78 | cpu: 100m 79 | memory: 256Mi -------------------------------------------------------------------------------- /platform/control/kubernetes-dashboard.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: helm.fluxcd.io/v1 2 | kind: HelmRelease 3 | metadata: 4 | name: stakater-control-dashboard 5 | namespace: control 6 | spec: 7 | releaseName: stakater-control-dashboard 8 | chart: 9 | repository: https://kubernetes-charts.storage.googleapis.com 10 | name: kubernetes-dashboard 11 | version: 1.5.2 12 | values: 13 | rbac: 14 | create: true 15 | clusterAdminRole: true 16 | # annotations: 17 | # authproxy.stakater.com/enabled: "true" 18 | # authproxy.stakater.com/upstream-url: "http://127.0.0.1:9090" 19 | # authproxy.stakater.com/source-service-name: stakater-control-dashboard-kubernetes-dashboard 20 | # authproxy.stakater.com/redirection-url: "https://dashboard.control.DOMAIN" 21 | # authproxy.stakater.com/listen: "0.0.0.0:80" 22 | enableInsecureLogin: true 23 | enableSkipLogin: false 24 | service: 25 | labels: 26 | expose: "true" 27 | annotations: 28 | config.xposer.stakater.com/Domain: DOMAIN 29 | config.xposer.stakater.com/IngressNameTemplate: '{{.Service}}' 30 | config.xposer.stakater.com/IngressURLTemplate: 'dashboard-{{.Namespace}}.{{.Domain}}' 31 | config.xposer.stakater.com/TLS: "true" 32 | config.xposer.stakater.com/TLSSecretNameTemplate: "tls-cert" 33 | xposer.stakater.com/annotations: |- 34 | kubernetes.io/ingress.class: internal-ingress 35 | ingress.kubernetes.io/force-ssl-redirect: true 36 | forecastle.stakater.com/expose: true 37 | forecastle.stakater.com/icon: https://github.com/stakater/ForecastleIcons/raw/master/kubernetes.png 38 | forecastle.stakater.com/appName: Dashboard 39 | exposeIngressUrl: locally 40 | resources: 41 | limits: 42 | cpu: 200m 43 | memory: 512Mi 44 | requests: 45 | cpu: 100m 46 | memory: 100Mi -------------------------------------------------------------------------------- /platform/control/reloader.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: helm.fluxcd.io/v1 2 | kind: HelmRelease 3 | metadata: 4 | name: stakater-control-reloader 5 | namespace: control 6 | spec: 7 | releaseName: stakater-control-reloader 8 | chart: 9 | repository: https://stakater.github.io/stakater-charts/ 10 | name: reloader 11 | version: 0.0.32 12 | values: 13 | reloader: 14 | watchGlobally: true 15 | deployment: 16 | resources: 17 | limits: 18 | cpu: "100m" 19 | memory: "512Mi" 20 | requests: 21 | cpu: "10m" 22 | memory: "128Mi" -------------------------------------------------------------------------------- /platform/control/secrets/secret-aws-creds.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | data: 3 | AWS_ACCESS_KEY_ID: EXTERNAL_DNS_AWS_ACCESS_KEY_ID 4 | AWS_SECRET_ACCESS_KEY: EXTERNAL_DNS_AWS_SECRET_ACCESS_KEY 5 | kind: Secret 6 | metadata: 7 | name: aws-creds 8 | namespace: control 9 | type: Opaque 10 | -------------------------------------------------------------------------------- /platform/control/secrets/secret-imc-config.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | data: 3 | config.yaml: BASE64_ENCODED_IMC_CONFIG 4 | kind: Secret 5 | metadata: 6 | name: imc-config 7 | namespace: control 8 | type: Opaque 9 | -------------------------------------------------------------------------------- /platform/control/secrets/secret-tls-cert.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | data: 3 | ca.crt: "BASE64_ENCODED_SSL_CERTIFICATE_CA_CRT" 4 | tls.key: "BASE64_ENCODED_SSL_CERTIFICATE_TLS_KEY" 5 | tls.crt: "BASE64_ENCODED_SSL_CERTIFICATE_TLS_CRT" 6 | kind: Secret 7 | metadata: 8 | name: tls-cert 9 | namespace: control 10 | type: Opaque -------------------------------------------------------------------------------- /platform/control/xposer.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: helm.fluxcd.io/v1 2 | kind: HelmRelease 3 | metadata: 4 | name: stakater-control-xposer 5 | namespace: control 6 | spec: 7 | releaseName: stakater-control-xposer 8 | chart: 9 | repository: https://stakater.github.io/stakater-charts/ 10 | name: xposer 11 | version: 0.0.17 12 | values: 13 | xposer: 14 | configFilePath: /configs/config.yaml 15 | watchGlobally: true 16 | exposeServiceURL: globally 17 | config: 18 | domain: DOMAIN 19 | ingressURLTemplate: "{{.Service}}-{{.Namespace}}.{{.Domain}}" 20 | ingressURLPath: / 21 | ingressNameTemplate: "{{.Service}}" 22 | tlsSecretNameTemplate: "tls-cert" 23 | tls: true -------------------------------------------------------------------------------- /platform/crds/cr-uptimerobot.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: forecastle.stakater.com/v1alpha1 2 | kind: ForecastleApp 3 | metadata: 4 | name: cr-uptimerobot 5 | namespace: control 6 | spec: 7 | name: UptimeRobot 8 | group: Alerting 9 | icon: https://uptimerobot.com/assets/img/logo_plain.png 10 | url: https://uptimerobot.com/ 11 | networkRestricted: false -------------------------------------------------------------------------------- /platform/crds/crd-forecastle.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apiextensions.k8s.io/v1beta1 2 | kind: CustomResourceDefinition 3 | metadata: 4 | name: forecastleapps.forecastle.stakater.com 5 | annotations: 6 | "helm.sh/hook": crd-install 7 | spec: 8 | group: forecastle.stakater.com 9 | names: 10 | kind: ForecastleApp 11 | listKind: ForecastleAppList 12 | plural: forecastleapps 13 | singular: forecastleapp 14 | scope: Namespaced 15 | subresources: 16 | status: {} 17 | validation: 18 | openAPIV3Schema: 19 | properties: 20 | apiVersion: 21 | description: 'APIVersion defines the versioned schema of this representation 22 | of an object. Servers should convert recognized schemas to the latest 23 | internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#resources' 24 | type: string 25 | kind: 26 | description: 'Kind is a string value representing the REST resource this 27 | object represents. Servers may infer this from the endpoint the client 28 | submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds' 29 | type: string 30 | metadata: 31 | type: object 32 | spec: 33 | properties: 34 | group: 35 | type: string 36 | icon: 37 | type: string 38 | instance: 39 | type: string 40 | name: 41 | type: string 42 | networkRestricted: 43 | type: boolean 44 | url: 45 | type: string 46 | urlFrom: 47 | properties: 48 | ingressRef: 49 | type: object 50 | type: object 51 | required: 52 | - name 53 | - group 54 | - icon 55 | type: object 56 | status: 57 | type: object 58 | version: v1alpha1 59 | versions: 60 | - name: v1alpha1 61 | served: true 62 | storage: true -------------------------------------------------------------------------------- /platform/crds/crd-konfigurator.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apiextensions.k8s.io/v1beta1 2 | kind: CustomResourceDefinition 3 | metadata: 4 | name: konfiguratortemplates.konfigurator.stakater.com 5 | spec: 6 | group: konfigurator.stakater.com 7 | names: 8 | kind: KonfiguratorTemplate 9 | listKind: KonfiguratorTemplateList 10 | plural: konfiguratortemplates 11 | singular: konfiguratortemplate 12 | scope: Namespaced 13 | version: v1alpha1 -------------------------------------------------------------------------------- /platform/crds/crd-sealed-secrets.yaml: -------------------------------------------------------------------------------- 1 | # Source: sealed-secrets/templates/sealedsecret-crd.yaml 2 | apiVersion: apiextensions.k8s.io/v1beta1 3 | kind: CustomResourceDefinition 4 | metadata: 5 | name: sealedsecrets.bitnami.com 6 | annotations: 7 | "helm.sh/resource-policy": delete 8 | labels: 9 | app.kubernetes.io/name: sealed-secrets 10 | helm.sh/chart: sealed-secrets-1.0.2 11 | app.kubernetes.io/managed-by: Tiller 12 | app.kubernetes.io/instance: RELEASE-NAME 13 | app.kubernetes.io/version: 0.7.0 14 | spec: 15 | group: bitnami.com 16 | names: 17 | kind: SealedSecret 18 | listKind: SealedSecretList 19 | plural: sealedsecrets 20 | singular: sealedsecret 21 | scope: Namespaced 22 | version: v1alpha1 -------------------------------------------------------------------------------- /platform/crds/crd-servicemonitor.yaml: -------------------------------------------------------------------------------- 1 | # Source: prometheus-operator/templates/prometheus-operator/crd-servicemonitor.yaml 2 | # Source: https://github.com/coreos/prometheus-operator/blob/master/contrib/kube-prometheus/manifests/0prometheus-operator-0servicemonitorCustomResourceDefinition.yaml 3 | apiVersion: apiextensions.k8s.io/v1beta1 4 | kind: CustomResourceDefinition 5 | metadata: 6 | creationTimestamp: null 7 | name: servicemonitors.monitoring.coreos.com 8 | labels: 9 | app: prometheus-operator-operator 10 | 11 | chart: prometheus-operator-5.10.3 12 | heritage: "Tiller" 13 | annotations: 14 | "helm.sh/hook": crd-install 15 | "helm.sh/hook-delete-policy": "before-hook-creation" 16 | spec: 17 | group: monitoring.coreos.com 18 | names: 19 | kind: ServiceMonitor 20 | plural: servicemonitors 21 | scope: Namespaced 22 | validation: 23 | openAPIV3Schema: 24 | properties: 25 | apiVersion: 26 | description: 'APIVersion defines the versioned schema of this representation 27 | of an object. Servers should convert recognized schemas to the latest 28 | internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#resources' 29 | type: string 30 | kind: 31 | description: 'Kind is a string value representing the REST resource this 32 | object represents. Servers may infer this from the endpoint the client 33 | submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds' 34 | type: string 35 | spec: 36 | description: ServiceMonitorSpec contains specification parameters for a 37 | ServiceMonitor. 38 | properties: 39 | endpoints: 40 | description: A list of endpoints allowed as part of this ServiceMonitor. 41 | items: 42 | description: Endpoint defines a scrapeable endpoint serving Prometheus 43 | metrics. 44 | properties: 45 | basicAuth: 46 | description: 'BasicAuth allow an endpoint to authenticate over 47 | basic authentication More info: https://prometheus.io/docs/operating/configuration/#endpoints' 48 | properties: 49 | password: 50 | description: SecretKeySelector selects a key of a Secret. 51 | properties: 52 | key: 53 | description: The key of the secret to select from. Must 54 | be a valid secret key. 55 | type: string 56 | name: 57 | description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' 58 | type: string 59 | optional: 60 | description: Specify whether the Secret or it's key must 61 | be defined 62 | type: boolean 63 | required: 64 | - key 65 | username: 66 | description: SecretKeySelector selects a key of a Secret. 67 | properties: 68 | key: 69 | description: The key of the secret to select from. Must 70 | be a valid secret key. 71 | type: string 72 | name: 73 | description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' 74 | type: string 75 | optional: 76 | description: Specify whether the Secret or it's key must 77 | be defined 78 | type: boolean 79 | required: 80 | - key 81 | bearerTokenFile: 82 | description: File to read bearer token for scraping targets. 83 | type: string 84 | honorLabels: 85 | description: HonorLabels chooses the metric's labels on collisions 86 | with target labels. 87 | type: boolean 88 | interval: 89 | description: Interval at which metrics should be scraped 90 | type: string 91 | metricRelabelings: 92 | description: MetricRelabelConfigs to apply to samples before ingestion. 93 | items: 94 | description: 'RelabelConfig allows dynamic rewriting of the 95 | label set, being applied to samples before ingestion. It defines 96 | ``-section of Prometheus configuration. 97 | More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#metric_relabel_configs' 98 | properties: 99 | action: 100 | description: Action to perform based on regex matching. 101 | Default is 'replace' 102 | type: string 103 | modulus: 104 | description: Modulus to take of the hash of the source label 105 | values. 106 | format: int64 107 | type: integer 108 | regex: 109 | description: Regular expression against which the extracted 110 | value is matched. defailt is '(.*)' 111 | type: string 112 | replacement: 113 | description: Replacement value against which a regex replace 114 | is performed if the regular expression matches. Regex 115 | capture groups are available. Default is '$1' 116 | type: string 117 | separator: 118 | description: Separator placed between concatenated source 119 | label values. default is ';'. 120 | type: string 121 | sourceLabels: 122 | description: The source labels select values from existing 123 | labels. Their content is concatenated using the configured 124 | separator and matched against the configured regular expression 125 | for the replace, keep, and drop actions. 126 | items: 127 | type: string 128 | type: array 129 | targetLabel: 130 | description: Label to which the resulting value is written 131 | in a replace action. It is mandatory for replace actions. 132 | Regex capture groups are available. 133 | type: string 134 | type: array 135 | params: 136 | description: Optional HTTP URL parameters 137 | type: object 138 | path: 139 | description: HTTP path to scrape for metrics. 140 | type: string 141 | port: 142 | description: Name of the service port this endpoint refers to. 143 | Mutually exclusive with targetPort. 144 | type: string 145 | proxyUrl: 146 | description: ProxyURL eg http://proxyserver:2195 Directs scrapes 147 | to proxy through this endpoint. 148 | type: string 149 | relabelings: 150 | description: 'RelabelConfigs to apply to samples before ingestion. 151 | More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config' 152 | items: 153 | description: 'RelabelConfig allows dynamic rewriting of the 154 | label set, being applied to samples before ingestion. It defines 155 | ``-section of Prometheus configuration. 156 | More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#metric_relabel_configs' 157 | properties: 158 | action: 159 | description: Action to perform based on regex matching. 160 | Default is 'replace' 161 | type: string 162 | modulus: 163 | description: Modulus to take of the hash of the source label 164 | values. 165 | format: int64 166 | type: integer 167 | regex: 168 | description: Regular expression against which the extracted 169 | value is matched. defailt is '(.*)' 170 | type: string 171 | replacement: 172 | description: Replacement value against which a regex replace 173 | is performed if the regular expression matches. Regex 174 | capture groups are available. Default is '$1' 175 | type: string 176 | separator: 177 | description: Separator placed between concatenated source 178 | label values. default is ';'. 179 | type: string 180 | sourceLabels: 181 | description: The source labels select values from existing 182 | labels. Their content is concatenated using the configured 183 | separator and matched against the configured regular expression 184 | for the replace, keep, and drop actions. 185 | items: 186 | type: string 187 | type: array 188 | targetLabel: 189 | description: Label to which the resulting value is written 190 | in a replace action. It is mandatory for replace actions. 191 | Regex capture groups are available. 192 | type: string 193 | type: array 194 | scheme: 195 | description: HTTP scheme to use for scraping. 196 | type: string 197 | scrapeTimeout: 198 | description: Timeout after which the scrape is ended 199 | type: string 200 | targetPort: 201 | anyOf: 202 | - type: string 203 | - type: integer 204 | tlsConfig: 205 | description: TLSConfig specifies TLS configuration parameters. 206 | properties: 207 | caFile: 208 | description: The CA cert to use for the targets. 209 | type: string 210 | certFile: 211 | description: The client cert file for the targets. 212 | type: string 213 | insecureSkipVerify: 214 | description: Disable target certificate validation. 215 | type: boolean 216 | keyFile: 217 | description: The client key file for the targets. 218 | type: string 219 | serverName: 220 | description: Used to verify the hostname for the targets. 221 | type: string 222 | type: array 223 | jobLabel: 224 | description: The label to use to retrieve the job name from. 225 | type: string 226 | namespaceSelector: 227 | description: NamespaceSelector is a selector for selecting either all 228 | namespaces or a list of namespaces. 229 | properties: 230 | any: 231 | description: Boolean describing whether all namespaces are selected 232 | in contrast to a list restricting them. 233 | type: boolean 234 | matchNames: 235 | description: List of namespace names. 236 | items: 237 | type: string 238 | type: array 239 | podTargetLabels: 240 | description: PodTargetLabels transfers labels on the Kubernetes Pod 241 | onto the target. 242 | items: 243 | type: string 244 | type: array 245 | sampleLimit: 246 | description: SampleLimit defines per-scrape limit on number of scraped 247 | samples that will be accepted. 248 | format: int64 249 | type: integer 250 | selector: 251 | description: A label selector is a label query over a set of resources. 252 | The result of matchLabels and matchExpressions are ANDed. An empty 253 | label selector matches all objects. A null label selector matches 254 | no objects. 255 | properties: 256 | matchExpressions: 257 | description: matchExpressions is a list of label selector requirements. 258 | The requirements are ANDed. 259 | items: 260 | description: A label selector requirement is a selector that contains 261 | values, a key, and an operator that relates the key and values. 262 | properties: 263 | key: 264 | description: key is the label key that the selector applies 265 | to. 266 | type: string 267 | operator: 268 | description: operator represents a key's relationship to a 269 | set of values. Valid operators are In, NotIn, Exists and 270 | DoesNotExist. 271 | type: string 272 | values: 273 | description: values is an array of string values. If the operator 274 | is In or NotIn, the values array must be non-empty. If the 275 | operator is Exists or DoesNotExist, the values array must 276 | be empty. This array is replaced during a strategic merge 277 | patch. 278 | items: 279 | type: string 280 | type: array 281 | required: 282 | - key 283 | - operator 284 | type: array 285 | matchLabels: 286 | description: matchLabels is a map of {key,value} pairs. A single 287 | {key,value} in the matchLabels map is equivalent to an element 288 | of matchExpressions, whose key field is "key", the operator is 289 | "In", and the values array contains only "value". The requirements 290 | are ANDed. 291 | type: object 292 | targetLabels: 293 | description: TargetLabels transfers labels on the Kubernetes Service 294 | onto the target. 295 | items: 296 | type: string 297 | type: array 298 | required: 299 | - endpoints 300 | - selector 301 | version: v1 302 | -------------------------------------------------------------------------------- /platform/delivery/jenkins-mvnstorage.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: helm.fluxcd.io/v1 2 | kind: HelmRelease 3 | metadata: 4 | name: stakater-delivery-mvnstorage 5 | namespace: delivery 6 | spec: 7 | releaseName: stakater-delivery-mvnstorage 8 | chart: 9 | repository: https://stakater.github.io/stakater-charts/ 10 | name: storage 11 | version: 1.0.5 12 | values: 13 | Claims: 14 | - accessModes: 15 | - ReadWriteOnce 16 | annotations: 17 | volume.beta.kubernetes.io/storage-class: stakater-storageclass 18 | labels: 19 | app: jenkins 20 | name: jenkins-mvn-local-repo 21 | storage: 10Gi 22 | storageClassName: stakater-storageclass 23 | -------------------------------------------------------------------------------- /platform/delivery/jenkins-rbac-master.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: helm.fluxcd.io/v1 2 | kind: HelmRelease 3 | metadata: 4 | name: stakater-delivery-rbac 5 | namespace: delivery 6 | spec: 7 | releaseName: stakater-delivery-rbac 8 | chart: 9 | repository: https://stakater.github.io/stakater-charts/ 10 | name: rbac 11 | version: 1.0.6 12 | values: 13 | rbac: 14 | appName: jenkins 15 | clusterRoleBinding: 16 | enabled: true 17 | name: jenkins-delivery-cluster-role-binding 18 | labels: {} 19 | clusterRoleName: cluster-admin 20 | serviceAccountName: stakater-delivery-jenkins 21 | serviceAccount: 22 | # Specifies whether a ServiceAccount should be created 23 | create: true 24 | labels: {} 25 | # The name of the ServiceAccount to use. 26 | # If not set and create is true, a name is generated using the fullname template 27 | name: stakater-delivery-jenkins 28 | -------------------------------------------------------------------------------- /platform/delivery/jenkins-rbac-slave.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: ClusterRoleBinding 3 | metadata: 4 | name: jenkins-delivery-slave-cluster-role-binding 5 | roleRef: 6 | apiGroup: rbac.authorization.k8s.io 7 | kind: ClusterRole 8 | name: cluster-admin 9 | subjects: 10 | - kind: ServiceAccount 11 | name: jenkins 12 | namespace: delivery -------------------------------------------------------------------------------- /platform/delivery/jenkins.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: helm.fluxcd.io/v1 2 | kind: HelmRelease 3 | metadata: 4 | name: stakater-delivery-jenkins 5 | namespace: delivery 6 | spec: 7 | releaseName: stakater-delivery-jenkins 8 | chart: 9 | repository: https://kubernetes-charts.storage.googleapis.com 10 | name: jenkins 11 | version: 1.8.2 12 | values: 13 | serviceAccount: 14 | name: jenkins 15 | 16 | persistence: 17 | enabled: true 18 | existingClaim: stakater-delivery-jenkins 19 | 20 | rbac: 21 | create: true 22 | 23 | master: 24 | image: jenkins/jenkins 25 | imageTag: "2.223" 26 | resources: 27 | limits: 28 | cpu: 2000m 29 | memory: 3072Mi 30 | requests: 31 | cpu: 50m 32 | memory: 256Mi 33 | 34 | ingress: 35 | annotations: 36 | exposeIngressUrl: globally 37 | forecastle.stakater.com/expose: "true" 38 | forecastle.stakater.com/appName: Jenkins 39 | forecastle.stakater.com/icon: https://github.com/stakater/ForecastleIcons/raw/master/jenkins.png 40 | ingress.kubernetes.io/force-ssl-redirect: "true" 41 | ingress.kubernetes.io/proxy-body-size: 150m 42 | kubernetes.io/ingress.class: external-ingress 43 | enabled: true 44 | hostName: jenkins-delivery.DOMAIN 45 | path: / 46 | tls: 47 | - hosts: 48 | - jenkins-delivery.DOMAIN 49 | 50 | securityRealm: |- 51 | 52 | KEYCLOAK_CLIENT_ID KEYCLOAK_CLIENT_SECRET 53 | https://keycloak-security.DOMAIN/auth/realms/stakater/protocol/openid-connect/token 54 | https://keycloak-security.DOMAIN/auth/realms/stakater/protocol/openid-connect/auth 55 | email openid email 56 | 57 | serviceType: ClusterIP 58 | installPlugins: 59 | - workflow-cps:2.80 60 | - git:3.9.1 61 | - oic-auth:1.7 62 | - github:1.29.2 63 | - github-pullrequest:0.2.4 64 | - github-oauth:0.29 65 | - github-api:1.92 66 | - github-branch-source:2.4.1 67 | - github-issues:1.2.4 68 | - workflow-multibranch:2.21 69 | - pipeline-model-api:1.6.0 70 | - pipeline-stage-step:2.3 71 | - workflow-cps-global-lib:2.16 72 | - pipeline-github-lib:1.0 73 | - kubernetes:1.12.6 74 | - kubernetes-pipeline-steps:1.5 75 | - kubernetes-pipeline-aggregator:1.5 76 | - workflow-basic-steps:2.19 77 | - jdk-tool:1.4 78 | - jackson2-api:2.9.8 79 | - blueocean-pipeline-api-impl:1.8.4 80 | - pipeline-utility-steps:2.5.0 81 | - gitlab-plugin:1.5.13 82 | - gitlab-merge-request-jenkins:2.0.0 83 | - job-dsl:1.77 84 | - cloudbees-folder:6.11.1 85 | - authorize-project:1.3.0 86 | - gitlab-hook:1.4.2 87 | - pipeline-stage-view:2.13 88 | - ssh-agent:1.19 89 | - ssh:2.6.1 90 | - ssh-credentials:1.17.2 91 | - ssh-steps:1.1.1 92 | - rich-text-publisher-plugin:1.4 93 | - timestamper:1.11.2 94 | - workflow-aggregator:2.6 95 | - cloudbees-bitbucket-branch-source:2.7.0 96 | - pipeline-aws:1.41 97 | - pipeline-model-extensions:1.6.0 98 | 99 | scriptApproval: 100 | - staticMethod org.codehaus.groovy.runtime.DefaultGroovyMethods first java.lang.Object[] 101 | - method hudson.tasks.test.AbstractTestResultAction getFailCount 102 | - method hudson.tasks.test.AbstractTestResultAction getSkipCount 103 | - method hudson.tasks.test.AbstractTestResultAction getTotalCount 104 | - method java.lang.CharSequence subSequence int int 105 | - field hudson.plugins.git.GitSCM GIT_BRANCH 106 | - method hudson.plugins.git.GitSCM getUserRemoteConfigs 107 | - method hudson.plugins.git.UserRemoteConfig getUrl 108 | - method hudson.plugins.git.UserRemoteConfig getRefspec 109 | - method hudson.plugins.git.UserRemoteConfig getName 110 | - staticMethod org.codehaus.groovy.runtime.DefaultGroovyMethods first java.util.List 111 | - method java.net.URL getHost 112 | - method java.net.URL getPath 113 | - field hudson.plugins.git.GitSCMBackwardCompatibility branch 114 | - field hudson.plugins.git.GitSCMBackwardCompatibility source 115 | - method groovy.json.JsonBuilder toPrettyString 116 | - method groovy.json.JsonSlurper parse java.io.Reader 117 | - method groovy.json.JsonSlurperClassic parse java.io.Reader 118 | - method groovy.json.JsonSlurperClassic parseText java.lang.String 119 | - method groovy.lang.GroovyObject getProperty java.lang.String 120 | - method groovy.lang.GroovyObject invokeMethod java.lang.String java.lang.Object 121 | - method groovy.lang.GString plus java.lang.String 122 | - method groovy.util.ConfigSlurper parse java.net.URL 123 | - method groovy.util.ConfigSlurper parse java.util.Properties 124 | - method groovy.util.slurpersupport.GPathResult text 125 | - method groovy.util.XmlSlurper parse java.lang.String 126 | - method groovy.util.XmlSlurper parseText java.lang.String 127 | - method groovy.xml.DOMBuilder parseText java.lang.String 128 | - method hudson.model.Actionable getAction java.lang.Class 129 | - method hudson.model.Job getBuildByNumber int 130 | - method hudson.model.Job getProperty java.lang.Class 131 | - method hudson.model.Run getCause java.lang.Class 132 | - method hudson.scm.SCM getBrowser 133 | - method io.fabric8.kubernetes.client.KubernetesClient configMaps 134 | - method io.fabric8.kubernetes.client.dsl.Namespaceable inNamespace java.lang.String 135 | - method io.fabric8.jenkins.openshiftsync.BuildCause getName 136 | - method io.fabric8.jenkins.openshiftsync.BuildConfigProjectProperty getName 137 | - method io.fabric8.kubernetes.api.model.Doneable done 138 | - method io.fabric8.kubernetes.api.model.KubernetesResourceList getItems 139 | - method io.fabric8.kubernetes.api.model.ObjectMeta getName 140 | - method io.fabric8.kubernetes.api.model.ObjectMetaFluent addToAnnotations java.lang.String java.lang.String 141 | - method io.fabric8.kubernetes.api.model.ObjectMetaFluent withName java.lang.String 142 | - method io.fabric8.kubernetes.api.pipelines.PipelineConfiguration getUseDockerSocketFlag 143 | - method io.fabric8.kubernetes.api.pipelines.PipelineConfiguration isUseDockerSocket 144 | - method io.fabric8.kubernetes.client.Client adapt java.lang.Class 145 | - method io.fabric8.kubernetes.client.Client getNamespace 146 | - method io.fabric8.kubernetes.client.Client isAdaptable java.lang.Class 147 | - method io.fabric8.kubernetes.client.dsl.Createable createNew 148 | - method io.fabric8.kubernetes.client.dsl.Editable edit 149 | - method io.fabric8.kubernetes.client.dsl.Gettable get 150 | - method io.fabric8.kubernetes.client.dsl.KubernetesDSL nodes 151 | - method io.fabric8.kubernetes.client.dsl.Listable list 152 | - method io.fabric8.kubernetes.client.dsl.Nameable withName java.lang.String 153 | - method io.fabric8.kubernetes.client.dsl.Namespaceable inNamespace java.lang.String 154 | - method io.fabric8.kubernetes.client.KubernetesClient namespaces 155 | - method io.fabric8.kubernetes.client.KubernetesClient nodes 156 | - method io.fabric8.kubernetes.client.KubernetesClient services 157 | - method io.fabric8.openshift.api.model.BuildFluent editMetadata 158 | - method io.fabric8.openshift.api.model.BuildFluent$MetadataNested endMetadata 159 | - method io.fabric8.openshift.api.model.ImageStream getStatus 160 | - method io.fabric8.openshift.api.model.ImageStreamStatus getTags 161 | - method io.fabric8.openshift.api.model.NamedTagEventList getItems 162 | - method io.fabric8.openshift.api.model.ProjectRequestFluent withDisplayName java.lang.String 163 | - method io.fabric8.openshift.api.model.ProjectRequestFluent withNewMetadata 164 | - method io.fabric8.openshift.api.model.ProjectRequestFluent$MetadataNested endMetadata 165 | - method io.fabric8.openshift.api.model.Route getSpec 166 | - method io.fabric8.openshift.api.model.TagEvent getImage 167 | - method io.fabric8.openshift.client.OpenShiftClient builds 168 | - method io.fabric8.openshift.client.OpenShiftClient imageStreams 169 | - method io.fabric8.openshift.client.OpenShiftClient projectrequests 170 | - method io.fabric8.openshift.client.OpenShiftClient projects 171 | - method io.fabric8.openshift.client.OpenShiftClient supportsOpenShiftAPIGroup 172 | - method io.fabric8.openshift.client.OpenShiftClient supportsOpenShiftAPIGroup java.lang.String 173 | - new org.csanchez.jenkins.plugins.kubernetes.PodAnnotation java.lang.String java.lang.String 174 | - staticMethod org.kohsuke.groovy.sandbox.impl.Checker checkedCall java.lang.Object boolean boolean java.lang.String java.lang.Object[] 175 | - new java.util.LinkedHashMap java.util.Map 176 | - method java.lang.Class getPackage 177 | - method java.lang.Package getSpecificationTitle 178 | - method java.lang.Package getSpecificationVersion 179 | - method java.lang.Package getImplementationVersion 180 | - staticMethod java.lang.Double parseDouble java.lang.String 181 | - method io.fabric8.kubernetes.client.KubernetesClient configMaps 182 | - method io.fabric8.kubernetes.api.model.ConfigMap getData 183 | - method java.io.File close 184 | - method java.io.File exists 185 | - method java.io.File newOutputStream 186 | - method java.io.File toURL 187 | - method java.io.Flushable flush 188 | - method java.io.Writer write java.lang.String 189 | - method java.lang.AutoCloseable close 190 | - method java.lang.Class isInstance java.lang.Object 191 | - method java.lang.ClassLoader loadClass java.lang.String 192 | - method java.lang.Object getClass 193 | - method java.lang.String isEmpty 194 | - method java.lang.String replaceAll java.lang.String java.lang.String 195 | - method java.lang.String substring int 196 | - method java.lang.Thread getContextClassLoader 197 | - method java.lang.Throwable printStackTrace 198 | - method java.net.HttpURLConnection disconnect 199 | - method java.net.HttpURLConnection getResponseCode 200 | - method java.net.HttpURLConnection setRequestMethod java.lang.String 201 | - method java.net.URL openConnection 202 | - method java.net.URL openStream 203 | - method java.net.URLConnection connect 204 | - method java.net.URLConnection getInputStream 205 | - method java.net.URLConnection getOutputStream 206 | - method java.net.URLConnection setDoInput boolean 207 | - method java.net.URLConnection setDoOutput boolean 208 | - method java.net.URLConnection setRequestProperty java.lang.String java.lang.String 209 | - method java.util.LinkedHashMap$LinkedHashIterator hasNext 210 | - method java.util.Properties load java.io.InputStream 211 | - method java.util.regex.Matcher group java.lang.String 212 | - method java.util.regex.Matcher matches 213 | - method java.util.regex.Pattern matcher java.lang.CharSequence 214 | - method java.util.Scanner useDelimiter java.lang.String 215 | - method jenkins.model.Jenkins getCloud java.lang.String 216 | - method jenkins.model.Jenkins getItemByFullName java.lang.String 217 | - method org.jenkinsci.plugins.workflow.support.actions.EnvironmentAction getEnvironment 218 | - method org.jenkinsci.plugins.workflow.support.steps.build.RunWrapper getRawBuild 219 | - method org.w3c.dom.Document getDocumentElement 220 | - method org.w3c.dom.Document getElementsByTagName java.lang.String 221 | - method org.w3c.dom.Element getElementsByTagName java.lang.String 222 | - method org.w3c.dom.Node getChildNodes 223 | - method org.w3c.dom.Node getNodeName 224 | - method org.w3c.dom.Node getTextContent 225 | - method org.w3c.dom.Node setTextContent java.lang.String 226 | - method org.w3c.dom.NodeList getLength 227 | - method org.w3c.dom.NodeList item int 228 | - method io.fabric8.kubernetes.api.model.ConfigMap getData 229 | - method io.fabric8.kubernetes.api.model.HasMetadata getMetadata 230 | - method java.util.Collection toArray 231 | - new groovy.json.JsonBuilder java.lang.Object 232 | - new groovy.json.JsonSlurper 233 | - new groovy.json.JsonSlurperClassic 234 | - new groovy.util.ConfigSlurper 235 | - new groovy.util.XmlSlurper 236 | - new io.fabric8.kubernetes.client.DefaultKubernetesClient 237 | - new io.fabric8.openshift.client.DefaultOpenShiftClient 238 | - new java.io.File java.lang.String 239 | - new java.io.FileInputStream java.io.File 240 | - new java.io.InputStreamReader java.io.InputStream java.lang.String 241 | - new java.io.InputStreamReader java.io.InputStream 242 | - new java.io.OutputStreamWriter java.io.OutputStream 243 | - new java.lang.String java.lang.String 244 | - new java.lang.StringBuilder 245 | - new java.util.Properties 246 | - new java.util.Scanner java.io.InputStream java.lang.String 247 | - new java.util.Scanner java.lang.Readable 248 | - new java.util.LinkedHashMap java.util.Map 249 | - staticField groovy.io.FileType FILES 250 | - staticMethod org.codehaus.groovy.runtime.DefaultGroovyMethods getAt java.lang.Object java.lang.String 251 | - staticMethod org.kohsuke.groovy.sandbox.impl.Checker checkedConstructor java.lang.Class java.lang.Object[] 252 | - staticMethod groovy.xml.DOMBuilder newInstance 253 | - staticMethod groovy.xml.XmlUtil serialize org.w3c.dom.Element 254 | - staticMethod io.fabric8.kubernetes.api.environments.Environments load io.fabric8.kubernetes.client.DefaultKubernetesClient java.lang.String 255 | - staticMethod io.fabric8.kubernetes.api.environments.Environments load io.fabric8.kubernetes.client.KubernetesClient java.lang.String 256 | - staticMethod io.fabric8.kubernetes.api.environments.Environments load java.lang.String 257 | - staticMethod io.fabric8.kubernetes.api.environments.Environments load 258 | - staticMethod io.fabric8.kubernetes.api.environments.Environments namespaceForEnvironment io.fabric8.kubernetes.client.DefaultKubernetesClient java.lang.String java.lang.String 259 | - staticMethod io.fabric8.kubernetes.api.environments.Environments namespaceForEnvironment io.fabric8.kubernetes.client.KubernetesClient java.lang.String java.lang.String 260 | - staticMethod io.fabric8.kubernetes.api.environments.Environments namespaceForEnvironment java.lang.String java.lang.String 261 | - staticMethod io.fabric8.kubernetes.api.environments.Environments namespaceForEnvironment java.lang.String 262 | - staticMethod io.fabric8.kubernetes.api.KubernetesHelper getServiceURL io.fabric8.kubernetes.client.DefaultKubernetesClient java.lang.String java.lang.String java.lang.String boolean 263 | - staticMethod io.fabric8.kubernetes.api.KubernetesHelper getServiceURL io.fabric8.kubernetes.client.KubernetesClient java.lang.String java.lang.String java.lang.String boolean 264 | - staticMethod io.fabric8.kubernetes.api.pipelines.PipelineConfiguration loadPipelineConfiguration io.fabric8.kubernetes.client.DefaultKubernetesClient java.lang.String 265 | - staticMethod io.fabric8.kubernetes.api.pipelines.PipelineConfiguration loadPipelineConfiguration io.fabric8.kubernetes.client.KubernetesClient java.lang.String 266 | - staticMethod io.fabric8.kubernetes.api.pipelines.PipelineConfiguration loadPipelineConfiguration java.lang.String 267 | - staticMethod io.fabric8.kubernetes.api.pipelines.PipelineConfiguration loadPipelineConfiguration 268 | - staticMethod io.fabric8.kubernetes.api.pipelines.Pipelines getPipeline io.fabric8.kubernetes.client.DefaultKubernetesClient java.lang.String io.fabric8.kubernetes.api.pipelines.JobEnvironment java.lang.String java.util.Map 269 | - staticMethod io.fabric8.kubernetes.api.pipelines.Pipelines getPipeline io.fabric8.kubernetes.client.KubernetesClient java.lang.String io.fabric8.kubernetes.api.pipelines.JobEnvironment 270 | - staticMethod io.fabric8.kubernetes.api.pipelines.Pipelines getPipeline io.fabric8.kubernetes.client.KubernetesClient java.lang.String java.util.Map 271 | - staticMethod io.fabric8.kubernetes.api.pipelines.Pipelines getPipeline java.lang.String java.util.Map 272 | - staticMethod io.fabric8.kubernetes.client.Adapters get java.lang.Class 273 | - staticMethod io.fabric8.utils.Strings isNotBlank java.lang.String 274 | - staticMethod java.lang.String valueOf int 275 | - staticMethod java.lang.System getenv 276 | - staticMethod java.lang.System getProperty java.lang.String 277 | - staticMethod java.lang.Thread currentThread 278 | - staticMethod java.lang.Thread sleep long 279 | - staticMethod java.util.regex.Pattern compile java.lang.String 280 | - staticMethod java.util.UUID randomUUID 281 | - staticMethod jenkins.model.Jenkins getActiveInstance 282 | - staticMethod jenkins.model.Jenkins getInstance 283 | - staticMethod org.codehaus.groovy.runtime.DefaultGroovyMethods count java.lang.String java.lang.String 284 | - staticMethod org.codehaus.groovy.runtime.DefaultGroovyMethods each java.lang.Object groovy.lang.Closure 285 | - staticMethod org.codehaus.groovy.runtime.DefaultGroovyMethods eachDirRecurse java.io.File groovy.lang.Closure 286 | - staticMethod org.codehaus.groovy.runtime.DefaultGroovyMethods eachFile java.io.File groovy.lang.Closure 287 | - staticMethod org.codehaus.groovy.runtime.DefaultGroovyMethods eachFileMatch java.io.File java.lang.Object groovy.lang.Closure 288 | - staticMethod org.codehaus.groovy.runtime.DefaultGroovyMethods eachFileRecurse java.io.File groovy.io.FileType groovy.lang.Closure 289 | - staticMethod org.codehaus.groovy.runtime.DefaultGroovyMethods eachFileRecurse java.io.File groovy.lang.Closure 290 | - staticMethod org.codehaus.groovy.runtime.DefaultGroovyMethods eachLine java.io.File groovy.lang.Closure 291 | - staticMethod org.codehaus.groovy.runtime.DefaultGroovyMethods eachLine java.lang.String groovy.lang.Closure 292 | - staticMethod org.codehaus.groovy.runtime.DefaultGroovyMethods eachWithIndex java.lang.Object groovy.lang.Closure 293 | - staticMethod org.codehaus.groovy.runtime.DefaultGroovyMethods get java.util.Map java.lang.Object java.lang.Object 294 | - staticMethod org.codehaus.groovy.runtime.DefaultGroovyMethods getCount java.util.regex.Matcher 295 | - staticMethod org.codehaus.groovy.runtime.DefaultGroovyMethods getText java.net.URL 296 | - staticMethod org.codehaus.groovy.runtime.DefaultGroovyMethods invokeMethod java.lang.Object java.lang.String java.lang.Object 297 | - staticMethod org.codehaus.groovy.runtime.DefaultGroovyMethods isNumber java.lang.String 298 | - staticMethod org.codehaus.groovy.runtime.DefaultGroovyMethods leftShift java.io.OutputStream java.io.InputStream 299 | - staticMethod org.codehaus.groovy.runtime.DefaultGroovyMethods leftShift java.io.OutputStream java.lang.Object 300 | - staticMethod org.codehaus.groovy.runtime.DefaultGroovyMethods leftShift java.util.Collection java.lang.Object 301 | - staticMethod org.codehaus.groovy.runtime.DefaultGroovyMethods minus java.lang.String java.lang.Object 302 | - staticMethod org.codehaus.groovy.runtime.DefaultGroovyMethods newReader java.net.URL 303 | - staticMethod org.codehaus.groovy.runtime.DefaultGroovyMethods println groovy.lang.Closure java.lang.Object 304 | - staticMethod org.codehaus.groovy.runtime.DefaultGroovyMethods readLine java.io.Reader 305 | - staticMethod org.codehaus.groovy.runtime.DefaultGroovyMethods removeAll java.util.Collection java.lang.Object[] 306 | - staticMethod org.codehaus.groovy.runtime.DefaultGroovyMethods size java.lang.Object[] 307 | - staticMethod org.codehaus.groovy.runtime.DefaultGroovyMethods take java.lang.CharSequence int 308 | - staticMethod org.codehaus.groovy.runtime.DefaultGroovyMethods toInteger java.lang.String 309 | - staticMethod org.codehaus.groovy.runtime.DefaultGroovyMethods use java.lang.Object java.lang.Class groovy.lang.Closure 310 | - staticMethod org.codehaus.groovy.runtime.DefaultGroovyMethods withInputStream java.io.File groovy.lang.Closure 311 | - staticMethod org.codehaus.groovy.runtime.ScriptBytecodeAdapter bitwiseNegate java.lang.Object 312 | - staticMethod org.codehaus.groovy.runtime.ScriptBytecodeAdapter compareGreaterThan java.lang.Object java.lang.Object 313 | - method java.net.URLConnection getHeaderField java.lang.String 314 | -------------------------------------------------------------------------------- /platform/delivery/nexus.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: helm.fluxcd.io/v1 2 | kind: HelmRelease 3 | metadata: 4 | name: stakater-delivery-nexus 5 | namespace: delivery 6 | spec: 7 | releaseName: stakater-delivery-nexus 8 | chart: 9 | repository: https://kubernetes-charts.storage.googleapis.com 10 | name: sonatype-nexus 11 | version: 1.18.1 12 | values: 13 | nameOverride: nexus 14 | fullnameOverride: nexus 15 | statefulset: 16 | enabled: false 17 | 18 | replicaCount: 1 19 | deploymentStrategy: {} 20 | 21 | nexus: 22 | annotations: 23 | config.xposer.stakater.com/Domain: DOMAIN 24 | config.xposer.stakater.com/IngressNameTemplate: "{{.Service}}-{{.Namespace}}" 25 | config.xposer.stakater.com/IngressURLTemplate: "{{.Service}}-{{.Namespace}}.{{.Domain}}" 26 | xposer.stakater.com/annotations: |- 27 | kubernetes.io/ingress.class: internal-ingress 28 | ingress.kubernetes.io/force-ssl-redirect: true 29 | ingress.kubernetes.io/proxy-body-size: 900m 30 | forecastle.stakater.com/expose: true 31 | forecastle.stakater.com/icon: https://github.com/stakater/ForecastleIcons/raw/master/nexus.png 32 | forecastle.stakater.com/appName: Nexus 33 | exposeIngressUrl: locally 34 | dockerPort: 5003 35 | env: null 36 | hostAliases: [] 37 | imageName: quay.io/travelaudience/docker-nexus 38 | imagePullPolicy: IfNotPresent 39 | imageTag: 3.15.2 40 | livenessProbe: 41 | failureThreshold: 6 42 | initialDelaySeconds: 30 43 | path: / 44 | periodSeconds: 30 45 | timeoutSeconds: 10 46 | nexusPort: 8081 47 | readinessProbe: 48 | failureThreshold: 6 49 | initialDelaySeconds: 30 50 | path: / 51 | periodSeconds: 30 52 | timeoutSeconds: 10 53 | resources: {} 54 | service: 55 | type: ClusterIP 56 | 57 | nexusProxy: 58 | enabled: true 59 | env: 60 | cloudIamAuthEnabled: false 61 | enforceHttps: false 62 | nexusDockerHost: null 63 | nexusHttpHost: null 64 | imageName: quay.io/travelaudience/docker-nexus-proxy 65 | imagePullPolicy: IfNotPresent 66 | imageTag: 2.4.0_8u191 67 | labels: 68 | expose: "true" 69 | port: 80 70 | resources: {} 71 | svcName: nexus 72 | targetPort: 8081 73 | 74 | persistence: 75 | accessMode: ReadWriteOnce 76 | enabled: true 77 | existingClaim: stakater-delivery-sonatype-nexus-data-big 78 | 79 | nexusBackup: 80 | enabled: false 81 | imageName: quay.io/travelaudience/docker-nexus-backup 82 | imagePullPolicy: IfNotPresent 83 | imageTag: 1.3.0 84 | nexusAdminPassword: admin123 85 | persistence: 86 | accessMode: ReadWriteOnce 87 | enabled: true 88 | storageSize: 8Gi 89 | 90 | ingress: 91 | annotations: {} 92 | enabled: false 93 | path: / 94 | tls: 95 | enabled: true 96 | secretName: nexus-tls 97 | 98 | tolerations: 99 | - effect: NoSchedule 100 | key: dedicated 101 | operator: Equal 102 | value: app 103 | 104 | deployment: 105 | additionalVolumeMounts: 106 | - mountPath: /sonatype-nexus-conf 107 | name: pre-install 108 | additionalVolumes: 109 | - emptyDir: {} 110 | name: pre-install 111 | annotations: {} 112 | initContainers: 113 | - command: 114 | - sh 115 | - -c 116 | - cp /scripts/* /etc/pre-install/ 117 | image: busybox 118 | name: copy-ro-scripts 119 | volumeMounts: 120 | - mountPath: /scripts 121 | name: nexus-conf 122 | - mountPath: /etc/pre-install 123 | name: pre-install 124 | - command: 125 | - chown 126 | - -R 127 | - "200" 128 | - /nexus-data 129 | image: busybox 130 | imagePullPolicy: IfNotPresent 131 | name: fmp-volume-permission 132 | volumeMounts: 133 | - mountPath: /nexus-data 134 | name: nexus-data 135 | - command: 136 | - chmod 137 | - -R 138 | - "777" 139 | - /sonatype-nexus-conf 140 | image: busybox 141 | imagePullPolicy: IfNotPresent 142 | name: fmp-volume-permission2 143 | volumeMounts: 144 | - mountPath: /sonatype-nexus-conf 145 | name: pre-install 146 | postStart: 147 | command: '["/bin/sh", "-c", "/sonatype-nexus-conf/postStart.sh"]' 148 | 149 | secret: 150 | data: 151 | .admin_account.json: BASE64_ENCODED_NEXUS_ADMIN_ACCOUNT_JSON 152 | .cluster_account.json: BASE64_ENCODED_NEXUS_CLUSTER_ACCOUNT_JSON 153 | enabled: true 154 | mountPath: /etc/secret-volume 155 | readOnly: true 156 | 157 | service: 158 | annotations: 159 | config.xposer.stakater.com/Domain: DOMAIN 160 | config.xposer.stakater.com/IngressNameTemplate: "{{.Service}}-{{.Namespace}}" 161 | config.xposer.stakater.com/IngressURLTemplate: "{{.Service}}-{{.Namespace}}.{{.Domain}}" 162 | xposer.stakater.com/annotations: |- 163 | kubernetes.io/ingress.class: internal-ingress 164 | ingress.kubernetes.io/force-ssl-redirect: true 165 | ingress.kubernetes.io/proxy-body-size: 900m 166 | enabled: true 167 | labels: 168 | expose: "true" 169 | name: docker 170 | port: 80 171 | portName: docker 172 | serviceType: ClusterIP 173 | targetPort: 5003 174 | 175 | config: 176 | data: 177 | eclipselink.json: | 178 | { 179 | "name": "eclipselink", 180 | "type": "groovy", 181 | "content": "repository.createMavenProxy('eclipselink', 'http://download.eclipse.org/rt/eclipselink/maven.repo/')" 182 | } 183 | fuse-ea.json: | 184 | { 185 | "name": "fuse-ea", 186 | "type": "groovy", 187 | "content": "repository.createMavenProxy('fuse-ea', 'https://repo.fusesource.com/nexus/content/groups/ea/')" 188 | } 189 | fuse.json: | 190 | { 191 | "name": "fuse", 192 | "type": "groovy", 193 | "content": "repository.createMavenProxy('fuse', 'https://repository.jboss.org/nexus/content/repositories/fs-releases/')" 194 | } 195 | jboss-http: | 196 | { 197 | "name": "jboss-http", 198 | "type": "groovy", 199 | "content": "repository.createMavenProxy('jboss-http', 'http://repository.jboss.org/nexus/content/groups/public/')" 200 | } 201 | jboss.json: | 202 | { 203 | "name": "jboss", 204 | "type": "groovy", 205 | "content": "repository.createMavenProxy('jboss', 'https://repository.jboss.org/nexus/content/groups/public/')" 206 | } 207 | jcenter.json: | 208 | { 209 | "name": "jcenter", 210 | "type": "groovy", 211 | "content": "repository.createMavenProxy('jcenter', 'http://jcenter.bintray.com/')" 212 | } 213 | jenkins-ci.json: | 214 | { 215 | "name": "jenkins-ci", 216 | "type": "groovy", 217 | "content": "repository.createMavenProxy('jenkins-ci', 'http://repo.jenkins-ci.org/public/')" 218 | } 219 | npm-internal.json: | 220 | { 221 | "name": "npm-internal", 222 | "type": "groovy", 223 | "content": "repository.createNpmHosted('npm-internal')" 224 | } 225 | npmjs.json: | 226 | { 227 | "name": "npmjs", 228 | "type": "groovy", 229 | "content": "repository.createNpmProxy('npmjs', 'https://registry.npmjs.org')" 230 | } 231 | postStart.sh: | 232 | #!/usr/bin/env bash 233 | HOST=localhost:8081 234 | 235 | # default user setup by Nexus. In the end of this script I will remove all roles from this account 236 | USERNAME=admin 237 | PASSWORD=admin123 238 | 239 | apk add --no-cache curl 240 | 241 | # Admin Account details specified in nexus secret .admin_account.json 242 | ADMIN_ACCOUNT_USERNAME=NEXUS_ADMIN_ACCOUNT_USER 243 | # Cluster Account details specified in nexus secret .cluster_account.json 244 | CLUSTER_ACCOUNT_USERNAME=NEXUS_CLUSTER_ACCOUNT_USER 245 | 246 | echo `pwd` 247 | cd /sonatype-nexus-conf/ 248 | 249 | REPOS=($(ls | grep json | sed -e 's/\..*$//')) 250 | 251 | until $(curl --output /dev/null --silent --head --fail http://$HOST/); do 252 | echo $? 253 | printf '.' 254 | sleep 5 255 | done 256 | 257 | if [ ${#REPOS[@]} -lt 1 ] 258 | then 259 | echo "Not enough JSON files!" 260 | exit 1 261 | fi 262 | 263 | echo "uploading secret admin account script" 264 | STATUSCODE=$(curl --output /dev/stderr --silent -v -u $USERNAME:$PASSWORD --header "Content-Type: application/json" --write-out "%{http_code}" "http://$HOST/service/rest/v1/script/" -d @/etc/secret-volume/.admin_account.json) 265 | if [ $STATUSCODE -eq 403 ] 266 | then 267 | echo "Already initialized; as we remove rights of the admin user in the end of this script; when it runs first time. So, when container restarts it should work." 268 | exit 0 269 | elif [ $STATUSCODE -lt 200 ] || [ $STATUSCODE -gt 299 ] 270 | then 271 | echo "Could not upload secret" 272 | exit 1 273 | else 274 | echo $STATUSCODE 275 | fi 276 | 277 | echo "Executing secret admin account script" 278 | STATUSCODE=$(curl --output /dev/stderr --silent -v -X POST -u $USERNAME:$PASSWORD --header "Content-Type: text/plain" --write-out "%{http_code}" "http://$HOST/service/rest/v1/script/${ADMIN_ACCOUNT_USERNAME}/run") 279 | if [ $STATUSCODE -lt 200 ] || [ $STATUSCODE -gt 299 ] 280 | then 281 | echo "Could not execute secret" 282 | exit 1 283 | fi 284 | 285 | echo "Delete secret admin account script" 286 | STATUSCODE=$(curl -X "DELETE" --output /dev/stderr --silent -v -u $USERNAME:$PASSWORD --write-out "%{http_code}" "http://$HOST/service/rest/v1/script/${ADMIN_ACCOUNT_USERNAME}") 287 | if [ $STATUSCODE -lt 200 ] || [ $STATUSCODE -gt 299 ] 288 | then 289 | echo "Could not delete secret" 290 | exit 1 291 | fi 292 | 293 | echo "Uploading secret cluster account script" 294 | STATUSCODE=$(curl --output /dev/stderr --silent -v -u $USERNAME:$PASSWORD --header "Content-Type: application/json" --write-out "%{http_code}" "http://$HOST/service/rest/v1/script/" -d @/etc/secret-volume/.cluster_account.json) 295 | if [ $STATUSCODE -lt 200 ] || [ $STATUSCODE -gt 299 ] 296 | then 297 | echo "Could not upload secret" 298 | exit 1 299 | fi 300 | 301 | echo "Executing secret cluster account script" 302 | STATUSCODE=$(curl --output /dev/stderr --silent -v -X POST -u $USERNAME:$PASSWORD --header "Content-Type: text/plain" --write-out "%{http_code}" "http://$HOST/service/rest/v1/script/${CLUSTER_ACCOUNT_USERNAME}/run") 303 | if [ $STATUSCODE -lt 200 ] || [ $STATUSCODE -gt 299 ] 304 | then 305 | echo "Could not execute secret" 306 | exit 1 307 | fi 308 | 309 | echo "Deleting secret cluster account script" 310 | STATUSCODE=$(curl -X "DELETE" --output /dev/stderr --silent -v -u $USERNAME:$PASSWORD --write-out "%{http_code}" "http://$HOST/service/rest/v1/script/${CLUSTER_ACCOUNT_USERNAME}") 311 | if [ $STATUSCODE -lt 200 ] || [ $STATUSCODE -gt 299 ] 312 | then 313 | echo "Could not delete secret" 314 | exit 1 315 | fi 316 | 317 | for i in "${REPOS[@]}" 318 | do 319 | echo "creating $i repository" 320 | STATUSCODE=$(curl --output /dev/stderr --silent -v -u $USERNAME:$PASSWORD --header "Content-Type: application/json" --write-out "%{http_code}" "http://$HOST/service/rest/v1/script/" -d @$i.json) 321 | if [ $STATUSCODE -lt 200 ] || [ $STATUSCODE -gt 299 ] 322 | then 323 | echo "Could not upload $i" 324 | exit 1 325 | fi 326 | 327 | STATUSCODE=$(curl --output /dev/stderr --silent -v -X POST -u $USERNAME:$PASSWORD --header "Content-Type: text/plain" --write-out "%{http_code}" "http://$HOST/service/rest/v1/script/$i/run") 328 | if [ $STATUSCODE -lt 200 ] || [ $STATUSCODE -gt 299 ] 329 | then 330 | echo "Could not execute $i" 331 | exit 1 332 | fi 333 | done 334 | 335 | exit $? 336 | remove-anonymous-configuration.json: | 337 | { 338 | "name": "remove-anonymous-configuration", 339 | "type": "groovy", 340 | "content": "security.setAnonymousAccess(false)" 341 | } 342 | rutauth.json: | 343 | { 344 | "name": "rutauth", 345 | "type": "groovy", 346 | "content": "import groovy.json.JsonOutput; import org.sonatype.nexus.capability.CapabilityReference; import org.sonatype.nexus.capability.CapabilityType; import org.sonatype.nexus.internal.capability.DefaultCapabilityReference;import org.sonatype.nexus.internal.capability.DefaultCapabilityRegistry; def capabilityRegistry = container.lookup(DefaultCapabilityRegistry.class.getName()); def capabilityType = CapabilityType.capabilityType('rutauth'); def capabilityProps = ['httpHeader': 'X-AUTH-STAKATER']; def capabilityNotes = 'configured through scripting api'; DefaultCapabilityReference existing = capabilityRegistry.all.find { CapabilityReference capabilityReference -> capabilityReference.context().descriptor().type() == capabilityType }; if (!existing) { capabilityRegistry.add(capabilityType, true, capabilityNotes, capabilityProps).toString(); JsonOutput.toJson([result : 'Successfully added Rut Auth!']) }" 347 | } 348 | servicemix.json: | 349 | { 350 | "name": "servicemix", 351 | "type": "groovy", 352 | "content": "repository.createMavenProxy('servicemix', 'http://svn.apache.org/repos/asf/servicemix/m2-repo/')" 353 | } 354 | sonatype-snapshots.json: | 355 | { 356 | "name": "sonatype-snapshots", 357 | "type": "groovy", 358 | "content": "repository.createMavenProxy('sonatype-snapshots', 'https://oss.sonatype.org/content/repositories/snapshots/')" 359 | } 360 | sonatype-staging.json: | 361 | { 362 | "name": "sonatype-staging", 363 | "type": "groovy", 364 | "content": "repository.createMavenProxy('sonatype-staging', 'https://oss.sonatype.org/content/repositories/staging/')" 365 | } 366 | spring-milestone.json: | 367 | { 368 | "name": "spring-milestone", 369 | "type": "groovy", 370 | "content": "repository.createMavenProxy('spring-milestone', 'http://repo.spring.io/milestone/')" 371 | } 372 | spring-release.json: | 373 | { 374 | "name": "spring-release", 375 | "type": "groovy", 376 | "content": "repository.createMavenProxy('spring-release', 'http://repo.spring.io/release/')" 377 | } 378 | stackator-docker.json: | 379 | { 380 | "name": "stackator-docker", 381 | "type": "groovy", 382 | "content": "repository.createDockerHosted('stackator-docker', 5003, null, 'default', false, true, org.sonatype.nexus.repository.storage.WritePolicy.ALLOW)" 383 | } 384 | zzz_npm-all.json: | 385 | { 386 | "name": "zzz_npm-all", 387 | "type": "groovy", 388 | "content": "repository.createNpmGroup('npm-all', ['npmjs','npm-internal'])" 389 | } 390 | zzz_public.json: | 391 | { 392 | "name": "zzz_public", 393 | "type": "groovy", 394 | "content": "repository.createMavenGroup('public', ['fuse','jboss','jenkins-ci','maven-central','maven-public','maven-releases','maven-snapshots','sonatype-snapshots','sonatype-staging'])" 395 | } 396 | zzzz-remove-default.json: |- 397 | { 398 | "name": "zzzz-remove-default", 399 | "type": "groovy", 400 | "content": "security.setUserRoles('admin', [])" 401 | } 402 | enabled: true 403 | mountPath: /sonatype-nexus-temp 404 | -------------------------------------------------------------------------------- /platform/delivery/pvc/jenkins-pvc.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: PersistentVolumeClaim 3 | metadata: 4 | labels: 5 | app: stakater-delivery-jenkins 6 | name: stakater-delivery-jenkins 7 | namespace: delivery 8 | spec: 9 | accessModes: 10 | - ReadWriteOnce 11 | resources: 12 | requests: 13 | storage: 8Gi 14 | storageClassName: stakater-storageclass 15 | -------------------------------------------------------------------------------- /platform/delivery/pvc/nexus-pvc.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: PersistentVolumeClaim 3 | metadata: 4 | labels: 5 | app: sonatype-nexus 6 | fullname: stakater-delivery-sonatype-nexus 7 | name: stakater-delivery-sonatype-nexus-data-big 8 | namespace: delivery 9 | spec: 10 | accessModes: 11 | - ReadWriteOnce 12 | resources: 13 | requests: 14 | storage: 80Gi 15 | storageClassName: stakater-storageclass 16 | -------------------------------------------------------------------------------- /platform/delivery/rdlm.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: helm.fluxcd.io/v1 2 | kind: HelmRelease 3 | metadata: 4 | name: stakater-delivery-rdlm 5 | namespace: delivery 6 | spec: 7 | releaseName: stakater-delivery-rdlm 8 | chart: 9 | repository: https://stakater.github.io/stakater-charts/ 10 | name: restful-distributed-lock-manager 11 | version: 1.0.4 12 | values: 13 | rdlm: 14 | labels: 15 | group: com.stakater.platform 16 | provider: stakater 17 | version: 0.5.3 18 | deployment: 19 | replicas: 1 20 | podLabels: 21 | app: rdlm 22 | container: 23 | name: rdlm 24 | imageName: stakater/restful-distributed-lock-manager 25 | imageTag: 0.5.3 26 | port: 8080 27 | targetPort: 8888 28 | -------------------------------------------------------------------------------- /platform/delivery/secrets/secret-jenkins-dockercfg.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | data: 3 | config.json: BASE64_ENCODED_JENKINS_CONFIG 4 | kind: Secret 5 | metadata: 6 | name: jenkins-docker-cfg 7 | namespace: delivery 8 | type: Opaque -------------------------------------------------------------------------------- /platform/delivery/secrets/secret-jenkins-maven.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | data: 3 | settings.xml: BASE64_ENCODED_JENKINS_MAVEN_CONFIG 4 | kind: Secret 5 | metadata: 6 | name: jenkins-maven-settings 7 | namespace: delivery 8 | type: Opaque -------------------------------------------------------------------------------- /platform/delivery/secrets/secret-jenkins-vc-api-tokens.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | data: 3 | bitbucket: JENKINS_PIPELINE_BITBUCKET_TOKEN 4 | gitlab.hub: JENKINS_PIPELINE_GITLAB_TOKEN 5 | hub: JENKINS_PIPELINE_GITHUB_TOKEN 6 | kind: Secret 7 | metadata: 8 | name: jenkins-hub-api-token 9 | namespace: delivery 10 | type: fabric8.io/jenkins-hub-api-token 11 | -------------------------------------------------------------------------------- /platform/delivery/secrets/secret-slack-hook.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | data: 3 | channel: JENKINS_NOTIFICATIONS_SLACK_CHANNEL 4 | webHookURL: JENKINS_NOTIFICATIONS_SLACK_WEBHOOK_URL 5 | kind: Secret 6 | metadata: 7 | name: slack-notification-hook 8 | namespace: delivery 9 | type: Opaque -------------------------------------------------------------------------------- /platform/flux/flux.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: helm.fluxcd.io/v1 2 | kind: HelmRelease 3 | metadata: 4 | name: stakater-infra-flux 5 | namespace: flux 6 | spec: 7 | releaseName: stakater-infra-flux 8 | chart: 9 | repository: https://charts.fluxcd.io 10 | name: flux 11 | version: 0.15.0 12 | values: 13 | replicaCount: 1 14 | image: 15 | repository: docker.io/fluxcd/flux 16 | tag: 1.15.0 17 | helmOperator: 18 | create: false 19 | createCRD: false 20 | rbac: 21 | create: false 22 | clusterRole: 23 | create: false 24 | serviceAccount: 25 | create: false 26 | name: helm-operator 27 | git: 28 | url: "ssh://STAKATER_PLATFORM_SSH_GIT_URL" 29 | pollInterval: "1m" 30 | branch: "STAKATER_PLATFORM_BRANCH" 31 | path: "platform" 32 | secretName: flux-key 33 | additionalArgs: 34 | - --k8s-allow-namespace=control,delivery,security,logging,monitoring,tracing,kube-system,flux,istio-system -------------------------------------------------------------------------------- /platform/flux/secrets/secret-flux-key.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | data: 3 | identity: BASE64_ENCODED_FLUX_PRIVATE_KEY 4 | kind: Secret 5 | metadata: 6 | name: flux-key 7 | namespace: flux 8 | type: Opaque -------------------------------------------------------------------------------- /platform/istio/istio-config.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: install.istio.io/v1alpha2 2 | kind: IstioControlPlane 3 | metadata: 4 | namespace: istio-system 5 | name: stakater-istiocontrolplane 6 | spec: 7 | profile: default 8 | autoInjection: 9 | components: 10 | injector: 11 | enabled: true 12 | enabled: true 13 | telemetry: 14 | components: 15 | telemetry: 16 | enabled: true 17 | k8s: 18 | resources: 19 | requests: 20 | cpu: 100m 21 | memory: 500m 22 | enabled: true 23 | trafficManagement: 24 | components: 25 | pilot: 26 | enabled: true 27 | enabled: true 28 | values: 29 | global: 30 | enableTracing: true 31 | disablePolicyChecks: false 32 | grafana: 33 | enabled: false 34 | kiali: 35 | enabled: true 36 | pilot: 37 | traceSampling: 100 38 | prometheus: 39 | enabled: false 40 | sidecarInjectorWebhook: 41 | rewriteAppHTTPProbe: true 42 | tracing: 43 | enabled: true 44 | -------------------------------------------------------------------------------- /platform/istio/istio-operator.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: apiextensions.k8s.io/v1beta1 3 | kind: CustomResourceDefinition 4 | metadata: 5 | name: istiocontrolplanes.install.istio.io 6 | spec: 7 | group: install.istio.io 8 | names: 9 | kind: IstioControlPlane 10 | listKind: IstioControlPlaneList 11 | plural: istiocontrolplanes 12 | singular: istiocontrolplane 13 | shortNames: 14 | - icp 15 | scope: Namespaced 16 | subresources: 17 | status: {} 18 | validation: 19 | openAPIV3Schema: 20 | properties: 21 | apiVersion: 22 | description: 'APIVersion defines the versioned schema of this representation 23 | of an object. Servers should convert recognized schemas to the latest 24 | internal value, and may reject unrecognized values. 25 | More info: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#resources' 26 | type: string 27 | kind: 28 | description: 'Kind is a string value representing the REST resource this 29 | object represents. Servers may infer this from the endpoint the client 30 | submits requests to. Cannot be updated. In CamelCase. 31 | More info: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#types-kinds' 32 | type: string 33 | spec: 34 | description: 'Specification of the desired state of the istio control plane resource. 35 | More info: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#spec-and-status' 36 | type: object 37 | status: 38 | description: 'Status describes each of istio control plane component status at the current time. 39 | 0 means NONE, 1 means UPDATING, 2 means HEALTHY, 3 means ERROR, 4 means RECONCILING. 40 | More info: https://github.com/istio/operator/blob/master/pkg/apis/istio/v1alpha2/v1alpha2.pb.html & 41 | https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#spec-and-status' 42 | type: object 43 | versions: 44 | - name: v1alpha2 45 | served: true 46 | storage: true 47 | ... 48 | --- 49 | apiVersion: v1 50 | kind: ServiceAccount 51 | metadata: 52 | namespace: istio-system 53 | name: istio-operator 54 | ... 55 | --- 56 | apiVersion: rbac.authorization.k8s.io/v1 57 | kind: ClusterRole 58 | metadata: 59 | creationTimestamp: null 60 | name: istio-operator 61 | rules: 62 | # istio groups 63 | - apiGroups: 64 | - authentication.istio.io 65 | resources: 66 | - '*' 67 | verbs: 68 | - '*' 69 | - apiGroups: 70 | - config.istio.io 71 | resources: 72 | - '*' 73 | verbs: 74 | - '*' 75 | - apiGroups: 76 | - install.istio.io 77 | resources: 78 | - '*' 79 | verbs: 80 | - '*' 81 | - apiGroups: 82 | - networking.istio.io 83 | resources: 84 | - '*' 85 | verbs: 86 | - '*' 87 | - apiGroups: 88 | - rbac.istio.io 89 | resources: 90 | - '*' 91 | verbs: 92 | - '*' 93 | - apiGroups: 94 | - security.istio.io 95 | resources: 96 | - '*' 97 | verbs: 98 | - '*' 99 | # k8s groups 100 | - apiGroups: 101 | - admissionregistration.k8s.io 102 | resources: 103 | - mutatingwebhookconfigurations 104 | - validatingwebhookconfigurations 105 | verbs: 106 | - '*' 107 | - apiGroups: 108 | - apiextensions.k8s.io 109 | resources: 110 | - customresourcedefinitions.apiextensions.k8s.io 111 | - customresourcedefinitions 112 | verbs: 113 | - '*' 114 | - apiGroups: 115 | - apps 116 | - extensions 117 | resources: 118 | - daemonsets 119 | - deployments 120 | - deployments/finalizers 121 | - ingresses 122 | - replicasets 123 | - statefulsets 124 | verbs: 125 | - '*' 126 | - apiGroups: 127 | - autoscaling 128 | resources: 129 | - horizontalpodautoscalers 130 | verbs: 131 | - '*' 132 | - apiGroups: 133 | - monitoring.coreos.com 134 | resources: 135 | - servicemonitors 136 | verbs: 137 | - get 138 | - create 139 | - apiGroups: 140 | - policy 141 | resources: 142 | - poddisruptionbudgets 143 | verbs: 144 | - '*' 145 | - apiGroups: 146 | - rbac.authorization.k8s.io 147 | resources: 148 | - clusterrolebindings 149 | - clusterroles 150 | - roles 151 | - rolebindings 152 | verbs: 153 | - '*' 154 | - apiGroups: 155 | - "" 156 | resources: 157 | - configmaps 158 | - endpoints 159 | - events 160 | - namespaces 161 | - pods 162 | - persistentvolumeclaims 163 | - secrets 164 | - services 165 | - serviceaccounts 166 | verbs: 167 | - '*' 168 | ... 169 | --- 170 | kind: ClusterRoleBinding 171 | apiVersion: rbac.authorization.k8s.io/v1 172 | metadata: 173 | name: istio-operator 174 | subjects: 175 | - kind: ServiceAccount 176 | name: istio-operator 177 | namespace: istio-system 178 | roleRef: 179 | kind: ClusterRole 180 | name: istio-operator 181 | apiGroup: rbac.authorization.k8s.io 182 | ... 183 | --- 184 | apiVersion: v1 185 | kind: Service 186 | metadata: 187 | namespace: istio-system 188 | labels: 189 | name: istio-operator 190 | name: istio-operator-metrics 191 | spec: 192 | ports: 193 | - name: http-metrics 194 | port: 8383 195 | targetPort: 8383 196 | selector: 197 | name: istio-operator 198 | ... 199 | --- 200 | apiVersion: apps/v1 201 | kind: Deployment 202 | metadata: 203 | namespace: istio-system 204 | name: istio-operator 205 | spec: 206 | replicas: 1 207 | selector: 208 | matchLabels: 209 | name: istio-operator 210 | template: 211 | metadata: 212 | labels: 213 | name: istio-operator 214 | spec: 215 | serviceAccountName: istio-operator 216 | containers: 217 | - name: istio-operator 218 | image: docker.io/istio/operator:1.4.3 219 | command: 220 | - istio-operator 221 | - server 222 | imagePullPolicy: Always 223 | resources: 224 | limits: 225 | cpu: 200m 226 | memory: 256Mi 227 | requests: 228 | cpu: 50m 229 | memory: 128Mi 230 | env: 231 | - name: WATCH_NAMESPACE 232 | value: "" 233 | - name: LEADER_ELECTION_NAMESPACE 234 | valueFrom: 235 | fieldRef: 236 | fieldPath: metadata.namespace 237 | - name: POD_NAME 238 | valueFrom: 239 | fieldRef: 240 | fieldPath: metadata.name 241 | - name: OPERATOR_NAME 242 | value: "istio-operator" 243 | ... -------------------------------------------------------------------------------- /platform/istio/jaeger-ingress.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: extensions/v1beta1 2 | kind: Ingress 3 | metadata: 4 | annotations: 5 | ingress.kubernetes.io/force-ssl-redirect: "true" 6 | kubernetes.io/ingress.class: internal-ingress 7 | nginx.ingress.kubernetes.io/service-upstream: "true" 8 | forecastle.stakater.com/appName: Jaeger 9 | forecastle.stakater.com/expose: "true" 10 | forecastle.stakater.com/icon: https://raw.githubusercontent.com/stakater/ForecastleIcons/master/jaeger.png 11 | ingress.kubernetes.io/rewrite-target: / 12 | name: jaeger-ingress 13 | namespace: istio-system 14 | spec: 15 | rules: 16 | - host: jaeger-tracing.DOMAIN 17 | http: 18 | paths: 19 | - backend: 20 | serviceName: jaeger-query 21 | servicePort: 16686 22 | tls: 23 | - hosts: 24 | - jaeger-tracing.DOMAIN 25 | secretName: control/tls-cert -------------------------------------------------------------------------------- /platform/istio/kiali-ingress.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: extensions/v1beta1 2 | kind: Ingress 3 | metadata: 4 | annotations: 5 | ingress.kubernetes.io/force-ssl-redirect: "true" 6 | kubernetes.io/ingress.class: internal-ingress 7 | nginx.ingress.kubernetes.io/service-upstream: "true" 8 | forecastle.stakater.com/appName: Kiali 9 | forecastle.stakater.com/expose: "true" 10 | forecastle.stakater.com/icon: https://raw.githubusercontent.com/stakater/ForecastleIcons/master/kiali.png 11 | ingress.kubernetes.io/rewrite-target: / 12 | name: kiali-ingress 13 | namespace: istio-system 14 | spec: 15 | rules: 16 | - host: kiali-tracing.DOMAIN 17 | http: 18 | paths: 19 | - backend: 20 | serviceName: kiali 21 | servicePort: 20001 22 | tls: 23 | - hosts: 24 | - kiali-tracing.DOMAIN 25 | secretName: control/tls-cert -------------------------------------------------------------------------------- /platform/istio/secrets/secret-kiali.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: kiali 5 | namespace: istio-system 6 | labels: 7 | app: kiali 8 | type: Opaque 9 | data: 10 | username: KIALI_USERNAME 11 | passphrase: KIALI_PASSWORD -------------------------------------------------------------------------------- /platform/logging/cerebro.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: helm.fluxcd.io/v1 2 | kind: HelmRelease 3 | metadata: 4 | name: stakater-logging-cerebro 5 | namespace: logging 6 | spec: 7 | releaseName: stakater-logging-cerebro 8 | chart: 9 | repository: https://kubernetes-charts.storage.googleapis.com 10 | name: cerebro 11 | version: 1.0.1 12 | values: 13 | config: 14 | secret: "ki:s:[[@=Ag?QIW2jMwkY:eqvrJ]JqoJyi2axj3ZvOv^/KavOT4ViJSv?6YY4[N" 15 | hosts: 16 | - host: "http://elasticsearch-master.logging:9200" 17 | name: elasticsearch.DOMAIN 18 | deployment: 19 | annotations: 20 | authproxy.stakater.com/enabled: "true" 21 | authproxy.stakater.com/listen: 0.0.0.0:80 22 | authproxy.stakater.com/redirection-url: https://cerebro-logging.DOMAIN 23 | authproxy.stakater.com/source-service-name: stakater-logging-cerebro 24 | authproxy.stakater.com/upstream-url: http://127.0.0.1:9000 25 | 26 | service: 27 | annotations: 28 | config.xposer.stakater.com/Domain: DOMAIN 29 | config.xposer.stakater.com/IngressNameTemplate: '{{.Service}}-{{.Namespace}}' 30 | config.xposer.stakater.com/IngressURLTemplate: cerebro-{{.Namespace}}.{{.Domain}} 31 | xposer.stakater.com/annotations: |- 32 | kubernetes.io/ingress.class: internal-ingress 33 | ingress.kubernetes.io/force-ssl-redirect: true 34 | forecastle.stakater.com/expose: true 35 | forecastle.stakater.com/icon: https://raw.githubusercontent.com/stakater/ForecastleIcons/master/cerebro.png 36 | forecastle.stakater.com/appName: Cerebro 37 | 38 | labels: 39 | expose: "true" 40 | 41 | resources: 42 | requests: 43 | cpu: 100m 44 | memory: 512Mi 45 | limits: 46 | cpu: 500m 47 | memory: 1024Mi -------------------------------------------------------------------------------- /platform/logging/elasticsearch-cluster-client.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: helm.fluxcd.io/v1 2 | kind: HelmRelease 3 | metadata: 4 | name: stakater-logging-es-client 5 | namespace: logging 6 | spec: 7 | releaseName: stakater-logging-es-client 8 | chart: 9 | repository: https://helm.elastic.co 10 | name: elasticsearch 11 | version: 7.5.0 12 | values: 13 | imageTag: 6.8.5 14 | minimumMasterNodes: 1 15 | replicas: 1 16 | esJavaOpts: "-Xmx1g -Xms1g" 17 | initResources: # they must be in sync with java-options setting above! 18 | requests: 19 | memory: 2Gi 20 | cpu: 500m 21 | limits: 22 | memory: 3Gi 23 | cpu: 1000m 24 | clusterName: "elasticsearch" 25 | nodeGroup: "client" 26 | roles: 27 | master: "false" 28 | ingest: "true" 29 | data: "false" 30 | persistence: 31 | enabled: false -------------------------------------------------------------------------------- /platform/logging/elasticsearch-cluster-data.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: helm.fluxcd.io/v1 2 | kind: HelmRelease 3 | metadata: 4 | name: stakater-logging-es-data 5 | namespace: logging 6 | spec: 7 | releaseName: stakater-logging-es-data 8 | chart: 9 | repository: https://helm.elastic.co 10 | name: elasticsearch 11 | version: 7.5.0 12 | values: 13 | imageTag: 6.8.5 14 | minimumMasterNodes: 1 15 | replicas: 2 16 | esJavaOpts: "-Xmx1g -Xms1g" 17 | initResources: # they must be in synch with java-options setting above! 18 | requests: 19 | memory: 2Gi 20 | cpu: 500m 21 | limits: 22 | memory: 3Gi 23 | cpu: 2000m 24 | clusterName: "elasticsearch" 25 | nodeGroup: "data" 26 | roles: 27 | master: "false" 28 | ingest: "false" 29 | data: "true" 30 | volumeClaimTemplate: 31 | accessModes: [ "ReadWriteOnce" ] 32 | storageClassName: stakater-storageclass 33 | resources: 34 | requests: 35 | storage: 20Gi -------------------------------------------------------------------------------- /platform/logging/elasticsearch-cluster-master.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: helm.fluxcd.io/v1 2 | kind: HelmRelease 3 | metadata: 4 | name: stakater-logging-es-master 5 | namespace: logging 6 | spec: 7 | releaseName: stakater-logging-es-master 8 | chart: 9 | repository: https://helm.elastic.co 10 | name: elasticsearch 11 | version: 7.5.0 12 | values: 13 | imageTag: 6.8.5 14 | minimumMasterNodes: 1 15 | replicas: 1 16 | esJavaOpts: "-Xmx1g -Xms1g" 17 | initResources: # they must be in synch with java-options setting above! 18 | requests: 19 | memory: 2Gi 20 | cpu: 200m 21 | limits: 22 | memory: 3Gi 23 | cpu: 1000m 24 | clusterName: "elasticsearch" 25 | nodeGroup: "master" 26 | roles: 27 | master: "true" 28 | ingest: "false" 29 | data: "false" 30 | 31 | volumeClaimTemplate: 32 | accessModes: [ "ReadWriteOnce" ] 33 | storageClassName: stakater-storageclass 34 | resources: 35 | requests: 36 | storage: 8Gi -------------------------------------------------------------------------------- /platform/logging/elasticsearch-curator.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: helm.fluxcd.io/v1 2 | kind: HelmRelease 3 | metadata: 4 | name: stakater-logging-curator 5 | namespace: logging 6 | spec: 7 | releaseName: stakater-logging-curator 8 | chart: 9 | repository: https://kubernetes-charts.storage.googleapis.com 10 | name: elasticsearch-curator 11 | version: 2.1.0 12 | values: 13 | cronjob: 14 | # At 06:30 every day 15 | schedule: "30 6 * * *" 16 | 17 | configMaps: 18 | action_file_yml: |- 19 | --- 20 | actions: 21 | 1: 22 | action: delete_indices 23 | description: "Clean up ES by deleting old indices" 24 | options: 25 | timeout_override: 26 | continue_if_exception: False 27 | disable_action: False 28 | ignore_empty_list: True 29 | filters: 30 | - filtertype: age 31 | source: name 32 | direction: older 33 | timestring: '%Y.%m.%d' 34 | unit: days 35 | unit_count: 30 36 | field: 37 | stats_result: 38 | epoch: 39 | exclude: False 40 | # 2: 41 | # action: snapshot 42 | # description: "Create snapshot" 43 | # filters: 44 | # - filtertype: pattern 45 | # kind: prefix 46 | # value: logstash- 47 | # - filtertype: age 48 | # source: name 49 | # direction: older 50 | # timestring: '%Y.%m.%d' 51 | # unit: days 52 | # unit_count: 1 53 | # options: 54 | # disable_action: false 55 | # ignore_unavailable: false 56 | # include_global_state: true 57 | # name: curator-%Y.%m.%d 58 | # partial: false 59 | # repository: "logger-es" 60 | # skip_repo_fs_check: false 61 | # wait_for_completion: true 62 | # 3: 63 | # action: restore 64 | # description: "Restore from snapshot" 65 | # options: 66 | # repository: "logger-es" 67 | # # If name is blank, the most recent snapshot by age will be selected 68 | # name: 69 | # # If indices is blank, all indices in the snapshot will be restored 70 | # indices: 71 | # include_aliases: False 72 | # ignore_unavailable: False 73 | # include_global_state: False 74 | # partial: False 75 | # rename_pattern: 76 | # rename_replacement: 77 | # extra_settings: 78 | # wait_for_completion: True 79 | # skip_repo_fs_check: True 80 | # disable_action: false 81 | # filters: 82 | # - filtertype: pattern 83 | # kind: prefix 84 | # value: curator- 85 | # - filtertype: state 86 | # state: SUCCESS 87 | 88 | config_yml: |- 89 | --- 90 | client: 91 | hosts: 92 | - elasticsearch-master.logging 93 | port: 9200 94 | url_prefix: 95 | use_ssl: False 96 | certificate: 97 | client_cert: 98 | client_key: 99 | ssl_no_validate: True 100 | http_auth: 101 | timeout: 30 102 | master_only: False 103 | logging: 104 | loglevel: INFO 105 | logfile: 106 | logformat: default 107 | blacklist: ['elasticsearch', 'urllib3'] 108 | # extraInitContainers: 109 | # elasticsearch-s3-repository: 110 | # image: jwilder/dockerize:latest 111 | # imagePullPolicy: "IfNotPresent" 112 | # command: 113 | # - "/bin/sh" 114 | # - "-c" 115 | # args: 116 | # - | 117 | # ES_HOST=elasticsearch-client.logging 118 | # ES_PORT=9200 119 | # ES_REPOSITORY=logger-es 120 | # S3_REGION=ap-southeast-1 121 | # S3_BUCKET=stakater-logs-backup 122 | # S3_BASE_PATH=/ 123 | # S3_COMPRESS=true 124 | # S3_STORAGE_CLASS=standard 125 | # apk add curl --no-cache && \ 126 | # dockerize -wait http://${ES_HOST}:${ES_PORT} --timeout 120s && \ 127 | # cat < 20 | @type null 21 | 22 | 23 | @include /etc/fluent/config.d/*.conf 24 | 25 | 26 | @type null 27 | 28 | 29 | # Do not collect tiller logs as they are too frequent and of very less value 30 | 31 | @type null 32 | 33 | 34 | 35 | @type kubernetes_metadata 36 | 37 | 38 | # Workaround until fluent-slack-plugin adds support for nested values 39 | 40 | @type record_transformer 41 | enable_ruby 42 | 43 | kubernetes_pod_name ${record["kubernetes"]["pod_name"]} 44 | kubernetes_namespace_name ${record["kubernetes"]["namespace_name"]} 45 | 46 | 47 | 48 | # Get distinct pods per application 49 | {{- $podsWithAnnotations := whereExist .Pods "ObjectMeta.Annotations.fluentdConfiguration" -}} 50 | {{- $distinctPods := distinctPodsByOwner $podsWithAnnotations -}} 51 | 52 | # Create concat filters for supporting multiline 53 | {{- range $pod := $distinctPods -}} 54 | {{- $config := first (parseJson $pod.ObjectMeta.Annotations.fluentdConfiguration) }} 55 | 56 | {{- range $containerConfig := $config.containers }} 57 | {{- if (len $pod.Spec.Containers) eq 1 }} 58 | 59 | {{- else }} 60 | 61 | {{- end }} 62 | @type concat 63 | key message 64 | multiline_start_regexp {{ $containerConfig.expressionFirstLine }} 65 | flush_interval 5s 66 | timeout_label @LOGS 67 | 68 | {{- end }} 69 | {{- end }} 70 | 71 | # Relabel all logs to ensure timeout logs are treated as normal logs and not ignored 72 | 73 | @type relabel 74 | @label @LOGS 75 | 76 | 77 | 123 | 124 | 125 | 150 | 151 | -------------------------------------------------------------------------------- /platform/logging/konfigurator.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: helm.fluxcd.io/v1 2 | kind: HelmRelease 3 | metadata: 4 | name: stakater-logging-konfigurator 5 | namespace: logging 6 | spec: 7 | releaseName: stakater-logging-konfigurator 8 | chart: 9 | repository: https://stakater.github.io/stakater-charts/ 10 | name: konfigurator 11 | version: 0.0.20 12 | values: 13 | konfigurator: 14 | deployCRD: false -------------------------------------------------------------------------------- /platform/logging/logrotate.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: helm.fluxcd.io/v1 2 | kind: HelmRelease 3 | metadata: 4 | name: stakater-logging-logrotate 5 | namespace: logging 6 | spec: 7 | releaseName: stakater-logging-logrotate 8 | chart: 9 | repository: https://stakater.github.io/stakater-charts 10 | name: logrotate 11 | version: 1.0.9 12 | values: 13 | config: 14 | k8sRotatorConf: |- 15 | /var/lib/docker/containers/*/*.log { 16 | rotate 5 17 | copytruncate 18 | missingok 19 | notifempty 20 | compress 21 | maxsize 200M 22 | daily 23 | create 0644 root root 24 | } 25 | 26 | environment: 27 | cronSchedule: 0 */12 * * * -------------------------------------------------------------------------------- /platform/monitoring/clusterrole.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: ClusterRole 3 | metadata: 4 | name: stakater-monitoring-cluster-role 5 | labels: 6 | app: prometheus-operator-operator 7 | 8 | chart: prometheus-operator-5.0.13 9 | release: "operatic-mouse" 10 | heritage: "Tiller" 11 | rules: 12 | - apiGroups: 13 | - apiextensions.k8s.io 14 | resources: 15 | - customresourcedefinitions 16 | verbs: 17 | - "*" 18 | - apiGroups: 19 | - monitoring.coreos.com 20 | resources: 21 | - alertmanagers 22 | - prometheuseshelm template 23 | - prometheuses/finalizers 24 | - alertmanagers/finalizers 25 | - servicemonitors 26 | - prometheusrules 27 | - podmonitors 28 | verbs: 29 | - "*" 30 | - apiGroups: 31 | - apps 32 | resources: 33 | - statefulsets 34 | verbs: 35 | - "*" 36 | - apiGroups: 37 | - "" 38 | resources: 39 | - configmaps 40 | - secrets 41 | verbs: 42 | - "*" 43 | - apiGroups: 44 | - "" 45 | resources: 46 | - pods 47 | verbs: 48 | - list 49 | - delete 50 | - apiGroups: 51 | - "" 52 | resources: 53 | - services 54 | - endpoints 55 | verbs: 56 | - get 57 | - create 58 | - update 59 | - apiGroups: 60 | - "" 61 | resources: 62 | - nodes 63 | verbs: 64 | - list 65 | - watch 66 | - apiGroups: 67 | - "" 68 | resources: 69 | - namespaces 70 | verbs: 71 | - get 72 | - list 73 | - watch 74 | -------------------------------------------------------------------------------- /platform/monitoring/clusterrolebindings.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: ClusterRoleBinding 3 | metadata: 4 | name: stakater-monitoring-role-binding 5 | labels: 6 | app: prometheus-operator-operator 7 | chart: prometheus-operator-5.0.13 8 | release: "operatic-mouse" 9 | heritage: "Tiller" 10 | roleRef: 11 | apiGroup: rbac.authorization.k8s.io 12 | kind: ClusterRole 13 | name: stakater-monitoring-cluster-role 14 | subjects: 15 | - kind: ServiceAccount 16 | name: stakater-monitoring 17 | namespace: monitoring 18 | -------------------------------------------------------------------------------- /platform/monitoring/metrics-server.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: helm.fluxcd.io/v1 2 | kind: HelmRelease 3 | metadata: 4 | name: stakater-monitoring-metrics-server 5 | namespace: monitoring 6 | spec: 7 | releaseName: stakater-monitoring-metrics-server 8 | chart: 9 | repository: https://kubernetes-charts.storage.googleapis.com 10 | name: metrics-server 11 | version: 2.9.0 12 | values: 13 | hostNetwork: 14 | enabled: true 15 | image: 16 | tag: v0.3.6 17 | args: 18 | - --kubelet-insecure-tls 19 | --- 20 | apiVersion: rbac.authorization.k8s.io/v1 21 | kind: ClusterRole 22 | metadata: 23 | name: stakater-system:aggregated-metrics-reader 24 | labels: 25 | rbac.authorization.k8s.io/aggregate-to-view: "true" 26 | rbac.authorization.k8s.io/aggregate-to-edit: "true" 27 | rbac.authorization.k8s.io/aggregate-to-admin: "true" 28 | rules: 29 | - apiGroups: ["metrics.k8s.io"] 30 | resources: ["pods", "nodes"] 31 | verbs: ["get", "list", "watch"] 32 | --- 33 | apiVersion: rbac.authorization.k8s.io/v1 34 | kind: ClusterRoleBinding 35 | metadata: 36 | name: stakater-monitoring-metrics-server:system:auth-delegator 37 | roleRef: 38 | apiGroup: rbac.authorization.k8s.io 39 | kind: ClusterRole 40 | name: system:auth-delegator 41 | subjects: 42 | - kind: ServiceAccount 43 | name: stakater-monitoring-metrics-server 44 | namespace: monitoring 45 | --- 46 | apiVersion: rbac.authorization.k8s.io/v1 47 | kind: RoleBinding 48 | metadata: 49 | name: stakater-monitoring-metrics-server-auth-reader 50 | namespace: monitoring 51 | roleRef: 52 | apiGroup: rbac.authorization.k8s.io 53 | kind: Role 54 | name: extension-apiserver-authentication-reader 55 | subjects: 56 | - kind: ServiceAccount 57 | name: stakater-monitoring-metrics-server 58 | namespace: monitoring 59 | --- 60 | apiVersion: apiregistration.k8s.io/v1beta1 61 | kind: APIService 62 | metadata: 63 | name: v1beta1.metrics.k8s.io 64 | spec: 65 | service: 66 | name: stakater-monitoring-metrics-server 67 | namespace: monitoring 68 | group: metrics.k8s.io 69 | version: v1beta1 70 | insecureSkipTLSVerify: true 71 | groupPriorityMinimum: 100 72 | versionPriority: 100 73 | --- 74 | apiVersion: rbac.authorization.k8s.io/v1 75 | kind: ClusterRole 76 | metadata: 77 | name: stakater-monitoring-metrics-server 78 | rules: 79 | - apiGroups: 80 | - "" 81 | resources: 82 | - pods 83 | - nodes 84 | - nodes/stats 85 | - namespaces 86 | - configmaps 87 | verbs: 88 | - get 89 | - list 90 | - watch 91 | --- 92 | apiVersion: rbac.authorization.k8s.io/v1 93 | kind: ClusterRoleBinding 94 | metadata: 95 | name: stakater-monitoring-metrics-server 96 | roleRef: 97 | apiGroup: rbac.authorization.k8s.io 98 | kind: ClusterRole 99 | name: stakater-monitoring-metrics-server 100 | subjects: 101 | - kind: ServiceAccount 102 | name: stakater-monitoring-metrics-server 103 | namespace: monitoring -------------------------------------------------------------------------------- /platform/monitoring/prometheus-operator.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: helm.fluxcd.io/v1 2 | kind: HelmRelease 3 | metadata: 4 | name: stakater-monitoring-prometheus-operator 5 | namespace: monitoring 6 | spec: 7 | releaseName: stakater-monitoring-prometheus-operator 8 | chart: 9 | repository: https://kubernetes-charts.storage.googleapis.com 10 | name: prometheus-operator 11 | version: 5.11.0 12 | values: 13 | nameOverride: stakater 14 | fullnameOverride: stakater 15 | global: 16 | rbac: 17 | create: true 18 | pspEnabled: true 19 | 20 | defaultRules: 21 | labels: 22 | kind: infra 23 | 24 | additionalPrometheusRules: 25 | - name: infra-rules 26 | additionalLabels: 27 | kind: infra 28 | groups: 29 | - name: infra-rules 30 | rules: 31 | - alert: HighCPULoad 32 | expr: node:node_cpu_utilisation:avg1m > 0.8 33 | for: 30s 34 | labels: 35 | severity: warning 36 | annotations: 37 | summary: "Server under high CPU load" 38 | 39 | - alert: HighMemoryLoad 40 | expr: (sum(node_memory_MemTotal_bytes) - sum(node_memory_MemFree_bytes + node_memory_Buffers_bytes + node_memory_Cached_bytes) ) / sum(node_memory_MemTotal_bytes) * 100 > 75 41 | for: 20s 42 | labels: 43 | severity: critical 44 | annotations: 45 | summary: "Server memory is almost full {{ $labels.node }}" 46 | description: "Host memory usage is {{ humanize $value}}%. Reported by instance {{ $labels.instance }} of job {{ $labels.job }}." 47 | 48 | - additionalLabels: 49 | kind: infra 50 | groups: 51 | - name: Fluentd 52 | rules: 53 | - alert: IncreasedFluentdRetryWait 54 | annotations: 55 | description: 'Fluentd Output Status Retry Wait has increased from 1000 in 1 minute' 56 | summary: Retry Wait Increased {{ $labels.kind }} 57 | expr: max_over_time(fluentd_output_status_retry_wait[1m]) > 1000 58 | for: 20s 59 | labels: 60 | kind: infra 61 | severity: critical 62 | - alert: IncreasedFluentdRetryCount 63 | annotations: 64 | description: 65 | Rate of Fluentd Output Retry Count has increased from 0.5 in 66 | 1m 67 | summary: Retry Wait Increased 68 | expr: rate(fluentd_output_status_retry_count[1m]) > 0.5 69 | for: 20s 70 | labels: 71 | kind: infra 72 | severity: critical 73 | - alert: IncreasedFluentdOutputBufferLength 74 | annotations: 75 | description: 76 | Fluentd Output Status Buffer Queue length has increased from 77 | 500. 78 | summary: Fluentd Buffer Queue length Increased - {{ $externalLabels.kind }} 79 | expr: max_over_time(fluentd_output_status_buffer_queue_length[1m]) > 500 80 | for: 10s 81 | labels: 82 | kind: infra 83 | severity: critical 84 | name: fluentd-rules 85 | 86 | commonLabels: 87 | expose: "true" 88 | 89 | prometheusOperator: 90 | admissionWebhooks: 91 | enabled: true 92 | failurePolicy: Fail 93 | patch: 94 | enabled: true 95 | image: 96 | pullPolicy: IfNotPresent 97 | repository: jettech/kube-webhook-certgen 98 | tag: v1.0.0 99 | nodeSelector: {} 100 | podAnnotations: {} 101 | priorityClassName: "" 102 | affinity: {} 103 | cleanupCustomResource: false 104 | cleanupCustomResourceBeforeInstall: false 105 | configmapReloadImage: 106 | repository: quay.io/coreos/configmap-reload 107 | tag: v0.0.1 108 | crdApiGroup: monitoring.coreos.com 109 | createCustomResource: false 110 | enabled: true 111 | hyperkubeImage: 112 | pullPolicy: IfNotPresent 113 | repository: k8s.gcr.io/hyperkube 114 | tag: v1.12.1 115 | image: 116 | pullPolicy: IfNotPresent 117 | repository: quay.io/coreos/prometheus-operator 118 | tag: v0.32.0 119 | kubeletService: 120 | enabled: false 121 | namespace: kube-system 122 | nodeSelector: {} 123 | podAnnotations: {} 124 | podLabels: {} 125 | prometheusConfigReloaderImage: 126 | repository: quay.io/coreos/prometheus-config-reloader 127 | tag: v0.32.0 128 | resources: {} 129 | securityContext: 130 | runAsNonRoot: true 131 | runAsUser: 65534 132 | service: 133 | additionalPorts: [] 134 | annotations: {} 135 | clusterIP: "" 136 | externalIPs: [] 137 | labels: {} 138 | loadBalancerIP: "" 139 | loadBalancerSourceRanges: [] 140 | nodePort: 30080 141 | nodePortTls: 30443 142 | type: ClusterIP 143 | serviceAccount: 144 | create: true 145 | name: stakater-monitoring 146 | serviceMonitor: 147 | interval: "" 148 | metricRelabelings: [] 149 | relabelings: [] 150 | selfMonitor: true 151 | tlsProxy: 152 | enabled: true 153 | image: 154 | pullPolicy: IfNotPresent 155 | repository: squareup/ghostunnel 156 | tag: v1.4.1 157 | resources: {} 158 | tolerations: [] 159 | 160 | prometheus: 161 | additionalServiceMonitors: 162 | - endpoints: 163 | - interval: 20s 164 | path: /metrics 165 | port: monitor-agent 166 | scheme: http 167 | jobLabel: k8s-app 168 | name: monitoring-fluentd 169 | namespaceSelector: 170 | matchNames: 171 | - logging 172 | selector: 173 | matchLabels: 174 | app.kubernetes.io/name: fluentd-elasticsearch 175 | - endpoints: 176 | - interval: 30s 177 | port: metrics 178 | jobLabel: k8s-app 179 | name: external-ingress 180 | namespaceSelector: 181 | matchNames: 182 | - control 183 | selector: 184 | matchLabels: 185 | k8s-app: external-ingress 186 | - endpoints: 187 | - interval: 30s 188 | port: metrics 189 | jobLabel: k8s-app 190 | name: internal-ingress 191 | namespaceSelector: 192 | matchNames: 193 | - control 194 | selector: 195 | matchLabels: 196 | k8s-app: internal-ingress 197 | enabled: true 198 | externalIPs: [] 199 | hosts: [] 200 | ingress: 201 | annotations: {} 202 | enabled: false 203 | labels: {} 204 | loadBalancerIP: "" 205 | loadBalancerSourceRanges: [] 206 | nodePort: 30090 207 | paths: [] 208 | podDisruptionBudget: 209 | enabled: false 210 | maxUnavailable: "" 211 | minAvailable: 1 212 | podSecurityPolicy: 213 | allowedCapabilities: [] 214 | prometheusSpec: 215 | additionalAlertManagerConfigs: [] 216 | additionalAlertRelabelConfigs: [] 217 | additionalScrapeConfigs: [] 218 | additionalScrapeConfigsExternal: false 219 | affinity: {} 220 | alertingEndpoints: [] 221 | configMaps: [] 222 | containers: [] 223 | enableAdminAPI: false 224 | evaluationInterval: "" 225 | externalLabels: {} 226 | externalUrl: "" 227 | image: 228 | repository: quay.io/prometheus/prometheus 229 | tag: v2.12.0 230 | listenLocal: false 231 | logFormat: logfmt 232 | logLevel: info 233 | nodeSelector: {} 234 | paused: false 235 | podAntiAffinity: "" 236 | podAntiAffinityTopologyKey: kubernetes.io/hostname 237 | podMetadata: {} 238 | priorityClassName: "" 239 | prometheusExternalLabelName: "" 240 | prometheusExternalLabelNameClear: false 241 | query: {} 242 | remoteRead: [] 243 | remoteWrite: [] 244 | replicaExternalLabelName: "" 245 | replicaExternalLabelNameClear: false 246 | replicas: 1 247 | resources: 248 | requests: 249 | cpu: 100m 250 | memory: 512Mi 251 | limits: 252 | cpu: 200m 253 | memory: 1024Mi 254 | retention: 10d 255 | retentionSize: "" 256 | routePrefix: / 257 | ruleNamespaceSelector: {} 258 | ruleSelector: {} 259 | ruleSelectorNilUsesHelmValues: true 260 | scrapeInterval: "" 261 | secrets: [] 262 | securityContext: 263 | fsGroup: 2000 264 | runAsNonRoot: true 265 | runAsUser: 1000 266 | serviceMonitorNamespaceSelector: {} 267 | serviceMonitorSelector: {} 268 | serviceMonitorSelectorNilUsesHelmValues: true 269 | storageSpec: 270 | volumeClaimTemplate: 271 | selector: {} 272 | spec: 273 | accessModes: 274 | - ReadWriteOnce 275 | resources: 276 | requests: 277 | storage: 6Gi 278 | storageClassName: stakater-storageclass 279 | thanos: {} 280 | tolerations: [] 281 | walCompression: false 282 | rbac: 283 | roleNamespaces: 284 | - monitoring 285 | - kube-system 286 | - default 287 | - logging 288 | - control 289 | service: 290 | annotations: 291 | config.xposer.stakater.com/Domain: DOMAIN 292 | config.xposer.stakater.com/IngressNameTemplate: "{{.Service}}-{{.Namespace}}" 293 | config.xposer.stakater.com/IngressURLPath: / 294 | config.xposer.stakater.com/IngressURLTemplate: prometheus-{{.Namespace}}.{{.Domain}} 295 | config.xposer.stakater.com/TLS: "true" 296 | config.xposer.stakater.com/TLSSecretNameTemplate: tls-cert 297 | xposer.stakater.com/annotations: |- 298 | kubernetes.io/ingress.class: internal-ingress 299 | ingress.kubernetes.io/rewrite-target: / 300 | ingress.kubernetes.io/force-ssl-redirect: true 301 | forecastle.stakater.com/expose: true 302 | forecastle.stakater.com/icon: https://raw.githubusercontent.com/stakater/ForecastleIcons/master/prometheus.png 303 | forecastle.stakater.com/appName: Prometheus 304 | labels: 305 | expose: "true" 306 | serviceAccount: 307 | create: true 308 | name: "" 309 | serviceMonitor: 310 | interval: "" 311 | metricRelabelings: [] 312 | relabelings: [] 313 | selfMonitor: true 314 | sessionAffinity: "" 315 | targetPort: 9090 316 | tls: [] 317 | type: ClusterIP 318 | 319 | grafana: 320 | admin: 321 | existingSecret: "grafana-credentials" 322 | userKey: "admin-user" 323 | passwordKey: "admin-password" 324 | ingress: 325 | annotations: 326 | forecastle.stakater.com/appName: Grafana 327 | forecastle.stakater.com/expose: "true" 328 | forecastle.stakater.com/icon: https://raw.githubusercontent.com/stakater/ForecastleIcons/master/grafana.png 329 | ingress.kubernetes.io/force-ssl-redirect: "true" 330 | ingress.kubernetes.io/rewrite-target: / 331 | kubernetes.io/ingress.class: internal-ingress 332 | enabled: "true" 333 | hosts: 334 | - grafana-monitoring.DOMAIN 335 | tls: 336 | - hosts: 337 | - grafana-monitoring.DOMAIN 338 | secretName: tls-cert 339 | rbac: 340 | create: true 341 | namespaced: true 342 | sidecar: 343 | dashboards: 344 | enabled: true 345 | 346 | kubeControllerManager: 347 | enabled: false 348 | endpoints: [] 349 | service: 350 | port: 10252 351 | selector: 352 | component: kube-controller-manager 353 | targetPort: 10252 354 | serviceMonitor: 355 | https: false 356 | insecureSkipVerify: null 357 | interval: "" 358 | metricRelabelings: [] 359 | relabelings: [] 360 | serverName: null 361 | 362 | kubeEtcd: 363 | enabled: true 364 | endpoints: [] 365 | service: 366 | port: 4001 367 | selector: 368 | component: etcd-server 369 | targetPort: 4001 370 | serviceMonitor: 371 | caFile: "" 372 | certFile: "" 373 | insecureSkipVerify: false 374 | interval: "" 375 | keyFile: "" 376 | metricRelabelings: [] 377 | relabelings: [] 378 | scheme: http 379 | serverName: "" 380 | 381 | kubeScheduler: 382 | enabled: false 383 | endpoints: [] 384 | service: 385 | port: 10251 386 | selector: 387 | component: kube-scheduler 388 | targetPort: 10251 389 | serviceMonitor: 390 | https: false 391 | insecureSkipVerify: null 392 | interval: "" 393 | metricRelabelings: [] 394 | relabelings: [] 395 | serverName: null 396 | 397 | alertmanager: 398 | alertmanagerSpec: 399 | additionalPeers: [] 400 | affinity: {} 401 | configMaps: [] 402 | containers: [] 403 | externalUrl: null 404 | image: 405 | repository: quay.io/prometheus/alertmanager 406 | tag: v0.17.0 407 | listenLocal: false 408 | logFormat: logfmt 409 | logLevel: info 410 | nodeSelector: {} 411 | paused: false 412 | podAntiAffinity: "" 413 | podAntiAffinityTopologyKey: kubernetes.io/hostname 414 | podMetadata: {} 415 | priorityClassName: "" 416 | replicas: 1 417 | resources: 418 | requests: 419 | cpu: 100m 420 | memory: 512Mi 421 | limits: 422 | cpu: 200m 423 | memory: 1024Mi 424 | retention: 120h 425 | routePrefix: / 426 | secrets: 427 | - alertmanager-stakater-alertmanager 428 | securityContext: 429 | fsGroup: 2000 430 | runAsNonRoot: true 431 | runAsUser: 1000 432 | storage: {} 433 | tolerations: [] 434 | useExistingSecret: true 435 | config: 436 | global: 437 | resolve_timeout: 5m 438 | receivers: 439 | - name: "null" 440 | route: 441 | group_by: 442 | - job 443 | group_interval: 5m 444 | group_wait: 30s 445 | receiver: "null" 446 | repeat_interval: 12h 447 | routes: 448 | - match: 449 | alertname: Watchdog 450 | receiver: "null" 451 | enabled: true 452 | ingress: 453 | annotations: {} 454 | enabled: false 455 | hosts: [] 456 | labels: {} 457 | paths: [] 458 | tls: [] 459 | podDisruptionBudget: 460 | enabled: false 461 | maxUnavailable: "" 462 | minAvailable: 1 463 | service: 464 | annotations: 465 | config.xposer.stakater.com/Domain: DOMAIN 466 | config.xposer.stakater.com/IngressNameTemplate: "{{.Service}}-{{.Namespace}}" 467 | config.xposer.stakater.com/IngressURLPath: / 468 | config.xposer.stakater.com/IngressURLTemplate: alertmanager-{{.Namespace}}.{{.Domain}} 469 | config.xposer.stakater.com/TLS: "true" 470 | config.xposer.stakater.com/TLSSecretNameTemplate: tls-cert 471 | xposer.stakater.com/annotations: |- 472 | kubernetes.io/ingress.class: internal-ingress 473 | ingress.kubernetes.io/rewrite-target: / 474 | ingress.kubernetes.io/force-ssl-redirect: true 475 | forecastle.stakater.com/expose: true 476 | forecastle.stakater.com/icon: https://raw.githubusercontent.com/stakater/ForecastleIcons/master/alert-manager.png 477 | forecastle.stakater.com/appName: Alert Manager 478 | clusterIP: "" 479 | externalIPs: [] 480 | labels: {} 481 | loadBalancerIP: "" 482 | loadBalancerSourceRanges: [] 483 | nodePort: 30903 484 | type: ClusterIP 485 | serviceAccount: 486 | create: true 487 | name: "" 488 | serviceMonitor: 489 | interval: "" 490 | metricRelabelings: [] 491 | relabelings: [] 492 | selfMonitor: true 493 | templateFiles: {} 494 | tplConfig: false 495 | 496 | kubelet: 497 | enabled: false 498 | namespace: kube-system 499 | serviceMonitor: 500 | cAdvisorMetricRelabelings: [] 501 | cAdvisorRelabelings: [] 502 | https: false 503 | interval: "" 504 | metricRelabelings: [] 505 | relabelings: [] 506 | 507 | kubeApiServer: 508 | enabled: true 509 | relabelings: 510 | - action: keep 511 | regex: default;kubernetes;https 512 | sourceLabels: 513 | - __meta_kubernetes_namespace 514 | - __meta_kubernetes_service_name 515 | - __meta_kubernetes_endpoint_port_name 516 | - replacement: kubernetes.default.svc:443 517 | targetLabel: __address__ 518 | serviceMonitor: 519 | interval: "" 520 | jobLabel: component 521 | metricRelabelings: [] 522 | selector: 523 | matchLabels: 524 | component: apiserver 525 | provider: kubernetes 526 | tlsConfig: 527 | insecureSkipVerify: true 528 | 529 | coreDns: 530 | enabled: true 531 | service: 532 | port: 9153 533 | selector: 534 | k8s-app: kube-dns 535 | targetPort: 9153 536 | serviceMonitor: 537 | interval: "" 538 | metricRelabelings: [] 539 | relabelings: [] 540 | -------------------------------------------------------------------------------- /platform/monitoring/secrets/secret-alertmanager-config.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | data: 3 | alertmanager.yaml: BASE64_ENCODED_ALERTMANAGER_CONFIG 4 | kind: Secret 5 | metadata: 6 | name: alertmanager-stakater-alertmanager 7 | namespace: monitoring 8 | type: Opaque -------------------------------------------------------------------------------- /platform/monitoring/secrets/secret-grafana-creds.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | data: 3 | admin-password: GRAFANA_PASSWORD 4 | admin-user: GRAFANA_USERNAME 5 | kind: Secret 6 | metadata: 7 | name: grafana-credentials 8 | namespace: monitoring 9 | type: Opaque 10 | -------------------------------------------------------------------------------- /platform/monitoring/service-account.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ServiceAccount 3 | metadata: 4 | name: stakater-monitoring 5 | labels: 6 | app: prometheus-operator-alertmanager 7 | chart: prometheus-operator-5.0.13 8 | release: "operatic-mouse" 9 | heritage: "Tiller" 10 | -------------------------------------------------------------------------------- /platform/security/keycloak.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: helm.fluxcd.io/v1 2 | kind: HelmRelease 3 | metadata: 4 | name: stakater-security-keycloak 5 | namespace: security 6 | spec: 7 | releaseName: stakater-security-keycloak 8 | chart: 9 | repository: https://codecentric.github.io/helm-charts 10 | name: keycloak 11 | version: 5.1.7 12 | values: 13 | init: 14 | image: 15 | pullPolicy: IfNotPresent 16 | repository: alpine 17 | tag: 3.9 18 | resources: {} 19 | 20 | clusterDomain: cluster.local 21 | keycloak: 22 | affinity: | 23 | podAntiAffinity: 24 | requiredDuringSchedulingIgnoredDuringExecution: 25 | - labelSelector: 26 | matchLabels: 27 | {{- include "keycloak.selectorLabels" . | nindent 10 }} 28 | matchExpressions: 29 | - key: role 30 | operator: NotIn 31 | values: 32 | - test 33 | topologyKey: kubernetes.io/hostname 34 | preferredDuringSchedulingIgnoredDuringExecution: 35 | - weight: 100 36 | podAffinityTerm: 37 | labelSelector: 38 | matchLabels: 39 | {{- include "keycloak.selectorLabels" . | nindent 12 }} 40 | matchExpressions: 41 | - key: role 42 | operator: NotIn 43 | values: 44 | - test 45 | topologyKey: failure-domain.beta.kubernetes.io/zone 46 | basepath: auth 47 | cli: 48 | custom: "" 49 | datasource: | 50 | {{ .Files.Get "scripts/datasource.cli" }} 51 | enabled: true 52 | ha: | 53 | {{ .Files.Get "scripts/ha.cli" }} 54 | logging: | 55 | {{ .Files.Get "scripts/logging.cli" }} 56 | nodeIdentifier: | 57 | {{ .Files.Get "scripts/node-identifier.cli" }} 58 | containerSecurityContext: 59 | runAsNonRoot: true 60 | runAsUser: 1000 61 | enableServiceLinks: false 62 | existingSecret: keycloak-secrets 63 | existingSecretKey: password 64 | extraArgs: -Djgroups.bind_addr=global -Dkeycloak.migration.action=import -Dkeycloak.migration.provider=singleFile 65 | -Dkeycloak.migration.file=/opt/jboss/keycloak/standalone/configuration/import/stakater-realm.json 66 | -Dkeycloak.migration.strategy=IGNORE_EXISTING 67 | extraContainers: "" 68 | extraEnv: "- name: OPERATING_MODE\n value: standalone\n- name: HIDE_OPENSHIFT_BTN\n 69 | \ value: \"true\"\n- name: HIDE_GITHUB_BTN\n value: \"false\"\n- name: PROXY_ADDRESS_FORWARDING 70 | # Why? https://www.keycloak.org/docs/3.4/server_installation/index.html#identifying-client-ip-addresses\n 71 | \ value: \"true\"\n- name: K8S_API_SERVER\n value: http://kubernetes\n- name: AUTH_URL\n 72 | \ value: http://auth\n- name: KEYCLOAK_URL\n value: http://keycloak \n" 73 | extraInitContainers: "" 74 | extraPorts: "" 75 | extraVolumeMounts: | 76 | - name: keycloak-config 77 | mountPath: /opt/jboss/keycloak/standalone/configuration/import/stakater-realm.json 78 | subPath: stakater-realm.json 79 | - name: data 80 | mountPath: /opt/jboss/keycloak/standalone/deployments 81 | extraVolumes: | 82 | - name: keycloak-config 83 | secret: 84 | secretName: keycloak-config 85 | items: 86 | - key: stakater-realm.json 87 | path: stakater-realm.json 88 | - name: data 89 | emptyDir: {} 90 | hostAliases: [] 91 | image: 92 | pullPolicy: IfNotPresent 93 | repository: jboss/keycloak 94 | tag: 6.0.1 95 | ingress: 96 | annotations: {} 97 | enabled: false 98 | hosts: 99 | - keycloak.example.com 100 | labels: {} 101 | path: / 102 | tls: [] 103 | lifecycleHooks: "" 104 | livenessProbe: 105 | initialDelaySeconds: 120 106 | timeoutSeconds: 5 107 | nodeSelector: {} 108 | password: "" 109 | persistence: 110 | dbHost: stakater-security-postgresql.security 111 | dbName: keycloak-db 112 | dbPassword: "" 113 | dbPort: 5432 114 | dbUser: keycloak 115 | dbVendor: postgres 116 | deployPostgres: false 117 | existingSecret: keycloak-secrets 118 | existingSecretKey: db.password 119 | podAnnotations: 120 | secret.reloader.stakater.com/reload: "keycloak-config,keycloak-secrets" 121 | fluentdConfiguration: | 122 | [ 123 | { 124 | "containers": 125 | [ 126 | { 127 | "expression": "/^\\S*\\s-\\s-\\s\\[(?