sails.log('Syncing Fleet instance data with Vanta for '+allActiveVantaConnections.length+(allActiveVantaConnections.length>1?' connections.':' connection.'));
// Create an empty object to store caught errors. We don't want this script to stop running if there is an error with a single Vanta integration, so instead, we'll store any errors that occur and bail early for that connection if any occur, and we'll log them individually before the script is done.
// Create a second empty object to store errors from the hosts/:id endpoint. If a there is an error getting detailed information about a host, then the script will continue and the host will not be included in the hosts sent to Vanta.
.tolerate((err)=>{// If an error occurs while sending a request to the Fleet instance, we'll add the error to the errorReportById object, with this connections ID set as the key.
errorReportById[connectionIdAsString]=newError(`When sending a request to the /users endpoint of a Fleet instance for a VantaConnection (id: ${connectionIdAsString}), the Fleet instance returned an Error: ${util.inspect(err.raw)}`);
});
}catch(error){
errorReportById[connectionIdAsString]=newError(`When sending a request to the /users endpoint of a Fleet instance for a VantaConnection (id: ${connectionIdAsString}), the Fleet instance returned an Error: ${util.inspect(error.raw)}`);
// Set the permissionLevel using the user's global_role value.
letpermissionLevel='BASE';
if(user.global_role==='admin'){
permissionLevel='ADMIN';
}elseif(user.global_role==='maintainer'){
permissionLevel='EDITOR';
}
// Create a user object for this Fleet user.
letuserToSyncWithVanta={
displayName:user.name,
uniqueId:String(user.id),// Vanta requires this value to be a string.
fullName:user.name,
accountName:user.name,
email:user.email,
createdTimestamp:user.created_at,
status:'ACTIVE',// Always set to 'ACTIVE', if a user is removed from the Fleet instance, it will not be included in the response from the Fleet instance's /users endpoint.
.tolerate(()=>{// If an error occurs while sending a request to the Fleet instance, we'll add the error to the errorReportById object, with this connections ID set as the key.
errorReportById[connectionIdAsString]=newError(`When requesting all hosts from a Fleet instance for a VantaConnection (id: ${connectionIdAsString}), the Fleet instance did not respond with all of it's hosts in the set amount of time.`);
});
if(errorReportById[connectionIdAsString]){// If an error occured in the previous request, we'll bail early for this connection.
osName:'macOS',// Setting the osName for all macOS hosts to 'macOS'. Different versions of macOS have different prefixes, (e.g., a macOS host running 12.6 would be returned as "macOS 12.6.1", while a mac running version 10.15.7 would be displayed as "Mac OS X 10.15.7")
osVersion:host.os_version.replace(/^([\D]+)\s(.+)/g,'$2'),// removing everything but the version number (XX.XX.XX) from the host's os_version value.
hardwareUuid:host.uuid,
serialNumber:host.hardware_serial,
applications:[],
browserExtensions:[],
drives:[],
users:[],// Sending an empty array of users.
systemScreenlockPolicies:[],// Sending an empty array of screenlock policies.
isManaged:false,// Defaulting to false
autoUpdatesEnabled:false,// Always sending this value as false
// If the host has an mdm property, set the `isManaged` parameter to true if the hosts's mdm enrollment_status is either "On (automatic)" or "On (manual)")
// If this host's MDM status is pending (MDM is not yet fully turned on for this host), then it doesn't have comprehensive vitals nor a complete host details page thus we'll exclude it from the hosts we sync with Vanta.
// More info about pending hosts: https://github.com/fleetdm/fleet/blob/3cc7c971c2c24e28d06323c329475ae32e9a8198/docs/Using-Fleet/MDM-setup.md#pending-hosts
hostApiErrorReportById[connectionIdAsString].push(newError(`When sending a request to the Fleet instance's /hosts/${host.id} endpoint for a Vanta connection (id: ${connectionIdAsString}), an error occurred: ${util.inspect(error.raw)}`));
softwareToAdd.browser=software.source.toUpperCase().split('_')[0];// Get the uppercased first word of the software source, this will either be CHROME or FIREFOX.
softwareToAdd.extensionId=software.name+' '+software.version;// Set the extensionId to be the software's name and the software version.
if(software.extension_id!==undefined&&software.extension_id!==null){// If the Fleet instance reported an extension_id for the extension, we'll use that value.
softwareToAdd.name+=' '+software.version;// Add the version to the software name
softwareToAdd.bundleId=software.bundle_identifier?software.bundle_identifier:' ';// If the software is missing a bundle identifier, we'll set it to a blank string.
}).tolerate((err)=>{// If an error occurs while sending requests for each host, add the error to the errorReportById object.
errorReportById[connectionIdAsString]=newError(`When building an array of macOS hosts for a Vanta connection (id: ${connectionIdAsString}), an error occured: ${err}`);
if(errorReportById[connectionIdAsString]){// If an error occured (that was not related to an API request) while gathering detailed host information, we'll bail early for this connection.
// If the host has an mdm property, set the `isManaged` parameter to true if the hosts's mdm enrollment_status is either "On (automatic)" or "On (manual)")
hostApiErrorReportById[connectionIdAsString].push(newError(`When sending a request to the Fleet instance's /hosts/${host.id} endpoint for a Vanta connection (id: ${connectionIdAsString}), an error occurred: ${util.inspect(error.raw)}`));
}
// If an error occured when sending a request to get detailed information about a host, add an error to the array of errors for this Vanta connection, and skip this host.
softwareToAdd.browser=software.source.toUpperCase().split('_')[0];// Get the uppercased first word of the software source, this will either be CHROME or FIREFOX.
softwareToAdd.extensionId=software.name+' '+software.version;// Set the extensionId to be the software's name and the software version.
if(software.extension_id!==undefined&&software.extension_id!==null){// If the Fleet instance reported an extension_id for this extension, we'll use that value.
}).tolerate((err)=>{// If an error occurs while sending requests for each host, add the error to the errorReportById object.
errorReportById[connectionIdAsString]=newError(`When building an array of Windows hosts for a Vanta connection (id: ${connectionIdAsString}), an error occured: ${err}`);
});// After every Windows host
if(errorReportById[connectionIdAsString]){// If an error occured (that was not related to an API request) while gathering detailed host information, we'll bail early for this connection.
errorReportById[connectionIdAsString]=newError(`vantaError: When sending a PUT request to the Vanta's '/user_account/sync_all' endpoint for a Vanta connection (id: ${connectionIdAsString}), an error occurred: ${util.inspect(error.raw)}`);
errorReportById[connectionIdAsString]=newError(`vantaError: When sending a PUT request to the Vanta's '/macos_user_computer/sync_all' endpoint for a Vanta connection (id: ${connectionIdAsString}), an error occurred: ${util.inspect(error.raw)}`);
errorReportById[connectionIdAsString]=newError(`vantaError: When sending a PUT request to the Vanta's '/macos_user_computer/sync_all' endpoint for a Vanta connection (id: ${connectionIdAsString}), an error occurred: ${util.inspect(error.raw)}`);
sails.log.warn('p1: An error occurred while syncing the vanta connection for VantaCustomer with id '+connectionIdAsString+'. Logged error:\n'+errorReportById[connectionIdAsString]);
sails.log.warn('p1: An error occurred while sending API requests to get information about a host for a VantaCustomer with id '+connectionIdAsString+'. Logged error:\n'+error);
sails.log('Information has been sent to Vanta for '+(allActiveVantaConnections.length-numberOfLoggedErrors)+(allActiveVantaConnections.length-numberOfLoggedErrors>1||numberOfLoggedErrors===allActiveVantaConnections.length?' connections.':' connection.'));