From b2c8c4684d97e8b907203f0ce5ae89b5630c9890 Mon Sep 17 00:00:00 2001 From: "Daniel (dB.) Doubrovkine" Date: Mon, 16 Dec 2024 14:05:44 -0500 Subject: [PATCH] Added support for using a certificate and key. (#731) Signed-off-by: dblock --- .github/workflows/test-spec.yml | 6 ++ CHANGELOG.md | 3 + DEVELOPER_GUIDE.md | 2 + TESTING_GUIDE.md | 14 ++++ spec/namespaces/security.yaml | 11 +++- spec/schemas/security._common.yaml | 5 ++ tests/plugins/security/.README.md | 1 + tests/plugins/security/.kirk-key.pem | 28 ++++++++ tests/plugins/security/.kirk.pem | 27 ++++++++ tests/plugins/security/api/nodesdn.yaml | 64 +++++++++++++++++++ tests/plugins/security/docker-compose.yml | 13 ++++ tools/src/OpenSearchHttpClient.ts | 19 +++++- .../dump-cluster-spec/dump-cluster-spec.ts | 4 ++ tools/src/tester/test.ts | 4 ++ .../tests/tester/OpenSearchHttpClient.test.ts | 43 +++++++++++++ tools/tests/tester/fixtures/keys/kirk-key.pem | 3 + tools/tests/tester/fixtures/keys/kirk.pem | 3 + 17 files changed, 247 insertions(+), 3 deletions(-) create mode 100644 tests/plugins/security/.README.md create mode 100644 tests/plugins/security/.kirk-key.pem create mode 100644 tests/plugins/security/.kirk.pem create mode 100644 tests/plugins/security/api/nodesdn.yaml create mode 100644 tests/plugins/security/docker-compose.yml create mode 100644 tools/tests/tester/fixtures/keys/kirk-key.pem create mode 100644 tools/tests/tester/fixtures/keys/kirk.pem diff --git a/.github/workflows/test-spec.yml b/.github/workflows/test-spec.yml index c63dde722..d3b495ca1 100644 --- a/.github/workflows/test-spec.yml +++ b/.github/workflows/test-spec.yml @@ -53,6 +53,10 @@ jobs: tests: plugins/workload-management - version: 2.18.0 tests: plugins/analysis + - version: 2.18.0 + tests: plugins/security + cert: tests/plugins/security/.kirk.pem + key: tests/plugins/security/.kirk-key.pem - version: 2.19.0 hub: opensearchstaging ref: '@sha256:4da23e0137b2b67206d23b36fcf0914cc39b3bf19310c782f536e4934b86f6cc' @@ -97,6 +101,8 @@ jobs: --opensearch-version=${{ matrix.entry.version }} \ --coverage coverage/test-spec-coverage-${{ steps.tests.outputs.hash }}.json \ --opensearch-url=${{ matrix.entry.url || 'https://localhost:9200'}} \ + --opensearch-cert=${{ matrix.entry.cert }} \ + --opensearch-key=${{ matrix.entry.key }} \ --tests=tests/${{ matrix.entry.tests || 'default' }} - name: Get Container Logs diff --git a/CHANGELOG.md b/CHANGELOG.md index 4b87969f0..1507d6df2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -33,6 +33,7 @@ Inspired from [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) - Added response schema for `PUT` and `DELETE /_plugins/_transform/{id}` ([#722](https://github.com/opensearch-project/opensearch-api-specification/pull/716)) - Added response schema for `GET /_plugins/_knn/warmup/{index}` ([#717](https://github.com/opensearch-project/opensearch-api-specification/pull/717)) - Added support for multiple test verbs ([#724](https://github.com/opensearch-project/opensearch-api-specification/pull/724)) +- Added support for using a certificate and key in tests ([#731](https://github.com/opensearch-project/opensearch-api-specification/pull/731)) ### Removed - Removed unsupported `_common.mapping:SourceField`'s `mode` field and associated `_common.mapping:SourceFieldMode` enum ([#652](https://github.com/opensearch-project/opensearch-api-specification/pull/652)) @@ -69,6 +70,8 @@ Inspired from [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) - Fixed response schema for `/_render/template` and `/_render/template/{id}` ([#724](https://github.com/opensearch-project/opensearch-api-specification/pull/724)) - Fixed data stream schema numeric property types ([#725](https://github.com/opensearch-project/opensearch-api-specification/pull/725)) - Fixed snapshot status numeric property types ([#729](https://github.com/opensearch-project/opensearch-api-specification/pull/729)) +- Fixed request schema for `PATCH /_plugins/_security/api/nodesdn` ([#731](https://github.com/opensearch-project/opensearch-api-specification/pull/731)) +- Fixed response schema for `GET /_plugins/_security/api/nodesdn/{cluster_name}` ([#731](https://github.com/opensearch-project/opensearch-api-specification/pull/731)) ### Changed - Changed `tasks._common:TaskInfo` and `tasks._common:TaskGroup` to be composed of a `tasks._common:TaskInfoBase` ([#683](https://github.com/opensearch-project/opensearch-api-specification/pull/683)) diff --git a/DEVELOPER_GUIDE.md b/DEVELOPER_GUIDE.md index 9709132fc..ffdc55b65 100644 --- a/DEVELOPER_GUIDE.md +++ b/DEVELOPER_GUIDE.md @@ -243,6 +243,8 @@ The dump-cluster-spec tool connects to an OpenSearch cluster which has the [open - `--opensearch-insecure`: Disable SSL/TLS certificate verification, defaults to performing verification. - `--opensearch-username `: The username to authenticate with the cluster, defaults to `admin`, only used when `--opensearch-password` is set. - `--opensearch-password `: The password to authenticate with the cluster, also settable via the `OPENSEARCH_PASSWORD` environment variable. +- `--opensearch-cert `: The OpenSSL certificate file, also settable via the `OPENSEARCH_CERT` environment variable. +- `--opensearch-key `: The OpenSSL certificate private key, also settable via the `OPENSEARCH_KEY` environment variable. - `--output `: The path to write the dumped spec to, defaults to `/build/opensearch-openapi-CLUSTER.yaml`. **Example** diff --git a/TESTING_GUIDE.md b/TESTING_GUIDE.md index 362f6359f..2812b37b2 100644 --- a/TESTING_GUIDE.md +++ b/TESTING_GUIDE.md @@ -5,6 +5,7 @@ - [Prerequisites](#prerequisites) - [OpenSearch Cluster](#opensearch-cluster) - [Run Tests](#run-tests) + - [Running Spec Tests that Require an Admin Certificate](#running-spec-tests-that-require-an-admin-certificate) - [Running Spec Tests with Amazon OpenSearch](#running-spec-tests-with-amazon-opensearch) - [Common Errors](#common-errors) - [401 Unauthorized](#401-unauthorized) @@ -76,6 +77,19 @@ Want to help with some missing tests? Choose from the remaining paths in the tes npm run test:spec -- --opensearch-insecure --coverage-report ``` +### Running Spec Tests that Require an Admin Certificate + +Some tests may require an admin certificate for authorization. The certificate can be provided wth `--opensearch-cert` and the key with `opensearch-key`. + +For example, run tests in [plugins/security](tests/plugins/security) as follows: +```bash +npm run test:spec--insecure -- \ + --tests tests/plugins/security/api/nodesdn.yaml \ + --opensearch-key tests/plugins/security/kirk-key.pem \ + --opensearch-cert tests/plugins/security/kirk.pem \ + --verbose +``` + ### Running Spec Tests with Amazon OpenSearch Use an Amazon OpenSearch service instance. diff --git a/spec/namespaces/security.yaml b/spec/namespaces/security.yaml index 2a63cd0d9..0a3a44bed 100644 --- a/spec/namespaces/security.yaml +++ b/spec/namespaces/security.yaml @@ -754,6 +754,8 @@ paths: responses: '200': $ref: '#/components/responses/security.update_distinguished_name@200' + '201': + $ref: '#/components/responses/security.update_distinguished_name@201' '400': $ref: '#/components/responses/security.update_distinguished_name@400' '403': @@ -1449,7 +1451,7 @@ components: content: application/json: schema: - $ref: '../schemas/security._common.yaml#/components/schemas/PatchOperation' + $ref: '../schemas/security._common.yaml#/components/schemas/PatchOperations' security.patch_distinguished_names: content: application/json: @@ -1843,7 +1845,7 @@ components: content: application/json: schema: - $ref: '../schemas/security._common.yaml#/components/schemas/DistinguishedNames' + $ref: '../schemas/security._common.yaml#/components/schemas/DistinguishedNamesMap' security.get_distinguished_name@400: content: application/json: @@ -2183,6 +2185,11 @@ components: application/json: schema: $ref: '../schemas/security._common.yaml#/components/schemas/Ok' + security.update_distinguished_name@201: + content: + application/json: + schema: + $ref: '../schemas/security._common.yaml#/components/schemas/Ok' security.update_distinguished_name@400: content: application/json: diff --git a/spec/schemas/security._common.yaml b/spec/schemas/security._common.yaml index c754e2325..ac53b2be7 100644 --- a/spec/schemas/security._common.yaml +++ b/spec/schemas/security._common.yaml @@ -524,6 +524,11 @@ components: type: string description: Message returned as part of CREATED response. + PatchOperations: + type: array + items: + $ref: '#/components/schemas/PatchOperation' + PatchOperation: type: object properties: diff --git a/tests/plugins/security/.README.md b/tests/plugins/security/.README.md new file mode 100644 index 000000000..239ff185d --- /dev/null +++ b/tests/plugins/security/.README.md @@ -0,0 +1 @@ +The demo certs in this directory do get updated from [the security repo](https://github.com/opensearch-project/security/tree/main/bwc-test/src/test/resources/security). The source of truth is [here](https://github.com/opensearch-project/security/blob/main/src/main/java/org/opensearch/security/tools/democonfig/Certificates.java). diff --git a/tests/plugins/security/.kirk-key.pem b/tests/plugins/security/.kirk-key.pem new file mode 100644 index 000000000..fd1728cda --- /dev/null +++ b/tests/plugins/security/.kirk-key.pem @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCVXDgEJQorgfXp +gpY0TgF55bD2xuzxN5Dc9rDfgWxrsOvOloMpd7k6FR71bKWjJi1KptSmM/cDElky +AWYKSfYWGiGxsQ+EQW+6kwCfEOHXQldn+0+JcWqP+osSPjtJfwRvRN5kRqP69MPo +7U0N2kdqenqMWjmG1chDGLRSOEGU5HIBiDxsZtOcvMaJ8b1eaW0lvS+6gFQ80AvB +GBkDDCOHHLtDXBylrZk2CQP8AzxNicIZ4B8G3CG3OHA8+nBtEtxZoIihrrkqlMt+ +b/5N8u8zB0Encew0kdrc4R/2wS//ahr6U+9Siq8T7WsUtGwKj3BJClg6OyDJRhlu +y2gFnxoPAgMBAAECggEAP5TOycDkx+megAWVoHV2fmgvgZXkBrlzQwUG/VZQi7V4 +ZGzBMBVltdqI38wc5MtbK3TCgHANnnKgor9iq02Z4wXDwytPIiti/ycV9CDRKvv0 +TnD2hllQFjN/IUh5n4thHWbRTxmdM7cfcNgX3aZGkYbLBVVhOMtn4VwyYu/Mxy8j +xClZT2xKOHkxqwmWPmdDTbAeZIbSv7RkIGfrKuQyUGUaWhrPslvYzFkYZ0umaDgQ +OAthZew5Bz3OfUGOMPLH61SVPuJZh9zN1hTWOvT65WFWfsPd2yStI+WD/5PU1Doo +1RyeHJO7s3ug8JPbtNJmaJwHe9nXBb/HXFdqb976yQKBgQDNYhpu+MYSYupaYqjs +9YFmHQNKpNZqgZ4ceRFZ6cMJoqpI5dpEMqToFH7tpor72Lturct2U9nc2WR0HeEs +/6tiptyMPTFEiMFb1opQlXF2ae7LeJllntDGN0Q6vxKnQV+7VMcXA0Y8F7tvGDy3 +qJu5lfvB1mNM2I6y/eMxjBuQhwKBgQC6K41DXMFro0UnoO879pOQYMydCErJRmjG +/tZSy3Wj4KA/QJsDSViwGfvdPuHZRaG9WtxdL6kn0w1exM9Rb0bBKl36lvi7o7xv +M+Lw9eyXMkww8/F5d7YYH77gIhGo+RITkKI3+5BxeBaUnrGvmHrpmpgRXWmINqr0 +0jsnN3u0OQKBgCf45vIgItSjQb8zonLz2SpZjTFy4XQ7I92gxnq8X0Q5z3B+o7tQ +K/4rNwTju/sGFHyXAJlX+nfcK4vZ4OBUJjP+C8CTjEotX4yTNbo3S6zjMyGQqDI5 +9aIOUY4pb+TzeUFJX7If5gR+DfGyQubvvtcg1K3GHu9u2l8FwLj87sRzAoGAflQF +RHuRiG+/AngTPnZAhc0Zq0kwLkpH2Rid6IrFZhGLy8AUL/O6aa0IGoaMDLpSWUJp +nBY2S57MSM11/MVslrEgGmYNnI4r1K25xlaqV6K6ztEJv6n69327MS4NG8L/gCU5 +3pEm38hkUi8pVYU7in7rx4TCkrq94OkzWJYurAkCgYATQCL/rJLQAlJIGulp8s6h +mQGwy8vIqMjAdHGLrCS35sVYBXG13knS52LJHvbVee39AbD5/LlWvjJGlQMzCLrw +F7oILW5kXxhb8S73GWcuMbuQMFVHFONbZAZgn+C9FW4l7XyRdkrbR1MRZ2km8YMs +/AHmo368d4PSNRMMzLHw8Q== +-----END PRIVATE KEY----- diff --git a/tests/plugins/security/.kirk.pem b/tests/plugins/security/.kirk.pem new file mode 100644 index 000000000..b89edfe18 --- /dev/null +++ b/tests/plugins/security/.kirk.pem @@ -0,0 +1,27 @@ +-----BEGIN CERTIFICATE----- +MIIEmDCCA4CgAwIBAgIUaYSlET3nzsotWTrWueVPPh10yLcwDQYJKoZIhvcNAQEL +BQAwgY8xEzARBgoJkiaJk/IsZAEZFgNjb20xFzAVBgoJkiaJk/IsZAEZFgdleGFt +cGxlMRkwFwYDVQQKDBBFeGFtcGxlIENvbSBJbmMuMSEwHwYDVQQLDBhFeGFtcGxl +IENvbSBJbmMuIFJvb3QgQ0ExITAfBgNVBAMMGEV4YW1wbGUgQ29tIEluYy4gUm9v +dCBDQTAeFw0yNDAyMjAxNzA0MjRaFw0zNDAyMTcxNzA0MjRaME0xCzAJBgNVBAYT +AmRlMQ0wCwYDVQQHDAR0ZXN0MQ8wDQYDVQQKDAZjbGllbnQxDzANBgNVBAsMBmNs +aWVudDENMAsGA1UEAwwEa2lyazCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC +ggEBAJVcOAQlCiuB9emCljROAXnlsPbG7PE3kNz2sN+BbGuw686Wgyl3uToVHvVs +paMmLUqm1KYz9wMSWTIBZgpJ9hYaIbGxD4RBb7qTAJ8Q4ddCV2f7T4lxao/6ixI+ +O0l/BG9E3mRGo/r0w+jtTQ3aR2p6eoxaOYbVyEMYtFI4QZTkcgGIPGxm05y8xonx +vV5pbSW9L7qAVDzQC8EYGQMMI4ccu0NcHKWtmTYJA/wDPE2JwhngHwbcIbc4cDz6 +cG0S3FmgiKGuuSqUy35v/k3y7zMHQSdx7DSR2tzhH/bBL/9qGvpT71KKrxPtaxS0 +bAqPcEkKWDo7IMlGGW7LaAWfGg8CAwEAAaOCASswggEnMAwGA1UdEwEB/wQCMAAw +DgYDVR0PAQH/BAQDAgXgMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMCMB0GA1UdDgQW +BBSjMS8tgguX/V7KSGLoGg7K6XMzIDCBzwYDVR0jBIHHMIHEgBQXh9+gWutmEqfV +0Pi6EkU8tysAnKGBlaSBkjCBjzETMBEGCgmSJomT8ixkARkWA2NvbTEXMBUGCgmS +JomT8ixkARkWB2V4YW1wbGUxGTAXBgNVBAoMEEV4YW1wbGUgQ29tIEluYy4xITAf +BgNVBAsMGEV4YW1wbGUgQ29tIEluYy4gUm9vdCBDQTEhMB8GA1UEAwwYRXhhbXBs +ZSBDb20gSW5jLiBSb290IENBghQNZAmZZn3EFOxBR4630XlhI+mo4jANBgkqhkiG +9w0BAQsFAAOCAQEACEUPPE66/Ot3vZqRGpjDjPHAdtOq+ebaglQhvYcnDw8LOZm8 +Gbh9M88CiO6UxC8ipQLTPh2yyeWArkpJzJK/Pi1eoF1XLiAa0sQ/RaJfQWPm9dvl +1ZQeK5vfD4147b3iBobwEV+CR04SKow0YeEEzAJvzr8YdKI6jqr+2GjjVqzxvRBy +KRVHWCFiR7bZhHGLq3br8hSu0hwjb3oGa1ZI8dui6ujyZt6nm6BoEkau3G/6+zq9 +E6vX3+8Fj4HKCAL6i0SwfGmEpTNp5WUhqibK/fMhhmMT4Mx6MxkT+OFnIjdUU0S/ +e3kgnG8qjficUr38CyEli1U0M7koIXUZI7r+LQ== +-----END CERTIFICATE----- diff --git a/tests/plugins/security/api/nodesdn.yaml b/tests/plugins/security/api/nodesdn.yaml new file mode 100644 index 000000000..176a748c9 --- /dev/null +++ b/tests/plugins/security/api/nodesdn.yaml @@ -0,0 +1,64 @@ +$schema: ../../../../json_schemas/test_story.schema.yaml + +description: Test dynamic distinguished names. +epilogues: + - path: /_plugins/_security/api/nodesdn/opensearch-cluster + method: DELETE + status: [200,404] +chapters: + - synopsis: Add distinguished names. + path: /_plugins/_security/api/nodesdn/{cluster_name} + method: PUT + parameters: + cluster_name: opensearch-cluster + request: + payload: + nodes_dn: + - CN=cluster.example.com + response: + status: 201 + payload: + status: CREATED + - synopsis: Retrieve distinguished names. + path: /_plugins/_security/api/nodesdn + method: GET + - synopsis: Update distinguished names. + path: /_plugins/_security/api/nodesdn + method: PATCH + request: + payload: + - op: replace + path: /opensearch-cluster/nodes_dn/0 + value: CN=Christopher Nolan,CN=admin,DC=movies,DC=opensearch,DC=org + response: + status: 200 + payload: + status: OK + - synopsis: Update distinguished names (with cluster name). + path: /_plugins/_security/api/nodesdn/{cluster_name} + method: PATCH + parameters: + cluster_name: opensearch-cluster + request: + payload: + - op: replace + path: /nodes_dn/0 + value: CN=Quentin Tarantino,CN=admin,DC=movies,DC=opensearch,DC=org + response: + status: 200 + payload: + status: OK + - synopsis: Retrieve distinguished names (with cluster name). + path: /_plugins/_security/api/nodesdn/{cluster_name} + method: GET + parameters: + cluster_name: opensearch-cluster + - synopsis: Delete all distinguished names. + path: /_plugins/_security/api/nodesdn/{cluster_name} + method: DELETE + parameters: + cluster_name: opensearch-cluster + response: + status: 200 + payload: + status: OK diff --git a/tests/plugins/security/docker-compose.yml b/tests/plugins/security/docker-compose.yml new file mode 100644 index 000000000..f5050da5c --- /dev/null +++ b/tests/plugins/security/docker-compose.yml @@ -0,0 +1,13 @@ +version: '3' + +services: + opensearch-cluster: + image: ${OPENSEARCH_DOCKER_HUB_PROJECT:-opensearchproject}/opensearch:${OPENSEARCH_VERSION:-latest}${OPENSEARCH_DOCKER_REF} + ports: + - 9200:9200 + - 9600:9600 + environment: + - OPENSEARCH_INITIAL_ADMIN_PASSWORD=${OPENSEARCH_PASSWORD:-myStrongPassword123!} + - OPENSEARCH_JAVA_OPTS=${OPENSEARCH_JAVA_OPTS} + - discovery.type=single-node + - plugins.security.nodes_dn_dynamic_config_enabled=true diff --git a/tools/src/OpenSearchHttpClient.ts b/tools/src/OpenSearchHttpClient.ts index 314a73d45..247f1f8f9 100644 --- a/tools/src/OpenSearchHttpClient.ts +++ b/tools/src/OpenSearchHttpClient.ts @@ -10,6 +10,7 @@ import { Option } from '@commander-js/extra-typings' import axios, { type AxiosInstance, type AxiosRequestConfig, type AxiosResponse, type ResponseType } from 'axios' import * as https from 'node:https' +import fs from 'fs' import { sleep } from './helpers' import { Logger } from './Logger' import { aws4Interceptor } from 'aws4-axios' @@ -29,6 +30,12 @@ export const OPENSEARCH_USERNAME_OPTION = new Option('--opensearch-username ', 'password to use when authenticating with OpenSearch') .env('OPENSEARCH_PASSWORD') +export const OPENSEARCH_CERT_OPTION = new Option('--opensearch-cert ', 'client certificate file to use when authenticating with OpenSearch') + .env('OPENSEARCH_CERT') + +export const OPENSEARCH_KEY_OPTION = new Option('--opensearch-key ', 'client certificate private key file name to use when authenticating with OpenSearch') + .env('OPENSEARCH_KEY') + export const OPENSEARCH_INSECURE_OPTION = new Option('--opensearch-insecure', 'disable SSL/TLS certificate verification when connecting to OpenSearch') .default(DEFAULT_INSECURE) @@ -65,6 +72,8 @@ export interface AwsAuth { export interface OpenSearchHttpClientOptions { url?: string insecure?: boolean + cert?: string, + key?: string, responseType?: ResponseType logger?: Logger, basic_auth?: BasicAuth @@ -77,6 +86,8 @@ export type OpenSearchHttpClientCliOptions = { opensearchUsername?: string opensearchPassword?: string opensearchInsecure?: boolean + opensearchCert?: string, + opensearchKey?: string, awsAccessKeyId?: string awsSecretAccessKey?: string awsSessionToken?: string @@ -90,6 +101,8 @@ export function get_opensearch_opts_from_cli (opts: OpenSearchHttpClientCliOptio return { url: opts.opensearchUrl, insecure: opts.opensearchInsecure, + cert: opts.opensearchCert, + key: opts.opensearchKey, basic_auth: opts.opensearchUsername !== undefined && opts.opensearchPassword !== undefined ? { username: opts.opensearchUsername, password: opts.opensearchPassword @@ -164,7 +177,11 @@ export class OpenSearchHttpClient { this._axios = axios.create({ baseURL: opts?.url ?? DEFAULT_URL, - httpsAgent: new https.Agent({ rejectUnauthorized: !(opts?.insecure ?? DEFAULT_INSECURE) }), + httpsAgent: new https.Agent({ + rejectUnauthorized: !(opts?.insecure ?? DEFAULT_INSECURE), + cert: opts?.cert !== undefined && opts?.cert !== '' ? fs.readFileSync(opts?.cert) : undefined, + key: opts?.key !== undefined && opts?.key !== '' ? fs.readFileSync(opts?.key) : undefined, + }), responseType: opts?.responseType, }) diff --git a/tools/src/dump-cluster-spec/dump-cluster-spec.ts b/tools/src/dump-cluster-spec/dump-cluster-spec.ts index 02dd77972..bdf8ea05a 100644 --- a/tools/src/dump-cluster-spec/dump-cluster-spec.ts +++ b/tools/src/dump-cluster-spec/dump-cluster-spec.ts @@ -13,7 +13,9 @@ import * as process from 'node:process' import { write_yaml } from '../helpers' import { get_opensearch_opts_from_cli, + OPENSEARCH_CERT_OPTION, OPENSEARCH_INSECURE_OPTION, + OPENSEARCH_KEY_OPTION, OPENSEARCH_PASSWORD_OPTION, OPENSEARCH_URL_OPTION, OPENSEARCH_USERNAME_OPTION, OpenSearchHttpClient, @@ -42,6 +44,8 @@ const command = new Command() .addOption(OPENSEARCH_USERNAME_OPTION) .addOption(OPENSEARCH_PASSWORD_OPTION) .addOption(OPENSEARCH_INSECURE_OPTION) + .addOption(OPENSEARCH_CERT_OPTION) + .addOption(OPENSEARCH_KEY_OPTION) .addOption(new Option('--output ', 'path to the output file').default(resolve(__dirname, '../../../build/opensearch-openapi-CLUSTER.yaml'))) .allowExcessArguments(false) .parse() diff --git a/tools/src/tester/test.ts b/tools/src/tester/test.ts index 77351fe75..8a69185fb 100644 --- a/tools/src/tester/test.ts +++ b/tools/src/tester/test.ts @@ -17,7 +17,9 @@ import { AWS_SERVICE_OPTION, AWS_SESSION_TOKEN_OPTION, get_opensearch_opts_from_cli, + OPENSEARCH_CERT_OPTION, OPENSEARCH_INSECURE_OPTION, + OPENSEARCH_KEY_OPTION, OPENSEARCH_PASSWORD_OPTION, OPENSEARCH_URL_OPTION, OPENSEARCH_USERNAME_OPTION, @@ -54,6 +56,8 @@ const command = new Command() .addOption(OPENSEARCH_USERNAME_OPTION) .addOption(OPENSEARCH_PASSWORD_OPTION) .addOption(OPENSEARCH_INSECURE_OPTION) + .addOption(OPENSEARCH_CERT_OPTION) + .addOption(OPENSEARCH_KEY_OPTION) .addOption(AWS_ACCESS_KEY_ID_OPTION) .addOption(AWS_SECRET_ACCESS_KEY_OPTION) .addOption(AWS_SESSION_TOKEN_OPTION) diff --git a/tools/tests/tester/OpenSearchHttpClient.test.ts b/tools/tests/tester/OpenSearchHttpClient.test.ts index 85c62af05..0493488c4 100644 --- a/tools/tests/tester/OpenSearchHttpClient.test.ts +++ b/tools/tests/tester/OpenSearchHttpClient.test.ts @@ -73,4 +73,47 @@ describe('OpenSearchHttpClient', () => { expect((await client.get('/')).data).toEqual({ called: true }) }) + + it('defaults to rejectUnauthorized', async () => { + let client = new OpenSearchHttpClient({ + url: 'https://localhost:9200' + }) + + mock.onAny().reply((config) => { + expect(config.httpsAgent.options.rejectUnauthorized).toBe(true) + return [200, { called: true }] + }) + + expect((await client.get('/')).data).toEqual({ called: true }) + }) + + it('sets rejectUnauthorized to false', async () => { + let client = new OpenSearchHttpClient({ + url: 'https://localhost:9200', + insecure: true + }) + + mock.onAny().reply((config) => { + expect(config.httpsAgent.options.rejectUnauthorized).toEqual(false) + return [200, { called: true }] + }) + + expect((await client.get('/')).data).toEqual({ called: true }) + }) + + it('adds a certificate file and key', async () => { + let client = new OpenSearchHttpClient({ + url: 'https://localhost:9200', + cert: './tools/tests/tester/fixtures/keys/kirk.pem', + key: './tools/tests/tester/fixtures/keys/kirk-key.pem' + }) + + mock.onAny().reply((config) => { + expect(config.httpsAgent.options.cert.toString()).toEqual("-----BEGIN CERTIFICATE-----\ncertificate\n-----END CERTIFICATE-----\n") + expect(config.httpsAgent.options.key.toString()).toEqual("-----BEGIN PRIVATE KEY-----\nprivate key\n-----END PRIVATE KEY-----\n") + return [200, { called: true }] + }) + + expect((await client.get('/')).data).toEqual({ called: true }) + }) }) diff --git a/tools/tests/tester/fixtures/keys/kirk-key.pem b/tools/tests/tester/fixtures/keys/kirk-key.pem new file mode 100644 index 000000000..5af21d7eb --- /dev/null +++ b/tools/tests/tester/fixtures/keys/kirk-key.pem @@ -0,0 +1,3 @@ +-----BEGIN PRIVATE KEY----- +private key +-----END PRIVATE KEY----- diff --git a/tools/tests/tester/fixtures/keys/kirk.pem b/tools/tests/tester/fixtures/keys/kirk.pem new file mode 100644 index 000000000..24c83bcd0 --- /dev/null +++ b/tools/tests/tester/fixtures/keys/kirk.pem @@ -0,0 +1,3 @@ +-----BEGIN CERTIFICATE----- +certificate +-----END CERTIFICATE-----