From 8876838e53384a53819072538610561d06aa9369 Mon Sep 17 00:00:00 2001 From: zcube Date: Fri, 8 Nov 2024 09:07:51 +0900 Subject: [PATCH] fix: Maintenance and #1 --- .gitignore | 1 + Dockerfile | 12 ++++++-- cmd/local.go | 19 +++++++----- cmd/ping.go | 4 +-- cmd/remote.go | 19 +++++++----- docker-compose.yaml | 16 ++++++++-- go.mod | 27 ++++++++--------- go.sum | 72 +++++++++++++++++++-------------------------- 8 files changed, 90 insertions(+), 80 deletions(-) diff --git a/.gitignore b/.gitignore index 66fd13c..6c67f77 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,4 @@ # Dependency directories (remove the comment below to include it) # vendor/ +factorio-port-fixer diff --git a/Dockerfile b/Dockerfile index e6cc970..4f6ae56 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM golang:1.19 as builder +FROM golang:1.22-alpine as builder WORKDIR /app @@ -10,10 +10,16 @@ ADD . /app/ RUN CGO_ENABLE=0 go build -o /app/factorio-port-fixer -FROM gcr.io/distroless/base-debian11 +FROM alpine:3.20.3 -EXPOSE 34197/udp +RUN apk add --no-cache ca-certificates curl + +EXPOSE 34197/udp 34197/tcp COPY --from=builder /app/factorio-port-fixer /factorio-port-fixer +HEALTHCHECK --interval=30s --timeout=30s --start-period=5s --retries=3 \ + CMD curl --fail http://localhost:34197/health || exit 1 + CMD ["/factorio-port-fixer", "remote"] + diff --git a/cmd/local.go b/cmd/local.go index 8c3f55d..f2c3d51 100644 --- a/cmd/local.go +++ b/cmd/local.go @@ -65,10 +65,11 @@ var localCmd = &cobra.Command{ e.GET("/health", func(c echo.Context) error { { + remoteClientIp := c.RealIP() + addr := net.UDPAddr{IP: net.ParseIP(ip)} - ip := c.RealIP() - remote := &net.UDPAddr{Port: int(remotePort), IP: net.ParseIP(ip)} + remote := &net.UDPAddr{Port: int(localPort), IP: net.ParseIP("127.0.0.1")} conn, err := net.ListenUDP("udp", &addr) if err != nil { @@ -89,9 +90,11 @@ var localCmd = &cobra.Command{ if wrerr != nil { sugar.Errorf("net.WriteTo() error: %s\n", wrerr) } else { - sugar.Infow("Wrote to socket", + sugar.Debugw("Wrote to socket", "Bytes", cc, - "Remote", remote) + "Remote", remote, + "RemoteClientIP", remoteClientIp, + ) } b := make([]byte, 2048) @@ -103,7 +106,7 @@ var localCmd = &cobra.Command{ sugar.Error("net.ReadFromUDP() error: %s", rderr) return c.String(http.StatusInternalServerError, rderr.Error()) } else { - sugar.Infow("Read from socket", + sugar.Debugw("Read from socket", "Bytes", cc, "Remote", remote) } @@ -123,7 +126,7 @@ var localCmd = &cobra.Command{ g.Go(func() error { for { - sugar.Infow("Accepting a new packet", + sugar.Debugw("Accepting a new packet", "IP", ip, "Port", port) @@ -132,7 +135,7 @@ var localCmd = &cobra.Command{ sugar.Errorf("net.ReadFromUDP() error: %s", rderr) return rderr } else { - sugar.Infow("Read from socket", + sugar.Debugw("Read from socket", "Bytes", cc, "Remote", remote) } @@ -170,7 +173,7 @@ var localCmd = &cobra.Command{ if wrerr != nil { sugar.Errorf("net.WriteTo() error: %s\n", wrerr) } else { - sugar.Infow("Wrote to socket", + sugar.Debugw("Wrote to socket", "Bytes", cc, "Remote", remote) } diff --git a/cmd/ping.go b/cmd/ping.go index 2be4f73..7f2d0cf 100644 --- a/cmd/ping.go +++ b/cmd/ping.go @@ -65,7 +65,7 @@ var pingCmd = &cobra.Command{ if wrerr != nil { sugar.Errorf("net.WriteTo() error: %s\n", wrerr) } else { - sugar.Infow("Wrote to socket", + sugar.Debugw("Wrote to socket", "Bytes", cc, "Remote", remote) } @@ -78,7 +78,7 @@ var pingCmd = &cobra.Command{ if rderr != nil { sugar.Fatalf("net.ReadFromUDP() error: %s", rderr) } else { - sugar.Infow("Read from socket", + sugar.Debugw("Read from socket", "Bytes", cc, "Remote", remote) } diff --git a/cmd/remote.go b/cmd/remote.go index 43f62ae..628c0a0 100644 --- a/cmd/remote.go +++ b/cmd/remote.go @@ -64,10 +64,11 @@ var remoteCmd = &cobra.Command{ e.GET("/health", func(c echo.Context) error { { + remoteClientIp := c.RealIP() + addr := net.UDPAddr{IP: net.ParseIP(ip)} - ip := c.RealIP() - remote := &net.UDPAddr{Port: int(remotePort), IP: net.ParseIP(ip)} + remote := &net.UDPAddr{Port: int(localPort), IP: net.ParseIP("127.0.0.1")} conn, err := net.ListenUDP("udp", &addr) if err != nil { @@ -88,9 +89,11 @@ var remoteCmd = &cobra.Command{ if wrerr != nil { sugar.Errorf("net.WriteTo() error: %s\n", wrerr) } else { - sugar.Infow("Wrote to socket", + sugar.Debugw("Wrote to socket", "Bytes", cc, - "Remote", remote) + "Remote", remote, + "RemoteClientIP", remoteClientIp, + ) } b := make([]byte, 2048) @@ -102,7 +105,7 @@ var remoteCmd = &cobra.Command{ sugar.Error("net.ReadFromUDP() error: %s", rderr) return c.String(http.StatusInternalServerError, rderr.Error()) } else { - sugar.Infow("Read from socket", + sugar.Debugw("Read from socket", "Bytes", cc, "Remote", remote) } @@ -122,7 +125,7 @@ var remoteCmd = &cobra.Command{ g.Go(func() error { for { - sugar.Infow("Accepting a new packet", + sugar.Debugw("Accepting a new packet", "IP", ip, "Port", port) @@ -131,7 +134,7 @@ var remoteCmd = &cobra.Command{ sugar.Errorf("net.ReadFromUDP() error: %s", rderr) return rderr } else { - sugar.Infow("Read from socket", + sugar.Debugw("Read from socket", "Bytes", cc, "Remote", remote) } @@ -163,7 +166,7 @@ var remoteCmd = &cobra.Command{ if wrerr != nil { sugar.Errorf("net.WriteTo() error: %s\n", wrerr) } else { - sugar.Infow("Wrote to socket", + sugar.Debugw("Wrote to socket", "Bytes", cc, "Remote", remote) } diff --git a/docker-compose.yaml b/docker-compose.yaml index de08da6..20a3522 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -1,7 +1,17 @@ -version: '3' +version: "3" services: - factorio: + factorio-port-fixer: image: ghcr.io/zcube/factorio-port-fixer:latest + build: + context: . + dockerfile: Dockerfile restart: unless-stopped ports: - - "34197:34197/udp" + - "34197:34197/udp" + - "34197:34197/tcp" + healthcheck: + test: curl --fail 127.0.0.1:34197/health || exit 1 + interval: 20s + retries: 5 + start_period: 20s + timeout: 10s diff --git a/go.mod b/go.mod index ed02898..20a600c 100644 --- a/go.mod +++ b/go.mod @@ -1,28 +1,27 @@ module github.com/zcube/factorio-port-fixer -go 1.19 +go 1.22 require ( - github.com/labstack/echo/v4 v4.10.0 + github.com/labstack/echo/v4 v4.12.0 github.com/rdegges/go-ipify v0.0.0-20150526035502-2d94a6a86c40 - github.com/spf13/cobra v1.6.1 - go.uber.org/zap v1.24.0 - golang.org/x/sync v0.1.0 + github.com/spf13/cobra v1.8.1 + go.uber.org/zap v1.27.0 + golang.org/x/sync v0.9.0 ) require ( - github.com/inconshreveable/mousetrap v1.0.1 // indirect + github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/jpillora/backoff v1.0.0 // indirect - github.com/labstack/gommon v0.4.0 // indirect + github.com/labstack/gommon v0.4.2 // indirect github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-isatty v0.0.16 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/valyala/fasttemplate v1.2.2 // indirect - go.uber.org/atomic v1.7.0 // indirect - go.uber.org/multierr v1.6.0 // indirect - golang.org/x/crypto v0.2.0 // indirect - golang.org/x/net v0.4.0 // indirect - golang.org/x/sys v0.3.0 // indirect - golang.org/x/text v0.5.0 // indirect + go.uber.org/multierr v1.11.0 // indirect + golang.org/x/crypto v0.29.0 // indirect + golang.org/x/net v0.30.0 // indirect + golang.org/x/sys v0.27.0 // indirect + golang.org/x/text v0.20.0 // indirect ) diff --git a/go.sum b/go.sum index 472886f..2d9f5aa 100644 --- a/go.sum +++ b/go.sum @@ -1,64 +1,52 @@ -github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= -github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/inconshreveable/mousetrap v1.0.1 h1:U3uMjPSQEBMNp1lFxmllqCPM6P5u/Xq7Pgzkat/bFNc= -github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= +github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= -github.com/labstack/echo/v4 v4.10.0 h1:5CiyngihEO4HXsz3vVsJn7f8xAlWwRr3aY6Ih280ZKA= -github.com/labstack/echo/v4 v4.10.0/go.mod h1:S/T/5fy/GigaXnHTkh0ZGe4LpkkQysvRjFMSUTkDRNQ= -github.com/labstack/gommon v0.4.0 h1:y7cvthEAEbU0yHOf4axH8ZG2NH8knB9iNSoTO8dyIk8= -github.com/labstack/gommon v0.4.0/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM= -github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= +github.com/labstack/echo/v4 v4.12.0 h1:IKpw49IMryVB2p1a4dzwlhP1O2Tf2E0Ir/450lH+kI0= +github.com/labstack/echo/v4 v4.12.0/go.mod h1:UP9Cr2DJXbOK3Kr9ONYzNowSh7HP0aG0ShAyycHSJvM= +github.com/labstack/gommon v0.4.2 h1:F8qTUNXgG1+6WQmqoUWnz8WiEU60mXVVw0P4ht1WRA0= +github.com/labstack/gommon v0.4.2/go.mod h1:QlUFxVM+SNXhDL/Z7YhocGIBYOiwB0mXm1+1bAPHPyU= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= -github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= -github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/rdegges/go-ipify v0.0.0-20150526035502-2d94a6a86c40 h1:31Y7UZ1yTYBU4E79CE52I/1IRi3TqiuwquXGNtZDXWs= github.com/rdegges/go-ipify v0.0.0-20150526035502-2d94a6a86c40/go.mod h1:j4c6zEU0eMG1oiZPUy+zD4ykX0NIpjZAEOEAviTWC18= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/spf13/cobra v1.6.1 h1:o94oiPyS4KD1mPy2fmcYYHHfCxLqYjJOhGsCHFZtEzA= -github.com/spf13/cobra v1.6.1/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUqzrY= +github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= +github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= -github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo= github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= -go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw= -go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI= -go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4= -go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= -go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60= -go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= -golang.org/x/crypto v0.2.0 h1:BRXPfhNivWL5Yq0BGQ39a2sW6t44aODpfxkWjYdzewE= -golang.org/x/crypto v0.2.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= -golang.org/x/net v0.4.0 h1:Q5QPcMlvfxFTAPV0+07Xz/MpK9NTXu2VDUuy0FeMfaU= -golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= -golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= -golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= +go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= +go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= +go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= +go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= +golang.org/x/crypto v0.29.0 h1:L5SG1JTTXupVV3n6sUqMTeWbjAyfPwoda2DLX8J8FrQ= +golang.org/x/crypto v0.29.0/go.mod h1:+F4F4N5hv6v38hfeYwTdx20oUvLLc+QfrE9Ax9HtgRg= +golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4= +golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU= +golang.org/x/sync v0.9.0 h1:fEo0HyrW1GIgZdpbhCRO0PkJajUS5H9IFUztCgEo2jQ= +golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.3.0 h1:w8ZOecv6NaNa/zC8944JTU3vz4u6Lagfk4RPQxv92NQ= -golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/text v0.5.0 h1:OLmvp0KP+FVG99Ct/qFiL/Fhk4zp4QQnZ7b2U+5piUM= -golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s= +golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug= +golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=