@mittwald/kubernetes
Advanced tools
Comparing version 2.3.4 to 2.5.0
@@ -19,4 +19,4 @@ import { IKubernetesRESTClient } from "./client"; | ||
constructor(restClient: IKubernetesRESTClient, registry: Registry); | ||
private nc<R, K, V, O>(apiBaseURL, resourceBaseURL); | ||
private c<R, K, V, O>(apiBaseURL, resourceBaseURL); | ||
private nc; | ||
private c; | ||
extend<C>(name: string, customResourceAPI: C): this & C; | ||
@@ -23,0 +23,0 @@ apiextensions(): APIExtensionsAPI; |
@@ -1,2 +0,2 @@ | ||
import { Store } from "./store"; | ||
import { ObservableStore, Store } from "./store"; | ||
import { MetadataObject } from "../types/meta"; | ||
@@ -11,6 +11,6 @@ import { IResourceClient } from "../resource"; | ||
private resource; | ||
private labelSelector; | ||
readonly store: Store<O>; | ||
private labelSelector?; | ||
readonly store: ObservableStore<O>; | ||
constructor(resource: IResourceClient<R, any, any, O>, labelSelector?: LabelSelector | undefined, store?: Store<O>); | ||
start(): Controller; | ||
} |
@@ -9,3 +9,3 @@ "use strict"; | ||
this.labelSelector = labelSelector; | ||
this.store = store || new store_1.InMemoryStore(); | ||
this.store = new store_1.ObservableStoreDecorator(store || new store_1.InMemoryStore()); | ||
} | ||
@@ -12,0 +12,0 @@ start() { |
@@ -8,2 +8,17 @@ import { MetadataObject } from "../types/meta"; | ||
} | ||
export interface ObservableStore<R extends MetadataObject> extends Store<R> { | ||
onStoredOrUpdated(fn: (obj: R) => any): void; | ||
onRemoved(fn: (obj: R) => any): void; | ||
} | ||
export declare class ObservableStoreDecorator<R extends MetadataObject> implements ObservableStore<R> { | ||
private inner; | ||
private onStoreHandlers; | ||
private onRemoveHandlers; | ||
constructor(inner: Store<R>); | ||
onStoredOrUpdated(fn: (obj: R) => any): void; | ||
onRemoved(fn: (obj: R) => any): void; | ||
get(namespace: string, name: string): Promise<R | undefined>; | ||
pull(obj: R): void; | ||
store(obj: R): void; | ||
} | ||
export declare class InMemoryStore<R extends MetadataObject> implements Store<R> { | ||
@@ -10,0 +25,0 @@ private objects; |
@@ -11,2 +11,27 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
class ObservableStoreDecorator { | ||
constructor(inner) { | ||
this.inner = inner; | ||
this.onStoreHandlers = []; | ||
this.onRemoveHandlers = []; | ||
} | ||
onStoredOrUpdated(fn) { | ||
this.onStoreHandlers.push(fn); | ||
} | ||
onRemoved(fn) { | ||
this.onRemoveHandlers.push(fn); | ||
} | ||
get(namespace, name) { | ||
return this.inner.get(namespace, name); | ||
} | ||
pull(obj) { | ||
this.inner.pull(obj); | ||
this.onRemoveHandlers.forEach(fn => fn(obj)); | ||
} | ||
store(obj) { | ||
this.inner.store(obj); | ||
this.onRemoveHandlers.forEach(fn => fn(obj)); | ||
} | ||
} | ||
exports.ObservableStoreDecorator = ObservableStoreDecorator; | ||
class InMemoryStore { | ||
@@ -13,0 +38,0 @@ constructor() { |
@@ -11,3 +11,3 @@ import { IKubernetesRESTClient, WatchResult } from "./client"; | ||
constructor(inner: IKubernetesRESTClient, registry: Registry); | ||
private wrap(method, fn); | ||
private wrap; | ||
post<R>(url: string, body: any): Promise<R>; | ||
@@ -14,0 +14,0 @@ put<R>(url: string, body: any): Promise<R>; |
@@ -6,5 +6,2 @@ import { IKubernetesClientConfig } from "./config"; | ||
export declare type RequestMethod = "GET" | "POST" | "PUT" | "PATCH" | "DELETE"; | ||
export interface IKubernetesRESTClientOptions { | ||
debugFn: (msg: string) => any; | ||
} | ||
export interface WatchOptions { | ||
@@ -30,5 +27,4 @@ labelSelector?: LabelSelector; | ||
private config; | ||
private opts; | ||
constructor(config: IKubernetesClientConfig, opts?: Partial<IKubernetesRESTClientOptions>); | ||
private request<R>(url, body?, method?, additionalOptions?); | ||
constructor(config: IKubernetesClientConfig); | ||
private request; | ||
post<R = any>(url: string, body: any): Promise<R>; | ||
@@ -35,0 +31,0 @@ put<R = any>(url: string, body: any): Promise<R>; |
@@ -6,11 +6,7 @@ "use strict"; | ||
const meta_1 = require("./types/meta"); | ||
const debug = require("debug")("k8s:client"); | ||
const defaultRESTClientOptions = { | ||
debugFn: () => { return; }, | ||
}; | ||
const debug = require("debug")("kubernetes:client"); | ||
const joinURL = (left, right) => (left + "/" + right).replace(/([^:])(\/\/)/g, "$1/"); | ||
class KubernetesRESTClient { | ||
constructor(config, opts = {}) { | ||
constructor(config) { | ||
this.config = config; | ||
this.opts = Object.assign({}, defaultRESTClientOptions, opts); | ||
} | ||
@@ -30,3 +26,3 @@ request(url, body, method = "POST", additionalOptions = {}) { | ||
opts = Object.assign({}, opts, additionalOptions); | ||
this.opts.debugFn(`executing ${method} request on ${opts.url}`); | ||
debug(`executing ${method} request on ${opts.url}`); | ||
request(opts, (err, response, responseBody) => { | ||
@@ -41,3 +37,3 @@ if (err) { | ||
} | ||
this.opts.debugFn(`${method} request on ${opts.url} succeeded with status ${response.statusCode}: ${responseBody}`); | ||
debug(`${method} request on ${opts.url} succeeded with status ${response.statusCode}: ${responseBody}`); | ||
res(responseBody); | ||
@@ -74,3 +70,3 @@ }); | ||
let lastVersion = watchOpts.resourceVersion || 0; | ||
this.opts.debugFn(`executing WATCH request on ${absoluteURL} (starting revision ${lastVersion})`); | ||
debug(`executing WATCH request on ${absoluteURL} (starting revision ${lastVersion})`); | ||
return new Promise((res, rej) => { | ||
@@ -87,4 +83,5 @@ const req = request(opts, (err, response, bodyString) => { | ||
if (bodyString.length === 0) { | ||
this.opts.debugFn(`WATCH request on ${url} returned empty response`); | ||
debug(`WATCH request on ${url} returned empty response`); | ||
res({ resourceVersion: lastVersion }); | ||
return; | ||
} | ||
@@ -96,28 +93,26 @@ let body; | ||
catch (err) { | ||
if (bodyString.length > 0) { | ||
const bodyLines = bodyString.split("\n"); | ||
for (const line of bodyLines) { | ||
try { | ||
const parsedLine = JSON.parse(line); | ||
if (parsedLine.type === "ADDED" || parsedLine.type === "MODIFIED" || parsedLine.type === "DELETED") { | ||
const resourceVersion = parseInt(parsedLine.object.metadata.resourceVersion || "0", 10); | ||
if (resourceVersion > lastVersion) { | ||
this.opts.debugFn(`watch: emitting missed ${parsedLine.type} event for ${parsedLine.object.metadata.name}`); | ||
lastVersion = resourceVersion; | ||
onUpdate(parsedLine); | ||
} | ||
const bodyLines = bodyString.split("\n"); | ||
for (const line of bodyLines) { | ||
try { | ||
const parsedLine = JSON.parse(line); | ||
if (parsedLine.type === "ADDED" || parsedLine.type === "MODIFIED" || parsedLine.type === "DELETED") { | ||
const resourceVersion = parseInt(parsedLine.object.metadata.resourceVersion || "0", 10); | ||
if (resourceVersion > lastVersion) { | ||
debug(`watch: emitting missed ${parsedLine.type} event for ${parsedLine.object.metadata.name}`); | ||
lastVersion = resourceVersion; | ||
onUpdate(parsedLine); | ||
} | ||
} | ||
catch (err) { | ||
this.opts.debugFn(`watch: could not parse JSON line '${line}'`); | ||
rej(err); | ||
} | ||
} | ||
res({ resourceVersion: lastVersion }); | ||
return; | ||
catch (err) { | ||
debug(`watch: could not parse JSON line '${line}'`); | ||
rej(err); | ||
return; | ||
} | ||
} | ||
rej(err); | ||
res({ resourceVersion: lastVersion }); | ||
return; | ||
} | ||
if (meta_1.isStatus(body) && body.status === "Failure") { | ||
debug(`watch: failed with status %O`, body); | ||
rej(body.message); | ||
@@ -139,3 +134,3 @@ return; | ||
if (resourceVersion > lastVersion) { | ||
this.opts.debugFn(`watch: emitting ${obj.type} event for ${obj.object.metadata.name}`); | ||
debug(`watch: emitting ${obj.type} event for ${obj.object.metadata.name}`); | ||
lastVersion = resourceVersion; | ||
@@ -162,3 +157,3 @@ onUpdate(obj); | ||
opts = this.config.mapRequestOptions(opts); | ||
this.opts.debugFn(`executing GET request on ${opts.url}`); | ||
debug(`executing GET request on ${opts.url}`); | ||
request(opts, (err, response, body) => { | ||
@@ -185,7 +180,7 @@ if (err) { | ||
} | ||
this.opts.debugFn(`executing GET request on ${opts.url} failed. response body: ${JSON.stringify(body)}`); | ||
debug(`executing GET request on %o failed. response body: %O`, response.statusCode, body); | ||
rej(new Error(body.message)); | ||
return; | ||
} | ||
this.opts.debugFn(`GET request on ${opts.url} succeeded with status ${response.statusCode}: ${body}`); | ||
debug(`GET request on %o succeeded with status %o: %O`, opts.url, response.statusCode, body); | ||
res(body); | ||
@@ -192,0 +187,0 @@ }); |
@@ -1,2 +0,1 @@ | ||
/// <reference types="request" /> | ||
import * as request from "request"; | ||
@@ -3,0 +2,0 @@ import { Config } from "./types/config"; |
@@ -31,9 +31,9 @@ { | ||
"devDependencies": { | ||
"@types/jest": "^21.1.8", | ||
"@types/jest": "^24.0.15", | ||
"@types/nock": "^8.2.1", | ||
"jest": "^21.2.1", | ||
"jest": "^24.8.0", | ||
"nock": "^9.1.3", | ||
"ts-jest": "^21.2.3", | ||
"ts-jest": "^24.0.2", | ||
"tslint": "^5.8.0", | ||
"typescript": "^2.6.2" | ||
"typescript": "~3.4.5" | ||
}, | ||
@@ -60,3 +60,3 @@ "publishConfig": { | ||
}, | ||
"version": "2.3.4" | ||
"version": "2.5.0" | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
2744
149191