Merge pull request #52 from spikegrobstein/add-https-support

add support for pi-hole running behind https
This commit is contained in:
Vincent Composieux 2020-06-06 09:25:54 +02:00 committed by GitHub
commit 9cc2b0206d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 33 additions and 8 deletions

View file

@ -61,6 +61,21 @@ $ docker run \
ekofr/pihole-exporter:latest
```
If you are running pi-hole behind https, you must both set the `PIHOLE_PROTOCOL` environment variable
as well as include your ssl certificates to the docker image as it does not have any baked in:
```
$ docker run \
-e 'PIHOLE_PROTOCOL=https' \
-e 'PIHOLE_HOSTNAME=192.168.1.2' \
-e 'PIHOLE_PASSWORD=mypassword' \
-e 'INTERVAL=30s' \
-e 'PORT=9617' \
-v '/etc/ssl/certs:/etc/ssl/certs:ro' \
-p 9617:9617 \
ekofr/pihole-exporter:latest
```
### From sources
Optionally, you can download and build it from the sources. You have to retrieve the project sources by using one of the following way:

View file

@ -15,6 +15,7 @@ import (
// Config is the exporter CLI configuration.
type Config struct {
PIHoleProtocol string `config:"pihole_protocol"`
PIHoleHostname string `config:"pihole_hostname"`
PIHolePassword string `config:"pihole_password"`
PIHoleApiToken string `config:"pihole_api_token"`
@ -24,6 +25,7 @@ type Config struct {
func getDefaultConfig() *Config {
return &Config{
PIHoleProtocol: "http",
PIHoleHostname: "127.0.0.1",
PIHolePassword: "",
PIHoleApiToken: "",

View file

@ -7,6 +7,7 @@ import (
"log"
"net/http"
"net/url"
"os"
"strconv"
"strings"
"time"
@ -15,14 +16,15 @@ import (
)
var (
loginURLPattern = "http://%s/admin/index.php?login"
statsURLPattern = "http://%s/admin/api.php?summaryRaw&overTimeData&topItems&recentItems&getQueryTypes&getForwardDestinations&getQuerySources&jsonForceObject"
loginURLPattern = "%s://%s/admin/index.php?login"
statsURLPattern = "%s://%s/admin/api.php?summaryRaw&overTimeData&topItems&recentItems&getQueryTypes&getForwardDestinations&getQuerySources&jsonForceObject"
)
// Client struct is a PI-Hole client to request an instance of a PI-Hole ad blocker.
type Client struct {
httpClient http.Client
interval time.Duration
protocol string
hostname string
password string
sessionID string
@ -30,8 +32,14 @@ type Client struct {
}
// NewClient method initializes a new PI-Hole client.
func NewClient(hostname, password, apiToken string, interval time.Duration) *Client {
func NewClient(protocol, hostname, password, apiToken string, interval time.Duration) *Client {
if protocol != "http" && protocol != "https" {
log.Printf("protocol %s is invalid. Must be http or https.", protocol)
os.Exit(1)
}
return &Client{
protocol: protocol,
hostname: hostname,
password: password,
apiToken: apiToken,
@ -101,7 +109,7 @@ func (c *Client) setMetrics(stats *Stats) {
}
func (c *Client) getPHPSessionID() (sessionID string) {
loginURL := fmt.Sprintf(loginURLPattern, c.hostname)
loginURL := fmt.Sprintf(loginURLPattern, c.protocol, c.hostname)
values := url.Values{"pw": []string{c.password}}
req, err := http.NewRequest("POST", loginURL, strings.NewReader(values.Encode()))
@ -130,7 +138,7 @@ func (c *Client) getPHPSessionID() (sessionID string) {
func (c *Client) getStatistics() *Stats {
var stats Stats
statsURL := fmt.Sprintf(statsURLPattern, c.hostname)
statsURL := fmt.Sprintf(statsURLPattern, c.protocol, c.hostname)
if c.isUsingApiToken() {
statsURL = fmt.Sprintf("%s&auth=%s", statsURL, c.apiToken)

View file

@ -26,14 +26,14 @@ func main() {
metrics.Init()
initPiHoleClient(conf.PIHoleHostname, conf.PIHolePassword, conf.PIHoleApiToken, conf.Interval)
initPiHoleClient(conf.PIHoleProtocol, conf.PIHoleHostname, conf.PIHolePassword, conf.PIHoleApiToken, conf.Interval)
initHttpServer(conf.Port)
handleExitSignal()
}
func initPiHoleClient(hostname, password, apiToken string, interval time.Duration) {
client := pihole.NewClient(hostname, password, apiToken, interval)
func initPiHoleClient(protocol, hostname, password, apiToken string, interval time.Duration) {
client := pihole.NewClient(protocol, hostname, password, apiToken, interval)
go client.Scrape()
}