Skip to content

Commit

Permalink
Use interfaces in gateway node selector (#3860)
Browse files Browse the repository at this point in the history
* feature: support passing interfaces as features on gateway nodes query

* WIP: bind features to domain name features

* chore(GatewayInterfaces): remove other interfaces keep only wireguard

* chore(GatewayInterfaces): cleanup

* chore(GatewayInterfaces): Fix gateway on ip, this is a workaround and maybe got enahnced later

* chore(GatewayInterfaces): set the has_ipv6 to undefined instead of false

* Style(CustomDomain): make the tooltip aligned center

* Style(DomainDialog): reorder fiedls

* Feature(GatewayDialog):
- refactor: change the type of selectedIPAddress as it always got converted to string
- pass the selected interface type as feature to the domainName component
  • Loading branch information
0oM4R authored Feb 18, 2025
1 parent fc2f461 commit 4dd5f0f
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 56 deletions.
119 changes: 68 additions & 51 deletions packages/playground/src/components/manage_gateway_dialog.vue
Original file line number Diff line number Diff line change
Expand Up @@ -89,56 +89,61 @@

<div v-if="gatewayTab === 1">
<form-validator v-model="valid">
<input-tooltip tooltip="Selecting custom domain sets subdomain as gateway name.">
<input-validator
:value="subdomain"
:rules="subdomainRules"
:async-rules="gatewayTab === 1 ? [validateSubdomain] : []"
#="{ props }"
>
<v-text-field label="Subdomain" v-model.trim="subdomain" v-bind="props" />
</input-validator>
</input-tooltip>

<div :style="{ marginTop: '-10px' }">
<TfSelectionDetails disable-node-selection require-domain use-fqdn v-model="selectionDetails" />
</div>

<input-validator :value="port" :rules="portRules" #="{ props }">
<v-text-field label="Port" v-model.number="port" type="number" v-bind="props" />
</input-validator>

<div :style="{ marginTop: '-10px' }">
<input-tooltip
tooltip="When enabled, the backend service will terminate the TLS traffic, otherwise the gateway service will do the TLS traffic termination."
inline
>
<v-switch
label="TLS Passthrough"
hide-details
inset
variant="tonal"
color="primary"
v-model="passThrough"
/>
</input-tooltip>
</div>

<v-select
label="Select node"
class="mt-4"
:items="availableK8SNodesNames"
v-model="selectedK8SNodeName"
v-if="k8s"
/>
<v-select label="Supported Interfaces" class="mt-4" :items="networks" v-model="selectedIPAddress" />
<copy-input-wrapper #="{ props }" :data="(selectedIPAddress as any)">
<v-text-field :readonly="true" label="Selected IP Address" v-model="selectedIPAddress" v-bind="props" />
</copy-input-wrapper>

<v-select label="Supported Interfaces" :items="networks" v-model="selectedIPAddress" />

<copy-input-wrapper #="{ props }" :data="networkName" v-if="isWireGuard">
<v-text-field label="Network name" v-model="networkName" readonly v-bind="props" />
</copy-input-wrapper>

<copy-input-wrapper #="{ props }" :data="(selectedIPAddress as any)">
<v-text-field :readonly="true" label="Selected IP Address" v-model="selectedIPAddress" v-bind="props" />
</copy-input-wrapper>

<input-validator :value="port" :rules="portRules" #="{ props }">
<v-text-field label="Port" v-model.number="port" type="number" v-bind="props" />
</input-validator>
<input-tooltip
tooltip="When enabled, the backend service will terminate the TLS traffic, otherwise the gateway service will do the TLS traffic termination."
:align-center="true"
>
<v-switch
label="TLS Passthrough"
hide-details
inset
density="compact"
variant="tonal"
color="primary"
v-model="passThrough"
/>
</input-tooltip>
<div style="margin-top: -15px">
<TfSelectionDetails
:align-center="true"
disable-node-selection
require-domain
use-fqdn
:interfaces="interfaceFeature"
v-model="selectionDetails"
/>
</div>
<input-tooltip tooltip="Selecting custom domain sets subdomain as gateway name.">
<input-validator
:value="subdomain"
:rules="subdomainRules"
:async-rules="gatewayTab === 1 ? [validateSubdomain] : []"
#="{ props }"
>
<v-text-field label="Subdomain" v-model.trim="subdomain" v-bind="props" />
</input-validator>
</input-tooltip>
</form-validator>
</div>

Expand Down Expand Up @@ -187,12 +192,12 @@
</template>

<script lang="ts">
import { type GridClient, WorkloadTypes, type ZmachineData } from "@threefold/grid_client";
import { onMounted, type PropType, ref, watch } from "vue";
import { Features, type GridClient, WorkloadTypes, type ZmachineData } from "@threefold/grid_client";
import { computed, onMounted, type PropType, ref, watch } from "vue";
import { useGrid } from "../stores";
import { ProjectName } from "../types";
import type { SelectionDetails } from "../types/nodeSelector";
import type { NetworkFeatures, SelectionDetails } from "../types/nodeSelector";
import {
type DeployGatewayConfig,
deployGatewayName,
Expand Down Expand Up @@ -245,7 +250,7 @@ export default {
const valid = ref(false);
const selectionDetails = ref<SelectionDetails>();
const networks = ref<VMNetwork[]>([]);
const selectedIPAddress = ref<VMNetwork | null>(null);
const selectedIPAddress = ref<string>();
const networkName = props.vm
? (props.vm.interfaces[0].network as string)
: (props.k8s?.masters[0].interfaces[0].network as string);
Expand All @@ -263,6 +268,21 @@ export default {
const availableK8SNodesNames = availableK8SNodes.map(node => node.name);
const selectedK8SNodeName = ref(availableK8SNodesNames[0]);
const selectedNode = ref();
const interfaceFeature = computed<NetworkFeatures[]>(() => {
const net = networks.value.find(net => net.value == selectedIPAddress.value);
switch (net?.title) {
case NetworkInterfaces.PublicIPV6:
return [Features.ip];
case NetworkInterfaces.Planetary:
return [Features.yggdrasil];
case NetworkInterfaces.Mycelium:
return [Features.mycelium];
case NetworkInterfaces.WireGuard:
return [Features.wireguard];
default:
return [];
}
});
const errorMessage = ref("");
watch(selectedK8SNodeName, getSupportedNetworks, { deep: true });
Expand Down Expand Up @@ -346,7 +366,7 @@ export default {
async function deployGateway() {
layout.value.setStatus("deploy");
try {
const IP = selectedIPAddress.value as unknown as string;
const IP = selectedIPAddress.value as string;
const gwConfig: DeployGatewayConfig = {
subdomain: subdomain.value,
Expand Down Expand Up @@ -425,18 +445,14 @@ export default {
if (selectedNode.value.type === WorkloadTypes.zmachinelight) {
addNetwork(NetworkInterfaces.Mycelium, myceliumIP);
}
selectedIPAddress.value = networks.value[0];
selectedIPAddress.value = networks.value[0].value;
}
watch(
selectedIPAddress,
() => {
if (selectedIPAddress.value?.value) {
selectedIPAddress.value = selectedIPAddress.value.value as unknown as VMNetwork;
}
const IP = selectedIPAddress.value as unknown as string;
isWireGuard.value = networks.value.find(net => net.value === IP)?.title === NetworkInterfaces.WireGuard;
isWireGuard.value =
networks.value.find(net => net.value === selectedIPAddress.value)?.title === NetworkInterfaces.WireGuard;
},
{ deep: true },
);
Expand Down Expand Up @@ -498,6 +514,7 @@ export default {
networkName,
loadingGateways,
gateways,
interfaceFeature,
failedToListGws,
failedDomainDialog,
requestDelete,
Expand Down
13 changes: 10 additions & 3 deletions packages/playground/src/components/node_selector/TfDomainName.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<section>
<h6 class="text-h5 mb-4 mt-2" v-if="!hideTitle">Domain Name</h6>

<input-tooltip tooltip="Use a custom domain">
<input-tooltip tooltip="Use a custom domain" align-center>
<div>
<VSwitch color="primary" inset label="Custom Domain" v-model="enableCustomDomain" hide-details />
</div>
Expand Down Expand Up @@ -94,7 +94,7 @@
</template>

<script lang="ts">
import type { FarmInfo, FilterOptions, NodeInfo } from "@threefold/grid_client";
import { type FarmInfo, Features, type FilterOptions, type NodeInfo } from "@threefold/grid_client";
import { noop } from "lodash";
import { computed, getCurrentInstance, nextTick, onUnmounted, type PropType, ref, watch } from "vue";
import { onMounted } from "vue";
Expand All @@ -106,7 +106,7 @@ import type { InputValidatorService } from "@/hooks/input_validator";
import { useAsync, usePagination, useWatchDeep } from "../../hooks";
import { useForm, ValidatorStatus } from "../../hooks/form_validator";
import { useGrid } from "../../stores";
import type { DomainInfo, SelectionDetailsFilters } from "../../types/nodeSelector";
import type { DomainInfo, NetworkFeatures, SelectionDetailsFilters } from "../../types/nodeSelector";
import { getNodePageCount, loadNodes } from "../../utils/nodeSelector";
export default {
Expand All @@ -121,6 +121,11 @@ export default {
hideTitle: Boolean,
status: String as PropType<ValidatorStatus>,
useFqdn: Boolean,
interfaces: {
type: Array as PropType<NetworkFeatures[]>,
required: false,
default: () => [],
},
},
emits: {
"update:model-value": (domain?: DomainInfo) => true || domain,
Expand Down Expand Up @@ -148,6 +153,8 @@ export default {
page: Math.max(1, pagination.value.page),
farmId: enableCustomDomain.value ? props.farm?.farmId : undefined,
availableFor: gridStore.client?.twinId,
features: props.interfaces.filter(i => i != Features.ip),
hasIPv6: props.interfaces.some(i => i === Features.ip) || undefined,
}));
const selectedDomain = ref<NodeInfo | null>(null);
const loadDomains = () => domainsTask.value.run(gridStore, filters.value);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,13 +67,14 @@
v-model:status="domainStatus"
:use-fqdn="$props.useFqdn"
v-if="requireDomain"
:interfaces="domainNameInterfaces"
/>
</VExpandTransition>
</section>
</template>

<script lang="ts">
import type { FarmInfo, GPUCardInfo, NodeInfo } from "@threefold/grid_client";
import { type FarmInfo, Features, type GPUCardInfo, type NodeInfo } from "@threefold/grid_client";
import { type Farm, NodeStatus } from "@threefold/gridproxy_client";
import type AwaitLock from "await-lock";
import noop from "lodash/fp/noop.js";
Expand All @@ -86,6 +87,7 @@ import { useForm, ValidatorStatus } from "../../hooks/form_validator";
import type { InputValidatorService } from "../../hooks/input_validator";
import type {
DomainInfo,
NetworkFeatures,
SelectedLocation,
SelectedMachine,
SelectionDetails,
Expand Down Expand Up @@ -121,6 +123,10 @@ export default {
type: Array as PropType<SelectedMachine[]>,
default: () => [],
},
interfaces: {
type: Array as PropType<NetworkFeatures[]>,
default: () => [],
},
nodesLock: Object as PropType<AwaitLock>,
},
emits: {
Expand All @@ -145,6 +151,14 @@ export default {
const domain = ref<DomainInfo>();
const domainStatus = ref<ValidatorStatus>();
const domainNameInterfaces = computed((): NetworkFeatures[] => {
if (props.interfaces.length === 0) {
const interfaces: NetworkFeatures[] = [];
if (props.filters.wireguard) interfaces.push(Features.wireguard);
// only wireguard needed for now; we may add some other interfaces in the future
return interfaces;
} else return props.interfaces;
});
const loadedFarms = new Map<number, Farm>();
async function loadFarm(farmId: number) {
if (loadedFarms.has(farmId)) {
Expand Down Expand Up @@ -254,6 +268,7 @@ export default {
domain,
domainStatus,
selectionDetails,
domainNameInterfaces,
NodeStatus,
loadFarm,
getFarm,
Expand Down
4 changes: 3 additions & 1 deletion packages/playground/src/types/nodeSelector.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { FarmInfo, GPUCardInfo, NodeInfo } from "@threefold/grid_client";
import type { FarmInfo, Features, GPUCardInfo, NodeInfo } from "@threefold/grid_client";

export type Locations = {
[region: string]: string[];
Expand Down Expand Up @@ -86,3 +86,5 @@ export interface SelectedMachine {
disk: number;
publicIp: boolean;
}

export type NetworkFeatures = Features.ipv4 | Features.ip | Features.yggdrasil | Features.wireguard | Features.mycelium;

0 comments on commit 4dd5f0f

Please sign in to comment.