@highstate/library 0.14.2 → 0.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/highstate.library.msgpack +0 -0
- package/dist/index.js +1721 -953
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/src/abbreviations.ts +1 -0
- package/src/common/access-point.ts +2 -2
- package/src/common/files.ts +10 -0
- package/src/common/server.ts +15 -57
- package/src/databases/etcd.ts +97 -0
- package/src/databases/index.ts +1 -0
- package/src/databases/mariadb.ts +48 -2
- package/src/databases/mongodb.ts +48 -2
- package/src/databases/postgresql.ts +51 -2
- package/src/databases/redis.ts +48 -2
- package/src/databases/s3.ts +65 -6
- package/src/databases/shared.ts +12 -6
- package/src/dns.ts +59 -49
- package/src/k8s/apps/etcd.ts +46 -0
- package/src/k8s/apps/index.ts +2 -0
- package/src/k8s/apps/mariadb.ts +0 -5
- package/src/k8s/apps/minio.ts +0 -5
- package/src/k8s/apps/mongodb.ts +0 -5
- package/src/k8s/apps/postgresql.ts +0 -5
- package/src/k8s/apps/shared.ts +10 -1
- package/src/k8s/apps/traefik.ts +16 -1
- package/src/k8s/apps/valkey.ts +0 -5
- package/src/k8s/apps/wg-feed-server.ts +34 -0
- package/src/k8s/reduced-access.ts +23 -53
- package/src/k8s/resources.ts +78 -35
- package/src/k8s/service.ts +21 -10
- package/src/k8s/shared.ts +60 -90
- package/src/k8s/workload.ts +87 -26
- package/src/network/address-space.ts +94 -0
- package/src/network/address.ts +33 -0
- package/src/network/dynamic-endpoint.ts +39 -0
- package/src/network/endpoint-schema.ts +116 -0
- package/src/network/endpoint.ts +347 -0
- package/src/network/index.ts +6 -0
- package/src/network/subnet.ts +31 -0
- package/src/ssh.ts +66 -10
- package/src/third-party/cloudflare.ts +1 -0
- package/src/utils.ts +41 -11
- package/src/wireguard.ts +340 -150
- package/src/network.ts +0 -391
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { defineEntity, defineUnit, z } from "@highstate/contract"
|
|
2
|
+
import { l3EndpointEntity } from "./endpoint"
|
|
3
|
+
import { subnetEntity } from "./subnet"
|
|
4
|
+
|
|
5
|
+
export type AddressSpace = z.infer<typeof addressSpaceEntity.schema>
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* The entity representing a network address space.
|
|
9
|
+
*/
|
|
10
|
+
export const addressSpaceEntity = defineEntity({
|
|
11
|
+
type: "network.address-space.v1",
|
|
12
|
+
|
|
13
|
+
includes: {
|
|
14
|
+
/**
|
|
15
|
+
* The minimal set of subnets that fully cover the address space.
|
|
16
|
+
*/
|
|
17
|
+
subnets: {
|
|
18
|
+
entity: subnetEntity,
|
|
19
|
+
multiple: true,
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
|
|
23
|
+
schema: z.unknown(),
|
|
24
|
+
|
|
25
|
+
meta: {
|
|
26
|
+
color: "#3F51B5",
|
|
27
|
+
},
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Defines an address space from a list of addresses/subnets/ranges.
|
|
32
|
+
*/
|
|
33
|
+
export const addressSpace = defineUnit({
|
|
34
|
+
type: "network.address-space.v1",
|
|
35
|
+
|
|
36
|
+
args: {
|
|
37
|
+
/**
|
|
38
|
+
* The list of addresses to include in the address space.
|
|
39
|
+
*
|
|
40
|
+
* The supported formats are:
|
|
41
|
+
* - Single IP address (e.g., `192.168.1.1`);
|
|
42
|
+
* - CIDR notation (e.g., `192.168.1.1/24`);
|
|
43
|
+
* - Dash notation (e.g., `192.168.1.1-192.168.1.254`).
|
|
44
|
+
*
|
|
45
|
+
* The addresses can be a mix of IPv4 and IPv6.
|
|
46
|
+
*/
|
|
47
|
+
included: z.string().array().default([]),
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* The list of addresses to exclude from the `addresses` list.
|
|
51
|
+
*
|
|
52
|
+
* The supported formats are the same as in `addresses`.
|
|
53
|
+
*/
|
|
54
|
+
excluded: z.string().array().default([]),
|
|
55
|
+
},
|
|
56
|
+
|
|
57
|
+
inputs: {
|
|
58
|
+
/**
|
|
59
|
+
* The endpoints to include in the address space.
|
|
60
|
+
*/
|
|
61
|
+
included: {
|
|
62
|
+
entity: l3EndpointEntity,
|
|
63
|
+
multiple: true,
|
|
64
|
+
required: false,
|
|
65
|
+
},
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* The endpoints to exclude from the `included` list.
|
|
69
|
+
*/
|
|
70
|
+
excluded: {
|
|
71
|
+
entity: l3EndpointEntity,
|
|
72
|
+
multiple: true,
|
|
73
|
+
required: false,
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
|
|
77
|
+
outputs: {
|
|
78
|
+
/**
|
|
79
|
+
* The address space entity representing the created address space.
|
|
80
|
+
*/
|
|
81
|
+
addressSpace: addressSpaceEntity,
|
|
82
|
+
},
|
|
83
|
+
|
|
84
|
+
meta: {
|
|
85
|
+
title: "Address Space",
|
|
86
|
+
icon: "mdi:network",
|
|
87
|
+
category: "Network",
|
|
88
|
+
},
|
|
89
|
+
|
|
90
|
+
source: {
|
|
91
|
+
package: "@highstate/common",
|
|
92
|
+
path: "units/network/address-space",
|
|
93
|
+
},
|
|
94
|
+
})
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { defineEntity, z } from "@highstate/contract"
|
|
2
|
+
import { addressTypeSchema, subnetEntity } from "./subnet"
|
|
3
|
+
|
|
4
|
+
export type Address = z.infer<typeof addressEntity.schema>
|
|
5
|
+
|
|
6
|
+
export const addressEntity = defineEntity({
|
|
7
|
+
type: "network.address.v1",
|
|
8
|
+
|
|
9
|
+
includes: {
|
|
10
|
+
/**
|
|
11
|
+
* The subnet to which the address belongs.
|
|
12
|
+
*/
|
|
13
|
+
subnet: subnetEntity,
|
|
14
|
+
},
|
|
15
|
+
|
|
16
|
+
schema: z.object({
|
|
17
|
+
/**
|
|
18
|
+
* The type of the address.
|
|
19
|
+
*/
|
|
20
|
+
type: addressTypeSchema,
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* The address in canonical string representation.
|
|
24
|
+
*
|
|
25
|
+
* IPv6 addresses must be in shortest possible notation as per RFC 5952.
|
|
26
|
+
*
|
|
27
|
+
* For example:
|
|
28
|
+
* - IPv4: `192.168.1.1`
|
|
29
|
+
* - IPv6: `2001:db8:85a3::8a2e:370:7334`
|
|
30
|
+
*/
|
|
31
|
+
value: z.string(),
|
|
32
|
+
}),
|
|
33
|
+
})
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { defineEntity, z } from "@highstate/contract"
|
|
2
|
+
import { implementationReferenceSchema } from "../impl-ref"
|
|
3
|
+
import { l3EndpointSchema } from "./endpoint-schema"
|
|
4
|
+
|
|
5
|
+
export type DynamicL3Endpoint = z.infer<typeof dynamicL3EndpointEntity.schema>
|
|
6
|
+
export type DynamicL4Endpoint = z.infer<typeof dynamicL4EndpointEntity.schema>
|
|
7
|
+
export type DynamicL7Endpoint = z.infer<typeof dynamicL7EndpointEntity.schema>
|
|
8
|
+
|
|
9
|
+
function defineDynamicEndpointEntity<TLevel extends number, TSchema extends z.ZodType>(
|
|
10
|
+
level: TLevel,
|
|
11
|
+
endpointSchema: TSchema,
|
|
12
|
+
) {
|
|
13
|
+
return defineEntity({
|
|
14
|
+
type: `network.dynamic-l${level}-endpoint.v1`,
|
|
15
|
+
|
|
16
|
+
schema: z.union([
|
|
17
|
+
z.object({
|
|
18
|
+
type: z.literal("static"),
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* The static endpoint.
|
|
22
|
+
*/
|
|
23
|
+
endpoint: endpointSchema,
|
|
24
|
+
}),
|
|
25
|
+
z.object({
|
|
26
|
+
type: z.literal("dynamic"),
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* The implementation reference to resolve the dynamic endpoint.
|
|
30
|
+
*/
|
|
31
|
+
implRef: implementationReferenceSchema,
|
|
32
|
+
}),
|
|
33
|
+
]),
|
|
34
|
+
})
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export const dynamicL3EndpointEntity = defineDynamicEndpointEntity(3, l3EndpointSchema)
|
|
38
|
+
export const dynamicL4EndpointEntity = defineDynamicEndpointEntity(4, l3EndpointSchema)
|
|
39
|
+
export const dynamicL7EndpointEntity = defineDynamicEndpointEntity(7, l3EndpointSchema)
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { z } from "@highstate/contract"
|
|
2
|
+
import { metadataSchema } from "../utils"
|
|
3
|
+
import { addressEntity } from "./address"
|
|
4
|
+
|
|
5
|
+
function createEndpointSchema<TLevel extends number, TShape extends z.core.$ZodShape>(
|
|
6
|
+
level: TLevel,
|
|
7
|
+
shape: TShape,
|
|
8
|
+
) {
|
|
9
|
+
return z.intersection(
|
|
10
|
+
z.object({
|
|
11
|
+
/**
|
|
12
|
+
* The level of the endpoint in the network stack.
|
|
13
|
+
*/
|
|
14
|
+
level: z.literal(level).default(level),
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* The extra metadata for the endpoint.
|
|
18
|
+
*
|
|
19
|
+
* In most cases, this is provided by the endpoint origin (e.g., a Kubernetes service).
|
|
20
|
+
*/
|
|
21
|
+
metadata: z.intersection(
|
|
22
|
+
metadataSchema,
|
|
23
|
+
z.object({
|
|
24
|
+
/**
|
|
25
|
+
* The scope of the endpoint as per IANA definitions.
|
|
26
|
+
*
|
|
27
|
+
* - `private`: The endpoint is intended for use within a private network.
|
|
28
|
+
* - `global`: The endpoint is intended for public access over the internet.
|
|
29
|
+
*
|
|
30
|
+
* If not specified, the scope is considered unknown.
|
|
31
|
+
*/
|
|
32
|
+
"iana.scope": z.enum(["private", "global"]).optional(),
|
|
33
|
+
}),
|
|
34
|
+
),
|
|
35
|
+
|
|
36
|
+
...shape,
|
|
37
|
+
}),
|
|
38
|
+
z.union([
|
|
39
|
+
z.object({
|
|
40
|
+
type: z.literal("hostname"),
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* The hostname of the endpoint in the format of a domain name as per RFC 1035.
|
|
44
|
+
*/
|
|
45
|
+
hostname: z.string(),
|
|
46
|
+
|
|
47
|
+
address: z.undefined().optional(),
|
|
48
|
+
}),
|
|
49
|
+
z.object({
|
|
50
|
+
type: z.enum(["ipv4", "ipv6"]),
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* The address entity representing the IP address of the endpoint.
|
|
54
|
+
*/
|
|
55
|
+
address: addressEntity.schema,
|
|
56
|
+
|
|
57
|
+
hostname: z.undefined().optional(),
|
|
58
|
+
}),
|
|
59
|
+
]),
|
|
60
|
+
)
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export const l4ProtocolSchema = z.enum(["tcp", "udp"])
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* The schema for a TCP/UDP port.
|
|
67
|
+
*/
|
|
68
|
+
export const portSchema = z.number().int().min(1).max(65535)
|
|
69
|
+
|
|
70
|
+
export const l4PortInfoSchema = z.object({
|
|
71
|
+
port: portSchema,
|
|
72
|
+
protocol: l4ProtocolSchema,
|
|
73
|
+
})
|
|
74
|
+
|
|
75
|
+
export const l7AppInfoSchema = z.object({
|
|
76
|
+
/**
|
|
77
|
+
* The name of the application protocol used by the endpoint.
|
|
78
|
+
*/
|
|
79
|
+
appProtocol: z.string(),
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* The resource path of the application endpoint, including query parameters.
|
|
83
|
+
* Must not start with a slash (`/`).
|
|
84
|
+
*
|
|
85
|
+
* Example: `api/v1/resource?query=value`, `database?param=value`, `user/repo.git`.
|
|
86
|
+
*/
|
|
87
|
+
path: z.string().optional(),
|
|
88
|
+
})
|
|
89
|
+
|
|
90
|
+
const onlyl3EndpointSchema = createEndpointSchema(3, {
|
|
91
|
+
port: z.undefined().optional(),
|
|
92
|
+
protocol: z.undefined().optional(),
|
|
93
|
+
appProtocol: z.undefined().optional(),
|
|
94
|
+
path: z.undefined().optional(),
|
|
95
|
+
})
|
|
96
|
+
|
|
97
|
+
const onlyl4EndpointSchema = createEndpointSchema(4, {
|
|
98
|
+
...l4PortInfoSchema.shape,
|
|
99
|
+
appProtocol: z.undefined().optional(),
|
|
100
|
+
path: z.undefined().optional(),
|
|
101
|
+
})
|
|
102
|
+
|
|
103
|
+
const onlyl7EndpointSchema = createEndpointSchema(7, {
|
|
104
|
+
...l4PortInfoSchema.shape,
|
|
105
|
+
...l7AppInfoSchema.shape,
|
|
106
|
+
})
|
|
107
|
+
|
|
108
|
+
export const l3EndpointSchema = z.union([
|
|
109
|
+
onlyl3EndpointSchema,
|
|
110
|
+
onlyl4EndpointSchema,
|
|
111
|
+
onlyl7EndpointSchema,
|
|
112
|
+
])
|
|
113
|
+
|
|
114
|
+
export const l4EndpointSchema = z.union([onlyl4EndpointSchema, onlyl7EndpointSchema])
|
|
115
|
+
|
|
116
|
+
export const l7EndpointSchema = onlyl7EndpointSchema
|
|
@@ -0,0 +1,347 @@
|
|
|
1
|
+
import type { Simplify } from "type-fest"
|
|
2
|
+
import { $args, defineEntity, defineUnit, z } from "@highstate/contract"
|
|
3
|
+
import { mapValues, pick } from "remeda"
|
|
4
|
+
import { metadataSchema } from "../utils"
|
|
5
|
+
import { addressEntity } from "./address"
|
|
6
|
+
import {
|
|
7
|
+
dynamicL3EndpointEntity,
|
|
8
|
+
dynamicL4EndpointEntity,
|
|
9
|
+
dynamicL7EndpointEntity,
|
|
10
|
+
} from "./dynamic-endpoint"
|
|
11
|
+
import {
|
|
12
|
+
l3EndpointSchema,
|
|
13
|
+
l4EndpointSchema,
|
|
14
|
+
type l4PortInfoSchema,
|
|
15
|
+
type l4ProtocolSchema,
|
|
16
|
+
type l7AppInfoSchema,
|
|
17
|
+
l7EndpointSchema,
|
|
18
|
+
} from "./endpoint-schema"
|
|
19
|
+
import { subnetEntity } from "./subnet"
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* The L3 endpoint for some service.
|
|
23
|
+
*
|
|
24
|
+
* May be a domain name or an IP address.
|
|
25
|
+
*/
|
|
26
|
+
export const l3EndpointEntity = defineEntity({
|
|
27
|
+
type: "network.l3-endpoint.v1",
|
|
28
|
+
|
|
29
|
+
includes: {
|
|
30
|
+
/**
|
|
31
|
+
* The subnet containing the endpoint.
|
|
32
|
+
*
|
|
33
|
+
* If type is "hostname", will be omitted.
|
|
34
|
+
*/
|
|
35
|
+
subnet: {
|
|
36
|
+
entity: subnetEntity,
|
|
37
|
+
required: false,
|
|
38
|
+
},
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* The address of the endpoint.
|
|
42
|
+
*
|
|
43
|
+
* If type is "hostname", will be omitted.
|
|
44
|
+
*/
|
|
45
|
+
address: {
|
|
46
|
+
entity: addressEntity,
|
|
47
|
+
required: false,
|
|
48
|
+
},
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* The dynamic endpoint which statically resolves to this endpoint.
|
|
52
|
+
*
|
|
53
|
+
* Allows to use any static endpoint as a dynamic without extra units.
|
|
54
|
+
*/
|
|
55
|
+
dynamic: {
|
|
56
|
+
entity: dynamicL3EndpointEntity,
|
|
57
|
+
required: false,
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
|
|
61
|
+
schema: l3EndpointSchema,
|
|
62
|
+
|
|
63
|
+
meta: {
|
|
64
|
+
color: "#4CAF50",
|
|
65
|
+
},
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* The schema for an IPv4 prefix length.
|
|
70
|
+
*/
|
|
71
|
+
export const ipv4PrefixSchema = z.number().int().min(0).max(32)
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* The schema for address that can be either IPv4 or IPv6.
|
|
75
|
+
*/
|
|
76
|
+
export const ipv46Schema = z.union([z.ipv4(), z.ipv6()])
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* The L4 endpoint for some service.
|
|
80
|
+
*
|
|
81
|
+
* Extends an L3 endpoint with a port and protocol.
|
|
82
|
+
*/
|
|
83
|
+
export const l4EndpointEntity = defineEntity({
|
|
84
|
+
type: "network.l4-endpoint.v1",
|
|
85
|
+
|
|
86
|
+
extends: { l3EndpointEntity },
|
|
87
|
+
|
|
88
|
+
includes: {
|
|
89
|
+
/**
|
|
90
|
+
* The dynamic endpoint which statically resolves to this endpoint.
|
|
91
|
+
*
|
|
92
|
+
* Allows to use any static endpoint as a dynamic without extra units.
|
|
93
|
+
*/
|
|
94
|
+
dynamic: dynamicL4EndpointEntity,
|
|
95
|
+
},
|
|
96
|
+
|
|
97
|
+
schema: l4EndpointSchema,
|
|
98
|
+
|
|
99
|
+
meta: {
|
|
100
|
+
color: "#2196F3",
|
|
101
|
+
},
|
|
102
|
+
})
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* The L7 endpoint for some service.
|
|
106
|
+
*
|
|
107
|
+
* Extends an L4 endpoint with application protocol information.
|
|
108
|
+
*/
|
|
109
|
+
export const l7EndpointEntity = defineEntity({
|
|
110
|
+
type: "network.l7-endpoint.v1",
|
|
111
|
+
|
|
112
|
+
extends: { l4EndpointEntity },
|
|
113
|
+
|
|
114
|
+
includes: {
|
|
115
|
+
/**
|
|
116
|
+
* The dynamic endpoint which statically resolves to this endpoint.
|
|
117
|
+
*
|
|
118
|
+
* Allows to use any static endpoint as a dynamic without extra units.
|
|
119
|
+
*/
|
|
120
|
+
dynamic: dynamicL7EndpointEntity,
|
|
121
|
+
},
|
|
122
|
+
|
|
123
|
+
schema: l7EndpointSchema,
|
|
124
|
+
|
|
125
|
+
meta: {
|
|
126
|
+
color: "#FF9800",
|
|
127
|
+
},
|
|
128
|
+
})
|
|
129
|
+
|
|
130
|
+
export const endpointArgs = $args({
|
|
131
|
+
/**
|
|
132
|
+
* The custom metadata entries of the endpoint.
|
|
133
|
+
*
|
|
134
|
+
* Can be used to filter them (for example, by environment, region, etc.).
|
|
135
|
+
*/
|
|
136
|
+
metadata: metadataSchema,
|
|
137
|
+
})
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* The component which creates an L3 endpoint.
|
|
141
|
+
*/
|
|
142
|
+
export const l3Endpoint = defineUnit({
|
|
143
|
+
type: "network.l3-endpoint.v1",
|
|
144
|
+
|
|
145
|
+
args: {
|
|
146
|
+
/**
|
|
147
|
+
* The string representation of the endpoint.
|
|
148
|
+
*
|
|
149
|
+
* May be a domain name or an IP address.
|
|
150
|
+
*/
|
|
151
|
+
endpoint: z.string(),
|
|
152
|
+
|
|
153
|
+
...endpointArgs,
|
|
154
|
+
},
|
|
155
|
+
|
|
156
|
+
outputs: {
|
|
157
|
+
endpoint: l3EndpointEntity,
|
|
158
|
+
},
|
|
159
|
+
|
|
160
|
+
meta: {
|
|
161
|
+
title: "L3 Endpoint",
|
|
162
|
+
icon: "mdi:network-outline",
|
|
163
|
+
iconColor: "#4CAF50",
|
|
164
|
+
defaultNamePrefix: "endpoint",
|
|
165
|
+
category: "Network",
|
|
166
|
+
},
|
|
167
|
+
|
|
168
|
+
source: {
|
|
169
|
+
package: "@highstate/common",
|
|
170
|
+
path: "units/network/l3-endpoint",
|
|
171
|
+
},
|
|
172
|
+
})
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* The component which creates an L4 endpoint.
|
|
176
|
+
*/
|
|
177
|
+
export const l4Endpoint = defineUnit({
|
|
178
|
+
type: "network.l4-endpoint.v1",
|
|
179
|
+
|
|
180
|
+
args: {
|
|
181
|
+
/**
|
|
182
|
+
* The string representation of the endpoint.
|
|
183
|
+
*
|
|
184
|
+
* May be a domain name or an IP address + port/protocol.
|
|
185
|
+
*
|
|
186
|
+
* The possible formats are:
|
|
187
|
+
*
|
|
188
|
+
* - `endpoint:port` (TCP by default)
|
|
189
|
+
* - `tcp://endpoint:port`
|
|
190
|
+
* - `udp://endpoint:port`
|
|
191
|
+
*/
|
|
192
|
+
endpoint: z.string(),
|
|
193
|
+
|
|
194
|
+
...endpointArgs,
|
|
195
|
+
},
|
|
196
|
+
|
|
197
|
+
outputs: {
|
|
198
|
+
endpoint: l4EndpointEntity,
|
|
199
|
+
},
|
|
200
|
+
|
|
201
|
+
meta: {
|
|
202
|
+
title: "L4 Endpoint",
|
|
203
|
+
icon: "mdi:network-outline",
|
|
204
|
+
iconColor: "#2196F3",
|
|
205
|
+
defaultNamePrefix: "endpoint",
|
|
206
|
+
category: "Network",
|
|
207
|
+
},
|
|
208
|
+
|
|
209
|
+
source: {
|
|
210
|
+
package: "@highstate/common",
|
|
211
|
+
path: "units/network/l4-endpoint",
|
|
212
|
+
},
|
|
213
|
+
})
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* The component which creates an L7 endpoint.
|
|
217
|
+
*/
|
|
218
|
+
export const l7Endpoint = defineUnit({
|
|
219
|
+
type: "network.l7-endpoint.v1",
|
|
220
|
+
|
|
221
|
+
args: {
|
|
222
|
+
/**
|
|
223
|
+
* The string representation of the endpoint.
|
|
224
|
+
*
|
|
225
|
+
* The format is `[protocol://]endpoint[:port][/path]`.
|
|
226
|
+
*/
|
|
227
|
+
endpoint: z.string(),
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* The L4 protocol of the endpoint.
|
|
231
|
+
*
|
|
232
|
+
* If not specified, it will be inferred from the endpoint string if possible or default to `tcp`.
|
|
233
|
+
*/
|
|
234
|
+
protocol: z.enum(["infer", "tcp", "udp"]).default("infer"),
|
|
235
|
+
|
|
236
|
+
...endpointArgs,
|
|
237
|
+
},
|
|
238
|
+
|
|
239
|
+
outputs: {
|
|
240
|
+
endpoint: l7EndpointEntity,
|
|
241
|
+
},
|
|
242
|
+
|
|
243
|
+
meta: {
|
|
244
|
+
title: "L7 Endpoint",
|
|
245
|
+
icon: "mdi:network-outline",
|
|
246
|
+
iconColor: "#FF9800",
|
|
247
|
+
defaultNamePrefix: "endpoint",
|
|
248
|
+
category: "Network",
|
|
249
|
+
},
|
|
250
|
+
|
|
251
|
+
source: {
|
|
252
|
+
package: "@highstate/common",
|
|
253
|
+
path: "units/network/l7-endpoint",
|
|
254
|
+
},
|
|
255
|
+
})
|
|
256
|
+
|
|
257
|
+
export const networkArgs = $args({
|
|
258
|
+
/**
|
|
259
|
+
* The filter expression to select endpoints by their properties and metadata.
|
|
260
|
+
*
|
|
261
|
+
* The following properties are available for filtering:
|
|
262
|
+
*
|
|
263
|
+
* - `type`: The type of the endpoint (`ipv4`, `ipv6`, `hostname`).
|
|
264
|
+
* - `level`: The level of the endpoint in the network stack (`3`, `4`, `7`). Numeric, can be used in expressions like `level >= 4`.
|
|
265
|
+
* - `protocol`: The L4 protocol of the endpoint (`tcp`, `udp`). Only available for L4 and L7 endpoints.
|
|
266
|
+
* - `port`: The port of the endpoint. Only available for L4 and L7 endpoints.
|
|
267
|
+
* - `appProtocol`: The application protocol of the endpoint (e.g., `http`, `https`, `dns`). Only available for L7 endpoints.
|
|
268
|
+
* - `metadata.{key}`: Any custom metadata field added to the endpoint. Nested fields (e.g., `metadata.k8s.service.clusterId`) are supported.
|
|
269
|
+
*
|
|
270
|
+
* See [filter-expression](https://github.com/tronghieu/filter-expression?tab=readme-ov-file#language) for more details on the expression syntax.
|
|
271
|
+
*/
|
|
272
|
+
endpointFilter: z.string().meta({ language: "javascript" }),
|
|
273
|
+
})
|
|
274
|
+
|
|
275
|
+
export const optionalNetworkArgs = mapValues(networkArgs, x => ({ schema: x.schema.optional() }))
|
|
276
|
+
|
|
277
|
+
/**
|
|
278
|
+
* Explicitly filter endpoints by their accessibility.
|
|
279
|
+
*/
|
|
280
|
+
export const endpointFilter = defineUnit({
|
|
281
|
+
type: "network.endpoint-filter.v1",
|
|
282
|
+
|
|
283
|
+
args: {
|
|
284
|
+
...pick(networkArgs, ["endpointFilter"]),
|
|
285
|
+
},
|
|
286
|
+
|
|
287
|
+
inputs: {
|
|
288
|
+
l3Endpoints: {
|
|
289
|
+
entity: l3EndpointEntity,
|
|
290
|
+
multiple: true,
|
|
291
|
+
required: false,
|
|
292
|
+
},
|
|
293
|
+
l4Endpoints: {
|
|
294
|
+
entity: l4EndpointEntity,
|
|
295
|
+
multiple: true,
|
|
296
|
+
required: false,
|
|
297
|
+
},
|
|
298
|
+
l7Endpoints: {
|
|
299
|
+
entity: l7EndpointEntity,
|
|
300
|
+
multiple: true,
|
|
301
|
+
required: false,
|
|
302
|
+
},
|
|
303
|
+
},
|
|
304
|
+
|
|
305
|
+
outputs: {
|
|
306
|
+
l3Endpoints: {
|
|
307
|
+
entity: l3EndpointEntity,
|
|
308
|
+
multiple: true,
|
|
309
|
+
},
|
|
310
|
+
l4Endpoints: {
|
|
311
|
+
entity: l4EndpointEntity,
|
|
312
|
+
multiple: true,
|
|
313
|
+
},
|
|
314
|
+
l7Endpoints: {
|
|
315
|
+
entity: l7EndpointEntity,
|
|
316
|
+
multiple: true,
|
|
317
|
+
},
|
|
318
|
+
},
|
|
319
|
+
|
|
320
|
+
meta: {
|
|
321
|
+
title: "Endpoint Filter",
|
|
322
|
+
icon: "mdi:network-outline",
|
|
323
|
+
iconColor: "#FF9800",
|
|
324
|
+
secondaryIcon: "mdi:filter-outline",
|
|
325
|
+
category: "Network",
|
|
326
|
+
},
|
|
327
|
+
|
|
328
|
+
source: {
|
|
329
|
+
package: "@highstate/common",
|
|
330
|
+
path: "units/network/endpoint-filter",
|
|
331
|
+
},
|
|
332
|
+
})
|
|
333
|
+
|
|
334
|
+
export type L3Endpoint = Simplify<z.infer<typeof l3EndpointEntity.schema>>
|
|
335
|
+
export type L4Endpoint = Simplify<z.infer<typeof l4EndpointEntity.schema>>
|
|
336
|
+
export type L4Protocol = z.infer<typeof l4ProtocolSchema>
|
|
337
|
+
export type L4PortInfo = z.infer<typeof l4PortInfoSchema>
|
|
338
|
+
export type L7Endpoint = Simplify<z.infer<typeof l7EndpointEntity.schema>>
|
|
339
|
+
export type L7AppInfo = z.infer<typeof l7AppInfoSchema>
|
|
340
|
+
|
|
341
|
+
export type EndpointLevel = L3Endpoint["level"]
|
|
342
|
+
|
|
343
|
+
export type EndpointByMinLevel<TMinLevel extends EndpointLevel> = {
|
|
344
|
+
3: L3Endpoint
|
|
345
|
+
4: L4Endpoint
|
|
346
|
+
7: L7Endpoint
|
|
347
|
+
}[TMinLevel]
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { defineEntity, z } from "@highstate/contract"
|
|
2
|
+
|
|
3
|
+
export type Subnet = z.infer<typeof subnetEntity.schema>
|
|
4
|
+
export type AddressType = z.infer<typeof addressTypeSchema>
|
|
5
|
+
|
|
6
|
+
export const addressTypeSchema = z.enum(["ipv4", "ipv6"])
|
|
7
|
+
|
|
8
|
+
export const subnetEntity = defineEntity({
|
|
9
|
+
type: "network.subnet.v1",
|
|
10
|
+
|
|
11
|
+
schema: z.object({
|
|
12
|
+
/**
|
|
13
|
+
* The type of the subnet.
|
|
14
|
+
*/
|
|
15
|
+
type: addressTypeSchema,
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* The canonical base IP address of the subnet.
|
|
19
|
+
*/
|
|
20
|
+
baseAddress: z.string(),
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* The prefix length of the subnet.
|
|
24
|
+
*/
|
|
25
|
+
prefixLength: z.number().int().nonnegative(),
|
|
26
|
+
}),
|
|
27
|
+
|
|
28
|
+
meta: {
|
|
29
|
+
color: "#3F51B5",
|
|
30
|
+
},
|
|
31
|
+
})
|