Skip to content

Instantly share code, notes, and snippets.

@MorenoMdz
Created May 23, 2021 13:35
Show Gist options
  • Save MorenoMdz/81632016b852c2bf247061f5e212ddaa to your computer and use it in GitHub Desktop.
Save MorenoMdz/81632016b852c2bf247061f5e212ddaa to your computer and use it in GitHub Desktop.
Example of firebase billing shutdown cloud function
// const admin = require('firebase-admin');
const { sendDiscordMessage } = require('./helpers');
const { google } = require('googleapis');
const { GoogleAuth } = require('google-auth-library');
const PROJECT_ID = 'project-name';
const PROJECT_NAME = `projects/${PROJECT_ID}`;
const billing = google.cloudbilling('v1').projects;
/**
* @return {Promise} Credentials set globally
*/
const _setAuthCredential = () => {
const client = new GoogleAuth({
scopes: [
'https://www.googleapis.com/auth/cloud-billing',
'https://www.googleapis.com/auth/cloud-platform'
]
});
// Set credential globally for all requests
google.options({
auth: client
});
};
/**
* Determine whether billing is enabled for a project
* @param {string} projectName Name of project to check if billing is enabled
* @return {bool} Whether project has billing enabled or not
*/
const _isBillingEnabled = async projectName => {
try {
const res = await billing.getBillingInfo({
name: projectName
});
// console.log(res);
return res.data.billingEnabled;
} catch (e) {
console.log(
'Unable to determine if billing is enabled on specified project, assuming billing is enabled'
);
return true;
}
};
/**
* Disable billing for a project by removing its billing account
* @param {string} projectName Name of project disable billing on
* @return {string} Text containing response from disabling billing
*/
const _disableBillingForProject = async projectName => {
const res = await billing.updateBillingInfo({
name: projectName,
resource: {
billingAccountName: ''
} // Disable billing
});
console.log(res);
console.log('Billing Disabled');
return `Billing disabled: ${JSON.stringify(res.data)}`;
};
const stopBilling = async pubsubEvent => {
console.log('!!!!!running stop billing' /* , pubsubEvent.data */);
const pubsubData = JSON.parse(
Buffer.from(pubsubEvent.data, 'base64').toString()
);
// console.log(pubsubData);
console.log('Actual cost amount:', pubsubData.costAmount);
console.log('Set budget:', pubsubData.budgetAmount);
if (pubsubData.costAmount <= pubsubData.budgetAmount) {
console.log('No action necessary.');
return `No action necessary. (Current cost: ${pubsubData.costAmount})`;
}
if (!PROJECT_ID) {
console.log('no project specified');
return 'No project specified';
}
_setAuthCredential();
const billingEnabled = await _isBillingEnabled(PROJECT_NAME);
if (billingEnabled) {
if (pubsubData.costAmount >= 1000) {
console.log('disabling billing');
await sendDiscordMessage(
'error',
'Warning',
`Stopping billing as the current usage is at ${pubsubData.costAmount}, past the budget set at ${pubsubData.budgetAmount}`
);
return; /* _disableBillingForProject(PROJECT_NAME); */
}
} else {
console.log('billing already disabled');
return 'Billing already disabled';
}
};
exports.stopBilling = stopBilling;
// You need to setup a budget and link it at the pub/sub *topics*
// Example of message payload sent from the budget trigger at
// https://console.cloud.google.com/cloudpubsub/topic/detail/budgets-control
// {
// "budgetDisplayName": "name-of-budget",
// "alertThresholdExceeded": 1.0,
// "costAmount": 100.01,
// "costIntervalStart": "2019-01-01T00:00:00Z",
// "budgetAmount": 100.00,
// "budgetAmountType": "SPECIFIED_AMOUNT",
// "currencyCode": "USD"
// }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment