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 {