import { HttpHeaders } from "Common/Constants"; import { QueryRequestOptions, QueryResponse } from "Contracts/AzureResourceGraph"; import useSWR from "swr"; import { configContext } from "../ConfigContext"; import { Subscription } from "../Contracts/DataModels"; /* eslint-disable @typescript-eslint/no-explicit-any */ interface SubscriptionListResult { nextLink: string; value: Subscription[]; } export async function fetchSubscriptions(accessToken: string): Promise { const headers = new Headers(); const bearer = `Bearer ${accessToken}`; headers.append("Authorization", bearer); let subscriptions: Array = []; let nextLink = `${configContext.ARM_ENDPOINT}subscriptions?api-version=2020-01-01`; while (nextLink) { const response = await fetch(nextLink, { headers }); const result: SubscriptionListResult = response.status === 204 || response.status === 304 ? undefined : await response.json(); if (!response.ok) { throw result; } nextLink = result.nextLink; const validSubscriptions = result.value.filter( (sub) => sub.state === "Enabled" || sub.state === "Warned" || sub.state === "PastDue", ); subscriptions = [...subscriptions, ...validSubscriptions]; } return subscriptions.sort((a, b) => a.displayName.localeCompare(b.displayName)); } export async function fetchSubscriptionsFromGraph(accessToken: string): Promise { const headers = new Headers(); const bearer = `Bearer ${accessToken}`; headers.append("Authorization", bearer); headers.append(HttpHeaders.contentType, "application/json"); const subscriptionsQuery = "resources | where type == 'microsoft.documentdb/databaseaccounts' | join kind=inner ( resourcecontainers | where type == 'microsoft.resources/subscriptions' | project subscriptionId, subscriptionName = name, subscriptionState = tostring(parse_json(properties).state) ) on subscriptionId | summarize by subscriptionId, subscriptionName, subscriptionState"; const apiVersion = "2021-03-01"; const managementResourceGraphAPIURL = `${configContext.ARM_ENDPOINT}providers/Microsoft.ResourceGraph/resources?api-version=${apiVersion}`; const subscriptions: Subscription[] = []; let skipToken: string; do { const body = { query: subscriptionsQuery, ...(skipToken && { options: { $skipToken: skipToken, } as QueryRequestOptions, }), }; const response = await fetch(managementResourceGraphAPIURL, { method: "POST", headers, body: JSON.stringify(body), }); if (!response.ok) { throw new Error(await response.text()); } const queryResponse: QueryResponse = (await response.json()) as QueryResponse; skipToken = queryResponse.$skipToken; queryResponse.data?.map((subscription: any) => { subscriptions.push({ displayName: subscription.subscriptionName, subscriptionId: subscription.subscriptionId, state: subscription.subscriptionState, } as Subscription); }); } while (skipToken); return subscriptions.sort((a, b) => a.displayName.localeCompare(b.displayName)); } export function useSubscriptions(armToken: string): Subscription[] | undefined { const { data } = useSWR( () => (armToken ? ["subscriptions", armToken] : undefined), (_, armToken) => fetchSubscriptionsFromGraph(armToken), ); return data; }