diff --git a/src/lib/ComputeWorkloadPool.svelte b/src/lib/ComputeWorkloadPool.svelte index 3eb4519..f3571ce 100644 --- a/src/lib/ComputeWorkloadPool.svelte +++ b/src/lib/ComputeWorkloadPool.svelte @@ -13,6 +13,7 @@ import Select from '$lib/forms/Select.svelte'; import Flavor from '$lib/Flavor.svelte'; import Image from '$lib/Image.svelte'; + import ComputeWorkloadPoolSecurityRule from '$lib/ComputeWorkloadPoolSecurityRule.svelte'; /* The pool index allows us to fully qualify IDs so they are unique */ export let index: number; @@ -191,6 +192,41 @@ return lookupImage(images, distro, variant, version); } + + let tempRule: Compute.FirewallRule | null; + + let tempRuleValid: boolean; + + function addFirewallRule() { + tempRuleValid = false; + + tempRule = { + direction: Compute.FirewallRuleDirectionEnum.Ingress, + protocol: Compute.FirewallRuleProtocolEnum.Tcp, + port: 0, + prefixes: [] + }; + } + + function submitFirewallRule() { + if (!tempRule) return; + + if (!pool.machine.firewall) { + pool.machine.firewall = []; + } + + pool.machine.firewall.push(tempRule); + pool.machine.firewall = pool.machine.firewall; + + tempRule = null; + } + + function deleteFirewallRule(index: number) { + if (!pool.machine.firewall) return; + + pool.machine.firewall.splice(index, 1); + pool.machine.firewall = pool.machine.firewall; + } @@ -295,4 +331,61 @@ hint="Selecting this option allocates a public IP address to each node in the pool." bind:checked={publicIP} /> + + +
+ + + + + + + + + + + + {#each pool.machine.firewall || [] as rule, i} + + + + + + + + {/each} + +
DirectionProtocolPortPrefixes
{rule.direction}{rule.protocol}{rule.port}{#if rule.portMax}-{rule.portMax}{/if}{rule.prefixes.join(', ')} + +
+
+ + {#if tempRule} + + + + {:else} + + {/if} +
diff --git a/src/lib/ComputeWorkloadPoolSecurityRule.svelte b/src/lib/ComputeWorkloadPoolSecurityRule.svelte new file mode 100644 index 0000000..6e10665 --- /dev/null +++ b/src/lib/ComputeWorkloadPoolSecurityRule.svelte @@ -0,0 +1,93 @@ + + + + + + + + + + + diff --git a/src/lib/openapi/compute/.openapi-generator/FILES b/src/lib/openapi/compute/.openapi-generator/FILES index aeebe1b..6d15b3d 100644 --- a/src/lib/openapi/compute/.openapi-generator/FILES +++ b/src/lib/openapi/compute/.openapi-generator/FILES @@ -9,10 +9,7 @@ models/ComputeClusterStatus.ts models/ComputeClusterWorkloadPool.ts models/ComputeClusterWorkloadPoolStatus.ts models/ComputeClusterWrite.ts -models/Firewall.ts models/FirewallRule.ts -models/FirewallRulePort.ts -models/FirewallRulePortRange.ts models/Flavor.ts models/FlavorSpec.ts models/GpuSpec.ts diff --git a/src/lib/openapi/compute/models/FirewallRule.ts b/src/lib/openapi/compute/models/FirewallRule.ts index 82b8221..3b28a6a 100644 --- a/src/lib/openapi/compute/models/FirewallRule.ts +++ b/src/lib/openapi/compute/models/FirewallRule.ts @@ -13,19 +13,18 @@ */ import { exists, mapValues } from '../runtime'; -import type { FirewallRulePort } from './FirewallRulePort'; -import { - FirewallRulePortFromJSON, - FirewallRulePortFromJSONTyped, - FirewallRulePortToJSON, -} from './FirewallRulePort'; - /** * A firewall rule applied to a workload pool. * @export * @interface FirewallRule */ export interface FirewallRule { + /** + * The direction of network traffic to apply the rule to. + * @type {string} + * @memberof FirewallRule + */ + direction: FirewallRuleDirectionEnum; /** * The protocol to allow. * @type {string} @@ -33,20 +32,35 @@ export interface FirewallRule { */ protocol: FirewallRuleProtocolEnum; /** - * - * @type {FirewallRulePort} + * The port to allow, or start of a port range. + * @type {number} * @memberof FirewallRule */ - port: FirewallRulePort; + port: number; /** - * A list of CIDR blocks to allow, it might be any IPv4 or IPv6 in CIDR notation. + * The end of a port range, inclusive of this this port, if specified. + * @type {number} + * @memberof FirewallRule + */ + portMax?: number; + /** + * A list of CIDR prefixes to allow, it might be any IPv4 or IPv6 in CIDR notation. * @type {Array} * @memberof FirewallRule */ - cidr: Array; + prefixes: Array; } +/** + * @export + */ +export const FirewallRuleDirectionEnum = { + Ingress: 'ingress', + Egress: 'egress' +} as const; +export type FirewallRuleDirectionEnum = typeof FirewallRuleDirectionEnum[keyof typeof FirewallRuleDirectionEnum]; + /** * @export */ @@ -62,9 +76,10 @@ export type FirewallRuleProtocolEnum = typeof FirewallRuleProtocolEnum[keyof typ */ export function instanceOfFirewallRule(value: object): boolean { let isInstance = true; + isInstance = isInstance && "direction" in value; isInstance = isInstance && "protocol" in value; isInstance = isInstance && "port" in value; - isInstance = isInstance && "cidr" in value; + isInstance = isInstance && "prefixes" in value; return isInstance; } @@ -79,9 +94,11 @@ export function FirewallRuleFromJSONTyped(json: any, ignoreDiscriminator: boolea } return { + 'direction': json['direction'], 'protocol': json['protocol'], - 'port': FirewallRulePortFromJSON(json['port']), - 'cidr': json['cidr'], + 'port': json['port'], + 'portMax': !exists(json, 'portMax') ? undefined : json['portMax'], + 'prefixes': json['prefixes'], }; } @@ -94,9 +111,11 @@ export function FirewallRuleToJSON(value?: FirewallRule | null): any { } return { + 'direction': value.direction, 'protocol': value.protocol, - 'port': FirewallRulePortToJSON(value.port), - 'cidr': value.cidr, + 'port': value.port, + 'portMax': value.portMax, + 'prefixes': value.prefixes, }; } diff --git a/src/lib/openapi/compute/models/MachinePool.ts b/src/lib/openapi/compute/models/MachinePool.ts index ff00c27..aeb7615 100644 --- a/src/lib/openapi/compute/models/MachinePool.ts +++ b/src/lib/openapi/compute/models/MachinePool.ts @@ -13,12 +13,12 @@ */ import { exists, mapValues } from '../runtime'; -import type { Firewall } from './Firewall'; +import type { FirewallRule } from './FirewallRule'; import { - FirewallFromJSON, - FirewallFromJSONTyped, - FirewallToJSON, -} from './Firewall'; + FirewallRuleFromJSON, + FirewallRuleFromJSONTyped, + FirewallRuleToJSON, +} from './FirewallRule'; import type { ImageSelector } from './ImageSelector'; import { ImageSelectorFromJSON, @@ -63,11 +63,11 @@ export interface MachinePool { */ disk?: Volume; /** - * - * @type {Firewall} + * A list of firewall rules applied to a workload pool. + * @type {Array} * @memberof MachinePool */ - firewall?: Firewall; + firewall?: Array; /** * * @type {PublicIPAllocation} @@ -113,7 +113,7 @@ export function MachinePoolFromJSONTyped(json: any, ignoreDiscriminator: boolean 'replicas': json['replicas'], 'flavorId': json['flavorId'], 'disk': !exists(json, 'disk') ? undefined : VolumeFromJSON(json['disk']), - 'firewall': !exists(json, 'firewall') ? undefined : FirewallFromJSON(json['firewall']), + 'firewall': !exists(json, 'firewall') ? undefined : ((json['firewall'] as Array).map(FirewallRuleFromJSON)), 'publicIPAllocation': !exists(json, 'publicIPAllocation') ? undefined : PublicIPAllocationFromJSON(json['publicIPAllocation']), 'image': ImageSelectorFromJSON(json['image']), 'userData': !exists(json, 'userData') ? undefined : json['userData'], @@ -132,7 +132,7 @@ export function MachinePoolToJSON(value?: MachinePool | null): any { 'replicas': value.replicas, 'flavorId': value.flavorId, 'disk': VolumeToJSON(value.disk), - 'firewall': FirewallToJSON(value.firewall), + 'firewall': value.firewall === undefined ? undefined : ((value.firewall as Array).map(FirewallRuleToJSON)), 'publicIPAllocation': PublicIPAllocationToJSON(value.publicIPAllocation), 'image': ImageSelectorToJSON(value.image), 'userData': value.userData, diff --git a/src/lib/openapi/compute/models/index.ts b/src/lib/openapi/compute/models/index.ts index 92bba6e..de55a26 100644 --- a/src/lib/openapi/compute/models/index.ts +++ b/src/lib/openapi/compute/models/index.ts @@ -8,10 +8,7 @@ export * from './ComputeClusterStatus'; export * from './ComputeClusterWorkloadPool'; export * from './ComputeClusterWorkloadPoolStatus'; export * from './ComputeClusterWrite'; -export * from './Firewall'; export * from './FirewallRule'; -export * from './FirewallRulePort'; -export * from './FirewallRulePortRange'; export * from './Flavor'; export * from './FlavorSpec'; export * from './GpuSpec'; diff --git a/src/lib/validation/index.ts b/src/lib/validation/index.ts index 7e59de1..f3b4d08 100644 --- a/src/lib/validation/index.ts +++ b/src/lib/validation/index.ts @@ -15,6 +15,14 @@ export function stringSet(s: string): boolean { return Boolean(s); } +export function stringInt(s: string): boolean { + return !isNaN(parseInt(s, 10)); +} + +export function stringIntOrUndefined(s: string): boolean { + return s == '' || !isNaN(parseInt(s, 10)); +} + export function kubernetesNameValid(name: string | null | undefined): boolean { if (!name) return false; // RFC-1123. Must start and end with alphanumeric.