
<h3 class="page-heading">PostgreSQL Connection</h3>

<div class="gf-form-group">
  <div class="gf-form max-width-30">
    <span class="gf-form-label width-10">Host</span>
    <input type="text" class="gf-form-input" ng-model='ctrl.current.url' placeholder="localhost:5432"
     bs-typeahead="{{['localhost:5432', 'localhost:5433']}}" required></input>
  </div>

  <div class="gf-form max-width-30">
    <span class="gf-form-label width-10">Database</span>
    <input type="text" class="gf-form-input" ng-model='ctrl.current.database' placeholder="database name" required></input>
  </div>

  <div class="gf-form-inline">
    <div class="gf-form max-width-15">
      <span class="gf-form-label width-10">User</span>
      <input type="text" class="gf-form-input" ng-model='ctrl.current.user' placeholder="user"></input>
    </div>
    <div class="gf-form">
      <secret-form-field
        isConfigured="ctrl.current.secureJsonFields.password"
        value="ctrl.current.secureJsonData.password"
        on-reset="ctrl.onPasswordReset"
        on-change="ctrl.onPasswordChange"
        inputWidth="9"
      />
    </div>
  </div>

  <div class="gf-form">
    <label class="gf-form-label width-10">TLS/SSL Mode</label>
    <div class="gf-form-select-wrapper max-width-15 gf-form-select-wrapper--has-help-icon">
      <select class="gf-form-input" ng-model="ctrl.current.jsonData.sslmode"
        ng-options="mode for mode in ['disable', 'require', 'verify-ca', 'verify-full']"
        ng-init="ctrl.current.jsonData.sslmode" ng-change="ctrl.tlsModeMapping()"></select>
      <info-popover mode="right-absolute">
        This option determines whether or with what priority a secure TLS/SSL TCP/IP connection will be negotiated with the server.
      </info-popover>
    </div>
  </div>

  <div class="gf-form" ng-if="ctrl.current.jsonData.sslmode != 'disable'">
    <label class="gf-form-label width-10">TLS/SSL Method</label>
    <div class="gf-form-select-wrapper max-width-15 gf-form-select-wrapper--has-help-icon">
      <select class="gf-form-input" ng-model="ctrl.current.jsonData.tlsConfigurationMethod"
        ng-options="f.id as f.label for f in [{ id: 'file-path', label: 'File system path' }, { id: 'file-content', label: 'Certificate  content' }]"
        ng-init="ctrl.current.jsonData.tlsConfigurationMethod"></select>
      <info-popover mode="right-absolute">
        This option determines how TLS/SSL certifications are configured. Selecting <i>File system path</i> will allow
        you to configure certificates by specifying paths to existing certificates on the local file system where
        Grafana is running. Be sure that the file is readable by the user executing the Grafana process.<br><br>

        Selecting <i>Certificate content</i> will allow you to configure certificates by specifying its content.
        The content will be stored encrypted in Grafana's database. When connecting to the database the certificates
        will be written as files to Grafana's configured data path on the local file system.
      </info-popover>
    </div>
  </div>
</div>

<div class="gf-form-group" ng-if="ctrl.current.jsonData.sslmode != 'disable' && ctrl.current.jsonData.tlsConfigurationMethod === 'file-path'">
  <div class="gf-form">
    <h6>TLS/SSL Auth Details</h6>
  </div>
  <div class="gf-form max-width-30">
    <span class="gf-form-label width-10">TLS/SSL Root Certificate</span>
    <input type="text" class="gf-form-input gf-form-input--has-help-icon"
      ng-model='ctrl.current.jsonData.sslRootCertFile' placeholder="TLS/SSL root cert file"></input>
    <info-popover mode="right-absolute">
    If the selected TLS/SSL mode requires a server root certificate, provide the path to the file here.
    </info-popover>
  </div>
  <div class="gf-form max-width-30">
    <span class="gf-form-label width-10">TLS/SSL Client Certificate</span>
    <input type="text" class="gf-form-input gf-form-input--has-help-icon" ng-model='ctrl.current.jsonData.sslCertFile'
      placeholder="TLS/SSL client cert file"></input>
    <info-popover mode="right-absolute">
      To authenticate with an TLS/SSL client certificate, provide the path to the file here.
      Be sure that the file is readable by the user executing the grafana process.
    </info-popover>
  </div>
  <div class="gf-form max-width-30">
    <span class="gf-form-label width-10">TLS/SSL Client Key</span>
    <input type="text" class="gf-form-input gf-form-input--has-help-icon" ng-model='ctrl.current.jsonData.sslKeyFile'
      placeholder="TLS/SSL client key file"></input>
    <info-popover mode="right-absolute">
      To authenticate with a client TLS/SSL certificate, provide the path to the corresponding key file here.
      Be sure that the file is <i>only</i> readable by the user executing the grafana process.
    </info-popover>
  </div>
</div>
<datasource-tls-auth-settings current="ctrl.current"
  ng-if="ctrl.current.jsonData.sslmode != 'disable' && ctrl.current.jsonData.tlsConfigurationMethod === 'file-content'">
</datasource-tls-auth-settings>

<b>Connection limits</b>

<div class="gf-form-group">
  <div class="gf-form max-width-15">
    <span class="gf-form-label width-7">Max open</span>
    <input type="number" min="0" class="gf-form-input gf-form-input--has-help-icon"
      ng-model="ctrl.current.jsonData.maxOpenConns" placeholder="unlimited"></input>
    <info-popover mode="right-absolute">
      The maximum number of open connections to the database. If <i>Max idle connections</i> is greater than 0 and the
      <i>Max open connections</i> is less than <i>Max idle connections</i>, then <i>Max idle connections</i> will be
      reduced to match the <i>Max open connections</i> limit. If set to 0, there is no limit on the number of open
      connections.
    </info-popover>
  </div>
  <div class="gf-form max-width-15">
    <span class="gf-form-label width-7">Max idle</span>
    <input type="number" min="0" class="gf-form-input gf-form-input--has-help-icon"
      ng-model="ctrl.current.jsonData.maxIdleConns" placeholder="2"></input>
    <info-popover mode="right-absolute">
      The maximum number of connections in the idle connection pool. If <i>Max open connections</i> is greater than 0 but
      less than the <i>Max idle connections</i>, then the <i>Max idle connections</i> will be reduced to match the
      <i>Max open connections</i> limit. If set to 0, no idle connections are retained.
    </info-popover>
  </div>
  <div class="gf-form max-width-15">
    <span class="gf-form-label width-7">Max lifetime</span>
    <input type="number" min="0" class="gf-form-input gf-form-input--has-help-icon"
      ng-model="ctrl.current.jsonData.connMaxLifetime" placeholder="14400"></input>
    <info-popover mode="right-absolute">
      The maximum amount of time in seconds a connection may be reused. If set to 0, connections are reused forever.
    </info-popover>
  </div>
</div>

<h3 class="page-heading">PostgreSQL details</h3>

<div class="gf-form-group">
  <div class="gf-form">
    <span class="gf-form-label width-9">
      Version
      <info-popover mode="right-normal" position="top center">
        This option controls what functions are available in the PostgreSQL query builder.
      </info-popover>
    </span>
    <span class="gf-form-select-wrapper">
      <select class="gf-form-input gf-size-auto" ng-model="ctrl.current.jsonData.postgresVersion"
        ng-options="f.value as f.name for f in ctrl.postgresVersions"></select>
    </span>
  </div>
  <div class="gf-form">
    <gf-form-switch class="gf-form" label="TimescaleDB" label-class="width-9"
      checked="ctrl.current.jsonData.timescaledb" switch-class="max-width-6"></gf-form-switch>
    <label class="gf-form-label query-keyword pointer" ng-click="ctrl.toggleTimescaleDBHelp()">
      Help&nbsp;
      <icon name="'angle-down'" ng-show="ctrl.showTimescaleDBHelp"></icon>
      <icon name="'angle-right'" ng-hide="ctrl.showTimescaleDBHelp">&nbsp;</icon>
    </label>
  </div>

  <div class="gf-form-inline">
    <div class="gf-form">
      <span class="gf-form-label width-9">Min time interval</span>
      <input
        type="text"
        class="gf-form-input width-6 gf-form-input--has-help-icon"
        ng-model="ctrl.current.jsonData.timeInterval"
        spellcheck='false'
        placeholder="1m"
        ng-pattern="/^\d+(ms|[Mwdhmsy])$/"
      ></input>
      <info-popover mode="right-absolute">
        A lower limit for the auto group by time interval. Recommended to be set to write frequency,
        for example <code>1m</code> if your data is written every minute.
      </info-popover>
    </div>
  </div>
  <div class="grafana-info-box alert alert-info" ng-show="ctrl.showTimescaleDBHelp">
    <div class="alert-body">
      <p>
        <a href="https://github.com/timescale/timescaledb" class="pointer" target="_blank">TimescaleDB</a> is a
        time-series database built as a PostgreSQL extension. If enabled, Grafana will use <code>time_bucket</code> in
        the <code>$__timeGroup</code> macro and display TimescaleDB specific aggregate functions in the query builder.
      </p>
    </div>
  </div>
</div>

<div class="gf-form-group">
  <div class="grafana-info-box">
    <h5>User Permission</h5>
    <p>
      The database user should only be granted SELECT permissions on the specified database &amp; tables you want to query.
      Grafana does not validate that queries are safe so queries can contain any SQL statement. For example, statements
      like <code>DELETE FROM user;</code> and <code>DROP TABLE user;</code> would be executed. To protect against this we
      <strong>Highly</strong> recommmend you create a specific PostgreSQL user with restricted permissions.
    </p>
  </div>
</div>
