//native
async function connect(auth: RT.F5Bigip): Promise<{
base: string
headers: { [key: string]: string }
release: () => Promise<void>
}> {
const base = auth.base_url.replace(/\/+$/, "")
if (auth.auth_method === "basic") {
return {
base,
headers: {
Authorization: `Basic ${btoa(`${auth.username}:${auth.password}`)}`,
},
release: async () => {},
}
}
const login = await fetch(`${base}/mgmt/shared/authn/login`, {
method: "POST",
headers: { "Content-Type": "application/json", Accept: "application/json" },
body: JSON.stringify({
username: auth.username,
password: auth.password,
loginProviderName: auth.login_provider_name || "tmos",
}),
})
if (!login.ok) {
throw new Error(`${login.status} ${await login.text()}`)
}
const token: string = (await login.json()).token.token
return {
base,
headers: { "X-F5-Auth-Token": token },
release: async () => {
await fetch(
`${base}/mgmt/shared/authz/tokens/${encodeURIComponent(token)}`,
{
method: "DELETE",
headers: { "X-F5-Auth-Token": token },
}
)
},
}
}
// "/Common/web" or "web" + partition -> "~Common~web" (iControl REST object reference);
// "%" (route domains, e.g. 10.0.0.1%2:80), "?" and "#" are escaped
function ref(name: string, partition: string | undefined) {
const path = name.startsWith("/") ? name : `/${partition || "Common"}/${name}`
return path.replace(/\//g, "~").replace(/[%?#]/g, encodeURIComponent)
}
/**
* Set pool member state
* 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.
*/
export async function main(
auth: RT.F5Bigip,
pool: string,
member: string,
state: "enabled" | "disabled" | "forced_offline",
partition: string | undefined
) {
const body =
state === "enabled"
? { session: "user-enabled", state: "user-up" }
: state === "disabled"
? { session: "user-disabled", state: "user-up" }
: { session: "user-disabled", state: "user-down" }
const f5 = await connect(auth)
try {
const response = await fetch(
`${f5.base}/mgmt/tm/ltm/pool/${ref(pool, partition)}/members/${ref(member, partition)}`,
{
method: "PATCH",
headers: {
...f5.headers,
"Content-Type": "application/json",
Accept: "application/json",
},
body: JSON.stringify(body),
}
)
if (!response.ok) {
throw new Error(`${response.status} ${await response.text()}`)
}
return await response.json()
} finally {
await f5.release()
}
}
Submitted by hugo989 7 hours ago