Skip to content

Commit

Permalink
Metabase init always imports new dashboards (#143)
Browse files Browse the repository at this point in the history
Clarified import methods
  • Loading branch information
thomas-gerber authored May 6, 2022
1 parent 3a8deda commit a27e585
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 9 deletions.
6 changes: 3 additions & 3 deletions init/scripts/metabase-init.sh
Original file line number Diff line number Diff line change
Expand Up @@ -115,9 +115,9 @@ else
echo "Metabase setup failed with response code: $setup_status"
exit 1
fi

echo "Importing dashboards"
node ../lib/metabase/init.js --metabase-url "$mb_url" --username "$mb_user" --password "$mb_password" --database "$db_name" --import
fi

echo "Attached Faros database to Metabase"

echo "Importing dashboards"
node ../lib/metabase/init.js --metabase-url "$mb_url" --username "$mb_user" --password "$mb_password" --database "$db_name" --import-new
13 changes: 13 additions & 0 deletions init/src/metabase/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,16 @@ export async function loadDashboards(): Promise<ReadonlyArray<Dashboard>> {
});
return await Promise.all(promises);
}

export async function loadDashboard(name: string): Promise<Dashboard> {
const dashboardPath = path.join(
BASE_RESOURCES_DIR,
'metabase',
'dashboards',
name
);

const template = await fs.readFile(dashboardPath, 'utf-8');

return {name, template};
}
32 changes: 30 additions & 2 deletions init/src/metabase/dashboards.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
import pino from 'pino';
import {VError} from 'verror';

import {loadDashboards} from './config';
import {Dashboard, loadDashboard, loadDashboards} from './config';
import {Metabase} from './metabase';

const DASHBOARD_REGEX = /\(\/dashboard\/(\d+)\)/g;
Expand Down Expand Up @@ -465,8 +465,36 @@ export class Dashboards {
);
}

async import(): Promise<void> {
async importNew(): Promise<void> {
const dashboards = await loadDashboards();
const existingDashboards = await this.metabase.getDashboards();
const existingDashboardNames = new Set<string>();

for (const item of existingDashboards) {
existingDashboardNames.add(item.name);
this.logger.debug('existing dashboard: %s', item.name);
}
// we need to quickly parse the json to access the dashboard name
// we simply ignore missing helpers
const handlebars = Handlebars.create();
handlebars.registerHelper('helperMissing', function () {
return new Handlebars.SafeString('""');
});
const newDashboards = dashboards.filter(
(dashboard) =>
!existingDashboardNames.has(
JSON.parse(handlebars.compile(dashboard.template)({})).name
)
);
return await this.import(newDashboards);
}

async importOne(name: string): Promise<void> {
const dashboards = new Array(await loadDashboard(name));
return await this.import(dashboards);
}

private async import(dashboards: ReadonlyArray<Dashboard>): Promise<void> {
this.logger.info(
'Importing dashboards: %s',
dashboards.map((d) => d.name)
Expand Down
23 changes: 19 additions & 4 deletions init/src/metabase/init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,19 @@ async function main(): Promise<void> {
.requiredOption('--username <string>')
.requiredOption('--password <string>')
.requiredOption('--database <string>')
.addOption(new Option('--export <dashboardId>').conflicts('import'))
.addOption(new Option('--import').conflicts('export'))
.addOption(
new Option('--export <dashboardId>')
.conflicts('import-one')
.conflicts('import-new')
)
.addOption(
new Option('--import-one <filename>')
.conflicts('export')
.conflicts('import-new')
)
.addOption(
new Option('--import-new').conflicts('export').conflicts('import-one')
)
.addOption(new Option('--sync-schema'));

program.parse();
Expand All @@ -32,7 +43,7 @@ async function main(): Promise<void> {
await metabase.syncSchema(options.database);
logger.info('Metabase sync schema triggered');
} else {
if (!options.export && !options.import) {
if (!options.export && !options.importOne && !options.importNew) {
program.help();
}

Expand All @@ -49,7 +60,11 @@ async function main(): Promise<void> {
if (options.export) {
console.log(await dashboards.export(parseInt(options.export, 10)));
} else {
await dashboards.import();
if (options.importNew) {
await dashboards.importNew();
} else {
await dashboards.importOne(options.importOne);
}
logger.info('Metabase import is complete');
}
}
Expand Down

0 comments on commit a27e585

Please sign in to comment.