A Python library for rendering Helm charts and ArgoCD applications
Project description
Kubeman
A Python library for rendering Helm charts and ArgoCD applications.
Features
- Abstract base class for defining Helm charts
- Abstract base class for raw Kubernetes resources (no Helm required)
- Chart registry for managing multiple charts and resources
- Git operations for manifest repository management
- Docker image build and push utilities
- Automatic ArgoCD Application manifest generation
Installation
From Source
Using uv (recommended):
uv pip install -e .
Or using pip:
pip install -e .
Development Setup
Install development dependencies:
uv sync --dev
Format code:
uv tool run black .
Pre-commit Hooks
This project uses pre-commit hooks to automatically format code with black before commits.
Install pre-commit as a tool (recommended):
uv tool install pre-commit
This installs pre-commit globally and makes it available in your PATH. Then install the git hooks:
pre-commit install
Now, every time you commit, black will automatically format your Python files. You can also run the hooks manually:
pre-commit run --all-files
Alternative: If you prefer to use pre-commit from the virtual environment, you can install it as a dev dependency and use the Python module:
uv sync --dev
uv run python -m pre_commit install
uv run python -m pre_commit run --all-files
Usage
Creating a Helm Chart
To create a Helm chart, subclass HelmChart and implement the required abstract methods:
from kubeman import HelmChart, ChartRegistry
@ChartRegistry.register
class MyChart(HelmChart):
@property
def name(self) -> str:
return "my-chart"
@property
def repository(self) -> dict:
"""Return repository information"""
return {
"type": "classic", # or "oci" or "none"
"remote": "https://charts.example.com"
}
@property
def namespace(self) -> str:
return "my-namespace"
@property
def version(self) -> str:
return "1.0.0"
def generate_values(self) -> dict:
"""Generate values.yaml content"""
return {
"replicaCount": 3,
"image": {
"repository": "my-app",
"tag": "latest"
}
}
Creating a Kubernetes Resource (Without Helm)
For projects that don't need Helm but still want ArgoCD Application generation and manifest management, use the KubernetesResource class:
from kubeman import KubernetesResource, ChartRegistry
@ChartRegistry.register
class MyKubernetesResources(KubernetesResource):
@property
def name(self) -> str:
return "my-app"
@property
def namespace(self) -> str:
return "production"
def manifests(self) -> list[dict]:
"""Return list of Kubernetes manifests"""
return [
{
"apiVersion": "v1",
"kind": "ConfigMap",
"metadata": {
"name": "my-app-config",
"namespace": "production"
},
"data": {
"DATABASE_URL": "postgres://db:5432/myapp",
"CACHE_ENABLED": "true"
}
},
{
"apiVersion": "apps/v1",
"kind": "Deployment",
"metadata": {
"name": "my-app",
"namespace": "production"
},
"spec": {
"replicas": 3,
"selector": {"matchLabels": {"app": "my-app"}},
"template": {
"metadata": {"labels": {"app": "my-app"}},
"spec": {
"containers": [{
"name": "my-app",
"image": "gcr.io/my-project/my-app:v1.0.0",
"envFrom": [{
"configMapRef": {"name": "my-app-config"}
}]
}]
}
}
}
},
{
"apiVersion": "v1",
"kind": "Service",
"metadata": {
"name": "my-app",
"namespace": "production"
},
"spec": {
"selector": {"app": "my-app"},
"ports": [{
"port": 80,
"targetPort": 8080
}]
}
}
]
The KubernetesResource class provides a simpler interface than HelmChart when you don't need Helm's templating capabilities. It still generates ArgoCD Applications and integrates with the ChartRegistry system.
Rendering Charts and Resources
Once your charts and resources are registered, you can render them:
from kubeman import ChartRegistry
# Get all registered charts and resources
charts = ChartRegistry.get_registered_charts()
# Render each chart/resource
for chart_class in charts:
chart = chart_class()
chart.render() # Generates manifests and ArgoCD Application
The render() method will:
For HelmChart:
- Render the Helm chart templates to
manifests/{chart-name}/{chart-name}-manifests.yaml - Write any extra manifests to
manifests/{chart-name}/ - Generate an ArgoCD Application manifest to
manifests/apps/{chart-name}-application.yaml
For KubernetesResource:
- Write each Kubernetes manifest to
manifests/{name}/{manifest-name}-{kind}.yaml - Generate an ArgoCD Application manifest to
manifests/apps/{name}-application.yaml
Advanced Chart Configuration
Custom Repository Package Name
If your repository uses a different package name than the chart name:
@property
def repository_package(self) -> str:
return "different-package-name"
OCI Registry Support
For OCI-based Helm repositories:
@property
def repository(self) -> dict:
return {
"type": "oci",
"remote": "oci://registry.example.com/charts"
}
Extra Manifests
Add additional Kubernetes manifests alongside your Helm chart:
def extra_manifests(self) -> list[dict]:
return [
{
"apiVersion": "v1",
"kind": "ConfigMap",
"metadata": {"name": "my-config"},
"data": {"key": "value"}
}
]
Custom ArgoCD Application Settings
Customize the ArgoCD Application generation:
def application_repo_url(self) -> str:
"""Override the repository URL for ArgoCD applications"""
return "https://github.com/org/manifests-repo"
def application_target_revision(self) -> str:
"""Override the target revision (defaults to current branch)"""
return "main"
def managed_namespace_metadata(self) -> dict:
"""Add labels to managed namespaces"""
return {
"app.kubernetes.io/managed-by": "argocd"
}
def argo_ignore_spec(self) -> list:
"""Configure ArgoCD ignore differences"""
return [
{
"group": "apps",
"kind": "Deployment",
"jsonPointers": ["/spec/replicas"]
}
]
Git Operations
The GitManager class provides utilities for working with Git repositories:
from kubeman import GitManager
git = GitManager()
# Get current commit hash (from STABLE_GIT_COMMIT env var)
commit_hash = git.fetch_commit_hash()
# Get current branch name (from STABLE_GIT_BRANCH env var)
branch_name = git.fetch_branch_name()
# Push rendered manifests to a repository
git.push_manifests(repo_url="https://github.com/org/manifests-repo")
The push_manifests() method will:
- Clone the manifests repository
- Checkout or create the branch matching
STABLE_GIT_BRANCH - Copy rendered manifests from
RENDERED_MANIFEST_DIR - Commit and push the changes
Docker Operations
The DockerManager class helps build and push Docker images to Google Container Registry:
from kubeman import DockerManager
# Initialize with project ID (or set GOOGLE_PROJECT_ID env var)
docker = DockerManager(
project_id="my-gcp-project",
repository_name="my-repo" # Optional, defaults to "default"
)
# Build an image
image_name = docker.build_image(
component="frontend",
context_path="./frontend",
tag="v1.0.0"
)
# Push an image
docker.push_image(component="frontend", tag="v1.0.0")
# Build and push in one step
image_name = docker.build_and_push(
component="backend",
context_path="./backend",
tag="latest"
)
Environment Variables
Required for Git Operations
STABLE_GIT_COMMIT- Current git commit hashSTABLE_GIT_BRANCH- Current git branch nameRENDERED_MANIFEST_DIR- Path to directory containing rendered manifestsMANIFEST_REPO_URL- Git repository URL for pushing manifests (optional if passed topush_manifests())
Required for ArgoCD Applications
ARGOCD_APP_REPO_URL- Repository URL for ArgoCD applications (or overrideapplication_repo_url())ARGOCD_APPS_SUBDIR- Subdirectory for applications (defaults to "apps")
Required for Docker Operations
GOOGLE_PROJECT_ID- Google Cloud project ID (or pass toDockerManagerconstructor)GOOGLE_REGION- GCP region (defaults to "us-central1")DOCKER_REPOSITORY_NAME- Docker repository name (defaults to "default")GITHUB_REPOSITORY- GitHub repository name (optional)
Complete Example
Here's a complete example that ties everything together, using both HelmChart and KubernetesResource:
from kubeman import HelmChart, KubernetesResource, ChartRegistry, GitManager, DockerManager
# Define a Helm chart for a third-party application
@ChartRegistry.register
class PostgresChart(HelmChart):
@property
def name(self) -> str:
return "postgres"
@property
def repository(self) -> dict:
return {
"type": "classic",
"remote": "https://charts.bitnami.com/bitnami"
}
@property
def namespace(self) -> str:
return "database"
@property
def version(self) -> str:
return "12.5.0"
def generate_values(self) -> dict:
return {
"auth": {
"postgresPassword": "changeme"
},
"persistence": {
"enabled": True,
"size": "10Gi"
}
}
# Define custom Kubernetes resources for your application
@ChartRegistry.register
class MyAppResources(KubernetesResource):
@property
def name(self) -> str:
return "my-app"
@property
def namespace(self) -> str:
return "production"
def manifests(self) -> list[dict]:
return [
{
"apiVersion": "v1",
"kind": "ConfigMap",
"metadata": {"name": "my-app-config", "namespace": "production"},
"data": {"DATABASE_HOST": "postgres.database.svc.cluster.local"}
},
{
"apiVersion": "apps/v1",
"kind": "Deployment",
"metadata": {"name": "my-app", "namespace": "production"},
"spec": {
"replicas": 3,
"selector": {"matchLabels": {"app": "my-app"}},
"template": {
"metadata": {"labels": {"app": "my-app"}},
"spec": {
"containers": [{
"name": "my-app",
"image": "gcr.io/my-project/my-app:v1.0.0",
"envFrom": [{"configMapRef": {"name": "my-app-config"}}]
}]
}
}
}
}
]
# Build and push Docker images
docker = DockerManager()
docker.build_and_push("my-app", "./app", tag="v1.0.0")
# Render all registered charts and resources
for chart_class in ChartRegistry.get_registered_charts():
chart = chart_class()
chart.render()
# Push manifests to repository
git = GitManager()
git.push_manifests()
Publishing
This package is automatically published to PyPI via GitHub Actions when:
- A new release is published on GitHub
- A version tag is pushed (e.g.,
v0.1.0,v1.0.0) - Manual trigger via the GitHub Actions workflow
Setup for Publishing
The workflow uses PyPI trusted publishing (OIDC). To enable it:
- Go to PyPI Account Settings
- Navigate to "API tokens" → "Add a pending project"
- Add your project name:
kubeman - Copy the "Trusted publisher" configuration
- In your GitHub repository, go to Settings → Secrets and variables → Actions
- Add the PyPI project name and repository owner as environment variables (if needed)
Alternatively, you can use an API token:
- Create an API token on PyPI
- Add it as a secret named
PYPI_API_TOKENin your GitHub repository
Manual Publishing
To publish manually:
# Build the package
python -m build
# Check the package
python -m twine check dist/*
# Upload to PyPI (requires credentials)
python -m twine upload dist/*
Installing from PyPI
Once published, users can install the package with:
pip install kubeman
Or with uv:
uv pip install kubeman
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file kubeman-0.2.0.tar.gz.
File metadata
- Download URL: kubeman-0.2.0.tar.gz
- Upload date:
- Size: 47.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fd2efce40d019c9130e5311f6204a7bab6ff3801bf372ef58048c2ba93eaad9f
|
|
| MD5 |
7990891f8c7b7c631c776aa05e4abcb3
|
|
| BLAKE2b-256 |
0ffbb3dc6a303f8ad1e850ed2f1c421793bbc6fca665d6cfe55f2be9918fc454
|
Provenance
The following attestation bundles were made for kubeman-0.2.0.tar.gz:
Publisher:
publish.yml on jasonzh0/kubeman
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
kubeman-0.2.0.tar.gz -
Subject digest:
fd2efce40d019c9130e5311f6204a7bab6ff3801bf372ef58048c2ba93eaad9f - Sigstore transparency entry: 715771940
- Sigstore integration time:
-
Permalink:
jasonzh0/kubeman@238854ec1d8ecd7753a96d65b7a244bd8572a1d1 -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/jasonzh0
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@238854ec1d8ecd7753a96d65b7a244bd8572a1d1 -
Trigger Event:
release
-
Statement type:
File details
Details for the file kubeman-0.2.0-py3-none-any.whl.
File metadata
- Download URL: kubeman-0.2.0-py3-none-any.whl
- Upload date:
- Size: 4.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b1de7faebfb1e76f8e6592e5be75e52bafb445270440efa17285e27bd9e81a4f
|
|
| MD5 |
0b7682e49a8c9a64eb58588ad11820c3
|
|
| BLAKE2b-256 |
c9d4ce75e2f24a8907bf9c2b83f91d37e93b9695c0a9b15289179416ccf1e236
|
Provenance
The following attestation bundles were made for kubeman-0.2.0-py3-none-any.whl:
Publisher:
publish.yml on jasonzh0/kubeman
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
kubeman-0.2.0-py3-none-any.whl -
Subject digest:
b1de7faebfb1e76f8e6592e5be75e52bafb445270440efa17285e27bd9e81a4f - Sigstore transparency entry: 715771946
- Sigstore integration time:
-
Permalink:
jasonzh0/kubeman@238854ec1d8ecd7753a96d65b7a244bd8572a1d1 -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/jasonzh0
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@238854ec1d8ecd7753a96d65b7a244bd8572a1d1 -
Trigger Event:
release
-
Statement type: