0

Get task

by
Published today

Get one provisioning task (legacy Network Provisioning API) by ID, with its workOrderUserDefinedStatus (Pending, Completed, Failed, Cancelled), its device and, once run, the change control it ran in (ccIdV2).

Script arista_cloudvision Verified

The script

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

3
/**
4
 * Get task
5
 * Get one provisioning task (legacy Network Provisioning API) by ID, with its workOrderUserDefinedStatus (Pending, Completed, Failed, Cancelled), its device and, once run, the change control it ran in (ccIdV2).
6
 */
7
export async function main(auth: RT.AristaCloudvision, task_id: string) {
8
  const task = await cv(
9
    auth,
10
    `/cvpservice/task/getTaskById.do?taskId=${encodeURIComponent(task_id)}`,
11
    { notFound: `Task ${task_id} not found` }
12
  )
13
  if (!task || task.workOrderId == null)
14
    throw new Error(`Task ${task_id} not found`)
15
  return task
16
}
17

18
// Calls CloudVision and turns its failures into readable errors. Legacy
19
// endpoints report errors as HTTP 200 with an errorCode field.
20
async function cv(
21
  auth: RT.AristaCloudvision,
22
  path: string,
23
  options: { body?: unknown; notFound?: string; optional?: boolean } = {}
24
): Promise<any> {
25
  const url = new URL(path, auth.base_url)
26
  // cvprac sends legacy endpoints to /cvpservice on CVaaS and /web on
27
  // on-premises CVP. Its is_cvaas flag is the resource's deployment field;
28
  // when that is unset, a host under arista.io is taken as CVaaS.
29
  const cvaas = auth.deployment
30
    ? auth.deployment === "cvaas"
31
    : /(^|\.)arista\.io\.?$/i.test(url.hostname)
32
  if (!cvaas && url.pathname.startsWith("/cvpservice/")) {
33
    url.pathname = url.pathname.replace(/^\/cvpservice\//, "/web/")
34
  }
35
  const response = await fetch(url, {
36
    method: options.body === undefined ? "GET" : "POST",
37
    headers: {
38
      Authorization: `Bearer ${auth.token}`,
39
      ...(options.body === undefined
40
        ? {}
41
        : { "Content-Type": "application/json" }),
42
      Accept: "application/json",
43
    },
44
    body: options.body === undefined ? undefined : JSON.stringify(options.body),
45
  })
46
  const text = await response.text()
47
  if (
48
    response.status === 401 ||
49
    response.status === 403 ||
50
    (!response.ok && text.includes("User is unauthorized"))
51
  ) {
52
    throw new Error(
53
      `CloudVision refused the token (HTTP ${response.status}): check that the service-account token is valid, not expired, and that its role allows this call. ${text}`
54
    )
55
  }
56
  const data =
57
    text.trim() === ""
58
      ? {}
59
      : /^\s*[[{]/.test(text)
60
        ? JSON.parse(text)
61
        : undefined
62
  const error = findError(data)
63
  if (response.ok && data !== undefined && !error) return data
64
  const detail = error
65
    ? `${error.errorCode} ${error.errorMessage ?? (error.errors ?? []).join("; ")}`
66
    : `HTTP ${response.status} ${text.slice(0, 500)}`
67
  // Legacy lookups answer an unknown name or ID with an errorCode (cvprac
68
  // treats any error from getTaskById and getImageBundleByName that way).
69
  if (
70
    response.status === 404 ||
71
    (error && (options.optional || options.notFound))
72
  ) {
73
    if (options.optional) return undefined
74
    if (options.notFound) throw new Error(`${options.notFound} (${detail})`)
75
  }
76
  if (response.ok && !error) {
77
    throw new Error(
78
      `CloudVision returned a non-JSON response for ${url.pathname}: check that base_url is the CloudVision address. ${detail}`
79
    )
80
  }
81
  throw new Error(`CloudVision ${url.pathname} failed: ${detail}`)
82
}
83

84
function findError(value: any): any {
85
  if (!value || typeof value !== "object") return undefined
86
  // Like cvprac, only a truthy errorCode counts, at any depth.
87
  if (!Array.isArray(value) && value.errorCode) return value
88
  for (const item of Object.values(value)) {
89
    const error = findError(item)
90
    if (error) return error
91
  }
92
  return undefined
93
}
94