0

Launch job template

by
Published today

Launch a job template with optional extra vars, host limit and inventory. They are applied only when the template prompts for them on launch; otherwise they are ignored and listed in ignored_fields.

Script awx Verified

The script

Submitted by hugo989 Typescript (fetch-only)
Verified 3 hours ago
1
//native
2

3
/**
4
 * Launch job template
5
 * Launch a job template. extra_vars, limit and inventory are applied only when the template prompts for them on launch (ask_variables_on_launch, ask_limit_on_launch, ask_inventory_on_launch); otherwise the controller ignores them and lists them in ignored_fields. Returns the new job, whose id is in job.
6
 */
7
export async function main(
8
  auth: RT.Awx,
9
  job_template_id: number,
10
  extra_vars: { [key: string]: any } | undefined,
11
  limit: string | undefined,
12
  inventory: number | undefined
13
) {
14
  const url = new URL(
15
    `${apiRoot(auth)}/job_templates/${job_template_id}/launch/`
16
  )
17

18
  const body: { [key: string]: any } = {}
19
  if (typeof extra_vars === "string") {
20
    // An API or AI caller may already pass the YAML/JSON string form.
21
    if (extra_vars !== "") body.extra_vars = extra_vars
22
  } else if (extra_vars != null && Object.keys(extra_vars).length > 0) {
23
    // Sent as a JSON string, the form the launch docs and awxkit use.
24
    body.extra_vars = JSON.stringify(extra_vars)
25
  }
26
  if (limit != null && limit !== "") {
27
    body.limit = limit
28
  }
29
  if (inventory != null) {
30
    body.inventory = inventory
31
  }
32

33
  const response = await fetch(url, {
34
    method: "POST",
35
    headers: {
36
      Authorization: authorization(auth),
37
      "Content-Type": "application/json",
38
      Accept: "application/json",
39
    },
40
    body: JSON.stringify(body),
41
  })
42

43
  if (!response.ok) {
44
    throw new Error(`${response.status} ${await response.text()}`)
45
  }
46

47
  return await response.json()
48
}
49

50
function apiRoot(auth: RT.Awx) {
51
  const path = (auth.api_path || "/api/v2").replace(/^\/+|\/+$/g, "")
52
  // Tolerate a base_url pasted with the API path already on it.
53
  const base = auth.base_url
54
    .replace(/\/+$/, "")
55
    .replace(new RegExp(`/${path}$`), "")
56
  return `${base}/${path}`
57
}
58

59
function authorization(auth: RT.Awx) {
60
  if (auth.token) {
61
    return `Bearer ${auth.token}`
62
  }
63
  if (auth.username) {
64
    const bytes = new TextEncoder().encode(
65
      `${auth.username}:${auth.password ?? ""}`
66
    )
67
    return `Basic ${btoa(String.fromCharCode(...bytes))}`
68
  }
69
  throw new Error(
70
    "The AWX resource needs either a token or a username and password"
71
  )
72
}
73