From c6e90d15b5e6355d500e63658b9c9f4073c5a946 Mon Sep 17 00:00:00 2001 From: pemontto <939704+pemontto@users.noreply.github.com> Date: Sun, 10 Jul 2022 10:00:47 +0100 Subject: [PATCH] feat(Elasticsearch Node): Add credential tests, index pipelines and index refresh (#2420) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * πŸ› ES query string not passed to request * πŸ”‘ Add ES credential test * ✨ Add ES index pipelines and index refresh * :hammer: merge fix * :zap: renamed additional filds as options * :zap: added ignore ssl to credentials * :zap: Improvements * :zap: Improvements * feat(Redis Node): Add push and pop operations (#3127) * ✨ Add push and pop operations * :zap: linter fixes * :zap: linter fixes * πŸ› Fix errors and remove overwrite * πŸ› Remove errant hint * :zap: Small change Co-authored-by: Michael Kret Co-authored-by: ricardo * refactor: Telemetry updates (#3529) * Init unit tests for telemetry * Update telemetry tests * Test Workflow execution errored event * Add new tracking logic in pulse * cleanup * interfaces * Add event_version for Workflow execution count event * add version_cli in all events * add user saved credentials event * update manual wf exec finished, fixes * improve typings, lint * add node_graph_string in User clicked execute workflow button event * add User set node operation or mode event * Add instance started event in FE * Add User clicked retry execution button event * add expression editor event * add input node type to add node event * add User stopped workflow execution wvent * add error message in saved credential event * update stop execution event * add execution preflight event * Remove instance started even tfrom FE, add session started to FE,BE * improve typing * remove node_graph as property from all events * move back from default export * move psl npm package to cli package * cr * update webhook node domain logic * fix is_valid for User saved credentials event * fix Expression Editor variable selector event * add caused_by_credential in preflight event * undo webhook_domain * change node_type to full type * add webhook_domain property in manual execution event (#3680) * add webhook_domain property in manual execution event * lint fix * feat(SpreadsheetFile Node): Allow skipping headers when writing spreadsheets (#3234) * ⚑ Allow skipping headers when writing spreadsheets * Fix type on sheet options * fix(Telegram Node): Fix sending binaryData media (photo, document, video etc.) (#3408) * fixed send media (photo, document, video etc.) issues on Telegram Node * fixed send media (photo, document, video etc.) issues on Telegram Node * file name is optional now * :zap: lock file and linter fix * :zap: improvements * :zap: fixes * :zap: Improvements * :zap: Add placeholder to File Name * :zap: Add error message * :fire: Remove requestWithAuthentication * :zap: Fix typo * :shirt: Fix linting issues Co-authored-by: Michael Kret Co-authored-by: ricardo * feat(Freshworks CRM Node): Add Search + Lookup functionality (#3131) * Add fields and Ops for Lookup Search * Adds Search (Search + Lookup) operations * :hammer: credentials update * :hammer: improvements * :zap: clean up and linter fixes * :zap: merged search and query, more hints * :zap: Improvements * :zap: Add generic type to authentication method Co-authored-by: Michael Kret Co-authored-by: ricardo * feat(Jira Trigger Node): Add optional query auth for security (#3172) * ✨ Add query auth for Jira Trigger security * :zap: small fixes: * :zap: Response with 403 when invalid query authentication * :shirt: Fix linting issues Co-authored-by: Michael Kret Co-authored-by: ricardo * :zap: Changed authentication to use the generic type Co-authored-by: Michael Kret Co-authored-by: ricardo Co-authored-by: Ahsan Virani Co-authored-by: Nicholas Penree Co-authored-by: Taha SΓΆnmez <35905778+tahasonmez@users.noreply.github.com> Co-authored-by: Jan Thiel Co-authored-by: Jan Oberhauser --- .../ElasticsearchApi.credentials.ts | 31 ++++++- .../Elasticsearch/Elasticsearch.node.ts | 19 +++- .../Elastic/Elasticsearch/GenericFunctions.ts | 12 +-- .../descriptions/DocumentDescription.ts | 93 +++++++++++++++++++ .../nodes/Elastic/Elasticsearch/types.d.ts | 1 + packages/workflow/src/Interfaces.ts | 1 + 6 files changed, 144 insertions(+), 13 deletions(-) diff --git a/packages/nodes-base/credentials/ElasticsearchApi.credentials.ts b/packages/nodes-base/credentials/ElasticsearchApi.credentials.ts index eb3a35243d..7762f96727 100644 --- a/packages/nodes-base/credentials/ElasticsearchApi.credentials.ts +++ b/packages/nodes-base/credentials/ElasticsearchApi.credentials.ts @@ -1,4 +1,6 @@ import { + IAuthenticateGeneric, + ICredentialTestRequest, ICredentialType, INodeProperties, } from 'n8n-workflow'; @@ -31,5 +33,32 @@ export class ElasticsearchApi implements ICredentialType { placeholder: 'https://mydeployment.es.us-central1.gcp.cloud.es.io:9243', description: 'Referred to as Elasticsearch \'endpoint\' in the Elastic deployment dashboard', }, + { + displayName: 'Ignore SSL Issues', + name: 'ignoreSSLIssues', + type: 'boolean', + default: false, + }, ]; -} + + authenticate: IAuthenticateGeneric = { + type: 'generic', + properties: { + auth: { + username: '={{$credentials.username}}', + password: '={{$credentials.password}}', + }, + skipSslCertificateValidation: '={{$credentials.ignoreSSLIssues}}', + }, + }; + + test: ICredentialTestRequest = { + request: { + baseURL: '={{$credentials.baseUrl}}', + auth: { + username: '=${{credentias.username}}', + password: '=${{credentials.password}}', + }, + url: '', + }, + };} diff --git a/packages/nodes-base/nodes/Elastic/Elasticsearch/Elasticsearch.node.ts b/packages/nodes-base/nodes/Elastic/Elasticsearch/Elasticsearch.node.ts index a4ce582a2e..e7aab680de 100644 --- a/packages/nodes-base/nodes/Elastic/Elasticsearch/Elasticsearch.node.ts +++ b/packages/nodes-base/nodes/Elastic/Elasticsearch/Elasticsearch.node.ts @@ -3,10 +3,14 @@ import { } from 'n8n-core'; import { + ICredentialsDecrypted, + ICredentialTestFunctions, IDataObject, + INodeCredentialTestResult, INodeExecutionData, INodeType, INodeTypeDescription, + JsonObject, } from 'n8n-workflow'; import { @@ -22,6 +26,7 @@ import { import { DocumentGetAllOptions, + ElasticsearchApiCredentials, FieldsUiValues, } from './types'; @@ -211,20 +216,23 @@ export class Elasticsearch implements INodeType { const qs = {} as IDataObject; const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const options = this.getNodeParameter('options', i, {}) as IDataObject; if (Object.keys(additionalFields).length) { Object.assign(qs, omit(additionalFields, ['documentId'])); } + Object.assign(qs, options); + const indexId = this.getNodeParameter('indexId', i); const { documentId } = additionalFields; if (documentId) { const endpoint = `/${indexId}/_doc/${documentId}`; - responseData = await elasticsearchApiRequest.call(this, 'PUT', endpoint, body); + responseData = await elasticsearchApiRequest.call(this, 'PUT', endpoint, body, qs); } else { const endpoint = `/${indexId}/_doc`; - responseData = await elasticsearchApiRequest.call(this, 'POST', endpoint, body); + responseData = await elasticsearchApiRequest.call(this, 'POST', endpoint, body, qs); } } else if (operation === 'update') { @@ -259,9 +267,14 @@ export class Elasticsearch implements INodeType { const indexId = this.getNodeParameter('indexId', i); const documentId = this.getNodeParameter('documentId', i); + const options = this.getNodeParameter('options', i, {}) as IDataObject; + + const qs = { + ...options, + }; const endpoint = `/${indexId}/_update/${documentId}`; - responseData = await elasticsearchApiRequest.call(this, 'POST', endpoint, body); + responseData = await elasticsearchApiRequest.call(this, 'POST', endpoint, body, qs); } diff --git a/packages/nodes-base/nodes/Elastic/Elasticsearch/GenericFunctions.ts b/packages/nodes-base/nodes/Elastic/Elasticsearch/GenericFunctions.ts index bfcd96faeb..9a14c7cbbe 100644 --- a/packages/nodes-base/nodes/Elastic/Elasticsearch/GenericFunctions.ts +++ b/packages/nodes-base/nodes/Elastic/Elasticsearch/GenericFunctions.ts @@ -23,23 +23,17 @@ export async function elasticsearchApiRequest( qs: IDataObject = {}, ) { const { - username, - password, baseUrl, + ignoreSSLIssues, } = await this.getCredentials('elasticsearchApi') as ElasticsearchApiCredentials; - const token = Buffer.from(`${username}:${password}`).toString('base64'); - const options: OptionsWithUri = { - headers: { - Authorization: `Basic ${token}`, - 'Content-Type': 'application/json', - }, method, body, qs, uri: `${baseUrl}${endpoint}`, json: true, + rejectUnauthorized: !ignoreSSLIssues, }; if (!Object.keys(body).length) { @@ -51,7 +45,7 @@ export async function elasticsearchApiRequest( } try { - return await this.helpers.request(options); + return await this.helpers.requestWithAuthentication.call(this, 'elasticsearchApi', options); } catch (error) { throw new NodeApiError(this.getNode(), error); } diff --git a/packages/nodes-base/nodes/Elastic/Elasticsearch/descriptions/DocumentDescription.ts b/packages/nodes-base/nodes/Elastic/Elasticsearch/descriptions/DocumentDescription.ts index f7c4321a77..fbad4196ab 100644 --- a/packages/nodes-base/nodes/Elastic/Elasticsearch/descriptions/DocumentDescription.ts +++ b/packages/nodes-base/nodes/Elastic/Elasticsearch/descriptions/DocumentDescription.ts @@ -651,6 +651,56 @@ export const documentFields: INodeProperties[] = [ }, ], }, + { + displayName: 'Options', + name: 'options', + type: 'collection', + placeholder: 'Add Field', + default: {}, + displayOptions: { + show: { + resource: [ + 'document', + ], + operation: [ + 'create', + ], + }, + }, + options: [ + { + displayName: 'Pipeline ID', + name: 'pipeline', + description: 'ID of the pipeline to use to preprocess incoming documents', + type: 'string', + default: '', + }, + { + displayName: 'Refresh', + name: 'refresh', + description: 'If true, Elasticsearch refreshes the affected shards to make this operation visible to search,if wait_for then wait for a refresh to make this operation visible to search,if false do nothing with refreshes', + type: 'options', + default: 'false', + options: [ + { + name: 'True', + value: 'true', + description: 'Refreshes the affected shards to make this operation visible to search', + }, + { + name: 'Wait For', + value: 'wait_for', + description: 'Wait for a refresh to make this operation visible', + }, + { + name: 'False', + value: 'false', + description: 'Do nothing with refreshes', + }, + ], + }, + ], + }, // ---------------------------------------- // document: update @@ -785,4 +835,47 @@ export const documentFields: INodeProperties[] = [ }, ], }, + { + displayName: 'Options', + name: 'options', + type: 'collection', + placeholder: 'Add Field', + default: {}, + displayOptions: { + show: { + resource: [ + 'document', + ], + operation: [ + 'update', + ], + }, + }, + options: [ + { + displayName: 'Refresh', + name: 'refresh', + description: 'If true, Elasticsearch refreshes the affected shards to make this operation visible to search,if wait_for then wait for a refresh to make this operation visible to search,if false do nothing with refreshes', + type: 'options', + default: 'false', + options: [ + { + name: 'True', + value: 'true', + description: 'Refreshes the affected shards to make this operation visible to search', + }, + { + name: 'Wait For', + value: 'wait_for', + description: 'Wait for a refresh to make this operation visible', + }, + { + name: 'False', + value: 'false', + description: 'Do nothing with refreshes', + }, + ], + }, + ], + }, ]; diff --git a/packages/nodes-base/nodes/Elastic/Elasticsearch/types.d.ts b/packages/nodes-base/nodes/Elastic/Elasticsearch/types.d.ts index 105766301e..05c6c58d30 100644 --- a/packages/nodes-base/nodes/Elastic/Elasticsearch/types.d.ts +++ b/packages/nodes-base/nodes/Elastic/Elasticsearch/types.d.ts @@ -2,6 +2,7 @@ export type ElasticsearchApiCredentials = { username: string; password: string; baseUrl: string; + ignoreSSLIssues: boolean; }; export type DocumentGetAllOptions = Partial<{ diff --git a/packages/workflow/src/Interfaces.ts b/packages/workflow/src/Interfaces.ts index 4fb1ebdbe7..908179deb8 100644 --- a/packages/workflow/src/Interfaces.ts +++ b/packages/workflow/src/Interfaces.ts @@ -158,6 +158,7 @@ export interface IRequestOptionsSimplifiedAuth { body?: IDataObject; headers?: IDataObject; qs?: IDataObject; + skipSslCertificateValidation?: boolean | string; } export abstract class ICredentialsHelper {