feature(wip): Implement basic services and some databases.

This commit is contained in:
greysoh 2024-07-19 10:45:34 -04:00
parent c36ae6cdf0
commit 7b7f90ff16
Signed by: imterah
GPG key ID: 8FA7DD57BA6CEA37
38 changed files with 794 additions and 6 deletions

6
.gitignore vendored
View file

@ -5,6 +5,10 @@ __pycache__
.server-setup
.env
out
<<<<<<< HEAD
# kubernetes/
meta
build.log
secrets.nix
kubernetes/meta
kubernetes/secrets

View file

@ -5,6 +5,7 @@ format_ver = 1
[k3s_dash_repo]
description = Kubernetes Dashboard Repository
mode = helm
depends_on = traefik
[#k3s_dash_repo/helm]
mode = add_repo

View file

@ -0,0 +1,4 @@
# IP map
* `192.168.2.11` = PostgreSQL
* `192.168.2.12` = MariaDB/MySQL
* `192.168.2.13-14` = Reserved (maybe add Redis?)

View file

@ -0,0 +1,8 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: mariadb-details
labels:
app: mariadb
data:
MARIADB_DATABASE: mdb_db

View file

@ -0,0 +1,17 @@
apiVersion: v1
kind: Service
metadata:
name: mariadb
labels:
app: mariadb
annotations:
metallb.universe.tf/loadBalancerIPs: 192.168.2.12
spec:
type: LoadBalancer
ports:
- protocol: TCP
port: 3306
targetPort: 3306
selector:
app: mariadb

View file

@ -0,0 +1,37 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: mariadb-deployment
spec:
replicas: 2
selector:
matchLabels:
app: mariadb
template:
metadata:
labels:
app: mariadb
spec:
containers:
- name: mariadb
image: "mariadb:11.2.4"
ports:
- containerPort: 3306
envFrom:
- configMapRef:
name: mariadb-details
env:
- name: MARIADB_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: db-credentials
key: password
- name: MARIADB_DATABASE
value: mdb_db
volumeMounts:
- mountPath: /var/lib/postgresql/data
name: mariadb_data
volumes:
- name: mariadb_data
persistentVolumeClaim:
claimName: mariadb-volume-claim

View file

@ -0,0 +1,42 @@
[meta]
format_ver = 1
[mariadb_configmap]
mode = k3s
depends_on = metallb_ip_config:db_credentials
[#mariadb_configmap/k3s]
mode = install
yml_path = ./configmap.yml
[mariadb_pv]
mode = k3s
depends_on = mariadb_configmap
[#mariadb_pv/k3s]
mode = install
yml_path = ./pv.yml
[mariadb_pv_claim]
mode = k3s
depends_on = mariadb_pv
[#mariadb_pv_claim/k3s]
mode = install
yml_path = ./pv-claim.yml
[mariadb]
mode = k3s
depends_on = mariadb_pv_claim
[#mariadb/k3s]
mode = install
yml_path = ./mariadb.yml
[mariadb_svc]
mode = k3s
depends_on = mariadb
[#mariadb_svc/k3s]
mode = install
yml_path = ./mariadb-svc.yml

View file

@ -0,0 +1,13 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mariadb-volume-claim
labels:
app: mariadb
spec:
storageClassName: manual
accessModes:
- ReadWriteMany
resources:
requests:
storage: 10Gi

View file

@ -0,0 +1,15 @@
apiVersion: v1
kind: PersistentVolume
metadata:
name: mariadb-volume
labels:
type: local
app: mariadb
spec:
storageClassName: manual
capacity:
storage: 10Gi
accessModes:
- ReadWriteMany
hostPath:
path: /var/lib/mysql

View file

@ -0,0 +1,30 @@
apiVersion: v1
kind: Service
metadata:
name: pgadmin
spec:
ports:
- name: web
port: 80
targetPort: web
selector:
app: pgadmin
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: pgadmin-ingress
spec:
rules:
- host: "pgadmin.hofers.cloud"
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: pgadmin
port:
name: web

View file

@ -0,0 +1,30 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: pgadmin
spec:
replicas: 1
selector:
matchLabels:
app: pgadmin
template:
metadata:
labels:
app: pgadmin
spec:
containers:
- name: pgadmin
image: dpage/pgadmin4
ports:
- containerPort: 80
env:
- name: PGADMIN_DEFAULT_EMAIL
valueFrom:
secretKeyRef:
name: pgadmin-credentials
key: default-email
- name: PGADMIN_DEFAULT_PASSWORD
valueFrom:
secretKeyRef:
name: pgadmin-credentials
key: default-password

View file

@ -0,0 +1,34 @@
[meta]
format_ver = 1
[pgadmin_pv]
mode = k3s
depends_on = traefik:postgres_svc
[#pgadmin_pv/k3s]
mode = install
yml_path = ./pv.yml
[pgadmin_pv_claim]
mode = k3s
depends_on = pgadmin_pv
[#pgadmin_pv_claim/k3s]
mode = install
yml_path = ./pv-claim.yml
[pgadmin]
mode = k3s
depends_on = pgadmin_pv_claim
[#pgadmin/k3s]
mode = install
yml_path = ./pgadmin.yml
[pgadmin_svc]
mode = k3s
depends_on = pgadmin
[#pgadmin_svc/k3s]
mode = install
yml_path = ./pgadmin-svc.yml

View file

@ -0,0 +1,13 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pgadmin-volume-claim
labels:
app: pgadmin
spec:
storageClassName: manual
accessModes:
- ReadWriteMany
resources:
requests:
storage: 10Gi

View file

@ -0,0 +1,15 @@
apiVersion: v1
kind: PersistentVolume
metadata:
name: pgadmin-data
labels:
type: local
app: pgadmin
spec:
storageClassName: manual
capacity:
storage: 10Gi
accessModes:
- ReadWriteMany
hostPath:
path: /var/lib/pgadmin

View file

@ -0,0 +1,8 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: postgres-db-details
labels:
app: postgres
data:
POSTGRES_DB: ps_db

View file

@ -0,0 +1,17 @@
apiVersion: v1
kind: Service
metadata:
name: postgres
labels:
app: postgres
annotations:
metallb.universe.tf/loadBalancerIPs: 192.168.2.11
spec:
type: LoadBalancer
ports:
- protocol: TCP
port: 5432
targetPort: 5432
selector:
app: postgres

View file

@ -0,0 +1,41 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: postgres-deployment
spec:
replicas: 2
selector:
matchLabels:
app: postgres
template:
metadata:
labels:
app: postgres
spec:
containers:
- name: postgres
image: "postgres:16"
imagePullPolicy: IfNotPresent
ports:
- containerPort: 5432
envFrom:
- configMapRef:
name: postgres-db-details
env:
- name: POSTGRES_USER
valueFrom:
secretKeyRef:
name: db-credentials
key: username
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
name: db-credentials
key: password
volumeMounts:
- mountPath: /var/lib/postgresql/data
name: postgresdata
volumes:
- name: postgresdata
persistentVolumeClaim:
claimName: postgres-volume-claim

View file

@ -0,0 +1,42 @@
[meta]
format_ver = 1
[postgres_configmap]
mode = k3s
depends_on = metallb_ip_config:db_credentials
[#postgres_configmap/k3s]
mode = install
yml_path = ./configmap.yml
[postgres_pv]
mode = k3s
depends_on = postgres_configmap
[#postgres_pv/k3s]
mode = install
yml_path = ./pv.yml
[postgres_pv_claim]
mode = k3s
depends_on = postgres_pv
[#postgres_pv_claim/k3s]
mode = install
yml_path = ./pv-claim.yml
[postgres]
mode = k3s
depends_on = postgres_pv_claim
[#postgres/k3s]
mode = install
yml_path = ./postgres.yml
[postgres_svc]
mode = k3s
depends_on = postgres
[#postgres_svc/k3s]
mode = install
yml_path = ./postgres-svc.yml

View file

@ -0,0 +1,13 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: postgres-volume-claim
labels:
app: postgres
spec:
storageClassName: manual
accessModes:
- ReadWriteMany
resources:
requests:
storage: 10Gi

View file

@ -0,0 +1,15 @@
apiVersion: v1
kind: PersistentVolume
metadata:
name: postgres-volume
labels:
type: local
app: postgres
spec:
storageClassName: manual
capacity:
storage: 10Gi
accessModes:
- ReadWriteMany
hostPath:
path: /data/postgresql

View file

@ -0,0 +1,17 @@
[meta]
format_ver = 1
[postgres]
description = PostgreSQL
mode = include
path = ./postgresql/project.ini
[mariadb]
description = MariaDB
mode = include
path = ./mariadb/project.ini
[pgadmin]
description = pgAdmin
mode = include
path = ./pgadmin/project.ini

View file

@ -0,0 +1,9 @@
apiVersion: v1
kind: Secret
metadata:
name: db-credentials
data:
# Kubernetes base64 encodes the data
# By default, this is:
username: ZGF0YWJhc2U= # database
password: ZGF0YWJhc2U= # database

View file

@ -0,0 +1,9 @@
apiVersion: v1
kind: Secret
metadata:
name: pgadmin-credentials
data:
# Kubernetes base64 encodes the data
# By default, this is:
default-email: cGdhZG1pbkBleGFtcGxlLmNvbQ== # pgadmin@example.com
default-password: ZGF0YWJhc2U= # database

View file

@ -0,0 +1,16 @@
[meta]
format_ver = 1
[db_credentials]
mode = k3s
[#db_credentials/k3s]
mode = install
yml_path = ./database-credentials.yml
[pgadmin_default_credentials]
mode = k3s
[#pgadmin_default_credentials/k3s]
mode = install
yml_path = ./pgadmin-default-login.yml

View file

@ -339,24 +339,27 @@ def generate_change_set(projects: list[Project]) -> dict[str, list[str]]:
f"helm repo add {project.helm_settings.name} {project.helm_settings.repo}"
]
elif project.helm_settings.mode == "upgrade" or project.helm_settings.mode == "install":
if project.helm_settings.name == None or project.helm_settings.repo == None or project.helm_settings.namespace_name == None:
print("ERROR: 'upgrade' or 'install' is set but either: name, repo, or namespace_name is undefined")
if project.helm_settings.name == None or project.helm_settings.repo == None:
print("ERROR: 'upgrade' or 'install' is set but either: name, or repo, is undefined")
exit(1)
data_in_bytes = bytearray(f"install.{project.helm_settings.repo}_{project.helm_settings.name}", "utf-8")
meta_id = hashlib.md5(data_in_bytes).hexdigest()
create_namespace = "--create-namespace" if project.helm_settings.create_namespace else ""
namespace = f"--namespace {project.helm_settings.namespace_name}" if project.helm_settings.namespace_name else ""
if not os.path.isfile(f"{changeset_path}/helmhashes/{meta_id}") and project.helm_settings.mode == "install":
Path(f"{changeset_path}/helmhashes/{meta_id}").touch()
changeset_values[project.name] = [
f"helm repo update {project.helm_settings.repo[:project.helm_settings.repo.index("/")]}",
f"helm upgrade --install {project.helm_settings.name} {project.helm_settings.repo} {"--create-namespace" if project.helm_settings.create_namespace else ""} --namespace {project.helm_settings.namespace_name}"
f"helm upgrade --install {project.helm_settings.name} {project.helm_settings.repo} {create_namespace} {namespace}"
]
elif project.helm_settings.mode == "upgrade" or mode == "update":
changeset_values[project.name] = [
f"helm repo update {project.helm_settings.repo[:project.helm_settings.repo.index("/")]}",
f"helm upgrade {project.helm_settings.name} {project.helm_settings.repo} {"--create-namespace" if project.helm_settings.create_namespace else ""} --namespace {project.helm_settings.namespace_name}"
f"helm upgrade {project.helm_settings.name} {project.helm_settings.repo} {create_namespace} {namespace}"
]
case "k3s":
data_in_bytes = bytearray(f"{project.kube_settings.yml_path}", "utf-8")

View file

@ -0,0 +1,12 @@
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
name: first-pool
spec:
addresses:
- 192.168.2.10-192.168.2.254
---
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
name: example

View file

@ -0,0 +1,8 @@
apiVersion: v1
kind: Namespace
metadata:
name: metallb-system
labels:
pod-security.kubernetes.io/enforce: privileged
pod-security.kubernetes.io/audit: privileged
pod-security.kubernetes.io/warn: privileged

View file

@ -0,0 +1,39 @@
[meta]
format_ver = 1
[metallb_namespace]
description = Namespace Configuration for MetalLB
mode = k3s
[#metallb_namespace/k3s]
mode = install
yml_path = ./metallb_namespace.yml
[metallb_repo]
description = MetalLB Repository
mode = helm
depends_on = metallb_namespace
[#metallb_repo/helm]
mode = add_repo
name = metallb
repo = https://metallb.github.io/metallb
[metallb]
description = MetalLB
mode = helm
depends_on = metallb_repo
[#metallb/helm]
mode = install
name = metallb
repo = metallb/metallb
[metallb_ip_config]
description = IPs for MetalLB
mode = k3s
depends_on = metallb
[#metallb_ip_config/k3s]
mode = install
yml_path = ./metallb_ip_config.yml

View file

@ -0,0 +1,12 @@
[meta]
format_ver = 1
[metallb]
description = MetalLB
mode = include
path = ./metallb/project.ini
[traefik]
description = MetalLB
mode = include
path = ./traefik/project.ini

View file

@ -0,0 +1,4 @@
apiVersion: v1
kind: ServiceAccount
metadata:
name: traefik-account

View file

@ -0,0 +1,65 @@
[meta]
format_ver = 1
[traefik_role]
description = Traefik role for self
mode = k3s
depends_on = metallb_ip_config:traefik_cf_credentials
[#traefik_role/k3s]
mode = install
yml_path = ./role.yml
[traefik_account]
description = Traefik account
mode = k3s
depends_on = traefik_role
[#traefik_account/k3s]
mode = install
yml_path = ./account.yml
[traefik_role_binding]
description = Traefik role binding
mode = k3s
depends_on = traefik_account
[#traefik_role_binding/k3s]
mode = install
yml_path = ./role-binding.yml
[traefik_pv]
description = Traefik certificate storage
mode = k3s
depends_on = traefik_role_binding
[#traefik_pv/k3s]
mode = install
yml_path = ./pv.yml
[traefik_pv_claim]
description = Traefik certificate storage claim
mode = k3s
depends_on = traefik_pv
[#traefik_pv_claim/k3s]
mode = install
yml_path = ./pv-claim.yml
[traefik]
description = Traefik
mode = k3s
depends_on = traefik_account
[#traefik/k3s]
mode = install
yml_path = ./traefik.yml
[traefik_dashboard]
description = Traefik Dashboard
mode = k3s
depends_on = traefik
[#traefik_dashboard/k3s]
mode = install
yml_path = ./traefik-dashboard.yml

View file

@ -0,0 +1,13 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: traefik-volume-claim
labels:
app: traefik
spec:
storageClassName: manual
accessModes:
- ReadWriteMany
resources:
requests:
storage: 5Gi

View file

@ -0,0 +1,15 @@
apiVersion: v1
kind: PersistentVolume
metadata:
name: traefik-certs-volume
labels:
type: local
app: traefik
spec:
storageClassName: manual
capacity:
storage: 5Gi
accessModes:
- ReadWriteMany
hostPath:
path: /ssl-certs/

View file

@ -0,0 +1,13 @@
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: traefik-role-binding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: traefik-role
subjects:
- kind: ServiceAccount
name: traefik-account
namespace: default # This tutorial uses the "default" K8s namespace.

View file

@ -0,0 +1,39 @@
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: traefik-role
rules:
- apiGroups:
- ""
resources:
- services
- secrets
verbs:
- get
- list
- watch
- apiGroups:
- discovery.k8s.io
resources:
- endpointslices
verbs:
- list
- watch
- apiGroups:
- extensions
- networking.k8s.io
resources:
- ingresses
- ingressclasses
verbs:
- get
- list
- watch
- apiGroups:
- extensions
- networking.k8s.io
resources:
- ingresses/status
verbs:
- update

View file

@ -0,0 +1,47 @@
apiVersion: v1
kind: Service
metadata:
name: traefik-dashboard-service
annotations:
metallb.universe.tf/loadBalancerIPs: 192.168.2.10
metallb.universe.tf/allow-shared-ip: "this-is-traefik"
spec:
type: LoadBalancer
ports:
- port: 8080
targetPort: dashboard
selector:
app: traefik
---
apiVersion: v1
kind: Service
metadata:
name: traefik-web-service
annotations:
metallb.universe.tf/loadBalancerIPs: 192.168.2.10
metallb.universe.tf/allow-shared-ip: "this-is-traefik"
spec:
type: LoadBalancer
ports:
- targetPort: web
port: 80
selector:
app: traefik
---
apiVersion: v1
kind: Service
metadata:
name: traefik-web-service
annotations:
metallb.universe.tf/loadBalancerIPs: 192.168.2.10
metallb.universe.tf/allow-shared-ip: "this-is-traefik"
spec:
type: LoadBalancer
ports:
- targetPort: web
port: 443
selector:
app: traefik

View file

@ -0,0 +1,53 @@
kind: Deployment
apiVersion: apps/v1
metadata:
name: traefik-deployment
labels:
app: traefik
spec:
replicas: 2
selector:
matchLabels:
app: traefik
template:
metadata:
labels:
app: traefik
spec:
serviceAccountName: traefik-account
containers:
- name: traefik
image: traefik:v3.1
args:
- --api.insecure
- --providers.kubernetesingress
- --certificatesresolvers.cloudflare.acme.dnschallenge.provider=cloudflare
- --certificatesresolvers.cloudflare.acme.email=greysonhofer09@gmail.com
- --certificatesresolvers.cloudflare.acme.dnschallenge.resolvers=1.1.1.1
- --certificatesresolvers.cloudflare.acme.storage=/ssl-certs/acme-cloudflare.json
ports:
- name: web
containerPort: 80
- name: web
containerPort: 443
- name: dashboard
containerPort: 8080
env:
- name: CF_API_EMAIL
valueFrom:
secretKeyRef:
name: traefik-cf-creds
key: cf-email
- name: CF_API_KEY
valueFrom:
secretKeyRef:
name: traefik-cf-creds
key: cf-key
volumeMounts:
- mountPath: /ssl-certs/
name: cert-data
volumes:
- name: cert-data
persistentVolumeClaim:
claimName: traefik-volume-claim

View file

@ -1,7 +1,22 @@
[meta]
format_ver = 1
[secrets]
description = Secret Values
mode = include
path = ./secrets/project.ini
[loadbalancer]
description = LoadBalancer Configuration
mode = include
path = ./loadbalancer/project.ini
[dashboard]
description = Various Dashboards
mode = include
path = ./dashboard/project.ini
path = ./dashboard/project.ini
[database]
description = Database Software
mode = include
path = ./databases/project.ini