@interopio/bridge 0.0.1-alpha → 0.0.3-beta
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/bin/bridge.js +1 -1
- package/dist/main.js +2139 -0
- package/dist/main.js.map +7 -0
- package/package.json +9 -6
- package/gen/instance/GeneratedBuildInfo.ts +0 -4
- package/src/cluster/Address.ts +0 -57
- package/src/cluster/Cluster.ts +0 -13
- package/src/cluster/Endpoint.ts +0 -5
- package/src/cluster/Member.ts +0 -9
- package/src/cluster/MembershipListener.ts +0 -6
- package/src/config/Config.ts +0 -100
- package/src/config/DiscoveryConfig.ts +0 -21
- package/src/config/Duration.ts +0 -168
- package/src/config/KubernetesConfig.ts +0 -7
- package/src/config/NamedDiscoveryConfig.ts +0 -17
- package/src/config/Properties.ts +0 -49
- package/src/config/index.ts +0 -1
- package/src/discovery/SimpleDiscoveryNode.ts +0 -14
- package/src/discovery/index.ts +0 -207
- package/src/discovery/multicast/MulticastDiscoveryStrategy.ts +0 -141
- package/src/discovery/multicast/MulticastDiscoveryStrategyFactory.ts +0 -30
- package/src/discovery/multicast/MulticastProperties.ts +0 -4
- package/src/discovery/settings.ts +0 -37
- package/src/error/RequestFailure.ts +0 -48
- package/src/gossip/ApplicationState.ts +0 -48
- package/src/gossip/EndpointState.ts +0 -141
- package/src/gossip/FailureDetector.ts +0 -235
- package/src/gossip/Gossiper.ts +0 -1133
- package/src/gossip/HeartbeatState.ts +0 -66
- package/src/gossip/Messenger.ts +0 -130
- package/src/gossip/VersionedValue.ts +0 -59
- package/src/index.ts +0 -3
- package/src/instance/AddressPicker.ts +0 -245
- package/src/instance/BridgeNode.ts +0 -141
- package/src/instance/ClusterTopologyIntentTracker.ts +0 -4
- package/src/io/VersionedSerializer.ts +0 -230
- package/src/io/util.ts +0 -117
- package/src/kubernetes/DnsEndpointResolver.ts +0 -70
- package/src/kubernetes/KubernetesApiEndpointResolver.ts +0 -111
- package/src/kubernetes/KubernetesApiProvider.ts +0 -75
- package/src/kubernetes/KubernetesClient.ts +0 -264
- package/src/kubernetes/KubernetesConfig.ts +0 -130
- package/src/kubernetes/KubernetesDiscoveryStrategy.ts +0 -30
- package/src/kubernetes/KubernetesDiscoveryStrategyFactory.ts +0 -71
- package/src/kubernetes/KubernetesEndpointResolver.ts +0 -43
- package/src/kubernetes/KubernetesProperties.ts +0 -22
- package/src/license/BridgeLicenseValidator.ts +0 -19
- package/src/license/LicenseValidator.ts +0 -114
- package/src/license/types.ts +0 -40
- package/src/logging.ts +0 -22
- package/src/main.mts +0 -53
- package/src/net/Action.ts +0 -143
- package/src/net/AddressSerializer.ts +0 -44
- package/src/net/ByteBufferAllocator.ts +0 -27
- package/src/net/FrameDecoder.ts +0 -314
- package/src/net/FrameEncoder.ts +0 -138
- package/src/net/HandshakeProtocol.ts +0 -143
- package/src/net/InboundConnection.ts +0 -108
- package/src/net/InboundConnectionInitiator.ts +0 -150
- package/src/net/InboundMessageHandler.ts +0 -377
- package/src/net/InboundSink.ts +0 -38
- package/src/net/Message.ts +0 -428
- package/src/net/OutboundConnection.ts +0 -1141
- package/src/net/OutboundConnectionInitiator.ts +0 -76
- package/src/net/RequestCallbacks.ts +0 -148
- package/src/net/ResponseHandler.ts +0 -30
- package/src/net/ShareableBytes.ts +0 -125
- package/src/net/internal/AsyncResourceExecutor.ts +0 -464
- package/src/net/internal/AsyncSocketPromise.ts +0 -37
- package/src/net/internal/channel/ChannelHandlerAdapter.ts +0 -99
- package/src/net/internal/channel/types.ts +0 -188
- package/src/utils/bigint.ts +0 -23
- package/src/utils/buffer.ts +0 -434
- package/src/utils/clock.ts +0 -148
- package/src/utils/collections.ts +0 -283
- package/src/utils/crc.ts +0 -39
- package/src/utils/internal/IpAddressUtil.ts +0 -161
- package/src/utils/memory/BufferPools.ts +0 -40
- package/src/utils/network.ts +0 -130
- package/src/utils/promise.ts +0 -38
- package/src/utils/uuid.ts +0 -5
- package/src/utils/vint.ts +0 -238
- package/src/version/MemberVersion.ts +0 -42
- package/src/version/Version.ts +0 -12
|
@@ -1,264 +0,0 @@
|
|
|
1
|
-
import {type ExposeExternallyMode} from './KubernetesConfig.ts';
|
|
2
|
-
import {KubernetesApiEndpointSlicesProvider, type KubernetesApiProvider} from './KubernetesApiProvider.ts';
|
|
3
|
-
import {type ClusterTopologyIntentTracker} from '../instance/ClusterTopologyIntentTracker.ts';
|
|
4
|
-
|
|
5
|
-
class Address {
|
|
6
|
-
readonly ip: string;
|
|
7
|
-
|
|
8
|
-
readonly port?: number;
|
|
9
|
-
|
|
10
|
-
constructor(ip: string, port?: number) {
|
|
11
|
-
this.ip = ip;
|
|
12
|
-
this.port = port;
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export type {Address};
|
|
17
|
-
|
|
18
|
-
export class EndpointAddress {
|
|
19
|
-
readonly targetRefName?: string;
|
|
20
|
-
|
|
21
|
-
private readonly address: Address;
|
|
22
|
-
|
|
23
|
-
constructor(address: Address, targetRefName?: string) {
|
|
24
|
-
this.address = address;
|
|
25
|
-
this.targetRefName = targetRefName;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
get ip(): string {
|
|
29
|
-
return this.address.ip;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
get port(): number | undefined {
|
|
33
|
-
return this.address.port;
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
export class Endpoint {
|
|
38
|
-
|
|
39
|
-
readonly privateAddress: EndpointAddress;
|
|
40
|
-
readonly publicAddress: EndpointAddress | undefined = undefined;
|
|
41
|
-
readonly ready: boolean;
|
|
42
|
-
readonly additionalProperties: ReadonlyMap<string, string> = new Map();
|
|
43
|
-
|
|
44
|
-
constructor(privateAddress: EndpointAddress,
|
|
45
|
-
publicAddress: EndpointAddress | undefined = undefined,
|
|
46
|
-
ready: boolean,
|
|
47
|
-
additionalProperties: ReadonlyMap<string, string> = new Map()) {
|
|
48
|
-
this.privateAddress = privateAddress;
|
|
49
|
-
this.publicAddress = publicAddress;
|
|
50
|
-
this.ready = ready;
|
|
51
|
-
this.additionalProperties = additionalProperties;
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
const READ_TIMEOUT_SECONDS = 10;
|
|
56
|
-
|
|
57
|
-
function isReady(podItemStatus: { containerStatuses?: Array<{ ready?: boolean }> }): boolean {
|
|
58
|
-
for (const containerStatus of podItemStatus.containerStatuses) {
|
|
59
|
-
if (containerStatus.ready !== true) {
|
|
60
|
-
return false;
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
return true;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
function containerPort(container: {
|
|
67
|
-
ports?: Array<{
|
|
68
|
-
containerPort?: number
|
|
69
|
-
}>
|
|
70
|
-
}): number | undefined {
|
|
71
|
-
const ports = container.ports;
|
|
72
|
-
if (ports.length > 0) {
|
|
73
|
-
const port = ports[0];
|
|
74
|
-
return port.containerPort;
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
function extractContainerPort(item: {
|
|
79
|
-
spec: {
|
|
80
|
-
containers?: Array<{ name?: string, ports?: Array<{ containerPort?: number }> }>
|
|
81
|
-
}
|
|
82
|
-
}): number | undefined {
|
|
83
|
-
const containers = item.spec.containers;
|
|
84
|
-
if (containers.length === 1) {
|
|
85
|
-
const container = containers[0];
|
|
86
|
-
return containerPort(container);
|
|
87
|
-
} else {
|
|
88
|
-
for (const container of containers) {
|
|
89
|
-
if (container.name === 'io-bridge') {
|
|
90
|
-
return containerPort(container);
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
function parsePodsList(podList: {
|
|
97
|
-
items?: Array<{
|
|
98
|
-
metadata: {
|
|
99
|
-
name: string
|
|
100
|
-
},
|
|
101
|
-
status: {
|
|
102
|
-
podIP?: string
|
|
103
|
-
containerStatuses?: Array<{ ready?: boolean }>
|
|
104
|
-
},
|
|
105
|
-
spec: {}
|
|
106
|
-
}>
|
|
107
|
-
}): Array<Endpoint> {
|
|
108
|
-
const addresses = new Array<Endpoint>();
|
|
109
|
-
for (const item of podList.items) {
|
|
110
|
-
const podName = item.metadata.name;
|
|
111
|
-
const status = item.status;
|
|
112
|
-
const ip = status.podIP;
|
|
113
|
-
if (ip) {
|
|
114
|
-
const port = extractContainerPort(item);
|
|
115
|
-
addresses.push(new Endpoint(new EndpointAddress({ip, port}, podName), undefined, isReady(status)));
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
return addresses;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
function getLabelSelectorParameter(labelNames: string, labelValues: string): string {
|
|
122
|
-
const labelNameArray = labelNames.split(',');
|
|
123
|
-
const labelValueArray = labelValues.split(',');
|
|
124
|
-
const selectorList = [];
|
|
125
|
-
for (let i = 0; i < labelNameArray.length; i++) {
|
|
126
|
-
selectorList[i] = (`${labelNameArray[i]}=${labelValueArray[i]}`);
|
|
127
|
-
}
|
|
128
|
-
return `labelSelector=${selectorList.join(',')}`;
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
export class KubernetesClient {
|
|
132
|
-
|
|
133
|
-
private readonly namespace: string;
|
|
134
|
-
private readonly kubernetesMaster: string;
|
|
135
|
-
private readonly exposeExternallyMode: ExposeExternallyMode;
|
|
136
|
-
private readonly tokenProvider: () => string;
|
|
137
|
-
private readonly servicePerPodLabelName?: string;
|
|
138
|
-
private readonly servicePerPodLabelValue?: string;
|
|
139
|
-
private readonly clientTopologyIntentTracker?: ClusterTopologyIntentTracker;
|
|
140
|
-
private readonly apiProvider: KubernetesApiProvider
|
|
141
|
-
|
|
142
|
-
/*testing*/
|
|
143
|
-
constructor(namespace: string,
|
|
144
|
-
kubernetesMaster: string,
|
|
145
|
-
exposeExternallyMode: ExposeExternallyMode,
|
|
146
|
-
tokenProvider: () => string,
|
|
147
|
-
servicePerPodLabelName?: string,
|
|
148
|
-
servicePerPodLabelValue?: string,
|
|
149
|
-
clientTopologyIntentTracker?: ClusterTopologyIntentTracker,
|
|
150
|
-
apiProvider?: KubernetesApiProvider) {
|
|
151
|
-
|
|
152
|
-
this.namespace = namespace;
|
|
153
|
-
this.kubernetesMaster = kubernetesMaster;
|
|
154
|
-
this.exposeExternallyMode = exposeExternallyMode;
|
|
155
|
-
this.tokenProvider = tokenProvider;
|
|
156
|
-
this.servicePerPodLabelName = servicePerPodLabelName;
|
|
157
|
-
this.servicePerPodLabelValue = servicePerPodLabelValue;
|
|
158
|
-
if (clientTopologyIntentTracker) {
|
|
159
|
-
clientTopologyIntentTracker.init();
|
|
160
|
-
}
|
|
161
|
-
this.apiProvider = apiProvider ?? new KubernetesApiEndpointSlicesProvider();
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
start(): void {
|
|
165
|
-
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
destroy(): void {
|
|
169
|
-
if (this.clientTopologyIntentTracker) {
|
|
170
|
-
this.clientTopologyIntentTracker.destroy();
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
/**
|
|
175
|
-
* Returns POD addresses in the specified namespace.
|
|
176
|
-
*
|
|
177
|
-
*/
|
|
178
|
-
async endpoints(): Promise<Endpoint[]> {
|
|
179
|
-
try {
|
|
180
|
-
const url = `${this.kubernetesMaster}/api/v1/namespaces/${this.namespace}/pods`;
|
|
181
|
-
return this.enrichWithPublicAddresses(parsePodsList(await this.callGet(url)));
|
|
182
|
-
} catch (e) {
|
|
183
|
-
return this.handleUnknownError(e);
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
/**
|
|
188
|
-
* Retrieves POD addresses for all services in the specified namespace filtered by service labels and values.
|
|
189
|
-
* @param serviceLabels comma separated list of service labels
|
|
190
|
-
* @param serviceLabelValues comma separated list of service label values
|
|
191
|
-
* @return all POD addresses from the specified namespace filtered by labels
|
|
192
|
-
*/
|
|
193
|
-
async endpointsByServiceLabel(serviceLabels: string, serviceLabelValues: string): Promise<Endpoint[]> {
|
|
194
|
-
try {
|
|
195
|
-
const param = getLabelSelectorParameter(serviceLabels, serviceLabelValues);
|
|
196
|
-
const url = this.apiProvider.getEndpointsByServiceLabelUrlString(this.kubernetesMaster, this.namespace, param);
|
|
197
|
-
return this.enrichWithPublicAddresses(this.apiProvider.parseEndpoints(this.callGet(url)));
|
|
198
|
-
} catch (e) {
|
|
199
|
-
return this.handleUnknownError(e);
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
/**
|
|
204
|
-
* Retrieves POD addresses from the specified namespace and given endpointName.
|
|
205
|
-
* @param endpointName endpoint name
|
|
206
|
-
* @return all POD addresses from the specified namespace and the given endpointName
|
|
207
|
-
*/
|
|
208
|
-
async endpointsByName(endpointName: string): Promise<Endpoint[]> {
|
|
209
|
-
try {
|
|
210
|
-
const url = this.apiProvider.getEndpointsByNameUrlString(this.kubernetesMaster, this.namespace, endpointName);
|
|
211
|
-
return this.enrichWithPublicAddresses(this.apiProvider.parseEndpoints(await this.callGet(url)));
|
|
212
|
-
} catch (e) {
|
|
213
|
-
return this.handleUnknownError(e);
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
/**
|
|
218
|
-
* Retrieves POD addresses for all services in the specified namespace filtered by pod labels and values.
|
|
219
|
-
* @param podLabels comma separated list of pod labels
|
|
220
|
-
* @param podLabelValues comma separated list of pod label values
|
|
221
|
-
* @return all POD addresses from the specified namespace filtered by the labels
|
|
222
|
-
*/
|
|
223
|
-
async endpointsByPodLabel(podLabels: string, podLabelValues: string) {
|
|
224
|
-
try {
|
|
225
|
-
const param = getLabelSelectorParameter(podLabels, podLabelValues);
|
|
226
|
-
const url = `${this.kubernetesMaster}/api/v1/namespaces/${this.namespace}/pods?${param}`;
|
|
227
|
-
return this.enrichWithPublicAddresses(parsePodsList(await this.callGet(url)));
|
|
228
|
-
} catch (e) {
|
|
229
|
-
return this.handleUnknownError(e);
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
private enrichWithPublicAddresses(endpoints: Endpoint[]): Endpoint[] {
|
|
234
|
-
if (this.exposeExternallyMode === 'disabled') {
|
|
235
|
-
return endpoints;
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
private handleUnknownError(e): Endpoint[] {
|
|
241
|
-
// todo handle error
|
|
242
|
-
return [];
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
private async callGet(url: string): Promise<any> {
|
|
246
|
-
const controller = new AbortController();
|
|
247
|
-
const timeout = setTimeout(() => {
|
|
248
|
-
controller.abort(`request to ${url} timed out`);
|
|
249
|
-
}, READ_TIMEOUT_SECONDS * 1000);
|
|
250
|
-
try {
|
|
251
|
-
const response = await fetch(url, {
|
|
252
|
-
signal: controller.signal,
|
|
253
|
-
headers: [["Authorization", `Bearer ${this.tokenProvider()}`]]
|
|
254
|
-
}).catch((err) => {
|
|
255
|
-
throw err;
|
|
256
|
-
});
|
|
257
|
-
|
|
258
|
-
return await response.json();
|
|
259
|
-
|
|
260
|
-
} finally {
|
|
261
|
-
clearTimeout(timeout);
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
}
|
|
@@ -1,130 +0,0 @@
|
|
|
1
|
-
import { readFileSync} from 'node:fs';
|
|
2
|
-
import { getOrDefault, getOrUndefined } from '../discovery/settings.ts';
|
|
3
|
-
import {
|
|
4
|
-
KUBERNETES_API_TOKEN,
|
|
5
|
-
KUBERNETES_MASTER_URL,
|
|
6
|
-
KUBERNETES_ENV_PREFIX,
|
|
7
|
-
NAMESPACE,
|
|
8
|
-
RESOLVE_NOT_READY_ADDRESSES,
|
|
9
|
-
SERVICE_DNS,
|
|
10
|
-
SERVICE_NAME,
|
|
11
|
-
SERVICE_PORT,
|
|
12
|
-
EXPOSE_EXTERNALLY,
|
|
13
|
-
SERVICE_LABEL_NAME,
|
|
14
|
-
SERVICE_LABEL_VALUE,
|
|
15
|
-
POD_LABEL_NAME,
|
|
16
|
-
POD_LABEL_VALUE,
|
|
17
|
-
SERVICE_PER_POD_LABEL_NAME, SERVICE_PER_POD_LABEL_VALUE
|
|
18
|
-
} from './KubernetesProperties.ts';
|
|
19
|
-
import {type Properties} from '../config/Properties.ts';
|
|
20
|
-
|
|
21
|
-
export type DiscoveryMode = 'kubernetes-api' | 'dns-lookup';
|
|
22
|
-
export type ExposeExternallyMode = 'auto' | 'enabled' | 'disabled';
|
|
23
|
-
|
|
24
|
-
function readFileContents(fileName: string): string {
|
|
25
|
-
return readFileSync(fileName, 'utf-8').toString();
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
export class KubernetesConfig {
|
|
30
|
-
readonly serviceDns?: string
|
|
31
|
-
|
|
32
|
-
readonly serviceName?: string
|
|
33
|
-
readonly serviceLabelName?: string
|
|
34
|
-
readonly serviceLabelValue?: string
|
|
35
|
-
readonly namespace: string
|
|
36
|
-
readonly podLabelName?: string
|
|
37
|
-
readonly podLabelValue?: string
|
|
38
|
-
readonly resolveNotReadyAddresses: boolean
|
|
39
|
-
readonly exposeExternallyMode: ExposeExternallyMode
|
|
40
|
-
readonly servicePerPodLabelName?: string
|
|
41
|
-
readonly servicePerPodLabelValue?: string
|
|
42
|
-
readonly kubernetesMasterUrl: string
|
|
43
|
-
readonly kubernetesApiToken?: string
|
|
44
|
-
|
|
45
|
-
readonly servicePort: number
|
|
46
|
-
private readonly fileContentsReader: (fileName: string) => string;
|
|
47
|
-
|
|
48
|
-
readonly tokenProvider: () => string;
|
|
49
|
-
|
|
50
|
-
constructor(properties: Properties, fileContentsReader: (fileName: string) => string = readFileContents) {
|
|
51
|
-
this.fileContentsReader = fileContentsReader;
|
|
52
|
-
this.serviceDns = getOrDefault(properties, KUBERNETES_ENV_PREFIX, SERVICE_DNS);
|
|
53
|
-
this.serviceName = getOrDefault(properties, KUBERNETES_ENV_PREFIX, SERVICE_NAME);
|
|
54
|
-
this.serviceLabelName = getOrUndefined(properties, KUBERNETES_ENV_PREFIX, SERVICE_LABEL_NAME);
|
|
55
|
-
this.serviceLabelValue = getOrDefault(properties, KUBERNETES_ENV_PREFIX, SERVICE_LABEL_VALUE, "true");
|
|
56
|
-
this.resolveNotReadyAddresses = getOrDefault(properties, KUBERNETES_ENV_PREFIX, RESOLVE_NOT_READY_ADDRESSES, true);
|
|
57
|
-
this.podLabelName = getOrUndefined(properties, KUBERNETES_ENV_PREFIX, POD_LABEL_NAME);
|
|
58
|
-
this.podLabelValue = getOrUndefined(properties, KUBERNETES_ENV_PREFIX, POD_LABEL_VALUE);
|
|
59
|
-
|
|
60
|
-
this.exposeExternallyMode = this.getExposeExternallyMode(properties);
|
|
61
|
-
this.servicePerPodLabelName = getOrUndefined(properties, KUBERNETES_ENV_PREFIX, SERVICE_PER_POD_LABEL_NAME);
|
|
62
|
-
this.servicePerPodLabelValue = getOrUndefined(properties, KUBERNETES_ENV_PREFIX, SERVICE_PER_POD_LABEL_VALUE);
|
|
63
|
-
this.kubernetesMasterUrl = getOrDefault(properties, KUBERNETES_ENV_PREFIX, KUBERNETES_MASTER_URL, "https://kubernetes.default.svc");
|
|
64
|
-
this.tokenProvider = this.buildTokenProvider(properties);
|
|
65
|
-
this.servicePort = getOrDefault(properties, KUBERNETES_ENV_PREFIX, SERVICE_PORT, 0);
|
|
66
|
-
this.namespace = this.getNamespaceWithFallbacks(properties);
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
private getExposeExternallyMode(properties: Properties): ExposeExternallyMode {
|
|
70
|
-
const exposeExternally: boolean | undefined = getOrUndefined<boolean>(properties, KUBERNETES_ENV_PREFIX, EXPOSE_EXTERNALLY);
|
|
71
|
-
if (exposeExternally === undefined) {
|
|
72
|
-
return 'auto';
|
|
73
|
-
}
|
|
74
|
-
else if (exposeExternally) {
|
|
75
|
-
return 'enabled';
|
|
76
|
-
}
|
|
77
|
-
else {
|
|
78
|
-
return 'disabled';
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
private getNamespaceWithFallbacks(properties: Properties): string {
|
|
83
|
-
let namespace: string | undefined = getOrDefault(properties, KUBERNETES_ENV_PREFIX, NAMESPACE);
|
|
84
|
-
if (!namespace) {
|
|
85
|
-
namespace = process.env['KUBERNETES_NAMESPACE'];
|
|
86
|
-
}
|
|
87
|
-
if (!namespace && this.mode === 'kubernetes-api') {
|
|
88
|
-
namespace = this.readNamespace();
|
|
89
|
-
}
|
|
90
|
-
return namespace;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
private buildTokenProvider(properties: {}): () => string {
|
|
94
|
-
const apiToken: string | undefined = getOrUndefined(properties, KUBERNETES_ENV_PREFIX, KUBERNETES_API_TOKEN);
|
|
95
|
-
if (!apiToken && this.mode === 'kubernetes-api') {
|
|
96
|
-
return () => readFileContents('/var/run/secrets/kubernetes.io/serviceaccount/token')
|
|
97
|
-
} else {
|
|
98
|
-
return () => apiToken;
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
private readNamespace(): string {
|
|
103
|
-
return this.fileContentsReader('/var/run/secrets/kubernetes.io/serviceaccount/namespace');
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
get mode(): DiscoveryMode {
|
|
108
|
-
if (this.serviceDns) {
|
|
109
|
-
return 'dns-lookup';
|
|
110
|
-
}
|
|
111
|
-
return 'kubernetes-api';
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
toString() {
|
|
115
|
-
return "KubernetesConfig: {"
|
|
116
|
-
+ "service-dns: " + this.serviceDns
|
|
117
|
-
+ ", service-name: " + this.serviceName
|
|
118
|
-
+ ", service-port: " + this.servicePort
|
|
119
|
-
+ ", service-label-name: " + this.serviceLabelName
|
|
120
|
-
+ ", service-label-value: " + this.serviceLabelValue
|
|
121
|
-
+ ", namespace: " + this.namespace
|
|
122
|
-
+ ", pod-label-name: " + this.podLabelName
|
|
123
|
-
+ ", pod-label-value: " + this.podLabelValue
|
|
124
|
-
+ ", resolve-not-ready-addresses: " + this.resolveNotReadyAddresses
|
|
125
|
-
+ ", expose-externally-mode: " + this.exposeExternallyMode
|
|
126
|
-
+ ", service-per-pod-label-name: " + this.servicePerPodLabelName
|
|
127
|
-
+ ", service-per-pod-label-value: " + this.servicePerPodLabelValue
|
|
128
|
-
+ ", kubernetes-master-url: " + this.kubernetesMasterUrl + "}";
|
|
129
|
-
}
|
|
130
|
-
}
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import {type DiscoveryNode, type DiscoveryStrategy} from '../discovery/index.ts';
|
|
2
|
-
import {KubernetesConfig} from './KubernetesConfig.ts';
|
|
3
|
-
import {KubernetesApiEndpointResolver} from './KubernetesApiEndpointResolver.ts';
|
|
4
|
-
import {KubernetesEndpointResolver} from './KubernetesEndpointResolver.ts';
|
|
5
|
-
import {type ClusterTopologyIntentTracker} from '../instance/ClusterTopologyIntentTracker.ts';
|
|
6
|
-
import {type Logger} from '../logging.ts';
|
|
7
|
-
|
|
8
|
-
export class KubernetesDiscoveryStrategy implements DiscoveryStrategy {
|
|
9
|
-
private readonly logger: Logger;
|
|
10
|
-
private readonly endpointResolver: KubernetesEndpointResolver;
|
|
11
|
-
|
|
12
|
-
constructor(logger: Logger, properties: {[key: string]: string | number | boolean}, intentTracker?: ClusterTopologyIntentTracker) {
|
|
13
|
-
this.logger = logger;
|
|
14
|
-
const config = new KubernetesConfig(properties);
|
|
15
|
-
this.logger.info(`${config}`);
|
|
16
|
-
this.endpointResolver = KubernetesApiEndpointResolver.of(this.logger, config, intentTracker);
|
|
17
|
-
this.logger.info(`Kubernetes Discovery activated with mode: ${config.mode}`);
|
|
18
|
-
}
|
|
19
|
-
async start() {
|
|
20
|
-
await this.endpointResolver.start();
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
async discover(): Promise<Iterable<DiscoveryNode> | undefined> {
|
|
24
|
-
return undefined
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
async close() {
|
|
28
|
-
await this.endpointResolver.close();
|
|
29
|
-
}
|
|
30
|
-
}
|
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
import {type DiscoveryNode, type DiscoveryStrategyFactory, DiscoveryStrategyPriorities} from '../discovery/index.ts';
|
|
2
|
-
import {stat} from 'node:fs/promises';
|
|
3
|
-
import {lookup} from 'node:dns/promises'
|
|
4
|
-
import {KubernetesDiscoveryStrategy} from './KubernetesDiscoveryStrategy.ts';
|
|
5
|
-
import type {Properties, PropertyDefinition} from '../config/Properties.ts';
|
|
6
|
-
import {
|
|
7
|
-
EXPOSE_EXTERNALLY, KUBERNETES_API_TOKEN,
|
|
8
|
-
KUBERNETES_MASTER_URL,
|
|
9
|
-
NAMESPACE, POD_LABEL_NAME, POD_LABEL_VALUE, RESOLVE_NOT_READY_ADDRESSES,
|
|
10
|
-
SERVICE_DNS,
|
|
11
|
-
SERVICE_LABEL_NAME,
|
|
12
|
-
SERVICE_LABEL_VALUE,
|
|
13
|
-
SERVICE_NAME, SERVICE_PORT
|
|
14
|
-
} from './KubernetesProperties.ts';
|
|
15
|
-
import {type ClusterTopologyIntentTracker} from '../instance/ClusterTopologyIntentTracker.ts';
|
|
16
|
-
import {type Logger} from '../logging.ts';
|
|
17
|
-
|
|
18
|
-
const PROPERTY_DEFINITIONS: ReadonlyArray<PropertyDefinition> = [
|
|
19
|
-
SERVICE_DNS,
|
|
20
|
-
SERVICE_NAME,
|
|
21
|
-
SERVICE_LABEL_NAME,
|
|
22
|
-
SERVICE_LABEL_VALUE,
|
|
23
|
-
NAMESPACE,
|
|
24
|
-
POD_LABEL_NAME,
|
|
25
|
-
POD_LABEL_VALUE,
|
|
26
|
-
RESOLVE_NOT_READY_ADDRESSES,
|
|
27
|
-
EXPOSE_EXTERNALLY,
|
|
28
|
-
KUBERNETES_MASTER_URL,
|
|
29
|
-
KUBERNETES_API_TOKEN,
|
|
30
|
-
SERVICE_PORT
|
|
31
|
-
];
|
|
32
|
-
|
|
33
|
-
export class KubernetesDiscoveryStrategyFactory implements DiscoveryStrategyFactory {
|
|
34
|
-
private readonly tokenPath: string;
|
|
35
|
-
readonly priority = DiscoveryStrategyPriorities.PLATFORM;
|
|
36
|
-
constructor(tokenPath = '/var/run/secrets/kubernetes.io/serviceaccount/token') {
|
|
37
|
-
this.tokenPath = tokenPath;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
private async defaultKubernetesMasterReachable() {
|
|
41
|
-
try {
|
|
42
|
-
await lookup('kubernetes.default.svc');
|
|
43
|
-
return true;
|
|
44
|
-
} catch (e) {
|
|
45
|
-
// todo log that io.Bridge running on Kubernetes, but "kubernetes.default.svc" is not reachable.
|
|
46
|
-
return false;
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
async tokenFileExists(){
|
|
51
|
-
try {
|
|
52
|
-
await stat(this.tokenPath);
|
|
53
|
-
return true;
|
|
54
|
-
} catch (e) {
|
|
55
|
-
return false;
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
async isAutoDetectionApplicable() {
|
|
60
|
-
return await this.tokenFileExists() && await this.defaultKubernetesMasterReachable()
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
newDiscoveryStrategy(node: DiscoveryNode | undefined, logger: Logger, properties: Properties) {
|
|
64
|
-
const tracker = node?.properties.get("internal.discovery.cluster.topology.intent.tracker");
|
|
65
|
-
return new KubernetesDiscoveryStrategy(logger, properties, tracker as ClusterTopologyIntentTracker | undefined);
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
getConfigurationProperties(): ReadonlyArray<PropertyDefinition> {
|
|
69
|
-
return PROPERTY_DEFINITIONS;
|
|
70
|
-
}
|
|
71
|
-
}
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import {type DiscoveryNode} from '../discovery/index.ts';
|
|
2
|
-
import {getByName} from '../utils/network.ts';
|
|
3
|
-
import type {Logger} from '../logging.ts';
|
|
4
|
-
|
|
5
|
-
const DNS_RETRY = 5;
|
|
6
|
-
|
|
7
|
-
export abstract class KubernetesEndpointResolver {
|
|
8
|
-
protected readonly logger: Logger;
|
|
9
|
-
constructor(logger: Logger) {
|
|
10
|
-
this.logger = logger;
|
|
11
|
-
}
|
|
12
|
-
async start() {
|
|
13
|
-
// do nothing
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
abstract resolve(): Promise<DiscoveryNode[]>
|
|
17
|
-
|
|
18
|
-
async close() {
|
|
19
|
-
// do nothing
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
protected async mapAddress(address?: string) {
|
|
23
|
-
if (!address) {
|
|
24
|
-
return;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
try {
|
|
28
|
-
let retry = 0;
|
|
29
|
-
try {
|
|
30
|
-
return await getByName(address);
|
|
31
|
-
} catch (e) {
|
|
32
|
-
if (retry < DNS_RETRY) {
|
|
33
|
-
retry++;
|
|
34
|
-
} else {
|
|
35
|
-
throw e;
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
} catch (e) {
|
|
39
|
-
// todo log address cloud not be resolved
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
}
|
|
43
|
-
}
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import {BOOLEAN, NUMBER, property, STRING} from '../config/Properties.ts';
|
|
2
|
-
|
|
3
|
-
export const KUBERNETES_ENV_PREFIX = 'io.bridge.kubernetes';
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
export const SERVICE_DNS = property<string>('service-dns', STRING);
|
|
9
|
-
export const SERVICE_NAME = property<string>('service-name', STRING);
|
|
10
|
-
export const SERVICE_LABEL_NAME = property<string>('service-label-name', STRING);
|
|
11
|
-
export const SERVICE_LABEL_VALUE = property<string>('service-label-value', STRING);
|
|
12
|
-
export const NAMESPACE = property<string>('namespace', STRING);
|
|
13
|
-
export const POD_LABEL_NAME = property<string>('pod-label-name', STRING);
|
|
14
|
-
export const POD_LABEL_VALUE = property<string>('pod-label-value', STRING);
|
|
15
|
-
export const EXPOSE_EXTERNALLY = property<boolean>('expose-externally', BOOLEAN);
|
|
16
|
-
export const SERVICE_PER_POD_LABEL_NAME = property<string>('service-per-pod-label-name', STRING);
|
|
17
|
-
export const SERVICE_PER_POD_LABEL_VALUE = property<string>('service-per-pod-label-value', STRING);
|
|
18
|
-
export const RESOLVE_NOT_READY_ADDRESSES = property<boolean>('resolve-not-ready-addresses', BOOLEAN);
|
|
19
|
-
|
|
20
|
-
export const KUBERNETES_MASTER_URL = property<string>('kubernetes-master', STRING);
|
|
21
|
-
export const KUBERNETES_API_TOKEN = property<string>('api-token', STRING);
|
|
22
|
-
export const SERVICE_PORT = property<number>('service-port', NUMBER);
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import type {Logger} from "../logging.ts";
|
|
2
|
-
import {LicenseValidator} from "./LicenseValidator.ts";
|
|
3
|
-
|
|
4
|
-
const validationKey = `-----BEGIN PUBLIC KEY-----
|
|
5
|
-
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAyyZrtwcQCMfyOkZDcjxZ
|
|
6
|
-
+07BrvgcAvoQETF+ho8VLfaDxgNPZd6Q7jZEfrtv0+wn0pxx8pUDeBh8mCYvkwmb
|
|
7
|
-
9tkFH47GJuDhWasNgyp4ugRX4bzoPV3SnHsBR4KJ/F76kBbike6sdIfO2lYGZ36s
|
|
8
|
-
LJPHV7epOYsfhoc4343/vOxEPvNbwacbXWl4NsCGev4qUmWhe9iMpb/JPd3o4hIU
|
|
9
|
-
SR31AmR2xoh3BkAJc2q/cSeQK6Kn9nZYocyW367+7FOvYsrOYotsuUASp0OWp+Lh
|
|
10
|
-
WGfR7F6d016+u6kbvLvcceGztiP1u25QmPNCUmw49cTatthiEwwGHb01CR58mStZ
|
|
11
|
-
xg5t9+N7X9hPO2K59b8EbOnnFTlwtMMF7MKR56S4YwMamCChr9WGgpOQV+lrqyx2
|
|
12
|
-
yn9lwn8Yf4gLoLPKBEhHTEy6r/we9qymmlSSe4wr5Fctov2odSE535nvtdRYZkKk
|
|
13
|
-
t32gOXuwnKg2kRlRSAErpyou1mz7/mWEt1H3sGTRArjNTP2KqZkc14vPToEEJt93
|
|
14
|
-
ZKjhD1pVEchDiWBOMj9o12pq80tGZ8PhGJasJVVi0JPUiaznG4r12JdyDAjuXMru
|
|
15
|
-
6f4Tx0ULkdwn9ia7lchcq7xC2PlTnYz+fGpfU7V0Ci56QDTp6oP567L1EIeddkaI
|
|
16
|
-
nIsi4KHT7Ctp047FTTelntUCAwEAAQ==
|
|
17
|
-
-----END PUBLIC KEY-----`;
|
|
18
|
-
|
|
19
|
-
export const BridgeLicenseValidator = (logger: Logger) => new LicenseValidator({validationKey, logger});
|