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 tabWidth: 2
semi: false semi: false
singleQuote: false singleQuote: false
bracketSpacing: false
useTabs: false

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

View File

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

297
.github/renovate.json5 vendored
View File

@@ -1,182 +1,173 @@
{ {
enabled: true, "extends": [
timezone: "Europe/Paris", ":enableRenovate",
semanticCommits: "enabled", "config:base",
dependencyDashboard: true, ":disableRateLimiting",
dependencyDashboardTitle: "Renovate Dashboard", ":dependencyDashboard",
commitBody: "Signed-off-by: auricom <27022259+auricom@users.noreply.github.com>", ":semanticCommits",
// Do not notify on closed unmerged PRs ":separatePatchReleases",
suppressNotifications: ["prIgnoreNotification"], "docker:enableMajor",
// Do not rebase PRs ":enablePreCommit",
rebaseWhen: "conflicted", "github>auricom/home-cluster//.github/renovate/autoMerge",
assignees: ["@auricom"], "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": { "helm-values": {
fileMatch: ["cluster/.+/helm-release\\.yaml$"], "fileMatch": [
"cluster/.+/helm-release\\.yaml$"
]
}, },
kubernetes: { "helmv3": {
fileMatch: ["cluster/.+\\.yaml$"], "fileMatch": [
ignorePaths: ["cluster/base/"], "charts/.+/Chart\\.yaml$"
]
}, },
regexManagers: [ "kubernetes": {
// regexManager to read and process HelmRelease files "fileMatch": [
{ "cluster/.+\\.yaml$"
fileMatch: ["cluster/.+\\.yaml$"], ],
matchStrings: [ "ignorePaths": [
// helm releases "cluster/base/"
"registryUrl=(?<registryUrl>.*?)\n *chart: (?<depName>.*?)\n *version: (?<currentValue>.*)\n", ]
], },
datasourceTemplate: "helm", "flux": {
}, "fileMatch": [
"cluster/.+\\.yaml$"
]
},
"regexManagers": [
// regexManager to read and process cert-manager CRD's // regexManager to read and process cert-manager CRD's
{ {
fileMatch: ["cluster/base-custom/crds/cert-manager/.+\\.yaml$"], "fileMatch": [
matchStrings: [ "cluster/base-custom/crds/cert-manager/.+\\.yaml$"
],
"matchStrings": [
"registryUrl=(?<registryUrl>.*?) chart=(?<depName>.*?)\n.*\\/(?<currentValue>.*?)\\/", "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$"], "fileMatch": [
matchStrings: [ "cluster/base-custom/crds/kube-prometheus-stack/.+\\.yaml$"
"registryUrl=(?<registryUrl>.*?)\n *tag: (?<depName>[a-zA-Z-]+)-(?<currentValue>.*)\n",
], ],
datasourceTemplate: "helm", "matchStrings": [
}, "registryUrl=(?<registryUrl>.*?)\n *tag: (?<depName>[a-zA-Z-]+)-(?<currentValue>.*)\n"
// regexManager to read and process Traefik CRD's
{
fileMatch: ["cluster/crds/traefik/.+\\.yaml$"],
matchStrings: [
"registryUrl=(?<registryUrl>.*?) chart=(?<depName>.*?)\n *tag: v(?<currentValue>.*)\n",
], ],
datasourceTemplate: "helm", "datasourceTemplate": "helm"
}, },
// regexManager to read and process Rook-Ceph CRD's // regexManager to read and process Rook-Ceph CRD's
{ {
fileMatch: ["cluster/base-custom/crds/rook-ceph/.+\\.yaml$"], "fileMatch": [
matchStrings: [ "cluster/base-custom/crds/rook-ceph/.+\\.yaml$"
],
"matchStrings": [
"registryUrl=(?<registryUrl>.*?) chart=(?<depName>.*?)\n *tag: (?<currentValue>.*)\n", "registryUrl=(?<registryUrl>.*?) chart=(?<depName>.*?)\n *tag: (?<currentValue>.*)\n",
], ],
datasourceTemplate: "helm", "datasourceTemplate": "helm",
}, }
], ],
packageRules: [ "packageRules": [
// Setup datasources // setup datasources
{ {
matchDatasources: ["helm"], "matchDatasources": [
semanticCommitScope: "charts", "helm"
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",
], ],
}, "ignoreDeprecated": true
// 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"],
}, },
{ {
matchDatasources: ["docker"], "matchDatasources": [
versioning: "loose", "docker"
matchPackageNames: ["ghcr.io/k8s-at-home/qbittorrent"], ],
"commitMessageExtra": "to {{newVersion}}"
}, },
// enable auto-merge // custom versioning
{ {
matchDatasources: ["docker"], "matchDatasources": [
automerge: true, "docker"
automergeType: "branch", ],
requiredStatusChecks: null, "versioning": "regex:^(?<major>\\d+)\\.(?<minor>\\d+)\\.(?<patch>\\d+)-(?<compatibility>.*)$",
matchUpdateTypes: ["minor", "patch"], "matchPackageNames": [
matchPackageNames: ["ghcr.io/k8s-at-home/prowlarr-nightly"], "blakeblackshear/frigate"
]
}, },
{ {
matchDatasources: ["helm", "docker"], "matchDatasources": [
matchPackagePatterns: ["^rook.ceph"], "docker"
groupName: "rook-ceph-suite", ],
additionalBranchPrefix: "", "versioning": "regex:^RELEASE\\.(?<major>\\d+)-(?<minor>\\d+)-(?<patch>\\d+)T.*Z(-(?<compatibility>.*))?$",
"matchPackageNames": [
"quay.io/minio/minio"
]
}, },
{ {
matchPackageNames: ["rancher/system-upgrade-controller"], "matchDatasources": [
groupName: "rancher/system-upgrade-controller", "docker"
additionalBranchPrefix: "", ],
separateMinorPatch: true, "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 - certificate
- ingress-nginx - ingress-nginx
- k8s-gateway - k8s-gateway
#- traefik
- unifi - 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 kind: Kustomization
resources: resources:
- cert-manager - cert-manager
- external-snapshotter
- kube-prometheus-stack - kube-prometheus-stack
- rook-ceph - 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 ```console
$ mkdir -p /var/lib/tftpboot/pxelinux/ $ 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 $ 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.2-live-server-amd64.iso` /mnt $ 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/vmlinuz /var/lib/tftpboot/pxelinux/
$ cp /mnt/casper/initrd /var/lib/tftpboot/pxelinux/ $ cp /mnt/casper/initrd /var/lib/tftpboot/pxelinux/
$ umount /mnt $ umount /mnt

View File

@@ -1,16 +1,3 @@
# Server infrastructure # 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. 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
```