kubernetes.js 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. import { CoreV1Api, Metrics } from "@kubernetes/client-node";
  2. import getKubeConfig from "../../../utils/config/kubernetes";
  3. import { parseCpu, parseMemory } from "../../../utils/kubernetes/kubernetes-utils";
  4. import createLogger from "../../../utils/logger";
  5. const logger = createLogger("kubernetes-widget");
  6. export default async function handler(req, res) {
  7. try {
  8. const kc = getKubeConfig();
  9. if (!kc) {
  10. return res.status(500).send({
  11. error: "No kubernetes configuration"
  12. });
  13. }
  14. const coreApi = kc.makeApiClient(CoreV1Api);
  15. const metricsApi = new Metrics(kc);
  16. const nodes = await coreApi.listNode()
  17. .then((response) => response.body)
  18. .catch((error) => {
  19. logger.error("Error getting ingresses: %d %s %s", error.statusCode, error.body, error.response);
  20. return null;
  21. });
  22. if (!nodes) {
  23. return res.status(500).send({
  24. error: "unknown error"
  25. });
  26. }
  27. let cpuTotal = 0;
  28. let cpuUsage = 0;
  29. let memTotal = 0;
  30. let memUsage = 0;
  31. const nodeMap = {};
  32. nodes.items.forEach((node) => {
  33. const cpu = Number.parseInt(node.status.capacity.cpu, 10);
  34. const mem = parseMemory(node.status.capacity.memory);
  35. const ready = node.status.conditions.filter(condition => condition.type === "Ready" && condition.status === "True").length > 0;
  36. nodeMap[node.metadata.name] = {
  37. name: node.metadata.name,
  38. ready,
  39. cpu: {
  40. total: cpu
  41. },
  42. memory: {
  43. total: mem
  44. }
  45. };
  46. cpuTotal += cpu;
  47. memTotal += mem;
  48. });
  49. try {
  50. const nodeMetrics = await metricsApi.getNodeMetrics();
  51. nodeMetrics.items.forEach((nodeMetric) => {
  52. const cpu = parseCpu(nodeMetric.usage.cpu);
  53. const mem = parseMemory(nodeMetric.usage.memory);
  54. cpuUsage += cpu;
  55. memUsage += mem;
  56. nodeMap[nodeMetric.metadata.name].cpu.load = cpu;
  57. nodeMap[nodeMetric.metadata.name].cpu.percent = (cpu / nodeMap[nodeMetric.metadata.name].cpu.total) * 100;
  58. nodeMap[nodeMetric.metadata.name].memory.used = mem;
  59. nodeMap[nodeMetric.metadata.name].memory.free = nodeMap[nodeMetric.metadata.name].memory.total - mem;
  60. nodeMap[nodeMetric.metadata.name].memory.percent = (mem / nodeMap[nodeMetric.metadata.name].memory.total) * 100;
  61. });
  62. } catch (error) {
  63. logger.error("Error getting metrics, ensure you have metrics-server installed: s", JSON.stringify(error));
  64. return res.status(500).send({
  65. error: "Error getting metrics, check logs for more details"
  66. });
  67. }
  68. const cluster = {
  69. cpu: {
  70. load: cpuUsage,
  71. total: cpuTotal,
  72. percent: (cpuUsage / cpuTotal) * 100
  73. },
  74. memory: {
  75. used: memUsage,
  76. total: memTotal,
  77. free: (memTotal - memUsage),
  78. percent: (memUsage / memTotal) * 100
  79. }
  80. };
  81. return res.status(200).json({
  82. cluster,
  83. nodes: Object.entries(nodeMap).map(([name, node]) => ({ name, ...node }))
  84. });
  85. } catch (e) {
  86. logger.error("exception %s", e);
  87. return res.status(500).send({
  88. error: "unknown error"
  89. });
  90. }
  91. }