mirror of
https://github.com/morten-olsen/homelab-operator.git
synced 2026-02-08 01:36:28 +01:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
40d387a07a |
2
.github/release-drafter-config.yml
vendored
2
.github/release-drafter-config.yml
vendored
@@ -1,5 +1,5 @@
|
|||||||
name-template: "$RESOLVED_VERSION 🌈"
|
name-template: "$RESOLVED_VERSION 🌈"
|
||||||
tag-template: "v$RESOLVED_VERSION"
|
tag-template: "$RESOLVED_VERSION"
|
||||||
categories:
|
categories:
|
||||||
- title: "🚀 Features"
|
- title: "🚀 Features"
|
||||||
labels:
|
labels:
|
||||||
|
|||||||
43
.github/workflows/main.yml
vendored
43
.github/workflows/main.yml
vendored
@@ -77,3 +77,46 @@ jobs:
|
|||||||
publish: true
|
publish: true
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
release:
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
packages: write
|
||||||
|
attestations: write
|
||||||
|
id-token: write
|
||||||
|
pages: write
|
||||||
|
name: Release
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
|
- name: Log in to the Container registry
|
||||||
|
uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1
|
||||||
|
with:
|
||||||
|
registry: ${{ env.DOCKER_REGISTRY }}
|
||||||
|
username: ${{ github.actor }}
|
||||||
|
password: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Extract metadata (tags, labels) for Docker
|
||||||
|
id: meta
|
||||||
|
uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7
|
||||||
|
with:
|
||||||
|
images: ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}
|
||||||
|
|
||||||
|
- name: Build and push Docker image
|
||||||
|
id: push
|
||||||
|
uses: docker/build-push-action@f2a1d5e99d037542a71f64918e516c093c6f3fc4
|
||||||
|
with:
|
||||||
|
context: .
|
||||||
|
push: true
|
||||||
|
tags: ${{ steps.meta.outputs.tags }}
|
||||||
|
labels: ${{ steps.meta.outputs.labels }}
|
||||||
|
|
||||||
|
- name: Generate artifact attestation
|
||||||
|
uses: actions/attest-build-provenance@v2
|
||||||
|
with:
|
||||||
|
subject-name: ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME}}
|
||||||
|
subject-digest: ${{ steps.push.outputs.digest }}
|
||||||
|
push-to-registry: true
|
||||||
4
.github/workflows/publish-tag.yml
vendored
4
.github/workflows/publish-tag.yml
vendored
@@ -2,10 +2,8 @@ name: Publish tag
|
|||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
|
||||||
- 'main'
|
|
||||||
tags:
|
tags:
|
||||||
- "v*"
|
- "v[0-9]+.[0-9]+.[0-9]+"
|
||||||
|
|
||||||
env:
|
env:
|
||||||
environment: test
|
environment: test
|
||||||
|
|||||||
277
README.md
277
README.md
@@ -1,282 +1,15 @@
|
|||||||
# homelab-operator
|
# homelab-operator
|
||||||
|
|
||||||
A Kubernetes operator designed for homelab environments that simplifies the
|
To install dependencies:
|
||||||
management of PostgreSQL databases and Kubernetes secrets. Built with TypeScript
|
|
||||||
and designed to run efficiently in resource-constrained environments.
|
|
||||||
|
|
||||||
## Features
|
|
||||||
|
|
||||||
- **PostgreSQL Database Management**: Automatically create and manage PostgreSQL
|
|
||||||
databases and roles
|
|
||||||
- **Secret Management**: Generate and manage Kubernetes secrets with
|
|
||||||
configurable data
|
|
||||||
- **Owner References**: Automatic cleanup when resources are deleted
|
|
||||||
- **Status Tracking**: Comprehensive status conditions and error reporting
|
|
||||||
- **Lightweight**: Minimal resource footprint suitable for homelab environments
|
|
||||||
|
|
||||||
## Architecture
|
|
||||||
|
|
||||||
The operator manages two main Custom Resource Definitions (CRDs):
|
|
||||||
|
|
||||||
### PostgresDatabase
|
|
||||||
|
|
||||||
Manages PostgreSQL databases and their associated roles:
|
|
||||||
|
|
||||||
- Creates a PostgreSQL role with a secure random password
|
|
||||||
- Creates a database owned by that role
|
|
||||||
- Generates a Kubernetes secret containing database credentials
|
|
||||||
- Ensures proper cleanup through owner references
|
|
||||||
|
|
||||||
### SecretRequest
|
|
||||||
|
|
||||||
Generates Kubernetes secrets with configurable data:
|
|
||||||
|
|
||||||
- Supports custom secret names
|
|
||||||
- Configurable data fields with various encodings
|
|
||||||
- Automatic secret lifecycle management
|
|
||||||
|
|
||||||
## Installation
|
|
||||||
|
|
||||||
### Prerequisites
|
|
||||||
|
|
||||||
- Kubernetes cluster (1.20+)
|
|
||||||
- PostgreSQL instance accessible from the cluster
|
|
||||||
- Helm 3.x (for chart-based installation)
|
|
||||||
|
|
||||||
### Using Helm Chart
|
|
||||||
|
|
||||||
1. Clone the repository:
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git clone <repository-url>
|
bun install
|
||||||
cd homelab-operator
|
|
||||||
```
|
```
|
||||||
|
|
||||||
2. Install using Helm:
|
To run:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
helm install homelab-operator ./chart \
|
bun run index.ts
|
||||||
--set-string env.POSTGRES_HOST=<your-postgres-host> \
|
|
||||||
--set-string env.POSTGRES_USER=<admin-user> \
|
|
||||||
--set-string env.POSTGRES_PASSWORD=<admin-password>
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Using kubectl
|
This project was created using `bun init` in bun v1.2.16. [Bun](https://bun.sh) is a fast all-in-one JavaScript runtime.
|
||||||
|
|
||||||
1. Build and push the Docker image:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
docker build -t your-registry/homelab-operator:latest .
|
|
||||||
docker push your-registry/homelab-operator:latest
|
|
||||||
```
|
|
||||||
|
|
||||||
2. Apply the Kubernetes manifests:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
kubectl apply -f chart/templates/
|
|
||||||
```
|
|
||||||
|
|
||||||
## Configuration
|
|
||||||
|
|
||||||
The operator is configured through environment variables:
|
|
||||||
|
|
||||||
| Variable | Description | Required | Default |
|
|
||||||
| ------------------- | ---------------------------------------- | -------- | ------- |
|
|
||||||
| `POSTGRES_HOST` | PostgreSQL server hostname | Yes | - |
|
|
||||||
| `POSTGRES_USER` | PostgreSQL admin username | Yes | - |
|
|
||||||
| `POSTGRES_PASSWORD` | PostgreSQL admin password | Yes | - |
|
|
||||||
| `POSTGRES_PORT` | PostgreSQL server port | No | 5432 |
|
|
||||||
| `LOG_LEVEL` | Logging level (debug, info, warn, error) | No | info |
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
### PostgreSQL Database
|
|
||||||
|
|
||||||
Create a PostgreSQL database with an associated role:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
apiVersion: homelab.mortenolsen.pro/v1
|
|
||||||
kind: PostgresDatabase
|
|
||||||
metadata:
|
|
||||||
name: my-app-db
|
|
||||||
namespace: my-namespace
|
|
||||||
spec: {}
|
|
||||||
```
|
|
||||||
|
|
||||||
This will create:
|
|
||||||
|
|
||||||
- A PostgreSQL role named `my-app-db`
|
|
||||||
- A PostgreSQL database named `my-namespace_my-app-db` owned by the role
|
|
||||||
- A Kubernetes secret `postgres-database-my-app-db` containing:
|
|
||||||
- `name`: Base64-encoded database name
|
|
||||||
- `user`: Base64-encoded username
|
|
||||||
- `password`: Base64-encoded password
|
|
||||||
|
|
||||||
### Secret Request
|
|
||||||
|
|
||||||
Generate a Kubernetes secret with custom data:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
apiVersion: homelab.mortenolsen.pro/v1
|
|
||||||
kind: SecretRequest
|
|
||||||
metadata:
|
|
||||||
name: my-secret
|
|
||||||
namespace: my-namespace
|
|
||||||
spec:
|
|
||||||
secretName: app-config
|
|
||||||
data:
|
|
||||||
- key: api-key
|
|
||||||
value: "my-api-key"
|
|
||||||
encoding: base64
|
|
||||||
- key: database-url
|
|
||||||
value: "postgresql://user:pass@host:5432/db"
|
|
||||||
- key: random-token
|
|
||||||
length: 32
|
|
||||||
chars: "abcdefghijklmnopqrstuvwxyz0123456789"
|
|
||||||
```
|
|
||||||
|
|
||||||
### Accessing Created Resources
|
|
||||||
|
|
||||||
To retrieve database credentials:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Get the secret
|
|
||||||
kubectl get secret postgres-database-my-app-db -o jsonpath='{.data.user}' | base64 -d
|
|
||||||
kubectl get secret postgres-database-my-app-db -o jsonpath='{.data.password}' | base64 -d
|
|
||||||
kubectl get secret postgres-database-my-app-db -o jsonpath='{.data.name}' | base64 -d
|
|
||||||
```
|
|
||||||
|
|
||||||
## Development
|
|
||||||
|
|
||||||
### Prerequisites
|
|
||||||
|
|
||||||
- [Bun](https://bun.sh/) runtime
|
|
||||||
- [pnpm](https://pnpm.io/) package manager
|
|
||||||
- Docker (for building images)
|
|
||||||
- Access to a Kubernetes cluster for testing
|
|
||||||
|
|
||||||
### Setup
|
|
||||||
|
|
||||||
1. Clone the repository:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
git clone <repository-url>
|
|
||||||
cd homelab-operator
|
|
||||||
```
|
|
||||||
|
|
||||||
2. Install dependencies:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
pnpm install
|
|
||||||
```
|
|
||||||
|
|
||||||
3. Set up development environment:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cp .env.example .env
|
|
||||||
# Edit .env with your PostgreSQL connection details
|
|
||||||
```
|
|
||||||
|
|
||||||
### Running Locally
|
|
||||||
|
|
||||||
For development, you can run the operator locally against a remote cluster:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Ensure kubectl is configured for your development cluster
|
|
||||||
export KUBECONFIG=~/.kube/config
|
|
||||||
|
|
||||||
# Set PostgreSQL connection environment variables
|
|
||||||
export POSTGRES_HOST=localhost
|
|
||||||
export POSTGRES_USER=postgres
|
|
||||||
export POSTGRES_PASSWORD=yourpassword
|
|
||||||
|
|
||||||
# Run the operator
|
|
||||||
bun run src/index.ts
|
|
||||||
```
|
|
||||||
|
|
||||||
### Development with Docker Compose
|
|
||||||
|
|
||||||
A development environment with PostgreSQL is provided:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
docker-compose -f docker-compose.dev.yaml up -d
|
|
||||||
```
|
|
||||||
|
|
||||||
### Building
|
|
||||||
|
|
||||||
Build the Docker image:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
docker build -t homelab-operator:latest .
|
|
||||||
```
|
|
||||||
|
|
||||||
### Testing
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Run linting
|
|
||||||
pnpm run test:lint
|
|
||||||
|
|
||||||
# Apply test resources
|
|
||||||
kubectl apply -f test.yaml
|
|
||||||
```
|
|
||||||
|
|
||||||
## Contributing
|
|
||||||
|
|
||||||
1. Fork the repository
|
|
||||||
2. Create a feature branch: `git checkout -b feature/new-feature`
|
|
||||||
3. Make your changes and add tests
|
|
||||||
4. Run linting: `pnpm run test:lint`
|
|
||||||
5. Commit your changes: `git commit -am 'Add new feature'`
|
|
||||||
6. Push to the branch: `git push origin feature/new-feature`
|
|
||||||
7. Submit a pull request
|
|
||||||
|
|
||||||
## Project Structure
|
|
||||||
|
|
||||||
```
|
|
||||||
├── chart/ # Helm chart for deployment
|
|
||||||
├── src/
|
|
||||||
│ ├── crds/ # Custom Resource Definitions
|
|
||||||
│ │ ├── postgres/ # PostgreSQL database management
|
|
||||||
│ │ └── secrets/ # Secret generation
|
|
||||||
│ ├── custom-resource/ # Base CRD framework
|
|
||||||
│ ├── database/ # Database migrations
|
|
||||||
│ ├── services/ # Core services
|
|
||||||
│ │ ├── config/ # Configuration management
|
|
||||||
│ │ ├── k8s.ts # Kubernetes API client
|
|
||||||
│ │ ├── log/ # Logging service
|
|
||||||
│ │ ├── postgres/ # PostgreSQL service
|
|
||||||
│ │ └── secrets/ # Secret management
|
|
||||||
│ └── utils/ # Utilities and constants
|
|
||||||
├── Dockerfile # Container build configuration
|
|
||||||
└── docker-compose.dev.yaml # Development environment
|
|
||||||
```
|
|
||||||
|
|
||||||
## License
|
|
||||||
|
|
||||||
This project is licensed under the MIT License - see the LICENSE file for
|
|
||||||
details.
|
|
||||||
|
|
||||||
## Support
|
|
||||||
|
|
||||||
For support and questions:
|
|
||||||
|
|
||||||
- Create an issue in the GitHub repository
|
|
||||||
- Check existing issues for similar problems
|
|
||||||
- Review the logs using `kubectl logs -l app=homelab-operator`
|
|
||||||
|
|
||||||
## Status Monitoring
|
|
||||||
|
|
||||||
Monitor the operator status:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Check operator logs
|
|
||||||
kubectl logs -l app=homelab-operator -f
|
|
||||||
|
|
||||||
# Check CRD status
|
|
||||||
kubectl get postgresdatabases
|
|
||||||
kubectl get secretrequests
|
|
||||||
|
|
||||||
# Describe resources for detailed status
|
|
||||||
kubectl describe postgresdatabase my-app-db
|
|
||||||
kubectl describe secretrequest my-secret
|
|
||||||
```
|
|
||||||
|
|||||||
@@ -4,9 +4,9 @@
|
|||||||
|
|
||||||
image:
|
image:
|
||||||
repository: ghcr.io/morten-olsen/homelab-operator
|
repository: ghcr.io/morten-olsen/homelab-operator
|
||||||
pullPolicy: Always
|
pullPolicy: IfNotPresent
|
||||||
# Overrides the image tag whose default is the chart appVersion.
|
# Overrides the image tag whose default is the chart appVersion.
|
||||||
tag: main
|
tag: ""
|
||||||
|
|
||||||
imagePullSecrets: []
|
imagePullSecrets: []
|
||||||
nameOverride: ""
|
nameOverride: ""
|
||||||
|
|||||||
Reference in New Issue
Block a user