presidium 0.16.16 → 0.16.18
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/.eslintrc.js +1 -1
- package/AwsCredentials.js +61 -0
- package/AwsCredentials.test.js +45 -0
- package/DynamoStream.test.js +80 -1
- package/package.json +1 -1
- package/teardown.js +39 -0
- package/teardown.test.js +62 -0
package/.eslintrc.js
CHANGED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
require('rubico/global')
|
|
2
|
+
const fs = require('fs')
|
|
3
|
+
const nodePath = require('path')
|
|
4
|
+
const pathResolve = require('./internal/pathResolve')
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @name AwsCredentials
|
|
8
|
+
*
|
|
9
|
+
* @synopsis
|
|
10
|
+
* ```coffeescript [specscript]
|
|
11
|
+
* AwsCredentials(options {
|
|
12
|
+
* profile?: string,
|
|
13
|
+
* credentialsFileDir?: string,
|
|
14
|
+
* }) -> awsCreds {
|
|
15
|
+
* accessKeyId: string,
|
|
16
|
+
* secretAccessKey: string,
|
|
17
|
+
* }
|
|
18
|
+
*
|
|
19
|
+
* AwsCredentials(profile string) -> awsCreds {
|
|
20
|
+
* accessKeyId: string,
|
|
21
|
+
* secretAccessKey: string,
|
|
22
|
+
* }
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
const AwsCredentials = async function (options = {}) {
|
|
27
|
+
const profile = (
|
|
28
|
+
typeof options == 'string' ? options : options.profile
|
|
29
|
+
) ?? 'default'
|
|
30
|
+
|
|
31
|
+
let credentialsFileDir =
|
|
32
|
+
options.credentialsFileDir ?? pathResolve(process.cwd())
|
|
33
|
+
let lines = ''
|
|
34
|
+
while (credentialsFileDir != '/') {
|
|
35
|
+
const credentialsFilePath =
|
|
36
|
+
pathResolve(credentialsFileDir, '.aws/credentials')
|
|
37
|
+
if (fs.existsSync(credentialsFilePath)) {
|
|
38
|
+
lines = await (
|
|
39
|
+
fs.promises.readFile(credentialsFilePath)
|
|
40
|
+
.then(buffer => `${buffer}`.split('\n'))
|
|
41
|
+
)
|
|
42
|
+
break
|
|
43
|
+
}
|
|
44
|
+
credentialsFileDir = pathResolve(credentialsFileDir, '..')
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const startingLineNumber = lines.findIndex(line => line == `[${profile}]`)
|
|
48
|
+
|
|
49
|
+
const accessKeyId = lines.find(
|
|
50
|
+
(line, index) => index > startingLineNumber
|
|
51
|
+
&& line.startsWith('aws_access_key_id')
|
|
52
|
+
).split(' = ')[1]
|
|
53
|
+
const secretAccessKey = lines.find(
|
|
54
|
+
(line, index) => index > startingLineNumber
|
|
55
|
+
&& line.startsWith('aws_secret_access_key')
|
|
56
|
+
).split(' = ')[1]
|
|
57
|
+
|
|
58
|
+
return { accessKeyId, secretAccessKey }
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
module.exports = AwsCredentials
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
const Test = require('thunk-test')
|
|
2
|
+
const assert = require('assert')
|
|
3
|
+
const fs = require('fs')
|
|
4
|
+
const AwsCredentials = require('./AwsCredentials')
|
|
5
|
+
|
|
6
|
+
const test = new Test('AwsCredentials', async function () {
|
|
7
|
+
try {
|
|
8
|
+
await fs.promises.mkdir(`${__dirname}/../.aws`)
|
|
9
|
+
} catch {
|
|
10
|
+
await fs.promises.rm(`${__dirname}/../.aws`, { recursive: true })
|
|
11
|
+
await fs.promises.mkdir(`${__dirname}/../.aws`)
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
await fs.promises.writeFile(`${__dirname}/../.aws/credentials`, `
|
|
15
|
+
[default]
|
|
16
|
+
aws_access_key_id = AAA
|
|
17
|
+
aws_secret_access_key = FFF
|
|
18
|
+
`.trim())
|
|
19
|
+
|
|
20
|
+
{
|
|
21
|
+
const awsCreds = await AwsCredentials('default')
|
|
22
|
+
assert.equal(awsCreds.accessKeyId, 'AAA')
|
|
23
|
+
assert.equal(awsCreds.secretAccessKey, 'FFF')
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
{
|
|
27
|
+
const awsCreds = await AwsCredentials({ profile: 'default' })
|
|
28
|
+
assert.equal(awsCreds.accessKeyId, 'AAA')
|
|
29
|
+
assert.equal(awsCreds.secretAccessKey, 'FFF')
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
{
|
|
33
|
+
const awsCreds = await AwsCredentials()
|
|
34
|
+
assert.equal(awsCreds.accessKeyId, 'AAA')
|
|
35
|
+
assert.equal(awsCreds.secretAccessKey, 'FFF')
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
await fs.promises.rm(`${__dirname}/../.aws`, { recursive: true })
|
|
39
|
+
}).case()
|
|
40
|
+
|
|
41
|
+
if (process.argv[1] == __filename) {
|
|
42
|
+
test()
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
module.exports = test
|
package/DynamoStream.test.js
CHANGED
|
@@ -38,6 +38,7 @@ const test = Test('DynamoStream', DynamoStream)
|
|
|
38
38
|
table: 'my-table',
|
|
39
39
|
endpoint: 'http://localhost:8000',
|
|
40
40
|
shardIteratorType: 'TRIM_HORIZON',
|
|
41
|
+
shardUpdatePeriod: 1000,
|
|
41
42
|
}, async function (myStream) {
|
|
42
43
|
await myStream.ready
|
|
43
44
|
|
|
@@ -83,7 +84,7 @@ const test = Test('DynamoStream', DynamoStream)
|
|
|
83
84
|
endpoint: 'http://localhost:8000',
|
|
84
85
|
getRecordsLimit: 1,
|
|
85
86
|
getRecordsInterval: 1000,
|
|
86
|
-
shardUpdatePeriod:
|
|
87
|
+
shardUpdatePeriod: 1000,
|
|
87
88
|
shardIteratorType: 'TRIM_HORIZON',
|
|
88
89
|
}, async function (myStream) {
|
|
89
90
|
await myStream.ready
|
|
@@ -129,6 +130,7 @@ const test = Test('DynamoStream', DynamoStream)
|
|
|
129
130
|
table: 'my-table',
|
|
130
131
|
endpoint: 'http://localhost:8000',
|
|
131
132
|
getRecordsLimit: 1,
|
|
133
|
+
shardUpdatePeriod: 1000,
|
|
132
134
|
shardIteratorType: 'TRIM_HORIZON',
|
|
133
135
|
}, async function (myStream) {
|
|
134
136
|
await myStream.ready
|
|
@@ -183,6 +185,7 @@ const test = Test('DynamoStream', DynamoStream)
|
|
|
183
185
|
listStreamsLimit: 1,
|
|
184
186
|
shardIteratorType: 'TRIM_HORIZON',
|
|
185
187
|
debug: true,
|
|
188
|
+
shardUpdatePeriod: 1000,
|
|
186
189
|
}, async function (myStream) {
|
|
187
190
|
await myStream.ready
|
|
188
191
|
|
|
@@ -223,6 +226,82 @@ const test = Test('DynamoStream', DynamoStream)
|
|
|
223
226
|
myStream.close()
|
|
224
227
|
})
|
|
225
228
|
|
|
229
|
+
.case({
|
|
230
|
+
table: 'my-table',
|
|
231
|
+
endpoint: 'http://localhost:8000',
|
|
232
|
+
listStreamsLimit: 1,
|
|
233
|
+
shardIteratorType: 'TRIM_HORIZON',
|
|
234
|
+
debug: true,
|
|
235
|
+
shardUpdatePeriod: 1000,
|
|
236
|
+
}, async function (myStream) {
|
|
237
|
+
await myStream.ready
|
|
238
|
+
|
|
239
|
+
const originalClient = myStream.client
|
|
240
|
+
const alternatingErrorClient = {
|
|
241
|
+
listStreams(options) {
|
|
242
|
+
return originalClient.listStreams(options)
|
|
243
|
+
},
|
|
244
|
+
describeStream(options) {
|
|
245
|
+
return originalClient.describeStream(options)
|
|
246
|
+
},
|
|
247
|
+
getShardIterator(options) {
|
|
248
|
+
return originalClient.getShardIterator(options)
|
|
249
|
+
},
|
|
250
|
+
getRecordsCount: 0,
|
|
251
|
+
getRecords(options) {
|
|
252
|
+
return {
|
|
253
|
+
async promise() {
|
|
254
|
+
if (alternatingErrorClient.getRecordsCount % 2 == 0) {
|
|
255
|
+
const error = new Error('stub error')
|
|
256
|
+
error.retryable = true
|
|
257
|
+
alternatingErrorClient.getRecordsCount += 1
|
|
258
|
+
throw error
|
|
259
|
+
}
|
|
260
|
+
alternatingErrorClient.getRecordsCount += 1
|
|
261
|
+
return originalClient.getRecords(options).promise()
|
|
262
|
+
},
|
|
263
|
+
}
|
|
264
|
+
},
|
|
265
|
+
}
|
|
266
|
+
myStream.client = alternatingErrorClient
|
|
267
|
+
|
|
268
|
+
const table = this.table
|
|
269
|
+
await table.putItem({
|
|
270
|
+
id: '1',
|
|
271
|
+
status: 'waitlist',
|
|
272
|
+
createTime: 1000,
|
|
273
|
+
name: 'George',
|
|
274
|
+
})
|
|
275
|
+
await table.putItem({
|
|
276
|
+
id: '2',
|
|
277
|
+
status: 'waitlist',
|
|
278
|
+
createTime: 1001,
|
|
279
|
+
name: 'geo',
|
|
280
|
+
})
|
|
281
|
+
await table.putItem({
|
|
282
|
+
id: '3',
|
|
283
|
+
status: 'waitlist',
|
|
284
|
+
createTime: 1002,
|
|
285
|
+
name: 'john',
|
|
286
|
+
})
|
|
287
|
+
await table.putItem({
|
|
288
|
+
id: '4',
|
|
289
|
+
status: 'approved',
|
|
290
|
+
createTime: 1003,
|
|
291
|
+
name: 'sally',
|
|
292
|
+
})
|
|
293
|
+
await table.putItem({
|
|
294
|
+
id: '5',
|
|
295
|
+
status: 'approved',
|
|
296
|
+
createTime: 1004,
|
|
297
|
+
name: 'sally',
|
|
298
|
+
})
|
|
299
|
+
|
|
300
|
+
const first5 = await asyncIterableTake(5)(myStream)
|
|
301
|
+
assert.strictEqual(first5.length, 5)
|
|
302
|
+
myStream.close()
|
|
303
|
+
})
|
|
304
|
+
|
|
226
305
|
.case({
|
|
227
306
|
table: 'my-table',
|
|
228
307
|
endpoint: 'http://localhost:8000',
|
package/package.json
CHANGED
package/teardown.js
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
const DynamoTable = require('./DynamoTable')
|
|
2
|
+
const DynamoStream = require('./DynamoStream')
|
|
3
|
+
const ElasticsearchIndex = require('./ElasticsearchIndex')
|
|
4
|
+
const S3Bucket = require('./S3Bucket')
|
|
5
|
+
const KinesisStream = require('./KinesisStream')
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @name teardown
|
|
9
|
+
*
|
|
10
|
+
* @synopsis
|
|
11
|
+
* ```coffeescript [specscript]
|
|
12
|
+
* teardown(
|
|
13
|
+
* dependency DynamoTable|DynamoStream
|
|
14
|
+
* |ElasticsearchIndex|S3Bucket
|
|
15
|
+
* |KinesisStream
|
|
16
|
+
* ) -> Promise<>
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
const teardown = async function (dependency) {
|
|
20
|
+
if (dependency.constructor == DynamoTable) {
|
|
21
|
+
await dependency.delete()
|
|
22
|
+
}
|
|
23
|
+
else if (dependency.constructor == DynamoStream) {
|
|
24
|
+
dependency.close()
|
|
25
|
+
}
|
|
26
|
+
else if (dependency.constructor == ElasticsearchIndex) {
|
|
27
|
+
await dependency.delete()
|
|
28
|
+
}
|
|
29
|
+
else if (dependency.constructor == S3Bucket) {
|
|
30
|
+
await dependency.deleteAllObjects()
|
|
31
|
+
await dependency.delete()
|
|
32
|
+
}
|
|
33
|
+
else if (dependency.constructor == KinesisStream) {
|
|
34
|
+
dependency.close()
|
|
35
|
+
await dependency.delete()
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
module.exports = teardown
|
package/teardown.test.js
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
const Test = require('thunk-test')
|
|
2
|
+
const DynamoTable = require('presidium/DynamoTable')
|
|
3
|
+
const DynamoStream = require('presidium/DynamoStream')
|
|
4
|
+
const ElasticsearchIndex = require('presidium/ElasticsearchIndex')
|
|
5
|
+
const S3Bucket = require('presidium/S3Bucket')
|
|
6
|
+
const KinesisStream = require('presidium/KinesisStream')
|
|
7
|
+
const teardown = require('./teardown')
|
|
8
|
+
|
|
9
|
+
const test = new Test('teardown', async function () {
|
|
10
|
+
const myDynamoTable = new DynamoTable({
|
|
11
|
+
name: 'my_dynamo_table',
|
|
12
|
+
key: [{ a: 'string' }],
|
|
13
|
+
endpoint: 'http://localhost:8000',
|
|
14
|
+
region: 'dynamodblocal',
|
|
15
|
+
})
|
|
16
|
+
await myDynamoTable.ready
|
|
17
|
+
|
|
18
|
+
const myDynamoStream = new DynamoStream({
|
|
19
|
+
table: 'my_dynamo_table',
|
|
20
|
+
endpoint: 'http://localhost:8000',
|
|
21
|
+
region: 'dynamodblocal',
|
|
22
|
+
})
|
|
23
|
+
await myDynamoStream.ready
|
|
24
|
+
|
|
25
|
+
const myElasticsearchIndex = new ElasticsearchIndex({
|
|
26
|
+
node: 'http://localhost:9200/',
|
|
27
|
+
index: 'local_post',
|
|
28
|
+
mappings: {
|
|
29
|
+
a: { type: 'keyword' },
|
|
30
|
+
b: { type: 'keyword' },
|
|
31
|
+
},
|
|
32
|
+
})
|
|
33
|
+
await myElasticsearchIndex.ready
|
|
34
|
+
|
|
35
|
+
const myS3Bucket = new S3Bucket({
|
|
36
|
+
name: 'my-s3-bucket',
|
|
37
|
+
endpoint: 'http://localhost:9000',
|
|
38
|
+
region: 'us-west-1',
|
|
39
|
+
accessKeyId: 'minioadmin',
|
|
40
|
+
secretAccessKey: 'minioadmin',
|
|
41
|
+
})
|
|
42
|
+
await myS3Bucket.ready
|
|
43
|
+
|
|
44
|
+
const myKinesisStream = new KinesisStream({
|
|
45
|
+
name: 'my_kinesis_stream',
|
|
46
|
+
endpoint: 'http://localhost:4567',
|
|
47
|
+
shardIteratorType: 'TRIM_HORIZON',
|
|
48
|
+
})
|
|
49
|
+
await myKinesisStream.ready
|
|
50
|
+
|
|
51
|
+
await teardown(myDynamoTable)
|
|
52
|
+
await teardown(myDynamoStream)
|
|
53
|
+
await teardown(myElasticsearchIndex)
|
|
54
|
+
await teardown(myS3Bucket)
|
|
55
|
+
await teardown(myKinesisStream)
|
|
56
|
+
}).case()
|
|
57
|
+
|
|
58
|
+
if (process.argv[1] == __filename) {
|
|
59
|
+
test()
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
module.exports = teardown
|