diff --git a/packages/playground/src/components/select_farm.vue b/packages/playground/src/components/select_farm.vue index 8b899a4e75..1f9557ad12 100644 --- a/packages/playground/src/components/select_farm.vue +++ b/packages/playground/src/components/select_farm.vue @@ -40,6 +40,7 @@ const props = defineProps({ modelValue: { type: Object as PropType }, country: String, filters: { default: () => ({} as Filters), type: Object as PropType }, + exclusiveFor: String, }); const emits = defineEmits<{ (event: "update:modelValue", value?: Farm): void }>(); @@ -61,15 +62,19 @@ async function loadFarms() { const grid = await getGrid(profileManager.profile!); const filters = props.filters; - farms.value = await getFarms(grid!, { - country: country.value, - cru: filters.cpu, - mru: filters.memory ? Math.round(filters.memory / 1024) : undefined, - hru: filters.disk, - sru: filters.ssd, - publicIPs: filters.publicIp, - availableFor: grid!.twinId, - }); + farms.value = await getFarms( + grid!, + { + country: country.value, + cru: filters.cpu, + mru: filters.memory ? Math.round(filters.memory / 1024) : undefined, + hru: filters.disk, + sru: filters.ssd, + publicIPs: filters.publicIp, + availableFor: grid!.twinId, + }, + { exclusiveFor: props.exclusiveFor }, + ); if (oldFarm) { farm.value = farms.value.find(f => f.name === oldFarm.name); diff --git a/packages/playground/src/utils/get_farms.ts b/packages/playground/src/utils/get_farms.ts index 03c4d61ff1..bbe87aa4da 100644 --- a/packages/playground/src/utils/get_farms.ts +++ b/packages/playground/src/utils/get_farms.ts @@ -1,8 +1,11 @@ import type { FilterOptions, GridClient, NodeInfo } from "@threefold/grid_client"; -import { gqlClient } from "../clients"; +import { gqlClient, gridProxyClient } from "../clients"; -export async function getFarms(grid: GridClient, filters: FilterOptions) { +export interface GetFarmsOptions { + exclusiveFor?: string; +} +export async function getFarms(grid: GridClient, filters: FilterOptions, options: GetFarmsOptions = {}) { const nodes: NodeInfo[][] = []; let page = 1; @@ -12,10 +15,38 @@ export async function getFarms(grid: GridClient, filters: FilterOptions) { page = nodes[page - 1].length ? ++page : 0; } - const farmIds = Array.from(new Set(nodes.flat(1).map(node => node.farmId))); + let farmIds = Array.from(new Set(nodes.flat(1).map(node => node.farmId))); + + if (options.exclusiveFor && !filters.publicIPs) { + const blockedFarms = await getBlockedFarmSet(options.exclusiveFor); + farmIds = farmIds.filter(id => !blockedFarms.has(id)); + } return gqlClient.farms( { farmID: true, name: true }, { orderBy: ["farmID_ASC"], where: { farmID_in: farmIds }, limit: farmIds.length }, ); } + +export async function getBlockedFarmSet(exclusiveFor: string): Promise> { + const { totalCount } = await gqlClient.nodeContractsConnection( + { totalCount: true }, + { + orderBy: ["id_ASC"], + where: { deploymentData_contains: exclusiveFor, state_eq: "Created", numberOfPublicIPs_eq: 0 }, + }, + ); + + const nodes = await gqlClient.nodeContracts( + { nodeID: true }, + { + limit: totalCount, + where: { deploymentData_contains: exclusiveFor, state_eq: "Created" }, + }, + ); + + const farms = await Promise.all( + Array.from(new Set(nodes.map(node => node.nodeID))).map(id => gridProxyClient.nodes.byId(id)), + ); + return new Set(farms.map(farm => farm.farmId)); +} diff --git a/packages/playground/src/weblets/tf_presearch.vue b/packages/playground/src/weblets/tf_presearch.vue index 1bdb325307..de7e343a1b 100644 --- a/packages/playground/src/weblets/tf_presearch.vue +++ b/packages/playground/src/weblets/tf_presearch.vue @@ -53,6 +53,7 @@ ssd: rootFsSize, publicIp: ipv4, }" + exclusive-for="research" v-model="farm" />