Msp dash: follow-up changes to software page after QA (#23210)

https://github.com/fleetdm/fleet/issues/21928#issuecomment-2436371970

Changes:
- updated the edit-software endpoint to make sure that text values
related to software installers (pre-install query, install script,
post-install script, uninstall script) are updated for all teams when
software is edited, and to delete software on the fleet instance when
the installer is replaced and all teams are removed.
- updated the ace editor component to emit an input event when text is
pasted inside of it.
- Updated the error messages in the upload software modal
- Fixed an issue where the edit software endpoint would return a 400
response when all teams are removed from a software installer when a new
installer package is provided.
This commit is contained in:
Eric 2024-10-24 17:00:01 -05:00 committed by GitHub
parent 0a612a06b4
commit d694d0572f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 60 additions and 23 deletions

View file

@ -61,7 +61,12 @@ module.exports = {
// let { Readable } = require('stream');
let axios = require('axios');
// Cast the strings in the newTeamIds array to numbers.
newTeamIds = newTeamIds.map(Number);
if(newTeamIds){
newTeamIds = newTeamIds.map(Number);
} else {
newTeamIds = [];
}
let currentSoftwareTeamIds = _.pluck(software.teams, 'fleetApid');
// If the teams have changed, or a new installer package was provided, we'll need to upload the package to an s3 bucket to deploy it to other teams.
if(_.xor(newTeamIds, currentSoftwareTeamIds).length !== 0 || newSoftware) {
@ -248,6 +253,28 @@ module.exports = {
});
// console.timeEnd(`transfering ${software.name} to fleet instance for team id ${teamApid}`);
});// After every team the software is currently deployed to.
} else if(preInstallQuery !== software.preInstallQuery ||
installScript !== software.installScript ||
postInstallScript !== software.postInstallScript ||
uninstallScript !== software.uninstallScript) {
await sails.helpers.flow.simultaneouslyForEach(unchangedTeamIds, async (teamApid)=>{
await sails.helpers.http.sendHttpRequest.with({
method: 'PATCH',
baseUrl: sails.config.custom.fleetBaseUrl,
url: `/api/v1/fleet/software/titles/${software.fleetApid}/package?team_id=${teamApid}`,
enctype: 'multipart/form-data',
headers: {
Authorization: `Bearer ${sails.config.custom.fleetApiToken}`
},
body: {
team_id: teamApid, // eslint-disable-line camelcase
pre_install_query: preInstallQuery, // eslint-disable-line camelcase
install_script: installScript, // eslint-disable-line camelcase
post_install_script: postInstallScript, // eslint-disable-line camelcase
uninstall_script: uninstallScript, // eslint-disable-line camelcase
}
});
});
}
// Now delete the software from teams it was removed from.
for(let team of removedTeams) {
@ -275,7 +302,11 @@ module.exports = {
uploadFd: softwareFd,
uploadMime: softwareMime,
name: softwareName,
platform: _.endsWith(softwareName, '.deb') ? 'Linux' : _.endsWith(softwareName, '.pkg') ? 'macOS' : 'Windows',
platform: software.platform,
postInstallScript,
preInstallQuery,
installScript,
uninstallScript,
});
} else {
// Save the information about the undeployed software in the app's DB.
@ -289,17 +320,17 @@ module.exports = {
installScript,
uninstallScript,
});
// Now delete the software on the Fleet instance.
for(let team of software.teams) {
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=${team.fleetApid}`,
headers: {
Authorization: `Bearer ${sails.config.custom.fleetApiToken}`,
}
});
}
}
// Now delete the software on the Fleet instance.
for(let team of software.teams) {
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=${team.fleetApid}`,
headers: {
Authorization: `Bearer ${sails.config.custom.fleetApiToken}`,
}
});
}
} else {
@ -308,6 +339,10 @@ module.exports = {
name: softwareName,
uploadMime: softwareMime,
uploadFd: softwareFd,
preInstallQuery,
installScript,
postInstallScript,
uninstallScript,
});
// console.log('removing old stored copy of '+softwareName);
await sails.rm(sails.config.uploads.prefixForFileDeletion+software.uploadFd);

View file

@ -47,7 +47,7 @@ parasails.registerComponent('aceEditor', {
// ╩ ╩ ╩ ╩ ╩╩═╝
template: `
<div class="ace-editor-container">
<div @input="inputDefaultItemField($event)" style="height: 300px;" :id="'editor' + uniqueId" :do-set="_getCurriedDoSetFn()">{{value}}</div>
<div @input="inputDefaultItemField($event)" @paste="inputDefaultItemField($event)" style="height: 300px;" :id="'editor' + uniqueId" :do-set="_getCurriedDoSetFn()">{{value}}</div>
</div>
`,

View file

@ -60,13 +60,13 @@ parasails.registerPage('software', {
}
},
clickOpenEditModal: async function(software) {
this.softwareToEdit = _.clone(software);
this.softwareToEdit = _.cloneDeep(software);
this.formData.newTeamIds = _.pluck(this.softwareToEdit.teams, 'fleetApid');
this.formData.software = software;
this.formData.preInstallQuery = software.preInstallQuery;
this.formData.installScript = software.installScript;
this.formData.postInstallScript = software.postInstallScript;
this.formData.uninstallScript = software.uninstallScript;
this.formData.preInstallQuery = this.softwareToEdit.preInstallQuery;
this.formData.installScript = this.softwareToEdit.installScript;
this.formData.postInstallScript = this.softwareToEdit.postInstallScript;
this.formData.uninstallScript = this.softwareToEdit.uninstallScript;
this.modal = 'edit-software';
},
clickOpenDeleteModal: async function(software) {
@ -108,9 +108,11 @@ parasails.registerPage('software', {
this.softwareToDisplay = softwareOnThisTeam;
},
handleSubmittingEditSoftwareForm: async function() {
let argins = _.clone(this.formData);
if(argins.newTeamIds === [undefined]){
argins.newTeamIds = [];
let argins = _.cloneDeep(this.formData);
if(argins.newTeamIds[0] === undefined){
argins.newTeamIds = undefined;
} else {
argins.newTeamIds = _.uniq(argins.newTeamIds);
}
await Cloud.editSoftware.with(argins);
if(!this.cloudError) {

View file

@ -187,7 +187,7 @@
<multifield :value="formData.teams" v-model="formData.teams" input-type="teamSelect" :select-options="teams" add-button-text="Add team"></multifield>
</div>
<div class="invalid-feedback text-center" v-if="formErrors.teams">Please select the teams you want to deploy this software to.</div>
<cloud-error v-if="cloudError && cloudError === 'softwareWithThisNameAlreadyExists'">A software with the same name as the uploaded software already exists on one or more of the selected teams.</cloud-error>
<cloud-error v-if="cloudError && cloudError === 'softwareAlreadyExistsOnThisTeam'">A software with the same name as the uploaded software already exists on one or more of the selected teams.</cloud-error>
<cloud-error v-else-if="cloudError"></cloud-error>
<div purpose="modal-buttons" class="d-flex flex-row justify-content-end align-items-center">
<a purpose="cancel-button" @click="closeModal()">Cancel</a>