Initial commit: loc_az_hci (smom-dbis-138 excluded via .gitignore)
Some checks failed
Test / test (push) Has been cancelled

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
defiQUG
2026-02-08 09:04:46 -08:00
commit c39465c2bd
386 changed files with 50649 additions and 0 deletions

122
gitops/README.md Normal file
View File

@@ -0,0 +1,122 @@
# GitOps Configuration
This directory contains GitOps manifests for Flux to manage infrastructure and applications.
## Structure
```
gitops/
├── infrastructure/ # Base infrastructure (namespaces, RBAC, etc.)
└── apps/ # Application deployments
├── besu/
├── firefly/
├── chainlink/
├── blockscout/
├── cacti/
└── nginx-proxy/
```
## Setup Instructions
### Prerequisites
1. Gitea must be configured and accessible
2. Flux must be installed in the K3s cluster
3. Git repository must be created in Gitea
### Steps
1. **Create Git Repository in Gitea:**
- Access Gitea: http://192.168.1.121:3000
- Create new repository: `gitops`
- Initialize with README
2. **Push GitOps Manifests:**
```bash
git clone http://192.168.1.121:3000/hc-stack/gitops.git
cd gitops
# Copy manifests from this directory
git add .
git commit -m "Initial GitOps configuration"
git push
```
3. **Configure Flux GitRepository:**
```bash
ssh ubuntu@192.168.1.188
export KUBECONFIG=/etc/rancher/k3s/k3s.yaml
# Create GitRepository
sudo kubectl apply -f - <<EOF
apiVersion: source.toolkit.fluxcd.io/v1beta2
kind: GitRepository
metadata:
name: gitops-repo
namespace: flux-system
spec:
interval: 1m
url: http://192.168.1.121:3000/hc-stack/gitops.git
ref:
branch: main
EOF
```
4. **Create Kustomizations:**
```bash
# Infrastructure Kustomization
sudo kubectl apply -f - <<EOF
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
name: infrastructure
namespace: flux-system
spec:
interval: 5m
path: ./infrastructure
prune: true
sourceRef:
kind: GitRepository
name: gitops-repo
EOF
# Applications Kustomization
sudo kubectl apply -f - <<EOF
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
name: applications
namespace: flux-system
spec:
interval: 5m
path: ./apps
prune: true
sourceRef:
kind: GitRepository
name: gitops-repo
EOF
```
5. **Monitor Reconciliation:**
```bash
sudo kubectl get gitrepository -n flux-system
sudo kubectl get kustomization -n flux-system
sudo kubectl logs -n flux-system -l app=kustomize-controller -f
```
## Notes
- If Gitea requires authentication, create a secret:
```bash
sudo kubectl create secret generic gitops-repo-auth \
--from-literal=username=<username> \
--from-literal=password=<token> \
-n flux-system
```
Then update GitRepository to reference the secret:
```yaml
spec:
secretRef:
name: gitops-repo-auth
```

1
gitops/apps/README.md Normal file
View File

@@ -0,0 +1 @@
# Application manifests

View File

@@ -0,0 +1,13 @@
apiVersion: v2
name: besu
description: Hyperledger Besu Ethereum client Helm chart
type: application
version: 1.0.0
appVersion: "23.10.0"
keywords:
- blockchain
- ethereum
- besu
maintainers:
- name: HC Stack Team

View File

@@ -0,0 +1,61 @@
{{/*
Expand the name of the chart.
*/}}
{{- define "besu.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Create a default fully qualified app name.
*/}}
{{- define "besu.fullname" -}}
{{- if .Values.fullnameOverride }}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- $name := default .Chart.Name .Values.nameOverride }}
{{- if contains $name .Release.Name }}
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- end }}
{{- end }}
{{/*
Create chart name and version as used by the chart label.
*/}}
{{- define "besu.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Common labels
*/}}
{{- define "besu.labels" -}}
helm.sh/chart: {{ include "besu.chart" . }}
{{ include "besu.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}
{{/*
Selector labels
*/}}
{{- define "besu.selectorLabels" -}}
app.kubernetes.io/name: {{ include "besu.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}
{{/*
Create the name of the service account to use
*/}}
{{- define "besu.serviceAccountName" -}}
{{- if .Values.serviceAccount.create }}
{{- default (include "besu.fullname" .) .Values.serviceAccount.name }}
{{- else }}
{{- default "default" .Values.serviceAccount.name }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,103 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "besu.fullname" . }}
labels:
{{- include "besu.labels" . | nindent 4 }}
spec:
{{- if not .Values.autoscaling.enabled }}
replicas: {{ .Values.replicaCount }}
{{- end }}
selector:
matchLabels:
{{- include "besu.selectorLabels" . | nindent 6 }}
template:
metadata:
{{- with .Values.podAnnotations }}
annotations:
{{- toYaml . | nindent 8 }}
{{- end }}
labels:
{{- include "besu.selectorLabels" . | nindent 8 }}
spec:
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
serviceAccountName: {{ include "besu.serviceAccountName" . }}
securityContext:
{{- toYaml .Values.podSecurityContext | nindent 8 }}
containers:
- name: {{ .Chart.Name }}
securityContext:
{{- toYaml .Values.securityContext | nindent 12 }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
command:
- /bin/sh
- -c
- |
besu --data-path={{ .Values.config.dataDir }} \
--network={{ .Values.config.network }} \
--rpc-http-enabled={{ .Values.config.rpcHttpEnabled }} \
--rpc-http-host={{ .Values.config.rpcHttpHost }} \
--rpc-http-port={{ .Values.config.rpcHttpPort }} \
--rpc-http-apis={{ join "," .Values.config.rpcHttpApis }} \
--rpc-ws-enabled={{ .Values.config.rpcWsEnabled }} \
--rpc-ws-host={{ .Values.config.rpcWsHost }} \
--rpc-ws-port={{ .Values.config.rpcWsPort }} \
--p2p-enabled={{ .Values.config.p2pEnabled }} \
--p2p-port={{ .Values.config.p2pPort }} \
--metrics-enabled={{ .Values.config.metricsEnabled }} \
--metrics-port={{ .Values.config.metricsPort }}
ports:
- name: http-rpc
containerPort: {{ .Values.service.rpcPort }}
protocol: TCP
- name: ws-rpc
containerPort: {{ .Values.service.wsPort }}
protocol: TCP
- name: p2p
containerPort: {{ .Values.service.p2pPort }}
protocol: TCP
- name: metrics
containerPort: {{ .Values.config.metricsPort }}
protocol: TCP
livenessProbe:
httpGet:
path: /liveness
port: http-rpc
initialDelaySeconds: 60
periodSeconds: 30
readinessProbe:
httpGet:
path: /readiness
port: http-rpc
initialDelaySeconds: 30
periodSeconds: 10
resources:
{{- toYaml .Values.resources | nindent 12 }}
volumeMounts:
- name: data
mountPath: {{ .Values.config.dataDir }}
volumes:
- name: data
{{- if .Values.persistence.enabled }}
persistentVolumeClaim:
claimName: {{ include "besu.fullname" . }}-data
{{- else }}
emptyDir: {}
{{- end }}
{{- with .Values.nodeSelector }}
nodeSelector:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.affinity }}
affinity:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.tolerations }}
tolerations:
{{- toYaml . | nindent 8 }}
{{- end }}

View File

@@ -0,0 +1,42 @@
{{- if .Values.ingress.enabled -}}
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{ include "besu.fullname" . }}
labels:
{{- include "besu.labels" . | nindent 4 }}
{{- with .Values.ingress.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
{{- if .Values.ingress.className }}
ingressClassName: {{ .Values.ingress.className }}
{{- end }}
{{- if .Values.ingress.tls }}
tls:
{{- range .Values.ingress.tls }}
- hosts:
{{- range .hosts }}
- {{ . | quote }}
{{- end }}
secretName: {{ .secretName }}
{{- end }}
{{- end }}
rules:
{{- range .Values.ingress.hosts }}
- host: {{ .host | quote }}
http:
paths:
{{- range .paths }}
- path: {{ .path }}
pathType: {{ .pathType }}
backend:
service:
name: {{ include "besu.fullname" $ }}
port:
number: {{ $.Values.service.port }}
{{- end }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,18 @@
{{- if .Values.persistence.enabled }}
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: {{ include "besu.fullname" . }}-data
labels:
{{- include "besu.labels" . | nindent 4 }}
spec:
accessModes:
- {{ .Values.persistence.accessMode }}
{{- if .Values.persistence.storageClass }}
storageClassName: {{ .Values.persistence.storageClass }}
{{- end }}
resources:
requests:
storage: {{ .Values.persistence.size }}
{{- end }}

View File

@@ -0,0 +1,24 @@
apiVersion: v1
kind: Service
metadata:
name: {{ include "besu.fullname" . }}
labels:
{{- include "besu.labels" . | nindent 4 }}
spec:
type: {{ .Values.service.type }}
ports:
- port: {{ .Values.service.port }}
targetPort: http-rpc
protocol: TCP
name: http-rpc
- port: {{ .Values.service.wsPort }}
targetPort: ws-rpc
protocol: TCP
name: ws-rpc
- port: {{ .Values.service.p2pPort }}
targetPort: p2p
protocol: TCP
name: p2p
selector:
{{- include "besu.selectorLabels" . | nindent 4 }}

View File

@@ -0,0 +1,13 @@
{{- if .Values.serviceAccount.create -}}
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ include "besu.serviceAccountName" . }}
labels:
{{- include "besu.labels" . | nindent 4 }}
{{- with .Values.serviceAccount.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,90 @@
replicaCount: 1
image:
repository: hyperledger/besu
pullPolicy: IfNotPresent
tag: "23.10.0"
nameOverride: ""
fullnameOverride: ""
serviceAccount:
create: true
annotations: {}
name: ""
podAnnotations: {}
podSecurityContext: {}
# fsGroup: 2000
securityContext: {}
# capabilities:
# drop:
# - ALL
# readOnlyRootFilesystem: true
# runAsNonRoot: true
# runAsUser: 1000
service:
type: ClusterIP
port: 8545
rpcPort: 8545
wsPort: 8546
p2pPort: 30303
ingress:
enabled: false
className: "nginx"
annotations: {}
# cert-manager.io/cluster-issuer: "letsencrypt-prod"
hosts:
- host: besu.example.com
paths:
- path: /
pathType: Prefix
tls: []
# - secretName: besu-tls
# hosts:
# - besu.example.com
resources:
limits:
cpu: 2000m
memory: 4Gi
requests:
cpu: 1000m
memory: 2Gi
nodeSelector: {}
tolerations: []
affinity: {}
autoscaling:
enabled: false
minReplicas: 1
maxReplicas: 3
targetCPUUtilizationPercentage: 80
config:
dataDir: /data
network: "mainnet" # Options: mainnet, goerli, sepolia, or custom
rpcHttpEnabled: true
rpcHttpHost: "0.0.0.0"
rpcHttpPort: 8545
rpcHttpApis: ["ETH", "NET", "WEB3", "ADMIN", "DEBUG"]
rpcWsEnabled: true
rpcWsHost: "0.0.0.0"
rpcWsPort: 8546
p2pEnabled: true
p2pPort: 30303
metricsEnabled: true
metricsPort: 9545
persistence:
enabled: true
storageClass: ""
accessMode: ReadWriteOnce
size: 100Gi

View File

@@ -0,0 +1,13 @@
apiVersion: v2
name: blockscout
description: Blockscout blockchain explorer Helm chart
type: application
version: 1.0.0
appVersion: "5.0.0"
keywords:
- blockchain
- explorer
- ethereum
maintainers:
- name: HC Stack Team

View File

@@ -0,0 +1,75 @@
replicaCount: 1
image:
repository: blockscout/blockscout
pullPolicy: IfNotPresent
tag: "5.0.0"
nameOverride: ""
fullnameOverride: ""
serviceAccount:
create: true
annotations: {}
name: ""
service:
type: ClusterIP
port: 4000
ingress:
enabled: false
className: "nginx"
annotations: {}
hosts:
- host: blockscout.example.com
paths:
- path: /
pathType: Prefix
tls: []
resources:
limits:
cpu: 2000m
memory: 4Gi
requests:
cpu: 1000m
memory: 2Gi
config:
database:
type: "postgres"
host: "postgres"
port: 5432
database: "blockscout"
username: "blockscout"
password: "blockscout"
ethereum:
rpcUrl: "http://besu:8545"
wsUrl: "ws://besu:8546"
node:
host: "0.0.0.0"
port: 4000
persistence:
enabled: true
storageClass: ""
accessMode: ReadWriteOnce
size: 20Gi
postgres:
enabled: true
image:
repository: postgres
tag: "15"
persistence:
enabled: true
size: 50Gi
resources:
limits:
cpu: 1000m
memory: 2Gi
requests:
cpu: 500m
memory: 1Gi

View File

@@ -0,0 +1,13 @@
apiVersion: v2
name: cacti
description: Cacti network monitoring and graphing Helm chart
type: application
version: 1.0.0
appVersion: "1.2.0"
keywords:
- monitoring
- graphing
- network
maintainers:
- name: HC Stack Team

View File

@@ -0,0 +1,64 @@
replicaCount: 1
image:
repository: cacti/cacti
pullPolicy: IfNotPresent
tag: "1.2.0"
nameOverride: ""
fullnameOverride: ""
serviceAccount:
create: true
annotations: {}
name: ""
service:
type: ClusterIP
port: 80
ingress:
enabled: false
className: "nginx"
annotations: {}
hosts:
- host: cacti.example.com
paths:
- path: /
pathType: Prefix
tls: []
resources:
limits:
cpu: 1000m
memory: 2Gi
requests:
cpu: 500m
memory: 1Gi
config:
timezone: "UTC"
rrdPath: "/var/www/html/rra"
persistence:
enabled: true
storageClass: ""
accessMode: ReadWriteOnce
size: 10Gi
mysql:
enabled: true
image:
repository: mysql
tag: "8.0"
persistence:
enabled: true
size: 10Gi
resources:
limits:
cpu: 500m
memory: 1Gi
requests:
cpu: 250m
memory: 512Mi

View File

@@ -0,0 +1,14 @@
apiVersion: v2
name: chainlink-ccip
description: Chainlink CCIP (Cross-Chain Interoperability Protocol) Helm chart
type: application
version: 1.0.0
appVersion: "2.0.0"
keywords:
- blockchain
- chainlink
- ccip
- oracle
maintainers:
- name: HC Stack Team

View File

@@ -0,0 +1,77 @@
replicaCount: 1
image:
repository: smartcontract/chainlink
pullPolicy: IfNotPresent
tag: "v2.0.0"
nameOverride: ""
fullnameOverride: ""
serviceAccount:
create: true
annotations: {}
name: ""
service:
type: ClusterIP
port: 6688
apiPort: 6688
ingress:
enabled: false
className: "nginx"
annotations: {}
hosts:
- host: chainlink.example.com
paths:
- path: /
pathType: Prefix
tls: []
resources:
limits:
cpu: 2000m
memory: 4Gi
requests:
cpu: 1000m
memory: 2Gi
config:
database:
type: "postgres"
host: "postgres"
port: 5432
database: "chainlink"
username: "chainlink"
password: "chainlink"
ethereum:
rpcUrl: "http://besu:8545"
chainId: 1337
node:
apiPort: 6688
secureCookies: false
sessionTimeout: "24h"
persistence:
enabled: true
storageClass: ""
accessMode: ReadWriteOnce
size: 50Gi
postgres:
enabled: true
image:
repository: postgres
tag: "15"
persistence:
enabled: true
size: 20Gi
resources:
limits:
cpu: 500m
memory: 1Gi
requests:
cpu: 250m
memory: 512Mi

View File

@@ -0,0 +1,13 @@
apiVersion: v2
name: firefly
description: Hyperledger Firefly blockchain middleware Helm chart
type: application
version: 1.0.0
appVersion: "1.3.0"
keywords:
- blockchain
- firefly
- middleware
maintainers:
- name: HC Stack Team

View File

@@ -0,0 +1,79 @@
replicaCount: 1
image:
repository: ghcr.io/hyperledger/firefly
pullPolicy: IfNotPresent
tag: "v1.3.0"
nameOverride: ""
fullnameOverride: ""
serviceAccount:
create: true
annotations: {}
name: ""
service:
type: ClusterIP
port: 5000
apiPort: 5000
metricsPort: 6060
ingress:
enabled: false
className: "nginx"
annotations: {}
hosts:
- host: firefly.example.com
paths:
- path: /
pathType: Prefix
tls: []
resources:
limits:
cpu: 1000m
memory: 2Gi
requests:
cpu: 500m
memory: 1Gi
config:
database:
type: "postgres" # Options: postgres, sqlite
host: "postgres"
port: 5432
database: "firefly"
username: "firefly"
password: "firefly"
blockchain:
provider: "besu"
rpcUrl: "http://besu:8545"
ipfs:
apiUrl: "http://ipfs:5001"
node:
name: "firefly-node-1"
orgName: "org1"
persistence:
enabled: true
storageClass: ""
accessMode: ReadWriteOnce
size: 10Gi
postgres:
enabled: true
image:
repository: postgres
tag: "15"
persistence:
enabled: true
size: 20Gi
resources:
limits:
cpu: 500m
memory: 1Gi
requests:
cpu: 250m
memory: 512Mi

View File

@@ -0,0 +1,13 @@
apiVersion: v2
name: nginx-proxy
description: NGINX reverse proxy for HC Stack services
type: application
version: 1.0.0
appVersion: "1.25.0"
keywords:
- nginx
- proxy
- ingress
maintainers:
- name: HC Stack Team

View File

@@ -0,0 +1,83 @@
replicaCount: 2
image:
repository: nginx
pullPolicy: IfNotPresent
tag: "1.25-alpine"
nameOverride: ""
fullnameOverride: ""
serviceAccount:
create: true
annotations: {}
name: ""
service:
type: LoadBalancer
port: 80
httpsPort: 443
ingress:
enabled: false
className: "nginx"
annotations: {}
hosts: []
tls: []
resources:
limits:
cpu: 500m
memory: 512Mi
requests:
cpu: 250m
memory: 256Mi
config:
# Custom nginx configuration
nginxConf: |
upstream besu {
server besu:8545;
}
upstream firefly {
server firefly:5000;
}
upstream blockscout {
server blockscout:4000;
}
upstream chainlink {
server chainlink-ccip:6688;
}
server {
listen 80;
server_name _;
location /besu {
proxy_pass http://besu;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
location /firefly {
proxy_pass http://firefly;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
location /blockscout {
proxy_pass http://blockscout;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
location /chainlink {
proxy_pass http://chainlink;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
persistence:
enabled: false

View File

@@ -0,0 +1 @@
# Infrastructure manifests

View File

@@ -0,0 +1,41 @@
apiVersion: v1
kind: Namespace
metadata:
name: cert-manager
labels:
app.kubernetes.io/name: cert-manager
---
apiVersion: helm.cattle.io/v1
kind: HelmChart
metadata:
name: cert-manager
namespace: kube-system
spec:
chart: cert-manager
repo: https://charts.jetstack.io
targetNamespace: cert-manager
valuesContent: |-
installCRDs: true
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 500m
memory: 512Mi
---
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: admin@example.com # Change this to your email
privateKeySecretRef:
name: letsencrypt-prod
solvers:
- http01:
ingress:
class: nginx

View File

@@ -0,0 +1,31 @@
apiVersion: v1
kind: Namespace
metadata:
name: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/instance: ingress-nginx
---
apiVersion: helm.cattle.io/v1
kind: HelmChart
metadata:
name: ingress-nginx
namespace: kube-system
spec:
chart: ingress-nginx
repo: https://kubernetes.github.io/ingress-nginx
targetNamespace: ingress-nginx
valuesContent: |-
controller:
service:
type: LoadBalancer
metrics:
enabled: true
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 500m
memory: 512Mi

View File

@@ -0,0 +1,36 @@
apiVersion: v1
kind: Namespace
metadata:
name: hc-stack
labels:
name: hc-stack
environment: hybrid
managed-by: gitops
---
apiVersion: v1
kind: Namespace
metadata:
name: blockchain
labels:
name: blockchain
environment: hybrid
managed-by: gitops
---
apiVersion: v1
kind: Namespace
metadata:
name: monitoring
labels:
name: monitoring
environment: hybrid
managed-by: gitops
---
apiVersion: v1
kind: Namespace
metadata:
name: gitops
labels:
name: gitops
environment: hybrid
managed-by: gitops