etcd3
etcd3 aims is a high-quality, production-ready client for the Protocol Buffer-based etcdv3 API. It includes:
and is type-safe for TypeScript consumers.
Quickstart
Install via:
npm install
Start building!
const { Etcd3 } = require('etcd3');
const client = new Etcd3();
(async () => {
await client.put('foo').value('bar');
const fooValue = await client.get('foo').string();
console.log('foo was:', fooValue);
const allFValues = await client.getAll().prefix('f').keys();
console.log('all our keys starting with "f":', allFValues);
await client.delete().all();
})();
API Documentation
Our TypeDoc docs are available here.
Our test cases are also readable.
Running tests
$ npm install
$ cd src/test/containers/3.2 && docker-compose up
$ npm test
$ docker-compose down
Contributing
Running tests for this module requires running an etcd3 server locally. The tests try to use the default port initially, and you can configure this by setting the ETCD_ADDR
environment variable, like export ETCD_ADDR=localhost:12345
.
This project has adopted the Microsoft Open Source Code of Conduct. For more information see the Code of Conduct FAQ or contact opencode@microsoft.com with any additional questions or comments.
Type aliases
CallContext
Call
Context: { isStream: false; method: "range"; params: IRangeRequest; service: "KV" } | { isStream: false; method: "put"; params: IPutRequest; service: "KV" } | { isStream: false; method: "deleteRange"; params: IDeleteRangeRequest; service: "KV" } | { isStream: false; method: "txn"; params: ITxnRequest; service: "KV" } | { isStream: false; method: "compact"; params: ICompactionRequest; service: "KV" } | { isStream: true; method: "watch"; service: "Watch" } | { isStream: false; method: "leaseGrant"; params: ILeaseGrantRequest; service: "Lease" } | { isStream: false; method: "leaseRevoke"; params: ILeaseRevokeRequest; service: "Lease" } | { isStream: true; method: "leaseKeepAlive"; service: "Lease" } | { isStream: false; method: "leaseTimeToLive"; params: ILeaseTimeToLiveRequest; service: "Lease" } | { isStream: false; method: "leaseLeases"; service: "Lease" } | { isStream: false; method: "memberAdd"; params: IMemberAddRequest; service: "Cluster" } | { isStream: false; method: "memberRemove"; params: IMemberRemoveRequest; service: "Cluster" } | { isStream: false; method: "memberUpdate"; params: IMemberUpdateRequest; service: "Cluster" } | { isStream: false; method: "memberList"; params: IMemberListRequest; service: "Cluster" } | { isStream: false; method: "memberPromote"; params: IMemberPromoteRequest; service: "Cluster" } | { isStream: false; method: "alarm"; params: IAlarmRequest; service: "Maintenance" } | { isStream: false; method: "status"; service: "Maintenance" } | { isStream: false; method: "defragment"; service: "Maintenance" } | { isStream: false; method: "hash"; service: "Maintenance" } | { isStream: false; method: "hashKV"; params: IHashKVRequest; service: "Maintenance" } | { isStream: true; method: "snapshot"; service: "Maintenance" } | { isStream: false; method: "moveLeader"; params: IMoveLeaderRequest; service: "Maintenance" } | { isStream: false; method: "downgrade"; params: IDowngradeRequest; service: "Maintenance" } | { isStream: false; method: "authEnable"; service: "Auth" } | { isStream: false; method: "authDisable"; service: "Auth" } | { isStream: false; method: "authStatus"; service: "Auth" } | { isStream: false; method: "authenticate"; params: IAuthenticateRequest; service: "Auth" } | { isStream: false; method: "userAdd"; params: IAuthUserAddRequest; service: "Auth" } | { isStream: false; method: "userGet"; params: IAuthUserGetRequest; service: "Auth" } | { isStream: false; method: "userList"; service: "Auth" } | { isStream: false; method: "userDelete"; params: IAuthUserDeleteRequest; service: "Auth" } | { isStream: false; method: "userChangePassword"; params: IAuthUserChangePasswordRequest; service: "Auth" } | { isStream: false; method: "userGrantRole"; params: IAuthUserGrantRoleRequest; service: "Auth" } | { isStream: false; method: "userRevokeRole"; params: IAuthUserRevokeRoleRequest; service: "Auth" } | { isStream: false; method: "roleAdd"; params: IAuthRoleAddRequest; service: "Auth" } | { isStream: false; method: "roleGet"; params: IAuthRoleGetRequest; service: "Auth" } | { isStream: false; method: "roleList"; service: "Auth" } | { isStream: false; method: "roleDelete"; params: IAuthRoleDeleteRequest; service: "Auth" } | { isStream: false; method: "roleGrantPermission"; params: IAuthRoleGrantPermissionRequest; service: "Auth" } | { isStream: false; method: "roleRevokePermission"; params: IAuthRoleRevokePermissionRequest; service: "Auth" }
CallOptionsFactory
Call
OptionsFactory: CallOptions | ((context: CallContext) => CallOptions)
IErrorCtor
IErrorCtor: {}
IPermissionRequest
IPermission
Request: { permission: keyof typeof Permission; range: Range } | { key: Buffer | string; permission: keyof typeof Permission }
Rangable
Rangable
: Range | string | Buffer | { end
: string | Buffer; start
: string | Buffer } | { prefix
: string | Buffer }
Variables
Const RecoverableError
RecoverableError: unique symbol = Symbol('RecoverableError')
Const ResignedCampaign
ResignedCampaign: unique symbol = Symbol('ResignedCampaign')
Const UnsetCurrent
UnsetCurrent: unique symbol = Symbol('unset')
Const emptyBuffer
emptyBuffer: Buffer = Buffer.from([])
Const emptyKey
emptyKey: Buffer = Buffer.from([])
Const etcdserverpb
etcdserverpb: {} = services.etcdserverpb as { [service: string]: typeof grpc.Client }
Type declaration
-
[service: string]: typeof Client
Const grpcCodeToError
grpc
CodeToError: Map<number, IErrorCtor> = new Map<number, IErrorCtor>([[1, GRPCCancelledError],[2, GRPCUnknownError],[3, GRPCInvalidArgumentError],[4, GRPCDeadlineExceededError],[5, GRPCNotFoundError],[6, GRPCAlreadyExistsError],[7, EtcdPermissionDeniedError],[8, GRPCResourceExhastedError],[9, GRPCFailedPreconditionError],[10, GRPCAbortedError],[11, GRPCOutOfRangeError],[12, GRPCNotImplementedError],[13, GRPCInternalError],[14, GRPCUnavailableError],[15, GRPCDataLossError],[16, GRPCUnauthenticatedError],])
Const grpcMessageToError
grpc
MessageToError: Map<string, IErrorCtor> = new Map<string, IErrorCtor>([['etcdserver: role name already exists', EtcdRoleExistsError],['etcdserver: user name already exists', EtcdUserExistsError],['etcdserver: role is not granted to the user', EtcdRoleNotGrantedError],['etcdserver: role name not found', EtcdRoleNotFoundError],['etcdserver: user name not found', EtcdUserNotFoundError],['etcdserver: authentication failed, invalid user ID or password', EtcdAuthenticationFailedError],['etcdserver: permission denied', EtcdPermissionDeniedError],['etcdserver: invalid auth token', EtcdInvalidAuthTokenError],['etcdserver: requested lease not found', EtcdLeaseInvalidError],])
Const packageDefinition
packageDefinition: PackageDefinition = loadSync(`${__dirname}/../proto/rpc.proto`, {keepCase: true,longs: String,enums: String,defaults: true,oneofs: true,})
Const secureProtocolPrefix
secureProtocolPrefix: "https:" = "https:"
Const services
services: GrpcObject = grpc.loadPackageDefinition(packageDefinition)
Const zeroKey
zeroKey: Buffer = Buffer.from([0])
Functions
assertWithin
- assertWithin<T>(map: T, value: keyof T, thing: string): void
-
Type parameters
Parameters
-
map: T
-
value: keyof T
-
thing: string
Returns void
castGrpcError
- castGrpcError<T>(err: T): Error
-
Type parameters
Parameters
castGrpcErrorMessage
- castGrpcErrorMessage(message: string): Error
compare
- compare(a: Buffer, b: Buffer): number
-
Parameters
Returns number
debounce
- debounce(duration: number, fn: () => void): wrapper
-
Parameters
-
duration: number
-
fn: () => void
Returns wrapper
Const defaultCircuitBreaker
- defaultCircuitBreaker(): CircuitBreakerPolicy
-
Returns CircuitBreakerPolicy
delay
- delay(duration: number): Promise<void>
-
Parameters
Returns Promise<void>
endRangeForPrefix
- endRangeForPrefix(prefix: Buffer): Buffer
-
Parameters
Returns Buffer
forOwn
- forOwn<T>(obj: T, iterator: <K>(value: T[K], key: K) => void): void
-
Type parameters
Parameters
-
obj: T
-
iterator: <K>(value: T[K], key: K) => void
-
- <K>(value: T[K], key: K): void
-
Type parameters
Parameters
Returns void
Returns void
Const getDeferred
- getDeferred<T>(): { promise: Promise<T>; reject: (error: unknown) => void; resolve: (value: T) => void }
-
Type parameters
Returns { promise: Promise<T>; reject: (error: unknown) => void; resolve: (value: T) => void }
-
promise: Promise<T>
-
reject: (error: unknown) => void
-
resolve: (value: T) => void
getMatchingGrpcError
- getMatchingGrpcError(message: string): IErrorCtor | undefined
Const isRecoverableError
- isRecoverableError(error: Error): boolean
-
Parameters
Returns boolean
keyValueToResponse
- keyValueToResponse(key: string | Buffer, value?: Buffer): IRangeResponse
-
Parameters
-
key: string | Buffer
-
Optional value: Buffer
leaseExpired
-
Parameters
Returns boolean
minBy
- minBy<T>(items: T[], prop: (x: T) => number): T[]
-
Type parameters
Parameters
-
items: T[]
-
prop: (x: T) => number
-
-
Parameters
Returns number
Returns T[]
onceEvent
- onceEvent(emitter: EventEmitter, ...events: string[]): Promise<any>
-
Parameters
-
emitter: EventEmitter
-
Rest ...events: string[]
Returns Promise<any>
rangableIsPrefix
- rangableIsPrefix(r: Rangable): r is { prefix: string | Buffer }
-
Parameters
Returns r is { prefix: string | Buffer }
removeProtocolPrefix
- removeProtocolPrefix(name: string): string
-
Parameters
Returns string
Const resolveCallOptions
- resolveCallOptions(callOptions: CallOptions | undefined, defaultOptions: undefined | CallOptionsFactory, context: CallContext): CallOptions | undefined
-
Parameters
-
callOptions: CallOptions | undefined
-
-
Returns CallOptions | undefined
rewriteErrorName
- rewriteErrorName(str: string, ctor: {}): string
-
Parameters
Returns string
runServiceCall
- runServiceCall(client: Client, metadata: Metadata, options: CallOptions | undefined, method: string, payload: unknown): Promise<any>
-
Parameters
-
client: Client
-
metadata: Metadata
-
options: CallOptions | undefined
-
method: string
-
payload: unknown
Returns Promise<any>
sample
-
Type parameters
Parameters
Returns T
throwIfError
- throwIfError<T>(value: T | Error): T
-
Type parameters
Parameters
Returns T
toBuffer
- toBuffer(input: string | Buffer | number): Buffer
-
Parameters
-
input: string | Buffer | number
Returns Buffer
waitForDelete
- waitForDelete(namespace: Namespace, key: Buffer, rev: string): Promise<void>
-
Parameters
Returns Promise<void>
waitForDeletes
- waitForDeletes(namespace: Namespace, keys: Buffer[]): Promise<void>
-
Parameters
Returns Promise<void>
Object literals
Const Services
Services: object
Const comparator
comparator: object
Const compareTarget
compareTarget: object
Create
Create: "create_revision" = "create_revision"
Lease
Lease: "lease" = "lease"
Mod
Mod: "mod_revision" = "mod_revision"
Value
Value: "value" = "value"
Version
Version: "version" = "version"
Const operationNames
operationNames: object
IPermission can be used to grant a certain role in etcd access to a certain key range, or prefix.