@techwavedev/agi-agent-kit 1.1.7 → 1.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of @techwavedev/agi-agent-kit might be problematic. Click here for more details.
- package/CHANGELOG.md +82 -1
- package/README.md +190 -12
- package/bin/init.js +30 -2
- package/package.json +6 -3
- package/templates/base/AGENTS.md +54 -23
- package/templates/base/README.md +325 -0
- package/templates/base/directives/memory_integration.md +95 -0
- package/templates/base/execution/memory_manager.py +309 -0
- package/templates/base/execution/session_boot.py +218 -0
- package/templates/base/execution/session_init.py +320 -0
- package/templates/base/skill-creator/SKILL_skillcreator.md +23 -36
- package/templates/base/skill-creator/scripts/init_skill.py +18 -135
- package/templates/skills/ec/README.md +31 -0
- package/templates/skills/ec/aws/SKILL.md +1020 -0
- package/templates/skills/ec/aws/defaults.yaml +13 -0
- package/templates/skills/ec/aws/references/common_patterns.md +80 -0
- package/templates/skills/ec/aws/references/mcp_servers.md +98 -0
- package/templates/skills/ec/aws-terraform/SKILL.md +349 -0
- package/templates/skills/ec/aws-terraform/references/best_practices.md +394 -0
- package/templates/skills/ec/aws-terraform/references/checkov_reference.md +337 -0
- package/templates/skills/ec/aws-terraform/scripts/configure_mcp.py +150 -0
- package/templates/skills/ec/confluent-kafka/SKILL.md +655 -0
- package/templates/skills/ec/confluent-kafka/references/ansible_playbooks.md +792 -0
- package/templates/skills/ec/confluent-kafka/references/ec_deployment.md +579 -0
- package/templates/skills/ec/confluent-kafka/references/kraft_migration.md +490 -0
- package/templates/skills/ec/confluent-kafka/references/troubleshooting.md +778 -0
- package/templates/skills/ec/confluent-kafka/references/upgrade_7x_to_8x.md +488 -0
- package/templates/skills/ec/confluent-kafka/scripts/kafka_health_check.py +435 -0
- package/templates/skills/ec/confluent-kafka/scripts/upgrade_preflight.py +568 -0
- package/templates/skills/ec/confluent-kafka/scripts/validate_config.py +455 -0
- package/templates/skills/ec/consul/SKILL.md +427 -0
- package/templates/skills/ec/consul/references/acl_setup.md +168 -0
- package/templates/skills/ec/consul/references/ha_config.md +196 -0
- package/templates/skills/ec/consul/references/troubleshooting.md +267 -0
- package/templates/skills/ec/consul/references/upgrades.md +213 -0
- package/templates/skills/ec/consul/scripts/consul_health_report.py +530 -0
- package/templates/skills/ec/consul/scripts/consul_status.py +264 -0
- package/templates/skills/ec/consul/scripts/generate_values.py +170 -0
- package/templates/skills/ec/documentation/SKILL.md +351 -0
- package/templates/skills/ec/documentation/references/best_practices.md +201 -0
- package/templates/skills/ec/documentation/scripts/analyze_code.py +307 -0
- package/templates/skills/ec/documentation/scripts/detect_changes.py +460 -0
- package/templates/skills/ec/documentation/scripts/generate_changelog.py +312 -0
- package/templates/skills/ec/documentation/scripts/sync_docs.py +272 -0
- package/templates/skills/ec/documentation/scripts/update_skill_docs.py +366 -0
- package/templates/skills/ec/gitlab/SKILL.md +529 -0
- package/templates/skills/ec/gitlab/references/agent_installation.md +416 -0
- package/templates/skills/ec/gitlab/references/api_reference.md +508 -0
- package/templates/skills/ec/gitlab/references/gitops_flux.md +465 -0
- package/templates/skills/ec/gitlab/references/troubleshooting.md +518 -0
- package/templates/skills/ec/gitlab/scripts/generate_agent_values.py +329 -0
- package/templates/skills/ec/gitlab/scripts/gitlab_agent_status.py +414 -0
- package/templates/skills/ec/jira/SKILL.md +484 -0
- package/templates/skills/ec/jira/references/jql_reference.md +148 -0
- package/templates/skills/ec/jira/scripts/add_comment.py +91 -0
- package/templates/skills/ec/jira/scripts/bulk_log_work.py +124 -0
- package/templates/skills/ec/jira/scripts/create_ticket.py +162 -0
- package/templates/skills/ec/jira/scripts/get_ticket.py +191 -0
- package/templates/skills/ec/jira/scripts/jira_client.py +383 -0
- package/templates/skills/ec/jira/scripts/log_work.py +154 -0
- package/templates/skills/ec/jira/scripts/search_tickets.py +104 -0
- package/templates/skills/ec/jira/scripts/update_comment.py +67 -0
- package/templates/skills/ec/jira/scripts/update_ticket.py +161 -0
- package/templates/skills/ec/karpenter/SKILL.md +301 -0
- package/templates/skills/ec/karpenter/references/ec2nodeclasses.md +421 -0
- package/templates/skills/ec/karpenter/references/migration.md +396 -0
- package/templates/skills/ec/karpenter/references/nodepools.md +400 -0
- package/templates/skills/ec/karpenter/references/troubleshooting.md +359 -0
- package/templates/skills/ec/karpenter/scripts/generate_ec2nodeclass.py +187 -0
- package/templates/skills/ec/karpenter/scripts/generate_nodepool.py +245 -0
- package/templates/skills/ec/karpenter/scripts/karpenter_status.py +359 -0
- package/templates/skills/ec/opensearch/SKILL.md +720 -0
- package/templates/skills/ec/opensearch/references/ml_neural_search.md +576 -0
- package/templates/skills/ec/opensearch/references/operator.md +532 -0
- package/templates/skills/ec/opensearch/references/query_dsl.md +532 -0
- package/templates/skills/ec/opensearch/scripts/configure_mcp.py +148 -0
- package/templates/skills/ec/victoriametrics/SKILL.md +598 -0
- package/templates/skills/ec/victoriametrics/references/kubernetes.md +531 -0
- package/templates/skills/ec/victoriametrics/references/prometheus_migration.md +333 -0
- package/templates/skills/ec/victoriametrics/references/troubleshooting.md +442 -0
- package/templates/skills/knowledge/SKILLS_CATALOG.md +274 -4
- package/templates/skills/knowledge/intelligent-routing/SKILL.md +237 -164
- package/templates/skills/knowledge/parallel-agents/SKILL.md +345 -73
- package/templates/skills/knowledge/plugin-discovery/SKILL.md +582 -0
- package/templates/skills/knowledge/plugin-discovery/scripts/platform_setup.py +1083 -0
- package/templates/skills/knowledge/design-md/README.md +0 -34
- package/templates/skills/knowledge/design-md/SKILL.md +0 -193
- package/templates/skills/knowledge/design-md/examples/DESIGN.md +0 -154
- package/templates/skills/knowledge/notebooklm-mcp/SKILL.md +0 -71
- package/templates/skills/knowledge/notebooklm-mcp/assets/example_asset.txt +0 -24
- package/templates/skills/knowledge/notebooklm-mcp/references/api_reference.md +0 -34
- package/templates/skills/knowledge/notebooklm-mcp/scripts/example.py +0 -19
- package/templates/skills/knowledge/react-components/README.md +0 -36
- package/templates/skills/knowledge/react-components/SKILL.md +0 -53
- package/templates/skills/knowledge/react-components/examples/gold-standard-card.tsx +0 -80
- package/templates/skills/knowledge/react-components/package-lock.json +0 -231
- package/templates/skills/knowledge/react-components/package.json +0 -16
- package/templates/skills/knowledge/react-components/resources/architecture-checklist.md +0 -15
- package/templates/skills/knowledge/react-components/resources/component-template.tsx +0 -37
- package/templates/skills/knowledge/react-components/resources/stitch-api-reference.md +0 -14
- package/templates/skills/knowledge/react-components/resources/style-guide.json +0 -27
- package/templates/skills/knowledge/react-components/scripts/fetch-stitch.sh +0 -30
- package/templates/skills/knowledge/react-components/scripts/validate.js +0 -68
- package/templates/skills/knowledge/self-update/SKILL.md +0 -60
- package/templates/skills/knowledge/self-update/scripts/update_kit.py +0 -103
- package/templates/skills/knowledge/stitch-loop/README.md +0 -54
- package/templates/skills/knowledge/stitch-loop/SKILL.md +0 -235
- package/templates/skills/knowledge/stitch-loop/examples/SITE.md +0 -73
- package/templates/skills/knowledge/stitch-loop/examples/next-prompt.md +0 -25
- package/templates/skills/knowledge/stitch-loop/resources/baton-schema.md +0 -61
- package/templates/skills/knowledge/stitch-loop/resources/site-template.md +0 -104
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Script: consul_status.py
|
|
4
|
+
Purpose: Get comprehensive status of Consul cluster on Kubernetes
|
|
5
|
+
|
|
6
|
+
Usage:
|
|
7
|
+
python consul_status.py --namespace consul [--context <context>]
|
|
8
|
+
|
|
9
|
+
Arguments:
|
|
10
|
+
--namespace Kubernetes namespace where Consul is installed (default: consul)
|
|
11
|
+
--context Kubernetes context to use (optional)
|
|
12
|
+
--json Output in JSON format
|
|
13
|
+
|
|
14
|
+
Exit Codes:
|
|
15
|
+
0 - Success
|
|
16
|
+
1 - Invalid arguments
|
|
17
|
+
2 - kubectl/cluster not accessible
|
|
18
|
+
3 - Consul not found
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
import argparse
|
|
22
|
+
import json
|
|
23
|
+
import subprocess
|
|
24
|
+
import sys
|
|
25
|
+
from typing import Dict, Any, Optional
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def run_kubectl(args: list, context: Optional[str] = None) -> tuple:
|
|
29
|
+
"""Run kubectl command and return (success, output)."""
|
|
30
|
+
cmd = ["kubectl"]
|
|
31
|
+
if context:
|
|
32
|
+
cmd.extend(["--context", context])
|
|
33
|
+
cmd.extend(args)
|
|
34
|
+
|
|
35
|
+
try:
|
|
36
|
+
result = subprocess.run(cmd, capture_output=True, text=True, timeout=30)
|
|
37
|
+
return result.returncode == 0, result.stdout.strip(), result.stderr.strip()
|
|
38
|
+
except subprocess.TimeoutExpired:
|
|
39
|
+
return False, "", "Command timed out"
|
|
40
|
+
except Exception as e:
|
|
41
|
+
return False, "", str(e)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def get_bootstrap_token(namespace: str, context: Optional[str] = None) -> Optional[str]:
|
|
45
|
+
"""Retrieve bootstrap ACL token from Kubernetes secret."""
|
|
46
|
+
cmd = ["kubectl"]
|
|
47
|
+
if context:
|
|
48
|
+
cmd.extend(["--context", context])
|
|
49
|
+
cmd.extend([
|
|
50
|
+
"get", "secret", "consul-bootstrap-acl-token",
|
|
51
|
+
"-n", namespace,
|
|
52
|
+
"-o", "jsonpath={.data.token}"
|
|
53
|
+
])
|
|
54
|
+
|
|
55
|
+
try:
|
|
56
|
+
result = subprocess.run(cmd, capture_output=True, text=True, timeout=10)
|
|
57
|
+
if result.returncode == 0 and result.stdout:
|
|
58
|
+
import base64
|
|
59
|
+
return base64.b64decode(result.stdout).decode('utf-8').strip()
|
|
60
|
+
except Exception:
|
|
61
|
+
pass
|
|
62
|
+
return None
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def run_consul_cmd(namespace: str, cmd: str, context: Optional[str] = None, token: Optional[str] = None) -> tuple:
|
|
66
|
+
"""Run consul command inside server pod with optional ACL token."""
|
|
67
|
+
consul_cmd = cmd.split()
|
|
68
|
+
if token:
|
|
69
|
+
consul_cmd.extend(["-token", token])
|
|
70
|
+
|
|
71
|
+
kubectl_args = [
|
|
72
|
+
"exec", "-n", namespace, "consul-server-0", "--",
|
|
73
|
+
"consul"
|
|
74
|
+
] + consul_cmd
|
|
75
|
+
return run_kubectl(kubectl_args, context)
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def get_pods_status(namespace: str, context: Optional[str] = None) -> Dict[str, Any]:
|
|
79
|
+
"""Get status of Consul pods."""
|
|
80
|
+
success, output, _ = run_kubectl(
|
|
81
|
+
["get", "pods", "-n", namespace, "-l", "app=consul",
|
|
82
|
+
"-o", "json"],
|
|
83
|
+
context
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
if not success:
|
|
87
|
+
return {"error": "Failed to get pods"}
|
|
88
|
+
|
|
89
|
+
try:
|
|
90
|
+
pods_data = json.loads(output)
|
|
91
|
+
pods = []
|
|
92
|
+
for pod in pods_data.get("items", []):
|
|
93
|
+
pod_info = {
|
|
94
|
+
"name": pod["metadata"]["name"],
|
|
95
|
+
"status": pod["status"]["phase"],
|
|
96
|
+
"ready": all(c.get("ready", False)
|
|
97
|
+
for c in pod["status"].get("containerStatuses", [])),
|
|
98
|
+
"restarts": sum(c.get("restartCount", 0)
|
|
99
|
+
for c in pod["status"].get("containerStatuses", [])),
|
|
100
|
+
"node": pod["spec"].get("nodeName", "unknown")
|
|
101
|
+
}
|
|
102
|
+
pods.append(pod_info)
|
|
103
|
+
return {"pods": pods, "total": len(pods)}
|
|
104
|
+
except json.JSONDecodeError:
|
|
105
|
+
return {"error": "Failed to parse pods JSON"}
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
def get_cluster_members(namespace: str, context: Optional[str] = None, token: Optional[str] = None) -> Dict[str, Any]:
|
|
109
|
+
"""Get Consul cluster members."""
|
|
110
|
+
success, output, error = run_consul_cmd(namespace, "members", context, token)
|
|
111
|
+
|
|
112
|
+
if not success:
|
|
113
|
+
return {"error": f"Failed to get members: {error}"}
|
|
114
|
+
|
|
115
|
+
members = []
|
|
116
|
+
lines = output.strip().split("\n")
|
|
117
|
+
for line in lines[1:]: # Skip header
|
|
118
|
+
parts = line.split()
|
|
119
|
+
if len(parts) >= 4:
|
|
120
|
+
members.append({
|
|
121
|
+
"name": parts[0],
|
|
122
|
+
"address": parts[1],
|
|
123
|
+
"status": parts[2],
|
|
124
|
+
"type": parts[3]
|
|
125
|
+
})
|
|
126
|
+
|
|
127
|
+
return {"members": members, "total": len(members)}
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
def get_raft_status(namespace: str, context: Optional[str] = None, token: Optional[str] = None) -> Dict[str, Any]:
|
|
131
|
+
"""Get Raft consensus status."""
|
|
132
|
+
success, output, error = run_consul_cmd(
|
|
133
|
+
namespace, "operator raft list-peers", context, token
|
|
134
|
+
)
|
|
135
|
+
|
|
136
|
+
if not success:
|
|
137
|
+
return {"error": f"Failed to get raft status: {error}"}
|
|
138
|
+
|
|
139
|
+
peers = []
|
|
140
|
+
leader = None
|
|
141
|
+
lines = output.strip().split("\n")
|
|
142
|
+
for line in lines[1:]: # Skip header
|
|
143
|
+
parts = line.split()
|
|
144
|
+
if len(parts) >= 4:
|
|
145
|
+
peer = {
|
|
146
|
+
"node": parts[0],
|
|
147
|
+
"id": parts[1] if len(parts) > 1 else "",
|
|
148
|
+
"address": parts[2] if len(parts) > 2 else "",
|
|
149
|
+
"state": parts[3] if len(parts) > 3 else "",
|
|
150
|
+
"voter": parts[4] if len(parts) > 4 else ""
|
|
151
|
+
}
|
|
152
|
+
peers.append(peer)
|
|
153
|
+
if peer["state"] == "leader":
|
|
154
|
+
leader = peer["node"]
|
|
155
|
+
|
|
156
|
+
return {"peers": peers, "leader": leader, "total": len(peers)}
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
def get_helm_info(namespace: str, context: Optional[str] = None) -> Dict[str, Any]:
|
|
160
|
+
"""Get Helm release info."""
|
|
161
|
+
cmd = ["helm", "list", "-n", namespace, "-o", "json"]
|
|
162
|
+
if context:
|
|
163
|
+
cmd.extend(["--kube-context", context])
|
|
164
|
+
|
|
165
|
+
try:
|
|
166
|
+
result = subprocess.run(cmd, capture_output=True, text=True, timeout=30)
|
|
167
|
+
if result.returncode == 0:
|
|
168
|
+
releases = json.loads(result.stdout)
|
|
169
|
+
for release in releases:
|
|
170
|
+
if release.get("name") == "consul":
|
|
171
|
+
return {
|
|
172
|
+
"name": release["name"],
|
|
173
|
+
"version": release.get("chart", ""),
|
|
174
|
+
"app_version": release.get("app_version", ""),
|
|
175
|
+
"status": release.get("status", ""),
|
|
176
|
+
"updated": release.get("updated", "")
|
|
177
|
+
}
|
|
178
|
+
return {"error": "Consul release not found"}
|
|
179
|
+
return {"error": result.stderr}
|
|
180
|
+
except Exception as e:
|
|
181
|
+
return {"error": str(e)}
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
def main():
|
|
185
|
+
parser = argparse.ArgumentParser(description="Get Consul cluster status")
|
|
186
|
+
parser.add_argument("--namespace", "-n", default="consul",
|
|
187
|
+
help="Kubernetes namespace (default: consul)")
|
|
188
|
+
parser.add_argument("--context", "-c", default=None,
|
|
189
|
+
help="Kubernetes context")
|
|
190
|
+
parser.add_argument("--json", action="store_true",
|
|
191
|
+
help="Output in JSON format")
|
|
192
|
+
args = parser.parse_args()
|
|
193
|
+
|
|
194
|
+
# Retrieve bootstrap token for ACL-enabled clusters
|
|
195
|
+
token = get_bootstrap_token(args.namespace, args.context)
|
|
196
|
+
|
|
197
|
+
status = {
|
|
198
|
+
"namespace": args.namespace,
|
|
199
|
+
"acl_token_found": token is not None,
|
|
200
|
+
"helm": get_helm_info(args.namespace, args.context),
|
|
201
|
+
"pods": get_pods_status(args.namespace, args.context),
|
|
202
|
+
"members": get_cluster_members(args.namespace, args.context, token),
|
|
203
|
+
"raft": get_raft_status(args.namespace, args.context, token)
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
if args.json:
|
|
207
|
+
print(json.dumps(status, indent=2))
|
|
208
|
+
else:
|
|
209
|
+
print(f"\n{'='*60}")
|
|
210
|
+
print(f"CONSUL STATUS - Namespace: {args.namespace}")
|
|
211
|
+
print(f"{'='*60}\n")
|
|
212
|
+
|
|
213
|
+
# Helm info
|
|
214
|
+
helm = status["helm"]
|
|
215
|
+
if "error" not in helm:
|
|
216
|
+
print(f"📦 Helm Release: {helm.get('name', 'N/A')}")
|
|
217
|
+
print(f" Chart: {helm.get('version', 'N/A')}")
|
|
218
|
+
print(f" App Version: {helm.get('app_version', 'N/A')}")
|
|
219
|
+
print(f" Status: {helm.get('status', 'N/A')}")
|
|
220
|
+
else:
|
|
221
|
+
print(f"❌ Helm: {helm['error']}")
|
|
222
|
+
print()
|
|
223
|
+
|
|
224
|
+
# Pods
|
|
225
|
+
pods = status["pods"]
|
|
226
|
+
if "error" not in pods:
|
|
227
|
+
print(f"🔵 Pods ({pods['total']} total):")
|
|
228
|
+
for pod in pods.get("pods", []):
|
|
229
|
+
icon = "✅" if pod["ready"] else "❌"
|
|
230
|
+
print(f" {icon} {pod['name']}: {pod['status']} (restarts: {pod['restarts']})")
|
|
231
|
+
else:
|
|
232
|
+
print(f"❌ Pods: {pods['error']}")
|
|
233
|
+
print()
|
|
234
|
+
|
|
235
|
+
# Raft
|
|
236
|
+
raft = status["raft"]
|
|
237
|
+
if "error" not in raft:
|
|
238
|
+
print(f"🗳️ Raft Consensus ({raft['total']} peers):")
|
|
239
|
+
print(f" Leader: {raft.get('leader', 'NONE')}")
|
|
240
|
+
for peer in raft.get("peers", []):
|
|
241
|
+
icon = "👑" if peer["state"] == "leader" else " "
|
|
242
|
+
print(f" {icon} {peer['node']}: {peer['state']}")
|
|
243
|
+
else:
|
|
244
|
+
print(f"❌ Raft: {raft['error']}")
|
|
245
|
+
print()
|
|
246
|
+
|
|
247
|
+
# Summary
|
|
248
|
+
healthy = (
|
|
249
|
+
"error" not in pods and
|
|
250
|
+
"error" not in raft and
|
|
251
|
+
raft.get("leader") is not None
|
|
252
|
+
)
|
|
253
|
+
print(f"{'='*60}")
|
|
254
|
+
if healthy:
|
|
255
|
+
print("✅ Cluster Status: HEALTHY")
|
|
256
|
+
else:
|
|
257
|
+
print("❌ Cluster Status: UNHEALTHY")
|
|
258
|
+
print(f"{'='*60}\n")
|
|
259
|
+
|
|
260
|
+
sys.exit(0)
|
|
261
|
+
|
|
262
|
+
|
|
263
|
+
if __name__ == "__main__":
|
|
264
|
+
main()
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Script: generate_values.py
|
|
4
|
+
Purpose: Generate Consul Helm values file based on configuration options
|
|
5
|
+
|
|
6
|
+
Usage:
|
|
7
|
+
python generate_values.py --datacenter dc1 --replicas 3 [options]
|
|
8
|
+
|
|
9
|
+
Arguments:
|
|
10
|
+
--datacenter Datacenter name (required)
|
|
11
|
+
--replicas Number of server replicas (3 or 5)
|
|
12
|
+
--connect-inject Enable Connect sidecar injection
|
|
13
|
+
--acls Enable ACL system
|
|
14
|
+
--tls Enable TLS
|
|
15
|
+
--mesh-gateway Enable mesh gateway
|
|
16
|
+
--ingress-gateway Enable ingress gateway
|
|
17
|
+
--output Output file path (default: stdout)
|
|
18
|
+
|
|
19
|
+
Exit Codes:
|
|
20
|
+
0 - Success
|
|
21
|
+
1 - Invalid arguments
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
import argparse
|
|
25
|
+
import sys
|
|
26
|
+
import yaml
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def generate_values(args) -> dict:
|
|
30
|
+
"""Generate Consul Helm values based on arguments."""
|
|
31
|
+
|
|
32
|
+
values = {
|
|
33
|
+
"global": {
|
|
34
|
+
"name": "consul",
|
|
35
|
+
"datacenter": args.datacenter,
|
|
36
|
+
},
|
|
37
|
+
"server": {
|
|
38
|
+
"replicas": args.replicas,
|
|
39
|
+
"bootstrapExpect": args.replicas,
|
|
40
|
+
"resources": {
|
|
41
|
+
"requests": {
|
|
42
|
+
"memory": "200Mi",
|
|
43
|
+
"cpu": "100m"
|
|
44
|
+
},
|
|
45
|
+
"limits": {
|
|
46
|
+
"memory": "500Mi",
|
|
47
|
+
"cpu": "500m"
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
"storageClass": "gp3",
|
|
51
|
+
"storage": "10Gi"
|
|
52
|
+
},
|
|
53
|
+
"connectInject": {
|
|
54
|
+
"enabled": args.connect_inject,
|
|
55
|
+
"default": False
|
|
56
|
+
},
|
|
57
|
+
"controller": {
|
|
58
|
+
"enabled": args.connect_inject
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
# Server anti-affinity for HA
|
|
63
|
+
if args.replicas >= 3:
|
|
64
|
+
values["server"]["affinity"] = """
|
|
65
|
+
podAntiAffinity:
|
|
66
|
+
requiredDuringSchedulingIgnoredDuringExecution:
|
|
67
|
+
- labelSelector:
|
|
68
|
+
matchLabels:
|
|
69
|
+
app: consul
|
|
70
|
+
component: server
|
|
71
|
+
topologyKey: kubernetes.io/hostname"""
|
|
72
|
+
|
|
73
|
+
# ACLs
|
|
74
|
+
if args.acls:
|
|
75
|
+
values["global"]["acls"] = {
|
|
76
|
+
"manageSystemACLs": True
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
# TLS
|
|
80
|
+
if args.tls:
|
|
81
|
+
values["global"]["tls"] = {
|
|
82
|
+
"enabled": True,
|
|
83
|
+
"enableAutoEncrypt": True
|
|
84
|
+
}
|
|
85
|
+
values["global"]["gossipEncryption"] = {
|
|
86
|
+
"autoGenerate": True
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
# Mesh Gateway
|
|
90
|
+
if args.mesh_gateway:
|
|
91
|
+
values["meshGateway"] = {
|
|
92
|
+
"enabled": True,
|
|
93
|
+
"replicas": 2
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
# Ingress Gateway
|
|
97
|
+
if args.ingress_gateway:
|
|
98
|
+
values["ingressGateway"] = {
|
|
99
|
+
"enabled": True,
|
|
100
|
+
"defaults": {
|
|
101
|
+
"replicas": 2
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
# Scale resources for larger clusters
|
|
106
|
+
if args.replicas >= 5:
|
|
107
|
+
values["server"]["resources"]["requests"]["memory"] = "500Mi"
|
|
108
|
+
values["server"]["resources"]["requests"]["cpu"] = "200m"
|
|
109
|
+
values["server"]["resources"]["limits"]["memory"] = "1Gi"
|
|
110
|
+
values["server"]["resources"]["limits"]["cpu"] = "1000m"
|
|
111
|
+
values["server"]["storage"] = "20Gi"
|
|
112
|
+
|
|
113
|
+
return values
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
def main():
|
|
117
|
+
parser = argparse.ArgumentParser(
|
|
118
|
+
description="Generate Consul Helm values file"
|
|
119
|
+
)
|
|
120
|
+
parser.add_argument("--datacenter", "-d", required=True,
|
|
121
|
+
help="Datacenter name")
|
|
122
|
+
parser.add_argument("--replicas", "-r", type=int, default=3,
|
|
123
|
+
choices=[1, 3, 5],
|
|
124
|
+
help="Number of server replicas (default: 3)")
|
|
125
|
+
parser.add_argument("--connect-inject", action="store_true",
|
|
126
|
+
help="Enable Connect sidecar injection")
|
|
127
|
+
parser.add_argument("--acls", action="store_true",
|
|
128
|
+
help="Enable ACL system")
|
|
129
|
+
parser.add_argument("--tls", action="store_true",
|
|
130
|
+
help="Enable TLS")
|
|
131
|
+
parser.add_argument("--mesh-gateway", action="store_true",
|
|
132
|
+
help="Enable mesh gateway")
|
|
133
|
+
parser.add_argument("--ingress-gateway", action="store_true",
|
|
134
|
+
help="Enable ingress gateway")
|
|
135
|
+
parser.add_argument("--output", "-o", default=None,
|
|
136
|
+
help="Output file path (default: stdout)")
|
|
137
|
+
|
|
138
|
+
args = parser.parse_args()
|
|
139
|
+
|
|
140
|
+
# Validate
|
|
141
|
+
if args.replicas == 1:
|
|
142
|
+
print("⚠️ Warning: Single server mode is not suitable for production",
|
|
143
|
+
file=sys.stderr)
|
|
144
|
+
|
|
145
|
+
values = generate_values(args)
|
|
146
|
+
|
|
147
|
+
# Add header comment
|
|
148
|
+
output = f"""# Consul Helm Values
|
|
149
|
+
# Generated for datacenter: {args.datacenter}
|
|
150
|
+
# Replicas: {args.replicas}
|
|
151
|
+
# Features: {'ACLs ' if args.acls else ''}{'TLS ' if args.tls else ''}{'Connect ' if args.connect_inject else ''}
|
|
152
|
+
#
|
|
153
|
+
# Install with:
|
|
154
|
+
# helm install consul hashicorp/consul -n consul -f <this-file>
|
|
155
|
+
#
|
|
156
|
+
"""
|
|
157
|
+
output += yaml.dump(values, default_flow_style=False, sort_keys=False)
|
|
158
|
+
|
|
159
|
+
if args.output:
|
|
160
|
+
with open(args.output, 'w') as f:
|
|
161
|
+
f.write(output)
|
|
162
|
+
print(f"✅ Values written to {args.output}")
|
|
163
|
+
else:
|
|
164
|
+
print(output)
|
|
165
|
+
|
|
166
|
+
sys.exit(0)
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
if __name__ == "__main__":
|
|
170
|
+
main()
|