@sonde/packs 0.0.0 → 0.1.1

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.
Files changed (359) hide show
  1. package/.turbo/turbo-build.log +6 -0
  2. package/.turbo/turbo-test.log +814 -0
  3. package/.turbo/turbo-typecheck.log +4 -0
  4. package/CHANGELOG.md +10 -0
  5. package/dist/index.d.ts +16 -1
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/index.js +40 -2
  8. package/dist/index.js.map +1 -1
  9. package/dist/integrations/citrix.d.ts +13 -0
  10. package/dist/integrations/citrix.d.ts.map +1 -0
  11. package/dist/integrations/citrix.js +420 -0
  12. package/dist/integrations/citrix.js.map +1 -0
  13. package/dist/integrations/citrix.test.d.ts +2 -0
  14. package/dist/integrations/citrix.test.d.ts.map +1 -0
  15. package/dist/integrations/citrix.test.js +464 -0
  16. package/dist/integrations/citrix.test.js.map +1 -0
  17. package/dist/integrations/graph.d.ts +9 -0
  18. package/dist/integrations/graph.d.ts.map +1 -0
  19. package/dist/integrations/graph.js +290 -0
  20. package/dist/integrations/graph.js.map +1 -0
  21. package/dist/integrations/graph.test.d.ts +2 -0
  22. package/dist/integrations/graph.test.d.ts.map +1 -0
  23. package/dist/integrations/graph.test.js +356 -0
  24. package/dist/integrations/graph.test.js.map +1 -0
  25. package/dist/integrations/httpbin.d.ts +3 -0
  26. package/dist/integrations/httpbin.d.ts.map +1 -0
  27. package/dist/integrations/httpbin.js +70 -0
  28. package/dist/integrations/httpbin.js.map +1 -0
  29. package/dist/integrations/nutanix.d.ts +18 -0
  30. package/dist/integrations/nutanix.d.ts.map +1 -0
  31. package/dist/integrations/nutanix.js +1121 -0
  32. package/dist/integrations/nutanix.js.map +1 -0
  33. package/dist/integrations/nutanix.test.d.ts +2 -0
  34. package/dist/integrations/nutanix.test.d.ts.map +1 -0
  35. package/dist/integrations/nutanix.test.js +978 -0
  36. package/dist/integrations/nutanix.test.js.map +1 -0
  37. package/dist/integrations/proxmox.d.ts +12 -0
  38. package/dist/integrations/proxmox.d.ts.map +1 -0
  39. package/dist/integrations/proxmox.js +733 -0
  40. package/dist/integrations/proxmox.js.map +1 -0
  41. package/dist/integrations/proxmox.test.d.ts +2 -0
  42. package/dist/integrations/proxmox.test.d.ts.map +1 -0
  43. package/dist/integrations/proxmox.test.js +697 -0
  44. package/dist/integrations/proxmox.test.js.map +1 -0
  45. package/dist/integrations/servicenow.d.ts +3 -0
  46. package/dist/integrations/servicenow.d.ts.map +1 -0
  47. package/dist/integrations/servicenow.js +257 -0
  48. package/dist/integrations/servicenow.js.map +1 -0
  49. package/dist/integrations/servicenow.test.d.ts +2 -0
  50. package/dist/integrations/servicenow.test.d.ts.map +1 -0
  51. package/dist/integrations/servicenow.test.js +217 -0
  52. package/dist/integrations/servicenow.test.js.map +1 -0
  53. package/dist/integrations/splunk.d.ts +9 -0
  54. package/dist/integrations/splunk.d.ts.map +1 -0
  55. package/dist/integrations/splunk.js +242 -0
  56. package/dist/integrations/splunk.js.map +1 -0
  57. package/dist/integrations/splunk.test.d.ts +2 -0
  58. package/dist/integrations/splunk.test.d.ts.map +1 -0
  59. package/dist/integrations/splunk.test.js +323 -0
  60. package/dist/integrations/splunk.test.js.map +1 -0
  61. package/dist/mysql/index.d.ts +3 -0
  62. package/dist/mysql/index.d.ts.map +1 -0
  63. package/dist/mysql/index.js +13 -0
  64. package/dist/mysql/index.js.map +1 -0
  65. package/dist/mysql/manifest.d.ts +3 -0
  66. package/dist/mysql/manifest.d.ts.map +1 -0
  67. package/dist/mysql/manifest.js +69 -0
  68. package/dist/mysql/manifest.js.map +1 -0
  69. package/dist/mysql/probes/databases-list.d.ts +13 -0
  70. package/dist/mysql/probes/databases-list.d.ts.map +1 -0
  71. package/dist/mysql/probes/databases-list.js +31 -0
  72. package/dist/mysql/probes/databases-list.js.map +1 -0
  73. package/dist/mysql/probes/databases-list.test.d.ts +2 -0
  74. package/dist/mysql/probes/databases-list.test.d.ts.map +1 -0
  75. package/dist/mysql/probes/databases-list.test.js +54 -0
  76. package/dist/mysql/probes/databases-list.test.js.map +1 -0
  77. package/dist/mysql/probes/processlist.d.ts +18 -0
  78. package/dist/mysql/probes/processlist.d.ts.map +1 -0
  79. package/dist/mysql/probes/processlist.js +36 -0
  80. package/dist/mysql/probes/processlist.js.map +1 -0
  81. package/dist/mysql/probes/processlist.test.d.ts +2 -0
  82. package/dist/mysql/probes/processlist.test.d.ts.map +1 -0
  83. package/dist/mysql/probes/processlist.test.js +41 -0
  84. package/dist/mysql/probes/processlist.test.js.map +1 -0
  85. package/dist/mysql/probes/status.d.ts +14 -0
  86. package/dist/mysql/probes/status.d.ts.map +1 -0
  87. package/dist/mysql/probes/status.js +40 -0
  88. package/dist/mysql/probes/status.js.map +1 -0
  89. package/dist/mysql/probes/status.test.d.ts +2 -0
  90. package/dist/mysql/probes/status.test.d.ts.map +1 -0
  91. package/dist/mysql/probes/status.test.js +43 -0
  92. package/dist/mysql/probes/status.test.js.map +1 -0
  93. package/dist/nginx/index.d.ts +3 -0
  94. package/dist/nginx/index.d.ts.map +1 -0
  95. package/dist/nginx/index.js +13 -0
  96. package/dist/nginx/index.js.map +1 -0
  97. package/dist/nginx/manifest.d.ts +3 -0
  98. package/dist/nginx/manifest.d.ts.map +1 -0
  99. package/dist/nginx/manifest.js +68 -0
  100. package/dist/nginx/manifest.js.map +1 -0
  101. package/dist/nginx/probes/access-log-tail.d.ts +9 -0
  102. package/dist/nginx/probes/access-log-tail.d.ts.map +1 -0
  103. package/dist/nginx/probes/access-log-tail.js +14 -0
  104. package/dist/nginx/probes/access-log-tail.js.map +1 -0
  105. package/dist/nginx/probes/access-log-tail.test.d.ts +2 -0
  106. package/dist/nginx/probes/access-log-tail.test.d.ts.map +1 -0
  107. package/dist/nginx/probes/access-log-tail.test.js +40 -0
  108. package/dist/nginx/probes/access-log-tail.test.js.map +1 -0
  109. package/dist/nginx/probes/config-test.d.ts +8 -0
  110. package/dist/nginx/probes/config-test.d.ts.map +1 -0
  111. package/dist/nginx/probes/config-test.js +18 -0
  112. package/dist/nginx/probes/config-test.js.map +1 -0
  113. package/dist/nginx/probes/config-test.test.d.ts +2 -0
  114. package/dist/nginx/probes/config-test.test.d.ts.map +1 -0
  115. package/dist/nginx/probes/config-test.test.js +35 -0
  116. package/dist/nginx/probes/config-test.test.js.map +1 -0
  117. package/dist/nginx/probes/error-log-tail.d.ts +9 -0
  118. package/dist/nginx/probes/error-log-tail.d.ts.map +1 -0
  119. package/dist/nginx/probes/error-log-tail.js +14 -0
  120. package/dist/nginx/probes/error-log-tail.js.map +1 -0
  121. package/dist/nginx/probes/error-log-tail.test.d.ts +2 -0
  122. package/dist/nginx/probes/error-log-tail.test.d.ts.map +1 -0
  123. package/dist/nginx/probes/error-log-tail.test.js +34 -0
  124. package/dist/nginx/probes/error-log-tail.test.js.map +1 -0
  125. package/dist/postgres/index.d.ts +3 -0
  126. package/dist/postgres/index.d.ts.map +1 -0
  127. package/dist/postgres/index.js +13 -0
  128. package/dist/postgres/index.js.map +1 -0
  129. package/dist/postgres/manifest.d.ts +3 -0
  130. package/dist/postgres/manifest.d.ts.map +1 -0
  131. package/dist/postgres/manifest.js +90 -0
  132. package/dist/postgres/manifest.js.map +1 -0
  133. package/dist/postgres/probes/connections-active.d.ts +17 -0
  134. package/dist/postgres/probes/connections-active.d.ts.map +1 -0
  135. package/dist/postgres/probes/connections-active.js +37 -0
  136. package/dist/postgres/probes/connections-active.js.map +1 -0
  137. package/dist/postgres/probes/connections-active.test.d.ts +2 -0
  138. package/dist/postgres/probes/connections-active.test.d.ts.map +1 -0
  139. package/dist/postgres/probes/connections-active.test.js +36 -0
  140. package/dist/postgres/probes/connections-active.test.js.map +1 -0
  141. package/dist/postgres/probes/databases-list.d.ts +14 -0
  142. package/dist/postgres/probes/databases-list.d.ts.map +1 -0
  143. package/dist/postgres/probes/databases-list.js +34 -0
  144. package/dist/postgres/probes/databases-list.js.map +1 -0
  145. package/dist/postgres/probes/databases-list.test.d.ts +2 -0
  146. package/dist/postgres/probes/databases-list.test.d.ts.map +1 -0
  147. package/dist/postgres/probes/databases-list.test.js +49 -0
  148. package/dist/postgres/probes/databases-list.test.js.map +1 -0
  149. package/dist/postgres/probes/query-slow.d.ts +17 -0
  150. package/dist/postgres/probes/query-slow.d.ts.map +1 -0
  151. package/dist/postgres/probes/query-slow.js +37 -0
  152. package/dist/postgres/probes/query-slow.js.map +1 -0
  153. package/dist/postgres/probes/query-slow.test.d.ts +2 -0
  154. package/dist/postgres/probes/query-slow.test.d.ts.map +1 -0
  155. package/dist/postgres/probes/query-slow.test.js +30 -0
  156. package/dist/postgres/probes/query-slow.test.js.map +1 -0
  157. package/dist/proxmox/index.d.ts +3 -0
  158. package/dist/proxmox/index.d.ts.map +1 -0
  159. package/dist/proxmox/index.js +23 -0
  160. package/dist/proxmox/index.js.map +1 -0
  161. package/dist/proxmox/manifest.d.ts +3 -0
  162. package/dist/proxmox/manifest.d.ts.map +1 -0
  163. package/dist/proxmox/manifest.js +75 -0
  164. package/dist/proxmox/manifest.js.map +1 -0
  165. package/dist/proxmox/probes/ceph-status.d.ts +36 -0
  166. package/dist/proxmox/probes/ceph-status.d.ts.map +1 -0
  167. package/dist/proxmox/probes/ceph-status.js +71 -0
  168. package/dist/proxmox/probes/ceph-status.js.map +1 -0
  169. package/dist/proxmox/probes/ceph-status.test.d.ts +2 -0
  170. package/dist/proxmox/probes/ceph-status.test.d.ts.map +1 -0
  171. package/dist/proxmox/probes/ceph-status.test.js +115 -0
  172. package/dist/proxmox/probes/ceph-status.test.js.map +1 -0
  173. package/dist/proxmox/probes/cluster-config.d.ts +31 -0
  174. package/dist/proxmox/probes/cluster-config.d.ts.map +1 -0
  175. package/dist/proxmox/probes/cluster-config.js +72 -0
  176. package/dist/proxmox/probes/cluster-config.js.map +1 -0
  177. package/dist/proxmox/probes/cluster-config.test.d.ts +2 -0
  178. package/dist/proxmox/probes/cluster-config.test.d.ts.map +1 -0
  179. package/dist/proxmox/probes/cluster-config.test.js +107 -0
  180. package/dist/proxmox/probes/cluster-config.test.js.map +1 -0
  181. package/dist/proxmox/probes/ha-status.d.ts +18 -0
  182. package/dist/proxmox/probes/ha-status.d.ts.map +1 -0
  183. package/dist/proxmox/probes/ha-status.js +38 -0
  184. package/dist/proxmox/probes/ha-status.js.map +1 -0
  185. package/dist/proxmox/probes/ha-status.test.d.ts +2 -0
  186. package/dist/proxmox/probes/ha-status.test.d.ts.map +1 -0
  187. package/dist/proxmox/probes/ha-status.test.js +66 -0
  188. package/dist/proxmox/probes/ha-status.test.js.map +1 -0
  189. package/dist/proxmox/probes/lvm.d.ts +35 -0
  190. package/dist/proxmox/probes/lvm.d.ts.map +1 -0
  191. package/dist/proxmox/probes/lvm.js +75 -0
  192. package/dist/proxmox/probes/lvm.js.map +1 -0
  193. package/dist/proxmox/probes/lvm.test.d.ts +2 -0
  194. package/dist/proxmox/probes/lvm.test.d.ts.map +1 -0
  195. package/dist/proxmox/probes/lvm.test.js +128 -0
  196. package/dist/proxmox/probes/lvm.test.js.map +1 -0
  197. package/dist/proxmox/probes/lxc-config.d.ts +29 -0
  198. package/dist/proxmox/probes/lxc-config.d.ts.map +1 -0
  199. package/dist/proxmox/probes/lxc-config.js +67 -0
  200. package/dist/proxmox/probes/lxc-config.js.map +1 -0
  201. package/dist/proxmox/probes/lxc-config.test.d.ts +2 -0
  202. package/dist/proxmox/probes/lxc-config.test.d.ts.map +1 -0
  203. package/dist/proxmox/probes/lxc-config.test.js +77 -0
  204. package/dist/proxmox/probes/lxc-config.test.js.map +1 -0
  205. package/dist/proxmox/probes/lxc-list.d.ts +20 -0
  206. package/dist/proxmox/probes/lxc-list.d.ts.map +1 -0
  207. package/dist/proxmox/probes/lxc-list.js +49 -0
  208. package/dist/proxmox/probes/lxc-list.js.map +1 -0
  209. package/dist/proxmox/probes/lxc-list.test.d.ts +2 -0
  210. package/dist/proxmox/probes/lxc-list.test.d.ts.map +1 -0
  211. package/dist/proxmox/probes/lxc-list.test.js +51 -0
  212. package/dist/proxmox/probes/lxc-list.test.js.map +1 -0
  213. package/dist/proxmox/probes/vm-config.d.ts +21 -0
  214. package/dist/proxmox/probes/vm-config.d.ts.map +1 -0
  215. package/dist/proxmox/probes/vm-config.js +58 -0
  216. package/dist/proxmox/probes/vm-config.js.map +1 -0
  217. package/dist/proxmox/probes/vm-config.test.d.ts +2 -0
  218. package/dist/proxmox/probes/vm-config.test.d.ts.map +1 -0
  219. package/dist/proxmox/probes/vm-config.test.js +80 -0
  220. package/dist/proxmox/probes/vm-config.test.js.map +1 -0
  221. package/dist/proxmox/probes/vm-locks.d.ts +16 -0
  222. package/dist/proxmox/probes/vm-locks.d.ts.map +1 -0
  223. package/dist/proxmox/probes/vm-locks.js +35 -0
  224. package/dist/proxmox/probes/vm-locks.js.map +1 -0
  225. package/dist/proxmox/probes/vm-locks.test.d.ts +2 -0
  226. package/dist/proxmox/probes/vm-locks.test.d.ts.map +1 -0
  227. package/dist/proxmox/probes/vm-locks.test.js +54 -0
  228. package/dist/proxmox/probes/vm-locks.test.js.map +1 -0
  229. package/dist/redis/index.d.ts +3 -0
  230. package/dist/redis/index.d.ts.map +1 -0
  231. package/dist/redis/index.js +13 -0
  232. package/dist/redis/index.js.map +1 -0
  233. package/dist/redis/manifest.d.ts +3 -0
  234. package/dist/redis/manifest.d.ts.map +1 -0
  235. package/dist/redis/manifest.js +51 -0
  236. package/dist/redis/manifest.js.map +1 -0
  237. package/dist/redis/probes/info.d.ts +15 -0
  238. package/dist/redis/probes/info.d.ts.map +1 -0
  239. package/dist/redis/probes/info.js +32 -0
  240. package/dist/redis/probes/info.js.map +1 -0
  241. package/dist/redis/probes/info.test.d.ts +2 -0
  242. package/dist/redis/probes/info.test.d.ts.map +1 -0
  243. package/dist/redis/probes/info.test.js +64 -0
  244. package/dist/redis/probes/info.test.js.map +1 -0
  245. package/dist/redis/probes/keys-count.d.ts +13 -0
  246. package/dist/redis/probes/keys-count.d.ts.map +1 -0
  247. package/dist/redis/probes/keys-count.js +24 -0
  248. package/dist/redis/probes/keys-count.js.map +1 -0
  249. package/dist/redis/probes/keys-count.test.d.ts +2 -0
  250. package/dist/redis/probes/keys-count.test.d.ts.map +1 -0
  251. package/dist/redis/probes/keys-count.test.js +37 -0
  252. package/dist/redis/probes/keys-count.test.js.map +1 -0
  253. package/dist/redis/probes/memory-usage.d.ts +16 -0
  254. package/dist/redis/probes/memory-usage.d.ts.map +1 -0
  255. package/dist/redis/probes/memory-usage.js +31 -0
  256. package/dist/redis/probes/memory-usage.js.map +1 -0
  257. package/dist/redis/probes/memory-usage.test.d.ts +2 -0
  258. package/dist/redis/probes/memory-usage.test.d.ts.map +1 -0
  259. package/dist/redis/probes/memory-usage.test.js +48 -0
  260. package/dist/redis/probes/memory-usage.test.js.map +1 -0
  261. package/dist/runbooks/nutanix.d.ts +3 -0
  262. package/dist/runbooks/nutanix.d.ts.map +1 -0
  263. package/dist/runbooks/nutanix.js +619 -0
  264. package/dist/runbooks/nutanix.js.map +1 -0
  265. package/dist/runbooks/nutanix.test.d.ts +2 -0
  266. package/dist/runbooks/nutanix.test.d.ts.map +1 -0
  267. package/dist/runbooks/nutanix.test.js +971 -0
  268. package/dist/runbooks/nutanix.test.js.map +1 -0
  269. package/dist/runbooks/proxmox.d.ts +3 -0
  270. package/dist/runbooks/proxmox.d.ts.map +1 -0
  271. package/dist/runbooks/proxmox.js +451 -0
  272. package/dist/runbooks/proxmox.js.map +1 -0
  273. package/dist/runbooks/proxmox.test.d.ts +2 -0
  274. package/dist/runbooks/proxmox.test.d.ts.map +1 -0
  275. package/dist/runbooks/proxmox.test.js +700 -0
  276. package/dist/runbooks/proxmox.test.js.map +1 -0
  277. package/dist/signatures.d.ts +2 -0
  278. package/dist/signatures.d.ts.map +1 -0
  279. package/dist/signatures.js +2 -0
  280. package/dist/signatures.js.map +1 -0
  281. package/dist/types.d.ts +53 -0
  282. package/dist/types.d.ts.map +1 -1
  283. package/dist/validation.d.ts +6 -1
  284. package/dist/validation.d.ts.map +1 -1
  285. package/dist/validation.js +10 -1
  286. package/dist/validation.js.map +1 -1
  287. package/package.json +1 -1
  288. package/src/index.ts +60 -6
  289. package/src/integrations/citrix.test.ts +592 -0
  290. package/src/integrations/citrix.ts +557 -0
  291. package/src/integrations/graph.test.ts +478 -0
  292. package/src/integrations/graph.ts +413 -0
  293. package/src/integrations/httpbin.ts +72 -0
  294. package/src/integrations/nutanix.test.ts +1508 -0
  295. package/src/integrations/nutanix.ts +1460 -0
  296. package/src/integrations/proxmox.test.ts +1020 -0
  297. package/src/integrations/proxmox.ts +989 -0
  298. package/src/integrations/servicenow.test.ts +314 -0
  299. package/src/integrations/servicenow.ts +285 -0
  300. package/src/integrations/splunk.test.ts +440 -0
  301. package/src/integrations/splunk.ts +356 -0
  302. package/src/mysql/index.ts +14 -0
  303. package/src/mysql/manifest.ts +70 -0
  304. package/src/mysql/probes/databases-list.test.ts +62 -0
  305. package/src/mysql/probes/databases-list.ts +45 -0
  306. package/src/mysql/probes/processlist.test.ts +47 -0
  307. package/src/mysql/probes/processlist.ts +55 -0
  308. package/src/mysql/probes/status.test.ts +50 -0
  309. package/src/mysql/probes/status.ts +56 -0
  310. package/src/nginx/index.ts +14 -0
  311. package/src/nginx/manifest.ts +69 -0
  312. package/src/nginx/probes/access-log-tail.test.ts +51 -0
  313. package/src/nginx/probes/access-log-tail.ts +23 -0
  314. package/src/nginx/probes/config-test.test.ts +47 -0
  315. package/src/nginx/probes/config-test.ts +24 -0
  316. package/src/nginx/probes/error-log-tail.test.ts +44 -0
  317. package/src/nginx/probes/error-log-tail.ts +23 -0
  318. package/src/postgres/index.ts +14 -0
  319. package/src/postgres/manifest.ts +91 -0
  320. package/src/postgres/probes/connections-active.test.ts +42 -0
  321. package/src/postgres/probes/connections-active.ts +55 -0
  322. package/src/postgres/probes/databases-list.test.ts +57 -0
  323. package/src/postgres/probes/databases-list.ts +49 -0
  324. package/src/postgres/probes/query-slow.test.ts +37 -0
  325. package/src/postgres/probes/query-slow.ts +55 -0
  326. package/src/proxmox/index.ts +24 -0
  327. package/src/proxmox/manifest.ts +76 -0
  328. package/src/proxmox/probes/ceph-status.test.ts +126 -0
  329. package/src/proxmox/probes/ceph-status.ts +116 -0
  330. package/src/proxmox/probes/cluster-config.test.ts +118 -0
  331. package/src/proxmox/probes/cluster-config.ts +97 -0
  332. package/src/proxmox/probes/ha-status.test.ts +76 -0
  333. package/src/proxmox/probes/ha-status.ts +56 -0
  334. package/src/proxmox/probes/lvm.test.ts +140 -0
  335. package/src/proxmox/probes/lvm.ts +121 -0
  336. package/src/proxmox/probes/lxc-config.test.ts +89 -0
  337. package/src/proxmox/probes/lxc-config.ts +90 -0
  338. package/src/proxmox/probes/lxc-list.test.ts +60 -0
  339. package/src/proxmox/probes/lxc-list.ts +67 -0
  340. package/src/proxmox/probes/vm-config.test.ts +93 -0
  341. package/src/proxmox/probes/vm-config.ts +77 -0
  342. package/src/proxmox/probes/vm-locks.test.ts +63 -0
  343. package/src/proxmox/probes/vm-locks.ts +49 -0
  344. package/src/redis/index.ts +14 -0
  345. package/src/redis/manifest.ts +52 -0
  346. package/src/redis/probes/info.test.ts +73 -0
  347. package/src/redis/probes/info.ts +46 -0
  348. package/src/redis/probes/keys-count.test.ts +44 -0
  349. package/src/redis/probes/keys-count.ts +38 -0
  350. package/src/redis/probes/memory-usage.test.ts +54 -0
  351. package/src/redis/probes/memory-usage.ts +46 -0
  352. package/src/runbooks/nutanix.test.ts +1138 -0
  353. package/src/runbooks/nutanix.ts +941 -0
  354. package/src/runbooks/proxmox.test.ts +838 -0
  355. package/src/runbooks/proxmox.ts +626 -0
  356. package/src/signatures.ts +1 -0
  357. package/src/types.ts +62 -0
  358. package/src/validation.ts +21 -1
  359. package/tsconfig.tsbuildinfo +1 -0
@@ -0,0 +1,557 @@
1
+ import type {
2
+ FetchFn,
3
+ IntegrationConfig,
4
+ IntegrationCredentials,
5
+ IntegrationPack,
6
+ IntegrationProbeHandler,
7
+ } from '@sonde/shared';
8
+
9
+ // --- Enum mappings (Citrix OData uses integer keys) ---
10
+
11
+ const CONNECTION_STATE: Record<number, string> = {
12
+ 0: 'Unknown',
13
+ 1: 'Connected',
14
+ 2: 'Disconnected',
15
+ 3: 'Disconnected',
16
+ 4: 'Preparing',
17
+ 5: 'Active',
18
+ };
19
+
20
+ const REGISTRATION_STATE: Record<number, string> = {
21
+ 0: 'Unregistered',
22
+ 1: 'Registered',
23
+ 2: 'AgentError',
24
+ };
25
+
26
+ const POWER_STATE: Record<number, string> = {
27
+ 0: 'Unmanaged',
28
+ 1: 'Unknown',
29
+ 2: 'Unavailable',
30
+ 3: 'Off',
31
+ 4: 'On',
32
+ 5: 'Suspended',
33
+ 6: 'TurningOn',
34
+ 7: 'TurningOff',
35
+ };
36
+
37
+ const FAULT_STATE: Record<number, string> = {
38
+ 0: 'None',
39
+ 1: 'FailedToStart',
40
+ 2: 'StuckOnBoot',
41
+ 3: 'Unregistered',
42
+ 4: 'MaxCapacity',
43
+ };
44
+
45
+ const FAILURE_CATEGORY: Record<number, string> = {
46
+ 0: 'None',
47
+ 1: 'ClientConnectionFailure',
48
+ 2: 'ClientError',
49
+ 3: 'CommunicationError',
50
+ 4: 'ConnectionTimeout',
51
+ 5: 'LicensingFailure',
52
+ 6: 'TicketingFailure',
53
+ 7: 'Other',
54
+ 8: 'Unknown',
55
+ };
56
+
57
+ // --- Cloud token cache ---
58
+
59
+ interface CachedToken {
60
+ accessToken: string;
61
+ expiresAt: number;
62
+ }
63
+
64
+ let tokenCache: CachedToken | null = null;
65
+
66
+ /** Acquire or reuse a Citrix Cloud OAuth2 token via client_credentials grant */
67
+ export async function ensureAccessToken(
68
+ credentials: IntegrationCredentials,
69
+ fetchFn: FetchFn,
70
+ ): Promise<string> {
71
+ if (tokenCache && Date.now() < tokenCache.expiresAt - 30_000) {
72
+ return tokenCache.accessToken;
73
+ }
74
+
75
+ const customerId = credentials.credentials.customerId ?? '';
76
+ const clientId = credentials.credentials.clientId ?? '';
77
+ const clientSecret = credentials.credentials.clientSecret ?? '';
78
+ const tokenUrl = `https://api.cloud.com/cctrustoauth2/${customerId}/tokens/clients`;
79
+
80
+ const body = new URLSearchParams({
81
+ grant_type: 'client_credentials',
82
+ client_id: clientId,
83
+ client_secret: clientSecret,
84
+ });
85
+
86
+ const res = await fetchFn(tokenUrl, {
87
+ method: 'POST',
88
+ headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
89
+ body: body.toString(),
90
+ });
91
+
92
+ if (!res.ok) {
93
+ throw new Error(`Citrix Cloud token request failed: ${res.status} ${res.statusText}`);
94
+ }
95
+
96
+ const data = (await res.json()) as { access_token: string; expires_in: number };
97
+ tokenCache = {
98
+ accessToken: data.access_token,
99
+ expiresAt: Date.now() + data.expires_in * 1000,
100
+ };
101
+ return tokenCache.accessToken;
102
+ }
103
+
104
+ /** Clear the cached token (used for testing) */
105
+ export function clearTokenCache(): void {
106
+ tokenCache = null;
107
+ }
108
+
109
+ // --- Auth & URL helpers ---
110
+
111
+ /** Build auth headers: Basic for on-prem (api_key), CWSAuth for cloud (oauth2) */
112
+ export function buildAuthHeaders(
113
+ credentials: IntegrationCredentials,
114
+ cloudToken?: string,
115
+ ): Record<string, string> {
116
+ if (credentials.authMethod === 'oauth2') {
117
+ const headers: Record<string, string> = {
118
+ Authorization: `CWSAuth bearer=${cloudToken ?? ''}`,
119
+ 'Citrix-CustomerId': credentials.credentials.customerId ?? '',
120
+ };
121
+ return headers;
122
+ }
123
+
124
+ // api_key = on-prem Director with DOMAIN\username:password Basic auth
125
+ const { domain, username, password } = credentials.credentials;
126
+ const user = domain ? `${domain}\\${username}` : username;
127
+ if (user && password) {
128
+ return { Authorization: `Basic ${Buffer.from(`${user}:${password}`).toString('base64')}` };
129
+ }
130
+ return {};
131
+ }
132
+
133
+ /** Build OData URL: on-prem appends /Citrix/Monitor/OData/v4/Data, cloud uses endpoint directly */
134
+ export function buildODataUrl(endpoint: string, authMethod: string, entity: string): string {
135
+ if (authMethod === 'oauth2') {
136
+ // Cloud: endpoint is e.g. https://api.cloud.com/monitorodata
137
+ return `${endpoint.replace(/\/$/, '')}/${entity}`;
138
+ }
139
+ // On-prem: append OData path
140
+ return `${endpoint.replace(/\/$/, '')}/Citrix/Monitor/OData/v4/Data/${entity}`;
141
+ }
142
+
143
+ // --- OData pagination ---
144
+
145
+ interface ODataResponse {
146
+ value: unknown[];
147
+ '@odata.nextLink'?: string;
148
+ }
149
+
150
+ /** Fetch all pages of an OData response, following @odata.nextLink */
151
+ export async function fetchAllPages(
152
+ url: string,
153
+ headers: Record<string, string>,
154
+ fetchFn: FetchFn,
155
+ maxPages = 10,
156
+ ): Promise<unknown[]> {
157
+ const results: unknown[] = [];
158
+ let nextUrl: string | undefined = url;
159
+ let page = 0;
160
+
161
+ while (nextUrl && page < maxPages) {
162
+ const res = await fetchFn(nextUrl, { headers: { Accept: 'application/json', ...headers } });
163
+ if (!res.ok) throw new Error(`Citrix OData API returned ${res.status}: ${res.statusText}`);
164
+ const data = (await res.json()) as ODataResponse;
165
+ results.push(...(data.value ?? []));
166
+ nextUrl = data['@odata.nextLink'];
167
+ page++;
168
+ }
169
+
170
+ return results;
171
+ }
172
+
173
+ // --- Combined fetch helper ---
174
+
175
+ async function citrixFetch(
176
+ entity: string,
177
+ odataParams: Record<string, string>,
178
+ config: IntegrationConfig,
179
+ credentials: IntegrationCredentials,
180
+ fetchFn: FetchFn,
181
+ maxPages = 10,
182
+ ): Promise<unknown[]> {
183
+ let cloudToken: string | undefined;
184
+ if (credentials.authMethod === 'oauth2') {
185
+ cloudToken = await ensureAccessToken(credentials, fetchFn);
186
+ }
187
+
188
+ const baseUrl = buildODataUrl(config.endpoint, credentials.authMethod, entity);
189
+ const url = new URL(baseUrl);
190
+ for (const [key, value] of Object.entries(odataParams)) {
191
+ url.searchParams.set(key, value);
192
+ }
193
+
194
+ const headers: Record<string, string> = {
195
+ ...buildAuthHeaders(credentials, cloudToken),
196
+ ...config.headers,
197
+ };
198
+
199
+ return fetchAllPages(url.toString(), headers, fetchFn, maxPages);
200
+ }
201
+
202
+ // --- Helpers ---
203
+
204
+ /** Calculate duration in ms from timestamp pair, or use existing duration field */
205
+ function calcDuration(
206
+ item: Record<string, unknown>,
207
+ durationKey: string,
208
+ startKey: string,
209
+ endKey: string,
210
+ ): number | null {
211
+ const dur = item[durationKey];
212
+ if (typeof dur === 'number' && dur > 0) return dur;
213
+ const start = item[startKey];
214
+ const end = item[endKey];
215
+ if (typeof start === 'string' && typeof end === 'string') {
216
+ const diff = new Date(end).getTime() - new Date(start).getTime();
217
+ return diff >= 0 ? diff : null;
218
+ }
219
+ return null;
220
+ }
221
+
222
+ function mapEnum(value: unknown, mapping: Record<number, string>): string {
223
+ if (typeof value === 'number') return mapping[value] ?? `Unknown(${value})`;
224
+ return String(value ?? 'Unknown');
225
+ }
226
+
227
+ // --- Probe handlers ---
228
+
229
+ const sessionsActive: IntegrationProbeHandler = async (params, config, credentials, fetchFn) => {
230
+ const items = (await citrixFetch(
231
+ 'Sessions',
232
+ { $filter: 'EndDate eq null', $expand: 'Machine,DesktopGroup' },
233
+ config,
234
+ credentials,
235
+ fetchFn,
236
+ )) as Array<Record<string, unknown>>;
237
+
238
+ // Group by delivery group
239
+ const groups: Record<string, { active: number; disconnected: number; total: number }> = {};
240
+ for (const s of items) {
241
+ const dg = (s.DesktopGroup as Record<string, unknown>)?.Name ?? 'Unknown';
242
+ const dgName = String(dg);
243
+ if (!groups[dgName]) groups[dgName] = { active: 0, disconnected: 0, total: 0 };
244
+ const state = s.ConnectionState as number;
245
+ if (state === 5) groups[dgName].active++;
246
+ else if (state === 3) groups[dgName].disconnected++;
247
+ groups[dgName].total++;
248
+ }
249
+
250
+ return {
251
+ totalSessions: items.length,
252
+ byDeliveryGroup: Object.entries(groups).map(([name, counts]) => ({
253
+ deliveryGroup: name,
254
+ ...counts,
255
+ })),
256
+ };
257
+ };
258
+
259
+ const sessionsFailures: IntegrationProbeHandler = async (params, config, credentials, fetchFn) => {
260
+ const hours = (params?.hours as number) || 24;
261
+ const cutoff = new Date(Date.now() - hours * 60 * 60 * 1000).toISOString();
262
+
263
+ const items = (await citrixFetch(
264
+ 'Connections',
265
+ {
266
+ $filter: `FailureDate ne null and LogOnStartDate ge datetime'${cutoff}'`,
267
+ },
268
+ config,
269
+ credentials,
270
+ fetchFn,
271
+ )) as Array<Record<string, unknown>>;
272
+
273
+ // Count by FailureCategory
274
+ const byCategory: Record<string, number> = {};
275
+ const affectedUsers = new Set<string>();
276
+ const affectedMachines = new Set<string>();
277
+
278
+ for (const c of items) {
279
+ const cat = mapEnum(c.FailureCategory, FAILURE_CATEGORY);
280
+ byCategory[cat] = (byCategory[cat] ?? 0) + 1;
281
+ if (c.UserName) affectedUsers.add(String(c.UserName));
282
+ if (c.MachineName) affectedMachines.add(String(c.MachineName));
283
+ }
284
+
285
+ return {
286
+ totalFailures: items.length,
287
+ periodHours: hours,
288
+ byCategory,
289
+ affectedUsers: [...affectedUsers],
290
+ affectedMachines: [...affectedMachines],
291
+ };
292
+ };
293
+
294
+ const logonPerformance: IntegrationProbeHandler = async (params, config, credentials, fetchFn) => {
295
+ const hours = (params?.hours as number) || 24;
296
+ const cutoff = new Date(Date.now() - hours * 60 * 60 * 1000).toISOString();
297
+
298
+ const items = (await citrixFetch(
299
+ 'Sessions',
300
+ {
301
+ $filter: `LogOnDuration ne null and StartDate ge datetime'${cutoff}'`,
302
+ $expand: 'DesktopGroup',
303
+ },
304
+ config,
305
+ credentials,
306
+ fetchFn,
307
+ )) as Array<Record<string, unknown>>;
308
+
309
+ // Aggregate by delivery group
310
+ const groups: Record<
311
+ string,
312
+ {
313
+ count: number;
314
+ totalLogon: number;
315
+ totalBrokering: number;
316
+ totalVM: number;
317
+ }
318
+ > = {};
319
+
320
+ for (const s of items) {
321
+ const dgName = String((s.DesktopGroup as Record<string, unknown>)?.Name ?? 'Unknown');
322
+ if (!groups[dgName]) {
323
+ groups[dgName] = { count: 0, totalLogon: 0, totalBrokering: 0, totalVM: 0 };
324
+ }
325
+ const g = groups[dgName];
326
+ g.count++;
327
+ const logon = calcDuration(s, 'LogOnDuration', 'LogOnStartDate', 'LogOnEndDate');
328
+ const brokering = calcDuration(s, 'BrokeringDuration', 'BrokeringDate', 'BrokeringDateEndDate');
329
+ const vm = calcDuration(s, 'VMStartStartDate', 'VMStartStartDate', 'VMStartEndDate');
330
+ if (logon !== null) g.totalLogon += logon;
331
+ if (brokering !== null) g.totalBrokering += brokering;
332
+ if (vm !== null) g.totalVM += vm;
333
+ }
334
+
335
+ return {
336
+ periodHours: hours,
337
+ totalSessions: items.length,
338
+ byDeliveryGroup: Object.entries(groups).map(([name, g]) => ({
339
+ deliveryGroup: name,
340
+ sessionCount: g.count,
341
+ avgLogonDurationMs: g.count > 0 ? Math.round(g.totalLogon / g.count) : 0,
342
+ avgBrokeringDurationMs: g.count > 0 ? Math.round(g.totalBrokering / g.count) : 0,
343
+ avgVMStartDurationMs: g.count > 0 ? Math.round(g.totalVM / g.count) : 0,
344
+ })),
345
+ };
346
+ };
347
+
348
+ const machinesStatus: IntegrationProbeHandler = async (_params, config, credentials, fetchFn) => {
349
+ const items = (await citrixFetch(
350
+ 'Machines',
351
+ { $filter: 'LifecycleState eq 0' },
352
+ config,
353
+ credentials,
354
+ fetchFn,
355
+ )) as Array<Record<string, unknown>>;
356
+
357
+ return items.map((m) => ({
358
+ name: m.DnsName ?? m.Name,
359
+ registrationState: mapEnum(m.CurrentRegistrationState, REGISTRATION_STATE),
360
+ powerState: mapEnum(m.CurrentPowerState, POWER_STATE),
361
+ faultState: mapEnum(m.FaultState, FAULT_STATE),
362
+ inMaintenanceMode: m.IsInMaintenanceMode ?? false,
363
+ currentLoadIndex: m.CurrentLoadIndex ?? null,
364
+ osType: m.OSType ?? null,
365
+ agentVersion: m.AgentVersion ?? null,
366
+ ipAddress: m.IPAddress ?? null,
367
+ }));
368
+ };
369
+
370
+ const machinesLoad: IntegrationProbeHandler = async (_params, config, credentials, fetchFn) => {
371
+ const items = (await citrixFetch(
372
+ 'Machines',
373
+ { $filter: 'LifecycleState eq 0 and CurrentRegistrationState eq 1' },
374
+ config,
375
+ credentials,
376
+ fetchFn,
377
+ )) as Array<Record<string, unknown>>;
378
+
379
+ // Sort by load index descending
380
+ // CurrentLoadIndex: 0-10000 scale (10000 = fully loaded). Divide by 100 for percentage.
381
+ const sorted = items
382
+ .map((m) => {
383
+ const loadIndex = (m.CurrentLoadIndex as number) ?? 0;
384
+ return {
385
+ name: m.DnsName ?? m.Name,
386
+ currentLoadIndex: loadIndex,
387
+ capacityPct: Math.round(loadIndex / 100),
388
+ activeSessions: m.CurrentSessionCount ?? 0,
389
+ inMaintenanceMode: m.IsInMaintenanceMode ?? false,
390
+ };
391
+ })
392
+ .sort((a, b) => (b.currentLoadIndex as number) - (a.currentLoadIndex as number));
393
+
394
+ return {
395
+ totalRegistered: items.length,
396
+ machines: sorted,
397
+ };
398
+ };
399
+
400
+ const deliverygroupsHealth: IntegrationProbeHandler = async (
401
+ _params,
402
+ config,
403
+ credentials,
404
+ fetchFn,
405
+ ) => {
406
+ // Three parallel queries: DesktopGroups, Machines, Sessions (active)
407
+ const [desktopGroups, machines, sessions] = await Promise.all([
408
+ citrixFetch('DesktopGroups', {}, config, credentials, fetchFn),
409
+ citrixFetch('Machines', { $filter: 'LifecycleState eq 0' }, config, credentials, fetchFn),
410
+ citrixFetch('Sessions', { $filter: 'EndDate eq null' }, config, credentials, fetchFn),
411
+ ]);
412
+
413
+ const dgList = desktopGroups as Array<Record<string, unknown>>;
414
+ const machineList = machines as Array<Record<string, unknown>>;
415
+ const sessionList = sessions as Array<Record<string, unknown>>;
416
+
417
+ // Index machines and sessions by DesktopGroupId
418
+ const machinesByDg: Record<string, Array<Record<string, unknown>>> = {};
419
+ for (const m of machineList) {
420
+ const dgId = String(m.DesktopGroupId ?? '');
421
+ if (!machinesByDg[dgId]) machinesByDg[dgId] = [];
422
+ machinesByDg[dgId].push(m);
423
+ }
424
+
425
+ const sessionsByDg: Record<string, number> = {};
426
+ for (const s of sessionList) {
427
+ const dgId = String(s.DesktopGroupId ?? '');
428
+ sessionsByDg[dgId] = (sessionsByDg[dgId] ?? 0) + 1;
429
+ }
430
+
431
+ return dgList.map((dg) => {
432
+ const dgId = String(dg.Id ?? '');
433
+ const dgMachines = machinesByDg[dgId] ?? [];
434
+ const registered = dgMachines.filter(
435
+ (m) => (m.CurrentRegistrationState as number) === 1,
436
+ ).length;
437
+ const maintenance = dgMachines.filter((m) => m.IsInMaintenanceMode === true).length;
438
+
439
+ return {
440
+ name: dg.Name,
441
+ totalMachines: dgMachines.length,
442
+ registeredMachines: registered,
443
+ unregisteredMachines: dgMachines.length - registered,
444
+ maintenanceMode: maintenance,
445
+ activeSessions: sessionsByDg[dgId] ?? 0,
446
+ enabled: dg.Enabled ?? true,
447
+ };
448
+ });
449
+ };
450
+
451
+ // --- Pack definition ---
452
+
453
+ export const citrixPack: IntegrationPack = {
454
+ manifest: {
455
+ name: 'citrix',
456
+ type: 'integration',
457
+ version: '0.1.0',
458
+ description:
459
+ 'Citrix Monitor OData — sessions, logon performance, machine status, and delivery group health',
460
+ requires: { groups: [], files: [], commands: [] },
461
+ probes: [
462
+ {
463
+ name: 'sessions.active',
464
+ description: 'Active and disconnected sessions grouped by delivery group',
465
+ capability: 'observe',
466
+ params: {},
467
+ timeout: 30000,
468
+ },
469
+ {
470
+ name: 'sessions.failures',
471
+ description: 'Session connection failures with affected users and machines',
472
+ capability: 'observe',
473
+ params: {
474
+ hours: {
475
+ type: 'number',
476
+ description: 'Lookback period in hours (default: 24)',
477
+ required: false,
478
+ },
479
+ },
480
+ timeout: 30000,
481
+ },
482
+ {
483
+ name: 'logon.performance',
484
+ description: 'Average logon duration breakdown per delivery group',
485
+ capability: 'observe',
486
+ params: {
487
+ hours: {
488
+ type: 'number',
489
+ description: 'Lookback period in hours (default: 24)',
490
+ required: false,
491
+ },
492
+ },
493
+ timeout: 30000,
494
+ },
495
+ {
496
+ name: 'machines.status',
497
+ description: 'Machine registration, power, and fault state with human-readable names',
498
+ capability: 'observe',
499
+ params: {},
500
+ timeout: 30000,
501
+ },
502
+ {
503
+ name: 'machines.load',
504
+ description: 'Registered machines sorted by load index with capacity percentage',
505
+ capability: 'observe',
506
+ params: {},
507
+ timeout: 30000,
508
+ },
509
+ {
510
+ name: 'deliverygroups.health',
511
+ description: 'Per-delivery-group health: machines, registration, maintenance, sessions',
512
+ capability: 'observe',
513
+ params: {},
514
+ timeout: 30000,
515
+ },
516
+ ],
517
+ runbook: {
518
+ category: 'citrix',
519
+ probes: ['sessions.active', 'machines.status', 'deliverygroups.health'],
520
+ parallel: true,
521
+ },
522
+ },
523
+
524
+ handlers: {
525
+ 'sessions.active': sessionsActive,
526
+ 'sessions.failures': sessionsFailures,
527
+ 'logon.performance': logonPerformance,
528
+ 'machines.status': machinesStatus,
529
+ 'machines.load': machinesLoad,
530
+ 'deliverygroups.health': deliverygroupsHealth,
531
+ },
532
+
533
+ testConnection: async (config, credentials, fetchFn) => {
534
+ try {
535
+ let cloudToken: string | undefined;
536
+ if (credentials.authMethod === 'oauth2') {
537
+ cloudToken = await ensureAccessToken(credentials, fetchFn);
538
+ }
539
+
540
+ const url = buildODataUrl(config.endpoint, credentials.authMethod, 'Machines');
541
+ const parsed = new URL(url);
542
+ parsed.searchParams.set('$top', '1');
543
+ parsed.searchParams.set('$select', 'Id');
544
+
545
+ const headers: Record<string, string> = {
546
+ Accept: 'application/json',
547
+ ...buildAuthHeaders(credentials, cloudToken),
548
+ ...config.headers,
549
+ };
550
+
551
+ const res = await fetchFn(parsed.toString(), { headers });
552
+ return res.ok;
553
+ } catch {
554
+ return false;
555
+ }
556
+ },
557
+ };