Skip to content

Commit

Permalink
better flags, support hashed password as input, ci
Browse files Browse the repository at this point in the history
  • Loading branch information
dehydr8 committed Jan 22, 2024
1 parent 95edb1f commit e98c31c
Show file tree
Hide file tree
Showing 10 changed files with 109 additions and 24 deletions.
1 change: 1 addition & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
bin/
33 changes: 33 additions & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
name: ci

on:
push:
tags:
- '*'

jobs:
docker:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build and push
uses: docker/build-push-action@v5
with:
context: .
platforms:
- linux/amd64
- linux/arm64
push: true
tags:
- okhalid/kasa-exporter:latest
- okhalid/kasa-exporter:${{ github.ref_name }}
9 changes: 9 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
FROM golang:1.21 as build

WORKDIR /go/src/github.com/dehydr8/kasa-go
COPY . .
RUN CGO_ENABLED=0 go build -o /kasa-exporter

FROM alpine
COPY --from=build /kasa-exporter /kasa-exporter
ENTRYPOINT ["/kasa-exporter"]
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
build-cli:
go build -o bin/kasa-exporter main.go
go build -o bin/kasa-exporter

build-cli-arm:
GOOS=linux GOARCH=arm64 go build -o bin/kasa-exporter-arm main.go
GOOS=linux GOARCH=arm64 go build -o bin/kasa-exporter-arm

run:
go run main.go
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ go 1.21.0
require (
github.com/go-kit/log v0.2.1
github.com/hashicorp/golang-lru/v2 v2.0.7
github.com/peterbourgon/ff/v4 v4.0.0-alpha.4
github.com/prometheus/client_golang v1.18.0
)

Expand Down
6 changes: 6 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs
github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 h1:jWpvCLoY8Z/e3VKvlsiIGKtc+UG6U5vzxaoagmhXfyg=
github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0/go.mod h1:QUyp042oQthUoa9bqDv0ER0wrtXnBruoNd7aNjkbP+k=
github.com/pelletier/go-toml/v2 v2.0.9 h1:uH2qQXheeefCCkuBBSLi7jCiSmj3VRh2+Goq2N7Xxu0=
github.com/pelletier/go-toml/v2 v2.0.9/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc=
github.com/peterbourgon/ff/v4 v4.0.0-alpha.4 h1:aiqS8aBlF9PsAKeMddMSfbwp3smONCn3UO8QfUg0Z7Y=
github.com/peterbourgon/ff/v4 v4.0.0-alpha.4/go.mod h1:H/13DK46DKXy7EaIxPhk2Y0EC8aubKm35nBjBe8AAGc=
github.com/prometheus/client_golang v1.18.0 h1:HzFfmkOzH5Q8L8G+kSJKUx5dtG87sewO+FoDDqP5Tbk=
github.com/prometheus/client_golang v1.18.0/go.mod h1:T+GXkCk5wSJyOqMIzVgvvjFDlkOQntgjkJWKrN5txjA=
github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw=
Expand All @@ -30,3 +34,5 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
54 changes: 40 additions & 14 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,17 @@ package main
import (
"crypto/rand"
"crypto/rsa"
"flag"
"fmt"
"net/http"
"os"

"github.com/dehydr8/kasa-go/device"
"github.com/dehydr8/kasa-go/exporter"
"github.com/dehydr8/kasa-go/logger"
"github.com/dehydr8/kasa-go/model"
"github.com/dehydr8/kasa-go/util"
"github.com/peterbourgon/ff/v4"
"github.com/peterbourgon/ff/v4/ffhelp"

lru "github.com/hashicorp/golang-lru/v2"

Expand All @@ -24,8 +27,8 @@ type MetricsServer struct {
registryCache *lru.Cache[string, *prometheus.Registry]
}

func NewMetricsServer(key *rsa.PrivateKey, credentials *model.Credentials) *MetricsServer {
cache, err := lru.New[string, *prometheus.Registry](10)
func NewMetricsServer(key *rsa.PrivateKey, credentials *model.Credentials, cacheMax int) *MetricsServer {
cache, err := lru.New[string, *prometheus.Registry](cacheMax)

if err != nil {
panic(err)
Expand Down Expand Up @@ -55,23 +58,46 @@ func (s *MetricsServer) getOrCreate(key string, create func() (*prometheus.Regis
}

func main() {
lvl := flag.String("log", "info", "debug, info, warn, error")
address := flag.String("address", "", "address to listen on")
port := flag.Int("port", 9500, "port to listen on")
username := flag.String("username", "", "username for kasa login")
password := flag.String("password", "", "password for kasa login")
fs := ff.NewFlagSet(fmt.Sprintf("kasa-exporter (rev %s)", util.Revision))

var (
lvl = fs.StringEnum('l', "log", "log level: debug, info, warn, error", "info", "debug", "warn", "error")
address = fs.String('a', "address", "", "address to listen on")
port = fs.Int('p', "port", 9500, "port to listen on")
username = fs.StringLong("username", "", "username for kasa login")
password = fs.StringLong("password", "", "password for kasa login")
hashedPassword = fs.StringLong("hashed_password", "", "hashed (sha1) password for kasa login")
maxRegistries = fs.IntLong("max_registries", 16, "maximum number of registries to cache")
)

if err := ff.Parse(fs, os.Args[1:],
ff.WithEnvVarPrefix("KASA_EXPORTER"),
ff.WithConfigFileFlag("config"),
ff.WithConfigFileParser(ff.PlainParser),
); err != nil {
fmt.Printf("%s\n", ffhelp.Flags(fs))
fmt.Printf("err=%v\n", err)
os.Exit(1)
}

flag.Parse()
if *username == "" {
fmt.Printf("%s\n", ffhelp.Flags(fs))
fmt.Printf("err=%v\n", "username must be specified")
os.Exit(1)
}

if *username == "" || *password == "" {
panic("username and password must be specified")
if *password == "" && *hashedPassword == "" {
fmt.Printf("%s\n", ffhelp.Flags(fs))
fmt.Printf("err=%v\n", "password or hashed_password must be specified")
os.Exit(1)
}

logger.SetupLogging(*lvl)

credentials := model.Credentials{
Username: *username,
Password: *password,
Username: *username,
Password: *password,
HashedPassword: *hashedPassword,
}

logger.Debug("msg", "Generating RSA key")
Expand All @@ -82,7 +108,7 @@ func main() {
panic(err)
}

server := NewMetricsServer(key, &credentials)
server := NewMetricsServer(key, &credentials, *maxRegistries)

http.HandleFunc("/scrape", server.ScrapeHandler)

Expand Down
8 changes: 4 additions & 4 deletions model/device.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@ package model
import "crypto/rsa"

type Credentials struct {
Username string
Password string
Username string
Password string
HashedPassword string
}

type DeviceConfig struct {
Address string

Credentials *Credentials
CredentialsHash *string
Credentials *Credentials

Key *rsa.PrivateKey
}
7 changes: 6 additions & 1 deletion protocol/aes.go
Original file line number Diff line number Diff line change
Expand Up @@ -388,7 +388,12 @@ func (t *AesTransport) hashCredentials(v2 bool) (string, string) {
var pass string

if v2 {
pass = base64.StdEncoding.EncodeToString([]byte(sha1Hash([]byte(t.config.Credentials.Password))))
// if we already have the hashed password, use it
if t.config.Credentials.HashedPassword != "" {
pass = base64.StdEncoding.EncodeToString([]byte(t.config.Credentials.HashedPassword))
} else {
pass = base64.StdEncoding.EncodeToString([]byte(sha1Hash([]byte(t.config.Credentials.Password))))
}
} else {
pass = base64.StdEncoding.EncodeToString([]byte(t.config.Credentials.Password))
}
Expand Down
10 changes: 7 additions & 3 deletions util/commit.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
package util

import "runtime/debug"
import (
"fmt"
"runtime/debug"
)

var Commit = func() string {
var Revision = func() string {
if info, ok := debug.ReadBuildInfo(); ok {
fmt.Println(info)
for _, setting := range info.Settings {
if setting.Key == "vcs.revision" {
return setting.Value
return setting.Value[:7]
}
}
}
Expand Down

0 comments on commit e98c31c

Please sign in to comment.