in api/v1/src/lib/appliers/bigQueryApplier.js [58:144]
async function performDatasetMetadataUpdate(projectId, datasetId, accounts) {
const datashareReaderRole = await runtimeConfig.bigQueryDataViewerRole(projectId);
console.log(`Begin metadata update for dataset: '${datasetId}'`);
const bigqueryUtil = new BigQueryUtil(projectId);
const exists = await bigqueryUtil.datasetExists(datasetId);
if (!exists) {
console.warn(`Skipping metadata update for non-existant dataset: '${datasetId}'`);
return false;
}
let isDirty = false;
const accessTypes = ["userByEmail", "groupByEmail"];
// Get metadata
let metadata = await bigqueryUtil.getDatasetMetadata(datasetId);
// Check for and remove any non-existing authorized views
let i = metadata.access.length;
while (i--) {
let a = metadata.access[i];
if (a.view && a.view.projectId && a.view.datasetId && a.view.tableId) {
const _viewExists = await bigqueryUtil.viewExists(a.view.datasetId, a.view.tableId);
// If view no longer exists, remove it
if (_viewExists === false) {
console.log(`Removing authorized view as it does not exist: ${a.view.datasetId}.${a.view.tableId}`);
metadata.access.splice(i, 1);
isDirty = true;
}
}
else if (a.role === datashareReaderRole) {
// Remove all 'datashare.bigquery.dataViewer' userByEmail and groupByEmail accounts that should not have access
const aKeys = Object.keys(a);
if (aKeys.length === 2) {
const accessType = aKeys[1];
const accessId = a[accessType];
if (accessTypes.includes(accessType)) {
const dsAccessType = getDatashareDatasetAccessType(accessType);
let shouldHaveAccess = underscore.findWhere(accounts, { email: accessId, emailType: dsAccessType });
// If returns false for a user, also check for service account
if (!shouldHaveAccess && dsAccessType === 'user') {
shouldHaveAccess = underscore.findWhere(accounts, { email: accessId, emailType: 'serviceAccount' });
}
if (!shouldHaveAccess) {
console.log(`Deleting user: ${accessType}:${accessId} from datasetId: ${datasetId}`);
metadata.access.splice(i, 1);
isDirty = true;
}
}
}
}
}
// Add new or missing accounts
accounts.forEach(account => {
// If a dataset contains no accounts, the query will return an array with
// a single item at zero index with attributes having all null values.
if (account.email && account.emailType) {
const bqAccessType = getBqDatasetAccessType(account.emailType);
let a = { role: datashareReaderRole };
a[bqAccessType] = account.email;
const accessRecordExists = underscore.findWhere(metadata.access, a);
if (!accessRecordExists) {
metadata.access.push(a);
isDirty = true;
console.log(`Adding access record to datasetId: ${datasetId}: ${JSON.stringify(account)}`);
}
}
});
// Save metadata if changed
if (isDirty === true) {
try {
await bigqueryUtil.setDatasetMetadata(datasetId, metadata);
console.info(`Metadata set successfully for dataset '${datasetId}'`);
} catch (err) {
console.error(`Failed to set metadata for dataset '${datasetId}' with error '${err}' and payload: ${JSON.stringify(metadata)}`);
throw err;
}
} else {
console.info(`Metadata is already up to date for dataset: '${datasetId}'`);
}
console.log(`End metadata update for dataset: ${datasetId}`);
return isDirty;
}