Skip to content

Commit 3f88ac6

Browse files
ARSN-479: Implement KMIP Cluster Client
With simple round robin
1 parent 8a4e4ae commit 3f88ac6

File tree

2 files changed

+100
-0
lines changed

2 files changed

+100
-0
lines changed

Diff for: lib/network/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ export const probe = { ProbeServer };
1111
export { default as RoundRobin } from './RoundRobin';
1212
export { default as kmip } from './kmip';
1313
export { default as kmipClient } from './kmip/Client';
14+
export { default as kmipClusterClient } from './kmip/ClusterClient';
1415
export { default as KmsAWSClient } from './kmsAWS/Client';
1516
export * as rpc from './rpc/rpc';
1617
export * as level from './rpc/level-net';

Diff for: lib/network/kmip/ClusterClient.ts

+99
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
'use strict'; // eslint-disable-line
2+
/* eslint new-cap: "off" */
3+
4+
import TTLVCodec from './codec/ttlv';
5+
import TlsTransport from './transport/tls';
6+
import KMIPClient from './Client';
7+
import { KMSInterface } from '../KMSInterface';
8+
import type { Logger } from 'werelogs';
9+
import async from 'async';
10+
11+
export default class ClusterClient implements KMSInterface {
12+
private readonly clients: KMIPClient[];
13+
private roundRobinIndex = 0;
14+
15+
/**
16+
* Construct a high level cluster of KMIP drivers suitable for cloudserver
17+
* @param options - Instance options
18+
* @param options.kmip - Low level driver options
19+
* @param options.kmip.client - This high level driver options
20+
* @param options.kmip.client.compoundCreateActivate -
21+
* Depends on the server's ability. False offers the best
22+
* compatibility. True does not offer a significant
23+
* performance gain, but can be useful in case of unreliable
24+
* time synchronization between the client and the server.
25+
* @param options.kmip.client.bucketNameAttributeName -
26+
* Depends on the server's ability. Not specifying this
27+
* offers the best compatibility and disable the attachement
28+
* of the bucket name as a key attribute.
29+
* @param options.kmip.codec - KMIP Codec options
30+
* @param options.kmip.transport - KMIP Transport options
31+
* @param CodecClass - diversion for the Codec class,
32+
* defaults to TTLVCodec
33+
* @param TransportClass - diversion for the Transport class,
34+
* defaults to TlsTransport
35+
*/
36+
constructor(
37+
options: {
38+
kmip: {
39+
codec: any;
40+
transport: any[];
41+
client: {
42+
compoundCreateActivate: any;
43+
bucketNameAttributeName: any;
44+
};
45+
}
46+
},
47+
CodecClass: any,
48+
TransportClass: any,
49+
) {
50+
const { codec, client } = options.kmip;
51+
this.clients = options.kmip.transport.map(transport => new KMIPClient(
52+
{ kmip: { codec, transport, client } },
53+
CodecClass || TTLVCodec,
54+
TransportClass || TlsTransport,
55+
));
56+
}
57+
58+
next() {
59+
if (this.roundRobinIndex >= this.clients.length) {
60+
this.roundRobinIndex = 0;
61+
}
62+
return this.clients[this.roundRobinIndex++];
63+
}
64+
65+
66+
createBucketKey(...args: Parameters<KMSInterface['createBucketKey']>) {
67+
const client = this.next();
68+
client.createBucketKey.apply(client, args);
69+
}
70+
71+
destroyBucketKey(...args: Parameters<KMSInterface['destroyBucketKey']>) {
72+
const client = this.next();
73+
client.destroyBucketKey.apply(client, args);
74+
}
75+
76+
cipherDataKey(...args: Parameters<KMSInterface['cipherDataKey']>) {
77+
const client = this.next();
78+
client.cipherDataKey.apply(client, args);
79+
}
80+
81+
decipherDataKey(...args: Parameters<KMSInterface['decipherDataKey']>) {
82+
const client = this.next();
83+
client.decipherDataKey.apply(client, args);
84+
}
85+
86+
clusterHealthcheck(logger: Logger, cb: (err: Error | null) => void) {
87+
async.parallel<any, Error>(
88+
this.clients.map(c => (next) => c.healthcheck(logger, next)),
89+
(err, results) => {
90+
cb(err ?? null);
91+
}
92+
)
93+
}
94+
95+
healthcheck(...args: Parameters<Required<KMSInterface>['healthcheck']>) {
96+
// for now check health of every member
97+
this.clusterHealthcheck.apply(this, args);
98+
}
99+
}

0 commit comments

Comments
 (0)