From 358d316e06133a24c2594e5eabbf52a001de3ad6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9o=20Crevon?= Date: Wed, 20 Mar 2024 11:41:11 +0100 Subject: [PATCH] Refactor README to rely on official documentation more (#93) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Refactor drop outdated exhaustives examples from README * Revamp wording of readme to rely more on the official documentation * Update README.md Co-authored-by: Daniel González Lopes --------- Co-authored-by: Daniel González Lopes --- README.md | 367 +++--------------------------------------------------- 1 file changed, 18 insertions(+), 349 deletions(-) diff --git a/README.md b/README.md index dbe45a3..489e324 100644 --- a/README.md +++ b/README.md @@ -1,36 +1,26 @@ # k6-jslib-aws -A library enabling users to interact with AWS resources for k6.io +A library enabling users to interact with AWS resources within k6 scripts. -This is an AWS client library for k6. It intends to allow interacting with a subset of AWS services in the context of k6 load test script. +This AWS client library for k6 facilitates interactions with a subset of AWS services in the context of k6 load testing scripts. -## Supported features +Extensive documentation and examples for each of these clients can be found in the [k6 documentation](https://grafana.com/docs/k6/latest/javascript-api/jslib/aws/). Please refer to the documentation for detailed information on how to use the library. -At the moment, this library provides the following: +## Supported services and features -- `S3Client`: allows to list buckets and bucket's objects, as well as uploading, downloading, and deletion of objects. -- `SecretsManager`: allows to list, get, create, update and delete secrets from the AWS secrets manager service. -- `SQS`: allows to list queues and send messages from AWS SQS. -- `KMS`: allows to list KMS keys and generate a unique symmetric data key for use outside of AWS KMS -- `SSM`: allows to retrieve a parameter from AWS Systems Manager -- `Kinesis`: allows to list streams, create streams, put records, list shards, get shard iterators, and get records from AWS Kinesis. -- `EventBridge`: allows to put events to AWS EventBridge. -- `Lambda`: allows to invoke functions in AWS Lambda. -- `V4 signature`: allows to sign requests to amazon AWS services -- `KinesisClient`: allows all APIs for Kinesis available by AWS. +- [`EventBridge`](https://grafana.com/docs/k6/latest/javascript-api/jslib/aws/eventbridgeclient/): allows to put events to AWS EventBridge. +- [`Kinesis`](./examples/kinesis.js): allows to list streams, create streams, put records, list shards, get shard iterators, and get records from AWS Kinesis. +- [`KMS`](https://grafana.com/docs/k6/latest/javascript-api/jslib/aws/kmsclient/): allows to list KMS keys and generate a unique symmetric data key for use outside of AWS KMS +- [`Lambda`](./examples/lambda.js): allows to invoke functions in AWS Lambda. +- [`S3Client`](https://grafana.com/docs/k6/latest/javascript-api/jslib/aws/s3client/): allows to list buckets and bucket's objects, as well as uploading, downloading, and deletion of objects. +- [`SecretsManager`](https://grafana.com/docs/k6/latest/javascript-api/jslib/aws/secretsmanagerclient/): allows to list, get, create, update and delete secrets from the AWS secrets manager service. +- [`SQS`](https://grafana.com/docs/k6/latest/javascript-api/jslib/aws/sqsclient/): allows to list queues and send messages from AWS SQS. +- [`SSM`](https://grafana.com/docs/k6/latest/javascript-api/jslib/aws/systemsmanagerclient/): allows to retrieve a parameter from AWS Systems Manager +- [`V4 signature`](https://grafana.com/docs/k6/latest/javascript-api/jslib/aws/signaturev4/): allows to sign requests to amazon AWS services -## Want to contribute? - -We welcome contributions from the community! Please read our [contributing guide](CONTRIBUTING.md) and [code of conduct](CODE_OF_CONDUCT.md) before getting started. ## Demo -### S3 - -Consult the `S3Client` [dedicated k6 documentation page](https://k6.io/docs/javascript-api/jslib/aws/s3client) for more details on its methods and how to use it. - -### Practical example - ```javascript import { check } from 'k6' import exec from 'k6/execution' @@ -91,342 +81,21 @@ export async function handleSummary(data) { } ``` -### Secrets Manager - -Consult the `SecretsManagerClient` [dedicated k6 documentation page](https://k6.io/docs/javascript-api/jslib/aws/secretsmanagerclient) for more details on its methods and how to use it. - -```javascript -import exec from 'k6/execution' - -import { AWSConfig, SecretsManagerClient } from 'https://jslib.k6.io/aws/0.11.0/secrets-manager.js' - -const awsConfig = new AWSConfig( - __ENV.AWS_REGION, - __ENV.AWS_ACCESS_KEY_ID, - __ENV.AWS_SECRET_ACCESS_KEY -) - -const secretsManager = new SecretsManagerClient(awsConfig) -const testSecretName = 'jslib-test-secret' -const testSecretValue = 'jslib-test-value' - -export default async function () { - // Let's make sure our test secret is created - const testSecret = await secretsManager.createSecret( - testSecretName, - testSecretValue, - 'this is a test secret, delete me.' - ) - - // List the secrets the AWS authentication configuration - // gives us access to, and verify the creation was successful. - const secrets = await secretsManager.listSecrets() - if (!secrets.filter((s) => s.name === testSecret.name).length == 0) { - exec.test.abort('test secret not found') - } - - // Now that we know the secret exist, let's update its value - const newTestSecretValue = 'new-test-value' - await secretsManager.putSecretValue(testSecretName, newTestSecretValue) - - // Let's get its value and verify it was indeed updated - const updatedSecret = await secretsManager.getSecret(testSecretName) - if (updatedSecret.secretString !== newTestSecretValue) { - exec.test.abort('unable to update test secret') - } - - // Finally, let's delete our test secret and verify it worked - await secretsManager.deleteSecret(updatedSecret.name, { noRecovery: true }) -} -``` - -### SQS - -Consult the `SQSClient` [dedicated k6 documentation page](https://k6.io/docs/javascript-api/jslib/aws/sqsclient) for more details on its methods and how to use it. - -```javascript -import { check } from 'k6' -import exec from 'k6/execution' -import http from 'k6/http' - -import { AWSConfig, SQSClient } from 'https://jslib.k6.io/aws/0.11.0/sqs.js' - -const awsConfig = new AWSConfig({ - region: __ENV.AWS_REGION, - accessKeyId: __ENV.AWS_ACCESS_KEY_ID, - secretAccessKey: __ENV.AWS_SECRET_ACCESS_KEY, - sessionToken: __ENV.AWS_SESSION_TOKEN, -}) - -const sqs = new SQSClient(awsConfig) -const testQueue = 'https://sqs.us-east-1.amazonaws.com/000000000/test-queue' - -export default async function () { - // If our test queue does not exist, abort the execution. - const queuesResponse = await sqs.listQueues() - if (queuesResponse.queueUrls.filter((q) => q === testQueue).length == 0) { - exec.test.abort() - } - - // Send message to test queue - await sqs.sendMessage(testQueue, JSON.stringify({ value: '123' })) - - // Send message with attributes to test queue - await sqs.sendMessage(testQueue, JSON.stringify({ value: '123' }), { - messageAttributes: { - 'my-attribute': { - type: 'String', - value: 'my-attribute-value' - } - } - }) -} -``` - -### KMS - -Consult the `KMS` [dedicated k6 documentation page](https://k6.io/docs/javascript-api/jslib/aws/kms) for more details on its methods and how to use it. - -```javascript -import exec from 'k6/execution' - -import { AWSConfig, KMSClient } from '../dist/kms.js' - -const awsConfig = new AWSConfig({ - region: __ENV.AWS_REGION, - accessKeyId: __ENV.AWS_ACCESS_KEY_ID, - secretAccessKey: __ENV.AWS_SECRET_ACCESS_KEY, -}) - -const KMS = new KMSClient(awsConfig) -const KeyId = 'alias/TestKey' - -export default async function () { - // Currently, the keys need to be created before hand - - // First let's list the keys we have available - const keys = await KMS.listKeys() - if (keys.length == 0) { - exec.test.abort('test keys not found') - } - - const key = keys.filter((s) => s.keyId === KeyId) - if (!key) { - exec.test.abort('target test key not found') - } - - //Run generateDataKey call on the key, with the default 32 byte size - const dataKey = await KMS.generateDataKey(key.keyId) - if (dataKey.ciphertextBlobText == undefined) { - exec.test.abort('data key not generated') - } -} -``` - -### SSM - -Consult the `SystemsManagerClient` [dedicated k6 documentation page](https://k6.io/docs/javascript-api/jslib/aws/systemsmanagerclient) for more details on its methods and how to use it. - -```javascript -import exec from 'k6/execution' - -import { AWSConfig, SystemsManagerClient } from 'https://jslib.k6.io/aws/0.11.0/ssm.js' - -const awsConfig = new AWSConfig({ - region: __ENV.AWS_REGION, - accessKeyId: __ENV.AWS_ACCESS_KEY_ID, - secretAccessKey: __ENV.AWS_SECRET_ACCESS_KEY, - sessionToken: __ENV.AWS_SESSION_TOKEN, -}) - -const systemsManager = new SystemsManagerClient(awsConfig) -const testParameterName = 'jslib-test-parameter' -const testParameterValue = 'jslib-test-value' -const testParameterSecretName = 'jslib-test-parameter-secret' -// this value was created with --type SecureString -const testParameterSecretValue = 'jslib-test-secret-value' - -export default async function () { - // Currently the parameter needs to be created before hand - - // Let's get its value - // getParameter returns an parameter object: e.g. {parameter: {name: string, value: string...}} - const parameter = await systemsManager.getParameter(testParameterName) - if (parameter.value !== testParameterValue) { - exec.test.abort('test parameter not found') - } - - // Let's get the secret value with decryption - // destructure the parameter object to get to the values you want - const { - parameter: { value: encryptedParameterValue }, - } = systemsManager.getParameter(testParameterSecretName, true) - if (encryptedParameterValue !== testParameterSecretValue) { - exec.test.abort('encrypted test parameter not found') - } -} -``` - -### Kinesis - -Consult the `KinesisClient` [dedicated k6 documentation page](https://k6.io/docs/javascript-api/jslib/aws/kinesisclient) for more details on its methods and how to use it. - -```javascript -import exec from 'k6/execution' -import encoding from 'k6/encoding' -import { fail } from 'k6' - -import { AWSConfig, KinesisClient } from 'https://jslib.k6.io/aws/0.11.0/kinesis.js' - -const awsConfig = new AWSConfig({ - region: __ENV.AWS_REGION, - accessKeyId: __ENV.AWS_ACCESS_KEY_ID, - secretAccessKey: __ENV.AWS_SECRET_ACCESS_KEY, - sessionToken: __ENV.AWS_SESSION_TOKEN, -}) -const kinesis = new KinesisClient(awsConfig) - -export default async function () { - // List the streamds the AWS authentication configuration - // gives us access to. - const streams = await kinesis.listStreams() - - if (streams.streamNames.filter((s) => s === dummyStream).length == 0) { - fail(`Stream ${dummyStream} does not exist`) - } - - // Create our test stream - await kinesis.createStream(dummyStream, { - shardCount: 10, - streamModeDetails: { - streamMode: 'PROVISIONED', - }, - }) - - // Put some records in it - const records = await kinesis.putRecords({ - streamName: dummyStream, - Records: [ - { - data: encoding.b64encode(JSON.stringify({ this: 'is', a: 'test' })), - partitionKey: 'partitionKey1', - }, - { - data: encoding.b64encode(JSON.stringify([{ this: 'is', second: 'test' }])), - partitionKey: 'partitionKey2', - }, - ], - }) - - // List the streams' shards - const shards = await kinesis.listShards(dummyStream).shards.map((shard) => shard.id) - - // For each shard, read all the data - shards.map(async (shard) => { - const iterator = await kinesis.getShardIterator(dummyStream, shardId, `TRIM_HORIZON`) - - while (true) { - const res = await kinesis.getRecords({ shardIterator: iterator }) - iterator = res.nextShardIterator - - if (!res.millisBehindLatest || res.millisBehindLatest == `0`) { - break - } - } - }) - - // Delete the stream - await kinesis.deleteStream({ streamName: dummyStream }) -} -``` - -### EventBridge - -Consult the `EventBridgeClient` [dedicated k6 documentation page](https://k6.io/docs/javascript-api/jslib/aws/eventbridgeclient) for more details on its methods and how to use it. - -```javascript -import { AWSConfig, EventBridgeClient } from 'https://jslib.k6.io/aws/0.11.0/event-bridge.js' - -const awsConfig = new AWSConfig({ - region: __ENV.AWS_REGION, - accessKeyId: __ENV.AWS_ACCESS_KEY_ID, - secretAccessKey: __ENV.AWS_SECRET_ACCESS_KEY, - sessionToken: __ENV.AWS_SESSION_TOKEN, -}) - -const eventBridge = new EventBridgeClient(awsConfig) - -export default async function () { - const eventDetails = { - Source: 'my.custom.source', - Detail: { key1: 'value1', key2: 'value2' }, - DetailType: 'MyDetailType', - Resources: ['arn:aws:resource1'], - } - - const input = { - Entries: [eventDetails], - } - - try { - await eventBridge.putEvents(input) - } catch (error) { - console.error(`Failed to put events: ${error.message}`) - } -} -``` - -### Lambda - -Consult the `LambdaClient` [dedicated k6 documentation page](https://k6.io/docs/javascript-api/jslib/aws/lambdaclient) for more details on its methods and how to use it. - -```javascript -import { AWSConfig, LambdaClient } from 'https://jslib.k6.io/aws/0.11.0/lambda.js' -import { check } from 'k6'; - -const awsConfig = new AWSConfig({ - region: __ENV.AWS_REGION, - accessKeyId: __ENV.AWS_ACCESS_KEY_ID, - secretAccessKey: __ENV.AWS_SECRET_ACCESS_KEY, - sessionToken: __ENV.AWS_SESSION_TOKEN, -}) - -const lambdaClient = new LambdaClient(awsConfig) - -export default async function () { - const response = await lambdaClient.invoke('add-numbers', JSON.stringify({x: 1, y: 2})) - - check(response, { - 'status is 200': (r) => r.statusCode === 200, - 'payload is 3': (r) => r.payload === 3, - }) -} - -``` - -## Development - -### Contributing +## Want to contribute? -The scope of this library has been kept minimal and limited to the use cases we, and our clients, need. If the library doesn't cater to your needs just yet, feel free to add it, and open a pull-request. We welcome contributions. +The scope of this library is intentionally minimal, focusing on the use cases needed by us and our clients. If the library doesn't yet meet your needs, feel free to extend it and open a pull request. Contributions are welcome. ### Build ```bash -# Install the local dependencies +# Install local dependencies npm install -# Bundle it in preparation for a publication +# Bundle the library in preparation for publication npm run webpack # Run the tests npm test ``` -For further details, take a look at [CONTRIBUTING.md](CONTRIBUTING.md). - -## Maintainers - -k6-jslib-aws is developped by the k6 core development team. Maintainers of this jslib specifically are the following: - -- Théo Crevon, core k6 developer [@oleiade](https://github.com/oleiade/) +For more details, refer to [CONTRIBUTING.md](./CONTRIBUTING.md).