import { z } from "zod";
// --- Tools ---
export const generateTerraformResourceSchema = {
name: "generate_terraform_resource",
description: "Generate Terraform resource blocks for common cloud providers.",
inputSchema: z.object({
provider: z.enum(["aws", "google", "azure"]).describe("Cloud provider"),
resourceType: z.string().describe("Resource type (e.g., s3_bucket, compute_instance)"),
name: z.string().describe("Resource name identifier"),
properties: z.record(z.any()).describe("Resource properties"),
}),
};
export const generateTerraformConfigSchema = {
name: "generate_terraform_config",
description: "Generates basic Terraform configuration for cloud providers",
inputSchema: z.object({
provider: z.enum(["aws", "gcp", "azure"]).describe("Cloud provider"),
resources: z.array(z.string()).describe("List of resources (e.g. 'vm', 'bucket', 'db')"),
region: z.string().default("us-east-1")
})
};
export const generateK8sManifestSchema = {
name: "generate_k8s_manifest",
description: "Generates Kubernetes manifests (Deployment, Service, Ingress)",
inputSchema: z.object({
name: z.string().describe("Application name"),
image: z.string().describe("Docker image"),
port: z.number().default(80),
replicas: z.number().default(1),
namespace: z.string().default("default"),
kind: z.enum(["Deployment", "Service", "ConfigMap", "Ingress", "Secret"]).default("Deployment").describe("K8s resource kind"),
spec: z.record(z.any()).optional().describe("Resource specification details (overrides defaults)")
}),
};
export const generateObservabilitySchema = {
name: "generate_observability_config",
description: "Generate observability configurations (Prometheus, Grafana).",
inputSchema: z.object({
type: z.enum(["prometheus", "grafana-dashboard"]).describe("Config type"),
appName: z.string().describe("Application name"),
}),
};
export const generateNginxConfigSchema = {
name: "generate_nginx_config",
description: "Generates Nginx configuration for reverse proxy or static site",
inputSchema: z.object({
domain: z.string().describe("Domain name"),
proxyTo: z.string().optional().describe("Upstream URL (e.g. http://localhost:3000)"),
rootPath: z.string().optional().describe("Root path for static files")
})
};
// --- Handlers ---
export async function generateTerraformResourceHandler(args: { provider: string, resourceType: string, name: string, properties: Record<string, any> }) {
const { provider, resourceType, name, properties } = args;
// Basic HCL generation
let hcl = `resource "${provider}_${resourceType}" "${name}" {\n`;
for (const [key, value] of Object.entries(properties)) {
const valStr = typeof value === 'string' ? `"${value}"` : value;
hcl += ` ${key} = ${valStr}\n`;
}
hcl += "}";
return {
content: [{ type: "text", text: hcl }]
};
}
export async function generateTerraformConfigHandler(args: { provider: string; resources: string[]; region: string }) {
const { provider, resources, region } = args;
let content = `provider "${provider}" {\n region = "${region}"\n}\n\n`;
if (provider === "aws") {
if (resources.some(r => r.includes("bucket"))) {
content += `resource "aws_s3_bucket" "main" {\n bucket = "my-app-bucket"\n acl = "private"\n}\n`;
}
if (resources.some(r => r.includes("vm"))) {
content += `resource "aws_instance" "web" {\n ami = "ami-12345678"\n instance_type = "t2.micro"\n}\n`;
}
} else {
content += `# TODO: Add templates for ${provider} resources: ${resources.join(", ")}`;
}
return {
content: [{
type: "text",
text: `# Terraform Config (${provider})\n\n\`\`\`hcl\n${content}\n\`\`\``
}]
};
}
export async function generateK8sManifestHandler(args: { name: string; image: string; port: number; replicas: number; namespace: string; kind: string; spec?: Record<string, any> }) {
const { name, image, port, replicas, namespace, kind, spec } = args;
if (spec) {
// Fallback/Custom spec handling (from original infrastructure.ts)
const customManifest = {
apiVersion: "v1",
kind,
metadata: { name, namespace },
spec
};
return {
content: [{ type: "text", text: `apiVersion: ${customManifest.apiVersion}\nkind: ${customManifest.kind}\nmetadata:\n name: ${customManifest.metadata.name}\n namespace: ${customManifest.metadata.namespace}\nspec:\n ${JSON.stringify(customManifest.spec, null, 2)}` }]
};
}
// Default Deployment + Service generation (improved from deployment.ts)
const manifest = `apiVersion: apps/v1
kind: Deployment
metadata:
name: ${name}
namespace: ${namespace}
spec:
replicas: ${replicas}
selector:
matchLabels:
app: ${name}
template:
metadata:
labels:
app: ${name}
spec:
containers:
- name: ${name}
image: ${image}
ports:
- containerPort: ${port}
---
apiVersion: v1
kind: Service
metadata:
name: ${name}-svc
namespace: ${namespace}
spec:
selector:
app: ${name}
ports:
- protocol: TCP
port: 80
targetPort: ${port}
type: ClusterIP`;
return {
content: [{
type: "text",
text: `# Kubernetes Manifest\n\n\`\`\`yaml\n${manifest}\n\`\`\``
}]
};
}
export async function generateObservabilityHandler(args: { type: string, appName: string }) {
if (args.type === "prometheus") {
return {
content: [{
type: "text",
text: `scrape_configs:\n - job_name: '${args.appName}'\n static_configs:\n - targets: ['${args.appName}:metrics']`
}]
};
}
// Grafana dashboard stub
return {
content: [{
type: "text",
text: JSON.stringify({
title: `${args.appName} Dashboard`,
panels: [
{ title: "Memory Usage", type: "graph", targets: [{ expr: `container_memory_usage_bytes{pod=~"${args.appName}.*"}` }] },
{ title: "CPU Usage", type: "graph", targets: [{ expr: `rate(container_cpu_usage_seconds_total{pod=~"${args.appName}.*"}[5m])` }] }
]
}, null, 2)
}]
};
}
export async function generateNginxConfigHandler(args: { domain: string; proxyTo?: string; rootPath?: string }) {
const { domain, proxyTo, rootPath } = args;
const config = `server {
listen 80;
server_name ${domain};
${rootPath ? `root ${rootPath};\n index index.html;` : ''}
location / {
${proxyTo ? `proxy_pass ${proxyTo};
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;` : 'try_files $uri $uri/ =404;'}
}
}`;
return {
content: [{
type: "text",
text: `# Nginx Config\n\n\`\`\`nginx\n${config}\n\`\`\``
}]
};
}