kubeview-mcp 1.0.0
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.
- package/.prettierrc.json +11 -0
- package/CHANGELOG.md +55 -0
- package/LICENSE +21 -0
- package/README.md +251 -0
- package/RELEASE.md +154 -0
- package/TODO.md +0 -0
- package/bin/kubeview-mcp.js +274 -0
- package/bin/setup.js +368 -0
- package/dist/src/cli/cli.d.ts +3 -0
- package/dist/src/cli/cli.d.ts.map +1 -0
- package/dist/src/cli/cli.js +23 -0
- package/dist/src/cli/cli.js.map +1 -0
- package/dist/src/index.d.ts +8 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +45 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/kubernetes/BaseResourceOperations.d.ts +155 -0
- package/dist/src/kubernetes/BaseResourceOperations.d.ts.map +1 -0
- package/dist/src/kubernetes/BaseResourceOperations.js +136 -0
- package/dist/src/kubernetes/BaseResourceOperations.js.map +1 -0
- package/dist/src/kubernetes/CircuitBreaker.d.ts +182 -0
- package/dist/src/kubernetes/CircuitBreaker.d.ts.map +1 -0
- package/dist/src/kubernetes/CircuitBreaker.js +369 -0
- package/dist/src/kubernetes/CircuitBreaker.js.map +1 -0
- package/dist/src/kubernetes/ConnectionManager.d.ts +60 -0
- package/dist/src/kubernetes/ConnectionManager.d.ts.map +1 -0
- package/dist/src/kubernetes/ConnectionManager.js +77 -0
- package/dist/src/kubernetes/ConnectionManager.js.map +1 -0
- package/dist/src/kubernetes/ConnectionPool.d.ts +183 -0
- package/dist/src/kubernetes/ConnectionPool.d.ts.map +1 -0
- package/dist/src/kubernetes/ConnectionPool.js +437 -0
- package/dist/src/kubernetes/ConnectionPool.js.map +1 -0
- package/dist/src/kubernetes/ErrorHandler.d.ts +172 -0
- package/dist/src/kubernetes/ErrorHandler.d.ts.map +1 -0
- package/dist/src/kubernetes/ErrorHandler.js +328 -0
- package/dist/src/kubernetes/ErrorHandler.js.map +1 -0
- package/dist/src/kubernetes/ErrorHandling.d.ts +148 -0
- package/dist/src/kubernetes/ErrorHandling.d.ts.map +1 -0
- package/dist/src/kubernetes/ErrorHandling.js +304 -0
- package/dist/src/kubernetes/ErrorHandling.js.map +1 -0
- package/dist/src/kubernetes/KubernetesClient.d.ts +162 -0
- package/dist/src/kubernetes/KubernetesClient.d.ts.map +1 -0
- package/dist/src/kubernetes/KubernetesClient.js +382 -0
- package/dist/src/kubernetes/KubernetesClient.js.map +1 -0
- package/dist/src/kubernetes/ResourceOperations.d.ts +69 -0
- package/dist/src/kubernetes/ResourceOperations.d.ts.map +1 -0
- package/dist/src/kubernetes/ResourceOperations.js +99 -0
- package/dist/src/kubernetes/ResourceOperations.js.map +1 -0
- package/dist/src/kubernetes/RetryStrategy.d.ts +137 -0
- package/dist/src/kubernetes/RetryStrategy.d.ts.map +1 -0
- package/dist/src/kubernetes/RetryStrategy.js +277 -0
- package/dist/src/kubernetes/RetryStrategy.js.map +1 -0
- package/dist/src/kubernetes/RetryableOperation.d.ts +118 -0
- package/dist/src/kubernetes/RetryableOperation.d.ts.map +1 -0
- package/dist/src/kubernetes/RetryableOperation.js +233 -0
- package/dist/src/kubernetes/RetryableOperation.js.map +1 -0
- package/dist/src/kubernetes/index.d.ts +18 -0
- package/dist/src/kubernetes/index.d.ts.map +1 -0
- package/dist/src/kubernetes/index.js +28 -0
- package/dist/src/kubernetes/index.js.map +1 -0
- package/dist/src/kubernetes/resources/ConfigMapOperations.d.ts +60 -0
- package/dist/src/kubernetes/resources/ConfigMapOperations.d.ts.map +1 -0
- package/dist/src/kubernetes/resources/ConfigMapOperations.js +306 -0
- package/dist/src/kubernetes/resources/ConfigMapOperations.js.map +1 -0
- package/dist/src/kubernetes/resources/CustomResourceOperations.d.ts +55 -0
- package/dist/src/kubernetes/resources/CustomResourceOperations.d.ts.map +1 -0
- package/dist/src/kubernetes/resources/CustomResourceOperations.js +363 -0
- package/dist/src/kubernetes/resources/CustomResourceOperations.js.map +1 -0
- package/dist/src/kubernetes/resources/DeploymentOperations.d.ts +66 -0
- package/dist/src/kubernetes/resources/DeploymentOperations.d.ts.map +1 -0
- package/dist/src/kubernetes/resources/DeploymentOperations.js +234 -0
- package/dist/src/kubernetes/resources/DeploymentOperations.js.map +1 -0
- package/dist/src/kubernetes/resources/IngressOperations.d.ts +60 -0
- package/dist/src/kubernetes/resources/IngressOperations.d.ts.map +1 -0
- package/dist/src/kubernetes/resources/IngressOperations.js +224 -0
- package/dist/src/kubernetes/resources/IngressOperations.js.map +1 -0
- package/dist/src/kubernetes/resources/MetricOperations.d.ts +218 -0
- package/dist/src/kubernetes/resources/MetricOperations.d.ts.map +1 -0
- package/dist/src/kubernetes/resources/MetricOperations.js +893 -0
- package/dist/src/kubernetes/resources/MetricOperations.js.map +1 -0
- package/dist/src/kubernetes/resources/NamespaceOperations.d.ts +38 -0
- package/dist/src/kubernetes/resources/NamespaceOperations.d.ts.map +1 -0
- package/dist/src/kubernetes/resources/NamespaceOperations.js +101 -0
- package/dist/src/kubernetes/resources/NamespaceOperations.js.map +1 -0
- package/dist/src/kubernetes/resources/PersistentVolumeClaimOperations.d.ts +109 -0
- package/dist/src/kubernetes/resources/PersistentVolumeClaimOperations.d.ts.map +1 -0
- package/dist/src/kubernetes/resources/PersistentVolumeClaimOperations.js +383 -0
- package/dist/src/kubernetes/resources/PersistentVolumeClaimOperations.js.map +1 -0
- package/dist/src/kubernetes/resources/PersistentVolumeOperations.d.ts +97 -0
- package/dist/src/kubernetes/resources/PersistentVolumeOperations.d.ts.map +1 -0
- package/dist/src/kubernetes/resources/PersistentVolumeOperations.js +321 -0
- package/dist/src/kubernetes/resources/PersistentVolumeOperations.js.map +1 -0
- package/dist/src/kubernetes/resources/PodOperations.d.ts +99 -0
- package/dist/src/kubernetes/resources/PodOperations.d.ts.map +1 -0
- package/dist/src/kubernetes/resources/PodOperations.js +333 -0
- package/dist/src/kubernetes/resources/PodOperations.js.map +1 -0
- package/dist/src/kubernetes/resources/SecretOperations.d.ts +71 -0
- package/dist/src/kubernetes/resources/SecretOperations.d.ts.map +1 -0
- package/dist/src/kubernetes/resources/SecretOperations.js +254 -0
- package/dist/src/kubernetes/resources/SecretOperations.js.map +1 -0
- package/dist/src/kubernetes/resources/ServiceOperations.d.ts +64 -0
- package/dist/src/kubernetes/resources/ServiceOperations.d.ts.map +1 -0
- package/dist/src/kubernetes/resources/ServiceOperations.js +232 -0
- package/dist/src/kubernetes/resources/ServiceOperations.js.map +1 -0
- package/dist/src/kubernetes/utils/ResourceUtils.d.ts +238 -0
- package/dist/src/kubernetes/utils/ResourceUtils.d.ts.map +1 -0
- package/dist/src/kubernetes/utils/ResourceUtils.js +439 -0
- package/dist/src/kubernetes/utils/ResourceUtils.js.map +1 -0
- package/dist/src/plugins/ArgoCDToolsPlugin.d.ts +45 -0
- package/dist/src/plugins/ArgoCDToolsPlugin.d.ts.map +1 -0
- package/dist/src/plugins/ArgoCDToolsPlugin.js +155 -0
- package/dist/src/plugins/ArgoCDToolsPlugin.js.map +1 -0
- package/dist/src/plugins/ArgoToolsPlugin.d.ts +45 -0
- package/dist/src/plugins/ArgoToolsPlugin.d.ts.map +1 -0
- package/dist/src/plugins/ArgoToolsPlugin.js +149 -0
- package/dist/src/plugins/ArgoToolsPlugin.js.map +1 -0
- package/dist/src/plugins/HelmToolsPlugin.d.ts +41 -0
- package/dist/src/plugins/HelmToolsPlugin.d.ts.map +1 -0
- package/dist/src/plugins/HelmToolsPlugin.js +146 -0
- package/dist/src/plugins/HelmToolsPlugin.js.map +1 -0
- package/dist/src/plugins/KubernetesToolsPlugin.d.ts +44 -0
- package/dist/src/plugins/KubernetesToolsPlugin.d.ts.map +1 -0
- package/dist/src/plugins/KubernetesToolsPlugin.js +159 -0
- package/dist/src/plugins/KubernetesToolsPlugin.js.map +1 -0
- package/dist/src/plugins/SamplePlugin.d.ts +12 -0
- package/dist/src/plugins/SamplePlugin.d.ts.map +1 -0
- package/dist/src/plugins/SamplePlugin.js +51 -0
- package/dist/src/plugins/SamplePlugin.js.map +1 -0
- package/dist/src/plugins/index.d.ts +5 -0
- package/dist/src/plugins/index.d.ts.map +1 -0
- package/dist/src/plugins/index.js +5 -0
- package/dist/src/plugins/index.js.map +1 -0
- package/dist/src/server/MCPServer.d.ts +93 -0
- package/dist/src/server/MCPServer.d.ts.map +1 -0
- package/dist/src/server/MCPServer.js +398 -0
- package/dist/src/server/MCPServer.js.map +1 -0
- package/dist/src/tools/argo/ArgoCronListTool.d.ts +10 -0
- package/dist/src/tools/argo/ArgoCronListTool.d.ts.map +1 -0
- package/dist/src/tools/argo/ArgoCronListTool.js +70 -0
- package/dist/src/tools/argo/ArgoCronListTool.js.map +1 -0
- package/dist/src/tools/argo/ArgoGetTool.d.ts +10 -0
- package/dist/src/tools/argo/ArgoGetTool.d.ts.map +1 -0
- package/dist/src/tools/argo/ArgoGetTool.js +80 -0
- package/dist/src/tools/argo/ArgoGetTool.js.map +1 -0
- package/dist/src/tools/argo/ArgoListTool.d.ts +10 -0
- package/dist/src/tools/argo/ArgoListTool.d.ts.map +1 -0
- package/dist/src/tools/argo/ArgoListTool.js +133 -0
- package/dist/src/tools/argo/ArgoListTool.js.map +1 -0
- package/dist/src/tools/argo/ArgoLogsTool.d.ts +10 -0
- package/dist/src/tools/argo/ArgoLogsTool.d.ts.map +1 -0
- package/dist/src/tools/argo/ArgoLogsTool.js +117 -0
- package/dist/src/tools/argo/ArgoLogsTool.js.map +1 -0
- package/dist/src/tools/argo/BaseTool.d.ts +60 -0
- package/dist/src/tools/argo/BaseTool.d.ts.map +1 -0
- package/dist/src/tools/argo/BaseTool.js +51 -0
- package/dist/src/tools/argo/BaseTool.js.map +1 -0
- package/dist/src/tools/argo/index.d.ts +7 -0
- package/dist/src/tools/argo/index.d.ts.map +1 -0
- package/dist/src/tools/argo/index.js +6 -0
- package/dist/src/tools/argo/index.js.map +1 -0
- package/dist/src/tools/argocd/ArgoCDAppGetTool.d.ts +10 -0
- package/dist/src/tools/argocd/ArgoCDAppGetTool.d.ts.map +1 -0
- package/dist/src/tools/argocd/ArgoCDAppGetTool.js +97 -0
- package/dist/src/tools/argocd/ArgoCDAppGetTool.js.map +1 -0
- package/dist/src/tools/argocd/ArgoCDAppHistoryTool.d.ts +10 -0
- package/dist/src/tools/argocd/ArgoCDAppHistoryTool.d.ts.map +1 -0
- package/dist/src/tools/argocd/ArgoCDAppHistoryTool.js +80 -0
- package/dist/src/tools/argocd/ArgoCDAppHistoryTool.js.map +1 -0
- package/dist/src/tools/argocd/ArgoCDAppListTool.d.ts +10 -0
- package/dist/src/tools/argocd/ArgoCDAppListTool.d.ts.map +1 -0
- package/dist/src/tools/argocd/ArgoCDAppListTool.js +128 -0
- package/dist/src/tools/argocd/ArgoCDAppListTool.js.map +1 -0
- package/dist/src/tools/argocd/ArgoCDAppLogsTool.d.ts +10 -0
- package/dist/src/tools/argocd/ArgoCDAppLogsTool.d.ts.map +1 -0
- package/dist/src/tools/argocd/ArgoCDAppLogsTool.js +143 -0
- package/dist/src/tools/argocd/ArgoCDAppLogsTool.js.map +1 -0
- package/dist/src/tools/argocd/ArgoCDAppResourcesTool.d.ts +10 -0
- package/dist/src/tools/argocd/ArgoCDAppResourcesTool.d.ts.map +1 -0
- package/dist/src/tools/argocd/ArgoCDAppResourcesTool.js +123 -0
- package/dist/src/tools/argocd/ArgoCDAppResourcesTool.js.map +1 -0
- package/dist/src/tools/argocd/BaseTool.d.ts +71 -0
- package/dist/src/tools/argocd/BaseTool.d.ts.map +1 -0
- package/dist/src/tools/argocd/BaseTool.js +62 -0
- package/dist/src/tools/argocd/BaseTool.js.map +1 -0
- package/dist/src/tools/argocd/index.d.ts +8 -0
- package/dist/src/tools/argocd/index.d.ts.map +1 -0
- package/dist/src/tools/argocd/index.js +7 -0
- package/dist/src/tools/argocd/index.js.map +1 -0
- package/dist/src/tools/helm/BaseTool.d.ts +51 -0
- package/dist/src/tools/helm/BaseTool.d.ts.map +1 -0
- package/dist/src/tools/helm/BaseTool.js +42 -0
- package/dist/src/tools/helm/BaseTool.js.map +1 -0
- package/dist/src/tools/helm/HelmGetHooksTool.d.ts +10 -0
- package/dist/src/tools/helm/HelmGetHooksTool.d.ts.map +1 -0
- package/dist/src/tools/helm/HelmGetHooksTool.js +38 -0
- package/dist/src/tools/helm/HelmGetHooksTool.js.map +1 -0
- package/dist/src/tools/helm/HelmGetManifestTool.d.ts +10 -0
- package/dist/src/tools/helm/HelmGetManifestTool.d.ts.map +1 -0
- package/dist/src/tools/helm/HelmGetManifestTool.js +38 -0
- package/dist/src/tools/helm/HelmGetManifestTool.js.map +1 -0
- package/dist/src/tools/helm/HelmGetNotesTool.d.ts +10 -0
- package/dist/src/tools/helm/HelmGetNotesTool.d.ts.map +1 -0
- package/dist/src/tools/helm/HelmGetNotesTool.js +38 -0
- package/dist/src/tools/helm/HelmGetNotesTool.js.map +1 -0
- package/dist/src/tools/helm/HelmGetResourcesTool.d.ts +13 -0
- package/dist/src/tools/helm/HelmGetResourcesTool.d.ts.map +1 -0
- package/dist/src/tools/helm/HelmGetResourcesTool.js +124 -0
- package/dist/src/tools/helm/HelmGetResourcesTool.js.map +1 -0
- package/dist/src/tools/helm/HelmGetValuesTool.d.ts +10 -0
- package/dist/src/tools/helm/HelmGetValuesTool.d.ts.map +1 -0
- package/dist/src/tools/helm/HelmGetValuesTool.js +54 -0
- package/dist/src/tools/helm/HelmGetValuesTool.js.map +1 -0
- package/dist/src/tools/helm/HelmHistoryTool.d.ts +10 -0
- package/dist/src/tools/helm/HelmHistoryTool.d.ts.map +1 -0
- package/dist/src/tools/helm/HelmHistoryTool.js +49 -0
- package/dist/src/tools/helm/HelmHistoryTool.js.map +1 -0
- package/dist/src/tools/helm/HelmListTool.d.ts +10 -0
- package/dist/src/tools/helm/HelmListTool.d.ts.map +1 -0
- package/dist/src/tools/helm/HelmListTool.js +107 -0
- package/dist/src/tools/helm/HelmListTool.js.map +1 -0
- package/dist/src/tools/helm/HelmListWithResourcesTool.d.ts +14 -0
- package/dist/src/tools/helm/HelmListWithResourcesTool.d.ts.map +1 -0
- package/dist/src/tools/helm/HelmListWithResourcesTool.js +175 -0
- package/dist/src/tools/helm/HelmListWithResourcesTool.js.map +1 -0
- package/dist/src/tools/helm/HelmStatusTool.d.ts +10 -0
- package/dist/src/tools/helm/HelmStatusTool.d.ts.map +1 -0
- package/dist/src/tools/helm/HelmStatusTool.js +54 -0
- package/dist/src/tools/helm/HelmStatusTool.js.map +1 -0
- package/dist/src/tools/helm/index.d.ts +12 -0
- package/dist/src/tools/helm/index.d.ts.map +1 -0
- package/dist/src/tools/helm/index.js +11 -0
- package/dist/src/tools/helm/index.js.map +1 -0
- package/dist/src/tools/kubernetes/BaseTool.d.ts +48 -0
- package/dist/src/tools/kubernetes/BaseTool.d.ts.map +1 -0
- package/dist/src/tools/kubernetes/BaseTool.js +55 -0
- package/dist/src/tools/kubernetes/BaseTool.js.map +1 -0
- package/dist/src/tools/kubernetes/GetConfigMapTool.d.ts +11 -0
- package/dist/src/tools/kubernetes/GetConfigMapTool.d.ts.map +1 -0
- package/dist/src/tools/kubernetes/GetConfigMapTool.js +28 -0
- package/dist/src/tools/kubernetes/GetConfigMapTool.js.map +1 -0
- package/dist/src/tools/kubernetes/GetContainerLogsTool.d.ts +15 -0
- package/dist/src/tools/kubernetes/GetContainerLogsTool.d.ts.map +1 -0
- package/dist/src/tools/kubernetes/GetContainerLogsTool.js +119 -0
- package/dist/src/tools/kubernetes/GetContainerLogsTool.js.map +1 -0
- package/dist/src/tools/kubernetes/GetDeploymentsTool.d.ts +11 -0
- package/dist/src/tools/kubernetes/GetDeploymentsTool.d.ts.map +1 -0
- package/dist/src/tools/kubernetes/GetDeploymentsTool.js +30 -0
- package/dist/src/tools/kubernetes/GetDeploymentsTool.js.map +1 -0
- package/dist/src/tools/kubernetes/GetEventsTool.d.ts +11 -0
- package/dist/src/tools/kubernetes/GetEventsTool.d.ts.map +1 -0
- package/dist/src/tools/kubernetes/GetEventsTool.js +123 -0
- package/dist/src/tools/kubernetes/GetEventsTool.js.map +1 -0
- package/dist/src/tools/kubernetes/GetIngressTool.d.ts +11 -0
- package/dist/src/tools/kubernetes/GetIngressTool.d.ts.map +1 -0
- package/dist/src/tools/kubernetes/GetIngressTool.js +35 -0
- package/dist/src/tools/kubernetes/GetIngressTool.js.map +1 -0
- package/dist/src/tools/kubernetes/GetMetricsTool.d.ts +11 -0
- package/dist/src/tools/kubernetes/GetMetricsTool.d.ts.map +1 -0
- package/dist/src/tools/kubernetes/GetMetricsTool.js +40 -0
- package/dist/src/tools/kubernetes/GetMetricsTool.js.map +1 -0
- package/dist/src/tools/kubernetes/GetNamespacesTool.d.ts +11 -0
- package/dist/src/tools/kubernetes/GetNamespacesTool.d.ts.map +1 -0
- package/dist/src/tools/kubernetes/GetNamespacesTool.js +33 -0
- package/dist/src/tools/kubernetes/GetNamespacesTool.js.map +1 -0
- package/dist/src/tools/kubernetes/GetPersistentVolumeClaimsTool.d.ts +11 -0
- package/dist/src/tools/kubernetes/GetPersistentVolumeClaimsTool.d.ts.map +1 -0
- package/dist/src/tools/kubernetes/GetPersistentVolumeClaimsTool.js +92 -0
- package/dist/src/tools/kubernetes/GetPersistentVolumeClaimsTool.js.map +1 -0
- package/dist/src/tools/kubernetes/GetPersistentVolumesTool.d.ts +11 -0
- package/dist/src/tools/kubernetes/GetPersistentVolumesTool.d.ts.map +1 -0
- package/dist/src/tools/kubernetes/GetPersistentVolumesTool.js +88 -0
- package/dist/src/tools/kubernetes/GetPersistentVolumesTool.js.map +1 -0
- package/dist/src/tools/kubernetes/GetPodMetricsTool.d.ts +11 -0
- package/dist/src/tools/kubernetes/GetPodMetricsTool.d.ts.map +1 -0
- package/dist/src/tools/kubernetes/GetPodMetricsTool.js +100 -0
- package/dist/src/tools/kubernetes/GetPodMetricsTool.js.map +1 -0
- package/dist/src/tools/kubernetes/GetPodsTool.d.ts +11 -0
- package/dist/src/tools/kubernetes/GetPodsTool.d.ts.map +1 -0
- package/dist/src/tools/kubernetes/GetPodsTool.js +35 -0
- package/dist/src/tools/kubernetes/GetPodsTool.js.map +1 -0
- package/dist/src/tools/kubernetes/GetResourceTool.d.ts +12 -0
- package/dist/src/tools/kubernetes/GetResourceTool.d.ts.map +1 -0
- package/dist/src/tools/kubernetes/GetResourceTool.js +79 -0
- package/dist/src/tools/kubernetes/GetResourceTool.js.map +1 -0
- package/dist/src/tools/kubernetes/GetSecretsTool.d.ts +11 -0
- package/dist/src/tools/kubernetes/GetSecretsTool.d.ts.map +1 -0
- package/dist/src/tools/kubernetes/GetSecretsTool.js +49 -0
- package/dist/src/tools/kubernetes/GetSecretsTool.js.map +1 -0
- package/dist/src/tools/kubernetes/GetServicesTool.d.ts +11 -0
- package/dist/src/tools/kubernetes/GetServicesTool.d.ts.map +1 -0
- package/dist/src/tools/kubernetes/GetServicesTool.js +35 -0
- package/dist/src/tools/kubernetes/GetServicesTool.js.map +1 -0
- package/dist/src/tools/kubernetes/index.d.ts +17 -0
- package/dist/src/tools/kubernetes/index.d.ts.map +1 -0
- package/dist/src/tools/kubernetes/index.js +16 -0
- package/dist/src/tools/kubernetes/index.js.map +1 -0
- package/dist/src/utils/CliUtils.d.ts +24 -0
- package/dist/src/utils/CliUtils.d.ts.map +1 -0
- package/dist/src/utils/CliUtils.js +159 -0
- package/dist/src/utils/CliUtils.js.map +1 -0
- package/dist/tests/__mocks__/@kubernetes/client-node.d.ts +34 -0
- package/dist/tests/__mocks__/@kubernetes/client-node.d.ts.map +1 -0
- package/dist/tests/__mocks__/@kubernetes/client-node.js +20 -0
- package/dist/tests/__mocks__/@kubernetes/client-node.js.map +1 -0
- package/dist/tests/argo/ArgoGetTool.test.d.ts +2 -0
- package/dist/tests/argo/ArgoGetTool.test.d.ts.map +1 -0
- package/dist/tests/argo/ArgoGetTool.test.js +141 -0
- package/dist/tests/argo/ArgoGetTool.test.js.map +1 -0
- package/dist/tests/helm/BaseTool.test.d.ts +2 -0
- package/dist/tests/helm/BaseTool.test.d.ts.map +1 -0
- package/dist/tests/helm/BaseTool.test.js +241 -0
- package/dist/tests/helm/BaseTool.test.js.map +1 -0
- package/dist/tests/index.test.d.ts +2 -0
- package/dist/tests/index.test.d.ts.map +1 -0
- package/dist/tests/index.test.js +7 -0
- package/dist/tests/index.test.js.map +1 -0
- package/dist/tests/kubernetes/ConfigMapOperations.test.d.ts +2 -0
- package/dist/tests/kubernetes/ConfigMapOperations.test.d.ts.map +1 -0
- package/dist/tests/kubernetes/ConfigMapOperations.test.js +460 -0
- package/dist/tests/kubernetes/ConfigMapOperations.test.js.map +1 -0
- package/dist/tests/kubernetes/ConnectionManager.test.d.ts +2 -0
- package/dist/tests/kubernetes/ConnectionManager.test.d.ts.map +1 -0
- package/dist/tests/kubernetes/ConnectionManager.test.js +97 -0
- package/dist/tests/kubernetes/ConnectionManager.test.js.map +1 -0
- package/dist/tests/kubernetes/ConnectionPool.test.d.ts +2 -0
- package/dist/tests/kubernetes/ConnectionPool.test.d.ts.map +1 -0
- package/dist/tests/kubernetes/ConnectionPool.test.js +328 -0
- package/dist/tests/kubernetes/ConnectionPool.test.js.map +1 -0
- package/dist/tests/kubernetes/DeploymentOperations.test.d.ts +2 -0
- package/dist/tests/kubernetes/DeploymentOperations.test.d.ts.map +1 -0
- package/dist/tests/kubernetes/DeploymentOperations.test.js +196 -0
- package/dist/tests/kubernetes/DeploymentOperations.test.js.map +1 -0
- package/dist/tests/kubernetes/ErrorHandling.test.d.ts +2 -0
- package/dist/tests/kubernetes/ErrorHandling.test.d.ts.map +1 -0
- package/dist/tests/kubernetes/ErrorHandling.test.js +329 -0
- package/dist/tests/kubernetes/ErrorHandling.test.js.map +1 -0
- package/dist/tests/kubernetes/GetPodMetricsTool.test.d.ts +2 -0
- package/dist/tests/kubernetes/GetPodMetricsTool.test.d.ts.map +1 -0
- package/dist/tests/kubernetes/GetPodMetricsTool.test.js +150 -0
- package/dist/tests/kubernetes/GetPodMetricsTool.test.js.map +1 -0
- package/dist/tests/kubernetes/KubernetesClient.test.d.ts +2 -0
- package/dist/tests/kubernetes/KubernetesClient.test.d.ts.map +1 -0
- package/dist/tests/kubernetes/KubernetesClient.test.js +371 -0
- package/dist/tests/kubernetes/KubernetesClient.test.js.map +1 -0
- package/dist/tests/kubernetes/MetricOperations.parsing.test.d.ts +2 -0
- package/dist/tests/kubernetes/MetricOperations.parsing.test.d.ts.map +1 -0
- package/dist/tests/kubernetes/MetricOperations.parsing.test.js +49 -0
- package/dist/tests/kubernetes/MetricOperations.parsing.test.js.map +1 -0
- package/dist/tests/kubernetes/NamespaceOperations.test.d.ts +2 -0
- package/dist/tests/kubernetes/NamespaceOperations.test.d.ts.map +1 -0
- package/dist/tests/kubernetes/NamespaceOperations.test.js +115 -0
- package/dist/tests/kubernetes/NamespaceOperations.test.js.map +1 -0
- package/dist/tests/kubernetes/PodOperations.test.d.ts +2 -0
- package/dist/tests/kubernetes/PodOperations.test.d.ts.map +1 -0
- package/dist/tests/kubernetes/PodOperations.test.js +209 -0
- package/dist/tests/kubernetes/PodOperations.test.js.map +1 -0
- package/dist/tests/kubernetes/RetryStrategy.test.d.ts +2 -0
- package/dist/tests/kubernetes/RetryStrategy.test.d.ts.map +1 -0
- package/dist/tests/kubernetes/RetryStrategy.test.js +419 -0
- package/dist/tests/kubernetes/RetryStrategy.test.js.map +1 -0
- package/dist/tests/kubernetes/ServiceOperations.test.d.ts +2 -0
- package/dist/tests/kubernetes/ServiceOperations.test.d.ts.map +1 -0
- package/dist/tests/kubernetes/ServiceOperations.test.js +159 -0
- package/dist/tests/kubernetes/ServiceOperations.test.js.map +1 -0
- package/dist/tests/plugins/KubernetesToolsPlugin.test.d.ts +2 -0
- package/dist/tests/plugins/KubernetesToolsPlugin.test.d.ts.map +1 -0
- package/dist/tests/plugins/KubernetesToolsPlugin.test.js +153 -0
- package/dist/tests/plugins/KubernetesToolsPlugin.test.js.map +1 -0
- package/dist/tests/server/MCPServer.integration.test.d.ts +2 -0
- package/dist/tests/server/MCPServer.integration.test.d.ts.map +1 -0
- package/dist/tests/server/MCPServer.integration.test.js +244 -0
- package/dist/tests/server/MCPServer.integration.test.js.map +1 -0
- package/dist/tests/server/MCPServer.test.d.ts +2 -0
- package/dist/tests/server/MCPServer.test.d.ts.map +1 -0
- package/dist/tests/server/MCPServer.test.js +257 -0
- package/dist/tests/server/MCPServer.test.js.map +1 -0
- package/package.json +85 -0
- package/src/cli/cli.ts +25 -0
- package/src/cli/run-command.js +391 -0
- package/src/index.ts +46 -0
- package/src/kubernetes/BaseResourceOperations.ts +286 -0
- package/src/kubernetes/CircuitBreaker.ts +485 -0
- package/src/kubernetes/ConnectionManager.ts +114 -0
- package/src/kubernetes/ConnectionPool.ts +551 -0
- package/src/kubernetes/ErrorHandler.ts +436 -0
- package/src/kubernetes/ErrorHandling.ts +401 -0
- package/src/kubernetes/KubernetesClient.ts +500 -0
- package/src/kubernetes/README.md +349 -0
- package/src/kubernetes/ResourceOperations.ts +116 -0
- package/src/kubernetes/RetryStrategy.ts +365 -0
- package/src/kubernetes/RetryableOperation.ts +313 -0
- package/src/kubernetes/docs/ResourceOperations.md +606 -0
- package/src/kubernetes/index.ts +116 -0
- package/src/kubernetes/resources/ConfigMapOperations.ts +367 -0
- package/src/kubernetes/resources/CustomResourceOperations.ts +392 -0
- package/src/kubernetes/resources/DeploymentOperations.ts +294 -0
- package/src/kubernetes/resources/IngressOperations.ts +277 -0
- package/src/kubernetes/resources/MetricOperations.ts +1159 -0
- package/src/kubernetes/resources/NamespaceOperations.ts +129 -0
- package/src/kubernetes/resources/PersistentVolumeClaimOperations.ts +516 -0
- package/src/kubernetes/resources/PersistentVolumeOperations.ts +438 -0
- package/src/kubernetes/resources/PodOperations.ts +417 -0
- package/src/kubernetes/resources/SecretOperations.ts +304 -0
- package/src/kubernetes/resources/ServiceOperations.ts +283 -0
- package/src/kubernetes/utils/ResourceUtils.ts +553 -0
- package/src/plugins/ArgoCDToolsPlugin.ts +189 -0
- package/src/plugins/ArgoToolsPlugin.ts +180 -0
- package/src/plugins/HelmToolsPlugin.ts +180 -0
- package/src/plugins/KubernetesToolsPlugin.ts +198 -0
- package/src/plugins/SamplePlugin.ts +60 -0
- package/src/plugins/index.ts +4 -0
- package/src/server/MCPServer.ts +500 -0
- package/src/tools/argo/ArgoCronListTool.ts +78 -0
- package/src/tools/argo/ArgoGetTool.ts +91 -0
- package/src/tools/argo/ArgoListTool.ts +143 -0
- package/src/tools/argo/ArgoLogsTool.ts +131 -0
- package/src/tools/argo/BaseTool.ts +69 -0
- package/src/tools/argo/index.ts +6 -0
- package/src/tools/argocd/ArgoCDAppGetTool.ts +109 -0
- package/src/tools/argocd/ArgoCDAppHistoryTool.ts +91 -0
- package/src/tools/argocd/ArgoCDAppListTool.ts +144 -0
- package/src/tools/argocd/ArgoCDAppLogsTool.ts +162 -0
- package/src/tools/argocd/ArgoCDAppResourcesTool.ts +139 -0
- package/src/tools/argocd/BaseTool.ts +83 -0
- package/src/tools/argocd/index.ts +7 -0
- package/src/tools/helm/BaseTool.ts +60 -0
- package/src/tools/helm/HelmGetHooksTool.ts +44 -0
- package/src/tools/helm/HelmGetManifestTool.ts +44 -0
- package/src/tools/helm/HelmGetNotesTool.ts +44 -0
- package/src/tools/helm/HelmGetResourcesTool.ts +140 -0
- package/src/tools/helm/HelmGetValuesTool.ts +62 -0
- package/src/tools/helm/HelmHistoryTool.ts +56 -0
- package/src/tools/helm/HelmListTool.ts +107 -0
- package/src/tools/helm/HelmListWithResourcesTool.ts +194 -0
- package/src/tools/helm/HelmStatusTool.ts +62 -0
- package/src/tools/helm/index.ts +11 -0
- package/src/tools/kubernetes/BaseTool.ts +76 -0
- package/src/tools/kubernetes/GetConfigMapTool.ts +33 -0
- package/src/tools/kubernetes/GetContainerLogsTool.ts +140 -0
- package/src/tools/kubernetes/GetDeploymentsTool.ts +33 -0
- package/src/tools/kubernetes/GetEventsTool.ts +133 -0
- package/src/tools/kubernetes/GetIngressTool.ts +39 -0
- package/src/tools/kubernetes/GetMetricsTool.ts +53 -0
- package/src/tools/kubernetes/GetNamespacesTool.ts +36 -0
- package/src/tools/kubernetes/GetPersistentVolumeClaimsTool.ts +113 -0
- package/src/tools/kubernetes/GetPersistentVolumesTool.ts +107 -0
- package/src/tools/kubernetes/GetPodMetricsTool.ts +113 -0
- package/src/tools/kubernetes/GetPodsTool.ts +39 -0
- package/src/tools/kubernetes/GetResourceTool.ts +90 -0
- package/src/tools/kubernetes/GetSecretsTool.ts +55 -0
- package/src/tools/kubernetes/GetServicesTool.ts +39 -0
- package/src/tools/kubernetes/index.ts +16 -0
- package/src/utils/CliUtils.ts +207 -0
- package/tsconfig.json +36 -0
|
@@ -0,0 +1,365 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Retry strategy for Kubernetes operations
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { Logger } from 'winston';
|
|
6
|
+
|
|
7
|
+
import { KubernetesError } from './ErrorHandling.js';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Retry configuration options
|
|
11
|
+
*/
|
|
12
|
+
export interface RetryConfig {
|
|
13
|
+
/** Maximum number of retry attempts */
|
|
14
|
+
maxAttempts: number;
|
|
15
|
+
/** Initial delay in milliseconds before first retry */
|
|
16
|
+
initialDelayMs: number;
|
|
17
|
+
/** Maximum delay in milliseconds between retries */
|
|
18
|
+
maxDelayMs: number;
|
|
19
|
+
/** Exponential backoff factor (e.g., 2 for doubling) */
|
|
20
|
+
backoffMultiplier: number;
|
|
21
|
+
/** Jitter factor (0-1) to randomize delays */
|
|
22
|
+
jitterFactor: number;
|
|
23
|
+
/** Timeout for entire retry operation in milliseconds */
|
|
24
|
+
timeoutMs?: number;
|
|
25
|
+
/** Custom function to determine if error is retryable */
|
|
26
|
+
isRetryable?: (error: any) => boolean;
|
|
27
|
+
/** Callback for retry events */
|
|
28
|
+
onRetry?: (attempt: number, error: any, nextDelayMs: number) => void;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Default retry configuration
|
|
33
|
+
*/
|
|
34
|
+
export const DEFAULT_RETRY_CONFIG: RetryConfig = {
|
|
35
|
+
maxAttempts: 3,
|
|
36
|
+
initialDelayMs: 1000,
|
|
37
|
+
maxDelayMs: 30000,
|
|
38
|
+
backoffMultiplier: 2,
|
|
39
|
+
jitterFactor: 0.1,
|
|
40
|
+
timeoutMs: 60000,
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Preset configurations for common scenarios
|
|
45
|
+
*/
|
|
46
|
+
export const RETRY_PRESETS = {
|
|
47
|
+
/** Fast retries for transient network issues */
|
|
48
|
+
FAST: {
|
|
49
|
+
maxAttempts: 3,
|
|
50
|
+
initialDelayMs: 100,
|
|
51
|
+
maxDelayMs: 1000,
|
|
52
|
+
backoffMultiplier: 2,
|
|
53
|
+
jitterFactor: 0.1,
|
|
54
|
+
timeoutMs: 5000,
|
|
55
|
+
},
|
|
56
|
+
/** Standard retries for most operations */
|
|
57
|
+
STANDARD: DEFAULT_RETRY_CONFIG,
|
|
58
|
+
/** Aggressive retries for critical operations */
|
|
59
|
+
AGGRESSIVE: {
|
|
60
|
+
maxAttempts: 5,
|
|
61
|
+
initialDelayMs: 500,
|
|
62
|
+
maxDelayMs: 60000,
|
|
63
|
+
backoffMultiplier: 2,
|
|
64
|
+
jitterFactor: 0.2,
|
|
65
|
+
timeoutMs: 300000,
|
|
66
|
+
},
|
|
67
|
+
/** No retries */
|
|
68
|
+
NONE: {
|
|
69
|
+
maxAttempts: 1,
|
|
70
|
+
initialDelayMs: 0,
|
|
71
|
+
maxDelayMs: 0,
|
|
72
|
+
backoffMultiplier: 1,
|
|
73
|
+
jitterFactor: 0,
|
|
74
|
+
},
|
|
75
|
+
} as const;
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Retry context for tracking state
|
|
79
|
+
*/
|
|
80
|
+
export interface RetryContext {
|
|
81
|
+
attempt: number;
|
|
82
|
+
totalDelay: number;
|
|
83
|
+
startTime: number;
|
|
84
|
+
errors: any[];
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Result of a retry operation
|
|
89
|
+
*/
|
|
90
|
+
export interface RetryResult<T> {
|
|
91
|
+
success: boolean;
|
|
92
|
+
value?: T;
|
|
93
|
+
error?: any;
|
|
94
|
+
attempts: number;
|
|
95
|
+
totalDelayMs: number;
|
|
96
|
+
totalTimeMs: number;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Retry strategy implementation
|
|
101
|
+
*/
|
|
102
|
+
export class RetryStrategy {
|
|
103
|
+
private readonly config: RetryConfig;
|
|
104
|
+
private readonly logger?: Logger;
|
|
105
|
+
|
|
106
|
+
constructor(config: Partial<RetryConfig> = {}, logger?: Logger) {
|
|
107
|
+
// If config is a preset, merge with DEFAULT_RETRY_CONFIG, then user config
|
|
108
|
+
let baseConfig: Partial<RetryConfig> = {};
|
|
109
|
+
if (
|
|
110
|
+
config &&
|
|
111
|
+
(config as any).maxAttempts !== undefined &&
|
|
112
|
+
(config as any).initialDelayMs !== undefined
|
|
113
|
+
) {
|
|
114
|
+
baseConfig = config;
|
|
115
|
+
}
|
|
116
|
+
// If config is a preset object (from RETRY_PRESETS), merge with default
|
|
117
|
+
this.config = { ...DEFAULT_RETRY_CONFIG, ...baseConfig, ...config };
|
|
118
|
+
this.logger = logger;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Execute an operation with retry logic
|
|
123
|
+
*/
|
|
124
|
+
async execute<T>(operation: () => Promise<T>, operationName?: string): Promise<RetryResult<T>> {
|
|
125
|
+
let timeoutId: NodeJS.Timeout | null = null;
|
|
126
|
+
let timeoutPromise: Promise<never> | null = null;
|
|
127
|
+
if (this.config.timeoutMs) {
|
|
128
|
+
timeoutPromise = new Promise((_, reject) => {
|
|
129
|
+
timeoutId = setTimeout(() => {
|
|
130
|
+
reject(new Error(`Operation timed out after ${this.config.timeoutMs}ms`));
|
|
131
|
+
}, this.config.timeoutMs);
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
let lastError: any = undefined;
|
|
136
|
+
let totalDelay = 0;
|
|
137
|
+
const startTime = Date.now();
|
|
138
|
+
for (let i = 0; i < this.config.maxAttempts; i++) {
|
|
139
|
+
try {
|
|
140
|
+
const race = timeoutPromise ? Promise.race([operation(), timeoutPromise]) : operation();
|
|
141
|
+
const opResult = await race;
|
|
142
|
+
if (timeoutId) clearTimeout(timeoutId);
|
|
143
|
+
return {
|
|
144
|
+
success: true,
|
|
145
|
+
value: opResult as T,
|
|
146
|
+
attempts: i + 1,
|
|
147
|
+
totalDelayMs: totalDelay,
|
|
148
|
+
totalTimeMs: Date.now() - startTime,
|
|
149
|
+
};
|
|
150
|
+
} catch (error) {
|
|
151
|
+
lastError = error;
|
|
152
|
+
if (
|
|
153
|
+
i < this.config.maxAttempts - 1 &&
|
|
154
|
+
this.shouldRetry(error, { attempt: i, totalDelay, startTime, errors: [] })
|
|
155
|
+
) {
|
|
156
|
+
const delayMs = this.calculateDelay(i + 1);
|
|
157
|
+
totalDelay += delayMs;
|
|
158
|
+
this.logger?.warn(
|
|
159
|
+
`Retry attempt ${i + 2}/${this.config.maxAttempts} for ${operationName || 'operation'}`,
|
|
160
|
+
{
|
|
161
|
+
error: error instanceof Error ? error.message : String(error),
|
|
162
|
+
nextDelayMs: delayMs,
|
|
163
|
+
totalDelayMs: totalDelay,
|
|
164
|
+
},
|
|
165
|
+
);
|
|
166
|
+
this.config.onRetry?.(i + 1, error, delayMs);
|
|
167
|
+
await this.delay(delayMs);
|
|
168
|
+
} else {
|
|
169
|
+
if (timeoutId) clearTimeout(timeoutId);
|
|
170
|
+
return {
|
|
171
|
+
success: false,
|
|
172
|
+
error,
|
|
173
|
+
attempts: i + 1,
|
|
174
|
+
totalDelayMs: totalDelay,
|
|
175
|
+
totalTimeMs: Date.now() - startTime,
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
if (timeoutId) clearTimeout(timeoutId);
|
|
181
|
+
return {
|
|
182
|
+
success: false,
|
|
183
|
+
error: lastError,
|
|
184
|
+
attempts: this.config.maxAttempts,
|
|
185
|
+
totalDelayMs: totalDelay,
|
|
186
|
+
totalTimeMs: Date.now() - startTime,
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Wrap a function with retry logic
|
|
192
|
+
*/
|
|
193
|
+
wrap<T extends (...args: any[]) => Promise<any>>(fn: T, operationName?: string): T {
|
|
194
|
+
return (async (...args: Parameters<T>) => {
|
|
195
|
+
const result = await this.execute(() => fn(...args), operationName);
|
|
196
|
+
if (!result.success) {
|
|
197
|
+
throw result.error;
|
|
198
|
+
}
|
|
199
|
+
return result.value;
|
|
200
|
+
}) as T;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Determine if an error is retryable
|
|
205
|
+
*/
|
|
206
|
+
private shouldRetry(error: any, context: RetryContext): boolean {
|
|
207
|
+
// Check if we have attempts remaining
|
|
208
|
+
if (context.attempt >= this.config.maxAttempts) {
|
|
209
|
+
return false;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
// Check timeout
|
|
213
|
+
if (this.config.timeoutMs) {
|
|
214
|
+
const elapsed = Date.now() - context.startTime;
|
|
215
|
+
if (elapsed + this.calculateDelay(context.attempt) > this.config.timeoutMs) {
|
|
216
|
+
return false;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
// Use custom retry logic if provided
|
|
221
|
+
if (this.config.isRetryable) {
|
|
222
|
+
return this.config.isRetryable(error);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
// Default retry logic for Kubernetes errors
|
|
226
|
+
if (error instanceof KubernetesError) {
|
|
227
|
+
return error.retryable;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
// Retry on specific error conditions
|
|
231
|
+
const errorMessage = error?.message?.toLowerCase() || '';
|
|
232
|
+
const retryableConditions = [
|
|
233
|
+
'econnrefused',
|
|
234
|
+
'enotfound',
|
|
235
|
+
'etimedout',
|
|
236
|
+
'econnreset',
|
|
237
|
+
'epipe',
|
|
238
|
+
'network',
|
|
239
|
+
'timeout',
|
|
240
|
+
'socket hang up',
|
|
241
|
+
'service unavailable',
|
|
242
|
+
'bad gateway',
|
|
243
|
+
'gateway timeout',
|
|
244
|
+
];
|
|
245
|
+
|
|
246
|
+
return retryableConditions.some((condition) => errorMessage.includes(condition));
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
/**
|
|
250
|
+
* Calculate delay for next retry attempt with exponential backoff and jitter
|
|
251
|
+
*/
|
|
252
|
+
private calculateDelay(attempt: number): number {
|
|
253
|
+
// Calculate base delay with exponential backoff
|
|
254
|
+
const baseDelay = Math.min(
|
|
255
|
+
this.config.initialDelayMs * Math.pow(this.config.backoffMultiplier, attempt - 1),
|
|
256
|
+
this.config.maxDelayMs,
|
|
257
|
+
);
|
|
258
|
+
|
|
259
|
+
// Add jitter to prevent thundering herd
|
|
260
|
+
const jitter = baseDelay * this.config.jitterFactor * (Math.random() * 2 - 1);
|
|
261
|
+
return Math.max(0, Math.floor(baseDelay + jitter));
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
/**
|
|
265
|
+
* Delay execution for specified milliseconds
|
|
266
|
+
*/
|
|
267
|
+
private delay(ms: number): Promise<void> {
|
|
268
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* Retry builder for fluent configuration
|
|
274
|
+
*/
|
|
275
|
+
export class RetryBuilder {
|
|
276
|
+
private config: Partial<RetryConfig> = {};
|
|
277
|
+
private logger?: Logger;
|
|
278
|
+
|
|
279
|
+
withMaxAttempts(attempts: number): this {
|
|
280
|
+
this.config.maxAttempts = attempts;
|
|
281
|
+
return this;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
withInitialDelay(ms: number): this {
|
|
285
|
+
this.config.initialDelayMs = ms;
|
|
286
|
+
return this;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
withMaxDelay(ms: number): this {
|
|
290
|
+
this.config.maxDelayMs = ms;
|
|
291
|
+
return this;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
withBackoffMultiplier(multiplier: number): this {
|
|
295
|
+
this.config.backoffMultiplier = multiplier;
|
|
296
|
+
return this;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
withJitterFactor(factor: number): this {
|
|
300
|
+
this.config.jitterFactor = factor;
|
|
301
|
+
return this;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
withTimeout(ms: number): this {
|
|
305
|
+
this.config.timeoutMs = ms;
|
|
306
|
+
return this;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
withRetryableCheck(fn: (error: any) => boolean): this {
|
|
310
|
+
this.config.isRetryable = fn;
|
|
311
|
+
return this;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
withRetryCallback(fn: (attempt: number, error: any, nextDelayMs: number) => void): this {
|
|
315
|
+
this.config.onRetry = fn;
|
|
316
|
+
return this;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
withLogger(logger: Logger): this {
|
|
320
|
+
this.logger = logger;
|
|
321
|
+
return this;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
withPreset(preset: keyof typeof RETRY_PRESETS): this {
|
|
325
|
+
// User overrides should take precedence
|
|
326
|
+
this.config = { ...RETRY_PRESETS[preset], ...this.config };
|
|
327
|
+
return this;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
build(): RetryStrategy {
|
|
331
|
+
return new RetryStrategy(this.config, this.logger);
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
/**
|
|
336
|
+
* Convenience function to create a retry strategy
|
|
337
|
+
*/
|
|
338
|
+
export function createRetryStrategy(config?: Partial<RetryConfig>, logger?: Logger): RetryStrategy {
|
|
339
|
+
return new RetryStrategy(config, logger);
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
/**
|
|
343
|
+
* Decorator for adding retry logic to methods
|
|
344
|
+
*/
|
|
345
|
+
export function Retryable(config: Partial<RetryConfig> = {}) {
|
|
346
|
+
return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
|
|
347
|
+
const originalMethod = descriptor.value;
|
|
348
|
+
const strategy = new RetryStrategy(config);
|
|
349
|
+
|
|
350
|
+
descriptor.value = async function (...args: any[]) {
|
|
351
|
+
const result = await strategy.execute(
|
|
352
|
+
() => originalMethod.apply(this, args),
|
|
353
|
+
`${target.constructor.name}.${propertyKey}`,
|
|
354
|
+
);
|
|
355
|
+
|
|
356
|
+
if (!result.success) {
|
|
357
|
+
throw result.error;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
return result.value;
|
|
361
|
+
};
|
|
362
|
+
|
|
363
|
+
return descriptor;
|
|
364
|
+
};
|
|
365
|
+
}
|
|
@@ -0,0 +1,313 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Retryable Operation Module
|
|
3
|
+
*
|
|
4
|
+
* Combines retry logic and circuit breaker pattern into a single
|
|
5
|
+
* reusable component for Kubernetes operations.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { Logger } from 'winston';
|
|
9
|
+
|
|
10
|
+
import { RetryStrategy, RetryConfig, RETRY_PRESETS } from './RetryStrategy.js';
|
|
11
|
+
import { CircuitBreaker, CircuitBreakerConfig } from './CircuitBreaker.js';
|
|
12
|
+
import { ErrorMonitor, KubernetesError, ErrorContext } from './ErrorHandling.js';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Configuration for retryable operations
|
|
16
|
+
*/
|
|
17
|
+
export interface RetryableOperationConfig {
|
|
18
|
+
/** Retry configuration */
|
|
19
|
+
retry?: Partial<RetryConfig>;
|
|
20
|
+
/** Circuit breaker configuration */
|
|
21
|
+
circuitBreaker?: Partial<Omit<CircuitBreakerConfig, 'name'>>;
|
|
22
|
+
/** Error monitor instance */
|
|
23
|
+
errorMonitor?: ErrorMonitor;
|
|
24
|
+
/** Logger instance */
|
|
25
|
+
logger?: Logger;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Result of a retryable operation
|
|
30
|
+
*/
|
|
31
|
+
export interface OperationResult<T> {
|
|
32
|
+
success: boolean;
|
|
33
|
+
value?: T;
|
|
34
|
+
error?: any;
|
|
35
|
+
attempts: number;
|
|
36
|
+
totalTimeMs: number;
|
|
37
|
+
circuitState?: string;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Retryable operation that combines retry and circuit breaker
|
|
42
|
+
*/
|
|
43
|
+
export class RetryableOperation<T> {
|
|
44
|
+
private readonly retryStrategy: RetryStrategy;
|
|
45
|
+
private readonly circuitBreaker: CircuitBreaker;
|
|
46
|
+
private readonly errorMonitor?: ErrorMonitor;
|
|
47
|
+
private readonly logger?: Logger;
|
|
48
|
+
|
|
49
|
+
constructor(
|
|
50
|
+
private readonly operationName: string,
|
|
51
|
+
config: RetryableOperationConfig = {},
|
|
52
|
+
) {
|
|
53
|
+
this.logger = config.logger;
|
|
54
|
+
this.errorMonitor = config.errorMonitor;
|
|
55
|
+
|
|
56
|
+
// Initialize retry strategy
|
|
57
|
+
this.retryStrategy = new RetryStrategy(config.retry || RETRY_PRESETS.STANDARD, this.logger);
|
|
58
|
+
|
|
59
|
+
// Initialize circuit breaker
|
|
60
|
+
this.circuitBreaker = new CircuitBreaker(
|
|
61
|
+
{
|
|
62
|
+
name: operationName,
|
|
63
|
+
failureThreshold: 5,
|
|
64
|
+
successThreshold: 2,
|
|
65
|
+
failureCountWindow: 60000,
|
|
66
|
+
resetTimeout: 30000,
|
|
67
|
+
...config.circuitBreaker,
|
|
68
|
+
},
|
|
69
|
+
this.logger,
|
|
70
|
+
);
|
|
71
|
+
|
|
72
|
+
// Set up circuit breaker event listeners
|
|
73
|
+
this.setupCircuitBreakerEvents();
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Execute an operation with retry and circuit breaker protection
|
|
78
|
+
*/
|
|
79
|
+
async execute<R = T>(
|
|
80
|
+
operation: () => Promise<R>,
|
|
81
|
+
context?: ErrorContext,
|
|
82
|
+
): Promise<OperationResult<R>> {
|
|
83
|
+
const startTime = Date.now();
|
|
84
|
+
|
|
85
|
+
try {
|
|
86
|
+
// Execute through circuit breaker
|
|
87
|
+
const result = await this.circuitBreaker.execute(async () => {
|
|
88
|
+
// Execute with retry logic
|
|
89
|
+
const retryResult = await this.retryStrategy.execute(operation, this.operationName);
|
|
90
|
+
|
|
91
|
+
if (!retryResult.success) {
|
|
92
|
+
throw retryResult.error;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
return retryResult;
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
return {
|
|
99
|
+
success: true,
|
|
100
|
+
value: result.value as R,
|
|
101
|
+
attempts: result.attempts,
|
|
102
|
+
totalTimeMs: Date.now() - startTime,
|
|
103
|
+
circuitState: this.circuitBreaker.getState(),
|
|
104
|
+
};
|
|
105
|
+
} catch (error) {
|
|
106
|
+
// Record error in monitor if available
|
|
107
|
+
if (this.errorMonitor && error instanceof KubernetesError) {
|
|
108
|
+
this.errorMonitor.recordError(error, this.operationName);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// Log error with context
|
|
112
|
+
this.logger?.error(`Operation '${this.operationName}' failed`, {
|
|
113
|
+
error: error instanceof Error ? error.message : String(error),
|
|
114
|
+
context,
|
|
115
|
+
circuitState: this.circuitBreaker.getState(),
|
|
116
|
+
stats: this.circuitBreaker.getStats(),
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
return {
|
|
120
|
+
success: false,
|
|
121
|
+
error,
|
|
122
|
+
attempts: 1, // Default if retry info not available
|
|
123
|
+
totalTimeMs: Date.now() - startTime,
|
|
124
|
+
circuitState: this.circuitBreaker.getState(),
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Execute operation and throw on failure
|
|
131
|
+
*/
|
|
132
|
+
async executeOrThrow<R = T>(operation: () => Promise<R>, context?: ErrorContext): Promise<R> {
|
|
133
|
+
const result = await this.execute(operation, context);
|
|
134
|
+
|
|
135
|
+
if (!result.success) {
|
|
136
|
+
throw result.error;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
return result.value!;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Get circuit breaker state
|
|
144
|
+
*/
|
|
145
|
+
getCircuitState(): string {
|
|
146
|
+
return this.circuitBreaker.getState();
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Get circuit breaker statistics
|
|
151
|
+
*/
|
|
152
|
+
getCircuitStats() {
|
|
153
|
+
return this.circuitBreaker.getStats();
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Manually reset the circuit breaker
|
|
158
|
+
*/
|
|
159
|
+
resetCircuit(): void {
|
|
160
|
+
this.circuitBreaker.reset();
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Force open the circuit breaker
|
|
165
|
+
*/
|
|
166
|
+
openCircuit(): void {
|
|
167
|
+
this.circuitBreaker.open();
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Set up circuit breaker event listeners
|
|
172
|
+
*/
|
|
173
|
+
private setupCircuitBreakerEvents(): void {
|
|
174
|
+
this.circuitBreaker.on('state-change', (oldState, newState) => {
|
|
175
|
+
this.logger?.info(
|
|
176
|
+
`Circuit breaker state changed for '${this.operationName}': ${oldState} -> ${newState}`,
|
|
177
|
+
);
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
this.circuitBreaker.on('circuit-open', (stats) => {
|
|
181
|
+
this.logger?.warn(`Circuit breaker opened for '${this.operationName}'`, { stats });
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
this.circuitBreaker.on('circuit-close', (stats) => {
|
|
185
|
+
this.logger?.info(`Circuit breaker closed for '${this.operationName}'`, { stats });
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Cleanup resources
|
|
191
|
+
*/
|
|
192
|
+
dispose(): void {
|
|
193
|
+
this.circuitBreaker.dispose();
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Factory for creating retryable operations
|
|
199
|
+
*/
|
|
200
|
+
export class RetryableOperationFactory {
|
|
201
|
+
private readonly operations = new Map<string, RetryableOperation<any>>();
|
|
202
|
+
private readonly defaultConfig: RetryableOperationConfig;
|
|
203
|
+
|
|
204
|
+
constructor(defaultConfig: RetryableOperationConfig = {}, logger?: Logger) {
|
|
205
|
+
this.defaultConfig = {
|
|
206
|
+
...defaultConfig,
|
|
207
|
+
logger: logger || defaultConfig.logger,
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Create or get a retryable operation
|
|
213
|
+
*/
|
|
214
|
+
create<T>(operationName: string, config?: RetryableOperationConfig): RetryableOperation<T> {
|
|
215
|
+
const existingOperation = this.operations.get(operationName);
|
|
216
|
+
|
|
217
|
+
if (existingOperation) {
|
|
218
|
+
return existingOperation;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
const operation = new RetryableOperation<T>(operationName, {
|
|
222
|
+
...this.defaultConfig,
|
|
223
|
+
...config,
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
this.operations.set(operationName, operation);
|
|
227
|
+
return operation;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* Get an existing operation
|
|
232
|
+
*/
|
|
233
|
+
get<T>(operationName: string): RetryableOperation<T> | undefined {
|
|
234
|
+
return this.operations.get(operationName);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* Remove an operation
|
|
239
|
+
*/
|
|
240
|
+
remove(operationName: string): boolean {
|
|
241
|
+
const operation = this.operations.get(operationName);
|
|
242
|
+
|
|
243
|
+
if (operation) {
|
|
244
|
+
operation.dispose();
|
|
245
|
+
return this.operations.delete(operationName);
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
return false;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* Get all operation names
|
|
253
|
+
*/
|
|
254
|
+
getOperationNames(): string[] {
|
|
255
|
+
return Array.from(this.operations.keys());
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
/**
|
|
259
|
+
* Get statistics for all operations
|
|
260
|
+
*/
|
|
261
|
+
getAllStats(): Record<string, any> {
|
|
262
|
+
const stats: Record<string, any> = {};
|
|
263
|
+
|
|
264
|
+
for (const [name, operation] of this.operations) {
|
|
265
|
+
stats[name] = {
|
|
266
|
+
circuitState: operation.getCircuitState(),
|
|
267
|
+
circuitStats: operation.getCircuitStats(),
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
return stats;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* Reset all circuit breakers
|
|
276
|
+
*/
|
|
277
|
+
resetAllCircuits(): void {
|
|
278
|
+
for (const operation of this.operations.values()) {
|
|
279
|
+
operation.resetCircuit();
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
/**
|
|
284
|
+
* Dispose all operations
|
|
285
|
+
*/
|
|
286
|
+
dispose(): void {
|
|
287
|
+
for (const operation of this.operations.values()) {
|
|
288
|
+
operation.dispose();
|
|
289
|
+
}
|
|
290
|
+
this.operations.clear();
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
/**
|
|
295
|
+
* Decorator for making methods retryable
|
|
296
|
+
*/
|
|
297
|
+
export function RetryableMethod(operationName?: string, config?: RetryableOperationConfig) {
|
|
298
|
+
return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
|
|
299
|
+
const originalMethod = descriptor.value;
|
|
300
|
+
const opName = operationName || `${target.constructor.name}.${propertyKey}`;
|
|
301
|
+
|
|
302
|
+
// Create a factory instance for the decorator
|
|
303
|
+
const factory = new RetryableOperationFactory(config);
|
|
304
|
+
|
|
305
|
+
descriptor.value = async function (...args: any[]) {
|
|
306
|
+
const operation = factory.create(opName);
|
|
307
|
+
|
|
308
|
+
return operation.executeOrThrow(() => originalMethod.apply(this, args));
|
|
309
|
+
};
|
|
310
|
+
|
|
311
|
+
return descriptor;
|
|
312
|
+
};
|
|
313
|
+
}
|