Initial commit
This commit is contained in:
156
scripts/applicationset_generator.py
Normal file
156
scripts/applicationset_generator.py
Normal file
@@ -0,0 +1,156 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Generate ArgoCD ApplicationSet manifests for multi-cluster deployments.
|
||||
Supports Cluster, List, and Matrix generators (ArgoCD 3.x).
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import sys
|
||||
import yaml
|
||||
|
||||
|
||||
APPLICATIONSET_TEMPLATE = """---
|
||||
apiVersion: argoproj.io/v1alpha1
|
||||
kind: ApplicationSet
|
||||
metadata:
|
||||
name: {name}
|
||||
namespace: argocd
|
||||
spec:
|
||||
goTemplate: true
|
||||
goTemplateOptions: ["missingkey=error"]
|
||||
generators:
|
||||
{generators}
|
||||
template:
|
||||
metadata:
|
||||
name: '{{{{.name}}}}-{name}'
|
||||
labels:
|
||||
environment: '{{{{.environment}}}}'
|
||||
spec:
|
||||
project: default
|
||||
source:
|
||||
repoURL: {repo_url}
|
||||
targetRevision: {target_revision}
|
||||
path: '{path}'
|
||||
destination:
|
||||
server: '{{{{.server}}}}'
|
||||
namespace: {namespace}
|
||||
syncPolicy:
|
||||
automated:
|
||||
prune: true
|
||||
selfHeal: true
|
||||
syncOptions:
|
||||
- CreateNamespace=true
|
||||
"""
|
||||
|
||||
|
||||
def generate_cluster_generator(label_selector: str = "") -> str:
|
||||
"""Generate Cluster generator."""
|
||||
selector = f"\n selector:\n matchLabels:\n {label_selector}" if label_selector else ""
|
||||
return f""" - cluster: {{{selector}}}"""
|
||||
|
||||
|
||||
def generate_list_generator(clusters: list) -> str:
|
||||
"""Generate List generator."""
|
||||
elements = "\n".join([f" - name: {c['name']}\n server: {c['server']}\n environment: {c.get('environment', 'production')}"
|
||||
for c in clusters])
|
||||
return f""" - list:
|
||||
elements:
|
||||
{elements}"""
|
||||
|
||||
|
||||
def generate_matrix_generator(cluster_label: str, git_directories: list) -> str:
|
||||
"""Generate Matrix generator (Cluster x Git directories)."""
|
||||
git_list = "\n".join([f" - path: {d}" for d in git_directories])
|
||||
return f""" - matrix:
|
||||
generators:
|
||||
- cluster:
|
||||
selector:
|
||||
matchLabels:
|
||||
environment: {cluster_label}
|
||||
- git:
|
||||
repoURL: https://github.com/example/apps
|
||||
revision: HEAD
|
||||
directories:
|
||||
{git_list}"""
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(
|
||||
description='Generate ArgoCD ApplicationSet manifests',
|
||||
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||
epilog="""
|
||||
Examples:
|
||||
# Cluster generator (all clusters)
|
||||
python3 applicationset_generator.py cluster \\
|
||||
--name my-apps \\
|
||||
--repo-url https://github.com/org/repo \\
|
||||
--path apps/
|
||||
|
||||
# List generator (specific clusters)
|
||||
python3 applicationset_generator.py list \\
|
||||
--name my-apps \\
|
||||
--clusters prod=https://prod.k8s.local,staging=https://staging.k8s.local
|
||||
|
||||
# Matrix generator (cluster x directories)
|
||||
python3 applicationset_generator.py matrix \\
|
||||
--name my-apps \\
|
||||
--cluster-label production \\
|
||||
--directories app1,app2,app3
|
||||
"""
|
||||
)
|
||||
|
||||
parser.add_argument('generator_type', choices=['cluster', 'list', 'matrix'],
|
||||
help='Generator type')
|
||||
parser.add_argument('--name', required=True, help='ApplicationSet name')
|
||||
parser.add_argument('--repo-url', default='https://github.com/example/repo',
|
||||
help='Git repository URL')
|
||||
parser.add_argument('--path', default='apps/', help='Path in repository')
|
||||
parser.add_argument('--namespace', default='default', help='Target namespace')
|
||||
parser.add_argument('--target-revision', default='main', help='Git branch/tag')
|
||||
parser.add_argument('--cluster-label', help='Cluster label selector')
|
||||
parser.add_argument('--clusters', help='Cluster list (name=server,name=server)')
|
||||
parser.add_argument('--directories', help='Git directories (comma-separated)')
|
||||
parser.add_argument('--output', help='Output file')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
# Generate based on type
|
||||
if args.generator_type == 'cluster':
|
||||
generators = generate_cluster_generator(args.cluster_label or "")
|
||||
elif args.generator_type == 'list':
|
||||
if not args.clusters:
|
||||
print("❌ --clusters required for list generator")
|
||||
sys.exit(1)
|
||||
cluster_list = []
|
||||
for c in args.clusters.split(','):
|
||||
name, server = c.split('=')
|
||||
cluster_list.append({'name': name, 'server': server})
|
||||
generators = generate_list_generator(cluster_list)
|
||||
elif args.generator_type == 'matrix':
|
||||
if not args.cluster_label or not args.directories:
|
||||
print("❌ --cluster-label and --directories required for matrix generator")
|
||||
sys.exit(1)
|
||||
directories = args.directories.split(',')
|
||||
generators = generate_matrix_generator(args.cluster_label, directories)
|
||||
|
||||
# Create ApplicationSet
|
||||
appset = APPLICATIONSET_TEMPLATE.format(
|
||||
name=args.name,
|
||||
generators=generators,
|
||||
repo_url=args.repo_url,
|
||||
target_revision=args.target_revision,
|
||||
path=args.path,
|
||||
namespace=args.namespace
|
||||
)
|
||||
|
||||
# Output
|
||||
if args.output:
|
||||
with open(args.output, 'w') as f:
|
||||
f.write(appset)
|
||||
print(f"✅ ApplicationSet written to: {args.output}")
|
||||
else:
|
||||
print(appset)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
Reference in New Issue
Block a user