refactor: workflows & renovate

This commit is contained in:
auricom
2022-01-22 00:35:09 +01:00
parent b12abc2f76
commit dc66e8398e
56 changed files with 1095 additions and 903 deletions

9
.github/labeler.yaml vendored Normal file
View File

@@ -0,0 +1,9 @@
---
area/ansible:
- "ansible/**/*"
area/ci:
- ".github/**/*"
area/cluster:
- "cluster/**/*"
area/terraform:
- "terraform/**/*"

64
.github/labels.yaml vendored Normal file
View File

@@ -0,0 +1,64 @@
---
# Area
- name: area/ansible
color: "72ccf3"
- name: area/ci
color: "72ccf3"
- name: area/cluster
color: "72ccf3"
- name: area/terraform
color: "72ccf3"
# Renovate
- name: renovate/ansible
color: "ffc300"
- name: renovate/container
color: "ffc300"
- name: renovate/helm
color: "ffc300"
- name: renovate/terraform
color: "ffc300"
# Semantic Type
- name: type/patch
color: "FFEC19"
- name: type/minor
color: "FF9800"
- name: type/major
color: "F6412D"
# Size
- name: size/XS
color: "009900"
description: >-
Denotes a PR that changes 0-9 lines, ignoring generated files.
- name: size/S
color: "77bb00"
description: >-
Denotes a PR that changes 10-29 lines, ignoring generated files.
- name: size/M
color: "eebb00"
description: >-
Denotes a PR that changes 30-99 lines, ignoring generated files.
- name: size/L
color: "ee9900"
description: >-
Denotes a PR that changes 100-499 lines, ignoring generated files.
- name: size/XL
color: "ee5500"
description: >-
Denotes a PR that changes 500-999 lines, ignoring generated files.
- name: size/XXL
color: "ee0000"
description: >-
Denotes a PR that changes 1000+ lines, ignoring generated files.
# Uncategorized
- name: bug
color: "ee0701"
- name: do-not-merge
color: "ee0701"
- name: docs
color: "F4D1B7"
- name: enhancement
color: "84b6eb"
- name: link-checker
color: "7B55D7"
- name: question
color: "cc317c"

View File

@@ -1,5 +0,0 @@
.private
.vscode
*.sops.*
ansible
gotk-components.yaml

3
.github/linters/.ansible-lint vendored Normal file
View File

@@ -0,0 +1,3 @@
# .ansible-lint
warn_list:
- unnamed-task

7
.github/linters/.prettierignore vendored Normal file
View File

@@ -0,0 +1,7 @@
charts/
docs/
.private/
.terraform/
.vscode/
*.sops.*
gotk-components.yaml

View File

@@ -3,3 +3,5 @@ trailingComma: "es5"
tabWidth: 2
semi: false
singleQuote: false
bracketSpacing: false
useTabs: false

0
.github/linters/.tflint.hcl vendored Normal file
View File

View File

@@ -1,10 +1,11 @@
---
ignore: |
charts/
docs/
.private/
.terraform/
.vscode/
*.sops.*
ansible/roles/xanmanning.k3s/
cluster/base-custom/secrets
gotk-components.yaml
extends: default
rules:

295
.github/renovate.json5 vendored
View File

@@ -1,182 +1,173 @@
{
enabled: true,
timezone: "Europe/Paris",
semanticCommits: "enabled",
dependencyDashboard: true,
dependencyDashboardTitle: "Renovate Dashboard",
commitBody: "Signed-off-by: auricom <27022259+auricom@users.noreply.github.com>",
// Do not notify on closed unmerged PRs
suppressNotifications: ["prIgnoreNotification"],
// Do not rebase PRs
rebaseWhen: "conflicted",
assignees: ["@auricom"],
"extends": [
":enableRenovate",
"config:base",
":disableRateLimiting",
":dependencyDashboard",
":semanticCommits",
":separatePatchReleases",
"docker:enableMajor",
":enablePreCommit",
"github>auricom/home-cluster//.github/renovate/autoMerge",
"github>auricom/home-cluster//.github/renovate/labels",
"github>auricom/home-cluster//.github/renovate/semanticCommits"
],
"platform": "github",
"username": "feisar-bot[bot]",
"repositories": ["auricom/home-cluster"],
"onboarding": false,
"requireConfig": false,
"gitAuthor": "feisar-bot <98030736+feisar-bot[bot]@users.noreply.github.com>",
"dependencyDashboardTitle": "Renovate Dashboard 🤖",
"suppressNotifications": [
"prIgnoreNotification"
],
"rebaseWhen": "conflicted",
// set up renovate managers
"docker-compose": {
"fileMatch": [
"(^|\/)docker-compose.*\.ya?ml$",
"(^|\/)docker-compose.*\.ya?ml\.j2$"
]
},
"helm-values": {
fileMatch: ["cluster/.+/helm-release\\.yaml$"],
"fileMatch": [
"cluster/.+/helm-release\\.yaml$"
]
},
kubernetes: {
fileMatch: ["cluster/.+\\.yaml$"],
ignorePaths: ["cluster/base/"],
"helmv3": {
"fileMatch": [
"charts/.+/Chart\\.yaml$"
]
},
regexManagers: [
// regexManager to read and process HelmRelease files
{
fileMatch: ["cluster/.+\\.yaml$"],
matchStrings: [
// helm releases
"registryUrl=(?<registryUrl>.*?)\n *chart: (?<depName>.*?)\n *version: (?<currentValue>.*)\n",
],
datasourceTemplate: "helm",
},
"kubernetes": {
"fileMatch": [
"cluster/.+\\.yaml$"
],
"ignorePaths": [
"cluster/base/"
]
},
"flux": {
"fileMatch": [
"cluster/.+\\.yaml$"
]
},
"regexManagers": [
// regexManager to read and process cert-manager CRD's
{
fileMatch: ["cluster/base-custom/crds/cert-manager/.+\\.yaml$"],
matchStrings: [
"fileMatch": [
"cluster/base-custom/crds/cert-manager/.+\\.yaml$"
],
"matchStrings": [
"registryUrl=(?<registryUrl>.*?) chart=(?<depName>.*?)\n.*\\/(?<currentValue>.*?)\\/",
],
datasourceTemplate: "helm",
"datasourceTemplate": "helm"
},
// regexManager to read and process kube-prometheus-stack CRD's
// regexManager to read and process kube-prometheus-stack CRDs
{
fileMatch: ["cluster/base-custom/crds/kube-prometheus-stack/.+\\.yaml$"],
matchStrings: [
"registryUrl=(?<registryUrl>.*?)\n *tag: (?<depName>[a-zA-Z-]+)-(?<currentValue>.*)\n",
"fileMatch": [
"cluster/base-custom/crds/kube-prometheus-stack/.+\\.yaml$"
],
datasourceTemplate: "helm",
},
// regexManager to read and process Traefik CRD's
{
fileMatch: ["cluster/crds/traefik/.+\\.yaml$"],
matchStrings: [
"registryUrl=(?<registryUrl>.*?) chart=(?<depName>.*?)\n *tag: v(?<currentValue>.*)\n",
"matchStrings": [
"registryUrl=(?<registryUrl>.*?)\n *tag: (?<depName>[a-zA-Z-]+)-(?<currentValue>.*)\n"
],
datasourceTemplate: "helm",
"datasourceTemplate": "helm"
},
// regexManager to read and process Rook-Ceph CRD's
{
fileMatch: ["cluster/base-custom/crds/rook-ceph/.+\\.yaml$"],
matchStrings: [
"fileMatch": [
"cluster/base-custom/crds/rook-ceph/.+\\.yaml$"
],
"matchStrings": [
"registryUrl=(?<registryUrl>.*?) chart=(?<depName>.*?)\n *tag: (?<currentValue>.*)\n",
],
datasourceTemplate: "helm",
},
"datasourceTemplate": "helm",
}
],
packageRules: [
// Setup datasources
"packageRules": [
// setup datasources
{
matchDatasources: ["helm"],
semanticCommitScope: "charts",
commitMessageTopic: "{{depName}}",
commitMessageExtra: "to {{{newValue}}}",
separateMinorPatch: true,
ignoreDeprecated: true,
},
{
matchDatasources: ["docker"],
enabled: true,
matchUpdateTypes: ["major", "minor", "patch"],
},
{
matchDatasources: ["docker"],
semanticCommitScope: "images",
commitMessageTopic: "{{depName}}",
commitMessageExtra: "to {{{newValue}}}",
separateMinorPatch: true,
},
// Add labels according to package and update types
{
matchDatasources: ["docker"],
matchUpdateTypes: ["major"],
commitMessagePrefix: "feat(images)!: ",
labels: ["renovate/image", "dep/major"],
},
{
matchDatasources: ["docker"],
matchUpdateTypes: ["minor"],
semanticCommitType: "feat",
labels: ["renovate/image", "dep/minor"],
},
{
matchDatasources: ["docker"],
matchUpdateTypes: ["patch"],
semanticCommitType: "fix",
labels: ["renovate/image", "dep/patch"],
},
{
matchDatasources: ["helm"],
matchUpdateTypes: ["major"],
commitMessagePrefix: "feat(charts)!: ",
labels: ["renovate/helm", "dep/major"],
},
{
matchDatasources: ["helm"],
matchUpdateTypes: ["minor"],
semanticCommitType: "feat",
labels: ["renovate/helm", "dep/minor"],
},
{
matchDatasources: ["helm"],
matchUpdateTypes: ["patch"],
semanticCommitType: "fix",
labels: ["renovate/helm", "dep/patch"],
},
// custom version schemes
{
matchDatasources: ["docker"],
versioning: "regex:^(?<major>\\d+)\\.(?<minor>\\d+)\\.(?<patch>\\d+)-amd64$",
matchPackageNames: ["blakeblackshear/frigate"],
},
// custom version schemes
{
matchDatasources: ["docker"],
versioning: "regex:^(?<major>\\d+)\\.(?<minor>\\d+)\\.(?<patch>\\d+)-beta$",
matchPackageNames: ["joplin/server"],
},
// custom version schemes
{
matchDatasources: ["docker"],
versioning: "regex:^version-v(?<major>\\d+)\\.(?<minor>\\d+)\\.(?<patch>\\d+)$",
matchPackageNames: [
"ghcr.io/linuxserver/bookstack",
"ghcr.io/linuxserver/healthchecks",
"matchDatasources": [
"helm"
],
},
// custom version schemes
{
matchDatasources: ["docker"],
versioning: "regex:^version-(?<major>\\d+)\\.(?<minor>\\d+)\\.(?<patch>\\d+)$",
matchPackageNames: ["ghcr.io/linuxserver/resilio-sync"],
},
// pin package versions
{
matchDatasources: ["docker"],
allowedVersions: "<13",
matchPackageNames: ["postgres", "prodrigestivill/postgres-backup-local"],
"ignoreDeprecated": true
},
{
matchDatasources: ["docker"],
versioning: "loose",
matchPackageNames: ["ghcr.io/k8s-at-home/qbittorrent"],
"matchDatasources": [
"docker"
],
"commitMessageExtra": "to {{newVersion}}"
},
// enable auto-merge
// custom versioning
{
matchDatasources: ["docker"],
automerge: true,
automergeType: "branch",
requiredStatusChecks: null,
matchUpdateTypes: ["minor", "patch"],
matchPackageNames: ["ghcr.io/k8s-at-home/prowlarr-nightly"],
"matchDatasources": [
"docker"
],
"versioning": "regex:^(?<major>\\d+)\\.(?<minor>\\d+)\\.(?<patch>\\d+)-(?<compatibility>.*)$",
"matchPackageNames": [
"blakeblackshear/frigate"
]
},
{
matchDatasources: ["helm", "docker"],
matchPackagePatterns: ["^rook.ceph"],
groupName: "rook-ceph-suite",
additionalBranchPrefix: "",
"matchDatasources": [
"docker"
],
"versioning": "regex:^RELEASE\\.(?<major>\\d+)-(?<minor>\\d+)-(?<patch>\\d+)T.*Z(-(?<compatibility>.*))?$",
"matchPackageNames": [
"quay.io/minio/minio"
]
},
{
matchPackageNames: ["rancher/system-upgrade-controller"],
groupName: "rancher/system-upgrade-controller",
additionalBranchPrefix: "",
separateMinorPatch: true,
"matchDatasources": [
"docker"
],
"versioning": "loose",
"matchPackageNames": [
"ghcr.io/k8s-at-home/qbittorrent"
]
},
],
{
"matchDatasources": [
"docker"
],
"versioning": "regex:^version-v(?<major>\\d+)\\.(?<minor>\\d+)\\.(?<patch>\\d+)$",
"matchPackageNames": [
"ghcr.io/linuxserver/bookstack",
"ghcr.io/linuxserver/healthchecks"
]
},
{
"matchDatasources": [
"docker"
],
"versioning": "regex:^version-(?<major>\\d+)\\.(?<minor>\\d+)\\.(?<patch>\\d+)$",
"matchPackageNames": ["ghcr.io/linuxserver/resilio-sync"]
},
// group packages
{
"matchDatasources": [
"helm",
"docker"
],
"matchPackagePatterns": [
"^rook.ceph"
],
"groupName": "rook-ceph-suite",
"additionalBranchPrefix": "",
"separateMinorPatch": true
},
{
"matchDatasources": [
"github-tags",
"docker"
],
"matchPackagePatterns": [
"rancher/system-upgrade-controller"
],
"groupName": "system-upgrade-controller-suite",
"additionalBranchPrefix": "",
"separateMinorPatch": true
}
]
}

21
.github/renovate/autoMerge.json vendored Normal file
View File

@@ -0,0 +1,21 @@
{
"packageRules": [
{
"matchDatasources": [
"docker",
"github-tags"
],
"automerge": true,
"automergeType": "branch",
"requiredStatusChecks": null,
"matchUpdateTypes": [
"minor",
"patch"
],
"matchPackageNames": [
"ghcr.io/k8s-at-home/prowlarr-nightly",
"renovatebot/github-action"
]
}
]
}

32
.github/renovate/labels.json vendored Normal file
View File

@@ -0,0 +1,32 @@
{
"packageRules": [
{
"matchUpdateTypes": ["major"],
"labels": ["type/major"]
},
{
"matchUpdateTypes": ["minor"],
"labels": ["type/minor"]
},
{
"matchUpdateTypes": ["patch"],
"labels": ["type/patch"]
},
{
"matchDatasources": ["docker"],
"addLabels": ["renovate/container"]
},
{
"matchDatasources": ["helm"],
"addLabels": ["renovate/helm"]
},
{
"matchDatasources": ["galaxy", "galaxy-collection"],
"addLabels": ["renovate/ansible"]
},
{
"matchDatasources": ["terraform-provider"],
"addLabels": ["renovate/terraform"]
}
]
}

78
.github/renovate/semanticCommits.json vendored Normal file
View File

@@ -0,0 +1,78 @@
{
"packageRules": [
{
"matchDatasources": ["docker"],
"matchUpdateTypes": ["major"],
"commitMessagePrefix": "feat(container)!: "
},
{
"matchDatasources": ["docker"],
"matchUpdateTypes": ["minor"],
"semanticCommitType": "feat",
"semanticCommitScope": "container"
},
{
"matchDatasources": ["docker"],
"matchUpdateTypes": ["patch"],
"semanticCommitType": "fix",
"semanticCommitScope": "container"
},
{
"matchDatasources": ["helm"],
"matchUpdateTypes": ["major"],
"commitMessagePrefix": "feat(helm)!: "
},
{
"matchDatasources": ["helm"],
"matchUpdateTypes": ["minor"],
"semanticCommitType": "feat",
"semanticCommitScope": "helm"
},
{
"matchDatasources": ["helm"],
"matchUpdateTypes": ["patch"],
"semanticCommitType": "fix",
"semanticCommitScope": "helm"
},
{
"matchDatasources": ["galaxy", "galaxy-collection"],
"matchUpdateTypes": ["major"],
"commitMessagePrefix": "feat(ansible)!: "
},
{
"matchDatasources": ["galaxy", "galaxy-collection"],
"matchUpdateTypes": ["minor"],
"semanticCommitType": "feat",
"semanticCommitScope": "ansible"
},
{
"matchDatasources": ["galaxy", "galaxy-collection"],
"matchUpdateTypes": ["patch"],
"semanticCommitType": "fix",
"semanticCommitScope": "ansible"
},
{
"matchDatasources": ["terraform-provider"],
"matchUpdateTypes": ["major"],
"commitMessagePrefix": "feat(terraform)!: "
},
{
"matchDatasources": ["terraform-provider"],
"matchUpdateTypes": ["minor"],
"semanticCommitType": "feat",
"semanticCommitScope": "terraform"
},
{
"matchDatasources": ["terraform-provider"],
"matchUpdateTypes": ["patch"],
"semanticCommitType": "fix",
"semanticCommitScope": "terraform"
},
{
"matchManagers": ["github-actions"],
"semanticCommitType": "ci"
}
]
}

124
.github/scripts/container-parser.sh vendored Executable file
View File

@@ -0,0 +1,124 @@
#!/usr/bin/env bash
# shellcheck source=/dev/null
source "$(dirname "${0}")/lib/functions.sh"
set -o errexit
set -o nounset
set -o pipefail
shopt -s lastpipe
show_help() {
cat << EOF
Usage: $(basename "$0") <options>
-h, --help Display help
-f, --file File to scan for container images
--nothing Enable nothing mode
EOF
}
main() {
local file=
local nothing=
parse_command_line "$@"
check "jo"
check "jq"
check "yq"
entry
}
parse_command_line() {
while :; do
case "${1:-}" in
-h|--help)
show_help
exit
;;
-f|--file)
if [[ -n "${2:-}" ]]; then
file="$2"
shift
else
echo "ERROR: '-f|--file' cannot be empty." >&2
show_help
exit 1
fi
;;
--nothing)
nothing=1
;;
*)
break
;;
esac
shift
done
if [[ -z "$file" ]]; then
echo "ERROR: '-f|--file' is required." >&2
show_help
exit 1
fi
if [[ -z "$nothing" ]]; then
nothing=0
fi
}
entry() {
# create new array to hold the images
images=()
# look in hydrated flux helm releases
chart_registry_url=$(chart_registry_url "${file}")
chart_name=$(yq eval-all .spec.chart.spec.chart "${file}" 2>/dev/null)
if [[ -n ${chart_registry_url} && -n "${chart_name}" && ! "${chart_name}" =~ "null" ]]; then
chart_version=$(yq eval .spec.chart.spec.version "${file}" 2>/dev/null)
chart_values=$(yq eval .spec.values "${file}" 2>/dev/null)
pushd "$(mktemp -d)" > /dev/null 2>&1
helm repo add main "${chart_registry_url}" > /dev/null 2>&1
helm pull "main/${chart_name}" --untar --version "${chart_version}"
resources=$(echo "${chart_values}" | helm template "${chart_name}" "${chart_name}" --version "${chart_version}" -f -)
popd > /dev/null 2>&1
images+=("$(echo "${resources}" | yq eval-all '.spec.template.spec.containers.[].image' -)")
helm repo remove main > /dev/null 2>&1
fi
# look in helm values
images+=("$(yq eval-all '[.. | select(has("repository")) | select(has("tag"))] | .[] | .repository + ":" + .tag' "${file}" 2>/dev/null)")
# look in kubernetes deployments, statefulsets and daemonsets
images+=("$(yq eval-all '.spec.template.spec.containers.[].image' "${file}" 2>/dev/null)")
# look in kubernetes pods
images+=("$(yq eval-all '.spec.containers.[].image' "${file}" 2>/dev/null)")
# look in kubernetes cronjobs
images+=("$(yq eval-all '.spec.jobTemplate.spec.template.spec.containers.[].image' "${file}" 2>/dev/null)")
# look in docker compose
images+=("$(yq eval-all '.services.*.image' "${file}" 2>/dev/null)")
# remove duplicate values xD
IFS=" " read -r -a images <<< "$(tr ' ' '\n' <<< "${images[@]}" | sort -u | tr '\n' ' ')"
# create new array to hold the parsed images
parsed_images=()
# loop thru the images removing any invalid items
for i in "${images[@]}"; do
# loop thru each image and split on new lines (for when yq finds multiple containers in the same file)
for b in ${i//\\n/ }; do
if [[ -z "${b}" || "${b}" == "null" || "${b}" == "---" ]]; then
continue
fi
parsed_images+=("${b}")
done
done
# check if parsed_images array has items
if (( ${#parsed_images[@]} )); then
# convert the bash array to json and wrap array in an containers object
jo -a "${parsed_images[@]}" | jq -c '{containers: [(.[])]}'
fi
}
main "$@"

175
.github/scripts/helm-release-differ.sh vendored Executable file
View File

@@ -0,0 +1,175 @@
#!/usr/bin/env bash
# shellcheck source=/dev/null
source "$(dirname "${0}")/lib/functions.sh"
set -o errexit
set -o nounset
set -o pipefail
shopt -s lastpipe
show_help() {
cat << EOF
Usage: $(basename "$0") <options>
-h, --help Display help
--source-file Original helm release
--target-file New helm release
--remove-common-labels Remove common labels from manifests
EOF
}
main() {
local source_file=
local target_file=
local remove_common_labels=
parse_command_line "$@"
check "helm"
check "yq"
entry
}
parse_command_line() {
while :; do
case "${1:-}" in
-h|--help)
show_help
exit
;;
--source-file)
if [[ -n "${2:-}" ]]; then
source_file="$2"
shift
else
echo "ERROR: '--source-file' cannot be empty." >&2
show_help
exit 1
fi
;;
--target-file)
if [[ -n "${2:-}" ]]; then
target_file="$2"
shift
else
echo "ERROR: '--target-file' cannot be empty." >&2
show_help
exit 1
fi
;;
--remove-common-labels)
remove_common_labels=true
;;
*)
break
;;
esac
shift
done
if [[ -z "${source_file}" ]]; then
echo "ERROR: '--source-file' is required." >&2
show_help
exit 1
fi
if [[ $(yq eval .kind "${source_file}" 2>/dev/null) != "HelmRelease" ]]; then
echo "ERROR: '--source-file' is not a HelmRelease"
show_help
exit 1
fi
if [[ -z "${target_file}" ]]; then
echo "ERROR: '--target-file' is required." >&2
show_help
exit 1
fi
if [[ $(yq eval .kind "${target_file}" 2>/dev/null) != "HelmRelease" ]]; then
echo "ERROR: '--target-file' is not a HelmRelease"
show_help
exit 1
fi
if [[ -z "$remove_common_labels" ]]; then
remove_common_labels=false
fi
}
_resources() {
local chart_name=${1}
local chart_version=${2}
local chart_registry_url=${3}
local chart_values=${4}
local resources=
helm repo add main "${chart_registry_url}" > /dev/null 2>&1
pushd "$(mktemp -d)" > /dev/null 2>&1
helm pull "main/${chart_name}" --untar --version "${chart_version}"
resources=$(echo "${chart_values}" | helm template "${chart_name}" "${chart_name}" --version "${chart_version}" -f -)
if [[ "${remove_common_labels}" == "true" ]]; then
labels='.metadata.labels."helm.sh/chart"'
labels+=',.metadata.labels.chart'
labels+=',.metadata.labels."app.kubernetes.io/version"'
labels+=',.spec.template.metadata.labels."helm.sh/chart"'
labels+=',.spec.template.metadata.labels.chart'
labels+=',.spec.template.metadata.labels."app.kubernetes.io/version"'
echo "${resources}" | yq eval "del($labels)" -
else
echo "${resources}"
fi
popd > /dev/null 2>&1
helm repo remove main > /dev/null 2>&1
}
entry() {
local comments=
source_chart_name=$(chart_name "${source_file}")
source_chart_version=$(chart_version "${source_file}")
source_chart_registry_url=$(chart_registry_url "${source_file}")
source_chart_values=$(chart_values "${source_file}")
source_resources=$(_resources "${source_chart_name}" "${source_chart_version}" "${source_chart_registry_url}" "${source_chart_values}")
echo "${source_resources}" > /tmp/source_resources
target_chart_version=$(chart_version "${target_file}")
target_chart_name=$(chart_name "${target_file}")
target_chart_registry_url=$(chart_registry_url "${target_file}")
target_chart_values=$(chart_values "${target_file}")
target_resources=$(_resources "${target_chart_name}" "${target_chart_version}" "${target_chart_registry_url}" "${target_chart_values}")
echo "${target_resources}" > /tmp/target_resources
# Diff the files and always return true
diff -u /tmp/source_resources /tmp/target_resources > /tmp/diff || true
# Remove the filenames
sed -i -e '1,2d' /tmp/diff
# Store the comment in an array
comments=()
# shellcheck disable=SC2016
comments+=( "$(printf 'Path: `%s`' "${target_file}")" )
if [[ "${source_chart_name}" != "${target_chart_name}" ]]; then
# shellcheck disable=SC2016
comments+=( "$(printf 'Chart: `%s` -> `%s`' "${source_chart_name}" "${target_chart_name}")" )
fi
if [[ "${source_chart_version}" != "${target_chart_version}" ]]; then
# shellcheck disable=SC2016
comments+=( "$(printf 'Version: `%s` -> `%s`' "${source_chart_version}" "${target_chart_version}")" )
fi
if [[ "${source_chart_registry_url}" != "${target_chart_registry_url}" ]]; then
# shellcheck disable=SC2016
comments+=( "$(printf 'Registry URL: `%s` -> `%s`' "${source_chart_registry_url}" "${target_chart_registry_url}")" )
fi
comments+=( "$(printf '\n\n')" )
if [[ -f /tmp/diff && -s /tmp/diff ]]; then
# shellcheck disable=SC2016
comments+=( "$(printf '```diff\n%s\n```' "$(cat /tmp/diff)")" )
else
# shellcheck disable=SC2016
comments+=( "$(printf '```\nNo changes in detected in resources\n```')" )
fi
# Join the array with a new line and print it
printf "%s\n" "${comments[@]}"
}
main "$@"

47
.github/scripts/lib/functions.sh vendored Normal file
View File

@@ -0,0 +1,47 @@
#!/usr/bin/env bash
set -o errexit
set -o nounset
set -o pipefail
shopt -s lastpipe
check() {
command -v "${1}" >/dev/null 2>&1 || {
echo >&2 "ERROR: ${1} is not installed or not found in \$PATH" >&2
exit 1
}
}
chart_registry_url() {
local helm_release=
local chart_id=
helm_release="${1}"
chart_id=$(yq eval .spec.chart.spec.sourceRef.name "${helm_release}" 2>/dev/null)
# Discover all HelmRepository
find . -iname '*-charts.yaml' -type f -print0 | while IFS= read -r -d '' file; do
# Skip non HelmRepository
[[ $(yq eval .kind "${file}" 2>/dev/null) != "HelmRepository" ]] && continue
# Skip unrelated HelmRepository
[[ "${chart_id}" != $(yq eval .metadata.name "${file}" 2>/dev/null) ]] && continue
yq eval .spec.url "${file}"
break
done
}
chart_name() {
local helm_release=
helm_release="${1}"
yq eval .spec.chart.spec.chart "${helm_release}" 2>/dev/null
}
chart_version() {
local helm_release=
helm_release="${1}"
yq eval .spec.chart.spec.version "${helm_release}" 2>/dev/null
}
chart_values() {
local helm_release=
helm_release="${1}"
yq eval .spec.values "${helm_release}" 2>/dev/null
}

View File

@@ -1,124 +0,0 @@
---
name: Diff Helm Releases on Pull Requests
on: # yamllint disable-line rule:truthy
pull_request:
branches:
- main
paths:
- "cluster/**.yaml"
env:
conf_live_branch: main
conf_ignore_known_labels_containing_versions: true
jobs:
changes:
name: Detect changes
runs-on: ubuntu-20.04
outputs:
files: "${{ steps.extract.outputs.files }}"
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Get changes
uses: dorny/paths-filter@v2
id: filter
with:
list-files: shell
filters: |
changed:
- '**'
- name: Filter Helm Releases
id: extract
run: |
filtered=$(grep -zl "kind: HelmRelease.*registryUrl=" ${{ steps.filter.outputs.changed_files }} \
| jq -nR '[inputs | select(length>0)]')
echo ::set-output name=files::${filtered}
helm:
name: Template Helm Releases
runs-on: ubuntu-20.04
if: ${{ needs.changes.outputs.files != '' }}
needs:
- changes
strategy:
matrix:
file: ${{ fromJson(needs.changes.outputs.files) }}
fail-fast: false
steps:
- name: Setup Kubernetes Tools
uses: yokawasa/action-setup-kube-tools@v0.8.0
with:
setup-tools: |
helmv3
yq
- name: Checkout live branch
uses: actions/checkout@v2
with:
ref: ${{ env.conf_live_branch }}
path: live
- name: Checkout PR branch
uses: actions/checkout@v2
with:
path: pr
- name: Create diff
id: diff
run: |
hr_live_url=$(sed -nr 's|.*registryUrl=(.+)$|\1|p' live/${{ matrix.file }})
hr_live_chart=$(yq e .spec.chart.spec.chart live/${{ matrix.file }})
hr_live_version=$(yq e .spec.chart.spec.version live/${{ matrix.file }})
hr_live_values=$(yq e .spec.values live/${{ matrix.file }})
hr_pr_url=$(sed -nr 's|.*registryUrl=(.+)$|\1|p' pr/${{ matrix.file }})
hr_pr_chart=$(yq e .spec.chart.spec.chart pr/${{ matrix.file }})
hr_pr_version=$(yq e .spec.chart.spec.version pr/${{ matrix.file }})
hr_pr_values=$(yq e .spec.values pr/${{ matrix.file }})
helm repo add live "$hr_live_url"
helm repo add pr "$hr_pr_url"
resources_live=$(echo "$hr_live_values" | \
helm template "$hr_live_chart" \
live/"$hr_live_chart" \
--version "$hr_live_version" -f - || true)
echo "$resources_live"
echo "#####################################################"
resources_pr=$(echo "$hr_pr_values" | \
helm template "$hr_pr_chart" \
pr/"$hr_pr_chart" \
--version "$hr_pr_version" -f -)
echo "$resources_pr"
echo "#####################################################"
if [ "$conf_ignore_known_labels_containing_versions" = "true" ]; then
labels='.metadata.labels."helm.sh/chart"'
labels+=',.metadata.labels.chart'
labels+=',.metadata.labels."app.kubernetes.io/version"'
labels+=',.spec.template.metadata.labels."helm.sh/chart"'
labels+=',.spec.template.metadata.labels.chart'
labels+=',.spec.template.metadata.labels."app.kubernetes.io/version"'
resources_live=$(echo "$resources_live" | yq e "del($labels)" -)
resources_pr=$(echo "$resources_pr" | yq e "del($labels)" -)
fi
diff=$((diff -u <(echo "$resources_live") <(echo "$resources_pr") || true) | tail +3)
echo "$diff"
message="Path: \`${{ matrix.file }}\`"
if [ "$hr_live_chart" != "$hr_pr_chart" ]; then
message="$message"$'\n'"Chart: \`$hr_live_chart\` -> \`$hr_pr_chart\`"
fi
if [ "$hr_live_version" != "$hr_pr_version" ]; then
message="$message"$'\n'"Version: \`$hr_live_version\` -> \`$hr_pr_version\`"
fi
if [ "$hr_live_url" != "$hr_pr_url" ]; then
message="$message"$'\n'"Repo: \`$hr_live_url\` -> \`$hr_pr_url\`"
fi
message="$message"$'\n'$'\n'
if [ -z "$diff" ]; then
message="$message"'```'$'\n'"No changes in detected in resources"$'\n''```'
else
message="$message"'```diff'$'\n'"$diff"$'\n''```'
fi
echo "::set-output name=message::$(echo "$message" | jq --raw-input --slurp)"
- name: Add Pull Request comment
uses: peter-evans/create-or-update-comment@v1
with:
issue-number: ${{ github.event.pull_request.number }}
body: "${{ fromJSON(steps.diff.outputs.message) }}"

View File

@@ -0,0 +1,79 @@
---
name: Helm Release Differ
on: # yamllint disable-line rule:truthy
pull_request:
branches:
- main
paths:
- "cluster/**.yaml"
env:
# Currently no way to detect automatically
DEFAULT_BRANCH: main
BOT_USERNAME: "feisar-bot[bot]"
jobs:
detect-file-changes:
name: Detect File Changes
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: dorny/paths-filter@v2
id: filter
with:
list-files: json
filters: |
yaml:
- added|modified: "**/helm-release.yaml"
outputs:
yaml_files: ${{ steps.filter.outputs.yaml_files }}
helm-release-differ:
name: Helm Release Differ
runs-on: ubuntu-latest
needs: detect-file-changes
strategy:
matrix:
file: ${{ fromJSON(needs.detect-file-changes.outputs.yaml_files) }}
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Generate Token
uses: tibdex/github-app-token@v1
id: generate-token
with:
app_id: ${{ secrets.BOT_APP_ID }}
private_key: ${{ secrets.BOT_APP_PRIVATE_KEY }}
- name: Checkout default branch
uses: actions/checkout@v2
with:
ref: "${{ env.DEFAULT_BRANCH }}"
path: default
- name: Install Helm
uses: azure/setup-helm@v1
with:
version: v3.6.3
- name: Helm Release Differ
id: diff
run: |
diff=$(.github/scripts/helm-release-differ.sh --source-file "default/${{ matrix.file }}" --target-file "${{ matrix.file }}" --remove-common-labels)
echo "${diff}"
diff="${diff//'%'/'%25'}"
diff="${diff//$'\n'/'%0A'}"
diff="${diff//$'\r'/'%0D'}"
echo "::set-output name=diff::$(echo ${diff})"
- name: Find Comment
uses: peter-evans/find-comment@v1
id: find-comment
with:
issue-number: "${{ github.event.pull_request.number }}"
comment-author: "${{ env.BOT_USERNAME }}"
body-includes: helm-release.yaml
- name: Create or update comment
uses: peter-evans/create-or-update-comment@v1
with:
token: "${{ steps.generate-token.outputs.token }}"
comment-id: "${{ steps.find-comment.outputs.comment-id }}"
issue-number: "${{ github.event.pull_request.number }}"
body: "${{ steps.diff.outputs.diff }}"
edit-mode: replace

View File

@@ -1,28 +0,0 @@
---
name: Lint Markdown files on Pull Requests
on: # yamllint disable-line rule:truthy
pull_request:
paths:
- "**.md"
jobs:
markdownlint:
runs-on: ubuntu-20.04
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Get changes
uses: dorny/paths-filter@v2
id: filter
with:
list-files: shell
filters: |
markdown:
- added|modified: "**.md"
- name: Lint files
if: ${{ steps.filter.outputs.markdown == 'true' }}
uses: reviewdog/action-shellcheck@v1
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
markdownlint_flags: "-c '.github/lint/.markdownlint.yaml' ${{ steps.filter.outputs.markdown_files }}"

View File

@@ -1,27 +0,0 @@
---
name: Lint Shell scripts on Pull Requests
on: # yamllint disable-line rule:truthy
pull_request:
paths:
- "**.sh"
jobs:
shellcheck:
runs-on: ubuntu-20.04
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Get changes
uses: dorny/paths-filter@v2
id: filter
with:
list-files: shell
filters: |
shell:
- added|modified: "**.sh"
- name: Lint files
if: ${{ steps.filter.outputs.shell == 'true' }}
uses: reviewdog/action-shellcheck@v1
with:
shellcheck_flags: "${{ steps.filter.outputs.shell_files }}"

View File

@@ -1,29 +0,0 @@
---
name: Lint YAML files on Pull Requests
on: # yamllint disable-line rule:truthy
pull_request:
paths:
- "**.yaml"
- "**.yml"
jobs:
yamllint:
runs-on: ubuntu-20.04
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Get changes
uses: dorny/paths-filter@v2
id: filter
with:
list-files: shell
filters: |
yaml:
- added|modified: "**.yaml"
- added|modified: "**.yml"
- name: Lint files
if: ${{ steps.filter.outputs.yaml == 'true' }}
uses: reviewdog/action-yamllint@v1
with:
yamllint_flags: "-c .github/lint/.yamllint.yaml ${{ steps.filter.outputs.yaml_files }}"

38
.github/workflows/lint.yaml vendored Normal file
View File

@@ -0,0 +1,38 @@
---
name: Lint
on: # yamllint disable-line rule:truthy
pull_request:
branches:
- main
env:
# Currently no way to detect automatically
DEFAULT_BRANCH: main
jobs:
build:
name: Lint
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
with:
fetch-depth: 0
- name: Generate Token
uses: tibdex/github-app-token@v1
id: generate-token
with:
app_id: "${{ secrets.BOT_APP_ID }}"
private_key: "${{ secrets.BOT_APP_PRIVATE_KEY }}"
- name: Lint
uses: github/super-linter/slim@v4
env:
VALIDATE_ALL_CODEBASE: false
DEFAULT_BRANCH: "${{ env.DEFAULT_BRANCH }}"
GITHUB_TOKEN: "${{ steps.generate-token.outputs.token }}"
ANSIBLE_CONFIG_FILE: .ansible-lint
MARKDOWN_CONFIG_FILE: .markdownlint.yaml
TERRAFORM_TFLINT_CONFIG_FILE: .tflint.hcl
YAML_CONFIG_FILE: .yamllint.yaml
KUBERNETES_KUBEVAL_OPTIONS: --ignore-missing-schemas

33
.github/workflows/meta-label-size.yaml vendored Normal file
View File

@@ -0,0 +1,33 @@
---
name: Meta - Label Size
on: # yamllint disable-line rule:truthy
pull_request:
branches:
- main
jobs:
label-size:
name: Label Size
runs-on: ubuntu-latest
steps:
- name: Generate Token
uses: tibdex/github-app-token@v1
id: generate-token
with:
app_id: "${{ secrets.BOT_APP_ID }}"
private_key: "${{ secrets.BOT_APP_PRIVATE_KEY }}"
- name: Label Size
uses: pascalgn/size-label-action@v0.4.3
env:
GITHUB_TOKEN: "${{ steps.generate-token.outputs.token }}"
with:
sizes: >
{
"0": "XS",
"20": "S",
"50": "M",
"200": "L",
"800": "XL",
"2000": "XXL"
}

44
.github/workflows/meta-labeler.yml vendored Normal file
View File

@@ -0,0 +1,44 @@
---
name: Schedule - Flux Update
on: # yamllint disable-line rule:truthy
workflow_dispatch:
schedule:
- cron: "0 */4 * * *"
jobs:
flux-update:
name: Flux Update
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Generate Token
uses: tibdex/github-app-token@v1
id: generate-token
with:
app_id: "${{ secrets.BOT_APP_ID }}"
private_key: "${{ secrets.BOT_APP_PRIVATE_KEY }}"
- name: Install Flux
uses: fluxcd/flux2/action@main
- name: Flux Update
id: update
run: |
UGLY_VERSION="$(flux -v)"
VERSION="v${UGLY_VERSION#*flux version }"
flux install --version="${VERSION}" \
--components-extra=image-reflector-controller,image-automation-controller \
--network-policy=false \
--export > ./cluster/base/flux-system/gotk-components.yaml
echo "::set-output name=flux_version::$VERSION"
- name: Create pull request
uses: peter-evans/create-pull-request@v3
with:
token: "${{ steps.generate-token.outputs.token }}"
branch: "ci/flux-update-${{ steps.update.outputs.flux_version }}"
delete-branch: true
title: "chore(ci): update flux components to ${{ steps.update.outputs.flux_version }}"
signoff: true
commit-message: "chore(ci): update flux components to ${{ steps.update.outputs.flux_version }}"
body: |
Release notes: https://github.com/fluxcd/flux2/releases/tag/${{ steps.update.outputs.flux_version }}

23
.github/workflows/meta-sync-labels.yaml vendored Normal file
View File

@@ -0,0 +1,23 @@
name: Meta - Sync labels
on: # yamllint disable-line rule:truthy
workflow_dispatch:
jobs:
labels:
name: Sync Labels
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Generate Token
uses: tibdex/github-app-token@v1
id: generate-token
with:
app_id: "${{ secrets.BOT_APP_ID }}"
private_key: "${{ secrets.BOT_APP_PRIVATE_KEY }}"
- name: Sync Labels
uses: EndBug/label-sync@v2
with:
config-file: .github/labels.yaml
token: "${{ steps.generate-token.outputs.token }}"

View File

@@ -1,33 +0,0 @@
---
name: Schedule - Add Helm Release Renovate annotations
on: # yamllint disable-line rule:truthy
workflow_dispatch:
schedule:
- cron: "0 */12 * * *"
jobs:
renovate-helm-releases:
runs-on: ubuntu-20.04
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Renovate Helm Releases
uses: k8s-at-home/renovate-helm-releases@v1
with:
cluster-path: "./cluster"
- name: Create pull request for renovatebot helm-release annotations
uses: peter-evans/create-pull-request@v3
with:
token: ${{ secrets.GITHUB_TOKEN }}
branch: renovate-annotations
delete-branch: true
title: "chore(deps): update renovate annotations"
signoff: true
committer: "auricom <27022259+auricom@users.noreply.github.com>"
author: "auricom <27022259+auricom@users.noreply.github.com>"
assignees: "auricom"
commit-message: "chore(deps): update renovate annotations"
body: |
Update Helm Releases in order for Renovate to pick up new versions of Helm charts
labels: renovate/annotations

73
.github/workflows/scan-containers.yaml vendored Normal file
View File

@@ -0,0 +1,73 @@
---
name: Scan Containers
on: # yamllint disable-line rule:truthy
pull_request:
branches:
- main
paths:
- "cluster/**.yaml"
- "ansible/**.yml.j2"
jobs:
detect-file-changes:
name: Detect File Changes
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: dorny/paths-filter@v2
id: filter
with:
list-files: json
filters: |
yaml:
- added|modified: "**.yaml"
- added|modified: "**.yml"
- added|modified: "**.yaml.j2"
- added|modified: "**.yml.j2"
outputs:
yaml_files: ${{ steps.filter.outputs.yaml_files }}
detect-containers:
name: Detect Containers
runs-on: ubuntu-latest
needs: detect-file-changes
strategy:
matrix:
file: ${{ fromJSON(needs.detect-file-changes.outputs.yaml_files) }}
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Install Jo
run: |
sudo apt-get install jo
- name: Detect Containers in Files
id: containers
run: |
containers=$(.github/scripts/container-parser.sh --file "${{ matrix.file }}")
echo "${containers}"
echo ::set-output name=containers::${containers}
outputs:
containers: ${{ steps.containers.outputs.containers }}
scan-containers:
name: Scan Containers
runs-on: ubuntu-latest
needs: detect-containers
strategy:
matrix: ${{ fromJSON(needs.detect-containers.outputs.containers) }}
fail-fast: false
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Scan Container
uses: aquasecurity/trivy-action@0.2.1
with:
image-ref: ${{ matrix.containers }}
vuln-type: os,library
severity: CRITICAL,HIGH
format: template
template: "@/contrib/sarif.tpl"
output: trivy-results.sarif
- name: Upload Trivy scan results to GitHub Security tab
uses: github/codeql-action/upload-sarif@v1
with:
sarif_file: trivy-results.sarif

View File

@@ -0,0 +1,44 @@
name: Schedule - Link Checker
on: # yamllint disable-line rule:truthy
workflow_dispatch:
schedule:
- cron: "0 0 * * *"
push:
branches:
- main
jobs:
link-checker:
name: Link Checker
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Generate Token
uses: tibdex/github-app-token@v1
id: generate-token
with:
app_id: "${{ secrets.BOT_APP_ID }}"
private_key: "${{ secrets.BOT_APP_PRIVATE_KEY }}"
- name: Link Checker
uses: lycheeverse/lychee-action@v1.2.0
id: lychee
with:
output: ./lychee.md
- name: Find Link Checker Issue
id: link-checker-issue
uses: micalevisk/last-issue-action@v1
with:
state: open
labels: |
link-checker
- name: Update Issue
uses: peter-evans/create-issue-from-file@v3
with:
title: Broken links detected in docs 🔗
issue-number: "${{ steps.link-checker-issue.outputs.issue_number }}"
content-filepath: ./lychee.md
token: "${{ steps.generate-token.outputs.token }}"
labels: |
link-checker

View File

@@ -0,0 +1,50 @@
name: Schedule - Renovate
on: # yamllint disable-line rule:truthy
workflow_dispatch:
inputs:
dryRun:
description: "Dry-Run"
default: "true"
required: false
logLevel:
description: "Log-Level"
default: "debug"
required: false
schedule:
- cron: "0 * * * *"
push:
branches:
- main
paths:
- ".github/renovate.json5"
- ".github/renovate/**.json"
env:
LOG_LEVEL: info
DRY_RUN: false
jobs:
renovate:
name: Renovate
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Verify Renovate Configuration
uses: suzuki-shunsuke/github-action-renovate-config-validator@v0.1.2
- name: Generate Token
uses: tibdex/github-app-token@v1
id: generate-token
with:
app_id: "${{ secrets.BOT_APP_ID }}"
private_key: "${{ secrets.BOT_APP_PRIVATE_KEY }}"
- name: Override default config from dispatch variables
run: |
echo "DRY_RUN=${{ github.event.inputs.dryRun || env.DRY_RUN }}" >> "${GITHUB_ENV}"
echo "LOG_LEVEL=${{ github.event.inputs.logLevel || env.LOG_LEVEL }}" >> "${GITHUB_ENV}"
- name: Renovate
uses: renovatebot/github-action@v31.42.0
with:
configurationFile: .github/renovate.json5
token: "x-access-token:${{ steps.generate-token.outputs.token }}"

View File

@@ -7,5 +7,4 @@ resources:
- certificate
- ingress-nginx
- k8s-gateway
#- traefik
- unifi

View File

@@ -1,20 +0,0 @@
---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: dashboard
namespace: networking
spec:
entryPoints:
- websecure
routes:
- match: Host(`traefik.${SECRET_CLUSTER_DOMAIN}`)
kind: Rule
priority: 10
services:
- name: api@internal
kind: TraefikService
middlewares:
- name: rfc1918
tls:
secretName: "${SECRET_CLUSTER_CERTIFICATE_DEFAULT}"

View File

@@ -1,5 +0,0 @@
---
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ingress-route.yaml

View File

@@ -1,102 +0,0 @@
---
apiVersion: helm.toolkit.fluxcd.io/v2beta1
kind: HelmRelease
metadata:
name: traefik
namespace: networking
spec:
interval: 5m
chart:
spec:
# renovate: registryUrl=https://helm.traefik.io/traefik
chart: traefik
version: 10.9.1
sourceRef:
kind: HelmRepository
name: traefik-charts
namespace: flux-system
interval: 5m
values:
deployment:
kind: DaemonSet
service:
enabled: true
type: LoadBalancer
spec:
externalIPs:
- "${CLUSTER_LB_TRAEFIK}"
externalTrafficPolicy: Local
logs:
general:
format: json
level: DEBUG
access:
enabled: true
format: json
ingressClass:
enabled: false
ingressRoute:
dashboard:
enabled: false
globalArguments:
- "--api.insecure=true"
- "--serverstransport.insecureskipverify=true"
- "--providers.kubernetesingress.ingressclass=traefik"
- "--entryPoints.websecure.forwardedHeaders.trustedIPs=10.0.0.0/8,192.168.0.0/16,103.21.244.0/22,103.22.200.0/22,103.31.4.0/22,104.16.0.0/13,104.24.0.0/14,108.162.192.0/18,131.0.72.0/22,141.101.64.0/18,162.158.0.0/15,172.64.0.0/13,173.245.48.0/20,188.114.96.0/20,190.93.240.0/20,197.234.240.0/22,198.41.128.0/17,2400:cb00::/32,2606:4700::/32,2803:f800::/32,2405:b500::/32,2405:8100::/32,2a06:98c0::/29,2c0f:f248::/32"
additionalArguments:
- "--providers.kubernetesingress.ingressendpoint.ip=${CLUSTER_LB_TRAEFIK}"
ports:
traefik:
expose: true
web:
redirectTo: websecure
websecure:
tls:
enabled: true
options: "default"
metrics:
port: 8082
expose: true
exposedPort: 8082
tlsOptions:
default:
minVersion: VersionTLS12
maxVersion: VersionTLS13
sniStrict: true
pilot:
enabled: true
token: "${SECRET_TRAEFIK_PILOT_TOKEN}"
experimental:
plugins:
enabled: true
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: app.kubernetes.io/name
operator: In
values:
- traefik
topologyKey: kubernetes.io/hostname
resources:
requests:
memory: 100Mi
cpu: 500m
limits:
memory: 500Mi

View File

@@ -1,9 +0,0 @@
---
apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
annotations:
ingressclass.kubernetes.io/is-default-class: "true"
name: traefik
spec:
controller: traefik.io/ingress-controller

View File

@@ -1,11 +0,0 @@
---
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- helm-release.yaml
- ingressclass.yaml
- service-monitor.yaml
- tls-store
- dashboard
- middlewares
- prometheus-rules.yaml

View File

@@ -1,9 +0,0 @@
---
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: authelia
namespace: networking
spec:
forwardAuth:
address: http://authelia.networking.svc.cluster.local./api/verify?rd=https://login.${SECRET_CLUSTER_DOMAIN}

View File

@@ -1,11 +0,0 @@
---
# Sets the maximum request body to 2000Mb
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: buffering-large
namespace: networking
spec:
buffering:
maxRequestBodyBytes: 2000000000
memRequestBodyBytes: 2000000

View File

@@ -1,11 +0,0 @@
---
# Sets the maximum request body to 200Mb
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: buffering-medium
namespace: networking
spec:
buffering:
maxRequestBodyBytes: 200000000
memRequestBodyBytes: 2000000

View File

@@ -1,11 +0,0 @@
---
# Sets the maximum request body to 20Mb
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: buffering-small
namespace: networking
spec:
buffering:
maxRequestBodyBytes: 20000000
memRequestBodyBytes: 2000000

View File

@@ -1,11 +0,0 @@
---
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: forward-auth
namespace: networking
spec:
chain:
middlewares:
- name: rfc1918-ips
- name: authelia

View File

@@ -1,12 +0,0 @@
---
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- authelia.yaml
- buffering-large.yaml
- buffering-medium.yaml
- buffering-small.yaml
- ratelimit.yaml
- rfc1918.yaml
- redirect-path.yaml
- forward-auth.yaml

View File

@@ -1,10 +0,0 @@
---
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: ratelimit
namespace: networking
spec:
rateLimit:
average: 10
period: "10s"

View File

@@ -1,32 +0,0 @@
---
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: redirect-regex
namespace: networking
spec:
redirectRegex:
regex: "^(https?://[^/]+/[a-z0-9_]+)$"
replacement: "${1}/"
permanent: true
---
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: strip-prefix-regex
namespace: networking
spec:
stripPrefixRegex:
regex:
- "/[a-z0-9_]+"
---
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: redirect-path
namespace: networking
spec:
chain:
middlewares:
- name: redirect-regex
- name: strip-prefix-regex

View File

@@ -1,22 +0,0 @@
---
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: rfc1918-ips
namespace: networking
spec:
ipWhiteList:
sourceRange:
- 10.0.0.0/8
- 172.16.0.0/12
- 192.168.0.0/16
---
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: rfc1918
namespace: networking
spec:
chain:
middlewares:
- name: rfc1918-ips

View File

@@ -1,72 +0,0 @@
---
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
labels:
app: traefik
name: traefik.rules
namespace: networking
spec:
groups:
- name: traefik.rules
rules:
- alert: TraefikAbsent
annotations:
summary: "Traefik has disappeared from Prometheus service discovery."
description: "Ingresses will be down until the Traefik reverse proxy is back up."
expr: |
absent(up{job="traefik"})
for: 5m
labels:
severity: critical
- alert: TraefikConfigError
annotations:
summary: "Traefik config error."
description:
"Traefik has failed to load the config file. Check Traefik
logs for exact parsing error."
expr: |
traefik_config_last_reload_failure{job="traefik"} == 1
for: 5m
labels:
severity: critical
- alert: TraefikHighHttp4xxErrorRateService
annotations:
summary: "Traefik has a high HTTP 4xx error rate."
description:
"Traefik is reporting {{ $value | humanizePercentage }} of 4xx
errors on {{ $labels.exported_service }}"
expr: |
sum(rate(traefik_service_requests_total{code=~"4.*"}[1m])) by (exported_service)
/
sum(rate(traefik_service_requests_total[1m])) by (exported_service)
> .10
for: 5m
labels:
severity: critical
- alert: TraefikHighHttp5xxErrorRateService
annotations:
summary: "Traefik has a high HTTP 5xx error rate."
description:
"Traefik is reporting {{ $value | humanizePercentage }} of 5xx
errors on {{ $labels.exported_service }}"
expr: |
sum(rate(traefik_service_requests_total{code=~"5.*"}[1m])) by (exported_service)
/
sum(rate(traefik_service_requests_total[1m])) by (exported_service)
> .10
for: 5m
labels:
severity: critical
- alert: TraefikTooManyRequest
annotations:
summary: "Traefik has too many open connections"
description:
"Traefik is reporting {{ $value }} of open connections on entrypoint
{{ $labels.entrypoint }}"
expr: |
avg(traefik_entrypoint_open_connections{job="traefik"})
> 5
for: 5m
labels:
severity: critical

View File

@@ -1,19 +0,0 @@
---
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: traefik
namespace: networking
labels:
app.kubernetes.io/name: traefik
spec:
endpoints:
- path: /metrics
targetPort: metrics
jobLabel: traefik
namespaceSelector:
matchNames:
- networking
selector:
matchLabels:
app.kubernetes.io/name: traefik

View File

@@ -1,9 +0,0 @@
---
apiVersion: traefik.containo.us/v1alpha1
kind: TLSStore
metadata:
name: default
namespace: networking
spec:
defaultCertificate:
secretName: "${SECRET_CLUSTER_CERTIFICATE_DEFAULT}"

View File

@@ -1,5 +0,0 @@
---
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- default.yaml

View File

@@ -1,38 +0,0 @@
---
apiVersion: source.toolkit.fluxcd.io/v1beta1
kind: GitRepository
metadata:
name: external-snapshotter-source
namespace: flux-system
spec:
interval: 1h
url: https://github.com./kubernetes-csi/external-snapshotter.git
ref:
tag: v4.1.0
ignore: |
# exclude all
/*
# include deploy crds dir
!/client/config/crd
---
apiVersion: kustomize.toolkit.fluxcd.io/v1beta2
kind: Kustomization
metadata:
name: external-snapshotter-crds
namespace: flux-system
spec:
interval: 15m
prune: false
sourceRef:
kind: GitRepository
name: external-snapshotter-source
healthChecks:
- apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
name: volumesnapshotclasses.snapshot.storage.k8s.io
- apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
name: volumesnapshotcontents.snapshot.storage.k8s.io
- apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
name: volumesnapshots.snapshot.storage.k8s.io

View File

@@ -1,4 +0,0 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- crds.yaml

View File

@@ -2,7 +2,5 @@ apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- cert-manager
- external-snapshotter
- kube-prometheus-stack
- rook-ceph
- traefik

View File

@@ -1,57 +0,0 @@
---
apiVersion: source.toolkit.fluxcd.io/v1beta1
kind: GitRepository
metadata:
name: traefik-crd-source
namespace: flux-system
spec:
interval: 1h
url: https://github.com./traefik/traefik-helm-chart.git
ref:
# renovate: registryUrl=https://helm.traefik.io/traefik chart=traefik
tag: v10.1.1
ignore: |
# exclude all
/*
# path to crds
!/traefik/crds/
---
apiVersion: kustomize.toolkit.fluxcd.io/v1beta2
kind: Kustomization
metadata:
name: traefik-crds
namespace: flux-system
spec:
interval: 15m
prune: false
sourceRef:
kind: GitRepository
name: traefik-crd-source
healthChecks:
- apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
name: ingressroutes.traefik.containo.us
- apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
name: ingressroutetcps.traefik.containo.us
- apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
name: ingressrouteudps.traefik.containo.us
- apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
name: middlewares.traefik.containo.us
- apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
name: middlewaretcps.traefik.containo.us
- apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
name: serverstransports.traefik.containo.us
- apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
name: tlsoptions.traefik.containo.us
- apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
name: tlsstores.traefik.containo.us
- apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
name: traefikservices.traefik.containo.us

View File

@@ -1,4 +0,0 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- crds.yaml

View File

@@ -11,8 +11,8 @@
```console
$ mkdir -p /var/lib/tftpboot/pxelinux/
$ curl https://releases.ubuntu.com/20.04/ubuntu-20.04.2-live-server-amd64.iso -o /var/lib/tftpboot/ubuntu-20.04.2-live-server-amd64.iso
$ mount -t cd9660 /dev/`mdconfig -f /var/lib/tftpboot/ubuntu-20.04.2-live-server-amd64.iso` /mnt
$ curl https://releases.ubuntu.com/20.04/ubuntu-20.04.3-live-server-amd64.iso -o /var/lib/tftpboot/ubuntu-20.04.3-live-server-amd64.iso
$ mount -t cd9660 /dev/`mdconfig -f /var/lib/tftpboot/ubuntu-20.04.3-live-server-amd64.iso` /mnt
$ cp /mnt/casper/vmlinuz /var/lib/tftpboot/pxelinux/
$ cp /mnt/casper/initrd /var/lib/tftpboot/pxelinux/
$ umount /mnt

View File

@@ -1,16 +1,3 @@
# Server infrastructure
These Ansible Playbooks and Roles are for preparing an Ubuntu 20.10.x OS to play nicely with Kubernetes and standing up k3s ontop of the nodes.
## Commands
Commands to run can be found in my Ansible Taskfile located [here](https://github.com/auricom/home-cluster/blob/main/.taskfiles/ansible.yml)
e.g.
```bash
# List hosts in my Ansible inventory
task ansible:list
# Ping hosts in my Ansible inventory
task ansible:ping
```