I recently posted a project to accomplish a similar task of cloning a switch with a simple web app. https://community.meraki.com/t5/Solutions-APIs/Meraki-Switch-Swapper/m-p/53897#M1613 The project is built with VueJS so it's not an exact answer to your question regarding Postman. The basic web app flow: - API call to pull source switch settings - API call to pull source switch ports - pull similar switch from inventory or same network - clone switch by creating an action batch to make all changes - loop each second to check status of action batch Ultimately, you will want to use Action Batches to accomplish this in the most efficient way. tl;dr The SwitchClone component that handles the clone logic. example of "onClone" function within this Vue.js component. onClone() {
console.log(
"Cloning Switches, this.oldSwitchDetails.serial, this.newSwitchDetails.serial",
this.oldSwitchDetails.serial,
this.newSwitchDetails.serial
);
// set new switch settings/ports to that of old switch and remove hard coded properties
let switchDetails = {};
switchDetails = { ...switchDetails, ...this.oldSwitchDetails };
delete switchDetails.serial;
delete switchDetails.mac;
console.log(
"Cloning Switches AFTER MODs, this.oldSwitchDetails.serial, this.newSwitchDetails.serial",
this.oldSwitchDetails.serial,
this.newSwitchDetails.serial
);
this.loading = true;
this.batchUpdateSwitch(
this.orgId,
this.netId,
this.oldSwitchPorts,
switchDetails,
this.newSwitchDetails.serial
).then(res => {
this.actionBatchDetails = res;
if (!this.actionBatchDetails) {
return;
}
// pull batch status (improve logic)
let statusInterval = setInterval(() => {
console.log("statusInterval");
this.checkBatchUpdateStatus(
this.orgId,
this.actionBatchDetails.id
).then(res => {
console.log("statusInterval", res);
this.actionBatchDetails = res;
// Handle Clone Results
if (
this.actionBatchDetails.status.completed ||
this.actionBatchDetails.status.failed
) {
console.log("clearing statusInterval");
clearInterval(statusInterval);
}
if (this.actionBatchDetails.status.completed) {
this.$emit("updatedSwitchDetails", this.updatedSwitchDetails);
// refresh updated device details
this.fetchSwitchDetails(this.newSwitchDetails.serial)
.then(res => {
this.updatedSwitchDetails = res;
this.$emit("updatedSwitchDetails", this.updatedSwitchDetails);
return res;
})
.then(res => {
return this.fetchSwitchPorts(this.newSwitchDetails.serial);
})
.then(res => {
this.updatedSwitchPorts = res;
this.$emit("updatedSwitchPorts", this.updatedSwitchPorts);
return res;
})
.then(res => {
this.successDialog = true;
})
.catch(e => this.handleError(e))
.finally(() => {
this.loading = false;
});
}
if (this.actionBatchDetails.status.failed) {
// Batch updated
this.failDialog = true;
this.loading = false;
}
});
}, 2000); // wait 2 seconds and get status
});
}, You could modify this application to accept switches of different model types. The SwapForm component defines the filter logic. I just check for matching models but this could easily be adjusted. unusedAndNetworkSwitchesModelMatch() {
return this.form.orgInventory.filter(i => {
return (
(i.networkId == this.network.id || !i.networkId) &&
i.model == this.form.oldSwitchDetails.model &&
i.serial != this.form.oldSwitchDetails.serial
);
}); Regarding the Python library setting empty properties as `null`, this is being investigated as a bug with the dynamic SDKs. Hope this helps!
... View more