Edits history of script submission #23997 for ' Get job stdout (awx)'

  • bunnative
    One script reply has been approved by the moderators
    Ap­pro­ved
    //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