0

Set pool member state

by
Published today

Enable, disable or force offline an LTM pool member. Member is the member name as BIG-IP shows it, e.g. 10.0.0.1:80 (IPv6: 2001:db8::1.80) or /Common/10.0.0.1:80.

Script f5_bigip Verified

The script

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

3
async function connect(auth: RT.F5Bigip): Promise<{
4
  base: string
5
  headers: { [key: string]: string }
6
  release: () => Promise<void>
7
}> {
8
  const base = auth.base_url.replace(/\/+$/, "")
9
  if (auth.auth_method === "basic") {
10
    return {
11
      base,
12
      headers: {
13
        Authorization: `Basic ${btoa(`${auth.username}:${auth.password}`)}`,
14
      },
15
      release: async () => {},
16
    }
17
  }
18
  const login = await fetch(`${base}/mgmt/shared/authn/login`, {
19
    method: "POST",
20
    headers: { "Content-Type": "application/json", Accept: "application/json" },
21
    body: JSON.stringify({
22
      username: auth.username,
23
      password: auth.password,
24
      loginProviderName: auth.login_provider_name || "tmos",
25
    }),
26
  })
27
  if (!login.ok) {
28
    throw new Error(`${login.status} ${await login.text()}`)
29
  }
30
  const token: string = (await login.json()).token.token
31
  return {
32
    base,
33
    headers: { "X-F5-Auth-Token": token },
34
    release: async () => {
35
      await fetch(
36
        `${base}/mgmt/shared/authz/tokens/${encodeURIComponent(token)}`,
37
        {
38
          method: "DELETE",
39
          headers: { "X-F5-Auth-Token": token },
40
        }
41
      )
42
    },
43
  }
44
}
45

46
// "/Common/web" or "web" + partition -> "~Common~web" (iControl REST object reference);
47
// "%" (route domains, e.g. 10.0.0.1%2:80), "?" and "#" are escaped
48
function ref(name: string, partition: string | undefined) {
49
  const path = name.startsWith("/") ? name : `/${partition || "Common"}/${name}`
50
  return path.replace(/\//g, "~").replace(/[%?#]/g, encodeURIComponent)
51
}
52

53
/**
54
 * Set pool member state
55
 * Enable a pool member, disable it (only persistent or active connections are allowed) or force it offline (only active connections are allowed). Same as the Enabled / Disabled / Forced Offline choice in the BIG-IP UI.
56
 */
57
export async function main(
58
  auth: RT.F5Bigip,
59
  pool: string,
60
  member: string,
61
  state: "enabled" | "disabled" | "forced_offline",
62
  partition: string | undefined
63
) {
64
  const body =
65
    state === "enabled"
66
      ? { session: "user-enabled", state: "user-up" }
67
      : state === "disabled"
68
        ? { session: "user-disabled", state: "user-up" }
69
        : { session: "user-disabled", state: "user-down" }
70

71
  const f5 = await connect(auth)
72
  try {
73
    const response = await fetch(
74
      `${f5.base}/mgmt/tm/ltm/pool/${ref(pool, partition)}/members/${ref(member, partition)}`,
75
      {
76
        method: "PATCH",
77
        headers: {
78
          ...f5.headers,
79
          "Content-Type": "application/json",
80
          Accept: "application/json",
81
        },
82
        body: JSON.stringify(body),
83
      }
84
    )
85

86
    if (!response.ok) {
87
      throw new Error(`${response.status} ${await response.text()}`)
88
    }
89

90
    return await response.json()
91
  } finally {
92
    await f5.release()
93
  }
94
}
95