diff --git a/.github/workflows/cypress_workflow.yml b/.github/workflows/cypress_workflow.yml index ac5d54bb7a2d..a4507d8bff55 100644 --- a/.github/workflows/cypress_workflow.yml +++ b/.github/workflows/cypress_workflow.yml @@ -30,7 +30,7 @@ env: TEST_REPO: ${{ inputs.test_repo != '' && inputs.test_repo || 'opensearch-project/opensearch-dashboards-functional-test' }} TEST_BRANCH: "${{ inputs.test_branch != '' && inputs.test_branch || github.base_ref }}" FTR_PATH: 'ftr' - START_CMD: 'node ../scripts/opensearch_dashboards --dev --no-base-path --no-watch --savedObjects.maxImportPayloadBytes=10485760 --server.maxPayloadBytes=1759977 --logging.json=false --data.search.aggs.shardDelay.enabled=true --csp.warnLegacyBrowsers=false' + START_CMD: 'node ../scripts/opensearch_dashboards --dev --no-base-path --no-watch --savedObjects.maxImportPayloadBytes=10485760 --server.maxPayloadBytes=1759977 --logging.json=false --data.search.aggs.shardDelay.enabled=true --csp.warnLegacyBrowsers=false --server.compression.enabled=true --opensearch.compression=true' OPENSEARCH_SNAPSHOT_CMD: 'node ../scripts/opensearch snapshot -E cluster.routing.allocation.disk.threshold_enabled=false' CYPRESS_BROWSER: 'chromium' CYPRESS_VISBUILDER_ENABLED: true diff --git a/changelogs/fragments/6366.yml b/changelogs/fragments/6366.yml new file mode 100644 index 000000000000..31543d235258 --- /dev/null +++ b/changelogs/fragments/6366.yml @@ -0,0 +1,2 @@ +feat: +- Support compressing traffic with `opensearch.compression: true` or `opensearch.compress: 'gzip'` ([#6366](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/6366)) \ No newline at end of file diff --git a/src/core/server/opensearch/client/client_config.ts b/src/core/server/opensearch/client/client_config.ts index 0432bb8ddfd6..7fff839c4d97 100644 --- a/src/core/server/opensearch/client/client_config.ts +++ b/src/core/server/opensearch/client/client_config.ts @@ -53,6 +53,7 @@ export type OpenSearchClientConfig = Pick< | 'username' | 'password' | 'disablePrototypePoisoningProtection' + | 'compression' > & { memoryCircuitBreaker?: | OpenSearchConfig['memoryCircuitBreaker'] @@ -120,6 +121,10 @@ export function parseClientOptions(config: OpenSearchClientConfig, scoped: boole clientOptions.disablePrototypePoisoningProtection = config.disablePrototypePoisoningProtection; } + if (config.compression) { + clientOptions.compression = config.compression; + } + return clientOptions; } diff --git a/src/core/server/opensearch/opensearch_config.test.ts b/src/core/server/opensearch/opensearch_config.test.ts index d7a17c12d293..9d25a95b3028 100644 --- a/src/core/server/opensearch/opensearch_config.test.ts +++ b/src/core/server/opensearch/opensearch_config.test.ts @@ -71,6 +71,7 @@ test('set correct defaults', () => { expect(configValue).toMatchInlineSnapshot(` OpenSearchConfig { "apiVersion": "7.x", + "compression": undefined, "customHeaders": Object {}, "disablePrototypePoisoningProtection": undefined, "healthCheckDelay": "PT2.5S", diff --git a/src/core/server/opensearch/opensearch_config.ts b/src/core/server/opensearch/opensearch_config.ts index ba63e7350753..55b62c845696 100644 --- a/src/core/server/opensearch/opensearch_config.ts +++ b/src/core/server/opensearch/opensearch_config.ts @@ -32,12 +32,14 @@ import { schema, TypeOf } from '@osd/config-schema'; import { Duration } from 'moment'; import { readFileSync } from 'fs'; import { ConfigDeprecationProvider } from 'src/core/server'; +import { ClientOptions } from '@opensearch-project/opensearch'; import { readPkcs12Keystore, readPkcs12Truststore } from '../utils'; import { ServiceConfigDescriptor } from '../internal_types'; const hostURISchema = schema.uri({ scheme: ['http', 'https'] }); export const DEFAULT_API_VERSION = '7.x'; +export const DEFAULT_COMPRESSION = 'gzip'; export type OpenSearchConfigType = TypeOf; type SslConfigSchema = OpenSearchConfigType['ssl']; @@ -131,6 +133,9 @@ export const configSchema = schema.object({ healthCheck: schema.object({ delay: schema.duration({ defaultValue: 2500 }) }), ignoreVersionMismatch: schema.boolean({ defaultValue: false }), disablePrototypePoisoningProtection: schema.maybe(schema.boolean({ defaultValue: false })), + compression: schema.maybe( + schema.oneOf([schema.literal(DEFAULT_COMPRESSION), schema.boolean({ defaultValue: false })]) + ), }); const deprecations: ConfigDeprecationProvider = ({ renameFromRoot, renameFromRootWithoutMap }) => [ @@ -313,6 +318,12 @@ export class OpenSearchConfig { */ public readonly disablePrototypePoisoningProtection?: boolean; + /** + * Specifies whether the client should use compression to engine + * or not. + */ + public readonly compression?: ClientOptions['compression']; + constructor(rawConfig: OpenSearchConfigType) { this.ignoreVersionMismatch = rawConfig.ignoreVersionMismatch; this.apiVersion = rawConfig.apiVersion; @@ -334,6 +345,12 @@ export class OpenSearchConfig { this.password = rawConfig.password; this.customHeaders = rawConfig.customHeaders; this.disablePrototypePoisoningProtection = rawConfig.disablePrototypePoisoningProtection; + this.compression = + typeof rawConfig.compression === 'boolean' && rawConfig.compression + ? DEFAULT_COMPRESSION + : typeof rawConfig.compression === 'string' + ? rawConfig.compression + : undefined; const { alwaysPresentCertificate, verificationMode } = rawConfig.ssl; const { key, keyPassphrase, certificate, certificateAuthorities } = readKeyAndCerts(rawConfig);