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

    Promise.all([
      Db.getClusterSettings({ flat_settings: true, include_defaults: true, cluster: req.query.cluster }),
      Db.getILMPolicy(req.query.cluster),
      Db.getTemplate('sessions3_template', req.query.cluster)
    ]).then(([{ body: settings }, ilm, { body: template }]) => {
      const rsettings = [];

      function getValue (key) {
        return settings.transient[key] || settings.persistent[key] || settings.defaults[key];
      }

      function addSetting (key, type, settingName, url, regex, current) {
        if (current === undefined) { current = getValue(key); }
        if (current === undefined) { return; }
        rsettings.push({ key, current, name: settingName, type, url, regex });
      }

      addSetting('search.max_buckets', 'Integer',
        'Max Aggregation Size',
        'https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket.html',
        '^(|null|\\d+)$');

      addSetting('arkime.disk.watermarks', '3 Percent or Byte Values',
        'Disk Watermark Low,High,Flood',
        'https://www.elastic.co/guide/en/elasticsearch/reference/current/disk-allocator.html',
        '^(|null|\\d*\\.?\\d+(%|b|kb|mb|gb|tb|pb),\\d*\\.?\\d+(%|b|kb|mb|gb|tb|pb),\\d*\\.?\\d+(%|b|kb|mb|gb|tb|pb))$',
        getValue('cluster.routing.allocation.disk.watermark.low') + ',' +
        getValue('cluster.routing.allocation.disk.watermark.high') + ',' +
        getValue('cluster.routing.allocation.disk.watermark.flood_stage')
      );

      addSetting('cluster.routing.allocation.enable', 'Mode',
        'Allocation Mode',
        'https://www.elastic.co/guide/en/elasticsearch/reference/current/shards-allocation.html',
        '^(all|primaries|new_primaries|none)$');

      addSetting('cluster.routing.allocation.cluster_concurrent_rebalance', 'Integer',
        'Concurrent Rebalances',
        'https://www.elastic.co/guide/en/elasticsearch/reference/current/shards-allocation.html',
        '^(|null|\\d+)$');

      addSetting('cluster.routing.allocation.node_concurrent_recoveries', 'Integer',
        'Concurrent Recoveries',
        'https://www.elastic.co/guide/en/elasticsearch/reference/current/shards-allocation.html',
        '^(|null|\\d+)$');

      addSetting('cluster.routing.allocation.node_initial_primaries_recoveries', 'Integer',
        'Initial Primaries Recoveries',
        'https://www.elastic.co/guide/en/elasticsearch/reference/current/shards-allocation.html',
        '^(|null|\\d+)$');

      addSetting('cluster.max_shards_per_node', 'Integer',
        'Max Shards per Node',
        'https://www.elastic.co/guide/en/elasticsearch/reference/master/misc-cluster.html',
        '^(|null|\\d+)$');

      addSetting('indices.recovery.max_bytes_per_sec', 'Byte Value',
        'Recovery Max Bytes per Second',
        'https://www.elastic.co/guide/en/elasticsearch/reference/current/recovery.html',
        '^(|null|\\d+(b|kb|mb|gb|tb|pb))$');

      addSetting('cluster.routing.allocation.awareness.attributes', 'List of Attributes',
        'Shard Allocation Awareness',
        'https://www.elastic.co/guide/en/elasticsearch/reference/current/allocation-awareness.html',
        '^(|null|[a-z0-9_,-]+)$');

      addSetting('indices.breaker.total.limit', 'Percent',
        'Breaker - Total Limit',
        'https://www.elastic.co/guide/en/elasticsearch/reference/current/circuit-breaker.html',
        '^(|null|\\d+%)$');

      addSetting('indices.breaker.fielddata.limit', 'Percent',
        'Breaker - Field data',
        'https://www.elastic.co/guide/en/elasticsearch/reference/current/circuit-breaker.html',
        '^(|null|\\d+%)$');

      addSetting('arkime.sessions.shards', 'Integer',
        'Sessions - Number of shards for FUTURE sessions3 indices',
        'https://www.elastic.co/guide/en/elasticsearch/reference/current/index-modules.html#index-number-of-shards',
        '^\\d+$',
        template[`${prefix}sessions3_template`].settings['index.number_of_shards']);

      addSetting('arkime.sessions.replicas', 'Integer',
        'Sessions - Number of replicas for FUTURE sessions3 indices',
        'https://www.elastic.co/guide/en/elasticsearch/reference/current/index-modules.html#index-number-of-replicas',
        '^\\d+$',
        template[`${prefix}sessions3_template`].settings['index.number_of_replicas'] || 0);

      addSetting('arkime.sessions.shards_per_node', 'Empty or Integer',
        'Sessions - Number of shards_per_node for FUTURE sessions3 indices',
        'https://www.elastic.co/guide/en/elasticsearch/reference/current/allocation-total-shards.html',
        '^(|\\d+)$',
        template[`${prefix}sessions3_template`].settings['index.routing.allocation.total_shards_per_node'] || '');

      function addIlm (key, current, ilmName, type, regex) {
        rsettings.push({ key, current, name: ilmName, type, url: 'https://arkime.com/faq#ilm', regex });
      }

      if (ilm[`${prefix}molochsessions`]) {
        const silm = ilm[`${prefix}molochsessions`];
        addIlm('arkime.ilm.sessions.forceTime', silm.policy.phases.warm.min_age,
          'ILM - Move to warm after', 'Time String', '^\\d+[hd]$');
        addIlm('arkime.ilm.sessions.replicas', silm.policy.phases.warm.actions.allocate.number_of_replicas,
          'ILM - Number of replicas after setting to warm', 'Integer', '^\\d$');
        addIlm('arkime.ilm.sessions.segments', silm.policy.phases.warm.actions.forcemerge.max_num_segments,
          'ILM - Number of segments after setting to warm', 'Integer', '^\\d$');
        addIlm('arkime.ilm.sessions.deleteTime', silm.policy.phases.delete.min_age,
          'ILM - Delete session index after', 'Time String', '^\\d+[hd]$');
      }

      if (ilm[`${prefix}molochhistory`]) {
        const hilm = ilm[`${prefix}molochhistory`];
        addIlm('arkime.ilm.history.deleteTime', hilm.policy.phases.delete.min_age,
          'ILM - Delete History index after', 'Time String', '^\\d+[hd]$');
      }

      return res.send(rsettings);
    });
  }
GET - /api/esadmin

Fetches all OpenSearch/Elasticsearch settings that a user can change (es admin only - set in config with <a href="settings#esadminusers">esAdminUsers</a>).
@name /esadmin
@returns {array} settings - List of ES settings that a user can change