Compare commits
5 Commits
5870ab952f
...
0072307bec
| Author | SHA1 | Date | |
|---|---|---|---|
| 0072307bec | |||
| d36a1e7655 | |||
| e3ed622ade | |||
| 1e7013269e | |||
| 45fd4454fa |
@@ -5,12 +5,15 @@ WORKDIR /app
|
||||
|
||||
COPY update.py /app/update.py
|
||||
COPY entrypoint.sh /app/entrypoint.sh
|
||||
COPY healthcheck.sh /app/healthcheck.sh
|
||||
|
||||
RUN pip install --no-cache-dir requests==2.32.3 \
|
||||
&& chmod +x /app/entrypoint.sh
|
||||
&& chmod +x /app/entrypoint.sh /app/healthcheck.sh
|
||||
|
||||
ENV OUT_DIR=/data
|
||||
VOLUME ["/data"]
|
||||
|
||||
ENTRYPOINT ["/app/entrypoint.sh"]
|
||||
|
||||
HEALTHCHECK --interval=5m --timeout=10s --start-period=30s --retries=3 \
|
||||
CMD /app/healthcheck.sh
|
||||
|
||||
111
Jenkinsfile
vendored
Normal file
111
Jenkinsfile
vendored
Normal file
@@ -0,0 +1,111 @@
|
||||
pipeline {
|
||||
agent any
|
||||
|
||||
environment {
|
||||
GIT_URL = 'https://gitea.mindboost.team/mindboost/education-flagger.git'
|
||||
GIT_BRANCH = 'pipeline/deploy-image'
|
||||
REGISTRY_SCHEME = 'https'
|
||||
REGISTRY_AUTHORITY = 'gitea.mindboost.team'
|
||||
IMAGE_NAME = 'mindboost/education-flagger'
|
||||
REGISTRY_CREDENTIALS_ID = 'REGISTRY_CREDENTIALS_ID'
|
||||
}
|
||||
|
||||
stages {
|
||||
stage('Checkout') {
|
||||
steps {
|
||||
script {
|
||||
checkout([
|
||||
$class: 'GitSCM',
|
||||
branches: [[name: "*/${env.GIT_BRANCH}"]],
|
||||
userRemoteConfigs: [[
|
||||
url: env.GIT_URL,
|
||||
credentialsId: 'b5f383be-8c74-40f9-b7e1-3a9c5856df0e'
|
||||
]]
|
||||
])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stage('Check Repository') {
|
||||
steps {
|
||||
script {
|
||||
sh 'pwd'
|
||||
sh 'ls -la'
|
||||
sh 'git status'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stage('Determine Version') {
|
||||
steps {
|
||||
script {
|
||||
def fullHash = sh(
|
||||
script: 'git rev-parse HEAD',
|
||||
returnStdout: true
|
||||
).trim()
|
||||
env.IMAGE_TAG = "sha256-${fullHash}"
|
||||
echo "Resolved image tag: ${env.IMAGE_TAG}"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stage('Check Docker Image with the same tag') {
|
||||
steps {
|
||||
script {
|
||||
def imageExists = sh(
|
||||
script: "docker images -q ${env.IMAGE_NAME}:${env.IMAGE_TAG} || true",
|
||||
returnStdout: true
|
||||
).trim()
|
||||
|
||||
if (imageExists) {
|
||||
echo "Docker Image mit Tag ${env.IMAGE_TAG} existiert bereits. Überspringe Build."
|
||||
currentBuild.result = 'SUCCESS'
|
||||
return
|
||||
} else {
|
||||
echo "Kein vorhandenes Docker Image gefunden. Baue neues Image..."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stage('Build Docker Image') {
|
||||
when {
|
||||
expression { currentBuild.result == null }
|
||||
}
|
||||
steps {
|
||||
script {
|
||||
sh "docker build --rm -t ${env.IMAGE_NAME}:${env.IMAGE_TAG} ."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stage('Push Docker Image') {
|
||||
when {
|
||||
expression { currentBuild.result == null }
|
||||
}
|
||||
steps {
|
||||
script {
|
||||
withCredentials([usernamePassword(
|
||||
credentialsId: env.REGISTRY_CREDENTIALS_ID,
|
||||
usernameVariable: 'REGISTRY_USER',
|
||||
passwordVariable: 'REGISTRY_PASS'
|
||||
)]) {
|
||||
def registryEndpoint = "${env.REGISTRY_SCHEME}://${env.REGISTRY_AUTHORITY}"
|
||||
sh "echo '${REGISTRY_PASS}' | docker login ${env.REGISTRY_AUTHORITY} -u '${REGISTRY_USER}' --password-stdin"
|
||||
sh "docker tag ${env.IMAGE_NAME}:${env.IMAGE_TAG} ${env.REGISTRY_AUTHORITY}/${env.IMAGE_NAME}:${env.IMAGE_TAG}"
|
||||
sh "docker push ${env.REGISTRY_AUTHORITY}/${env.IMAGE_NAME}:${env.IMAGE_TAG}"
|
||||
sh "docker logout ${env.REGISTRY_AUTHORITY}"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stage('Cleanup Docker Images') {
|
||||
steps {
|
||||
script {
|
||||
sh 'set -eux; docker image prune -f; docker builder prune -f'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
17
README.md
17
README.md
@@ -69,6 +69,23 @@ Die dafür vorgesehenen Labels sind:
|
||||
|
||||
Bitte füge diese zu dem Service hinzu, bei welchem man die gewünschten Header möchte.
|
||||
|
||||
## Run/Deploy (kurz)
|
||||
|
||||
1. `example.env` kopieren und als `.env` befüllen (mindestens `MAXMIND_LICENSE_KEY`).
|
||||
2. Den Updater-Container starten und `OUT_DIR` als Volume mounten (z. B. `/data`).
|
||||
3. Den ASN-Detection-Service so starten, dass er **denselben** `OUT_DIR` liest.
|
||||
4. Traefik ForwardAuth aktivieren und `authResponseHeaders` durchreichen.
|
||||
5. Nach dem ersten Update sollten `GeoLite2-ASN.mmdb` und `nren_asns.txt` im `OUT_DIR` liegen.
|
||||
|
||||
## example.env (kurz erklärt)
|
||||
|
||||
- `MAXMIND_LICENSE_KEY`: notwendig für den GeoLite2 Download.
|
||||
- `PDB_API_KEY`: optional, reduziert PeeringDB Rate-Limits.
|
||||
- `OUT_DIR`: gemeinsamer Datenpfad zwischen Updater und Detection-Service.
|
||||
- `PDB_BASE`, `PDB_INFO_TYPE`, `PDB_LIMIT`: PeeringDB Filter.
|
||||
- `HTTP_TIMEOUT`: Timeout pro HTTP-Request.
|
||||
- `INTERVAL_SECONDS`: Update-Intervall (Standard 30 Tage).
|
||||
|
||||
## Update-Strategie
|
||||
|
||||
- monatliche Aktualisierung der ASN-Daten
|
||||
|
||||
19
example.env
Normal file
19
example.env
Normal file
@@ -0,0 +1,19 @@
|
||||
# Required
|
||||
MAXMIND_LICENSE_KEY=
|
||||
|
||||
# Optional (helps with rate limits)
|
||||
PDB_API_KEY=
|
||||
|
||||
# Output data location shared with the detection service
|
||||
OUT_DIR=/data
|
||||
|
||||
# PeeringDB settings
|
||||
PDB_BASE=https://www.peeringdb.com
|
||||
PDB_INFO_TYPE=Educational/Research
|
||||
PDB_LIMIT=250
|
||||
|
||||
# HTTP settings
|
||||
HTTP_TIMEOUT=30
|
||||
|
||||
# Update interval (seconds, default 30 days)
|
||||
INTERVAL_SECONDS=2592000
|
||||
49
healthcheck.sh
Normal file
49
healthcheck.sh
Normal file
@@ -0,0 +1,49 @@
|
||||
#!/bin/sh
|
||||
set -eu
|
||||
|
||||
OUT_DIR="${OUT_DIR:-/data}"
|
||||
PDB_BASE="${PDB_BASE:-https://www.peeringdb.com}"
|
||||
INFO_TYPE="${PDB_INFO_TYPE:-Educational/Research}"
|
||||
|
||||
if [ -z "${MAXMIND_LICENSE_KEY:-}" ]; then
|
||||
echo "[health] MAXMIND_LICENSE_KEY missing" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -d "${OUT_DIR}" ]; then
|
||||
echo "[health] OUT_DIR missing: ${OUT_DIR}" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -s "${OUT_DIR}/GeoLite2-ASN.mmdb" ]; then
|
||||
echo "[health] GeoLite2-ASN.mmdb missing in ${OUT_DIR}" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -s "${OUT_DIR}/nren_asns.txt" ]; then
|
||||
echo "[health] nren_asns.txt missing in ${OUT_DIR}" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
mm_url="https://download.maxmind.com/app/geoip_download?edition_id=GeoLite2-ASN&license_key=${MAXMIND_LICENSE_KEY}&suffix=tar.gz"
|
||||
mm_code="$(curl -fsS -o /dev/null -w "%{http_code}" "${mm_url}" || true)"
|
||||
if [ "${mm_code}" != "200" ]; then
|
||||
echo "[health] MaxMind download not accessible (status ${mm_code})" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
pdb_code="000"
|
||||
pdb_url="${PDB_BASE}/api/net"
|
||||
pdb_args="--get --data-urlencode info_type=${INFO_TYPE} --data-urlencode limit=1 --data-urlencode skip=0 --data-urlencode fields=asn,status,info_type"
|
||||
if [ -n "${PDB_API_KEY:-}" ]; then
|
||||
pdb_code="$(curl -fsS -o /dev/null -w "%{http_code}" -H "Accept: application/json" -H "Authorization: Api-Key ${PDB_API_KEY}" ${pdb_args} "${pdb_url}" || true)"
|
||||
else
|
||||
pdb_code="$(curl -fsS -o /dev/null -w "%{http_code}" -H "Accept: application/json" ${pdb_args} "${pdb_url}" || true)"
|
||||
fi
|
||||
|
||||
if [ "${pdb_code}" != "200" ] && [ "${pdb_code}" != "429" ]; then
|
||||
echo "[health] PeeringDB not accessible (status ${pdb_code})" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
exit 0
|
||||
@@ -5,7 +5,7 @@ OUT_DIR = os.getenv("OUT_DIR", "/data")
|
||||
LICENSE_KEY = os.getenv("MAXMIND_LICENSE_KEY", "").strip()
|
||||
PDB_API_KEY = os.getenv("PDB_API_KEY", "").strip()
|
||||
PDB_BASE = os.getenv("PDB_BASE", "https://www.peeringdb.com")
|
||||
INFO_TYPE = os.getenv("PDB_INFO_TYPE", "Research and Education")
|
||||
INFO_TYPE = os.getenv("PDB_INFO_TYPE", "Educational/Research")
|
||||
TIMEOUT = int(os.getenv("HTTP_TIMEOUT", "30"))
|
||||
LIMIT = int(os.getenv("PDB_LIMIT", "250"))
|
||||
|
||||
@@ -49,7 +49,7 @@ def pdb_headers():
|
||||
if not PDB_API_KEY:
|
||||
return {"Accept": "application/json"}
|
||||
# PeeringDB API Key (optional)
|
||||
return {"Accept": "application/json", "Authorization": f"api-key {PDB_API_KEY}"}
|
||||
return {"Accept": "application/json", "Authorization": f"Api-Key {PDB_API_KEY}"}
|
||||
|
||||
def fetch_pdb_page(skip: int):
|
||||
url = f"{PDB_BASE}/api/net"
|
||||
@@ -105,4 +105,3 @@ def main():
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user