Skip to content

Commit 1a7684f

Browse files
committed
add Go-Services
1 parent fffcfc2 commit 1a7684f

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+1727
-64
lines changed

.terraformignore

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
# Terraform state and backup files
2+
*.tfstate
3+
*.tfstate.backup
4+
*.tfplan
5+
6+
# Terraform internal directories
7+
.terraform/
8+
9+
# Logs and debug artifacts
10+
*.log
11+
crash.log
12+
*.out
13+
*.err
14+
15+
# AWS credentials and sensitive files
16+
.aws/
17+
*.pem
18+
*.key
19+
*.crt
20+
*.env
21+
.env.*
22+
credentials.json
23+
secrets/
24+
**/credentials.tfvars
25+
26+
# Python artifacts
27+
__pycache__/
28+
*.pyc
29+
*.pyo
30+
*.pyd
31+
*.egg-info/
32+
*.dist-info/
33+
*.ipynb_checkpoints/
34+
*.sqlite3
35+
*.db
36+
.venv/
37+
venv/
38+
env/
39+
40+
# Docker build cache and local overrides
41+
Dockerfile.*
42+
docker-compose.override.yml
43+
*.tar
44+
*.img
45+
46+
# Node-related (if present)
47+
node_modules/
48+
npm-debug.log
49+
yarn-error.log
50+
51+
# Editor/OS/CI-related
52+
.idea/
53+
.vscode/
54+
*.swp
55+
*.swo
56+
*.bak
57+
*.tmp
58+
.DS_Store
59+
Thumbs.db
60+
61+
# Git
62+
.git/
63+
.gitignore
64+
.gitattributes
65+
66+
# Tests & coverage (optional)
67+
coverage/
68+
tests/__pycache__/
69+
test-results/
70+
71+
# Model cache (if using Hugging Face Transformers)
72+
model_cache/
73+
transformers_cache/
74+
huggingface/

Jenkinsfile

Lines changed: 13 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,25 @@
11
pipeline {
22
agent any
33
environment {
4-
// Set environment variables
54
ECR_REGISTRY = credentials('ecr-registry-uri')
65
AWS_REGION = 'eu-central-1'
76
DOCKER_TAG = 'latest'
87
}
98
stages {
109
stage('Build and Push ai-agent') {
11-
agent {
12-
docker {
13-
image 'docker:24-dind'
14-
args '--privileged'
15-
reuseNode true
16-
}
17-
}
18-
when {
19-
changeset "ai-agent/**"
20-
}
10+
agent { docker { image 'docker:24-dind'; args '--privileged'; reuseNode true } }
11+
when { changeset "ai-agent/**" }
2112
steps {
22-
withAWS(credentials: 'aws-credentials', region: "${AWS_REGION}") { // AWS creds stored in Jenkins
13+
withAWS(credentials: 'aws-credentials', region: "${AWS_REGION}") {
2314
sh 'aws ecr get-login-password --region ${AWS_REGION} | docker login --username AWS --password-stdin ${ECR_REGISTRY}'
2415
sh 'docker build -t ${ECR_REGISTRY}/ai-agent:${DOCKER_TAG} ./ai-agent'
2516
sh 'docker push ${ECR_REGISTRY}/ai-agent:${DOCKER_TAG}'
2617
}
2718
}
2819
}
2920
stage('Build and Push Go Microservices') {
30-
agent {
31-
docker {
32-
image 'docker:24-dind'
33-
args '--privileged'
34-
reuseNode true
35-
}
36-
}
37-
when {
38-
anyOf {
39-
changeset "go-services/blockchain-monitor/**"
40-
changeset "go-services/anomaly-detector/**"
41-
}
42-
}
21+
agent { docker { image 'docker:24-dind'; args '--privileged'; reuseNode true } }
22+
when { anyOf { changeset "go-services/blockchain-monitor/**"; changeset "go-services/anomaly-detector/**" } }
4323
steps {
4424
withAWS(credentials: 'aws-credentials', region: "${AWS_REGION}") {
4525
sh 'aws ecr get-login-password --region ${AWS_REGION} | docker login --username AWS --password-stdin ${ECR_REGISTRY}'
@@ -54,20 +34,12 @@ pipeline {
5434
}
5535
}
5636
stage('Build and Push Dashboard') {
57-
agent {
58-
docker {
59-
image 'docker:24-dind'
60-
args '--privileged'
61-
reuseNode true
62-
}
63-
}
64-
when {
65-
changeset "dashboard/**"
66-
}
37+
agent { docker { image 'docker:24-dind'; args '--privileged'; reuseNode true } }
38+
when { changeset "dashboard/**" }
6739
steps {
6840
withAWS(credentials: 'aws-credentials', region: "${AWS_REGION}") {
6941
sh 'aws ecr get-login-password --region ${AWS_REGION} | docker login --username AWS --password-stdin ${ECR_REGISTRY}'
70-
sh 'docker build -t ${ECR_REGISTRY}/dashboard:${DOCKER_TAG} ./dashboard'
42+
sh 'docker build -t ${ECR_REGISTRY}/dashboard:${DOCKER_TAG} ./dashboard' // Adjust if merged with anomaly-detector
7143
sh 'docker push ${ECR_REGISTRY}/dashboard:${DOCKER_TAG}'
7244
}
7345
}
@@ -76,19 +48,15 @@ pipeline {
7648
steps {
7749
withAWS(credentials: 'aws-credentials', region: "${AWS_REGION}") {
7850
sh 'helm upgrade --install ai-agent ./helm/ai-agent --namespace default --set image.repository=${ECR_REGISTRY}/ai-agent'
79-
sh 'helm upgrade --install blockchain-monitor ./helm/go-microservices/blockchain-monitor --namespace default'
80-
sh 'helm upgrade --install anomaly-detector ./helm/go-microservices/anomaly-detector --namespace default'
81-
sh 'helm upgrade --install dashboard ./helm/dashboard --namespace default'
51+
sh 'helm upgrade --install blockchain-monitor ./helm/go-microservices/blockchain-monitor --namespace default --set image.repository=${ECR_REGISTRY}/blockchain-monitor'
52+
sh 'helm upgrade --install anomaly-detector ./helm/go-microservices/anomaly-detector --namespace default --set image.repository=${ECR_REGISTRY}/anomaly-detector'
53+
sh 'helm upgrade --install dashboard ./helm/dashboard --namespace default --set image.repository=${ECR_REGISTRY}/dashboard'
8254
}
8355
}
8456
}
8557
}
8658
post {
87-
always {
88-
sh 'echo "Pipeline complete!"'
89-
}
90-
failure {
91-
echo 'Build failed!'
92-
}
59+
always { sh 'echo "Pipeline complete!"' }
60+
failure { echo 'Build failed!' }
9361
}
9462
}

ai-agent/Dockerfile

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,18 @@
22
FROM python:3.12-slim AS builder
33
WORKDIR /app
44
COPY requirements.txt .
5-
RUN pip install --no-cache-dir -r requirements.txt
5+
RUN pip install --no-cache-dir -r requirements.txt && \
6+
pip install --no-cache-dir hf_xet
67

78
# Stage 2: Runtime image
89
FROM python:3.12-slim
910
WORKDIR /home/appuser/app
1011
COPY --from=builder /usr/local/lib/python3.12/site-packages/ /usr/local/lib/python3.12/site-packages/
1112
COPY --from=builder /usr/local/bin/ /usr/local/bin/
1213
COPY ai_agent.py .
13-
RUN useradd -m appuser && chown -R appuser:appuser /home/appuser/app
14+
RUN useradd -m appuser && \
15+
mkdir -p /home/appuser/.cache && \
16+
chown -R appuser:appuser /home/appuser
1417
USER appuser
1518
HEALTHCHECK --interval=30s --timeout=3s \
1619
CMD curl -f http://localhost:8000/health || exit 1

ai-agent/ai_agent.py

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import os
33
import re
44
import hvac
5+
import subprocess
56
from fastapi import FastAPI, HTTPException
67
from pydantic import BaseModel
78
from transformers import AutoTokenizer, AutoModelForSequenceClassification
@@ -78,6 +79,14 @@ def analyze(self, tx_data, web3):
7879
else:
7980
return f"Normal Transaction (Score: {anomaly_score:.2f})"
8081

82+
# Ensure hf_xet is installed
83+
def ensure_hf_xet():
84+
try:
85+
import hf_xet
86+
logger.info("hf_xet package is already installed")
87+
except ImportError:
88+
logger.warning("hf_xet not installed in image, expected pre-installation. Falling back to HTTP download.")
89+
8190
# Health endpoint
8291
@app.get("/health")
8392
async def health_check():
@@ -99,7 +108,8 @@ async def health_check():
99108
# Vault client setup
100109
@lru_cache(maxsize=1)
101110
def get_vault_client():
102-
client = hvac.Client(url="http://vault.vault.svc.cluster.local:8200")
111+
vault_addr = os.environ.get("VAULT_ADDR", "http://vault:8200")
112+
client = hvac.Client(url=vault_addr)
103113
client.token = os.environ.get("VAULT_AUTH_TOKEN")
104114
if not client.is_authenticated():
105115
raise Exception("Vault authentication failed")
@@ -116,7 +126,7 @@ def get_infura_key():
116126
if api_key.startswith("https://"):
117127
logger.warning("Infura key from Vault appears to be a full URL - extracting key")
118128
api_key = api_key.split("/")[-1]
119-
os.environ["INFURA_API_KEY"] = api_key # For redaction in logs
129+
os.environ["INFURA_API_KEY"] = api_key
120130
logger.info("Infura key retrieved from Vault")
121131
return api_key
122132
except Exception as e:
@@ -209,6 +219,7 @@ async def analyze_transaction(tx: Transaction):
209219
@app.on_event("startup")
210220
async def startup_event():
211221
try:
222+
ensure_hf_xet() # Ensure hf_xet is installed
212223
web3 = connect_web3()
213224
ai_model = AIModel.get_instance()
214225
logger.info("Starting blockchain polling and historical fetch in background")
@@ -240,4 +251,3 @@ async def poll_blockchain(web3):
240251
if __name__ == "__main__":
241252
import uvicorn
242253
uvicorn.run(app, host="0.0.0.0", port=8000)
243-

ai-agent/requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,4 @@ gunicorn==23.0.0
1212
hvac==2.3.0
1313
psycopg2-binary==2.9.10
1414
pydantic==2.10.6
15+
huggingface-hub[hf_xet]

docker-compose.yml

Lines changed: 69 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,76 @@
11
services:
2+
vault:
3+
image: hashicorp/vault:1.19.0
4+
container_name: vault
5+
ports:
6+
- "8200:8200"
7+
environment:
8+
- VAULT_DEV_ROOT_TOKEN_ID=myroot
9+
- VAULT_DEV_LISTEN_ADDRESS=0.0.0.0:8200
10+
command: server -dev
11+
cap_add:
12+
- IPC_LOCK
13+
healthcheck:
14+
test: ["CMD", "vault", "status", "-address=http://localhost:8200"]
15+
interval: 5s
16+
timeout: 2s
17+
retries: 10
18+
19+
blockchain-monitor:
20+
build:
21+
context: ./go-services/blockchain-monitor
22+
dockerfile: Dockerfile
23+
container_name: blockchain-monitor
24+
ports:
25+
- "8081:8081"
26+
environment:
27+
- PORT=8081
28+
- VAULT_ADDR=http://vault:8200
29+
- VAULT_TOKEN=myroot
30+
depends_on:
31+
vault:
32+
condition: service_healthy
33+
command: "sh -c 'sleep 15 && ./blockchain-monitor'"
34+
anomaly-detector:
35+
build:
36+
context: ./go-services/anomaly-detector
37+
dockerfile: Dockerfile
38+
container_name: anomaly-detector
39+
ports:
40+
- "8082:8082"
41+
environment:
42+
- PORT=8082
43+
- VAULT_ADDR=http://vault:8200
44+
- VAULT_TOKEN=myroot
45+
depends_on:
46+
- vault
47+
48+
dashboard:
49+
build:
50+
context: ./go-services/dashboard
51+
dockerfile: Dockerfile
52+
container_name: dashboard
53+
ports:
54+
- "8083:8083"
55+
environment:
56+
- PORT=8083
57+
- VAULT_ADDR=http://vault:8200
58+
- VAULT_TOKEN=myroot
59+
depends_on:
60+
- vault
61+
262
ai-agent:
363
build:
464
context: ./ai-agent
565
dockerfile: Dockerfile
6-
image: ${DOCKER_USERNAME}/ai-agent:${TAG}
66+
container_name: ai-agent
767
ports:
8-
- "8000:8000" # Exposes FastAPI API
9-
user: "1000:1000" # Run as non-root user
68+
- "8000:8000"
1069
environment:
11-
- AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID}
12-
- AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY}
13-
- AWS_REGION=eu-central-1
14-
restart: unless-stopped
15-
networks:
16-
- ai-network
17-
18-
networks:
19-
ai-network:
20-
driver: bridge
70+
- PORT=8000
71+
- VAULT_ADDR=http://vault:8200
72+
- VAULT_AUTH_TOKEN=myroot
73+
depends_on:
74+
vault:
75+
condition: service_healthy
76+
command: "sh -c 'sleep 15 && gunicorn -k uvicorn.workers.UvicornWorker ai_agent:app'"
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# Stage 1: Build the application
2+
FROM golang:1.24 AS builder
3+
4+
WORKDIR /app
5+
6+
COPY go.mod go.sum ./
7+
8+
RUN go mod download
9+
10+
COPY . .
11+
12+
RUN CGO_ENABLED=0 GOOS=linux go build -o anomaly-detector
13+
14+
# Stage 2: Copy the application to the runtime image
15+
FROM alpine:latest
16+
17+
WORKDIR /app
18+
19+
COPY --from=builder /app/anomaly-detector .
20+
21+
EXPOSE 8082
22+
23+
CMD ["./anomaly-detector"]

0 commit comments

Comments
 (0)