Fix application specific password handling
All checks were successful
continuous-integration/drone Build is passing
All checks were successful
continuous-integration/drone Build is passing
This commit is contained in:
parent
8a39056599
commit
817acc3ecf
44
deployment.yaml
Normal file
44
deployment.yaml
Normal file
@ -0,0 +1,44 @@
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: wildduck-exporter
|
||||
namespace: wildduck
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: wildduck-exporter
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: wildduck-exporter
|
||||
spec:
|
||||
containers:
|
||||
- name: wildduck-exporter
|
||||
image: harbor.k-space.ee/k-space/wildduck-exporter
|
||||
securityContext:
|
||||
readOnlyRootFilesystem: true
|
||||
runAsNonRoot: true
|
||||
runAsUser: 65534
|
||||
command:
|
||||
- /wildduck_exporter.py
|
||||
args:
|
||||
- info
|
||||
- accounting
|
||||
ports:
|
||||
- containerPort: 3001
|
||||
name: metrics
|
||||
env:
|
||||
- name: MONGODB_HOST
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: wildduck
|
||||
key: MONGO_URI
|
||||
- name: PROMETHEUS_BEARER_TOKEN
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: wildduck-exporter
|
||||
key: PROMETHEUS_BEARER_TOKEN
|
||||
imagePullSecrets:
|
||||
- name: regcred
|
18
skaffold.yaml
Normal file
18
skaffold.yaml
Normal file
@ -0,0 +1,18 @@
|
||||
---
|
||||
apiVersion: skaffold/v3
|
||||
kind: Config
|
||||
metadata:
|
||||
name: wildduck-exporter
|
||||
build:
|
||||
artifacts:
|
||||
- docker:
|
||||
dockerfile: Dockerfile
|
||||
image: harbor.k-space.ee/k-space/wildduck-exporter
|
||||
deploy:
|
||||
kubectl:
|
||||
flags:
|
||||
global:
|
||||
- --namespace=wildduck
|
||||
manifests:
|
||||
rawYaml:
|
||||
- deployment.yaml
|
@ -1,7 +1,9 @@
|
||||
#!/usr/bin/env python3
|
||||
import os
|
||||
import sys
|
||||
from motor.motor_asyncio import AsyncIOMotorClient
|
||||
from sanic import Sanic, response, exceptions
|
||||
from sanic import Sanic, exceptions
|
||||
from sanic.log import logger
|
||||
|
||||
MONGODB_HOST = os.getenv("MONGODB_HOST")
|
||||
if not MONGODB_HOST:
|
||||
@ -12,6 +14,7 @@ if not PROMETHEUS_BEARER_TOKEN:
|
||||
raise ValueError("No PROMETHEUS_BEARER_TOKEN specified")
|
||||
|
||||
app = Sanic("exporter")
|
||||
usernames = list(set(sys.argv[1:]))
|
||||
|
||||
|
||||
@app.listener("before_server_start")
|
||||
@ -32,30 +35,44 @@ async def wrap(i, prefix="wildduck_"):
|
||||
|
||||
|
||||
async def fetch():
|
||||
async for u in app.ctx.db.users.find():
|
||||
last_login = {}
|
||||
user_labels = {}
|
||||
args = []
|
||||
if usernames:
|
||||
args.append({"username": {"$in": usernames}})
|
||||
async for u in app.ctx.db.users.find(*args):
|
||||
labels = {
|
||||
"username": u["username"],
|
||||
"email": u["address"],
|
||||
}
|
||||
user_labels[u["_id"]] = labels
|
||||
|
||||
if u["lastLogin"]["time"]:
|
||||
yield "last_login", "gauge", u["lastLogin"]["time"].timestamp(), labels
|
||||
last_login[u["_id"]] = u["lastLogin"]["time"]
|
||||
|
||||
if u["storageUsed"]:
|
||||
yield "storage_used", "gauge", u["storageUsed"], labels
|
||||
if u["targets"]:
|
||||
yield "forwarding_addresses", "gauge", len(u["targets"]), labels
|
||||
yield "account_enabled", "gauge", not u["disabled"], labels
|
||||
|
||||
# Merge application specific passwords last used timestamps
|
||||
async for a in app.ctx.db.asps.find({"user": {"$in": list(last_login.keys())}}):
|
||||
if a["used"] > last_login[a["user"]]:
|
||||
last_login[a["user"]] = a["used"]
|
||||
|
||||
for user, dt in last_login.items():
|
||||
yield "last_login", "gauge", dt.timestamp(), user_labels[user]
|
||||
|
||||
|
||||
@app.route("/metrics")
|
||||
async def view_export(request):
|
||||
if request.token != PROMETHEUS_BEARER_TOKEN:
|
||||
raise exceptions.Forbidden("Invalid bearer token")
|
||||
response = await request.respond(content_type="text/plain")
|
||||
async for line in wrap(fetch()):
|
||||
await response.send(line + "\n")
|
||||
|
||||
async def streaming_fn(response):
|
||||
async for line in wrap(fetch()):
|
||||
await response.write(line + "\n")
|
||||
|
||||
return response.stream(streaming_fn, content_type="text/plain")
|
||||
|
||||
if __name__ == "__main__":
|
||||
app.run(host="0.0.0.0", port=3001, single_process=True)
|
||||
|
Loading…
Reference in New Issue
Block a user