feat(GoogleBigQuery Node): Add support for service account authentication (#3128)

*  Enable service account authentication with the BigQuery node

* 🔨 fixed auth issue with key, fixed nodelinter issues

*  added continue on fail

*  Improvements

Co-authored-by: Mark Steve Samson <marksteve@thinkingmachin.es>
Co-authored-by: ricardo <ricardoespinoza105@gmail.com>
This commit is contained in:
Michael Kret
2022-04-18 19:46:50 +03:00
committed by GitHub
parent 794ad7c756
commit ac5f357001
3 changed files with 186 additions and 68 deletions

View File

@@ -9,6 +9,7 @@ import {
INodePropertyOptions,
INodeType,
INodeTypeDescription,
NodeApiError,
} from 'n8n-workflow';
import {
@@ -39,16 +40,52 @@ export class GoogleBigQuery implements INodeType {
inputs: ['main'],
outputs: ['main'],
credentials: [
{
name: 'googleApi',
required: true,
displayOptions: {
show: {
authentication: [
'serviceAccount',
],
},
},
},
{
name: 'googleBigQueryOAuth2Api',
required: true,
displayOptions: {
show: {
authentication: [
'oAuth2',
],
},
},
},
],
properties: [
{
displayName: 'Authentication',
name: 'authentication',
type: 'options',
noDataExpression: true,
options: [
{
name: 'Service Account',
value: 'serviceAccount',
},
{
name: 'OAuth2',
value: 'oAuth2',
},
],
default: 'oAuth2',
},
{
displayName: 'Resource',
name: 'resource',
type: 'options',
noDataExpression: true,
options: [
{
name: 'Record',
@@ -56,7 +93,7 @@ export class GoogleBigQuery implements INodeType {
},
],
default: 'record',
description: 'The resource to operate on.',
description: 'The resource to operate on',
},
...recordOperations,
...recordFields,
@@ -171,14 +208,22 @@ export class GoogleBigQuery implements INodeType {
}
body.rows = rows;
responseData = await googleApiRequest.call(
this,
'POST',
`/v2/projects/${projectId}/datasets/${datasetId}/tables/${tableId}/insertAll`,
body,
);
returnData.push(responseData);
try {
responseData = await googleApiRequest.call(
this,
'POST',
`/v2/projects/${projectId}/datasets/${datasetId}/tables/${tableId}/insertAll`,
body,
);
returnData.push(responseData);
} catch (error) {
if (this.continueOnFail()) {
returnData.push({ error: error.message });
} else {
throw new NodeApiError(this.getNode(), error);
}
}
} else if (operation === 'getAll') {
// ----------------------------------
@@ -205,40 +250,48 @@ export class GoogleBigQuery implements INodeType {
}
for (let i = 0; i < length; i++) {
const options = this.getNodeParameter('options', i) as IDataObject;
Object.assign(qs, options);
try {
const options = this.getNodeParameter('options', i) as IDataObject;
Object.assign(qs, options);
// if (qs.useInt64Timestamp !== undefined) {
// qs.formatOptions = {
// useInt64Timestamp: qs.useInt64Timestamp,
// };
// delete qs.useInt64Timestamp;
// }
// if (qs.useInt64Timestamp !== undefined) {
// qs.formatOptions = {
// useInt64Timestamp: qs.useInt64Timestamp,
// };
// delete qs.useInt64Timestamp;
// }
if (qs.selectedFields) {
fields = (qs.selectedFields as string).split(',');
}
if (qs.selectedFields) {
fields = (qs.selectedFields as string).split(',');
}
if (returnAll) {
responseData = await googleApiRequestAllItems.call(
this,
'rows',
'GET',
`/v2/projects/${projectId}/datasets/${datasetId}/tables/${tableId}/data`,
{},
qs,
);
returnData.push.apply(returnData, (simple) ? simplify(responseData, fields) : responseData);
} else {
qs.maxResults = this.getNodeParameter('limit', i) as number;
responseData = await googleApiRequest.call(
this,
'GET',
`/v2/projects/${projectId}/datasets/${datasetId}/tables/${tableId}/data`,
{},
qs,
);
returnData.push.apply(returnData, (simple) ? simplify(responseData.rows, fields) : responseData.rows);
if (returnAll) {
responseData = await googleApiRequestAllItems.call(
this,
'rows',
'GET',
`/v2/projects/${projectId}/datasets/${datasetId}/tables/${tableId}/data`,
{},
qs,
);
returnData.push.apply(returnData, (simple) ? simplify(responseData, fields) : responseData);
} else {
qs.maxResults = this.getNodeParameter('limit', i) as number;
responseData = await googleApiRequest.call(
this,
'GET',
`/v2/projects/${projectId}/datasets/${datasetId}/tables/${tableId}/data`,
{},
qs,
);
returnData.push.apply(returnData, (simple) ? simplify(responseData.rows, fields) : responseData.rows);
}
} catch (error) {
if (this.continueOnFail()) {
returnData.push({ error: error.message });
continue;
}
throw new NodeApiError(this.getNode(), error);
}
}
}