UNPKG

sfdx-hardis

Version:

Swiss-army-knife Toolbox for Salesforce. Allows you to define a complete CD/CD Pipeline. Orchestrate base commands and assist users with interactive wizards

239 lines (227 loc) • 9.82 kB
/* jscpd:ignore-start */ import { SfCommand, Flags, requiredOrgFlagWithDeprecations } from '@salesforce/sf-plugins-core'; import { Messages } from '@salesforce/core'; import c from 'chalk'; import { execCommand, uxLog, uxLogTable } from '../../../../common/utils/index.js'; import { CONSTANTS, getConfig, getEnvVar } from '../../../../config/index.js'; Messages.importMessagesDirectoryFromMetaUrl(import.meta.url); const messages = Messages.loadMessages('sfdx-hardis', 'org'); export default class MonitorAll extends SfCommand { static title = 'Monitor org'; static monitoringCommandsDefault = [ { key: 'AUDIT_TRAIL', title: 'Detect suspect setup actions in major org', command: 'sf hardis:org:diagnose:audittrail', frequency: 'daily', }, { key: 'LEGACY_API', title: 'Detect calls to deprecated API versions', command: 'sf hardis:org:diagnose:legacyapi', frequency: 'daily', }, { key: 'ORG_LIMITS', title: 'Detect if org limits are close to be reached', command: 'sf hardis:org:monitor:limits', frequency: 'daily', }, { key: 'UNSECURED_CONNECTED_APPS', title: 'Detect unsecured Connected Apps in an org', command: 'sf hardis:org:diagnose:unsecure-connected-apps', frequency: 'daily', }, { key: 'LICENSES', title: 'Extract licenses information', command: 'sf hardis:org:diagnose:licenses', frequency: 'weekly', }, { key: 'LINT_ACCESS', title: 'Detect custom elements with no access rights defined in permission sets', command: 'sf hardis:lint:access', frequency: 'weekly', }, { key: 'UNUSED_LICENSES', title: 'Detect permission set licenses that are assigned to users that do not need them', command: 'sf hardis:org:diagnose:unusedlicenses', frequency: 'weekly', }, { key: 'UNUSED_USERS', title: 'Detect active users without recent logins', command: 'sf hardis:org:diagnose:unusedusers', frequency: 'weekly', }, { key: 'ACTIVE_USERS', title: 'Detect active users with recent logins', command: 'sf hardis:org:diagnose:unusedusers --returnactiveusers', frequency: 'weekly', }, { key: 'ORG_INFO', title: 'Get org info + SF instance info + next major upgrade date', command: 'sf hardis:org:diagnose:instanceupgrade', frequency: 'weekly', }, { key: 'RELEASE_UPDATES', title: 'Gather warnings about incoming and overdue Release Updates', command: 'sf hardis:org:diagnose:releaseupdates', frequency: 'weekly', }, { key: 'UNUSED_METADATAS', title: 'Detect custom labels and custom permissions that are not in use', command: 'sf hardis:lint:unusedmetadatas', frequency: 'weekly', }, { key: 'UNUSED_APEX_CLASSES', title: 'Detect unused Apex classes in an org', command: 'sf hardis:org:diagnose:unused-apex-classes', frequency: 'weekly', }, { key: 'CONNECTED_APPS', title: 'Detect unused Connected Apps in an org', command: 'sf hardis:org:diagnose:unused-connected-apps', frequency: 'weekly', }, { key: 'METADATA_STATUS', title: 'Detect inactive metadata', command: 'sf hardis:lint:metadatastatus', frequency: 'weekly', }, { key: 'MISSING_ATTRIBUTES', title: 'Detect missing description on custom field', command: 'sf hardis:lint:missingattributes', frequency: 'weekly', }, ]; static description = `Monitor org, generate reports and sends notifications You can disable some commands defining either a **monitoringDisable** property in \`.sfdx-hardis.yml\`, or a comma separated list in env variable **MONITORING_DISABLE** Example in .sfdx-hardis.yml: \`\`\`yaml monitoringDisable: - METADATA_STATUS - MISSING_ATTRIBUTES - UNUSED_METADATAS \`\`\` Example in env var: \`\`\`sh MONITORING_DISABLE=METADATA_STATUS,MISSING_ATTRIBUTES,UNUSED_METADATAS \`\`\` A [default list of monitoring commands](${CONSTANTS.DOC_URL_ROOT}/salesforce-monitoring-home/#monitoring-commands) is used, if you want to override it you can define property **monitoringCommands** in your .sfdx-hardis.yml file Example: \`\`\`yaml monitoringCommands: - title: My Custom command command: sf my:custom:command - title: My Custom command 2 command: sf my:other:custom:command \`\`\` You can force the daily run of all commands by defining env var \`MONITORING_IGNORE_FREQUENCY=true\` The default list of commands is the following: ${this.getDefaultCommandsMarkdown()} `; static examples = ['$ sf hardis:org:monitor:all']; static flags = { debug: Flags.boolean({ char: 'd', default: false, description: messages.getMessage('debugMode'), }), websocket: Flags.string({ description: messages.getMessage('websocket'), }), skipauth: Flags.boolean({ description: 'Skip authentication check when a default username is required', }), 'target-org': requiredOrgFlagWithDeprecations, }; // Set this to true if your command requires a project workspace; 'requiresProject' is false by default static requiresProject = true; // Trigger notification(s) to MsTeams channel static triggerNotification = true; debugMode = false; /* jscpd:ignore-end */ static getDefaultCommandsMarkdown() { const mdLines = [ "| Key | Description | Command | Frequency |", "| :---: | :---- | :---- | :-----: |", ]; for (const cmd of MonitorAll.monitoringCommandsDefault) { const commandDocUrl = `${CONSTANTS.DOC_URL_ROOT}/${cmd.command.split(" ")[1].replaceAll(":", "/")}`; mdLines.push(`| [${cmd.key}](${commandDocUrl}) | ${cmd.title} | [${cmd.command}](${commandDocUrl}) | ${cmd.frequency} |`); } return mdLines.join("\n"); } async run() { const { flags } = await this.parse(MonitorAll); this.debugMode = flags.debug || false; // Build target org full manifest uxLog("action", this, c.cyan('Running monitoring scripts for org ' + c.bold(flags['target-org'].getConnection().instanceUrl)) + ' ...'); const config = await getConfig('user'); const commands = MonitorAll.monitoringCommandsDefault.concat(config.monitoringCommands || []); const monitoringDisable = config.monitoringDisable ?? (process.env?.MONITORING_DISABLE ? process.env.MONITORING_DISABLE.split(',') : []); let success = true; const commandsSummary = []; for (const command of commands) { if (monitoringDisable.includes(command.key)) { uxLog("log", this, c.grey(`Skipped command ${c.bold(command.key)} according to custom configuration`)); continue; } if (command?.frequency === 'weekly' && new Date().getDay() !== 6 && getEnvVar('MONITORING_IGNORE_FREQUENCY') !== 'true') { uxLog("log", this, c.grey(`Skipped command ${c.bold(command.key)} as its frequency is defined as weekly and we are not Saturday`)); continue; } // Run command uxLog("action", this, c.cyan(`Running monitoring command ${c.bold(command.title)} (key: ${c.bold(command.key)})`)); try { const execCommandResult = await execCommand(command.command, this, { fail: false, output: true }); if (execCommandResult.status === 0) { uxLog("success", this, c.green(`Command ${c.bold(command.title)} has been run successfully`)); } else { success = false; uxLog("warning", this, c.yellow(`Command ${c.bold(command.title)} has failed`)); } commandsSummary.push({ title: command.title, status: execCommandResult.status === 0 ? 'success' : 'failure', command: command.command, }); } catch (e) { // Handle unexpected failure success = false; uxLog("warning", this, c.yellow(`Command ${c.bold(command.title)} has failed !\n${e.message}`)); commandsSummary.push({ title: command.title, status: 'error', command: command.command, }); } } uxLog("action", this, c.cyan('Summary of monitoring scripts')); uxLogTable(this, commandsSummary); uxLog("log", this, c.grey('You can check details in reports in Job Artifacts')); uxLog("warning", this, c.yellow(`To know more about sfdx-hardis monitoring, please check ${CONSTANTS.DOC_URL_ROOT}/salesforce-monitoring-home/`)); // Exit code is 1 if monitoring detected stuff if (success === false) { process.exitCode = 1; } return { outputString: 'Monitoring processed on org ' + flags['target-org'].getConnection().instanceUrl }; } } //# sourceMappingURL=all.js.map