commit 8ff5c3c52700ff6f0bb841859dc14a54165e22b5 Author: Lino Silva Date: Thu Jun 12 10:38:14 2025 +0100 Initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a4f1f63 --- /dev/null +++ b/.gitignore @@ -0,0 +1,38 @@ +# Node modules +node_modules/ + +# Build output +dist/ +build/ +out/ + +# TypeScript cache +*.tsbuildinfo + +# Logs +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# Environment files +.env +.env.* + +# IDE files +.vscode/ +.DS_Store + +# Coverage directory +coverage/ + +# Optional npm cache directory +.npm/ + +# Optional eslint cache +.eslintcache + +# Mac system files +.DS_Store + +# Optional REPL history +.node_repl_history \ No newline at end of file diff --git a/@types/node b/@types/node new file mode 120000 index 0000000..5f990c9 --- /dev/null +++ b/@types/node @@ -0,0 +1 @@ +../.pnpm/@types+node@24.0.1/node_modules/@types/node \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..068653b --- /dev/null +++ b/package.json @@ -0,0 +1,17 @@ +{ + "name": "obsidian-proxmox-nodes", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "keywords": [], + "author": "", + "license": "ISC", + "packageManager": "pnpm@10.6.4", + "dependencies": { + "@types/node": "^24.0.1", + "proxmox-api": "^1.1.1" + } +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 0000000..d663684 --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,45 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + '@types/node': + specifier: ^24.0.1 + version: 24.0.1 + proxmox-api: + specifier: ^1.1.1 + version: 1.1.1 + +packages: + + '@types/node@24.0.1': + resolution: {integrity: sha512-MX4Zioh39chHlDJbKmEgydJDS3tspMP/lnQC67G3SWsTnb9NeYVWOjkxpOSy4oMfPs4StcWHwBrvUb4ybfnuaw==} + + proxmox-api@1.1.1: + resolution: {integrity: sha512-2qH7pxKBBHa7WtEBmxPaBY2FZEH2R04hqr9zD9PmErLzJ7RGGcfNcXoS/v5G4vBM2Igmnx0EAYBstPwwfDwHnA==} + + undici-types@7.8.0: + resolution: {integrity: sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw==} + + undici@6.21.3: + resolution: {integrity: sha512-gBLkYIlEnSp8pFbT64yFgGE6UIB9tAkhukC23PmMDCe5Nd+cRqKxSjw5y54MK2AZMgZfJWMaNE4nYUHgi1XEOw==} + engines: {node: '>=18.17'} + +snapshots: + + '@types/node@24.0.1': + dependencies: + undici-types: 7.8.0 + + proxmox-api@1.1.1: + dependencies: + undici: 6.21.3 + + undici-types@7.8.0: {} + + undici@6.21.3: {} diff --git a/src/helpers/build-node-file.ts b/src/helpers/build-node-file.ts new file mode 100644 index 0000000..7836eea --- /dev/null +++ b/src/helpers/build-node-file.ts @@ -0,0 +1,47 @@ +import fs from "fs"; +import path from "path"; + +interface BuildNodeFileParams { + name: string; + cpuCores: number; + cpuThreads: number; + cpuName: string; + sockets: number; + memory: number; +} + +export const buildNodeFile = ( + params: BuildNodeFileParams +): Promise => { + const { name, cpuCores, cpuThreads, cpuName, sockets, memory } = params; + + const content = `# Node: ${name} +# CPU: ${cpuCores} cores, ${cpuThreads} threads - ${cpuName} +# Sockets: ${sockets} +# Memory: ${memory} MB +# Generated by Proxmox API Helper +`; + + const filePath = path.join( + __dirname, + "../../", + "build", + `${name}.nodeinfo.md` + ); + return new Promise((resolve, reject) => { + fs.writeFile( + filePath, + content, + { flag: "wx", encoding: "utf8" }, + (err: NodeJS.ErrnoException | null) => { + if (err) { + console.error(`Error writing file ${filePath}:`, err); + reject(err); + } else { + console.info(`File ${filePath} created successfully.`); + resolve(true); + } + } + ); + }); +}; diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 0000000..a074734 --- /dev/null +++ b/src/index.ts @@ -0,0 +1,70 @@ +import proxmoxApi from "proxmox-api"; +import { buildNodeFile } from "./helpers/build-node-file"; + +// authorize self signed cert if you do not use a valid SSL certificat +process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0"; + +const connect = () => + proxmoxApi({ + host: "10.0.2.2", + password: "bemjogado", + username: "root@pam", + + port: 8006, + }); + +async function test() { + const proxmox = await connect(); + + const nodes = await proxmox.nodes.$get(); + + for (const node of nodes) { + const theNode = proxmox.nodes.$(node.node); + + console.log(`Node: ${JSON.stringify(node)}`); + + if (node.status === "online") { + const status = await theNode.status.$get(); + console.log(`##### Status: ${JSON.stringify(status)}`); + const cpuName = status.cpuinfo.model; + const cpuCores = status.cpuinfo.cores; + const cpuThreads = status.cpuinfo.cpus; + const sockets = status.cpuinfo.sockets; + + await buildNodeFile({ + name: node.node, + cpuCores, + cpuThreads, + cpuName, + sockets, + memory: status.memory.total, + }); + + console.log(`CPU: ${cpuCores} cores, ${cpuThreads} threads - ${cpuName}`); + + const config = await theNode.config.$get(); + console.log(`##### Config: ${JSON.stringify(config)}`); + + const hw = await theNode.hardware.$get(); + console.log(`##### Hardware: ${JSON.stringify(hw)}`); + + const qemus = await theNode.qemu.$get({ full: true }); + for (const qemu of qemus) { + const config = await theNode.qemu.$(qemu.vmid).config.$get(); + console.log(`##### vm: ${config.name}, memory: ${config.memory}`); + } + + const lxcs = await theNode.lxc.$get(); + for (const lxc of lxcs) { + const config = await theNode.lxc.$(lxc.vmid).config.$get(); + console.log( + `##### lxc: ${config.hostname}, cpus: ${config.cores} memory: ${config.memory}` + ); + } + } else { + console.log("Node is offline, skipping detailed info."); + } + } +} + +test().catch(console.error);