static async setESAdminSettings (req, res) {
    if (!ArkimeUtil.isString(req.body.key)) { return res.serverError(500, 'Missing key'); }
    if (!ArkimeUtil.isString(req.body.value, 0)) { return res.serverError(500, 'Missing value'); }

    let prefix = internals.prefix;
    if (req.query.cluster) {
      const details = await Db.getClusterDetails();
      prefix = details.body?.prefix[req.query.cluster];
    }

    // Convert null string to null
    if (req.body.value === 'null') { req.body.value = null; }

    // Must set all 3 at once because of ES bug/feature
    if (req.body.key === 'arkime.disk.watermarks') {
      const query = { body: { persistent: {} }, cluster: req.query.cluster };
      if (req.body.value === '' || req.body.value === null) {
        query.body.persistent['cluster.routing.allocation.disk.watermark.low'] = null;
        query.body.persistent['cluster.routing.allocation.disk.watermark.high'] = null;
        query.body.persistent['cluster.routing.allocation.disk.watermark.flood_stage'] = null;
      } else {
        const parts = req.body.value.split(',');
        if (parts.length !== 3) {
          return res.serverError(500, 'Must be 3 piece of info');
        }

        query.body.persistent['cluster.routing.allocation.disk.watermark.low'] = parts[0];
        query.body.persistent['cluster.routing.allocation.disk.watermark.high'] = parts[1];
        query.body.persistent['cluster.routing.allocation.disk.watermark.flood_stage'] = parts[2];
      }

      try {
        await Db.putClusterSettings(query);
        return res.send(JSON.stringify({
          success: true,
          text: 'Successfully set settings'
        }));
      } catch (err) {
        console.log(`ERROR - ${req.method} /api/esadmin/set`, util.inspect(err, false, 50));
        return res.serverError(500, 'Set failed');
      }
    }

    if (req.body.key.startsWith('arkime.ilm')) {
      Promise.all([Db.getILMPolicy(req.query.cluster)]).then(([ilm]) => {
        const silm = ilm[`${prefix}molochsessions`];
        const hilm = ilm[`${prefix}molochhistory`];

        if (silm === undefined || hilm === undefined) {
          return res.serverError(500, `ILM isn't configured`);
        }

        switch (req.body.key) {
        case 'arkime.ilm.sessions.forceTime':
          silm.policy.phases.warm.min_age = req.body.value;
          break;
        case 'arkime.ilm.sessions.replicas':
          silm.policy.phases.warm.actions.allocate.number_of_replicas = parseInt(req.body.value || 0, 10);
          break;
        case 'arkime.ilm.sessions.segments':
          silm.policy.phases.warm.actions.forcemerge.max_num_segments = parseInt(req.body.value || 0, 10);
          break;
        case 'arkime.ilm.sessions.deleteTime':
          silm.policy.phases.delete.min_age = req.body.value;
          break;
        case 'arkime.ilm.history.deleteTime':
          hilm.policy.phases.delete.min_age = req.body.value;
          break;
        default:
          return res.serverError(500, 'Unknown field');
        }
        if (req.body.key.startsWith('arkime.ilm.history')) {
          Db.setILMPolicy(`${prefix}molochhistory`, hilm, req.query.cluster);
        } else {
          Db.setILMPolicy(`${prefix}molochsessions`, silm, req.query.cluster);
        }
        return res.send(JSON.stringify({ success: true, text: 'Set' }));
      });
      return;
    }

    if (req.body.key.startsWith('arkime.sessions')) {
      Promise.all([Db.getTemplate('sessions3_template', req.query.cluster)]).then(([{ body: template }]) => {
        switch (req.body.key) {
        case 'arkime.sessions.shards':
          template[`${prefix}sessions3_template`].settings['index.number_of_shards'] = req.body.value;
          break;
        case 'arkime.sessions.replicas':
          template[`${prefix}sessions3_template`].settings['index.number_of_replicas'] = req.body.value;
          break;
        case 'arkime.sessions.shards_per_node':
          if (req.body.value === '') {
            delete template[`${prefix}sessions3_template`].settings['index.routing.allocation.total_shards_per_node'];
          } else {
            template[`${prefix}sessions3_template`].settings['index.routing.allocation.total_shards_per_node'] = req.body.value;
          }
          break;
        default:
          return res.serverError(500, 'Unknown field');
        }
        Db.putTemplate('sessions3_template', template[`${prefix}sessions3_template`], req.query.cluster);
        return res.send(JSON.stringify({ success: true, text: 'Successfully set settings' }));
      });
      return;
    }

    const clusterQuery = { body: { persistent: {} }, cluster: req.query.cluster };
    clusterQuery.body.persistent[req.body.key] = req.body.value || null;

    try {
      await Db.putClusterSettings(clusterQuery);
      return res.send(JSON.stringify({
        success: true,
        text: 'Successfully set settings'
      }));
    } catch (err) {
      console.log(`ERROR - ${req.method} /api/esadmin/set`, util.inspect(err, false, 50));
      return res.serverError(500, 'Set failed');
    }
  }
POST - /api/esadmin/set

Sets OpenSearch/Elasticsearch settings (es admin only - set in config with <a href="settings#esadminusers">esAdminUsers</a>).
@name /esadmin/set
@returns {boolean} success - Whether saving the settings was successful.
@returns {string} text - The success/error message to (optionally) display to the user.