Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
runs-on: ubuntu-latest
env:
GO_VERSION: stable
GOLANGCI_LINT_VERSION: v1.63.4
GOLANGCI_LINT_VERSION: v2.1.2
CGO_ENABLED: 0

steps:
Expand Down
124 changes: 62 additions & 62 deletions .golangci.yml
Original file line number Diff line number Diff line change
@@ -1,84 +1,84 @@
run:
timeout: 2m

linters-settings:
govet:
enable-all: true
disable:
- fieldalignment
gocyclo:
min-complexity: 16
goconst:
min-len: 3
min-occurrences: 3
misspell:
locale: US
funlen:
lines: -1
statements: 40
gofumpt:
extra-rules: true
depguard:
rules:
main:
deny:
- pkg: "github.com/instana/testify"
desc: not allowed
- pkg: "github.com/pkg/errors"
desc: Should be replaced by standard lib errors package
godox:
keywords:
- FIXME
gocritic:
enabled-tags:
- diagnostic
- style
- performance
disabled-checks:
- sloppyReassign
- rangeValCopy
- octalLiteral
- paramTypeCombine # already handle by gofumpt.extra-rules
settings:
hugeParam:
sizeThreshold: 100
forbidigo:
forbid:
- '^print(ln)?$'
- '^panic$'
- '^spew\.Print(f|ln)?$'
- '^spew\.Dump$'

version: "2"
linters:
enable-all: true
default: all
disable:
- rowserrcheck # not relevant (SQL)
- sqlclosecheck # not relevant (SQL)
- cyclop # duplicate of gocyclo
- cyclop
- dupl
- err113
- exhaustive
- exhaustruct
- exportloopref
- forbidigo
- gochecknoglobals
- gochecknoinits
- err113
- mnd
- gosec
- lll
- mnd
- nilnil
- nlreturn
- paralleltest
- prealloc
- rowserrcheck
- sqlclosecheck
- testpackage
- tparallel
- varnamelen
- wrapcheck
- wsl

settings:
depguard:
rules:
main:
deny:
- pkg: github.com/instana/testify
desc: not allowed
- pkg: github.com/pkg/errors
desc: Should be replaced by standard lib errors package
forbidigo:
forbid:
- pattern: ^print(ln)?$
- pattern: ^panic$
- pattern: ^spew\.Print(f|ln)?$
- pattern: ^spew\.Dump$
funlen:
lines: -1
statements: 40
goconst:
min-len: 3
min-occurrences: 3
gocritic:
disabled-checks:
- sloppyReassign
- rangeValCopy
- octalLiteral
- paramTypeCombine
enabled-tags:
- diagnostic
- style
- performance
settings:
hugeParam:
sizeThreshold: 100
gocyclo:
min-complexity: 16
godox:
keywords:
- FIXME
govet:
disable:
- fieldalignment
enable-all: true
misspell:
locale: US
exclusions:
presets:
- comments
issues:
exclude-use-default: false
max-issues-per-linter: 0
max-same-issues: 0
exclude:
- 'package-comments: should have a package comment'
formatters:
enable:
- gci
- gofumpt
settings:
gofumpt:
extra-rules: true
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,6 @@ check:

image:
docker build -t $(IMAGE_NAME) .

protoc:
protoc --proto_path . ./grpc.proto --go-grpc_out=./ --go_out=./
85 changes: 61 additions & 24 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,45 +59,82 @@ Heath check.
## Examples

```console
$ docker run -d -P --name iamfoo traefik/whoami

$ docker inspect --format '{{ .NetworkSettings.Ports }}' iamfoo
map[80/tcp:[{0.0.0.0 32769}]]

$ curl "http://0.0.0.0:32769"
Hostname : 6e0030e67d6a
IP : 127.0.0.1
IP : ::1
IP : 172.17.0.27
IP : fe80::42:acff:fe11:1b
$ docker run -d -p 8080:80 --name iamfoo traefik/whoami

$ curl http://localhost:8080
Hostname: 9c9c93da54b5
IP: 127.0.0.1
IP: ::1
IP: 172.17.0.2
RemoteAddr: 172.17.0.1:41040
GET / HTTP/1.1
Host: 0.0.0.0:32769
User-Agent: curl/7.35.0
Host: localhost:8080
User-Agent: curl/8.5.0
Accept: */*
```

```console
# updates health check status
$ curl -X POST -d '500' http://localhost:80/health
$ curl -X POST -d '500' http://localhost:8080/health

# calls the health check
$ curl -v http://localhost:80/health
* Trying ::1:80...
* TCP_NODELAY set
* Connected to localhost (::1) port 80 (#0)
$ curl -v http://localhost:8080/health
* Host localhost:8080 was resolved.
* IPv6: ::1
* IPv4: 127.0.0.1
* Trying [::1]:8080...
* Connected to localhost (::1) port 8080
> GET /health HTTP/1.1
> Host: localhost:80
> User-Agent: curl/7.65.3
> Host: localhost:8080
> User-Agent: curl/8.5.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 500 Internal Server Error
< Date: Mon, 16 Sep 2019 22:52:40 GMT
< Date: Fri, 18 Apr 2025 13:36:02 GMT
< Content-Length: 0
```

```console
docker run -d -P -v ./certs:/certs --name iamfoo traefik/whoami --cert /certs/example.cert --key /certs/example.key
$ openssl req -newkey rsa:4096 \
-x509 \
-sha256 \
-days 3650 \
-nodes \
-out ./certs/example.crt \
-keyout ./certs/example.key

$ docker run -d -p 8080:80 -v ./certs:/certs --name iamfoo traefik/whoami --cert /certs/example.crt --key /certs/example.key

$ curl https://localhost:8080 -k --cert certs/example.crt --key certs/example.key
Hostname: 25bc0df47b95
IP: 127.0.0.1
IP: ::1
IP: 172.17.0.2
RemoteAddr: 172.17.0.1:50278
Certificate[0] Subject: CN=traefik.io,O=TraefikLabs,L=Lyon,ST=France,C=FR
GET / HTTP/1.1
Host: localhost:8080
User-Agent: curl/8.5.0
Accept: */*
```

```console
$ docker run -d -p 8080:80 --name iamfoo traefik/whoami

$ grpcurl -plaintext -proto grpc.proto localhost:8080 whoami.Whoami/Whoami
{
"hostname": "5a45e21984b4",
"iface": [
"127.0.0.1",
"::1",
"172.17.0.2"
]
}

$ grpcurl -plaintext -proto grpc.proto localhost:8080 whoami.Whoami/Bench
{
"data": 1
}
```

```yml
Expand All @@ -110,4 +147,4 @@ services:
# It tells whoami to start listening on 2001 instead of 80
- --port=2001
- --name=iamfoo
```
```
50 changes: 48 additions & 2 deletions app.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package main

import (
"context"
"crypto/tls"
"crypto/x509"
"encoding/json"
Expand All @@ -17,6 +18,10 @@ import (
"time"

"github.com/gorilla/websocket"
grpcWhoami "github.com/traefik/whoami/grpc"
"golang.org/x/net/http2"
"golang.org/x/net/http2/h2c"
"google.golang.org/grpc"
)

// Units.
Expand Down Expand Up @@ -78,16 +83,22 @@ func main() {
mux.Handle("/health", handle(healthHandler, verbose))
mux.Handle("/", handle(whoamiHandler, verbose))

serverGRPC := grpc.NewServer()
grpcWhoami.RegisterWhoamiServer(serverGRPC, whoamiServer{})
mux.Handle("/whoami.Whoami/", serverGRPC)

h := handle(mux.ServeHTTP, verbose)

if cert == "" || key == "" {
log.Printf("Starting up on port %s", port)

log.Fatal(http.ListenAndServe(":"+port, mux))
log.Fatal(http.ListenAndServe(":"+port, h2c.NewHandler(h, &http2.Server{})))
}

server := &http.Server{
Addr: ":" + port,
TLSConfig: &tls.Config{ClientAuth: tls.RequestClientCert},
Handler: mux,
Handler: h,
}

if ca != "" {
Expand Down Expand Up @@ -344,3 +355,38 @@ func getIPs() []string {

return ips
}

type whoamiServer struct {
grpcWhoami.UnimplementedWhoamiServer
}

func (g whoamiServer) Bench(_ context.Context, _ *grpcWhoami.BenchRequest) (*grpcWhoami.BenchReply, error) {
return &grpcWhoami.BenchReply{Data: 1}, nil
}

func (g whoamiServer) Whoami(_ context.Context, _ *grpcWhoami.WhoamiRequest) (*grpcWhoami.WhoamiReply, error) {
reply := &grpcWhoami.WhoamiReply{}
if name != "" {
reply.Name = name
}

reply.Hostname, _ = os.Hostname()

ifaces, _ := net.Interfaces()
for _, i := range ifaces {
addrs, _ := i.Addrs()
// handle err
for _, addr := range addrs {
var ip net.IP
switch v := addr.(type) {
case *net.IPNet:
ip = v.IP
case *net.IPAddr:
ip = v.IP
}
reply.Iface = append(reply.Iface, ip.String())
}
}

return reply, nil
}
15 changes: 13 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
module github.com/traefik/whoami

go 1.23
go 1.24

require github.com/gorilla/websocket v1.5.3
require (
github.com/gorilla/websocket v1.5.3
golang.org/x/net v0.34.0
google.golang.org/grpc v1.71.1
google.golang.org/protobuf v1.36.6
)

require (
golang.org/x/sys v0.29.0 // indirect
golang.org/x/text v0.21.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f // indirect
)
Loading
Loading