Msp dashboard: Update error handling in software related actions (#24283)

Changes:
- Updated the edit-software endpoint to:
- log a detailed warning when a request to get a stream of an existing
software installer returns a non-200 repsonse
- Use the modify package API endpoint when a software installer is
replaced.
- include the nested response from the Fleet instance in error messages
- Updated the delete-software endpoint to return a
'softwareDeletionFailed` exit when a specified software installer is
included in the macOS setup experience and cannot be deleted via API
requests.
- Updated the software page to show an error message with a link to the
controls page on the connected Fleet instance if the delete-software
endpoint returns a `softwareDeletionFailed` exit
This commit is contained in:
Eric 2024-12-02 14:46:07 -06:00 committed by GitHub
parent 4b5de2646a
commit 6d468cada4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 19 additions and 16 deletions

View file

@ -16,7 +16,10 @@ module.exports = {
exits: {
softwareDeletionFailed: {
description: 'The specified software could not be deleted from the Fleet instance.',
statusCode: 409,
}
},
@ -34,6 +37,11 @@ module.exports = {
headers: {
Authorization: `Bearer ${sails.config.custom.fleetApiToken}`,
}
})
.intercept({raw:{statusCode: 409}}, (error)=>{
// If the Fleet instance's returns a 409 response, then the software is configured to be installed as
// part of the macOS setup experience, and must be removed before it can be deleted via API requests.
return {softwareDeletionFailed: error};
});
}
}

View file

@ -84,6 +84,9 @@ module.exports = {
headers: {
Authorization: `Bearer ${sails.config.custom.fleetApiToken}`,
}
})
.intercept('non200Response', (error)=>{
return new Error(`When attempting to transfer the installer for ${software.name} to a new team on the Fleet instance, the Fleet isntance returned a non-200 response when a request was sent to get a download stream of the installer on team_id ${teamIdToGetInstallerFrom}. Full Error: ${require('util').inspect(error, {depth: 1})}`);
});
let tempUploadedSoftware = await sails.uploadOne(softwareStream, {bucket: sails.config.uploads.bucketWithPostfix});
softwareFd = tempUploadedSoftware.fd;
@ -173,7 +176,7 @@ module.exports = {
await sails.rm(sails.config.uploads.prefixForFileDeletion+softwareFd);
}
// Log a warning containing an error
sails.log.warn(`When attempting to upload a software installer, an unexpected error occurred communicating with the Fleet API, ${require('util').inspect(error, {depth: 0})}`);
sails.log.warn(`When attempting to upload a software installer, an unexpected error occurred communicating with the Fleet API, Full error: ${require('util').inspect(error, {depth: 2})}`);
return {'softwareUploadFailed': error};
});
// console.timeEnd(`transfering ${software.name} to fleet instance for team id ${team}`);
@ -183,15 +186,6 @@ module.exports = {
// If a new installer package was provided, send patch requests to update the installer package on teams that it is already deployed to.
await sails.helpers.flow.simultaneouslyForEach(unchangedTeamIds, async (teamApid)=>{
// console.log(`Adding new version of ${softwareName} to teamId ${teamApid}`);
await sails.helpers.http.sendHttpRequest.with({
method: 'DELETE',
baseUrl: sails.config.custom.fleetBaseUrl,
url: `/api/v1/fleet/software/titles/${software.fleetApid}/available_for_install?team_id=${teamApid}`,
headers: {
Authorization: `Bearer ${sails.config.custom.fleetApiToken}`,
}
});
// console.log(`transfering the changed installer ${software.name} to fleet instance for team id ${teamApid}`);
// console.time(`transfering ${software.name} to fleet instance for team id ${teamApid}`);
await sails.cp(softwareFd, {bucket: sails.config.uploads.bucketWithPostfix},
{
@ -220,7 +214,7 @@ module.exports = {
contentType: 'application/octet-stream'
});
(async ()=>{
await axios.post(`${sails.config.custom.fleetBaseUrl}/api/v1/fleet/software/package`, form, {
await axios.patch(`${sails.config.custom.fleetBaseUrl}/api/v1/fleet/software/titles/${software.fleetApid}/package`, form, {
headers: {
Authorization: `Bearer ${sails.config.custom.fleetApiToken}`,
...form.getHeaders()
@ -248,7 +242,7 @@ module.exports = {
await sails.rm(sails.config.uploads.prefixForFileDeletion+softwareFd);
}
// Log a warning containing an error
sails.log.warn(`When attempting to upload a software installer, an unexpected error occurred communicating with the Fleet API, ${require('util').inspect(error, {depth: 0})}`);
sails.log.warn(`When attempting to upload a software installer, an unexpected error occurred communicating with the Fleet API, ${require('util').inspect(error, {depth: 2})}`);
return {'softwareUploadFailed': error};
});
// console.timeEnd(`transfering ${software.name} to fleet instance for team id ${teamApid}`);

View file

@ -106,7 +106,7 @@ module.exports = {
})
.intercept({name: 'AxiosError'}, async (error)=>{
await sails.rm(sails.config.uploads.prefixForFileDeletion+uploadedSoftware.fd);
sails.log.warn(`When attempting to upload a software installer, an unexpected error occurred communicating with the Fleet API, ${require('util').inspect(error, {depth: 0})}`);
sails.log.warn(`When attempting to upload a software installer, an unexpected error occurred communicating with the Fleet API, ${require('util').inspect(error, {depth: 2})}`);
return {'softwareUploadFailed': error};
});
}

View file

@ -104,7 +104,7 @@ module.exports = {
let undeployedSoftware = await UndeployedSoftware.find();
allSoftware = allSoftware.concat(undeployedSoftware);
return {software: allSoftware, teams};
return {software: allSoftware, teams, fleetBaseUrl: sails.config.custom.fleetBaseUrl};
}

View file

@ -163,7 +163,8 @@
</div>
<p>{{formData.software.name}} will be removed from your library.</p>
<ajax-form :handle-submitting="handleSubmittingDeleteSoftwareForm" :syncing.sync="syncing" :cloud-error.sync="cloudError" :form-errors.sync="formErrors" :form-data="formData" :form-rules="editSoftwareFormRules" @submitted="submittedForm()">
<cloud-error v-if="cloudError"></cloud-error>
<cloud-error v-if="cloudError && cloudError === 'softwareDeletionFailed'">This software has been configured to be installed as part of the macOS setup experience and cannot be deleted. Please remove this software from all teams the <a :href="`${fleetBaseUrl}/controls/setup-experience/install-software`" target="_blank">"Setup experience" tab of the Controls page</a> on your Fleet instance and try again </cloud-error>
<cloud-error v-else-if="cloudError"></cloud-error>
<div class="d-flex flex-row justify-content-end align-items-center">
<a class="mr-3" style="color: #D66C7B; cursor: pointer;" @click="closeModal()">Cancel</a>
<ajax-button class="btn" purpose="delete-button" :syncing.sync="syncing">Delete</ajax-button>