//native
/**
* Get job stdout
* Get the Ansible output of a job. txt_download (default) returns the full plain text at any size; ansi_download keeps the color codes. txt, ansi and json return a "Standard Output too large to display" message instead of the output above the controller's display limit. json returns { range, content } and is the only format that applies start_line and end_line.
*/
export async function main(
auth: RT.Awx,
job_id: number,
format:
| "txt_download"
| "txt"
| "ansi"
| "ansi_download"
| "json"
| undefined,
start_line: number | undefined,
end_line: number | undefined
) {
const outputFormat = format || "txt_download"
const url = new URL(`${apiRoot(auth)}/jobs/${job_id}/stdout/`)
url.searchParams.append("format", outputFormat)
// The controller reads start_line/end_line only for the json format.
if (outputFormat === "json" && start_line != null) {
url.searchParams.append("start_line", String(start_line))
}
if (outputFormat === "json" && end_line != null) {
url.searchParams.append("end_line", String(end_line))
}
const response = await fetch(url, {
headers: {
Authorization: authorization(auth),
Accept: outputFormat === "json" ? "application/json" : "text/plain",
},
})
if (!response.ok) {
throw new Error(`${response.status} ${await response.text()}`)
}
return outputFormat === "json" ? await response.json() : await response.text()
}
function apiRoot(auth: RT.Awx) {
const path = (auth.api_path || "/api/v2").replace(/^\/+|\/+$/g, "")
// Tolerate a base_url pasted with the API path already on it.
const base = auth.base_url
.replace(/\/+$/, "")
.replace(new RegExp(`/${path}$`), "")
return `${base}/${path}`
}
function authorization(auth: RT.Awx) {
if (auth.token) {
return `Bearer ${auth.token}`
}
if (auth.username) {
const bytes = new TextEncoder().encode(
`${auth.username}:${auth.password ?? ""}`
)
return `Basic ${btoa(String.fromCharCode(...bytes))}`
}
throw new Error(
"The AWX resource needs either a token or a username and password"
)
}
Submitted by hugo989 3 hours ago