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:
		
							
								
								
									
										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) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user