//native
/**
* Run show commands
* Run up to 10 show commands on a Cisco Nexus switch through NX-API and return the output of each, as structured JSON (cli_show) or as plain text (cli_show_ascii).
*/
export async function main(
auth: RT.CiscoNxos,
commands: string[],
output_format: "json" | "text" | undefined
) {
const cmds = (commands ?? []).map((c) => c.trim()).filter((c) => c !== "")
if (cmds.length === 0) {
throw new Error("Provide at least one show command")
}
// NX-API splits input on ';', and in text mode it runs any exec command:
// keep this action to show commands.
for (const c of cmds) {
if (!/^show\s/i.test(c) || c.includes(";")) {
throw new Error(`Not a single show command: ${c}`)
}
}
// NX-API ignores show commands past the 10th in a single request
if (cmds.length > 10) {
throw new Error("NX-API accepts at most 10 show commands per request")
}
const type =
(output_format || "json") === "text" ? "cli_show_ascii" : "cli_show"
const outputs = await nxapi(auth, type, cmds)
return outputs.map((o, i) => ({
command: o.input ?? cmds[i],
output: o.body,
}))
}
type NxapiOutput = {
input?: string
body?: any
code: string
msg?: string
clierror?: string
}
async function nxapi(
auth: RT.CiscoNxos,
type: "cli_show" | "cli_show_ascii" | "cli_conf",
commands: string[]
): Promise<NxapiOutput[]> {
const response = await fetch(new URL("/ins", auth.base_url), {
method: "POST",
headers: {
Authorization: `Basic ${btoa(`${auth.username}:${auth.password}`)}`,
"Content-Type": "application/json",
Accept: "application/json",
},
// Keep "type" before "input": some NX-OS releases misparse the payload otherwise
body: JSON.stringify({
ins_api: {
version: "1.0",
type,
chunk: "0",
sid: null,
input: commands.join(" ;"),
output_format: "json",
},
}),
})
if (!response.ok) {
throw new Error(`${response.status} ${await response.text()}`)
}
const text = await response.text()
if (text.trimStart().startsWith("<")) {
// NX-API falls back to XML when the output exceeds 1 MB
throw new Error(
`NX-API returned XML instead of JSON (outputs over 1 MB come back as XML): ${text.slice(0, 500)}`
)
}
const data = JSON.parse(text)
const raw = data?.ins_api?.outputs?.output
const outputs: NxapiOutput[] =
raw == null ? [] : Array.isArray(raw) ? raw : [raw]
for (const o of outputs) {
if (String(o.code) !== "200") {
throw new Error(
`${o.code} ${o.input ?? ""}: ${o.msg ?? ""} ${o.clierror ?? ""}`.trim()
)
}
}
return outputs
}
Submitted by hugo989 3 hours ago