diff --git a/cmd/enrichment/enrichment/tasks/webapi/landingpage.py b/cmd/enrichment/enrichment/tasks/webapi/landingpage.py
index 3a29513..5b76059 100644
--- a/cmd/enrichment/enrichment/tasks/webapi/landingpage.py
+++ b/cmd/enrichment/enrichment/tasks/webapi/landingpage.py
@@ -47,8 +47,8 @@ class LandingPageRoutes(Routable):
Main Services
Dashboard
+ Hasura (API)
Kibana
- pgAdmin (Postgres)
RabbitMQ Management UI
Monitoring
diff --git a/kubernetes/hasura/configmap.yml b/kubernetes/hasura/configmap.yml
new file mode 100644
index 0000000..b177597
--- /dev/null
+++ b/kubernetes/hasura/configmap.yml
@@ -0,0 +1,8 @@
+apiVersion: v1
+kind: ConfigMap
+metadata:
+ name: hasura-metadata
+data:
+ # to export: curl -d '{"type": "export_metadata", "args": {}}' http://localhost:8080/v1/metadata -o hasura_metadata.json
+ hasura_metadata.json: |
+ {"version":3,"sources":[{"name":"nemesis","kind":"postgres","tables":[{"table":{"name":"agents","schema":"nemesis"},"object_relationships":[{"name":"host","using":{"foreign_key_constraint_on":"host_id"}}]},{"table":{"name":"api_data_messages","schema":"nemesis"}},{"table":{"name":"authentication_data","schema":"nemesis"}},{"table":{"name":"chromium_cookies","schema":"nemesis"}},{"table":{"name":"chromium_downloads","schema":"nemesis"}},{"table":{"name":"chromium_history","schema":"nemesis"}},{"table":{"name":"chromium_logins","schema":"nemesis"}},{"table":{"name":"chromium_state_files","schema":"nemesis"}},{"table":{"name":"dpapi_blobs","schema":"nemesis"}},{"table":{"name":"dpapi_domain_backupkeys","schema":"nemesis"}},{"table":{"name":"dpapi_masterkeys","schema":"nemesis"}},{"table":{"name":"extracted_hashes","schema":"nemesis"}},{"table":{"name":"file_data_enriched","schema":"nemesis"}},{"table":{"name":"filesystem_objects","schema":"nemesis"},"array_relationships":[{"name":"services","using":{"foreign_key_constraint_on":{"column":"filesystem_object_id","table":{"name":"services","schema":"nemesis"}}}}]},{"table":{"name":"hosts","schema":"nemesis"},"array_relationships":[{"name":"agents","using":{"foreign_key_constraint_on":{"column":"host_id","table":{"name":"agents","schema":"nemesis"}}}}]},{"table":{"name":"named_pipes","schema":"nemesis"}},{"table":{"name":"network_connections","schema":"nemesis"}},{"table":{"name":"notes","schema":"nemesis"}},{"table":{"name":"project_data","schema":"nemesis"},"object_relationships":[{"name":"project","using":{"foreign_key_constraint_on":"project_id"}}]},{"table":{"name":"projects","schema":"nemesis"},"array_relationships":[{"name":"project_data","using":{"foreign_key_constraint_on":{"column":"project_id","table":{"name":"project_data","schema":"nemesis"}}}}]},{"table":{"name":"registry_objects","schema":"nemesis"}},{"table":{"name":"services","schema":"nemesis"},"object_relationships":[{"name":"filesystem_object","using":{"foreign_key_constraint_on":"filesystem_object_id"}}]},{"table":{"name":"slack_downloads","schema":"nemesis"}},{"table":{"name":"slack_workspaces","schema":"nemesis"}},{"table":{"name":"triage","schema":"nemesis"}}],"configuration":{"connection_info":{"database_url":{"from_env":"PG_DATABASE_URL"},"isolation_level":"read-committed","use_prepared_statements":false}}}]}
\ No newline at end of file
diff --git a/kubernetes/hasura/deployment.yaml b/kubernetes/hasura/deployment.yaml
new file mode 100644
index 0000000..b6479f2
--- /dev/null
+++ b/kubernetes/hasura/deployment.yaml
@@ -0,0 +1,82 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: hasura
+ labels:
+ app: hasura
+spec:
+ replicas: 1
+ selector:
+ matchLabels:
+ app: hasura
+ strategy: {}
+ template:
+ metadata:
+ labels:
+ app: hasura
+ spec:
+ containers:
+ - env:
+ - name: POSTGRES_SERVER
+ value: postgres
+ - name: POSTGRES_PORT
+ value: "5432"
+ - name: POSTGRES_DATABASE
+ value: nemesis
+ - name: POSTGRES_USER
+ valueFrom:
+ secretKeyRef:
+ name: postgres-creds
+ key: postgres-user
+ - name: POSTGRES_PASSWORD
+ valueFrom:
+ secretKeyRef:
+ name: postgres-creds
+ key: postgres-password
+ - name: PG_DATABASE_URL
+ value: "postgresql://$(POSTGRES_USER):$(POSTGRES_PASSWORD)@$(POSTGRES_SERVER):$(POSTGRES_PORT)/$(POSTGRES_DATABASE)"
+ - name: HASURA_GRAPHQL_DATABASE_URL
+ value: "postgresql://$(POSTGRES_USER):$(POSTGRES_PASSWORD)@$(POSTGRES_SERVER):$(POSTGRES_PORT)/$(POSTGRES_DATABASE)"
+ - name: HASURA_GRAPHQL_METADATA_DATABASE_URL
+ value: "postgresql://$(POSTGRES_USER):$(POSTGRES_PASSWORD)@$(POSTGRES_SERVER):$(POSTGRES_PORT)/$(POSTGRES_DATABASE)"
+ - name: HASURA_GRAPHQL_ENABLE_CONSOLE
+ value: "true"
+ - name: HASURA_GRAPHQL_DEV_MODE
+ value: "true"
+ - name: HASURA_GRAPHQL_ENABLED_LOG_TYPES
+ value: startup
+ image: hasura/graphql-engine:v2.36.2.cli-migrations-v2
+ imagePullPolicy: IfNotPresent
+ name: hasura
+ ports:
+ - containerPort: 8080
+ name: http
+ livenessProbe:
+ httpGet:
+ path: /healthz
+ port: http
+ initialDelaySeconds: 5
+ timeoutSeconds: 5
+ periodSeconds: 5
+ readinessProbe:
+ httpGet:
+ path: /healthz
+ port: http
+ initialDelaySeconds: 5
+ timeoutSeconds: 5
+ periodSeconds: 5
+ volumeMounts:
+ - name: hasura-metadata
+ mountPath: /opt/hasura/hasura_metadata.json
+ subPath: hasura_metadata.json
+ readOnly: false
+ lifecycle:
+ postStart:
+ exec:
+ command: ["/bin/sh", "-c", "sleep 10 && curl -d '{\"type\":\"replace_metadata\", \"args\":'$(cat /opt/hasura/hasura_metadata.json)'}' http://localhost:8080/v1/metadata"]
+ volumes:
+ - name: hasura-metadata
+ configMap:
+ name: hasura-metadata
+ restartPolicy: Always
+status: {}
diff --git a/kubernetes/hasura/ingress.yaml b/kubernetes/hasura/ingress.yaml
new file mode 100644
index 0000000..bf6f364
--- /dev/null
+++ b/kubernetes/hasura/ingress.yaml
@@ -0,0 +1,23 @@
+apiVersion: networking.k8s.io/v1
+kind: Ingress
+metadata:
+ name: hasura-ingress
+ annotations:
+ nginx.ingress.kubernetes.io/auth-type: basic
+ nginx.ingress.kubernetes.io/auth-secret: basic-auth
+ nginx.ingress.kubernetes.io/auth-realm: 'Authentication Required'
+ nginx.ingress.kubernetes.io/ssl-redirect: "false"
+ nginx.ingress.kubernetes.io/rewrite-target: /$2
+
+spec:
+ ingressClassName: nginx
+ rules:
+ - http:
+ paths:
+ - path: /hasura(/|$)(.*)
+ pathType: ImplementationSpecific
+ backend:
+ service:
+ name: hasura
+ port:
+ number: 8080
\ No newline at end of file
diff --git a/kubernetes/hasura/service.yaml b/kubernetes/hasura/service.yaml
new file mode 100644
index 0000000..364e469
--- /dev/null
+++ b/kubernetes/hasura/service.yaml
@@ -0,0 +1,17 @@
+apiVersion: v1
+kind: Service
+metadata:
+ labels:
+ app: hasura
+ name: hasura
+spec:
+ type: NodePort
+ ports:
+ - name: "8080"
+ port: 8080
+ targetPort: 8080
+ nodePort: 31887
+ selector:
+ app: hasura
+status:
+ loadBalancer: {}
\ No newline at end of file
diff --git a/skaffold.yaml b/skaffold.yaml
index 1820ab8..490a1e6 100644
--- a/skaffold.yaml
+++ b/skaffold.yaml
@@ -112,6 +112,7 @@ manifests:
- &k8s-postgres-deployment kubernetes/postgres/deployment.yaml
- &k8s-postgres-service kubernetes/postgres/service.yaml
- &k8s-pgadmin kubernetes/pgadmin/*
+ - &k8s-hasura kubernetes/hasura/*
- &k8s-tika kubernetes/tika/*
deploy:
@@ -128,6 +129,7 @@ profiles:
- kubernetes/postgres/deployment-dev.yaml
- kubernetes/postgres/service.yaml
- kubernetes/pgadmin/*
+ - kubernetes/hasura/*
- kubernetes/tika/*
# portForward: