check-kubernetes-cluster-fixed
Version:
MCP server to check Kubernetes cluster health and status
240 lines • 9.24 kB
JavaScript
#!/usr/bin/env node
import { FastMCP, UserError } from "fastmcp";
import { z } from "zod"; // For validation
import * as helpers from "./utils/chai-exec.js";
// Import the helper functions from your tests
// Create the MCP server
const server = new FastMCP({
name: "Kubernetes Validation Server",
version: "1.0.0",
instructions: "Use the checkKubernetesClusterFixed tool to validate your Kubernetes environment by running a comprehensive test suite.",
});
// Add the validation tool
server.addTool({
name: "checkKubernetesClusterFixed",
description: "Run comprehensive tests to validate Kubernetes cluster configuration and connectivity between services",
parameters: z.object({}), // No parameters needed
execute: async () => {
try {
const results = await runValidationTests();
return formatResults(results);
}
catch (error) {
throw new UserError(`Failed to run validation tests: ${error.message}`);
}
},
});
// Function to run all tests and collect results
async function runValidationTests() {
// Get cluster from environment variable (same as your Mocha tests)
const cluster = process.env.CONTEXT;
if (!cluster) {
throw new UserError("CONTEXT environment variable is not set");
}
// Define all test suites based on your test.js file
const testSuites = [
{
name: "Application mysql, version v1",
tests: [
{
name: "mysql-v1 pods are ready",
run: () => helpers.checkDeployment({
context: cluster, namespace: 'default', k8sObj: 'mysql-v1'
})
},
{
name: "mysql-v1 service is present",
run: () => helpers.k8sObjectIsPresent({
context: cluster, namespace: 'default', k8sType: 'service', k8sObj: 'mysql-v1'
})
}
]
},
{
name: "Application neo4j-db, version v1",
tests: [
{
name: "neo4j-db-v1 pods are ready",
run: () => helpers.checkDeployment({
context: cluster, namespace: 'default', k8sObj: 'neo4j-db-v1'
})
},
{
name: "neo4j-db-v1 service is present",
run: () => helpers.k8sObjectIsPresent({
context: cluster, namespace: 'default', k8sType: 'service', k8sObj: 'neo4j-db-v1'
})
}
]
},
{
name: "Application backend, version v1",
tests: [
{
name: "backend-v1 pods are ready",
run: () => helpers.checkDeployment({
context: cluster, namespace: 'default', k8sObj: 'backend-v1'
})
},
{
name: "backend-v1 service is present",
run: () => helpers.k8sObjectIsPresent({
context: cluster, namespace: 'default', k8sType: 'service', k8sObj: 'backend-v1'
})
}
]
},
{
name: "Application backend, version v2",
tests: [
{
name: "backend-v2 pods are ready",
run: () => helpers.checkDeployment({
context: cluster, namespace: 'default', k8sObj: 'backend-v2'
})
},
{
name: "backend-v2 service is present",
run: () => helpers.k8sObjectIsPresent({
context: cluster, namespace: 'default', k8sType: 'service', k8sObj: 'backend-v2'
})
},
{
name: "backend-v2 is able to call http://neo4j-db-v1:7474",
run: () => helpers.genericCommand({
command: `kubectl --context ${cluster} -n default exec deploy/backend-v2 -- curl -s -o /dev/null -w "%{http_code}" http://neo4j-db-v1:7474`,
responseContains: "200"
})
}
]
},
{
name: "Application backend, version v3",
tests: [
{
name: "backend-v3 pods are ready",
run: () => helpers.checkDeployment({
context: cluster, namespace: 'default', k8sObj: 'backend-v3'
})
},
{
name: "backend-v3 service is present",
run: () => helpers.k8sObjectIsPresent({
context: cluster, namespace: 'default', k8sType: 'service', k8sObj: 'backend-v3'
})
}
]
},
{
name: "Application frontend, version v1",
tests: [
{
name: "frontend-v1 pods are ready",
run: () => helpers.checkDeployment({
context: cluster, namespace: 'default', k8sObj: 'frontend-v1'
})
},
{
name: "frontend-v1 service is present",
run: () => helpers.k8sObjectIsPresent({
context: cluster, namespace: 'default', k8sType: 'service', k8sObj: 'frontend-v1'
})
},
{
name: "frontend-v1 is able to call http://backend-v1:8080",
run: () => helpers.genericCommand({
command: `kubectl --context ${cluster} -n default exec deploy/frontend-v1 -- curl -s -o /dev/null -w "%{http_code}" http://backend-v1:8080`,
responseContains: "200"
})
},
{
name: "frontend-v1 is able to call http://backend-v2:8080",
run: () => helpers.genericCommand({
command: `kubectl --context ${cluster} -n default exec deploy/frontend-v1 -- curl -s -o /dev/null -w "%{http_code}" http://backend-v2:8080`,
responseContains: "200"
})
},
{
name: "frontend-v1 is able to call http://backend-v3:8080",
run: () => helpers.genericCommand({
command: `kubectl --context ${cluster} -n default exec deploy/frontend-v1 -- curl -s -o /dev/null -w "%{http_code}" http://backend-v3:8080`,
responseContains: "200"
})
}
]
}
];
// Run all tests and collect results
const results = {
summary: {
total: 0,
passed: 0,
failed: 0
},
suites: []
};
for (const suite of testSuites) {
const suiteResult = {
name: suite.name,
passed: [],
failed: []
};
for (const test of suite.tests) {
results.summary.total++;
try {
const result = await test.run();
suiteResult.passed.push({ name: test.name, result });
results.summary.passed++;
}
catch (error) {
suiteResult.failed.push({
name: test.name,
error: error.message
});
results.summary.failed++;
}
}
results.suites.push(suiteResult);
}
return results;
}
// Format results as markdown
function formatResults(results) {
let output = `# Kubernetes Validation Results\n\n`;
// Summary section
output += `## Summary\n\n`;
output += `- **Total tests**: ${results.summary.total}\n`;
output += `- **Passed**: ${results.summary.passed}\n`;
output += `- **Failed**: ${results.summary.failed}\n\n`;
// Check if any tests failed
if (results.summary.failed > 0) {
output += `## Failed Tests\n\n`;
for (const suite of results.suites) {
if (suite.failed.length > 0) {
output += `### ${suite.name}\n\n`;
for (const test of suite.failed) {
output += `❌ **${test.name}**\n`;
output += ` Error: ${test.error}\n\n`;
}
}
}
}
// All passed tests
output += `## Passed Tests\n\n`;
for (const suite of results.suites) {
if (suite.passed.length > 0) {
output += `### ${suite.name}\n\n`;
for (const testName of suite.passed) {
output += `✅ **${testName.name}**\n`;
}
output += `\n`;
}
}
return output;
}
// Start the server
server.start({
transportType: "stdio", // Use stdio for command-line interaction
});
console.log("Kubernetes Validation MCP Server started");
//# sourceMappingURL=index.js.map