@optimizely/opti-cli
Advanced tools
Comparing version 1.0.0-beta.5 to 1.0.0-beta.6
@@ -11,2 +11,3 @@ export declare class LogsCommand { | ||
search?: string[]; | ||
private availability; | ||
logs(): Promise<void>; | ||
@@ -13,0 +14,0 @@ private printLogEntry; |
@@ -15,2 +15,3 @@ "use strict"; | ||
const TerminalSpinner_1 = require("../../lib/TerminalSpinner"); | ||
const Moria_1 = require("../../lib/Moria"); | ||
const Rivendell_1 = require("../../lib/Rivendell"); | ||
@@ -35,2 +36,3 @@ const formatError_1 = require("../../lib/formatError"); | ||
constructor() { | ||
this.availability = ''; | ||
this.printLogEntry = (entry) => { | ||
@@ -75,5 +77,14 @@ console.log(entry.time); | ||
} | ||
this.availability = this.availability ? this.availability : 'us'; | ||
let shard = (await Rivendell_1.Rivendell.shards()).find((_shard) => _shard.id === this.availability); | ||
if (!shard) { | ||
die_1.die('Could not find the specified availability zone.'); | ||
} | ||
else if (shard.id === 'us') { // TODO: shard.is_primary? | ||
// Use Rivendell instead | ||
shard = undefined; | ||
} | ||
try { | ||
if (this.tail) { | ||
await this.tailLogs(fromDate); | ||
await this.tailLogs(fromDate, shard); | ||
} | ||
@@ -83,3 +94,3 @@ else { | ||
try { | ||
await this.dumpLogs(fromDate, this.printLogEntry, toDate); | ||
await this.dumpLogs(fromDate, this.printLogEntry, toDate, shard); | ||
} | ||
@@ -95,3 +106,3 @@ finally { | ||
} | ||
async dumpLogs(from, cb, to) { | ||
async dumpLogs(from, cb, to, shard) { | ||
let result; | ||
@@ -101,3 +112,8 @@ let count = 0; | ||
do { | ||
result = await Rivendell_1.Rivendell.searchLogging(request); | ||
if (shard) { | ||
result = await Moria_1.Moria.searchLogging(request, shard); | ||
} | ||
else { | ||
result = await Rivendell_1.Rivendell.searchLogging(request); | ||
} | ||
result.entries.forEach(cb); | ||
@@ -109,3 +125,3 @@ request.cursor = result.cursor; | ||
} | ||
async tailLogs(from) { | ||
async tailLogs(from, shard) { | ||
const dedupeCache = new Set(); | ||
@@ -127,3 +143,3 @@ let start = from.valueOf(); | ||
start = Math.min(start, end + TAIL_CONFIG.minWindowMs); | ||
await this.dumpLogs(start, callback, end); | ||
await this.dumpLogs(start, callback, end, shard); | ||
spinner.update(chalk_1.default.gray('Waiting for more logs...')); | ||
@@ -186,2 +202,6 @@ setTimeout(query, TAIL_CONFIG.queryIntervalMs); | ||
__decorate([ | ||
oo_cli_1.option('a'), | ||
oo_cli_1.help('The availability zone that will be targeted (default: us)') | ||
], LogsCommand.prototype, "availability", void 0); | ||
__decorate([ | ||
oo_cli_1.command, | ||
@@ -188,0 +208,0 @@ oo_cli_1.help('Fetch app logs') |
@@ -186,3 +186,23 @@ import { AppContext } from './AppContext'; | ||
description: string; | ||
url: string; | ||
} | ||
interface JwtResponse { | ||
jwt: string; | ||
} | ||
interface JwtHeader { | ||
kid: string; | ||
typ: string; | ||
alg: string; | ||
} | ||
interface JwtPayload { | ||
aud: string; | ||
exp: number; | ||
iss: string; | ||
sub: string; | ||
} | ||
interface Jwt { | ||
token: string; | ||
header: JwtHeader; | ||
payload: JwtPayload; | ||
} | ||
function searchAccounts(term: string, shard: string): Promise<Account[]>; | ||
@@ -280,2 +300,3 @@ function whoami(): Promise<Developer>; | ||
function shards(): Promise<Shard[]>; | ||
function jwt(shard: string): Promise<string>; | ||
} |
@@ -245,3 +245,24 @@ "use strict"; | ||
Rivendell.shards = shards; | ||
/** | ||
* Get Moria JWT for this developer. | ||
*/ | ||
let cachedJwt; | ||
async function jwt(shard) { | ||
const now = new Date(); | ||
if (!cachedJwt || cachedJwt.payload.exp * 1000 - now.getTime() <= 60) { | ||
const response = await RivendellApi_1.RivendellApi.get(path(shard, 'tokens/jwt')); | ||
cachedJwt = parseJwt(response.body.jwt); | ||
} | ||
return cachedJwt.token; | ||
} | ||
Rivendell.jwt = jwt; | ||
function parseJwt(token) { | ||
const parts = token.split('.'); | ||
return { | ||
token, | ||
header: JSON.parse(Buffer.from(parts[0], 'base64').toString()), | ||
payload: JSON.parse(Buffer.from(parts[1], 'base64').toString()) | ||
}; | ||
} | ||
})(Rivendell = exports.Rivendell || (exports.Rivendell = {})); | ||
//# sourceMappingURL=Rivendell.js.map |
@@ -165,2 +165,12 @@ { | ||
"multiple": true | ||
}, | ||
{ | ||
"name": "availability", | ||
"key": "availability", | ||
"aliases": [ | ||
"a" | ||
], | ||
"help": "The availability zone that will be targeted (default: us)", | ||
"optional": true, | ||
"multiple": false | ||
} | ||
@@ -790,3 +800,3 @@ ], | ||
"package": { | ||
"version": "1.0.0-beta.5", | ||
"version": "1.0.0-beta.6", | ||
"name": "@optimizely/opti-cli", | ||
@@ -793,0 +803,0 @@ "license": "Apache-2.0", |
{ | ||
"name": "@optimizely/opti-cli", | ||
"version": "1.0.0-beta.5", | ||
"version": "1.0.0-beta.6", | ||
"description": "Optimizely command line interface", | ||
@@ -5,0 +5,0 @@ "repository": "https://github.com/ZaiusInc/opti-cli", |
@@ -8,2 +8,3 @@ import chalk from 'chalk'; | ||
import {TerminalSpinner} from '../../lib/TerminalSpinner'; | ||
import {Moria} from '../../lib/Moria'; | ||
import {Rivendell} from '../../lib/Rivendell'; | ||
@@ -73,2 +74,6 @@ import {formatError} from '../../lib/formatError'; | ||
@option('a') | ||
@help('The availability zone that will be targeted (default: us)') | ||
private availability: string = ''; | ||
@command | ||
@@ -89,9 +94,18 @@ @help('Fetch app logs') | ||
this.availability = this.availability ? this.availability : 'us'; | ||
let shard = (await Rivendell.shards()).find((_shard) => _shard.id === this.availability); | ||
if (!shard) { | ||
die('Could not find the specified availability zone.'); | ||
} else if (shard.id === 'us') { // TODO: shard.is_primary? | ||
// Use Rivendell instead | ||
shard = undefined; | ||
} | ||
try { | ||
if (this.tail) { | ||
await this.tailLogs(fromDate); | ||
await this.tailLogs(fromDate, shard); | ||
} else { | ||
const spinner = new TerminalSpinner().start(''); | ||
try { | ||
await this.dumpLogs(fromDate, this.printLogEntry, toDate); | ||
await this.dumpLogs(fromDate, this.printLogEntry, toDate, shard); | ||
} finally { | ||
@@ -134,3 +148,8 @@ spinner.stop(); | ||
private async dumpLogs(from: Date | number, cb: LogEntryCallback, to?: Date | number): Promise<number> { | ||
private async dumpLogs( | ||
from: Date | number, | ||
cb: LogEntryCallback, | ||
to?: Date | number, | ||
shard?: Rivendell.Shard | ||
): Promise<number> { | ||
let result: LoggingSearchResult; | ||
@@ -140,3 +159,7 @@ let count = 0; | ||
do { | ||
result = await Rivendell.searchLogging(request); | ||
if (shard) { | ||
result = await Moria.searchLogging(request, shard); | ||
} else { | ||
result = await Rivendell.searchLogging(request); | ||
} | ||
result.entries.forEach(cb); | ||
@@ -149,3 +172,3 @@ request.cursor = result.cursor; | ||
private async tailLogs(from: Date) { | ||
private async tailLogs(from: Date, shard?: Rivendell.Shard) { | ||
const dedupeCache: Set<string> = new Set(); | ||
@@ -170,3 +193,3 @@ let start = from.valueOf(); | ||
start = Math.min(start, end + TAIL_CONFIG.minWindowMs); | ||
await this.dumpLogs(start, callback, end); | ||
await this.dumpLogs(start, callback, end, shard); | ||
spinner.update(chalk.gray('Waiting for more logs...')); | ||
@@ -173,0 +196,0 @@ setTimeout(query, TAIL_CONFIG.queryIntervalMs); |
@@ -214,4 +214,28 @@ import {RivendellApi} from './RivendellApi'; | ||
description: string; | ||
url: string; | ||
} | ||
export interface JwtResponse { | ||
jwt: string; | ||
} | ||
export interface JwtHeader { | ||
kid: string; | ||
typ: string; | ||
alg: string; | ||
} | ||
export interface JwtPayload { | ||
aud: string; | ||
exp: number; | ||
iss: string; | ||
sub: string; | ||
} | ||
export interface Jwt { | ||
token: string; | ||
header: JwtHeader; | ||
payload: JwtPayload; | ||
} | ||
function path(shard: string, endpoint: string) { | ||
@@ -424,2 +448,25 @@ return `${shard}/${endpoint}`.replace(/^\//, ''); | ||
} | ||
/** | ||
* Get Moria JWT for this developer. | ||
*/ | ||
let cachedJwt: Jwt; | ||
export async function jwt(shard: string): Promise<string> { | ||
const now = new Date(); | ||
if (!cachedJwt || cachedJwt.payload.exp * 1000 - now.getTime() <= 60) { | ||
const response = await RivendellApi.get<JwtResponse>(path(shard, 'tokens/jwt')); | ||
cachedJwt = parseJwt(response.body.jwt); | ||
} | ||
return cachedJwt.token; | ||
} | ||
function parseJwt(token: string): Jwt { | ||
const parts = token.split('.'); | ||
return { | ||
token, | ||
header: JSON.parse(Buffer.from(parts[0], 'base64').toString()), | ||
payload: JSON.parse(Buffer.from(parts[1], 'base64').toString()) | ||
}; | ||
} | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
446042
243
8750