From e7a2501fe865dc04cb999be4d50332dc4e0f57f0 Mon Sep 17 00:00:00 2001 From: Raal Goff Date: Sun, 26 Sep 2021 16:53:05 +0800 Subject: [PATCH 001/300] initial work on OIDC (SSO) integration --- api.go | 17 +- app.go | 6 + cmd/headscale/cli/utils.go | 4 + go.mod | 3 + go.sum | 11 ++ oidc.go | 310 +++++++++++++++++++++++++++++++++++++ 6 files changed, 347 insertions(+), 4 deletions(-) create mode 100644 oidc.go diff --git a/api.go b/api.go index e2a56185..2c5a1321 100644 --- a/api.go +++ b/api.go @@ -133,8 +133,13 @@ func (h *Headscale) RegistrationHandler(c *gin.Context) { Str("handler", "Registration"). Str("machine", m.Name). Msg("Not registered and not NodeKey rotation. Sending a authurl to register") - resp.AuthURL = fmt.Sprintf("%s/register?key=%s", - h.cfg.ServerURL, mKey.HexString()) + + if h.cfg.OIDCEndpoint != "" { + resp.AuthURL = fmt.Sprintf("%s/oidc/register/%s", h.cfg.ServerURL, mKey.HexString()) + } else { + resp.AuthURL = fmt.Sprintf("%s/register?key=%s", + h.cfg.ServerURL, mKey.HexString()) + } respBody, err := encode(resp, &mKey, h.privateKey) if err != nil { log.Error(). @@ -199,8 +204,12 @@ func (h *Headscale) RegistrationHandler(c *gin.Context) { Str("handler", "Registration"). Str("machine", m.Name). Msg("The node is sending us a new NodeKey, sending auth url") - resp.AuthURL = fmt.Sprintf("%s/register?key=%s", - h.cfg.ServerURL, mKey.HexString()) + if h.cfg.OIDCEndpoint != "" { + resp.AuthURL = fmt.Sprintf("%s/oidc/register/%s", h.cfg.ServerURL, mKey.HexString()) + } else { + resp.AuthURL = fmt.Sprintf("%s/register?key=%s", + h.cfg.ServerURL, mKey.HexString()) + } respBody, err := encode(resp, &mKey, h.privateKey) if err != nil { log.Error(). diff --git a/app.go b/app.go index c903d83f..81871a87 100644 --- a/app.go +++ b/app.go @@ -45,6 +45,10 @@ type Config struct { TLSKeyPath string DNSConfig *tailcfg.DNSConfig + + OIDCEndpoint string + OIDCClientID string + OIDCClientSecret string } // Headscale represents the base app of the service @@ -168,6 +172,8 @@ func (h *Headscale) Serve() error { r.GET("/register", h.RegisterWebAPI) r.POST("/machine/:id/map", h.PollNetMapHandler) r.POST("/machine/:id", h.RegistrationHandler) + r.GET("/oidc/register/:mKey", h.RegisterOIDC) + r.GET("/oidc/callback", h.OIDCCallback) var err error timeout := 30 * time.Second diff --git a/cmd/headscale/cli/utils.go b/cmd/headscale/cli/utils.go index 7ada6693..b7faad57 100644 --- a/cmd/headscale/cli/utils.go +++ b/cmd/headscale/cli/utils.go @@ -170,6 +170,10 @@ func getHeadscaleApp() (*headscale.Headscale, error) { TLSKeyPath: absPath(viper.GetString("tls_key_path")), DNSConfig: GetDNSConfig(), + + OIDCEndpoint: viper.GetString("oidc_endpoint"), + OIDCClientID: viper.GetString("oidc_client_id"), + OIDCClientSecret: viper.GetString("oidc_client_secret"), } h, err := headscale.NewHeadscale(cfg) diff --git a/go.mod b/go.mod index 8709119b..031460e8 100644 --- a/go.mod +++ b/go.mod @@ -17,8 +17,10 @@ require ( github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6 // indirect github.com/opencontainers/runc v1.0.2 // indirect github.com/ory/dockertest/v3 v3.7.0 + github.com/patrickmn/go-cache v2.1.0+incompatible github.com/pterm/pterm v0.12.30 github.com/rs/zerolog v1.25.0 + github.com/s12v/go-jwks v0.2.1 github.com/spf13/cobra v1.2.1 github.com/spf13/viper v1.8.1 github.com/stretchr/testify v1.7.0 @@ -28,6 +30,7 @@ require ( golang.org/x/net v0.0.0-20210913180222-943fd674d43e // indirect golang.org/x/sys v0.0.0-20210910150752-751e447fb3d0 // indirect gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c + gopkg.in/square/go-jose.v2 v2.3.1 gopkg.in/yaml.v2 v2.4.0 gorm.io/datatypes v1.0.2 gorm.io/driver/postgres v1.1.1 diff --git a/go.sum b/go.sum index ac934dbe..195fb21d 100644 --- a/go.sum +++ b/go.sum @@ -711,6 +711,8 @@ github.com/ory/dockertest/v3 v3.7.0 h1:Bijzonc69Ont3OU0a3TWKJ1Rzlh3TsDXP1JrTAkSm github.com/ory/dockertest/v3 v3.7.0/go.mod h1:PvCCgnP7AfBZeVrzwiUTjZx/IUXlGLC1zQlUQrLIlUE= github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc= +github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ= github.com/pborman/getopt v1.1.0/go.mod h1:FxXoW1Re00sQG/+KIkuSqRL/LwQgSkv7uyac+STFsbk= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= @@ -786,6 +788,8 @@ github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQD github.com/ryancurrah/gomodguard v1.1.0/go.mod h1:4O8tr7hBODaGE6VIhfJDHcwzh5GUccKSJBU0UMXJFVM= github.com/ryanrolds/sqlclosecheck v0.3.0/go.mod h1:1gREqxyTGR3lVtpngyFo3hZAgk0KCtEdgEkHwDbigdA= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/s12v/go-jwks v0.2.1 h1:2zShofKJoSXztWyh5ASPfpzuQrE+b+Sum9JJdif05Po= +github.com/s12v/go-jwks v0.2.1/go.mod h1:DmmtP4Etd59Y90j8zmTS4z61MKu0QPvgioAXv+mqyjQ= github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= github.com/sassoftware/go-rpmutils v0.0.0-20190420191620-a8f1baeba37b/go.mod h1:am+Fp8Bt506lA3Rk3QCmSqmYmLMnPDhdDUcosQCAx+I= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= @@ -845,6 +849,8 @@ github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5q github.com/spf13/viper v1.7.1/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= github.com/spf13/viper v1.8.1 h1:Kq1fyeebqsBfbjZj4EL7gj2IO0mMaiyjYUWcUsl2O44= github.com/spf13/viper v1.8.1/go.mod h1:o0Pch8wJ9BVSWGQMbra6iw0oQ5oktSIBaujf1rJH9Ns= +github.com/square/go-jose v2.5.1+incompatible h1:FC+BwI9FzJZWpKaE0yUhFNbp/CyFHndARzuGVME/LGk= +github.com/square/go-jose v2.5.1+incompatible/go.mod h1:7MxpAF/1WTVUu8Am+T5kNy+t0902CaLWM4Z745MkOa8= github.com/ssgreg/nlreturn/v2 v2.1.0/go.mod h1:E/iiPB78hV7Szg2YfRgyIrk1AD6JVMTRkkxBiELzh2I= github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= @@ -958,6 +964,7 @@ go4.org/mem v0.0.0-20201119185036-c04c5a6ff174/go.mod h1:reUoABIJ9ikfM5sgtSF3Wus go4.org/unsafe/assume-no-moving-gc v0.0.0-20201222175341-b30ae309168e/go.mod h1:FftLjUGFEDu5k8lt0ddY+HcrH/qU/0qk+H8j9/nTl3E= go4.org/unsafe/assume-no-moving-gc v0.0.0-20201222180813-1025295fd063 h1:1tk03FUNpulq2cuWpXZWj649rwJpk0d20rxWiopKRmc= go4.org/unsafe/assume-no-moving-gc v0.0.0-20201222180813-1025295fd063/go.mod h1:FftLjUGFEDu5k8lt0ddY+HcrH/qU/0qk+H8j9/nTl3E= +golang.org/x/crypto v0.0.0-20180621125126-a49355c7e3f8/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -1021,6 +1028,7 @@ golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180729183719-c4299a1a0d85/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1097,6 +1105,7 @@ golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1436,6 +1445,8 @@ gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.62.0 h1:duBzk771uxoUuOlyRLkHsygud9+5lrlGjdFBb4mSKDU= gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= +gopkg.in/square/go-jose.v2 v2.3.1 h1:SK5KegNXmKmqE342YYN2qPHEnUYeoMiXXl1poUlI+o4= +gopkg.in/square/go-jose.v2 v2.3.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= diff --git a/oidc.go b/oidc.go new file mode 100644 index 00000000..0006cc32 --- /dev/null +++ b/oidc.go @@ -0,0 +1,310 @@ +package headscale + +import ( + "crypto/rand" + "encoding/hex" + "encoding/json" + "errors" + "fmt" + "github.com/gin-gonic/gin" + "github.com/patrickmn/go-cache" + "github.com/rs/zerolog/log" + "github.com/s12v/go-jwks" + "gopkg.in/square/go-jose.v2/jwt" + "gorm.io/gorm" + "io" + "net/http" + "net/url" + "strings" + "time" +) + +type OpenIDConfiguration struct { + Issuer string `json:"issuer"` + AuthorizationEndpoint string `json:"authorization_endpoint"` + TokenEndpoint string `json:"token_endpoint"` + JWKSURI string `json:"jwks_uri"` +} + +type OpenIDTokens struct { + AccessToken string `json:"access_token"` + ExpiresIn int `json:"expires_in"` + IdToken string `json:"id_token"` + NotBeforePolicy int `json:"not-before-policy,omitempty"` + RefreshExpiresIn int `json:"refresh_expires_in"` + RefreshToken string `json:"refresh_token"` + Scope string `json:"scope"` + SessionState string `json:"session_state,omitempty"` + TokenType string `json:"token_type,omitempty"` +} + +type AccessToken struct { + jwt.Claims + Name string `json:"name,omitempty"` + Groups []string `json:"groups,omitempty"` + Email string `json:"email"` + Username string `json:"preferred_username,omitempty"` +} + +var oidcConfig *OpenIDConfiguration +var stateCache *cache.Cache +var jwksSource *jwks.WebSource +var jwksClient jwks.JWKSClient + +func verifyToken(token string) (*AccessToken, error) { + + if jwksClient == nil { + jwksSource = jwks.NewWebSource(oidcConfig.JWKSURI) + jwksClient = jwks.NewDefaultClient( + jwksSource, + time.Hour, // Refresh keys every 1 hour + 12*time.Hour, // Expire keys after 12 hours + ) + } + + //decode jwt + tok, err := jwt.ParseSigned(token) + if err != nil { + return nil, err + } + + if tok.Headers[0].KeyID != "" { + log.Debug().Msgf("Checking KID %s\n", tok.Headers[0].KeyID) + + jwk, err := jwksClient.GetSignatureKey(tok.Headers[0].KeyID) + if err != nil { + return nil, err + } + + claims := AccessToken{} + + err = tok.Claims(jwk.Certificates[0].PublicKey, &claims) + if err != nil { + return nil, err + } else { + + err = claims.Validate(jwt.Expected{ + Time: time.Now(), + }) + if err != nil { + return nil, err + } + + return &claims, nil + } + + } else { + return nil, err + } +} + +func getOIDCConfig(oidcConfigURL string) (*OpenIDConfiguration, error) { + client := &http.Client{} + req, err := http.NewRequest("GET", oidcConfigURL, nil) + if err != nil { + log.Error().Msgf("%v", err) + return nil, err + } + + log.Debug().Msgf("Requesting OIDC Config from %s", oidcConfigURL) + + oidcConfigResp, err := client.Do(req) + if err != nil { + log.Error().Msgf("%v", err) + return nil, err + } + defer oidcConfigResp.Body.Close() + + var oidcConfig OpenIDConfiguration + + err = json.NewDecoder(oidcConfigResp.Body).Decode(&oidcConfig) + if err != nil { + log.Error().Msgf("%v", err) + return nil, err + } + return &oidcConfig, nil +} + +func (h *Headscale) exchangeCodeForTokens(code string, redirectURI string) (*OpenIDTokens, error) { + var err error + + if oidcConfig == nil { + oidcConfig, err = getOIDCConfig(fmt.Sprintf("%s.well-known/openid-configuration", h.cfg.OIDCEndpoint)) + if err != nil { + return nil, err + } + } + + params := url.Values{} + params.Add("grant_type", "authorization_code") + params.Add("code", code) + params.Add("client_id", h.cfg.OIDCClientID) + params.Add("client_secret", h.cfg.OIDCClientSecret) + params.Add("redirect_uri", redirectURI) + + client := &http.Client{} + req, err := http.NewRequest("POST", oidcConfig.TokenEndpoint, strings.NewReader(params.Encode())) + req.Header.Add("Content-Type", "application/x-www-form-urlencoded") + + if err != nil { + log.Error().Msgf("%v", err) + return nil, err + } + + tokenResp, err := client.Do(req) + if err != nil { + log.Error().Msgf("%v", err) + return nil, err + } + defer tokenResp.Body.Close() + + if tokenResp.StatusCode != 200 { + b, _ := io.ReadAll(tokenResp.Body) + log.Error().Msgf("%s", b) + } + + var tokens OpenIDTokens + + err = json.NewDecoder(tokenResp.Body).Decode(&tokens) + if err != nil { + log.Error().Msgf("%v", err) + return nil, err + } + + log.Info().Msg("Successfully exchanged code for tokens") + + return &tokens, nil +} + +// RegisterOIDC redirects to the OIDC provider for authentication +// Puts machine key in cache so the callback can retrieve it using the oidc state param +// Listens in /oidc/register/:mKey +func (h *Headscale) RegisterOIDC(c *gin.Context) { + mKeyStr := c.Param("mKey") + if mKeyStr == "" { + c.String(http.StatusBadRequest, "Wrong params") + return + } + + var err error + + // grab oidc config if it hasn't been already + if oidcConfig == nil { + oidcConfig, err = getOIDCConfig(fmt.Sprintf("%s.well-known/openid-configuration", h.cfg.OIDCEndpoint)) + + if err != nil { + c.String(http.StatusInternalServerError, "Could not retrieve OIDC Config") + return + } + } + + b := make([]byte, 16) + _, err = rand.Read(b) + stateStr := hex.EncodeToString(b)[:32] + + // init the state cache if it hasn't been already + if stateCache == nil { + stateCache = cache.New(time.Minute*5, time.Minute*10) + } + + // place the machine key into the state cache, so it can be retrieved later + stateCache.Set(stateStr, mKeyStr, time.Minute*5) + + params := url.Values{} + params.Add("response_type", "code") + params.Add("client_id", h.cfg.OIDCClientID) + params.Add("redirect_uri", fmt.Sprintf("%s/oidc/callback", h.cfg.ServerURL)) + params.Add("scope", "openid") + params.Add("state", stateStr) + + authUrl := fmt.Sprintf("%s?%s", oidcConfig.AuthorizationEndpoint, params.Encode()) + log.Debug().Msg(authUrl) + + c.Redirect(http.StatusFound, authUrl) +} + +// OIDCCallback handles the callback from the OIDC endpoint +// Retrieves the mkey from the state cache, if the machine is not registered, presents a confirmation +// Listens in /oidc/callback +func (h *Headscale) OIDCCallback(c *gin.Context) { + + code := c.Query("code") + state := c.Query("state") + + if code == "" || state == "" { + c.String(http.StatusBadRequest, "Wrong params") + return + } + + redirectURI := fmt.Sprintf("%s/oidc/callback", h.cfg.ServerURL) + + tokens, err := h.exchangeCodeForTokens(code, redirectURI) + + if err != nil { + c.String(http.StatusBadRequest, "Could not exchange code for token") + return + } + + //verify tokens + claims, err := verifyToken(tokens.AccessToken) + + if err != nil { + c.String(http.StatusBadRequest, "invalid tokens") + return + } + + //retrieve machinekey from state cache + mKeyIf, mKeyFound := stateCache.Get(state) + + if !mKeyFound { + c.String(http.StatusBadRequest, "state has expired") + return + } + mKeyStr, mKeyOK := mKeyIf.(string) + + if !mKeyOK { + c.String(http.StatusInternalServerError, "could not get machine key from cache") + return + } + + // retrieve machine information + var m Machine + if result := h.db.Preload("Namespace").First(&m, "machine_key = ?", mKeyStr); errors.Is(result.Error, gorm.ErrRecordNotFound) { + log.Error().Msg("machine key not found in database") + c.String(http.StatusInternalServerError, "could not get machine info from database") + return + } + + //look for a namespace of the users email for now + if !m.Registered { + + ns, err := h.GetNamespace(claims.Email) + if err != nil { + ns, err = h.CreateNamespace(claims.Email) + } + + ip, err := h.getAvailableIP() + if err != nil { + c.String(http.StatusInternalServerError, "could not get an IP from the pool") + return + } + + m.IPAddress = ip.String() + m.NamespaceID = ns.ID + m.Registered = true + m.RegisterMethod = "oidc" + h.db.Save(&m) + } + + c.Data(http.StatusOK, "text/html; charset=utf-8", []byte(fmt.Sprintf(` + + +

headscale

+

+ Authenticated, you can now close this window. +

+ + + +`))) +} From b22a9781a22a41834dcb87b96b8ae2f87df17d55 Mon Sep 17 00:00:00 2001 From: Raal Goff Date: Sun, 26 Sep 2021 21:12:36 +0800 Subject: [PATCH 002/300] fix linter errors, error out if jwt does not contain a key id --- oidc.go | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/oidc.go b/oidc.go index 0006cc32..dabd8b03 100644 --- a/oidc.go +++ b/oidc.go @@ -94,7 +94,7 @@ func verifyToken(token string) (*AccessToken, error) { } } else { - return nil, err + return nil, errors.New("JWT does not contain a key id") } } @@ -200,6 +200,13 @@ func (h *Headscale) RegisterOIDC(c *gin.Context) { b := make([]byte, 16) _, err = rand.Read(b) + + if err != nil { + log.Error().Msg("could not read 16 bytes from rand") + c.String(http.StatusInternalServerError, "could not read 16 bytes from rand") + return + } + stateStr := hex.EncodeToString(b)[:32] // init the state cache if it hasn't been already @@ -281,6 +288,13 @@ func (h *Headscale) OIDCCallback(c *gin.Context) { ns, err := h.GetNamespace(claims.Email) if err != nil { ns, err = h.CreateNamespace(claims.Email) + + if err != nil { + log.Error().Msgf("could not create new namespace '%s'", claims.Email) + c.String(http.StatusInternalServerError, "could not create new namespace") + return + } + } ip, err := h.getAvailableIP() @@ -301,10 +315,10 @@ func (h *Headscale) OIDCCallback(c *gin.Context) {

headscale

- Authenticated, you can now close this window. + Authenticated as %s, you can now close this window.

-`))) +`, claims.Email))) } From c487591437afb292701c8a905dc7ce9ad0477562 Mon Sep 17 00:00:00 2001 From: Raal Goff Date: Wed, 6 Oct 2021 17:19:15 +0800 Subject: [PATCH 003/300] use go-oidc instead of verifying and extracting tokens ourselves, rename oidc_endpoint to oidc_issuer to be more inline with spec --- api.go | 4 +- app.go | 6 +- cmd/headscale/cli/utils.go | 2 +- go.mod | 7 +- go.sum | 8 +- machine.go | 5 + oidc.go | 222 ++++++++----------------------------- 7 files changed, 69 insertions(+), 185 deletions(-) diff --git a/api.go b/api.go index 2c5a1321..fb54f3cf 100644 --- a/api.go +++ b/api.go @@ -134,7 +134,7 @@ func (h *Headscale) RegistrationHandler(c *gin.Context) { Str("machine", m.Name). Msg("Not registered and not NodeKey rotation. Sending a authurl to register") - if h.cfg.OIDCEndpoint != "" { + if h.cfg.OIDCIssuer != "" { resp.AuthURL = fmt.Sprintf("%s/oidc/register/%s", h.cfg.ServerURL, mKey.HexString()) } else { resp.AuthURL = fmt.Sprintf("%s/register?key=%s", @@ -204,7 +204,7 @@ func (h *Headscale) RegistrationHandler(c *gin.Context) { Str("handler", "Registration"). Str("machine", m.Name). Msg("The node is sending us a new NodeKey, sending auth url") - if h.cfg.OIDCEndpoint != "" { + if h.cfg.OIDCIssuer != "" { resp.AuthURL = fmt.Sprintf("%s/oidc/register/%s", h.cfg.ServerURL, mKey.HexString()) } else { resp.AuthURL = fmt.Sprintf("%s/register?key=%s", diff --git a/app.go b/app.go index 6f24c82b..3c4b307a 100644 --- a/app.go +++ b/app.go @@ -46,7 +46,7 @@ type Config struct { DNSConfig *tailcfg.DNSConfig - OIDCEndpoint string + OIDCIssuer string OIDCClientID string OIDCClientSecret string } @@ -172,11 +172,11 @@ func (h *Headscale) Serve() error { r.GET("/register", h.RegisterWebAPI) r.POST("/machine/:id/map", h.PollNetMapHandler) r.POST("/machine/:id", h.RegistrationHandler) - r.GET("/oidc/register/:mKey", h.RegisterOIDC) + r.GET("/oidc/register/:mkey", h.RegisterOIDC) r.GET("/oidc/callback", h.OIDCCallback) r.GET("/apple", h.AppleMobileConfig) r.GET("/apple/:platform", h.ApplePlatformConfig) - + var err error timeout := 30 * time.Second diff --git a/cmd/headscale/cli/utils.go b/cmd/headscale/cli/utils.go index b7faad57..6ccdcdee 100644 --- a/cmd/headscale/cli/utils.go +++ b/cmd/headscale/cli/utils.go @@ -171,7 +171,7 @@ func getHeadscaleApp() (*headscale.Headscale, error) { DNSConfig: GetDNSConfig(), - OIDCEndpoint: viper.GetString("oidc_endpoint"), + OIDCIssuer: viper.GetString("oidc_issuer"), OIDCClientID: viper.GetString("oidc_client_id"), OIDCClientSecret: viper.GetString("oidc_client_secret"), } diff --git a/go.mod b/go.mod index c1d4561b..a770338b 100644 --- a/go.mod +++ b/go.mod @@ -7,11 +7,12 @@ require ( github.com/Microsoft/go-winio v0.5.0 // indirect github.com/cenkalti/backoff/v4 v4.1.1 // indirect github.com/containerd/continuity v0.1.0 // indirect + github.com/coreos/go-oidc/v3 v3.1.0 github.com/docker/cli v20.10.8+incompatible // indirect github.com/docker/docker v20.10.8+incompatible // indirect github.com/efekarakus/termcolor v1.0.1 github.com/gin-gonic/gin v1.7.4 - github.com/gofrs/uuid v4.0.0+incompatible // indirect + github.com/gofrs/uuid v4.0.0+incompatible github.com/google/go-github v17.0.0+incompatible // indirect github.com/google/go-querystring v1.1.0 // indirect github.com/hako/durafmt v0.0.0-20210608085754-5c1018a4e16b @@ -28,13 +29,13 @@ require ( github.com/spf13/viper v1.8.1 github.com/stretchr/testify v1.7.0 github.com/tailscale/hujson v0.0.0-20210818175511-7360507a6e88 - github.com/tcnksm/go-latest v0.0.0-20170313132115-e3007ae9052e // indirect + github.com/tcnksm/go-latest v0.0.0-20170313132115-e3007ae9052e github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 golang.org/x/net v0.0.0-20210913180222-943fd674d43e // indirect + golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602 golang.org/x/sys v0.0.0-20210910150752-751e447fb3d0 // indirect gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c - gopkg.in/square/go-jose.v2 v2.3.1 gopkg.in/yaml.v2 v2.4.0 gorm.io/datatypes v1.0.2 gorm.io/driver/postgres v1.1.1 diff --git a/go.sum b/go.sum index 9a76d176..fc498e75 100644 --- a/go.sum +++ b/go.sum @@ -143,6 +143,8 @@ github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkE github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-iptables v0.6.0/go.mod h1:Qe8Bv2Xik5FyTXwgIbLAnv2sWSBmvWdFETJConOQ//Q= +github.com/coreos/go-oidc/v3 v3.1.0 h1:6avEvcdvTa1qYsOZ6I5PRkSYHzpTNWgKYmaJfaYbrRw= +github.com/coreos/go-oidc/v3 v3.1.0/go.mod h1:rEJ/idjfUyfkBit1eI1fvyr+64/g9dcKpAm8MJMesvo= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= @@ -1067,6 +1069,7 @@ golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200505041828-1ed23360d12c/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= @@ -1101,6 +1104,7 @@ golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602 h1:0Ja1LBD+yisY6RWM/BH7TJVXWsSjs2VwBSmvSX4HdBc= golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1355,6 +1359,7 @@ google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7 google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= @@ -1452,8 +1457,9 @@ gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.62.0 h1:duBzk771uxoUuOlyRLkHsygud9+5lrlGjdFBb4mSKDU= gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= -gopkg.in/square/go-jose.v2 v2.3.1 h1:SK5KegNXmKmqE342YYN2qPHEnUYeoMiXXl1poUlI+o4= gopkg.in/square/go-jose.v2 v2.3.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= +gopkg.in/square/go-jose.v2 v2.5.1 h1:7odma5RETjNHWJnR32wx8t+Io4djHE1PqxCFx3iiZ2w= +gopkg.in/square/go-jose.v2 v2.5.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= diff --git a/machine.go b/machine.go index 1d4939c1..b5c821f5 100644 --- a/machine.go +++ b/machine.go @@ -50,6 +50,11 @@ func (m Machine) isAlreadyRegistered() bool { return m.Registered } +// isExpired returns whether the machine registration has expired +func (m Machine) isExpired() bool { + return time.Now().UTC().After(*m.Expiry) +} + // toNode converts a Machine into a Tailscale Node. includeRoutes is false for shared nodes // as per the expected behaviour in the official SaaS func (m Machine) toNode(includeRoutes bool) (*tailcfg.Node, error) { diff --git a/oidc.go b/oidc.go index dabd8b03..aa80911b 100644 --- a/oidc.go +++ b/oidc.go @@ -1,186 +1,37 @@ package headscale import ( + "context" "crypto/rand" "encoding/hex" - "encoding/json" "errors" "fmt" + "github.com/coreos/go-oidc/v3/oidc" "github.com/gin-gonic/gin" "github.com/patrickmn/go-cache" "github.com/rs/zerolog/log" - "github.com/s12v/go-jwks" - "gopkg.in/square/go-jose.v2/jwt" + "golang.org/x/oauth2" "gorm.io/gorm" - "io" "net/http" - "net/url" - "strings" "time" ) -type OpenIDConfiguration struct { - Issuer string `json:"issuer"` - AuthorizationEndpoint string `json:"authorization_endpoint"` - TokenEndpoint string `json:"token_endpoint"` - JWKSURI string `json:"jwks_uri"` -} - -type OpenIDTokens struct { - AccessToken string `json:"access_token"` - ExpiresIn int `json:"expires_in"` - IdToken string `json:"id_token"` - NotBeforePolicy int `json:"not-before-policy,omitempty"` - RefreshExpiresIn int `json:"refresh_expires_in"` - RefreshToken string `json:"refresh_token"` - Scope string `json:"scope"` - SessionState string `json:"session_state,omitempty"` - TokenType string `json:"token_type,omitempty"` -} - -type AccessToken struct { - jwt.Claims +type IDTokenClaims struct { Name string `json:"name,omitempty"` Groups []string `json:"groups,omitempty"` Email string `json:"email"` Username string `json:"preferred_username,omitempty"` } -var oidcConfig *OpenIDConfiguration +var oidcProvider *oidc.Provider +var oauth2Config *oauth2.Config var stateCache *cache.Cache -var jwksSource *jwks.WebSource -var jwksClient jwks.JWKSClient - -func verifyToken(token string) (*AccessToken, error) { - - if jwksClient == nil { - jwksSource = jwks.NewWebSource(oidcConfig.JWKSURI) - jwksClient = jwks.NewDefaultClient( - jwksSource, - time.Hour, // Refresh keys every 1 hour - 12*time.Hour, // Expire keys after 12 hours - ) - } - - //decode jwt - tok, err := jwt.ParseSigned(token) - if err != nil { - return nil, err - } - - if tok.Headers[0].KeyID != "" { - log.Debug().Msgf("Checking KID %s\n", tok.Headers[0].KeyID) - - jwk, err := jwksClient.GetSignatureKey(tok.Headers[0].KeyID) - if err != nil { - return nil, err - } - - claims := AccessToken{} - - err = tok.Claims(jwk.Certificates[0].PublicKey, &claims) - if err != nil { - return nil, err - } else { - - err = claims.Validate(jwt.Expected{ - Time: time.Now(), - }) - if err != nil { - return nil, err - } - - return &claims, nil - } - - } else { - return nil, errors.New("JWT does not contain a key id") - } -} - -func getOIDCConfig(oidcConfigURL string) (*OpenIDConfiguration, error) { - client := &http.Client{} - req, err := http.NewRequest("GET", oidcConfigURL, nil) - if err != nil { - log.Error().Msgf("%v", err) - return nil, err - } - - log.Debug().Msgf("Requesting OIDC Config from %s", oidcConfigURL) - - oidcConfigResp, err := client.Do(req) - if err != nil { - log.Error().Msgf("%v", err) - return nil, err - } - defer oidcConfigResp.Body.Close() - - var oidcConfig OpenIDConfiguration - - err = json.NewDecoder(oidcConfigResp.Body).Decode(&oidcConfig) - if err != nil { - log.Error().Msgf("%v", err) - return nil, err - } - return &oidcConfig, nil -} - -func (h *Headscale) exchangeCodeForTokens(code string, redirectURI string) (*OpenIDTokens, error) { - var err error - - if oidcConfig == nil { - oidcConfig, err = getOIDCConfig(fmt.Sprintf("%s.well-known/openid-configuration", h.cfg.OIDCEndpoint)) - if err != nil { - return nil, err - } - } - - params := url.Values{} - params.Add("grant_type", "authorization_code") - params.Add("code", code) - params.Add("client_id", h.cfg.OIDCClientID) - params.Add("client_secret", h.cfg.OIDCClientSecret) - params.Add("redirect_uri", redirectURI) - - client := &http.Client{} - req, err := http.NewRequest("POST", oidcConfig.TokenEndpoint, strings.NewReader(params.Encode())) - req.Header.Add("Content-Type", "application/x-www-form-urlencoded") - - if err != nil { - log.Error().Msgf("%v", err) - return nil, err - } - - tokenResp, err := client.Do(req) - if err != nil { - log.Error().Msgf("%v", err) - return nil, err - } - defer tokenResp.Body.Close() - - if tokenResp.StatusCode != 200 { - b, _ := io.ReadAll(tokenResp.Body) - log.Error().Msgf("%s", b) - } - - var tokens OpenIDTokens - - err = json.NewDecoder(tokenResp.Body).Decode(&tokens) - if err != nil { - log.Error().Msgf("%v", err) - return nil, err - } - - log.Info().Msg("Successfully exchanged code for tokens") - - return &tokens, nil -} // RegisterOIDC redirects to the OIDC provider for authentication // Puts machine key in cache so the callback can retrieve it using the oidc state param // Listens in /oidc/register/:mKey func (h *Headscale) RegisterOIDC(c *gin.Context) { - mKeyStr := c.Param("mKey") + mKeyStr := c.Param("mkey") if mKeyStr == "" { c.String(http.StatusBadRequest, "Wrong params") return @@ -189,13 +40,23 @@ func (h *Headscale) RegisterOIDC(c *gin.Context) { var err error // grab oidc config if it hasn't been already - if oidcConfig == nil { - oidcConfig, err = getOIDCConfig(fmt.Sprintf("%s.well-known/openid-configuration", h.cfg.OIDCEndpoint)) + if oauth2Config == nil { + oidcProvider, err = oidc.NewProvider(context.Background(), h.cfg.OIDCIssuer) if err != nil { + log.Error().Msgf("Could not retrieve OIDC Config: %s", err.Error()) c.String(http.StatusInternalServerError, "Could not retrieve OIDC Config") return } + + oauth2Config = &oauth2.Config{ + ClientID: h.cfg.OIDCClientID, + ClientSecret: h.cfg.OIDCClientSecret, + Endpoint: oidcProvider.Endpoint(), + RedirectURL: fmt.Sprintf("%s/oidc/callback", h.cfg.ServerURL), + Scopes: []string{oidc.ScopeOpenID, "profile", "email"}, + } + } b := make([]byte, 16) @@ -217,21 +78,16 @@ func (h *Headscale) RegisterOIDC(c *gin.Context) { // place the machine key into the state cache, so it can be retrieved later stateCache.Set(stateStr, mKeyStr, time.Minute*5) - params := url.Values{} - params.Add("response_type", "code") - params.Add("client_id", h.cfg.OIDCClientID) - params.Add("redirect_uri", fmt.Sprintf("%s/oidc/callback", h.cfg.ServerURL)) - params.Add("scope", "openid") - params.Add("state", stateStr) - - authUrl := fmt.Sprintf("%s?%s", oidcConfig.AuthorizationEndpoint, params.Encode()) - log.Debug().Msg(authUrl) + authUrl := oauth2Config.AuthCodeURL(stateStr) + log.Debug().Msgf("Redirecting to %s for authentication", authUrl) c.Redirect(http.StatusFound, authUrl) } // OIDCCallback handles the callback from the OIDC endpoint -// Retrieves the mkey from the state cache, if the machine is not registered, presents a confirmation +// Retrieves the mkey from the state cache and adds the machine to the users email namespace +// TODO: A confirmation page for new machines should be added to avoid phishing vulnerabilities +// TODO: Add groups information from OIDC tokens into machine HostInfo // Listens in /oidc/callback func (h *Headscale) OIDCCallback(c *gin.Context) { @@ -243,20 +99,36 @@ func (h *Headscale) OIDCCallback(c *gin.Context) { return } - redirectURI := fmt.Sprintf("%s/oidc/callback", h.cfg.ServerURL) - - tokens, err := h.exchangeCodeForTokens(code, redirectURI) - + oauth2Token, err := oauth2Config.Exchange(context.Background(), code) if err != nil { c.String(http.StatusBadRequest, "Could not exchange code for token") return } - //verify tokens - claims, err := verifyToken(tokens.AccessToken) + rawIDToken, rawIDTokenOK := oauth2Token.Extra("id_token").(string) + if !rawIDTokenOK { + c.String(http.StatusBadRequest, "Could not extract ID Token") + return + } + verifier := oidcProvider.Verifier(&oidc.Config{ClientID: h.cfg.OIDCClientID}) + + idToken, err := verifier.Verify(context.Background(), rawIDToken) if err != nil { - c.String(http.StatusBadRequest, "invalid tokens") + c.String(http.StatusBadRequest, "Failed to verify id token: %s", err.Error()) + return + } + + //userInfo, err := oidcProvider.UserInfo(context.Background(), oauth2.StaticTokenSource(oauth2Token)) + //if err != nil { + // c.String(http.StatusBadRequest, "Failed to retrieve userinfo: "+err.Error()) + // return + //} + + // Extract custom claims + var claims IDTokenClaims + if err = idToken.Claims(&claims); err != nil { + c.String(http.StatusBadRequest, "Failed to decode id token claims: "+err.Error()) return } From 35795c79c367c80590deefe51415bc364f82a024 Mon Sep 17 00:00:00 2001 From: unreality Date: Fri, 8 Oct 2021 15:26:31 +0800 Subject: [PATCH 004/300] Handle trailing slash on uris Co-authored-by: Kristoffer Dalby --- api.go | 8 ++++---- oidc.go | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/api.go b/api.go index fb54f3cf..ddabd937 100644 --- a/api.go +++ b/api.go @@ -135,10 +135,10 @@ func (h *Headscale) RegistrationHandler(c *gin.Context) { Msg("Not registered and not NodeKey rotation. Sending a authurl to register") if h.cfg.OIDCIssuer != "" { - resp.AuthURL = fmt.Sprintf("%s/oidc/register/%s", h.cfg.ServerURL, mKey.HexString()) + resp.AuthURL = fmt.Sprintf("%s/oidc/register/%s", strings.TrimSuffix(h.cfg.ServerURL, "/"), mKey.HexString()) } else { resp.AuthURL = fmt.Sprintf("%s/register?key=%s", - h.cfg.ServerURL, mKey.HexString()) + strings.TrimSuffix(h.cfg.ServerURL, "/"), mKey.HexString()) } respBody, err := encode(resp, &mKey, h.privateKey) if err != nil { @@ -205,10 +205,10 @@ func (h *Headscale) RegistrationHandler(c *gin.Context) { Str("machine", m.Name). Msg("The node is sending us a new NodeKey, sending auth url") if h.cfg.OIDCIssuer != "" { - resp.AuthURL = fmt.Sprintf("%s/oidc/register/%s", h.cfg.ServerURL, mKey.HexString()) + resp.AuthURL = fmt.Sprintf("%s/oidc/register/%s", strings.TrimSuffix(h.cfg.ServerURL, "/"), mKey.HexString()) } else { resp.AuthURL = fmt.Sprintf("%s/register?key=%s", - h.cfg.ServerURL, mKey.HexString()) + strings.TrimSuffix(h.cfg.ServerURL, "/"), mKey.HexString()) } respBody, err := encode(resp, &mKey, h.privateKey) if err != nil { diff --git a/oidc.go b/oidc.go index aa80911b..328731ec 100644 --- a/oidc.go +++ b/oidc.go @@ -53,7 +53,7 @@ func (h *Headscale) RegisterOIDC(c *gin.Context) { ClientID: h.cfg.OIDCClientID, ClientSecret: h.cfg.OIDCClientSecret, Endpoint: oidcProvider.Endpoint(), - RedirectURL: fmt.Sprintf("%s/oidc/callback", h.cfg.ServerURL), + RedirectURL: fmt.Sprintf("%s/oidc/callback", strings.TrimSuffix(h.cfg.ServerURL, "/")), Scopes: []string{oidc.ScopeOpenID, "profile", "email"}, } From e407d423d44c208d0989f9ec8e94ca29909a6f16 Mon Sep 17 00:00:00 2001 From: Raal Goff Date: Fri, 8 Oct 2021 17:43:52 +0800 Subject: [PATCH 005/300] updates from code review --- api.go | 56 +++++++++++++++++++++--- app.go | 17 ++++++++ cmd/headscale/cli/utils.go | 13 ++++++ oidc.go | 88 ++++++++++++++++++++++---------------- 4 files changed, 131 insertions(+), 43 deletions(-) diff --git a/api.go b/api.go index ddabd937..02f28919 100644 --- a/api.go +++ b/api.go @@ -7,6 +7,7 @@ import ( "fmt" "io" "net/http" + "strings" "time" "github.com/rs/zerolog/log" @@ -83,7 +84,7 @@ func (h *Headscale) RegistrationHandler(c *gin.Context) { if result := h.db.Preload("Namespace").First(&m, "machine_key = ?", mKey.HexString()); errors.Is(result.Error, gorm.ErrRecordNotFound) { log.Info().Str("machine", req.Hostinfo.Hostname).Msg("New machine") m = Machine{ - Expiry: &req.Expiry, + Expiry: &time.Time{}, MachineKey: mKey.HexString(), Name: req.Hostinfo.Hostname, NodeKey: wgkey.Key(req.NodeKey).HexString(), @@ -107,7 +108,33 @@ func (h *Headscale) RegistrationHandler(c *gin.Context) { // We have the updated key! if m.NodeKey == wgkey.Key(req.NodeKey).HexString() { - if m.Registered { + + if !req.Expiry.IsZero() && req.Expiry.UTC().Before(now) { + log.Debug(). + Str("handler", "Registration"). + Str("machine", m.Name). + Msg("Client requested logout") + + m.Expiry = &req.Expiry + h.db.Save(&m) + + resp.AuthURL = "" + resp.MachineAuthorized = false + resp.User = *m.Namespace.toUser() + respBody, err := encode(resp, &mKey, h.privateKey) + if err != nil { + log.Error(). + Str("handler", "Registration"). + Err(err). + Msg("Cannot encode message") + c.String(http.StatusInternalServerError, "") + return + } + c.Data(200, "application/json; charset=utf-8", respBody) + return + } + + if m.Registered && m.Expiry.UTC().After(now) { log.Debug(). Str("handler", "Registration"). Str("machine", m.Name). @@ -132,14 +159,19 @@ func (h *Headscale) RegistrationHandler(c *gin.Context) { log.Debug(). Str("handler", "Registration"). Str("machine", m.Name). - Msg("Not registered and not NodeKey rotation. Sending a authurl to register") + Msg("Not registered (or expired) and not NodeKey rotation. Sending a authurl to register") if h.cfg.OIDCIssuer != "" { - resp.AuthURL = fmt.Sprintf("%s/oidc/register/%s", strings.TrimSuffix(h.cfg.ServerURL, "/"), mKey.HexString()) + resp.AuthURL = fmt.Sprintf("%s/oidc/register/%s", + strings.TrimSuffix(h.cfg.ServerURL, "/"), mKey.HexString()) } else { resp.AuthURL = fmt.Sprintf("%s/register?key=%s", strings.TrimSuffix(h.cfg.ServerURL, "/"), mKey.HexString()) } + + m.Expiry = &req.Expiry // save the requested expiry time for retrieval later + h.db.Save(&m) + respBody, err := encode(resp, &mKey, h.privateKey) if err != nil { log.Error(). @@ -153,8 +185,8 @@ func (h *Headscale) RegistrationHandler(c *gin.Context) { return } - // The NodeKey we have matches OldNodeKey, which means this is a refresh after an key expiration - if m.NodeKey == wgkey.Key(req.OldNodeKey).HexString() { + // The NodeKey we have matches OldNodeKey, which means this is a refresh after a key expiration + if m.NodeKey == wgkey.Key(req.OldNodeKey).HexString() && m.Expiry.UTC().After(now) { log.Debug(). Str("handler", "Registration"). Str("machine", m.Name). @@ -179,14 +211,19 @@ func (h *Headscale) RegistrationHandler(c *gin.Context) { // We arrive here after a client is restarted without finalizing the authentication flow or // when headscale is stopped in the middle of the auth process. - if m.Registered { + if m.Registered && m.Expiry.UTC().After(now) { log.Debug(). Str("handler", "Registration"). Str("machine", m.Name). Msg("The node is sending us a new NodeKey, but machine is registered. All clear for /map") + + m.NodeKey = wgkey.Key(req.NodeKey).HexString() + h.db.Save(&m) + resp.AuthURL = "" resp.MachineAuthorized = true resp.User = *m.Namespace.toUser() + respBody, err := encode(resp, &mKey, h.privateKey) if err != nil { log.Error(). @@ -210,6 +247,11 @@ func (h *Headscale) RegistrationHandler(c *gin.Context) { resp.AuthURL = fmt.Sprintf("%s/register?key=%s", strings.TrimSuffix(h.cfg.ServerURL, "/"), mKey.HexString()) } + + m.Expiry = &req.Expiry // save the requested expiry time for retrieval later + m.NodeKey = wgkey.Key(req.NodeKey).HexString() // save the new nodekey + h.db.Save(&m) + respBody, err := encode(resp, &mKey, h.privateKey) if err != nil { log.Error(). diff --git a/app.go b/app.go index 3c4b307a..2ad72154 100644 --- a/app.go +++ b/app.go @@ -3,6 +3,9 @@ package headscale import ( "errors" "fmt" + "github.com/coreos/go-oidc/v3/oidc" + "github.com/patrickmn/go-cache" + "golang.org/x/oauth2" "net/http" "os" "strings" @@ -49,6 +52,9 @@ type Config struct { OIDCIssuer string OIDCClientID string OIDCClientSecret string + + MaxMachineExpiry time.Duration + DefaultMachineExpiry time.Duration } // Headscale represents the base app of the service @@ -68,6 +74,10 @@ type Headscale struct { clientsUpdateChannelMutex sync.Mutex lastStateChange sync.Map + + oidcProvider *oidc.Provider + oauth2Config *oauth2.Config + oidcStateCache *cache.Cache } // NewHeadscale returns the Headscale app @@ -107,6 +117,13 @@ func NewHeadscale(cfg Config) (*Headscale, error) { return nil, err } + if cfg.OIDCIssuer != "" { + err = h.initOIDC() + if err != nil { + return nil, err + } + } + return &h, nil } diff --git a/cmd/headscale/cli/utils.go b/cmd/headscale/cli/utils.go index 6ccdcdee..67017aa0 100644 --- a/cmd/headscale/cli/utils.go +++ b/cmd/headscale/cli/utils.go @@ -144,6 +144,16 @@ func getHeadscaleApp() (*headscale.Headscale, error) { return nil, err } + maxMachineExpiry, _ := time.ParseDuration("8h") + if viper.GetDuration("max_machine_expiry") >= time.Second { + maxMachineExpiry = viper.GetDuration("max_machine_expiry") + } + + defaultMachineExpiry, _ := time.ParseDuration("8h") + if viper.GetDuration("default_machine_expiry") >= time.Second { + defaultMachineExpiry = viper.GetDuration("default_machine_expiry") + } + cfg := headscale.Config{ ServerURL: viper.GetString("server_url"), Addr: viper.GetString("listen_addr"), @@ -174,6 +184,9 @@ func getHeadscaleApp() (*headscale.Headscale, error) { OIDCIssuer: viper.GetString("oidc_issuer"), OIDCClientID: viper.GetString("oidc_client_id"), OIDCClientSecret: viper.GetString("oidc_client_secret"), + + MaxMachineExpiry: maxMachineExpiry, + DefaultMachineExpiry: defaultMachineExpiry, } h, err := headscale.NewHeadscale(cfg) diff --git a/oidc.go b/oidc.go index 328731ec..1220098c 100644 --- a/oidc.go +++ b/oidc.go @@ -13,6 +13,7 @@ import ( "golang.org/x/oauth2" "gorm.io/gorm" "net/http" + "strings" "time" ) @@ -23,9 +24,33 @@ type IDTokenClaims struct { Username string `json:"preferred_username,omitempty"` } -var oidcProvider *oidc.Provider -var oauth2Config *oauth2.Config -var stateCache *cache.Cache +func (h *Headscale) initOIDC() error { + var err error + // grab oidc config if it hasn't been already + if h.oauth2Config == nil { + h.oidcProvider, err = oidc.NewProvider(context.Background(), h.cfg.OIDCIssuer) + + if err != nil { + log.Error().Msgf("Could not retrieve OIDC Config: %s", err.Error()) + return err + } + + h.oauth2Config = &oauth2.Config{ + ClientID: h.cfg.OIDCClientID, + ClientSecret: h.cfg.OIDCClientSecret, + Endpoint: h.oidcProvider.Endpoint(), + RedirectURL: fmt.Sprintf("%s/oidc/callback", strings.TrimSuffix(h.cfg.ServerURL, "/")), + Scopes: []string{oidc.ScopeOpenID, "profile", "email"}, + } + } + + // init the state cache if it hasn't been already + if h.oidcStateCache == nil { + h.oidcStateCache = cache.New(time.Minute*5, time.Minute*10) + } + + return nil +} // RegisterOIDC redirects to the OIDC provider for authentication // Puts machine key in cache so the callback can retrieve it using the oidc state param @@ -37,30 +62,8 @@ func (h *Headscale) RegisterOIDC(c *gin.Context) { return } - var err error - - // grab oidc config if it hasn't been already - if oauth2Config == nil { - oidcProvider, err = oidc.NewProvider(context.Background(), h.cfg.OIDCIssuer) - - if err != nil { - log.Error().Msgf("Could not retrieve OIDC Config: %s", err.Error()) - c.String(http.StatusInternalServerError, "Could not retrieve OIDC Config") - return - } - - oauth2Config = &oauth2.Config{ - ClientID: h.cfg.OIDCClientID, - ClientSecret: h.cfg.OIDCClientSecret, - Endpoint: oidcProvider.Endpoint(), - RedirectURL: fmt.Sprintf("%s/oidc/callback", strings.TrimSuffix(h.cfg.ServerURL, "/")), - Scopes: []string{oidc.ScopeOpenID, "profile", "email"}, - } - - } - b := make([]byte, 16) - _, err = rand.Read(b) + _, err := rand.Read(b) if err != nil { log.Error().Msg("could not read 16 bytes from rand") @@ -70,15 +73,10 @@ func (h *Headscale) RegisterOIDC(c *gin.Context) { stateStr := hex.EncodeToString(b)[:32] - // init the state cache if it hasn't been already - if stateCache == nil { - stateCache = cache.New(time.Minute*5, time.Minute*10) - } - // place the machine key into the state cache, so it can be retrieved later - stateCache.Set(stateStr, mKeyStr, time.Minute*5) + h.oidcStateCache.Set(stateStr, mKeyStr, time.Minute*5) - authUrl := oauth2Config.AuthCodeURL(stateStr) + authUrl := h.oauth2Config.AuthCodeURL(stateStr) log.Debug().Msgf("Redirecting to %s for authentication", authUrl) c.Redirect(http.StatusFound, authUrl) @@ -99,7 +97,7 @@ func (h *Headscale) OIDCCallback(c *gin.Context) { return } - oauth2Token, err := oauth2Config.Exchange(context.Background(), code) + oauth2Token, err := h.oauth2Config.Exchange(context.Background(), code) if err != nil { c.String(http.StatusBadRequest, "Could not exchange code for token") return @@ -111,7 +109,7 @@ func (h *Headscale) OIDCCallback(c *gin.Context) { return } - verifier := oidcProvider.Verifier(&oidc.Config{ClientID: h.cfg.OIDCClientID}) + verifier := h.oidcProvider.Verifier(&oidc.Config{ClientID: h.cfg.OIDCClientID}) idToken, err := verifier.Verify(context.Background(), rawIDToken) if err != nil { @@ -133,7 +131,7 @@ func (h *Headscale) OIDCCallback(c *gin.Context) { } //retrieve machinekey from state cache - mKeyIf, mKeyFound := stateCache.Get(state) + mKeyIf, mKeyFound := h.oidcStateCache.Get(state) if !mKeyFound { c.String(http.StatusBadRequest, "state has expired") @@ -157,6 +155,8 @@ func (h *Headscale) OIDCCallback(c *gin.Context) { //look for a namespace of the users email for now if !m.Registered { + log.Debug().Msg("Registering new machine after successful callback") + ns, err := h.GetNamespace(claims.Email) if err != nil { ns, err = h.CreateNamespace(claims.Email) @@ -182,6 +182,22 @@ func (h *Headscale) OIDCCallback(c *gin.Context) { h.db.Save(&m) } + if m.isExpired() { + maxExpiry := time.Now().UTC().Add(h.cfg.MaxMachineExpiry) + + // use the maximum expiry if it's sooner than the requested expiry + if maxExpiry.Before(*m.Expiry) { + log.Debug().Msgf("Clamping expiry time to maximum: %v (%v)", maxExpiry, h.cfg.MaxMachineExpiry) + m.Expiry = &maxExpiry + h.db.Save(&m) + } else if m.Expiry.IsZero() { + log.Debug().Msgf("Using default machine expiry time: %v (%v)", maxExpiry, h.cfg.MaxMachineExpiry) + defaultExpiry := time.Now().UTC().Add(h.cfg.DefaultMachineExpiry) + m.Expiry = &defaultExpiry + h.db.Save(&m) + } + } + c.Data(http.StatusOK, "text/html; charset=utf-8", []byte(fmt.Sprintf(` From 74e6c1479e64ea13e49fbb4ca87f668dd14068ab Mon Sep 17 00:00:00 2001 From: Raal Goff Date: Sun, 10 Oct 2021 17:22:42 +0800 Subject: [PATCH 006/300] updates from code review --- api.go | 71 +++++++++++++------------------------- app.go | 4 +-- cli.go | 3 ++ cmd/headscale/cli/utils.go | 18 +++++----- go.mod | 6 ++-- machine.go | 30 ++++++++++++++-- oidc.go | 43 ++++++++++------------- 7 files changed, 88 insertions(+), 87 deletions(-) diff --git a/api.go b/api.go index a70df5b3..bda9d9bd 100644 --- a/api.go +++ b/api.go @@ -65,7 +65,7 @@ func (h *Headscale) RegistrationHandler(c *gin.Context) { Str("handler", "Registration"). Err(err). Msg("Cannot parse machine key") - machineRegistrations.WithLabelValues("unkown", "web", "error", "unknown").Inc() + machineRegistrations.WithLabelValues("unknown", "web", "error", "unknown").Inc() c.String(http.StatusInternalServerError, "Sad!") return } @@ -76,34 +76,33 @@ func (h *Headscale) RegistrationHandler(c *gin.Context) { Str("handler", "Registration"). Err(err). Msg("Cannot decode message") - machineRegistrations.WithLabelValues("unkown", "web", "error", "unknown").Inc() + machineRegistrations.WithLabelValues("unknown", "web", "error", "unknown").Inc() c.String(http.StatusInternalServerError, "Very sad!") return } now := time.Now().UTC() - var m Machine - if result := h.db.Preload("Namespace").First(&m, "machine_key = ?", mKey.HexString()); errors.Is(result.Error, gorm.ErrRecordNotFound) { + m, err := h.GetMachineByMachineKey(mKey.HexString()) + if errors.Is(err, gorm.ErrRecordNotFound) { log.Info().Str("machine", req.Hostinfo.Hostname).Msg("New machine") - m = Machine{ - Expiry: &time.Time{}, - MachineKey: mKey.HexString(), - Name: req.Hostinfo.Hostname, - NodeKey: wgkey.Key(req.NodeKey).HexString(), - LastSuccessfulUpdate: &now, + newMachine := Machine{ + Expiry: &time.Time{}, + MachineKey: mKey.HexString(), + Name: req.Hostinfo.Hostname, } - if err := h.db.Create(&m).Error; err != nil { + if err := h.db.Create(&newMachine).Error; err != nil { log.Error(). Str("handler", "Registration"). Err(err). Msg("Could not create row") - machineRegistrations.WithLabelValues("unkown", "web", "error", m.Namespace.Name).Inc() + machineRegistrations.WithLabelValues("unknown", "web", "error", m.Namespace.Name).Inc() return } + m = &newMachine } if !m.Registered && req.Auth.AuthKey != "" { - h.handleAuthKey(c, h.db, mKey, req, m) + h.handleAuthKey(c, h.db, mKey, req, *m) return } @@ -112,13 +111,14 @@ func (h *Headscale) RegistrationHandler(c *gin.Context) { // We have the updated key! if m.NodeKey == wgkey.Key(req.NodeKey).HexString() { + // The client sends an Expiry in the past if the client is requesting a logout if !req.Expiry.IsZero() && req.Expiry.UTC().Before(now) { - log.Debug(). + log.Info(). Str("handler", "Registration"). Str("machine", m.Name). Msg("Client requested logout") - m.Expiry = &req.Expiry + m.Expiry = &req.Expiry // save the expiry so that the machine is marked as expired h.db.Save(&m) resp.AuthURL = "" @@ -138,6 +138,7 @@ func (h *Headscale) RegistrationHandler(c *gin.Context) { } if m.Registered && m.Expiry.UTC().After(now) { + // The machine registration is valid, respond with redirect to /map log.Debug(). Str("handler", "Registration"). Str("machine", m.Name). @@ -161,10 +162,11 @@ func (h *Headscale) RegistrationHandler(c *gin.Context) { return } + // The client has registered before, but has expired log.Debug(). Str("handler", "Registration"). Str("machine", m.Name). - Msg("Not registered (or expired) and not NodeKey rotation. Sending a authurl to register") + Msg("Machine registration has expired. Sending a authurl to register") if h.cfg.OIDCIssuer != "" { resp.AuthURL = fmt.Sprintf("%s/oidc/register/%s", @@ -174,7 +176,7 @@ func (h *Headscale) RegistrationHandler(c *gin.Context) { strings.TrimSuffix(h.cfg.ServerURL, "/"), mKey.HexString()) } - m.Expiry = &req.Expiry // save the requested expiry time for retrieval later + m.RequestedExpiry = &req.Expiry // save the requested expiry time for retrieval later in the authentication flow h.db.Save(&m) respBody, err := encode(resp, &mKey, h.privateKey) @@ -216,34 +218,7 @@ func (h *Headscale) RegistrationHandler(c *gin.Context) { return } - // We arrive here after a client is restarted without finalizing the authentication flow or - // when headscale is stopped in the middle of the auth process. - if m.Registered && m.Expiry.UTC().After(now) { - log.Debug(). - Str("handler", "Registration"). - Str("machine", m.Name). - Msg("The node is sending us a new NodeKey, but machine is registered. All clear for /map") - - m.NodeKey = wgkey.Key(req.NodeKey).HexString() - h.db.Save(&m) - - resp.AuthURL = "" - resp.MachineAuthorized = true - resp.User = *m.Namespace.toUser() - - respBody, err := encode(resp, &mKey, h.privateKey) - if err != nil { - log.Error(). - Str("handler", "Registration"). - Err(err). - Msg("Cannot encode message") - c.String(http.StatusInternalServerError, "") - return - } - c.Data(200, "application/json; charset=utf-8", respBody) - return - } - + // The machine registration is new, redirect the client to the registration URL log.Debug(). Str("handler", "Registration"). Str("machine", m.Name). @@ -255,8 +230,8 @@ func (h *Headscale) RegistrationHandler(c *gin.Context) { strings.TrimSuffix(h.cfg.ServerURL, "/"), mKey.HexString()) } - m.Expiry = &req.Expiry // save the requested expiry time for retrieval later - m.NodeKey = wgkey.Key(req.NodeKey).HexString() // save the new nodekey + m.RequestedExpiry = &req.Expiry // save the requested expiry time for retrieval later in the authentication flow + m.NodeKey = wgkey.Key(req.NodeKey).HexString() // save the NodeKey h.db.Save(&m) respBody, err := encode(resp, &mKey, h.privateKey) @@ -436,6 +411,8 @@ func (h *Headscale) handleAuthKey(c *gin.Context, db *gorm.DB, idKey wgkey.Key, m.RegisterMethod = "authKey" db.Save(&m) + h.updateMachineExpiry(&m) // TODO: do we want to do different expiry times for AuthKeys? + resp.MachineAuthorized = true resp.User = *pak.Namespace.toUser() respBody, err := encode(resp, &idKey, h.privateKey) diff --git a/app.go b/app.go index 9e688fe1..239998c2 100644 --- a/app.go +++ b/app.go @@ -59,8 +59,8 @@ type Config struct { OIDCClientID string OIDCClientSecret string - MaxMachineExpiry time.Duration - DefaultMachineExpiry time.Duration + MaxMachineRegistrationDuration time.Duration + DefaultMachineRegistrationDuration time.Duration } // Headscale represents the base app of the service diff --git a/cli.go b/cli.go index 9c5b66e5..8610b334 100644 --- a/cli.go +++ b/cli.go @@ -23,6 +23,8 @@ func (h *Headscale) RegisterMachine(key string, namespace string) (*Machine, err return nil, errors.New("Machine not found") } + h.updateMachineExpiry(&m) // update the machine's expiry before bailing if its already registered + if m.isAlreadyRegistered() { return nil, errors.New("Machine already registered") } @@ -36,5 +38,6 @@ func (h *Headscale) RegisterMachine(key string, namespace string) (*Machine, err m.Registered = true m.RegisterMethod = "cli" h.db.Save(&m) + return &m, nil } diff --git a/cmd/headscale/cli/utils.go b/cmd/headscale/cli/utils.go index 17bc37e7..366e9597 100644 --- a/cmd/headscale/cli/utils.go +++ b/cmd/headscale/cli/utils.go @@ -144,14 +144,16 @@ func getHeadscaleApp() (*headscale.Headscale, error) { return nil, err } - maxMachineExpiry, _ := time.ParseDuration("8h") - if viper.GetDuration("max_machine_expiry") >= time.Second { - maxMachineExpiry = viper.GetDuration("max_machine_expiry") + // maxMachineRegistrationDuration is the maximum time a client can request for a client registration + maxMachineRegistrationDuration, _ := time.ParseDuration("10h") + if viper.GetDuration("max_machine_registration_duration") >= time.Second { + maxMachineRegistrationDuration = viper.GetDuration("max_machine_registration_duration") } - defaultMachineExpiry, _ := time.ParseDuration("8h") - if viper.GetDuration("default_machine_expiry") >= time.Second { - defaultMachineExpiry = viper.GetDuration("default_machine_expiry") + // defaultMachineRegistrationDuration is the default time assigned to a client registration if one is not specified by the client + defaultMachineRegistrationDuration, _ := time.ParseDuration("8h") + if viper.GetDuration("default_machine_registration_duration") >= time.Second { + defaultMachineRegistrationDuration = viper.GetDuration("default_machine_registration_duration") } cfg := headscale.Config{ @@ -188,8 +190,8 @@ func getHeadscaleApp() (*headscale.Headscale, error) { OIDCClientID: viper.GetString("oidc_client_id"), OIDCClientSecret: viper.GetString("oidc_client_secret"), - MaxMachineExpiry: maxMachineExpiry, - DefaultMachineExpiry: defaultMachineExpiry, + MaxMachineRegistrationDuration: maxMachineRegistrationDuration, // the maximum duration a client may request for expiry time + DefaultMachineRegistrationDuration: defaultMachineRegistrationDuration, // if a client does not request a specific expiry time, use this duration } h, err := headscale.NewHeadscale(cfg) diff --git a/go.mod b/go.mod index 7e137e19..5a116bb4 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,7 @@ require ( github.com/docker/cli v20.10.8+incompatible // indirect github.com/docker/docker v20.10.8+incompatible // indirect github.com/efekarakus/termcolor v1.0.1 - github.com/fatih/set v0.2.1 // indirect + github.com/fatih/set v0.2.1 github.com/gin-gonic/gin v1.7.4 github.com/gofrs/uuid v4.0.0+incompatible github.com/google/go-github v17.0.0+incompatible // indirect @@ -23,7 +23,7 @@ require ( github.com/opencontainers/runc v1.0.2 // indirect github.com/ory/dockertest/v3 v3.7.0 github.com/patrickmn/go-cache v2.1.0+incompatible - github.com/prometheus/client_golang v1.11.0 // indirect + github.com/prometheus/client_golang v1.11.0 github.com/pterm/pterm v0.12.30 github.com/rs/zerolog v1.25.0 github.com/s12v/go-jwks v0.2.1 @@ -33,7 +33,7 @@ require ( github.com/tailscale/hujson v0.0.0-20210818175511-7360507a6e88 github.com/tcnksm/go-latest v0.0.0-20170313132115-e3007ae9052e github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect - github.com/zsais/go-gin-prometheus v0.1.0 // indirect + github.com/zsais/go-gin-prometheus v0.1.0 golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 golang.org/x/net v0.0.0-20210913180222-943fd674d43e // indirect golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602 diff --git a/machine.go b/machine.go index bd5caf0d..6eecbc6f 100644 --- a/machine.go +++ b/machine.go @@ -36,6 +36,7 @@ type Machine struct { LastSeen *time.Time LastSuccessfulUpdate *time.Time Expiry *time.Time + RequestedExpiry *time.Time // when a client connects, it may request a specific expiry time, use this field to store it HostInfo datatypes.JSON Endpoints datatypes.JSON @@ -59,8 +60,33 @@ func (m Machine) isAlreadyRegistered() bool { // isExpired returns whether the machine registration has expired func (m Machine) isExpired() bool { return time.Now().UTC().After(*m.Expiry) -} - +} + +// If the Machine is expired, updateMachineExpiry updates the Machine Expiry time to the maximum allowed duration, +// or the default duration if no Expiry time was requested by the client +func (h *Headscale) updateMachineExpiry(m *Machine) { + + if m.isExpired() { + now := time.Now().UTC() + maxExpiry := now.Add(h.cfg.MaxMachineRegistrationDuration) // calculate the maximum expiry + defaultExpiry := now.Add(h.cfg.DefaultMachineRegistrationDuration) // calculate the default expiry + + // clamp the expiry time of the machine registration to the maximum allowed, or use the default if none supplied + if maxExpiry.Before(*m.RequestedExpiry) { + log.Debug().Msgf("Clamping registration expiry time to maximum: %v (%v)", maxExpiry, h.cfg.MaxMachineRegistrationDuration) + m.Expiry = &maxExpiry + } else if m.RequestedExpiry.IsZero() { + log.Debug().Msgf("Using default machine registration expiry time: %v (%v)", defaultExpiry, h.cfg.DefaultMachineRegistrationDuration) + m.Expiry = &defaultExpiry + } else { + log.Debug().Msgf("Using requested machine registration expiry time: %v", m.RequestedExpiry) + m.Expiry = m.RequestedExpiry + } + + h.db.Save(&m) + } +} + func (h *Headscale) getDirectPeers(m *Machine) (Machines, error) { log.Trace(). Str("func", "getDirectPeers"). diff --git a/oidc.go b/oidc.go index 1220098c..01c54b44 100644 --- a/oidc.go +++ b/oidc.go @@ -4,14 +4,12 @@ import ( "context" "crypto/rand" "encoding/hex" - "errors" "fmt" "github.com/coreos/go-oidc/v3/oidc" "github.com/gin-gonic/gin" "github.com/patrickmn/go-cache" "github.com/rs/zerolog/log" "golang.org/x/oauth2" - "gorm.io/gorm" "net/http" "strings" "time" @@ -103,6 +101,8 @@ func (h *Headscale) OIDCCallback(c *gin.Context) { return } + log.Debug().Msgf("AccessToken: %v", oauth2Token.AccessToken) + rawIDToken, rawIDTokenOK := oauth2Token.Extra("id_token").(string) if !rawIDTokenOK { c.String(http.StatusBadRequest, "Could not extract ID Token") @@ -117,16 +117,17 @@ func (h *Headscale) OIDCCallback(c *gin.Context) { return } + // TODO: we can use userinfo at some point to grab additional information about the user (groups membership, etc) //userInfo, err := oidcProvider.UserInfo(context.Background(), oauth2.StaticTokenSource(oauth2Token)) //if err != nil { - // c.String(http.StatusBadRequest, "Failed to retrieve userinfo: "+err.Error()) + // c.String(http.StatusBadRequest, fmt.Sprintf("Failed to retrieve userinfo: %s", err)) // return //} // Extract custom claims var claims IDTokenClaims if err = idToken.Claims(&claims); err != nil { - c.String(http.StatusBadRequest, "Failed to decode id token claims: "+err.Error()) + c.String(http.StatusBadRequest, fmt.Sprintf("Failed to decode id token claims: %s", err)) return } @@ -134,39 +135,44 @@ func (h *Headscale) OIDCCallback(c *gin.Context) { mKeyIf, mKeyFound := h.oidcStateCache.Get(state) if !mKeyFound { + log.Error().Msg("requested machine state key expired before authorisation completed") c.String(http.StatusBadRequest, "state has expired") return } mKeyStr, mKeyOK := mKeyIf.(string) if !mKeyOK { + log.Error().Msg("could not get machine key from cache") c.String(http.StatusInternalServerError, "could not get machine key from cache") return } // retrieve machine information - var m Machine - if result := h.db.Preload("Namespace").First(&m, "machine_key = ?", mKeyStr); errors.Is(result.Error, gorm.ErrRecordNotFound) { + m, err := h.GetMachineByMachineKey(mKeyStr) + + if err != nil { log.Error().Msg("machine key not found in database") c.String(http.StatusInternalServerError, "could not get machine info from database") return } - //look for a namespace of the users email for now + now := time.Now().UTC() + + // register the machine if it's new if !m.Registered { + nsName := strings.ReplaceAll(claims.Email, "@", "-") // TODO: Implement a better email sanitisation log.Debug().Msg("Registering new machine after successful callback") - ns, err := h.GetNamespace(claims.Email) + ns, err := h.GetNamespace(nsName) if err != nil { - ns, err = h.CreateNamespace(claims.Email) + ns, err = h.CreateNamespace(nsName) if err != nil { log.Error().Msgf("could not create new namespace '%s'", claims.Email) c.String(http.StatusInternalServerError, "could not create new namespace") return } - } ip, err := h.getAvailableIP() @@ -179,24 +185,11 @@ func (h *Headscale) OIDCCallback(c *gin.Context) { m.NamespaceID = ns.ID m.Registered = true m.RegisterMethod = "oidc" + m.LastSuccessfulUpdate = &now h.db.Save(&m) } - if m.isExpired() { - maxExpiry := time.Now().UTC().Add(h.cfg.MaxMachineExpiry) - - // use the maximum expiry if it's sooner than the requested expiry - if maxExpiry.Before(*m.Expiry) { - log.Debug().Msgf("Clamping expiry time to maximum: %v (%v)", maxExpiry, h.cfg.MaxMachineExpiry) - m.Expiry = &maxExpiry - h.db.Save(&m) - } else if m.Expiry.IsZero() { - log.Debug().Msgf("Using default machine expiry time: %v (%v)", maxExpiry, h.cfg.MaxMachineExpiry) - defaultExpiry := time.Now().UTC().Add(h.cfg.DefaultMachineExpiry) - m.Expiry = &defaultExpiry - h.db.Save(&m) - } - } + h.updateMachineExpiry(m) c.Data(http.StatusOK, "text/html; charset=utf-8", []byte(fmt.Sprintf(` From 8843188b8448cbcac4d603ff903a85144ab829a1 Mon Sep 17 00:00:00 2001 From: Raal Goff Date: Sun, 10 Oct 2021 22:52:30 +0800 Subject: [PATCH 007/300] add notes to README.md about OIDC --- README.md | 55 +++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 39 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 5f691a6c..9d2ec159 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,7 @@ Headscale implements this coordination server. - [x] Support for alternative IP ranges in the tailnets (default Tailscale's 100.64.0.0/10) - [x] DNS (passing DNS servers to nodes) - [x] Share nodes between ~~users~~ namespaces +- [x] SSO (via OIDC) - [ ] MagicDNS / Smart DNS ## Client OS support @@ -100,7 +101,21 @@ Suggestions/PRs welcomed! docker exec headscale create myfirstnamespace ``` -5. Run the server +5. (Optional) Configure an OIDC Issuer + + You can optionally configure an OIDC endpoint to which your users will be redirected to authenticate with headscale. In config.json set the following parameters: + + ```json + { + "oidc_issuer": "https://your-oidc.issuer.com/path", + "oidc_client_id": "your-oidc-client-id", + "oidc_client_secret": "your-oidc-client-secret" + } + ``` + + If `oidc_issuer` is set, headscale will attempt to send your users to the OIDC server for authentication, otherwise it will give instructions on how to authorise clients via the CLI. + +6. Run the server ```shell headscale serve @@ -114,7 +129,7 @@ Suggestions/PRs welcomed! docker run -v $(pwd)/private.key:/private.key -v $(pwd)/config.json:/config.json -v $(pwd)/derp.yaml:/derp.yaml -v $(pwd)/db.sqlite:/db.sqlite -p 127.0.0.1:8080:8080 headscale/headscale:x.x.x headscale serve ``` -6. If you used tailscale.com before in your nodes, make sure you clear the tailscald data folder +7. If you used tailscale.com before in your nodes, make sure you clear the tailscald data folder ```shell systemctl stop tailscaled @@ -122,26 +137,26 @@ Suggestions/PRs welcomed! systemctl start tailscaled ``` -7. Add your first machine +8. Add your first machine ```shell tailscale up --login-server YOUR_HEADSCALE_URL ``` -8. Navigate to the URL you will get with `tailscale up`, where you'll find your machine key. +9. Navigate to the URL you will get with `tailscale up`, where you'll find your machine key. If OIDC is configured, once you login your user will be added to a namespace automatically, and you can skip step 10. -9. In the server, register your machine to a namespace with the CLI - ```shell - headscale -n myfirstnamespace nodes register YOURMACHINEKEY - ``` - or docker: - ```shell - docker run -v $(pwd)/private.key:/private.key -v $(pwd)/config.json:/config.json -v $(pwd)/derp.yaml:/derp.yaml headscale/headscale:x.x.x headscale -n myfirstnamespace nodes register YOURMACHINEKEY - ``` - or if your server is already running in docker: - ```shell - docker exec headscale -n myfirstnamespace nodes register YOURMACHINEKEY - ``` +10. In the server, register your machine to a namespace with the CLI + ```shell + headscale -n myfirstnamespace nodes register YOURMACHINEKEY + ``` + or docker: + ```shell + docker run -v $(pwd)/private.key:/private.key -v $(pwd)/config.json:/config.json -v $(pwd)/derp.yaml:/derp.yaml headscale/headscale:x.x.x headscale -n myfirstnamespace nodes register YOURMACHINEKEY + ``` + or if your server is already running in docker: + ```shell + docker exec headscale -n myfirstnamespace nodes register YOURMACHINEKEY + ``` Alternatively, you can use Auth Keys to register your machines: @@ -218,6 +233,14 @@ Headscale's configuration file is named `config.json` or `config.yaml`. Headscal The fields starting with `db_` are used for the PostgreSQL connection information. +OpenID Connect settings: +``` + "oidc_issuer": "https://your-oidc.issuer.com/path", + "oidc_client_id": "your-oidc-client-id", + "oidc_client_secret": "your-oidc-client-secret" +``` + + ### Running the service via TLS (optional) ``` From 0603e29c46143b4de0d74a375d13cd7bfec4ab3c Mon Sep 17 00:00:00 2001 From: Raal Goff Date: Fri, 15 Oct 2021 23:09:55 +0800 Subject: [PATCH 008/300] add login details to RegisterResponse so GUI clients show login display name --- api.go | 2 ++ namespaces.go | 11 +++++++++++ 2 files changed, 13 insertions(+) diff --git a/api.go b/api.go index bda9d9bd..d85221bc 100644 --- a/api.go +++ b/api.go @@ -147,6 +147,8 @@ func (h *Headscale) RegistrationHandler(c *gin.Context) { resp.AuthURL = "" resp.MachineAuthorized = true resp.User = *m.Namespace.toUser() + resp.Login = *m.Namespace.toLogin() + respBody, err := encode(resp, &mKey, h.privateKey) if err != nil { log.Error(). diff --git a/namespaces.go b/namespaces.go index 2bf62bb3..212df9a6 100644 --- a/namespaces.go +++ b/namespaces.go @@ -216,3 +216,14 @@ func (n *Namespace) toUser() *tailcfg.User { } return &u } + +func (n *Namespace) toLogin() *tailcfg.Login { + l := tailcfg.Login{ + ID: tailcfg.LoginID(n.ID), + LoginName: n.Name, + DisplayName: n.Name, + ProfilePicURL: "", + Domain: "headscale.net", + } + return &l +} From d0cd5af419d2fee7b1ae6a7b8510b27eb25d4c8d Mon Sep 17 00:00:00 2001 From: Raal Goff Date: Sat, 16 Oct 2021 22:34:11 +0800 Subject: [PATCH 009/300] fix incorrect merge --- cmd/headscale/cli/utils.go | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/cmd/headscale/cli/utils.go b/cmd/headscale/cli/utils.go index ba8d34ad..f29c389d 100644 --- a/cmd/headscale/cli/utils.go +++ b/cmd/headscale/cli/utils.go @@ -161,8 +161,7 @@ func getHeadscaleApp() (*headscale.Headscale, error) { return nil, err } - - // maxMachineRegistrationDuration is the maximum time a client can request for a client registration + // maxMachineRegistrationDuration is the maximum time a client can request for a client registration maxMachineRegistrationDuration, _ := time.ParseDuration("10h") if viper.GetDuration("max_machine_registration_duration") >= time.Second { maxMachineRegistrationDuration = viper.GetDuration("max_machine_registration_duration") @@ -174,7 +173,7 @@ func getHeadscaleApp() (*headscale.Headscale, error) { defaultMachineRegistrationDuration = viper.GetDuration("default_machine_registration_duration") } - dnsConfig, baseDomain := GetDNSConfig() + dnsConfig, baseDomain := GetDNSConfig() cfg := headscale.Config{ ServerURL: viper.GetString("server_url"), @@ -207,8 +206,6 @@ func getHeadscaleApp() (*headscale.Headscale, error) { ACMEEmail: viper.GetString("acme_email"), ACMEURL: viper.GetString("acme_url"), - DNSConfig: GetDNSConfig(), - OIDCIssuer: viper.GetString("oidc_issuer"), OIDCClientID: viper.GetString("oidc_client_id"), OIDCClientSecret: viper.GetString("oidc_client_secret"), From a347d276bd650223109d9f12cc9829e99651b6b9 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Mon, 18 Oct 2021 19:26:43 +0000 Subject: [PATCH 010/300] Fix broken machine test --- cli_test.go | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/cli_test.go b/cli_test.go index 528a115e..291b5df1 100644 --- a/cli_test.go +++ b/cli_test.go @@ -1,6 +1,8 @@ package headscale import ( + "time" + "gopkg.in/check.v1" ) @@ -8,14 +10,18 @@ func (s *Suite) TestRegisterMachine(c *check.C) { n, err := h.CreateNamespace("test") c.Assert(err, check.IsNil) + now := time.Now().UTC() + m := Machine{ - ID: 0, - MachineKey: "8ce002a935f8c394e55e78fbbb410576575ff8ec5cfa2e627e4b807f1be15b0e", - NodeKey: "bar", - DiscoKey: "faa", - Name: "testmachine", - NamespaceID: n.ID, - IPAddress: "10.0.0.1", + ID: 0, + MachineKey: "8ce002a935f8c394e55e78fbbb410576575ff8ec5cfa2e627e4b807f1be15b0e", + NodeKey: "bar", + DiscoKey: "faa", + Name: "testmachine", + NamespaceID: n.ID, + IPAddress: "10.0.0.1", + Expiry: &now, + RequestedExpiry: &now, } h.db.Save(&m) From 677bd9b657d0ca229cb5e97875e58b6f43571bed Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Mon, 18 Oct 2021 19:27:52 +0000 Subject: [PATCH 011/300] Implement namespace matching --- api.go | 6 +- app.go | 26 +++--- cmd/headscale/cli/utils.go | 24 ++++- oidc.go | 93 ++++++++++++-------- oidc_test.go | 173 +++++++++++++++++++++++++++++++++++++ 5 files changed, 267 insertions(+), 55 deletions(-) create mode 100644 oidc_test.go diff --git a/api.go b/api.go index cbe48072..c542b3aa 100644 --- a/api.go +++ b/api.go @@ -170,7 +170,7 @@ func (h *Headscale) RegistrationHandler(c *gin.Context) { Str("machine", m.Name). Msg("Machine registration has expired. Sending a authurl to register") - if h.cfg.OIDCIssuer != "" { + if h.cfg.OIDC.Issuer != "" { resp.AuthURL = fmt.Sprintf("%s/oidc/register/%s", strings.TrimSuffix(h.cfg.ServerURL, "/"), mKey.HexString()) } else { @@ -225,7 +225,7 @@ func (h *Headscale) RegistrationHandler(c *gin.Context) { Str("handler", "Registration"). Str("machine", m.Name). Msg("The node is sending us a new NodeKey, sending auth url") - if h.cfg.OIDCIssuer != "" { + if h.cfg.OIDC.Issuer != "" { resp.AuthURL = fmt.Sprintf("%s/oidc/register/%s", strings.TrimSuffix(h.cfg.ServerURL, "/"), mKey.HexString()) } else { resp.AuthURL = fmt.Sprintf("%s/register?key=%s", @@ -424,7 +424,7 @@ func (h *Headscale) handleAuthKey(c *gin.Context, db *gorm.DB, idKey wgkey.Key, db.Save(&m) h.updateMachineExpiry(&m) // TODO: do we want to do different expiry times for AuthKeys? - + pak.Used = true db.Save(&pak) diff --git a/app.go b/app.go index 89c43589..c89856f8 100644 --- a/app.go +++ b/app.go @@ -3,9 +3,6 @@ package headscale import ( "errors" "fmt" - "github.com/coreos/go-oidc/v3/oidc" - "github.com/patrickmn/go-cache" - "golang.org/x/oauth2" "net/http" "os" "sort" @@ -13,6 +10,10 @@ import ( "sync" "time" + "github.com/coreos/go-oidc/v3/oidc" + "github.com/patrickmn/go-cache" + "golang.org/x/oauth2" + "github.com/rs/zerolog/log" "github.com/gin-gonic/gin" @@ -57,14 +58,19 @@ type Config struct { DNSConfig *tailcfg.DNSConfig - OIDCIssuer string - OIDCClientID string - OIDCClientSecret string + OIDC OIDCConfig MaxMachineRegistrationDuration time.Duration DefaultMachineRegistrationDuration time.Duration } +type OIDCConfig struct { + Issuer string + ClientID string + ClientSecret string + MatchMap map[string]string +} + // Headscale represents the base app of the service type Headscale struct { cfg Config @@ -122,14 +128,14 @@ func NewHeadscale(cfg Config) (*Headscale, error) { return nil, err } - if cfg.OIDCIssuer != "" { + if cfg.OIDC.Issuer != "" { err = h.initOIDC() if err != nil { return nil, err } - } + } - if h.cfg.DNSConfig != nil && h.cfg.DNSConfig.Proxied { // if MagicDNS + if h.cfg.DNSConfig != nil && h.cfg.DNSConfig.Proxied { // if MagicDNS magicDNSDomains, err := generateMagicDNSRootDomains(h.cfg.IPPrefix, h.cfg.BaseDomain) if err != nil { return nil, err @@ -294,7 +300,6 @@ func (h *Headscale) getLastStateChange(namespaces ...string) time.Time { times = append(times, lastChange) } - } sort.Slice(times, func(i, j int) bool { @@ -305,7 +310,6 @@ func (h *Headscale) getLastStateChange(namespaces ...string) time.Time { if len(times) == 0 { return time.Now().UTC() - } else { return times[0] } diff --git a/cmd/headscale/cli/utils.go b/cmd/headscale/cli/utils.go index f29c389d..4a598e77 100644 --- a/cmd/headscale/cli/utils.go +++ b/cmd/headscale/cli/utils.go @@ -7,6 +7,7 @@ import ( "io" "os" "path/filepath" + "regexp" "strings" "time" @@ -73,7 +74,6 @@ func LoadConfig(path string) error { } else { return nil } - } func GetDNSConfig() (*tailcfg.DNSConfig, string) { @@ -206,15 +206,19 @@ func getHeadscaleApp() (*headscale.Headscale, error) { ACMEEmail: viper.GetString("acme_email"), ACMEURL: viper.GetString("acme_url"), - OIDCIssuer: viper.GetString("oidc_issuer"), - OIDCClientID: viper.GetString("oidc_client_id"), - OIDCClientSecret: viper.GetString("oidc_client_secret"), + OIDC: headscale.OIDCConfig{ + Issuer: viper.GetString("oidc.issuer"), + ClientID: viper.GetString("oidc.client_id"), + ClientSecret: viper.GetString("oidc.client_secret"), + }, MaxMachineRegistrationDuration: maxMachineRegistrationDuration, // the maximum duration a client may request for expiry time DefaultMachineRegistrationDuration: defaultMachineRegistrationDuration, // if a client does not request a specific expiry time, use this duration } + cfg.OIDC.MatchMap = loadOIDCMatchMap() + h, err := headscale.NewHeadscale(cfg) if err != nil { return nil, err @@ -291,3 +295,15 @@ func HasJsonOutputFlag() bool { } return false } + +// loadOIDCMatchMap is a wrapper around viper to verifies that the keys in +// the match map is valid regex strings. +func loadOIDCMatchMap() map[string]string { + strMap := viper.GetStringMapString("oidc.domain_map") + + for oidcMatcher := range strMap { + _ = regexp.MustCompile(oidcMatcher) + } + + return strMap +} diff --git a/oidc.go b/oidc.go index 01c54b44..1b13963c 100644 --- a/oidc.go +++ b/oidc.go @@ -5,14 +5,16 @@ import ( "crypto/rand" "encoding/hex" "fmt" + "net/http" + "regexp" + "strings" + "time" + "github.com/coreos/go-oidc/v3/oidc" "github.com/gin-gonic/gin" "github.com/patrickmn/go-cache" "github.com/rs/zerolog/log" "golang.org/x/oauth2" - "net/http" - "strings" - "time" ) type IDTokenClaims struct { @@ -26,7 +28,7 @@ func (h *Headscale) initOIDC() error { var err error // grab oidc config if it hasn't been already if h.oauth2Config == nil { - h.oidcProvider, err = oidc.NewProvider(context.Background(), h.cfg.OIDCIssuer) + h.oidcProvider, err = oidc.NewProvider(context.Background(), h.cfg.OIDC.Issuer) if err != nil { log.Error().Msgf("Could not retrieve OIDC Config: %s", err.Error()) @@ -34,8 +36,8 @@ func (h *Headscale) initOIDC() error { } h.oauth2Config = &oauth2.Config{ - ClientID: h.cfg.OIDCClientID, - ClientSecret: h.cfg.OIDCClientSecret, + ClientID: h.cfg.OIDC.ClientID, + ClientSecret: h.cfg.OIDC.ClientSecret, Endpoint: h.oidcProvider.Endpoint(), RedirectURL: fmt.Sprintf("%s/oidc/callback", strings.TrimSuffix(h.cfg.ServerURL, "/")), Scopes: []string{oidc.ScopeOpenID, "profile", "email"}, @@ -62,7 +64,6 @@ func (h *Headscale) RegisterOIDC(c *gin.Context) { b := make([]byte, 16) _, err := rand.Read(b) - if err != nil { log.Error().Msg("could not read 16 bytes from rand") c.String(http.StatusInternalServerError, "could not read 16 bytes from rand") @@ -86,7 +87,6 @@ func (h *Headscale) RegisterOIDC(c *gin.Context) { // TODO: Add groups information from OIDC tokens into machine HostInfo // Listens in /oidc/callback func (h *Headscale) OIDCCallback(c *gin.Context) { - code := c.Query("code") state := c.Query("state") @@ -109,7 +109,7 @@ func (h *Headscale) OIDCCallback(c *gin.Context) { return } - verifier := h.oidcProvider.Verifier(&oidc.Config{ClientID: h.cfg.OIDCClientID}) + verifier := h.oidcProvider.Verifier(&oidc.Config{ClientID: h.cfg.OIDC.ClientID}) idToken, err := verifier.Verify(context.Background(), rawIDToken) if err != nil { @@ -131,7 +131,7 @@ func (h *Headscale) OIDCCallback(c *gin.Context) { return } - //retrieve machinekey from state cache + // retrieve machinekey from state cache mKeyIf, mKeyFound := h.oidcStateCache.Get(state) if !mKeyFound { @@ -149,7 +149,6 @@ func (h *Headscale) OIDCCallback(c *gin.Context) { // retrieve machine information m, err := h.GetMachineByMachineKey(mKeyStr) - if err != nil { log.Error().Msg("machine key not found in database") c.String(http.StatusInternalServerError, "could not get machine info from database") @@ -158,40 +157,40 @@ func (h *Headscale) OIDCCallback(c *gin.Context) { now := time.Now().UTC() - // register the machine if it's new - if !m.Registered { - nsName := strings.ReplaceAll(claims.Email, "@", "-") // TODO: Implement a better email sanitisation + if nsName, ok := h.getNamespaceFromEmail(claims.Email); ok { + // register the machine if it's new + if !m.Registered { - log.Debug().Msg("Registering new machine after successful callback") - - ns, err := h.GetNamespace(nsName) - if err != nil { - ns, err = h.CreateNamespace(nsName) + log.Debug().Msg("Registering new machine after successful callback") + ns, err := h.GetNamespace(nsName) if err != nil { - log.Error().Msgf("could not create new namespace '%s'", claims.Email) - c.String(http.StatusInternalServerError, "could not create new namespace") + ns, err = h.CreateNamespace(nsName) + + if err != nil { + log.Error().Msgf("could not create new namespace '%s'", claims.Email) + c.String(http.StatusInternalServerError, "could not create new namespace") + return + } + } + + ip, err := h.getAvailableIP() + if err != nil { + c.String(http.StatusInternalServerError, "could not get an IP from the pool") return } + + m.IPAddress = ip.String() + m.NamespaceID = ns.ID + m.Registered = true + m.RegisterMethod = "oidc" + m.LastSuccessfulUpdate = &now + h.db.Save(&m) } - ip, err := h.getAvailableIP() - if err != nil { - c.String(http.StatusInternalServerError, "could not get an IP from the pool") - return - } + h.updateMachineExpiry(m) - m.IPAddress = ip.String() - m.NamespaceID = ns.ID - m.Registered = true - m.RegisterMethod = "oidc" - m.LastSuccessfulUpdate = &now - h.db.Save(&m) - } - - h.updateMachineExpiry(m) - - c.Data(http.StatusOK, "text/html; charset=utf-8", []byte(fmt.Sprintf(` + c.Data(http.StatusOK, "text/html; charset=utf-8", []byte(fmt.Sprintf(`

headscale

@@ -202,4 +201,24 @@ func (h *Headscale) OIDCCallback(c *gin.Context) { `, claims.Email))) + + } + + log.Error(). + Str("email", claims.Email). + Str("username", claims.Username). + Str("machine", m.Name). + Msg("Email could not be mapped to a namespace") + c.String(http.StatusBadRequest, "email from claim could not be mapped to a namespace") +} + +func (h *Headscale) getNamespaceFromEmail(email string) (string, bool) { + for match, namespace := range h.cfg.OIDC.MatchMap { + regex := regexp.MustCompile(match) + if regex.MatchString(email) { + return namespace, true + } + } + + return "", false } diff --git a/oidc_test.go b/oidc_test.go new file mode 100644 index 00000000..ddb44e4c --- /dev/null +++ b/oidc_test.go @@ -0,0 +1,173 @@ +package headscale + +import ( + "sync" + "testing" + + "github.com/coreos/go-oidc/v3/oidc" + "github.com/patrickmn/go-cache" + "golang.org/x/oauth2" + "gorm.io/gorm" + "tailscale.com/tailcfg" + "tailscale.com/types/wgkey" +) + +func TestHeadscale_getNamespaceFromEmail(t *testing.T) { + type fields struct { + cfg Config + db *gorm.DB + dbString string + dbType string + dbDebug bool + publicKey *wgkey.Key + privateKey *wgkey.Private + aclPolicy *ACLPolicy + aclRules *[]tailcfg.FilterRule + lastStateChange sync.Map + oidcProvider *oidc.Provider + oauth2Config *oauth2.Config + oidcStateCache *cache.Cache + } + type args struct { + email string + } + tests := []struct { + name string + fields fields + args args + want string + want1 bool + }{ + { + name: "match all", + fields: fields{ + cfg: Config{ + OIDC: OIDCConfig{ + MatchMap: map[string]string{ + ".*": "space", + }, + }, + }, + }, + args: args{ + email: "test@example.no", + }, + want: "space", + want1: true, + }, + { + name: "match user", + fields: fields{ + cfg: Config{ + OIDC: OIDCConfig{ + MatchMap: map[string]string{ + "specific@user\\.no": "user-namespace", + }, + }, + }, + }, + args: args{ + email: "specific@user.no", + }, + want: "user-namespace", + want1: true, + }, + { + name: "match domain", + fields: fields{ + cfg: Config{ + OIDC: OIDCConfig{ + MatchMap: map[string]string{ + ".*@example\\.no": "example", + }, + }, + }, + }, + args: args{ + email: "test@example.no", + }, + want: "example", + want1: true, + }, + { + name: "multi match domain", + fields: fields{ + cfg: Config{ + OIDC: OIDCConfig{ + MatchMap: map[string]string{ + ".*@example\\.no": "exammple", + ".*@gmail\\.com": "gmail", + }, + }, + }, + }, + args: args{ + email: "someuser@gmail.com", + }, + want: "gmail", + want1: true, + }, + { + name: "no match domain", + fields: fields{ + cfg: Config{ + OIDC: OIDCConfig{ + MatchMap: map[string]string{ + ".*@dontknow.no": "never", + }, + }, + }, + }, + args: args{ + email: "test@wedontknow.no", + }, + want: "", + want1: false, + }, + { + name: "multi no match domain", + fields: fields{ + cfg: Config{ + OIDC: OIDCConfig{ + MatchMap: map[string]string{ + ".*@dontknow.no": "never", + ".*@wedontknow.no": "other", + ".*\\.no": "stuffy", + }, + }, + }, + }, + args: args{ + email: "tasy@nonofthem.com", + }, + want: "", + want1: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + h := &Headscale{ + cfg: tt.fields.cfg, + db: tt.fields.db, + dbString: tt.fields.dbString, + dbType: tt.fields.dbType, + dbDebug: tt.fields.dbDebug, + publicKey: tt.fields.publicKey, + privateKey: tt.fields.privateKey, + aclPolicy: tt.fields.aclPolicy, + aclRules: tt.fields.aclRules, + lastStateChange: tt.fields.lastStateChange, + oidcProvider: tt.fields.oidcProvider, + oauth2Config: tt.fields.oauth2Config, + oidcStateCache: tt.fields.oidcStateCache, + } + got, got1 := h.getNamespaceFromEmail(tt.args.email) + if got != tt.want { + t.Errorf("Headscale.getNamespaceFromEmail() got = %v, want %v", got, tt.want) + } + if got1 != tt.want1 { + t.Errorf("Headscale.getNamespaceFromEmail() got1 = %v, want %v", got1, tt.want1) + } + }) + } +} From dbe193ad1783ccc323f4227d1fd849e3290f9454 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Tue, 19 Oct 2021 18:25:59 +0100 Subject: [PATCH 012/300] Fix up leftovers from kradalby PR --- README.md | 24 ++++++++++++++---------- oidc.go | 4 ++++ 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 0cb41bcb..16b6c67f 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ Headscale implements this coordination server. - [x] Support for alternative IP ranges in the tailnets (default Tailscale's 100.64.0.0/10) - [x] DNS (passing DNS servers to nodes) - [x] Share nodes between ~~users~~ namespaces -- [x] SSO (via OIDC) +- [x] Single-Sign-On (via Open ID Connect) - [x] MagicDNS (see `docs/`) ## Client OS support @@ -109,13 +109,14 @@ Suggestions/PRs welcomed! ```json { - "oidc_issuer": "https://your-oidc.issuer.com/path", - "oidc_client_id": "your-oidc-client-id", - "oidc_client_secret": "your-oidc-client-secret" + "oidc": { + "issuer": "https://your-oidc.issuer.com/path", + "client_id": "your-oidc-client-id", + "client_secret": "your-oidc-client-secret", + "domain_map": { + ".*": "default-namespace" + } } - ``` - - If `oidc_issuer` is set, headscale will attempt to send your users to the OIDC server for authentication, otherwise it will give instructions on how to authorise clients via the CLI. 6. Run the server @@ -237,9 +238,12 @@ The fields starting with `db_` are used for the PostgreSQL connection informatio OpenID Connect settings: ``` - "oidc_issuer": "https://your-oidc.issuer.com/path", - "oidc_client_id": "your-oidc-client-id", - "oidc_client_secret": "your-oidc-client-secret" + oidc: + issuer: "https://your-oidc.issuer.com/path" + client_id: "your-oidc-client-id" + client_secret: "your-oidc-client-secret" + domain_map: + ".*": default-namespace ``` diff --git a/oidc.go b/oidc.go index 1b13963c..51c443db 100644 --- a/oidc.go +++ b/oidc.go @@ -212,6 +212,10 @@ func (h *Headscale) OIDCCallback(c *gin.Context) { c.String(http.StatusBadRequest, "email from claim could not be mapped to a namespace") } +// getNamespaceFromEmail passes the users email through a list of "matchers" +// and iterates through them until it matches and returns a namespace. +// If no match is found, an empty string will be returned. +// TODO(kradalby): golang Maps key order is not stable, so this list is _not_ deterministic. Find a way to make the list of keys stable, preferably in the order presented in a users configuration. func (h *Headscale) getNamespaceFromEmail(email string) (string, bool) { for match, namespace := range h.cfg.OIDC.MatchMap { regex := regexp.MustCompile(match) From c22b93734e3639b27fc301f4654683042d682934 Mon Sep 17 00:00:00 2001 From: Remus CURSARU Date: Sun, 24 Oct 2021 14:09:07 +0200 Subject: [PATCH 013/300] update Running.md clarify setup steps; use a single directory to hold all configuration for docker container --- docs/Running.md | 73 ++++++++++++++++++++++++------------------------- 1 file changed, 36 insertions(+), 37 deletions(-) diff --git a/docs/Running.md b/docs/Running.md index 08373653..2193c107 100644 --- a/docs/Running.md +++ b/docs/Running.md @@ -1,5 +1,6 @@ # Running headscale +## Server configuration 1. Download the headscale binary https://github.com/juanfont/headscale/releases, and place it somewhere in your $PATH or use the docker container ```shell @@ -12,8 +13,15 @@ docker pull ghrc.io/juanfont/headscale:x.x.x ``` --> -2. (Optional, you can also use SQLite) Get yourself a PostgreSQL DB running +2. When running headscale in a docker container, prepare a directory to hold all configuration + ```shell + mkdir config + ``` + +3. Get yourself a DB + + a) Get a Postgres DB running in docker ```shell docker run --name headscale \ -e POSTGRES_DB=headscale @@ -22,16 +30,22 @@ -p 5432:5432 \ -d postgres ``` - -3. Create a WireGuard private key and headscale configuration - + or b) Prepare a SQLite DB file ```shell - wg genkey > private.key - - cp config.yaml.example config.yaml + touch config/db.sqlite ``` -4. Create a namespace +4. Create a WireGuard private key, headscale configuration, and a DERP map file. Refer to [tailscale sample](https://raw.githubusercontent.com/tailscale/tailscale/main/net/dnsfallback/dns-fallback-servers.json) for more guidance. + + ```shell + wg genkey > config/private.key + + cp config.yaml.[sqlite|postgres].example config/config.yaml + + cp derp-example.yaml config/derp.yaml + ``` + +5. Create a namespace ```shell headscale namespaces create myfirstnamespace @@ -39,15 +53,9 @@ or docker: - the db.sqlite mount is only needed if you use sqlite - ```shell - touch db.sqlite docker run \ - -v $(pwd)/private.key:/private.key \ - -v $(pwd)/config.json:/config.json \ - -v $(pwd)/derp.yaml:/derp.yaml \ - -v $(pwd)/db.sqlite:/db.sqlite \ + -v $(pwd)/config:/etc/headscale/ \ -p 127.0.0.1:8080:8080 \ headscale/headscale:x.x.x \ headscale namespaces create myfirstnamespace @@ -56,10 +64,10 @@ or if your server is already running in docker: ```shell - docker exec headscale create myfirstnamespace + docker exec headscale namespaces create myfirstnamespace ``` -5. Run the server +6. Run the server ```shell headscale serve @@ -67,44 +75,38 @@ or docker: - the db.sqlite mount is only needed if you use sqlite - ```shell docker run \ - -v $(pwd)/private.key:/private.key \ - -v $(pwd)/config.json:/config.json \ - -v $(pwd)/derp.yaml:/derp.yaml \ - -v $(pwd)/db.sqlite:/db.sqlite \ + -v $(pwd)/config:/etc/headscale/ \ -p 127.0.0.1:8080:8080 \ headscale/headscale:x.x.x headscale serve ``` +## Nodes configuration -6. If you used tailscale.com before in your nodes, make sure you clear the tailscaled data folder +If you used tailscale.com before in your nodes, make sure you clear the tailscaled data folder ```shell systemctl stop tailscaled rm -fr /var/lib/tailscale systemctl start tailscaled ``` - -7. Add your first machine +### Adding node based on MACHINEKEY +1. Add your first machine ```shell tailscale up --login-server YOUR_HEADSCALE_URL ``` -8. Navigate to the URL you will get with `tailscale up`, where you'll find your machine key. +2. Navigate to the URL returned by `tailscale up`, where you'll find your machine key. -9. In the server, register your machine to a namespace with the CLI +3. In the server, register your machine to a namespace with the CLI ```shell headscale -n myfirstnamespace nodes register YOURMACHINEKEY ``` or docker: ```shell docker run \ - -v $(pwd)/private.key:/private.key \ - -v $(pwd)/config.json:/config.json \ - -v $(pwd)/derp.yaml:/derp.yaml \ + -v $(pwd)/config:/etc/headscale/ \ headscale/headscale:x.x.x \ headscale -n myfirstnamespace nodes register YOURMACHINEKEY ``` @@ -113,7 +115,7 @@ docker exec headscale -n myfirstnamespace nodes register YOURMACHINEKEY ``` -Alternatively, you can use Auth Keys to register your machines: +### Alternative: adding node with AUTHKEY 1. Create an authkey @@ -125,10 +127,7 @@ Alternatively, you can use Auth Keys to register your machines: ```shell docker run \ - -v $(pwd)/private.key:/private.key \ - -v $(pwd)/config.json:/config.json \ - -v$(pwd)/derp.yaml:/derp.yaml \ - -v $(pwd)/db.sqlite:/db.sqlite \ + -v $(pwd)/config:/etc/headscale/ \ headscale/headscale:x.x.x \ headscale -n myfirstnamespace preauthkeys create --reusable --expiration 24h ``` @@ -139,7 +138,7 @@ Alternatively, you can use Auth Keys to register your machines: docker exec headscale -n myfirstnamespace preauthkeys create --reusable --expiration 24h ``` -2. Use the authkey from your machine to register it +2. Use the authkey on your node to register it ```shell tailscale up --login-server YOUR_HEADSCALE_URL --authkey YOURAUTHKEY ``` From c8e1afb14b9bf8db67b3cebdb1a90c184382ec3f Mon Sep 17 00:00:00 2001 From: Ward Vandewege Date: Sun, 24 Oct 2021 17:00:51 -0400 Subject: [PATCH 014/300] When attempting to unshare a node from the primary namespace, return errorMachineNotShared, not errorSameNamespace. Add test for same. --- sharing.go | 3 ++- sharing_test.go | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/sharing.go b/sharing.go index 879ed06f..5f6a8f45 100644 --- a/sharing.go +++ b/sharing.go @@ -43,7 +43,8 @@ func (h *Headscale) AddSharedMachineToNamespace(m *Machine, ns *Namespace) error // RemoveSharedMachineFromNamespace removes a shared machine from a namespace func (h *Headscale) RemoveSharedMachineFromNamespace(m *Machine, ns *Namespace) error { if m.NamespaceID == ns.ID { - return errorSameNamespace + // Can't unshare from primary namespace + return errorMachineNotShared } sharedMachine := SharedMachine{} diff --git a/sharing_test.go b/sharing_test.go index 140b05f2..1133fd92 100644 --- a/sharing_test.go +++ b/sharing_test.go @@ -86,6 +86,9 @@ func (s *Suite) TestUnshare(c *check.C) { err = h.RemoveSharedMachineFromNamespace(m2, n1) c.Assert(err, check.Equals, errorMachineNotShared) + + err = h.RemoveSharedMachineFromNamespace(m1, n1) + c.Assert(err, check.Equals, errorMachineNotShared) } func (s *Suite) TestAlreadyShared(c *check.C) { From dd7557850ec07e23d0c075998ffe1d84d9e3cf3b Mon Sep 17 00:00:00 2001 From: Ward Vandewege Date: Sun, 24 Oct 2021 17:02:57 -0400 Subject: [PATCH 015/300] cli changes for the `nodes` subcommand: * when listing nodes, a namespace is now optional, when it is not provided, all nodes are shown * when deleting, and sharing a node, remove the `namespace` flag, it was superfluous and unused * when unsharing a node, specify the namespace as an argument not a flag, making the UX the same as for sharing. Also refactor the share/unshare code to reuse the shared bits. --- cmd/headscale/cli/nodes.go | 149 ++++++++++++++++++------------------- 1 file changed, 72 insertions(+), 77 deletions(-) diff --git a/cmd/headscale/cli/nodes.go b/cmd/headscale/cli/nodes.go index c44aa5ed..954e338e 100644 --- a/cmd/headscale/cli/nodes.go +++ b/cmd/headscale/cli/nodes.go @@ -17,12 +17,13 @@ import ( func init() { rootCmd.AddCommand(nodeCmd) - nodeCmd.PersistentFlags().StringP("namespace", "n", "", "Namespace") - err := nodeCmd.MarkPersistentFlagRequired("namespace") + listNodesCmd.Flags().StringP("namespace", "n", "", "Namespace") + nodeCmd.AddCommand(listNodesCmd) + registerNodeCmd.Flags().StringP("namespace", "n", "", "Namespace") + err := registerNodeCmd.MarkFlagRequired("namespace") if err != nil { log.Fatalf(err.Error()) } - nodeCmd.AddCommand(listNodesCmd) nodeCmd.AddCommand(registerNodeCmd) nodeCmd.AddCommand(deleteNodeCmd) nodeCmd.AddCommand(shareMachineCmd) @@ -69,7 +70,7 @@ var registerNodeCmd = &cobra.Command{ var listNodesCmd = &cobra.Command{ Use: "list", - Short: "List the nodes in a given namespace", + Short: "List nodes", Run: func(cmd *cobra.Command, args []string) { n, err := cmd.Flags().GetString("namespace") if err != nil { @@ -82,23 +83,44 @@ var listNodesCmd = &cobra.Command{ log.Fatalf("Error initializing: %s", err) } - namespace, err := h.GetNamespace(n) - if err != nil { - log.Fatalf("Error fetching namespace: %s", err) + var namespaces []headscale.Namespace + var namespace *headscale.Namespace + var sharedMachines *[]headscale.Machine + if len(n) == 0 { + // no namespace provided, list all + tmp, err := h.ListNamespaces() + if err != nil { + log.Fatalf("Error fetching namespace: %s", err) + } + namespaces = *tmp + } else { + namespace, err = h.GetNamespace(n) + if err != nil { + log.Fatalf("Error fetching namespace: %s", err) + } + namespaces = append(namespaces, *namespace) + + sharedMachines, err = h.ListSharedMachinesInNamespace(n) + if err != nil { + log.Fatalf("Error fetching shared machines: %s", err) + } } - machines, err := h.ListMachinesInNamespace(n) - if err != nil { - log.Fatalf("Error fetching machines: %s", err) + var allMachines []headscale.Machine + for _, n := range namespaces { + machines, err := h.ListMachinesInNamespace(n.Name) + if err != nil { + log.Fatalf("Error fetching machines: %s", err) + } + allMachines = append(allMachines, *machines...) } - sharedMachines, err := h.ListSharedMachinesInNamespace(n) - if err != nil { - log.Fatalf("Error fetching shared machines: %s", err) + // listing sharedMachines is only relevant when a particular namespace is + // requested + if sharedMachines != nil { + allMachines = append(allMachines, *sharedMachines...) } - allMachines := append(*machines, *sharedMachines...) - if strings.HasPrefix(o, "json") { JsonOutput(allMachines, err, o) return @@ -108,7 +130,7 @@ var listNodesCmd = &cobra.Command{ log.Fatalf("Error getting nodes: %s", err) } - d, err := nodesToPtables(*namespace, allMachines) + d, err := nodesToPtables(namespace, allMachines) if err != nil { log.Fatalf("Error converting to table: %s", err) } @@ -176,6 +198,31 @@ var deleteNodeCmd = &cobra.Command{ }, } +func sharingWorker(cmd *cobra.Command, args []string) (*headscale.Headscale, string, *headscale.Machine, *headscale.Namespace) { + output, _ := cmd.Flags().GetString("output") + + h, err := getHeadscaleApp() + if err != nil { + log.Fatalf("Error initializing: %s", err) + } + + namespace, err := h.GetNamespace(args[1]) + if err != nil { + log.Fatalf("Error fetching namespace %s: %s", args[1], err) + } + + id, err := strconv.Atoi(args[0]) + if err != nil { + log.Fatalf("Error converting ID to integer: %s", err) + } + machine, err := h.GetMachineByID(uint64(id)) + if err != nil { + log.Fatalf("Error getting node: %s", err) + } + + return h, output, machine, namespace +} + var shareMachineCmd = &cobra.Command{ Use: "share ID namespace", Short: "Shares a node from the current namespace to the specified one", @@ -186,37 +233,8 @@ var shareMachineCmd = &cobra.Command{ return nil }, Run: func(cmd *cobra.Command, args []string) { - namespace, err := cmd.Flags().GetString("namespace") - if err != nil { - log.Fatalf("Error getting namespace: %s", err) - } - output, _ := cmd.Flags().GetString("output") - - h, err := getHeadscaleApp() - if err != nil { - log.Fatalf("Error initializing: %s", err) - } - - _, err = h.GetNamespace(namespace) - if err != nil { - log.Fatalf("Error fetching origin namespace: %s", err) - } - - destinationNamespace, err := h.GetNamespace(args[1]) - if err != nil { - log.Fatalf("Error fetching destination namespace: %s", err) - } - - id, err := strconv.Atoi(args[0]) - if err != nil { - log.Fatalf("Error converting ID to integer: %s", err) - } - machine, err := h.GetMachineByID(uint64(id)) - if err != nil { - log.Fatalf("Error getting node: %s", err) - } - - err = h.AddSharedMachineToNamespace(machine, destinationNamespace) + h, output, machine, namespace := sharingWorker(cmd, args) + err := h.AddSharedMachineToNamespace(machine, namespace) if strings.HasPrefix(output, "json") { JsonOutput(map[string]string{"Result": "Node shared"}, err, output) return @@ -231,41 +249,17 @@ var shareMachineCmd = &cobra.Command{ } var unshareMachineCmd = &cobra.Command{ - Use: "unshare ID", + Use: "unshare ID namespace", Short: "Unshares a node from the specified namespace", Args: func(cmd *cobra.Command, args []string) error { - if len(args) < 1 { + if len(args) < 2 { return fmt.Errorf("missing parameters") } return nil }, Run: func(cmd *cobra.Command, args []string) { - namespace, err := cmd.Flags().GetString("namespace") - if err != nil { - log.Fatalf("Error getting namespace: %s", err) - } - output, _ := cmd.Flags().GetString("output") - - h, err := getHeadscaleApp() - if err != nil { - log.Fatalf("Error initializing: %s", err) - } - - n, err := h.GetNamespace(namespace) - if err != nil { - log.Fatalf("Error fetching namespace: %s", err) - } - - id, err := strconv.Atoi(args[0]) - if err != nil { - log.Fatalf("Error converting ID to integer: %s", err) - } - machine, err := h.GetMachineByID(uint64(id)) - if err != nil { - log.Fatalf("Error getting node: %s", err) - } - - err = h.RemoveSharedMachineFromNamespace(machine, n) + h, output, machine, namespace := sharingWorker(cmd, args) + err := h.RemoveSharedMachineFromNamespace(machine, namespace) if strings.HasPrefix(output, "json") { JsonOutput(map[string]string{"Result": "Node unshared"}, err, output) return @@ -279,7 +273,7 @@ var unshareMachineCmd = &cobra.Command{ }, } -func nodesToPtables(currentNamespace headscale.Namespace, machines []headscale.Machine) (pterm.TableData, error) { +func nodesToPtables(currentNamespace *headscale.Namespace, machines []headscale.Machine) (pterm.TableData, error) { d := pterm.TableData{{"ID", "Name", "NodeKey", "Namespace", "IP address", "Ephemeral", "Last seen", "Online"}} for _, machine := range machines { @@ -307,9 +301,10 @@ func nodesToPtables(currentNamespace headscale.Namespace, machines []headscale.M } var namespace string - if currentNamespace.ID == machine.NamespaceID { + if (currentNamespace == nil) || (currentNamespace.ID == machine.NamespaceID) { namespace = pterm.LightMagenta(machine.Namespace.Name) } else { + // Shared into this namespace namespace = pterm.LightYellow(machine.Namespace.Name) } d = append(d, []string{strconv.FormatUint(machine.ID, 10), machine.Name, nodeKey.ShortString(), namespace, machine.IPAddress, strconv.FormatBool(ephemeral), lastSeenTime, online}) From 1d9954d8e9a247428121262383da2e6017a60bc7 Mon Sep 17 00:00:00 2001 From: Ward Vandewege Date: Sun, 24 Oct 2021 20:11:47 -0400 Subject: [PATCH 016/300] Fix integration test. --- integration_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integration_test.go b/integration_test.go index 53092423..a1a5e953 100644 --- a/integration_test.go +++ b/integration_test.go @@ -493,7 +493,7 @@ func (s *IntegrationTestSuite) TestSharedNodes() { result, err := executeCommand( &headscale, - []string{"headscale", "nodes", "share", "--namespace", "shared", fmt.Sprint(machine.ID), "main"}, + []string{"headscale", "nodes", "share", fmt.Sprint(machine.ID), "main"}, []string{}, ) assert.Nil(s.T(), err) From 4d3b638a3d2ce4d377cb2cdfef018812e7b0e0cf Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Mon, 25 Oct 2021 19:38:11 +0100 Subject: [PATCH 017/300] Add note about main containing unreleased changes #201 --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index a3c09396..91e13b92 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,8 @@ An open source, self-hosted implementation of the Tailscale coordination server. Join our [Discord](https://discord.gg/XcQxk2VHjx) server for a chat. +**Note:** Always select the same GitHub tag as the released version you use to ensure you have the correct example configuration and documentation. The `main` branch might contain unreleased changes. + ## Overview Tailscale is [a modern VPN](https://tailscale.com/) built on top of [Wireguard](https://www.wireguard.com/). It [works like an overlay network](https://tailscale.com/blog/how-tailscale-works/) between the computers of your networks - using all kinds of [NAT traversal sorcery](https://tailscale.com/blog/how-nat-traversal-works/). From f9ece0087d0e0cbbf1ae726cce2eed340d53ed91 Mon Sep 17 00:00:00 2001 From: Ward Vandewege Date: Tue, 26 Oct 2021 08:50:25 -0400 Subject: [PATCH 018/300] Make the cli help a little more explicit for the nodes subcommand. --- cmd/headscale/cli/nodes.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd/headscale/cli/nodes.go b/cmd/headscale/cli/nodes.go index 954e338e..ba843f70 100644 --- a/cmd/headscale/cli/nodes.go +++ b/cmd/headscale/cli/nodes.go @@ -17,9 +17,9 @@ import ( func init() { rootCmd.AddCommand(nodeCmd) - listNodesCmd.Flags().StringP("namespace", "n", "", "Namespace") + listNodesCmd.Flags().StringP("namespace", "n", "", "Filter by namespace") nodeCmd.AddCommand(listNodesCmd) - registerNodeCmd.Flags().StringP("namespace", "n", "", "Namespace") + registerNodeCmd.Flags().StringP("namespace", "n", "", "Filter by namespace") err := registerNodeCmd.MarkFlagRequired("namespace") if err != nil { log.Fatalf(err.Error()) From b096a2e7e50b4eca45caabeacc94a3a9fb8b9191 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Tue, 26 Oct 2021 20:37:37 +0000 Subject: [PATCH 019/300] Create an initial gRPC service This commit adds protobuf files and tooling surrounding generating APIs and datatypes. --- .gitignore | 3 ++ buf.gen.yaml | 21 ++++++++++++ proto/buf.lock | 24 ++++++++++++++ proto/buf.yaml | 12 +++++++ proto/v1/headscale.proto | 71 ++++++++++++++++++++++++++++++++++++++++ tools.go | 12 +++++++ 6 files changed, 143 insertions(+) create mode 100644 buf.gen.yaml create mode 100644 proto/buf.lock create mode 100644 proto/buf.yaml create mode 100644 proto/v1/headscale.proto create mode 100644 tools.go diff --git a/.gitignore b/.gitignore index 610550b9..f45c47a5 100644 --- a/.gitignore +++ b/.gitignore @@ -25,3 +25,6 @@ config.yaml .idea test_output/ + +# Protobuf generated code +gen/ diff --git a/buf.gen.yaml b/buf.gen.yaml new file mode 100644 index 00000000..d7b832ab --- /dev/null +++ b/buf.gen.yaml @@ -0,0 +1,21 @@ +version: v1 +plugins: + - name: go + out: gen/go + opt: + - paths=source_relative + - name: go-grpc + out: gen/go + opt: + - paths=source_relative + - name: grpc-gateway + out: gen/go + opt: + - paths=source_relative + - generate_unbound_methods=true + # - name: gorm + # out: gen/go + # opt: + # - paths=source_relative,enums=string,gateway=true + - name: openapiv2 + out: gen/openapiv2 diff --git a/proto/buf.lock b/proto/buf.lock new file mode 100644 index 00000000..03cd7b89 --- /dev/null +++ b/proto/buf.lock @@ -0,0 +1,24 @@ +# Generated by buf. DO NOT EDIT. +version: v1 +deps: + - remote: buf.build + owner: googleapis + repository: googleapis + branch: main + commit: cd101b0abb7b4404a0b1ecc1afd4ce10 + digest: b1-H4GHwHVHcJBbVPg-Cdmnx812reFCDQws_QoQ0W2hYQA= + create_time: 2021-10-23T15:04:06.087748Z + - remote: buf.build + owner: grpc-ecosystem + repository: grpc-gateway + branch: main + commit: ff83506eb9cc4cf8972f49ce87e6ed3e + digest: b1-iLPHgLaoeWWinMiXXqPnxqE4BThtY3eSbswVGh9GOGI= + create_time: 2021-10-23T16:26:52.283938Z + - remote: buf.build + owner: ufoundit-dev + repository: protoc-gen-gorm + branch: main + commit: e2ecbaa0d37843298104bd29fd866df8 + digest: b1-SV9yKH_8P-IKTOlHZxP-bb0ALANYeEqH_mtPA0EWfLc= + create_time: 2021-10-08T06:03:05.64876Z diff --git a/proto/buf.yaml b/proto/buf.yaml new file mode 100644 index 00000000..7e524ba0 --- /dev/null +++ b/proto/buf.yaml @@ -0,0 +1,12 @@ +version: v1 +lint: + use: + - DEFAULT +breaking: + use: + - FILE + +deps: + - buf.build/googleapis/googleapis + - buf.build/grpc-ecosystem/grpc-gateway + - buf.build/ufoundit-dev/protoc-gen-gorm diff --git a/proto/v1/headscale.proto b/proto/v1/headscale.proto new file mode 100644 index 00000000..b6356b8f --- /dev/null +++ b/proto/v1/headscale.proto @@ -0,0 +1,71 @@ +syntax = "proto3"; +package headscale.v1; +option go_package = "github.com/juanfont/headscale/gen/go/v1"; + +import "google/protobuf/timestamp.proto"; +import "google/api/annotations.proto"; +import "options/gorm.proto"; + +enum RegisterMethod { + AUTH_KEY = 0; + CLI = 1; + OIDC = 2; +} + +message Namespace { + string Name = 1; +} + +message PreAuthKey { + uint64 ID = 1; + string Key = 2; + uint32 NamespaceID = 3; + Namespace Namespace = 4; + bool Reusable = 5; + bool Ephemeral = 6; + bool Used = 7; + + google.protobuf.Timestamp CreatedAt = 8; + google.protobuf.Timestamp Expiration = 9; +} + +message GetMachineRequest { + uint64 machine_id = 1; +} + +message Machine { + option(gorm.opts).ormable = true; + uint64 ID = 1; + string MachineKey = 2; + string NodeKey = 3; + string DiscoKey = 4; + string IPAddress = 5; + string Name = 6; + uint32 NamespaceID = 7; + + bool Registered = 8; + RegisterMethod RegisterMethod = 9; + uint32 AuthKeyID = 10; + PreAuthKey AuthKey = 11; + + google.protobuf.Timestamp LastSeen = 12; + google.protobuf.Timestamp LastSuccessfulUpdate = 13; + google.protobuf.Timestamp Expiry = 14; + + bytes HostInfo = 15; + bytes Endpoints = 16; + bytes EnabledRoutes = 17; + + google.protobuf.Timestamp CreatedAt = 18; + google.protobuf.Timestamp UpdatedAt = 19; + google.protobuf.Timestamp DeletedAt = 20; +} + +// Gin Router will prefix this with /api/v1 +service HeadscaleService { + rpc GetMachine(GetMachineRequest) returns(Machine) { + option(google.api.http) = { + get : "/api/v1/machine/{machine_id}" + }; + } +} diff --git a/tools.go b/tools.go new file mode 100644 index 00000000..287c1230 --- /dev/null +++ b/tools.go @@ -0,0 +1,12 @@ +//go:build tools +// +build tools + +package tools + +import ( + _ "github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway" + _ "github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2" + _ "github.com/infobloxopen/protoc-gen-gorm" + _ "google.golang.org/grpc/cmd/protoc-gen-go-grpc" + _ "google.golang.org/protobuf/cmd/protoc-gen-go" +) From a9da7c8fd9e59c4320fe4a2d2fc7a7406ba0f59f Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Tue, 26 Oct 2021 20:41:35 +0000 Subject: [PATCH 020/300] Update go.mod --- go.mod | 10 ++++++- go.sum | 85 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 93 insertions(+), 2 deletions(-) diff --git a/go.mod b/go.mod index 65165e0d..002e3ede 100644 --- a/go.mod +++ b/go.mod @@ -10,12 +10,14 @@ require ( github.com/docker/cli v20.10.8+incompatible // indirect github.com/docker/docker v20.10.8+incompatible // indirect github.com/efekarakus/termcolor v1.0.1 - github.com/fatih/set v0.2.1 // indirect + github.com/fatih/set v0.2.1 github.com/gin-gonic/gin v1.7.4 github.com/gofrs/uuid v4.0.0+incompatible github.com/google/go-github v17.0.0+incompatible // indirect github.com/google/go-querystring v1.1.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.6.0 github.com/hako/durafmt v0.0.0-20210608085754-5c1018a4e16b + github.com/infobloxopen/protoc-gen-gorm v1.0.1 github.com/klauspost/compress v1.13.5 github.com/lib/pq v1.10.3 // indirect github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6 // indirect @@ -24,6 +26,7 @@ require ( github.com/prometheus/client_golang v1.11.0 github.com/pterm/pterm v0.12.30 github.com/rs/zerolog v1.25.0 + github.com/soheilhy/cmux v0.1.5 github.com/spf13/cobra v1.2.1 github.com/spf13/viper v1.8.1 github.com/stretchr/testify v1.7.0 @@ -33,7 +36,12 @@ require ( github.com/zsais/go-gin-prometheus v0.1.0 golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 golang.org/x/net v0.0.0-20210913180222-943fd674d43e // indirect + golang.org/x/sync v0.0.0-20210220032951-036812b2e83c golang.org/x/sys v0.0.0-20210910150752-751e447fb3d0 // indirect + google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83 + google.golang.org/grpc v1.40.0 + google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0 + google.golang.org/protobuf v1.27.1 gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c gopkg.in/yaml.v2 v2.4.0 gorm.io/datatypes v1.0.2 diff --git a/go.sum b/go.sum index b429ca95..9e31f2fe 100644 --- a/go.sum +++ b/go.sum @@ -38,6 +38,7 @@ cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0Zeo cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= +contrib.go.opencensus.io/exporter/ocagent v0.7.0/go.mod h1:IshRmMJBhDfFj5Y67nVhMYTTIze91RUeT73ipWKs/GY= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/AlecAivazis/survey/v2 v2.3.2 h1:TqTB+aDDCLYhf9/bD2TwSO8u8jDSmMUd2SUVO4gCnU8= github.com/AlecAivazis/survey/v2 v2.3.2/go.mod h1:TH2kPCDU3Kqq7pLbnCWwZXDBjnhZtmsCle5EiYDJ2fg= @@ -46,6 +47,7 @@ github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOEl github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= github.com/Djarvur/go-err113 v0.0.0-20200511133814-5174e21577d5/go.mod h1:4UJr5HIiMZrwgkSPdsjy2uOQExX/WEILpIrO9UPGuXs= github.com/Djarvur/go-err113 v0.1.0/go.mod h1:4UJr5HIiMZrwgkSPdsjy2uOQExX/WEILpIrO9UPGuXs= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= @@ -70,6 +72,7 @@ github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 h1:TngWCqHvy9oXAN6lEV github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/OpenPeeDeeP/depguard v1.0.1/go.mod h1:xsIw86fROiiwelg+jB2uM9PiKihMMmUx/1V+TNhjQvM= +github.com/PuerkitoBio/goquery v1.5.1/go.mod h1:GsLWisAFVj4WgDibEWF4pvYnkVQBpKBKeU+7zCJoLcc= github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= @@ -84,6 +87,7 @@ github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRF github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= github.com/alexbrainman/sspi v0.0.0-20210105120005-909beea2cc74/go.mod h1:cEWa1LVoE5KvSD9ONXsZrj0z6KqySlCCNKHlLzbqAt4= github.com/andybalholm/brotli v1.0.0/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y= +github.com/andybalholm/cascadia v1.1.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= @@ -105,12 +109,14 @@ github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24 github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d/go.mod h1:6QX/PXZ00z/TKoufEY6K/a0k6AhaJrQKdFe6OfVXsa4= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/bits-and-blooms/bitset v1.2.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= github.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqOes/6LfM= github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb/go.mod h1:PkYb9DJNAwrSvRx5DYA+gUcOIgTGVMNkfSCbZM8cWpI= github.com/bombsimon/wsl/v3 v3.1.0/go.mod h1:st10JtZYLE4D5sC7b8xV4zTKZwAQjCH/Hy2Pm1FNZIc= +github.com/bufbuild/buf v0.37.0/go.mod h1:lQ1m2HkIaGOFba6w/aC3KYBHhKEOESP3gaAEpS3dAFM= github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= github.com/cavaliercoder/go-cpio v0.0.0-20180626203310-925f9528c45e/go.mod h1:oDpT4efm8tSYHXV5tHSdRvBet/b/QzxZ+XyyPehvm3A= github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4= @@ -134,6 +140,7 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I= github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= @@ -168,9 +175,12 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs 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/denis-tingajkin/go-header v0.3.1/go.mod h1:sq/2IxMhaZX+RRcgHfCRx/m0M5na0fBt4/CRe7Lrji0= +github.com/denisenkom/go-mssqldb v0.0.0-20191124224453-732737034ffd/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU= +github.com/denisenkom/go-mssqldb v0.9.0/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU= github.com/denisenkom/go-mssqldb v0.10.0 h1:QykgLZBorFE95+gO3u9esLd0BmbvpWp0/waNNZfHBM8= github.com/denisenkom/go-mssqldb v0.10.0/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/dgrijalva/jwt-go v3.2.1-0.20200107013213-dc14462fd587+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= github.com/docker/cli v20.10.7+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/cli v20.10.8+incompatible h1:/zO/6y9IOpcehE49yMRTV9ea0nBpb8OeqSskXLNfH1E= @@ -199,7 +209,10 @@ github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1m github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5 h1:Yzb9+7DPaBjB8zlTR87/ElzFsnQfuHnVUVqpZZIcV5Y= +github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5/go.mod h1:a2zkGnVExMxdzMo3M0Hi/3sEU+cWnZpSni0O6/Yb/P0= github.com/fanliao/go-promise v0.0.0-20141029170127-1890db352a72/go.mod h1:PjfxuH4FZdUyfMdtBio2lsRr1AKEaVPwelzuHuh8Lqc= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= @@ -214,6 +227,7 @@ github.com/frankban/quicktest v1.13.0/go.mod h1:qLE0fzW0VuyUAJgPU19zByoIr0HtCHN/ github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= @@ -249,6 +263,7 @@ github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+ github.com/go-playground/validator/v10 v10.4.1 h1:pH2c5ADXtd66mxoE0Zm9SUhxE20r7aM3F26W0hOn+GE= github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4= github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= +github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE= github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= @@ -278,6 +293,8 @@ github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69 github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe h1:lXe2qZdvpiX5WZkZR4hgp4KJVfY3nMkvmwbVkpv1rVY= github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/glog v1.0.0 h1:nfP3RFugxnNRyKgeWd4oI1nYvXpxrx8ck8ZrcizshdQ= +github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4= github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -370,6 +387,7 @@ github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaU github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/gookit/color v1.3.1/go.mod h1:R3ogXq2B9rTbXoSHJ1HyUVAZ3poOJHpd9nQmyGZsfvQ= @@ -377,6 +395,7 @@ github.com/gookit/color v1.4.2 h1:tXy44JFSFkKnELV6WaMo/lLfu/meqITX3iAV52do7lk= github.com/gookit/color v1.4.2/go.mod h1:fqRyamkC1W8uxl+lxCQxOT09l/vYfZ+QeiX3rKQHCoQ= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gordonklaus/ineffassign v0.0.0-20200309095847-7953dde2c7bf/go.mod h1:cuNKsD1zp2v6XfE/orVX2QE1LC+i254ceGcVeDT3pTU= github.com/goreleaser/chglog v0.1.2/go.mod h1:tTZsFuSZK4epDXfjMkxzcGbrIOXprf0JFp47BjIr3B8= github.com/goreleaser/fileglob v0.3.1/go.mod h1:kNcPrPzjCp+Ox3jmXLU5QEsjhqrtLBm6OnXAif8KRl8= github.com/goreleaser/nfpm v1.10.3/go.mod h1:EEC7YD5wi+ol0MiAshpgPANBOkjXDl7wqTLVk68OBsk= @@ -394,10 +413,17 @@ github.com/gostaticanalysis/comment v1.3.0/go.mod h1:xMicKDx7XRXYdVwY9f9wQpDJVnq github.com/gostaticanalysis/comment v1.4.1/go.mod h1:ih6ZxzTHLdadaiSnF5WY3dxUoXfXAlTaRzuaNDlSado= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-middleware v1.2.2/go.mod h1:EaizFBKfUKtMIF5iaDEhniwNedqGo9FuLFzppDr3uwI= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/grpc-ecosystem/grpc-gateway v1.14.6/go.mod h1:zdiPV4Yse/1gnckTHtghG4GkDEdKCRJduHpTxT3/jcw= +github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.3.0/go.mod h1:d2gYTOTUQklu06xp0AJYYmRdTVU1VKrqhkYfYag2L08= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.4.0/go.mod h1:IOyTYjcIO0rkmnGBfJTL0NJ11exy/Tc2QEuv7hCXp24= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.6.0 h1:rgxjzoDmDXw5q8HONgyHhBas4to0/XWRo/gPpJhsUNQ= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.6.0/go.mod h1:qrJPVzv9YlhsrxJc3P/Q85nr0w1lIRikTl4JlhdDH5w= github.com/hako/durafmt v0.0.0-20210608085754-5c1018a4e16b h1:wDUNC2eKiL35DbLvsDhiblTUXHxcOPwQSCzi7xpQUN4= github.com/hako/durafmt v0.0.0-20210608085754-5c1018a4e16b/go.mod h1:VzxiSdG6j1pi7rwGm/xYI5RbtpBgM8sARDXlvEvxlu0= github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= @@ -441,6 +467,9 @@ github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= +github.com/infobloxopen/atlas-app-toolkit v0.24.1-0.20210416193901-4c7518b07e08/go.mod h1:9BTHnpff654rY1J8KxSUOLJ+ZUDn2Vi3mmk26gQDo1M= +github.com/infobloxopen/protoc-gen-gorm v1.0.1 h1:IjvQ02gZSll+CjpWjxkLqrpxnvKAGfs5dXRJEpfZx2s= +github.com/infobloxopen/protoc-gen-gorm v1.0.1/go.mod h1:gTu86stnDQXwcNqLG9WNJfl3IPUIhxmGNqJ8z4826uo= github.com/insomniacslk/dhcp v0.0.0-20210621130208-1cac67f12b1e/go.mod h1:h+MxyHxRg9NH3terB1nfRIUaQEcI0XOVkdR9LNBlp8E= github.com/jackc/chunkreader v1.0.0 h1:4s39bBR8ByfqH+DKm8rQA3E1LHZWB9XWcrz8fqaZbe0= github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo= @@ -508,9 +537,13 @@ github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dv github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jgautheron/goconst v0.0.0-20201117150253-ccae5bf973f3/go.mod h1:aAosetZ5zaeC/2EfMeRswtxUFBpe2Hr7HzkgX4fanO4= +github.com/jhump/protoreflect v1.8.1/go.mod h1:7GcYQDdMU/O/BBrl/cX6PNHpXh6cenjd8pneu5yW7Tg= github.com/jingyugao/rowserrcheck v0.0.0-20191204022205-72ab7603b68a/go.mod h1:xRskid8CManxVta/ALEhJha/pweKBaVG6fWgc0yH25s= +github.com/jinzhu/gorm v1.9.16 h1:+IyIjPEABKRpsu/F8OvDPy9fyQlgsg2luMV2ZIH5i5o= +github.com/jinzhu/gorm v1.9.16/go.mod h1:G3LB3wezTOWM2ITLzPxEXgSkOXAntiLHS7UdBefADcs= github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= +github.com/jinzhu/now v1.0.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= github.com/jinzhu/now v1.1.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= github.com/jinzhu/now v1.1.2 h1:eVKgfIdy9b6zbWBMgFpfDPoAMifwSZagU9HmEU6zgiI= github.com/jinzhu/now v1.1.2/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= @@ -555,9 +588,11 @@ github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.10.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.11.0/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= +github.com/klauspost/compress v1.11.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.12.2/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= github.com/klauspost/compress v1.13.5 h1:9O69jUPDcsT9fEm74W92rZL9FQY7rCdaXVneq+yyzl4= github.com/klauspost/compress v1.13.5/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= +github.com/klauspost/pgzip v1.2.5/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= @@ -580,8 +615,10 @@ github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgx github.com/lib/pq v0.0.0-20180327071824-d34b9ff171c2/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.3.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.3.1-0.20200116171513-9eb3fc897d6f/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/lib/pq v1.10.3 h1:v9QZf2Sn6AmjXtQeFpdoq/eaNtYP6IN+7lcrygsIAtg= github.com/lib/pq v1.10.3/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= @@ -591,6 +628,7 @@ github.com/logrusorgru/aurora v0.0.0-20181002194514-a7b3b318ed4e/go.mod h1:7rIyQ github.com/lxn/walk v0.0.0-20210112085537-c389da54e794/go.mod h1:E23UucZGqpuUANJooIbHWCufXvOcT6E7Stq81gU+CSQ= github.com/lxn/win v0.0.0-20210218163916-a377121e959e/go.mod h1:KxxjdtRkfNoYDCUP5ryK7XJJNTnpC8atvtmTheChOtk= github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= +github.com/magefile/mage v1.10.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.4/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= @@ -620,7 +658,9 @@ github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzp github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= +github.com/mattn/go-sqlite3 v1.14.0/go.mod h1:JIl7NbARA7phWnGvh0LKTyg7S9BA+6gx71ShQilpsus= github.com/mattn/go-sqlite3 v1.14.5/go.mod h1:WVKg1VTActs4Qso6iwGbiFih2UIHo0ENGwNd0Lj+XmI= +github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/mattn/go-sqlite3 v1.14.8 h1:gDp86IdQsN/xWjIEmr9MF6o9mpksUgh0fu+9ByFxzIU= github.com/mattn/go-sqlite3 v1.14.8/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= @@ -690,6 +730,7 @@ github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OS github.com/nbutton23/zxcvbn-go v0.0.0-20180912185939-ae427f1e4c1d/go.mod h1:o96djdrsSGy3AWPyBgZMAGfxZNfgntdJG+11KU4QvbU= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/nishanths/exhaustive v0.1.0/go.mod h1:S1j9110vxV1ECdCudXRkeMnFQ/DQk9ajLT0Uf2MYZQQ= +github.com/nishanths/predeclared v0.0.0-20200524104333-86fad755b4d3/go.mod h1:nt3d53pc1VYcphSCIaYAJtnPYnr3Zyn8fMq2wvPGPso= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= @@ -745,6 +786,7 @@ github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= +github.com/pkg/profile v1.5.0/go.mod h1:qBsxPvzyUincmltOk6iyRVxHYg4adc0OFOv72ZdLa18= github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= github.com/pkg/sftp v1.13.0/go.mod h1:41g+FIPlQUTDCveupEmEA65IoiQFrtgCeDopC4ajGIM= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= @@ -835,6 +877,7 @@ github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMB github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/sirupsen/logrus v1.8.0/go.mod h1:4GuYW9TZmE769R5STWrRakJc4UqQ3+QQ95fyz7ENv1A= github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= @@ -842,6 +885,8 @@ github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1 github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= +github.com/soheilhy/cmux v0.1.5 h1:jjzc5WVemNEDTLwv9tlmemhC73tI08BNOIGwBOo10Js= +github.com/soheilhy/cmux v0.1.5/go.mod h1:T7TcVDs9LWfQgPlPsdngu6I6QIoyIFZDDC6sNE1GqG0= github.com/sonatard/noctx v0.0.1/go.mod h1:9D2D/EoULe8Yy2joDHJj7bv3sZoq9AaSb8B4lqBjiZI= github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= github.com/sourcegraph/go-diff v0.6.1/go.mod h1:iBszgVvyxdc8SFZ7gm69go2KDdt3ag071iBaWPF6cjs= @@ -856,6 +901,7 @@ github.com/spf13/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng= github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= +github.com/spf13/cobra v1.0.1-0.20201006035406-b97b5ead31f7/go.mod h1:yk5b0mALVusDL5fMM6Rd1wgnoO5jUPhwsQ6LQAJTidQ= github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJQMI= github.com/spf13/cobra v1.2.1 h1:+KmjbUw1hriSNMF55oPrkZcb27aECyrj8V2ytv7kWDw= github.com/spf13/cobra v1.2.1/go.mod h1:ExllRjgxM/piMAM+3tAZvg8fsklGAf3tPfi+i8t68Nk= @@ -911,6 +957,7 @@ github.com/tomarrell/wrapcheck v0.0.0-20200807122107-df9e8bcb914d/go.mod h1:yiFB github.com/tomarrell/wrapcheck v0.0.0-20201130113247-1683564d9756/go.mod h1:yiFB6fFoV7saXirUGfuK+cPtUh4NX/Hf5y2WC2lehu0= github.com/tommy-muehle/go-mnd v1.3.1-0.20200224220436-e6f9a994e8fa/go.mod h1:dSUh0FtTP8VhvkL1S+gUR1OKd9ZnSaozuI6r3m6wOig= github.com/toqueteos/webbrowser v1.2.0/go.mod h1:XWoZq4cyp9WeUeak7w7LXRUQf1F1ATJMir8RTqb4ayM= +github.com/twitchtv/twirp v7.1.0+incompatible/go.mod h1:RRJoFSAmTEh2weEqWtpPE3vFK5YBhA6bqp2l1kfCC5A= github.com/u-root/uio v0.0.0-20210528114334-82958018845c/go.mod h1:LpEX5FO/cB+WF4TYGY1V5qktpaZLkKkSegbr0V4eYXA= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo= @@ -966,7 +1013,9 @@ go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= +go.opencensus.io v0.22.6/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= +go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= @@ -980,6 +1029,7 @@ go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9E go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= +go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ= go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= go4.org/intern v0.0.0-20210108033219-3eb7198706b2 h1:VFTf+jjIgsldaz/Mr00VaCSswHJrI2hIjQygE/W4IMg= go4.org/intern v0.0.0-20210108033219-3eb7198706b2/go.mod h1:vLqJ+12kCw61iCWsPto0EOHhBS+o4rO5VIucbc9g2Cc= @@ -1001,6 +1051,7 @@ golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191205180655-e7c4368fe9dd/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= @@ -1025,6 +1076,7 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= +golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -1050,6 +1102,7 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1073,6 +1126,7 @@ golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191002035440-2ec189313ef0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191007182048-72f939374954/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -1081,6 +1135,7 @@ golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200421231249-e086a090c8fd/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= @@ -1094,6 +1149,7 @@ golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwY golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20201216054612-986b41b23924/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= @@ -1117,6 +1173,8 @@ golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210427180440-81ed05c6b58c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1127,6 +1185,7 @@ golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1176,6 +1235,7 @@ golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1304,11 +1364,13 @@ golang.org/x/tools v0.0.0-20200426102838-f3a5411a4c3b/go.mod h1:EkVYQZoAsY45+roY golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200522201501-cb1345f3a375/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200622203043-20e05c1c8ffa/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200624225443-88f3c62a19ff/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200625211823-6506e20df31f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200717024301-6ddee64345a6/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200724022722-7017fd6b1305/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200731060945-b5fad4ed8dd6/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= @@ -1357,6 +1419,7 @@ google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/ google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.25.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= @@ -1396,26 +1459,34 @@ google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfG google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20200527145253-8367513e4ece/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200806141610-86f49bd18e98/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210207032614-bba0dbe2a9ea/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210224155714-063164c882e6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= +google.golang.org/genproto v0.0.0-20210426193834-eac7f76ac494/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83 h1:3V2dxSZpz4zozWWUq36vUxXEKnSYitEH2LdsAx+RUmg= +google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= @@ -1437,10 +1508,19 @@ google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= +google.golang.org/grpc v1.35.0-dev.0.20201218190559-666aea1fb34c/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.40.0 h1:AGJ0Ih4mHjSeibYkFGh1dD9KJ/eOtZ93I6hoHhukQ5Q= +google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= +google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.0.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= +google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0 h1:M1YKkFIboKNieVO5DLUEVzQfGwJD30Nv2jfUgzb5UcE= +google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= +google.golang.org/grpc/examples v0.0.0-20210309220351-d5b628860d4e/go.mod h1:Ly7ZA/ARzg8fnPU9TyZIxoz33sEUuWX7txiqs8lPTgE= +google.golang.org/grpc/examples v0.0.0-20210601155443-8bdcb4c9ab8d/go.mod h1:bF8wuZSAZTcbF7ZPKrDI/qY52toTP/yxLpRRY4Eu9Js= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -1451,9 +1531,12 @@ google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2 google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/protobuf v1.25.1-0.20200805231151-a709e31e5d12/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/protobuf v1.25.1-0.20201208041424-160c7477e0e8/go.mod h1:hFxJC2f0epmp1elRCiEGJTKAWbwxZ2nvqZdHl3FQXCY= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ= +google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= From caa4d33cbd1d3db42c21fd59ca72b3f469f41b3e Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Tue, 26 Oct 2021 20:42:20 +0000 Subject: [PATCH 021/300] Add an initial grpcv1 service (implementing the proto generated service) --- grpcv1.go | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 grpcv1.go diff --git a/grpcv1.go b/grpcv1.go new file mode 100644 index 00000000..d9bbf531 --- /dev/null +++ b/grpcv1.go @@ -0,0 +1,33 @@ +package headscale + +import ( + "context" + + apiV1 "github.com/juanfont/headscale/gen/go/v1" +) + +type headscaleV1APIServer struct { // apiV1.HeadscaleServiceServer + apiV1.UnimplementedHeadscaleServiceServer + h *Headscale +} + +func newHeadscaleV1APIServer(h *Headscale) apiV1.HeadscaleServiceServer { + return headscaleV1APIServer{ + h: h, + } +} + +func (api headscaleV1APIServer) GetMachine( + ctx context.Context, + request *apiV1.GetMachineRequest, +) (*apiV1.Machine, error) { + m, err := api.h.GetMachineByID(request.MachineId) + if err != nil { + return nil, err + } + + // TODO(kradalby): Make this function actually do something + return &apiV1.Machine{Name: m.Name}, nil +} + +func (api headscaleV1APIServer) mustEmbedUnimplementedHeadscaleServiceServer() {} From 2f045b20fbaf630d6bbeb0c28ad62856d014653a Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Tue, 26 Oct 2021 20:42:56 +0000 Subject: [PATCH 022/300] Refactor tls and wire up grpc, grpc gateway/api This commit moves the TLS configuration into a seperate function. It also wires up the gRPC interface and prepares handing the API endpoints to the grpc gateway. --- app.go | 127 +++++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 105 insertions(+), 22 deletions(-) diff --git a/app.go b/app.go index 546eb866..dbe30168 100644 --- a/app.go +++ b/app.go @@ -1,8 +1,11 @@ package headscale import ( + "context" + "crypto/tls" "errors" "fmt" + "net" "net/http" "net/url" "os" @@ -11,12 +14,16 @@ import ( "sync" "time" - "github.com/rs/zerolog/log" - "github.com/gin-gonic/gin" + "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" + apiV1 "github.com/juanfont/headscale/gen/go/v1" + "github.com/rs/zerolog/log" + "github.com/soheilhy/cmux" ginprometheus "github.com/zsais/go-gin-prometheus" "golang.org/x/crypto/acme" "golang.org/x/crypto/acme/autocert" + "golang.org/x/sync/errgroup" + "google.golang.org/grpc" "gorm.io/gorm" "inet.af/netaddr" "tailscale.com/tailcfg" @@ -24,7 +31,7 @@ import ( "tailscale.com/types/wgkey" ) -// Config contains the initial Headscale configuration +// Config contains the initial Headscale configuration. type Config struct { ServerURL string Addr string @@ -64,7 +71,7 @@ type DERPConfig struct { UpdateFrequency time.Duration } -// Headscale represents the base app of the service +// Headscale represents the base app of the service. type Headscale struct { cfg Config db *gorm.DB @@ -82,12 +89,13 @@ type Headscale struct { lastStateChange sync.Map } -// NewHeadscale returns the Headscale app +// NewHeadscale returns the Headscale app. func NewHeadscale(cfg Config) (*Headscale, error) { content, err := os.ReadFile(cfg.PrivateKeyPath) if err != nil { return nil, err } + privKey, err := wgkey.ParsePrivate(string(content)) if err != nil { return nil, err @@ -136,14 +144,14 @@ func NewHeadscale(cfg Config) (*Headscale, error) { return &h, nil } -// Redirect to our TLS url +// Redirect to our TLS url. func (h *Headscale) redirect(w http.ResponseWriter, req *http.Request) { target := h.cfg.ServerURL + req.URL.RequestURI() http.Redirect(w, req, target, http.StatusFound) } // expireEphemeralNodes deletes ephemeral machine records that have not been -// seen for longer than h.cfg.EphemeralNodeInactivityTimeout +// seen for longer than h.cfg.EphemeralNodeInactivityTimeout. func (h *Headscale) expireEphemeralNodes(milliSeconds int64) { ticker := time.NewTicker(time.Duration(milliSeconds) * time.Millisecond) for range ticker.C { @@ -155,18 +163,23 @@ func (h *Headscale) expireEphemeralNodesWorker() { namespaces, err := h.ListNamespaces() if err != nil { log.Error().Err(err).Msg("Error listing namespaces") + return } + for _, ns := range *namespaces { machines, err := h.ListMachinesInNamespace(ns.Name) if err != nil { log.Error().Err(err).Str("namespace", ns.Name).Msg("Error listing machines in namespace") + return } + for _, m := range *machines { if m.AuthKey != nil && m.LastSeen != nil && m.AuthKey.Ephemeral && time.Now().After(m.LastSeen.Add(h.cfg.EphemeralNodeInactivityTimeout)) { log.Info().Str("machine", m.Name).Msg("Ephemeral client removed from database") + err = h.db.Unscoped().Delete(m).Error if err != nil { log.Error(). @@ -176,12 +189,13 @@ func (h *Headscale) expireEphemeralNodesWorker() { } } } + h.setLastStateChangeToNow(ns.Name) } } // WatchForKVUpdates checks the KV DB table for requests to perform tailnet upgrades -// This is a way to communitate the CLI with the headscale server +// This is a way to communitate the CLI with the headscale server. func (h *Headscale) watchForKVUpdates(milliSeconds int64) { ticker := time.NewTicker(time.Duration(milliSeconds) * time.Millisecond) for range ticker.C { @@ -194,24 +208,60 @@ func (h *Headscale) watchForKVUpdatesWorker() { // more functions will come here in the future } -// Serve launches a GIN server with the Headscale API +// Serve launches a GIN server with the Headscale API. func (h *Headscale) Serve() error { + var err error + + ctx := context.Background() + ctx, cancel := context.WithCancel(ctx) + + defer cancel() + + l, err := net.Listen("tcp", h.cfg.Addr) + if err != nil { + panic(err) + } + + // Create the cmux object that will multiplex 2 protocols on the same port. + // The two following listeners will be served on the same port below gracefully. + m := cmux.New(l) + // Match gRPC requests here + grpcListener := m.MatchWithWriters(cmux.HTTP2MatchHeaderFieldSendSettings("content-type", "application/grpc")) + // Otherwise match regular http requests. + httpListener := m.Match(cmux.Any()) + + // Now create the grpc server with those options. + grpcServer := grpc.NewServer() + + // TODO(kradalby): register the new server when we have authentication ready + // apiV1.RegisterHeadscaleServiceServer(grpcServer, newHeadscaleV1APIServer(h)) + + grpcGatewayMux := runtime.NewServeMux() + + opts := []grpc.DialOption{grpc.WithInsecure()} + + err = apiV1.RegisterHeadscaleServiceHandlerFromEndpoint(ctx, grpcGatewayMux, h.cfg.Addr, opts) + if err != nil { + return err + } + r := gin.Default() p := ginprometheus.NewPrometheus("gin") p.Use(r) - r.GET("/health", func(c *gin.Context) { c.JSON(200, gin.H{"healthy": "ok"}) }) + r.GET("/health", func(c *gin.Context) { c.JSON(http.StatusOK, gin.H{"healthy": "ok"}) }) r.GET("/key", h.KeyHandler) r.GET("/register", h.RegisterWebAPI) r.POST("/machine/:id/map", h.PollNetMapHandler) r.POST("/machine/:id", h.RegistrationHandler) r.GET("/apple", h.AppleMobileConfig) r.GET("/apple/:platform", h.ApplePlatformConfig) - var err error - go h.watchForKVUpdates(5000) - go h.expireEphemeralNodes(5000) + r.Any("/api/v1/*any", gin.WrapF(grpcGatewayMux.ServeHTTP)) + r.StaticFile("/swagger/swagger.json", "gen/openapiv2/v1/headscale.swagger.json") + + updateMillisecondsWait := int64(5000) // Fetch an initial DERP Map before we start serving h.DERPMap = GetDERPMap(h.cfg.DERP) @@ -222,7 +272,11 @@ func (h *Headscale) Serve() error { go h.scheduledDERPMapUpdateWorker(derpMapCancelChannel) } - s := &http.Server{ + // I HATE THIS + go h.watchForKVUpdates(updateMillisecondsWait) + go h.expireEphemeralNodes(updateMillisecondsWait) + + httpServer := &http.Server{ Addr: h.cfg.Addr, Handler: r, ReadTimeout: 30 * time.Second, @@ -233,6 +287,29 @@ func (h *Headscale) Serve() error { WriteTimeout: 0, } + tlsConfig, err := h.getTLSSettings() + if err != nil { + log.Error().Err(err).Msg("Failed to set up TLS configuration") + + return err + } + + if tlsConfig != nil { + httpServer.TLSConfig = tlsConfig + } + + g := new(errgroup.Group) + + g.Go(func() error { return grpcServer.Serve(grpcListener) }) + g.Go(func() error { return httpServer.Serve(httpListener) }) + g.Go(func() error { return m.Serve() }) + + log.Info().Msgf("listening and serving (multiplexed HTTP and gRPC) on: %s", h.cfg.Addr) + + return g.Wait() +} + +func (h *Headscale) getTLSSettings() (*tls.Config, error) { if h.cfg.TLSLetsEncryptHostname != "" { if !strings.HasPrefix(h.cfg.ServerURL, "https://") { log.Warn().Msg("Listening with TLS but ServerURL does not start with https://") @@ -248,13 +325,11 @@ func (h *Headscale) Serve() error { Email: h.cfg.ACMEEmail, } - s.TLSConfig = m.TLSConfig() - if h.cfg.TLSLetsEncryptChallengeType == "TLS-ALPN-01" { // Configuration via autocert with TLS-ALPN-01 (https://tools.ietf.org/html/rfc8737) // The RFC requires that the validation is done on port 443; in other words, headscale // must be reachable on port 443. - err = s.ListenAndServeTLS("", "") + return m.TLSConfig(), nil } else if h.cfg.TLSLetsEncryptChallengeType == "HTTP-01" { // Configuration via autocert with HTTP-01. This requires listening on // port 80 for the certificate validation in addition to the headscale @@ -264,22 +339,30 @@ func (h *Headscale) Serve() error { Err(http.ListenAndServe(h.cfg.TLSLetsEncryptListen, m.HTTPHandler(http.HandlerFunc(h.redirect)))). Msg("failed to set up a HTTP server") }() - err = s.ListenAndServeTLS("", "") + + return m.TLSConfig(), nil } else { - return errors.New("unknown value for TLSLetsEncryptChallengeType") + return nil, errors.New("unknown value for TLSLetsEncryptChallengeType") } } else if h.cfg.TLSCertPath == "" { if !strings.HasPrefix(h.cfg.ServerURL, "http://") { log.Warn().Msg("Listening without TLS but ServerURL does not start with http://") } - err = s.ListenAndServe() + + return nil, nil } else { if !strings.HasPrefix(h.cfg.ServerURL, "https://") { log.Warn().Msg("Listening with TLS but ServerURL does not start with https://") } - err = s.ListenAndServeTLS(h.cfg.TLSCertPath, h.cfg.TLSKeyPath) + var err error + tlsConfig := &tls.Config{} + tlsConfig.ClientAuth = tls.RequireAnyClientCert + tlsConfig.NextProtos = []string{"http/1.1"} + tlsConfig.Certificates = make([]tls.Certificate, 1) + tlsConfig.Certificates[0], err = tls.LoadX509KeyPair(h.cfg.TLSCertPath, h.cfg.TLSKeyPath) + + return tlsConfig, err } - return err } func (h *Headscale) setLastStateChangeToNow(namespace string) { From b8c89cd63ca413bcce3a217779d8fb2f7aabc62a Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Tue, 26 Oct 2021 20:53:10 +0000 Subject: [PATCH 023/300] Add readme and makefile entry about code generation --- Makefile | 5 ++++- README.md | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 755253fc..4c1d6134 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ # Calculate version version = $(shell ./scripts/version-at-commit.sh) -build: +build: generate go build -ldflags "-s -w -X github.com/juanfont/headscale/cmd/headscale/cli.Version=$(version)" cmd/headscale/headscale.go dev: lint test build @@ -25,3 +25,6 @@ lint: compress: build upx --brute headscale +generate: + rm -rf gen + buf generate proto diff --git a/README.md b/README.md index 91e13b92..4e373315 100644 --- a/README.md +++ b/README.md @@ -60,6 +60,41 @@ Please have a look at the documentation under [`docs/`](docs/). 1. We have nothing to do with Tailscale, or Tailscale Inc. 2. The purpose of writing this was to learn how Tailscale works. +## Contributing + +To contribute to Headscale you would need the lastest version of [Go](golang.org) and [Buf](https://buf.build)(Protobuf generator). + +### Install development tools + +- Go +- Buf +- Protobuf tools: + +```shell +go install \ + github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway \ + github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2 \ + google.golang.org/protobuf/cmd/protoc-gen-go \ + google.golang.org/grpc/cmd/protoc-gen-go-grpc +``` + +Building the project requires the generation of Go code from Protobuf (in `proto/`) and it can be (re-)generated with: + +```shell +make generate +``` + +To run the tests: + +```shell +make test +``` + +To build the program: + +```shell +make build +``` ## Contributors From 11d987549fb0d234e1695325d9b27c8e15595386 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Tue, 26 Oct 2021 21:34:51 +0000 Subject: [PATCH 024/300] Ignore generated files for docker --- .dockerignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.dockerignore b/.dockerignore index f90134b3..b7a5c8a8 100644 --- a/.dockerignore +++ b/.dockerignore @@ -14,4 +14,4 @@ docker-compose* README.md LICENSE .vscode - +gen/ From 6e764942a2c084e803c26ad749b0b384cc86e0e0 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Tue, 26 Oct 2021 21:35:18 +0000 Subject: [PATCH 025/300] Add grpc step to dockerfile --- Dockerfile | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 6e216aad..ba248d35 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,11 +1,23 @@ +FROM bufbuild/buf:1.0.0-rc6 as buf + FROM golang:1.17.1-bullseye AS build ENV GOPATH /go +COPY --from=buf /usr/local/bin/buf /usr/local/bin/buf + COPY go.mod go.sum /go/src/headscale/ WORKDIR /go/src/headscale RUN go mod download -COPY . /go/src/headscale +COPY . . + +RUN go install \ + github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway \ + github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2 \ + google.golang.org/protobuf/cmd/protoc-gen-go \ + google.golang.org/grpc/cmd/protoc-gen-go-grpc + +RUN buf generate proto RUN go install -a -ldflags="-extldflags=-static" -tags netgo,sqlite_omit_load_extension ./cmd/headscale RUN test -e /go/bin/headscale From 8f2ef6a57de373cdeb5fb2236dbfd233bb57a15f Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Wed, 27 Oct 2021 06:40:39 +0000 Subject: [PATCH 026/300] Prepare for checking in generated code --- .dockerignore | 1 - .gitignore | 3 --- Dockerfile | 12 +----------- Makefile | 7 +++++++ README.md | 11 +++++------ 5 files changed, 13 insertions(+), 21 deletions(-) diff --git a/.dockerignore b/.dockerignore index b7a5c8a8..33f9aea2 100644 --- a/.dockerignore +++ b/.dockerignore @@ -14,4 +14,3 @@ docker-compose* README.md LICENSE .vscode -gen/ diff --git a/.gitignore b/.gitignore index f45c47a5..610550b9 100644 --- a/.gitignore +++ b/.gitignore @@ -25,6 +25,3 @@ config.yaml .idea test_output/ - -# Protobuf generated code -gen/ diff --git a/Dockerfile b/Dockerfile index ba248d35..9590070b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,23 +2,13 @@ FROM bufbuild/buf:1.0.0-rc6 as buf FROM golang:1.17.1-bullseye AS build ENV GOPATH /go - -COPY --from=buf /usr/local/bin/buf /usr/local/bin/buf +WORKDIR /go/src/headscale COPY go.mod go.sum /go/src/headscale/ -WORKDIR /go/src/headscale RUN go mod download COPY . . -RUN go install \ - github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway \ - github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2 \ - google.golang.org/protobuf/cmd/protoc-gen-go \ - google.golang.org/grpc/cmd/protoc-gen-go-grpc - -RUN buf generate proto - RUN go install -a -ldflags="-extldflags=-static" -tags netgo,sqlite_omit_load_extension ./cmd/headscale RUN test -e /go/bin/headscale diff --git a/Makefile b/Makefile index 4c1d6134..3ce7025c 100644 --- a/Makefile +++ b/Makefile @@ -28,3 +28,10 @@ compress: build generate: rm -rf gen buf generate proto + +install-protobuf-plugins: + go install \ + github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway \ + github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2 \ + google.golang.org/protobuf/cmd/protoc-gen-go \ + google.golang.org/grpc/cmd/protoc-gen-go-grpc diff --git a/README.md b/README.md index 4e373315..060824b9 100644 --- a/README.md +++ b/README.md @@ -71,18 +71,17 @@ To contribute to Headscale you would need the lastest version of [Go](golang.org - Protobuf tools: ```shell -go install \ - github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway \ - github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2 \ - google.golang.org/protobuf/cmd/protoc-gen-go \ - google.golang.org/grpc/cmd/protoc-gen-go-grpc +make install-protobuf-plugins ``` -Building the project requires the generation of Go code from Protobuf (in `proto/`) and it can be (re-)generated with: +### Testing and building + +Some parts of the project requires the generation of Go code from Protobuf (if changes is made in `proto/`) and it must be (re-)generated with: ```shell make generate ``` +**Note**: Please check in changes from `gen/` in a separate commit to make it easier to review. To run the tests: From d4265779ef81fb083fb97ccf73e5b74e3601b2f4 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Wed, 27 Oct 2021 06:44:04 +0000 Subject: [PATCH 027/300] Check in generated code This does not have to be reviewed, here is some reasoning: Go (and go mod) is designed for having code available and we need to check in the generated code to make sure it is "go gettable". If we dont we give ourselves a headache trying to setup all the ci, tests etc to install and generate the code before it runs. Because the code isnt there, the plugins needed to generate the code fail to install... I didnt find any good documentation for this, but there is this github comment: https://github.com/golang/go/issues/34514#issuecomment-535406759 --- gen/go/v1/headscale.pb.go | 702 ++++++++++++++++++++++++ gen/go/v1/headscale.pb.gw.go | 185 +++++++ gen/go/v1/headscale_grpc.pb.go | 101 ++++ gen/openapiv2/v1/headscale.swagger.json | 210 +++++++ 4 files changed, 1198 insertions(+) create mode 100644 gen/go/v1/headscale.pb.go create mode 100644 gen/go/v1/headscale.pb.gw.go create mode 100644 gen/go/v1/headscale_grpc.pb.go create mode 100644 gen/openapiv2/v1/headscale.swagger.json diff --git a/gen/go/v1/headscale.pb.go b/gen/go/v1/headscale.pb.go new file mode 100644 index 00000000..104e3746 --- /dev/null +++ b/gen/go/v1/headscale.pb.go @@ -0,0 +1,702 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.27.1 +// protoc v3.18.1 +// source: v1/headscale.proto + +package v1 + +import ( + _ "github.com/infobloxopen/protoc-gen-gorm/options" + _ "google.golang.org/genproto/googleapis/api/annotations" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + timestamppb "google.golang.org/protobuf/types/known/timestamppb" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type RegisterMethod int32 + +const ( + RegisterMethod_AUTH_KEY RegisterMethod = 0 + RegisterMethod_CLI RegisterMethod = 1 + RegisterMethod_OIDC RegisterMethod = 2 +) + +// Enum value maps for RegisterMethod. +var ( + RegisterMethod_name = map[int32]string{ + 0: "AUTH_KEY", + 1: "CLI", + 2: "OIDC", + } + RegisterMethod_value = map[string]int32{ + "AUTH_KEY": 0, + "CLI": 1, + "OIDC": 2, + } +) + +func (x RegisterMethod) Enum() *RegisterMethod { + p := new(RegisterMethod) + *p = x + return p +} + +func (x RegisterMethod) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (RegisterMethod) Descriptor() protoreflect.EnumDescriptor { + return file_v1_headscale_proto_enumTypes[0].Descriptor() +} + +func (RegisterMethod) Type() protoreflect.EnumType { + return &file_v1_headscale_proto_enumTypes[0] +} + +func (x RegisterMethod) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use RegisterMethod.Descriptor instead. +func (RegisterMethod) EnumDescriptor() ([]byte, []int) { + return file_v1_headscale_proto_rawDescGZIP(), []int{0} +} + +type Namespace struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Name string `protobuf:"bytes,1,opt,name=Name,proto3" json:"Name,omitempty"` +} + +func (x *Namespace) Reset() { + *x = Namespace{} + if protoimpl.UnsafeEnabled { + mi := &file_v1_headscale_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Namespace) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Namespace) ProtoMessage() {} + +func (x *Namespace) ProtoReflect() protoreflect.Message { + mi := &file_v1_headscale_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Namespace.ProtoReflect.Descriptor instead. +func (*Namespace) Descriptor() ([]byte, []int) { + return file_v1_headscale_proto_rawDescGZIP(), []int{0} +} + +func (x *Namespace) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +type PreAuthKey struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ID uint64 `protobuf:"varint,1,opt,name=ID,proto3" json:"ID,omitempty"` + Key string `protobuf:"bytes,2,opt,name=Key,proto3" json:"Key,omitempty"` + NamespaceID uint32 `protobuf:"varint,3,opt,name=NamespaceID,proto3" json:"NamespaceID,omitempty"` + Namespace *Namespace `protobuf:"bytes,4,opt,name=Namespace,proto3" json:"Namespace,omitempty"` + Reusable bool `protobuf:"varint,5,opt,name=Reusable,proto3" json:"Reusable,omitempty"` + Ephemeral bool `protobuf:"varint,6,opt,name=Ephemeral,proto3" json:"Ephemeral,omitempty"` + Used bool `protobuf:"varint,7,opt,name=Used,proto3" json:"Used,omitempty"` + CreatedAt *timestamppb.Timestamp `protobuf:"bytes,8,opt,name=CreatedAt,proto3" json:"CreatedAt,omitempty"` + Expiration *timestamppb.Timestamp `protobuf:"bytes,9,opt,name=Expiration,proto3" json:"Expiration,omitempty"` +} + +func (x *PreAuthKey) Reset() { + *x = PreAuthKey{} + if protoimpl.UnsafeEnabled { + mi := &file_v1_headscale_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PreAuthKey) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PreAuthKey) ProtoMessage() {} + +func (x *PreAuthKey) ProtoReflect() protoreflect.Message { + mi := &file_v1_headscale_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PreAuthKey.ProtoReflect.Descriptor instead. +func (*PreAuthKey) Descriptor() ([]byte, []int) { + return file_v1_headscale_proto_rawDescGZIP(), []int{1} +} + +func (x *PreAuthKey) GetID() uint64 { + if x != nil { + return x.ID + } + return 0 +} + +func (x *PreAuthKey) GetKey() string { + if x != nil { + return x.Key + } + return "" +} + +func (x *PreAuthKey) GetNamespaceID() uint32 { + if x != nil { + return x.NamespaceID + } + return 0 +} + +func (x *PreAuthKey) GetNamespace() *Namespace { + if x != nil { + return x.Namespace + } + return nil +} + +func (x *PreAuthKey) GetReusable() bool { + if x != nil { + return x.Reusable + } + return false +} + +func (x *PreAuthKey) GetEphemeral() bool { + if x != nil { + return x.Ephemeral + } + return false +} + +func (x *PreAuthKey) GetUsed() bool { + if x != nil { + return x.Used + } + return false +} + +func (x *PreAuthKey) GetCreatedAt() *timestamppb.Timestamp { + if x != nil { + return x.CreatedAt + } + return nil +} + +func (x *PreAuthKey) GetExpiration() *timestamppb.Timestamp { + if x != nil { + return x.Expiration + } + return nil +} + +type GetMachineRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + MachineId uint64 `protobuf:"varint,1,opt,name=machine_id,json=machineId,proto3" json:"machine_id,omitempty"` +} + +func (x *GetMachineRequest) Reset() { + *x = GetMachineRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_v1_headscale_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetMachineRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetMachineRequest) ProtoMessage() {} + +func (x *GetMachineRequest) ProtoReflect() protoreflect.Message { + mi := &file_v1_headscale_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetMachineRequest.ProtoReflect.Descriptor instead. +func (*GetMachineRequest) Descriptor() ([]byte, []int) { + return file_v1_headscale_proto_rawDescGZIP(), []int{2} +} + +func (x *GetMachineRequest) GetMachineId() uint64 { + if x != nil { + return x.MachineId + } + return 0 +} + +type Machine struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ID uint64 `protobuf:"varint,1,opt,name=ID,proto3" json:"ID,omitempty"` + MachineKey string `protobuf:"bytes,2,opt,name=MachineKey,proto3" json:"MachineKey,omitempty"` + NodeKey string `protobuf:"bytes,3,opt,name=NodeKey,proto3" json:"NodeKey,omitempty"` + DiscoKey string `protobuf:"bytes,4,opt,name=DiscoKey,proto3" json:"DiscoKey,omitempty"` + IPAddress string `protobuf:"bytes,5,opt,name=IPAddress,proto3" json:"IPAddress,omitempty"` + Name string `protobuf:"bytes,6,opt,name=Name,proto3" json:"Name,omitempty"` + NamespaceID uint32 `protobuf:"varint,7,opt,name=NamespaceID,proto3" json:"NamespaceID,omitempty"` + Registered bool `protobuf:"varint,8,opt,name=Registered,proto3" json:"Registered,omitempty"` + RegisterMethod RegisterMethod `protobuf:"varint,9,opt,name=RegisterMethod,proto3,enum=headscale.v1.RegisterMethod" json:"RegisterMethod,omitempty"` + AuthKeyID uint32 `protobuf:"varint,10,opt,name=AuthKeyID,proto3" json:"AuthKeyID,omitempty"` + AuthKey *PreAuthKey `protobuf:"bytes,11,opt,name=AuthKey,proto3" json:"AuthKey,omitempty"` + LastSeen *timestamppb.Timestamp `protobuf:"bytes,12,opt,name=LastSeen,proto3" json:"LastSeen,omitempty"` + LastSuccessfulUpdate *timestamppb.Timestamp `protobuf:"bytes,13,opt,name=LastSuccessfulUpdate,proto3" json:"LastSuccessfulUpdate,omitempty"` + Expiry *timestamppb.Timestamp `protobuf:"bytes,14,opt,name=Expiry,proto3" json:"Expiry,omitempty"` + HostInfo []byte `protobuf:"bytes,15,opt,name=HostInfo,proto3" json:"HostInfo,omitempty"` + Endpoints []byte `protobuf:"bytes,16,opt,name=Endpoints,proto3" json:"Endpoints,omitempty"` + EnabledRoutes []byte `protobuf:"bytes,17,opt,name=EnabledRoutes,proto3" json:"EnabledRoutes,omitempty"` + CreatedAt *timestamppb.Timestamp `protobuf:"bytes,18,opt,name=CreatedAt,proto3" json:"CreatedAt,omitempty"` + UpdatedAt *timestamppb.Timestamp `protobuf:"bytes,19,opt,name=UpdatedAt,proto3" json:"UpdatedAt,omitempty"` + DeletedAt *timestamppb.Timestamp `protobuf:"bytes,20,opt,name=DeletedAt,proto3" json:"DeletedAt,omitempty"` +} + +func (x *Machine) Reset() { + *x = Machine{} + if protoimpl.UnsafeEnabled { + mi := &file_v1_headscale_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Machine) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Machine) ProtoMessage() {} + +func (x *Machine) ProtoReflect() protoreflect.Message { + mi := &file_v1_headscale_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Machine.ProtoReflect.Descriptor instead. +func (*Machine) Descriptor() ([]byte, []int) { + return file_v1_headscale_proto_rawDescGZIP(), []int{3} +} + +func (x *Machine) GetID() uint64 { + if x != nil { + return x.ID + } + return 0 +} + +func (x *Machine) GetMachineKey() string { + if x != nil { + return x.MachineKey + } + return "" +} + +func (x *Machine) GetNodeKey() string { + if x != nil { + return x.NodeKey + } + return "" +} + +func (x *Machine) GetDiscoKey() string { + if x != nil { + return x.DiscoKey + } + return "" +} + +func (x *Machine) GetIPAddress() string { + if x != nil { + return x.IPAddress + } + return "" +} + +func (x *Machine) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *Machine) GetNamespaceID() uint32 { + if x != nil { + return x.NamespaceID + } + return 0 +} + +func (x *Machine) GetRegistered() bool { + if x != nil { + return x.Registered + } + return false +} + +func (x *Machine) GetRegisterMethod() RegisterMethod { + if x != nil { + return x.RegisterMethod + } + return RegisterMethod_AUTH_KEY +} + +func (x *Machine) GetAuthKeyID() uint32 { + if x != nil { + return x.AuthKeyID + } + return 0 +} + +func (x *Machine) GetAuthKey() *PreAuthKey { + if x != nil { + return x.AuthKey + } + return nil +} + +func (x *Machine) GetLastSeen() *timestamppb.Timestamp { + if x != nil { + return x.LastSeen + } + return nil +} + +func (x *Machine) GetLastSuccessfulUpdate() *timestamppb.Timestamp { + if x != nil { + return x.LastSuccessfulUpdate + } + return nil +} + +func (x *Machine) GetExpiry() *timestamppb.Timestamp { + if x != nil { + return x.Expiry + } + return nil +} + +func (x *Machine) GetHostInfo() []byte { + if x != nil { + return x.HostInfo + } + return nil +} + +func (x *Machine) GetEndpoints() []byte { + if x != nil { + return x.Endpoints + } + return nil +} + +func (x *Machine) GetEnabledRoutes() []byte { + if x != nil { + return x.EnabledRoutes + } + return nil +} + +func (x *Machine) GetCreatedAt() *timestamppb.Timestamp { + if x != nil { + return x.CreatedAt + } + return nil +} + +func (x *Machine) GetUpdatedAt() *timestamppb.Timestamp { + if x != nil { + return x.UpdatedAt + } + return nil +} + +func (x *Machine) GetDeletedAt() *timestamppb.Timestamp { + if x != nil { + return x.DeletedAt + } + return nil +} + +var File_v1_headscale_proto protoreflect.FileDescriptor + +var file_v1_headscale_proto_rawDesc = []byte{ + 0x0a, 0x12, 0x76, 0x31, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0c, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, + 0x76, 0x31, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, + 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x1a, 0x12, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x67, 0x6f, 0x72, 0x6d, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x1f, 0x0a, 0x09, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0xcb, 0x02, 0x0a, 0x0a, 0x50, 0x72, 0x65, 0x41, 0x75, + 0x74, 0x68, 0x4b, 0x65, 0x79, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x04, 0x52, 0x02, 0x49, 0x44, 0x12, 0x10, 0x0a, 0x03, 0x4b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x03, 0x4b, 0x65, 0x79, 0x12, 0x20, 0x0a, 0x0b, 0x4e, 0x61, 0x6d, 0x65, 0x73, + 0x70, 0x61, 0x63, 0x65, 0x49, 0x44, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x4e, 0x61, + 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x49, 0x44, 0x12, 0x35, 0x0a, 0x09, 0x4e, 0x61, 0x6d, + 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x68, + 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x61, 0x6d, 0x65, + 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x09, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, + 0x12, 0x1a, 0x0a, 0x08, 0x52, 0x65, 0x75, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x08, 0x52, 0x65, 0x75, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x1c, 0x0a, 0x09, + 0x45, 0x70, 0x68, 0x65, 0x6d, 0x65, 0x72, 0x61, 0x6c, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x09, 0x45, 0x70, 0x68, 0x65, 0x6d, 0x65, 0x72, 0x61, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x55, 0x73, + 0x65, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x04, 0x55, 0x73, 0x65, 0x64, 0x12, 0x38, + 0x0a, 0x09, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x43, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x3a, 0x0a, 0x0a, 0x45, 0x78, 0x70, 0x69, + 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, + 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0a, 0x45, 0x78, 0x70, 0x69, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x32, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x4d, 0x61, 0x63, 0x68, 0x69, + 0x6e, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x6d, 0x61, 0x63, + 0x68, 0x69, 0x6e, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x6d, + 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x49, 0x64, 0x22, 0xcd, 0x06, 0x0a, 0x07, 0x4d, 0x61, 0x63, + 0x68, 0x69, 0x6e, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, + 0x52, 0x02, 0x49, 0x44, 0x12, 0x1e, 0x0a, 0x0a, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x4b, + 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, + 0x65, 0x4b, 0x65, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x4e, 0x6f, 0x64, 0x65, 0x4b, 0x65, 0x79, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x4e, 0x6f, 0x64, 0x65, 0x4b, 0x65, 0x79, 0x12, 0x1a, + 0x0a, 0x08, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x4b, 0x65, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x08, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x4b, 0x65, 0x79, 0x12, 0x1c, 0x0a, 0x09, 0x49, 0x50, + 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x49, + 0x50, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, + 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, + 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x49, 0x44, 0x18, 0x07, 0x20, 0x01, 0x28, + 0x0d, 0x52, 0x0b, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x49, 0x44, 0x12, 0x1e, + 0x0a, 0x0a, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x65, 0x64, 0x18, 0x08, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x0a, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x65, 0x64, 0x12, 0x44, + 0x0a, 0x0e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, + 0x18, 0x09, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1c, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, + 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x4d, 0x65, + 0x74, 0x68, 0x6f, 0x64, 0x52, 0x0e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x4d, 0x65, + 0x74, 0x68, 0x6f, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x41, 0x75, 0x74, 0x68, 0x4b, 0x65, 0x79, 0x49, + 0x44, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x41, 0x75, 0x74, 0x68, 0x4b, 0x65, 0x79, + 0x49, 0x44, 0x12, 0x32, 0x0a, 0x07, 0x41, 0x75, 0x74, 0x68, 0x4b, 0x65, 0x79, 0x18, 0x0b, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, + 0x76, 0x31, 0x2e, 0x50, 0x72, 0x65, 0x41, 0x75, 0x74, 0x68, 0x4b, 0x65, 0x79, 0x52, 0x07, 0x41, + 0x75, 0x74, 0x68, 0x4b, 0x65, 0x79, 0x12, 0x36, 0x0a, 0x08, 0x4c, 0x61, 0x73, 0x74, 0x53, 0x65, + 0x65, 0x6e, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, + 0x74, 0x61, 0x6d, 0x70, 0x52, 0x08, 0x4c, 0x61, 0x73, 0x74, 0x53, 0x65, 0x65, 0x6e, 0x12, 0x4e, + 0x0a, 0x14, 0x4c, 0x61, 0x73, 0x74, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x66, 0x75, 0x6c, + 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, + 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x14, 0x4c, 0x61, 0x73, 0x74, 0x53, 0x75, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x66, 0x75, 0x6c, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x32, + 0x0a, 0x06, 0x45, 0x78, 0x70, 0x69, 0x72, 0x79, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x06, 0x45, 0x78, 0x70, 0x69, + 0x72, 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x48, 0x6f, 0x73, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x18, 0x0f, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x48, 0x6f, 0x73, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1c, + 0x0a, 0x09, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x18, 0x10, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x09, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x12, 0x24, 0x0a, 0x0d, + 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x18, 0x11, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x0d, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x52, 0x6f, 0x75, 0x74, + 0x65, 0x73, 0x12, 0x38, 0x0a, 0x09, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x18, + 0x12, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, + 0x70, 0x52, 0x09, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x38, 0x0a, 0x09, + 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x18, 0x13, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x55, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x38, 0x0a, 0x09, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, + 0x64, 0x41, 0x74, 0x18, 0x14, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, + 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x41, 0x74, + 0x3a, 0x06, 0xba, 0xb9, 0x19, 0x02, 0x08, 0x01, 0x2a, 0x31, 0x0a, 0x0e, 0x52, 0x65, 0x67, 0x69, + 0x73, 0x74, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, 0x0c, 0x0a, 0x08, 0x41, 0x55, + 0x54, 0x48, 0x5f, 0x4b, 0x45, 0x59, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x43, 0x4c, 0x49, 0x10, + 0x01, 0x12, 0x08, 0x0a, 0x04, 0x4f, 0x49, 0x44, 0x43, 0x10, 0x02, 0x32, 0x7e, 0x0a, 0x10, 0x48, + 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, + 0x6a, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x12, 0x1f, 0x2e, + 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, + 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x15, + 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x61, + 0x63, 0x68, 0x69, 0x6e, 0x65, 0x22, 0x24, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1e, 0x12, 0x1c, 0x2f, + 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x2f, 0x7b, + 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x42, 0x29, 0x5a, 0x27, 0x67, + 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6a, 0x75, 0x61, 0x6e, 0x66, 0x6f, + 0x6e, 0x74, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2f, 0x67, 0x65, 0x6e, + 0x2f, 0x67, 0x6f, 0x2f, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_v1_headscale_proto_rawDescOnce sync.Once + file_v1_headscale_proto_rawDescData = file_v1_headscale_proto_rawDesc +) + +func file_v1_headscale_proto_rawDescGZIP() []byte { + file_v1_headscale_proto_rawDescOnce.Do(func() { + file_v1_headscale_proto_rawDescData = protoimpl.X.CompressGZIP(file_v1_headscale_proto_rawDescData) + }) + return file_v1_headscale_proto_rawDescData +} + +var file_v1_headscale_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_v1_headscale_proto_msgTypes = make([]protoimpl.MessageInfo, 4) +var file_v1_headscale_proto_goTypes = []interface{}{ + (RegisterMethod)(0), // 0: headscale.v1.RegisterMethod + (*Namespace)(nil), // 1: headscale.v1.Namespace + (*PreAuthKey)(nil), // 2: headscale.v1.PreAuthKey + (*GetMachineRequest)(nil), // 3: headscale.v1.GetMachineRequest + (*Machine)(nil), // 4: headscale.v1.Machine + (*timestamppb.Timestamp)(nil), // 5: google.protobuf.Timestamp +} +var file_v1_headscale_proto_depIdxs = []int32{ + 1, // 0: headscale.v1.PreAuthKey.Namespace:type_name -> headscale.v1.Namespace + 5, // 1: headscale.v1.PreAuthKey.CreatedAt:type_name -> google.protobuf.Timestamp + 5, // 2: headscale.v1.PreAuthKey.Expiration:type_name -> google.protobuf.Timestamp + 0, // 3: headscale.v1.Machine.RegisterMethod:type_name -> headscale.v1.RegisterMethod + 2, // 4: headscale.v1.Machine.AuthKey:type_name -> headscale.v1.PreAuthKey + 5, // 5: headscale.v1.Machine.LastSeen:type_name -> google.protobuf.Timestamp + 5, // 6: headscale.v1.Machine.LastSuccessfulUpdate:type_name -> google.protobuf.Timestamp + 5, // 7: headscale.v1.Machine.Expiry:type_name -> google.protobuf.Timestamp + 5, // 8: headscale.v1.Machine.CreatedAt:type_name -> google.protobuf.Timestamp + 5, // 9: headscale.v1.Machine.UpdatedAt:type_name -> google.protobuf.Timestamp + 5, // 10: headscale.v1.Machine.DeletedAt:type_name -> google.protobuf.Timestamp + 3, // 11: headscale.v1.HeadscaleService.GetMachine:input_type -> headscale.v1.GetMachineRequest + 4, // 12: headscale.v1.HeadscaleService.GetMachine:output_type -> headscale.v1.Machine + 12, // [12:13] is the sub-list for method output_type + 11, // [11:12] is the sub-list for method input_type + 11, // [11:11] is the sub-list for extension type_name + 11, // [11:11] is the sub-list for extension extendee + 0, // [0:11] is the sub-list for field type_name +} + +func init() { file_v1_headscale_proto_init() } +func file_v1_headscale_proto_init() { + if File_v1_headscale_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_v1_headscale_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Namespace); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_v1_headscale_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PreAuthKey); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_v1_headscale_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetMachineRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_v1_headscale_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Machine); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_v1_headscale_proto_rawDesc, + NumEnums: 1, + NumMessages: 4, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_v1_headscale_proto_goTypes, + DependencyIndexes: file_v1_headscale_proto_depIdxs, + EnumInfos: file_v1_headscale_proto_enumTypes, + MessageInfos: file_v1_headscale_proto_msgTypes, + }.Build() + File_v1_headscale_proto = out.File + file_v1_headscale_proto_rawDesc = nil + file_v1_headscale_proto_goTypes = nil + file_v1_headscale_proto_depIdxs = nil +} diff --git a/gen/go/v1/headscale.pb.gw.go b/gen/go/v1/headscale.pb.gw.go new file mode 100644 index 00000000..4ae6db39 --- /dev/null +++ b/gen/go/v1/headscale.pb.gw.go @@ -0,0 +1,185 @@ +// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT. +// source: v1/headscale.proto + +/* +Package v1 is a reverse proxy. + +It translates gRPC into RESTful JSON APIs. +*/ +package v1 + +import ( + "context" + "io" + "net/http" + + "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" + "github.com/grpc-ecosystem/grpc-gateway/v2/utilities" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/grpclog" + "google.golang.org/grpc/metadata" + "google.golang.org/grpc/status" + "google.golang.org/protobuf/proto" +) + +// Suppress "imported and not used" errors +var _ codes.Code +var _ io.Reader +var _ status.Status +var _ = runtime.String +var _ = utilities.NewDoubleArray +var _ = metadata.Join + +func request_HeadscaleService_GetMachine_0(ctx context.Context, marshaler runtime.Marshaler, client HeadscaleServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq GetMachineRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["machine_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "machine_id") + } + + protoReq.MachineId, err = runtime.Uint64(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "machine_id", err) + } + + msg, err := client.GetMachine(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_HeadscaleService_GetMachine_0(ctx context.Context, marshaler runtime.Marshaler, server HeadscaleServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq GetMachineRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["machine_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "machine_id") + } + + protoReq.MachineId, err = runtime.Uint64(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "machine_id", err) + } + + msg, err := server.GetMachine(ctx, &protoReq) + return msg, metadata, err + +} + +// RegisterHeadscaleServiceHandlerServer registers the http handlers for service HeadscaleService to "mux". +// UnaryRPC :call HeadscaleServiceServer directly. +// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. +// Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterHeadscaleServiceHandlerFromEndpoint instead. +func RegisterHeadscaleServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux, server HeadscaleServiceServer) error { + + mux.Handle("GET", pattern_HeadscaleService_GetMachine_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/headscale.v1.HeadscaleService/GetMachine", runtime.WithHTTPPathPattern("/api/v1/machine/{machine_id}")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_HeadscaleService_GetMachine_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_HeadscaleService_GetMachine_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +// RegisterHeadscaleServiceHandlerFromEndpoint is same as RegisterHeadscaleServiceHandler but +// automatically dials to "endpoint" and closes the connection when "ctx" gets done. +func RegisterHeadscaleServiceHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) { + conn, err := grpc.Dial(endpoint, opts...) + if err != nil { + return err + } + defer func() { + if err != nil { + if cerr := conn.Close(); cerr != nil { + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) + } + return + } + go func() { + <-ctx.Done() + if cerr := conn.Close(); cerr != nil { + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) + } + }() + }() + + return RegisterHeadscaleServiceHandler(ctx, mux, conn) +} + +// RegisterHeadscaleServiceHandler registers the http handlers for service HeadscaleService to "mux". +// The handlers forward requests to the grpc endpoint over "conn". +func RegisterHeadscaleServiceHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error { + return RegisterHeadscaleServiceHandlerClient(ctx, mux, NewHeadscaleServiceClient(conn)) +} + +// RegisterHeadscaleServiceHandlerClient registers the http handlers for service HeadscaleService +// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "HeadscaleServiceClient". +// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "HeadscaleServiceClient" +// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in +// "HeadscaleServiceClient" to call the correct interceptors. +func RegisterHeadscaleServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, client HeadscaleServiceClient) error { + + mux.Handle("GET", pattern_HeadscaleService_GetMachine_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req, "/headscale.v1.HeadscaleService/GetMachine", runtime.WithHTTPPathPattern("/api/v1/machine/{machine_id}")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_HeadscaleService_GetMachine_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_HeadscaleService_GetMachine_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +var ( + pattern_HeadscaleService_GetMachine_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"api", "v1", "machine", "machine_id"}, "")) +) + +var ( + forward_HeadscaleService_GetMachine_0 = runtime.ForwardResponseMessage +) diff --git a/gen/go/v1/headscale_grpc.pb.go b/gen/go/v1/headscale_grpc.pb.go new file mode 100644 index 00000000..3028d183 --- /dev/null +++ b/gen/go/v1/headscale_grpc.pb.go @@ -0,0 +1,101 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. + +package v1 + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +// HeadscaleServiceClient is the client API for HeadscaleService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type HeadscaleServiceClient interface { + GetMachine(ctx context.Context, in *GetMachineRequest, opts ...grpc.CallOption) (*Machine, error) +} + +type headscaleServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewHeadscaleServiceClient(cc grpc.ClientConnInterface) HeadscaleServiceClient { + return &headscaleServiceClient{cc} +} + +func (c *headscaleServiceClient) GetMachine(ctx context.Context, in *GetMachineRequest, opts ...grpc.CallOption) (*Machine, error) { + out := new(Machine) + err := c.cc.Invoke(ctx, "/headscale.v1.HeadscaleService/GetMachine", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// HeadscaleServiceServer is the server API for HeadscaleService service. +// All implementations must embed UnimplementedHeadscaleServiceServer +// for forward compatibility +type HeadscaleServiceServer interface { + GetMachine(context.Context, *GetMachineRequest) (*Machine, error) + mustEmbedUnimplementedHeadscaleServiceServer() +} + +// UnimplementedHeadscaleServiceServer must be embedded to have forward compatible implementations. +type UnimplementedHeadscaleServiceServer struct { +} + +func (UnimplementedHeadscaleServiceServer) GetMachine(context.Context, *GetMachineRequest) (*Machine, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetMachine not implemented") +} +func (UnimplementedHeadscaleServiceServer) mustEmbedUnimplementedHeadscaleServiceServer() {} + +// UnsafeHeadscaleServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to HeadscaleServiceServer will +// result in compilation errors. +type UnsafeHeadscaleServiceServer interface { + mustEmbedUnimplementedHeadscaleServiceServer() +} + +func RegisterHeadscaleServiceServer(s grpc.ServiceRegistrar, srv HeadscaleServiceServer) { + s.RegisterService(&HeadscaleService_ServiceDesc, srv) +} + +func _HeadscaleService_GetMachine_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetMachineRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(HeadscaleServiceServer).GetMachine(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/headscale.v1.HeadscaleService/GetMachine", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(HeadscaleServiceServer).GetMachine(ctx, req.(*GetMachineRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// HeadscaleService_ServiceDesc is the grpc.ServiceDesc for HeadscaleService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var HeadscaleService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "headscale.v1.HeadscaleService", + HandlerType: (*HeadscaleServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "GetMachine", + Handler: _HeadscaleService_GetMachine_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "v1/headscale.proto", +} diff --git a/gen/openapiv2/v1/headscale.swagger.json b/gen/openapiv2/v1/headscale.swagger.json new file mode 100644 index 00000000..a20225d3 --- /dev/null +++ b/gen/openapiv2/v1/headscale.swagger.json @@ -0,0 +1,210 @@ +{ + "swagger": "2.0", + "info": { + "title": "v1/headscale.proto", + "version": "version not set" + }, + "tags": [ + { + "name": "HeadscaleService" + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "paths": { + "/api/v1/machine/{machineId}": { + "get": { + "operationId": "HeadscaleService_GetMachine", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1Machine" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "machineId", + "in": "path", + "required": true, + "type": "string", + "format": "uint64" + } + ], + "tags": [ + "HeadscaleService" + ] + } + } + }, + "definitions": { + "protobufAny": { + "type": "object", + "properties": { + "@type": { + "type": "string" + } + }, + "additionalProperties": {} + }, + "rpcStatus": { + "type": "object", + "properties": { + "code": { + "type": "integer", + "format": "int32" + }, + "message": { + "type": "string" + }, + "details": { + "type": "array", + "items": { + "$ref": "#/definitions/protobufAny" + } + } + } + }, + "v1Machine": { + "type": "object", + "properties": { + "ID": { + "type": "string", + "format": "uint64" + }, + "MachineKey": { + "type": "string" + }, + "NodeKey": { + "type": "string" + }, + "DiscoKey": { + "type": "string" + }, + "IPAddress": { + "type": "string" + }, + "Name": { + "type": "string" + }, + "NamespaceID": { + "type": "integer", + "format": "int64" + }, + "Registered": { + "type": "boolean" + }, + "RegisterMethod": { + "$ref": "#/definitions/v1RegisterMethod" + }, + "AuthKeyID": { + "type": "integer", + "format": "int64" + }, + "AuthKey": { + "$ref": "#/definitions/v1PreAuthKey" + }, + "LastSeen": { + "type": "string", + "format": "date-time" + }, + "LastSuccessfulUpdate": { + "type": "string", + "format": "date-time" + }, + "Expiry": { + "type": "string", + "format": "date-time" + }, + "HostInfo": { + "type": "string", + "format": "byte" + }, + "Endpoints": { + "type": "string", + "format": "byte" + }, + "EnabledRoutes": { + "type": "string", + "format": "byte" + }, + "CreatedAt": { + "type": "string", + "format": "date-time" + }, + "UpdatedAt": { + "type": "string", + "format": "date-time" + }, + "DeletedAt": { + "type": "string", + "format": "date-time" + } + } + }, + "v1Namespace": { + "type": "object", + "properties": { + "Name": { + "type": "string" + } + } + }, + "v1PreAuthKey": { + "type": "object", + "properties": { + "ID": { + "type": "string", + "format": "uint64" + }, + "Key": { + "type": "string" + }, + "NamespaceID": { + "type": "integer", + "format": "int64" + }, + "Namespace": { + "$ref": "#/definitions/v1Namespace" + }, + "Reusable": { + "type": "boolean" + }, + "Ephemeral": { + "type": "boolean" + }, + "Used": { + "type": "boolean" + }, + "CreatedAt": { + "type": "string", + "format": "date-time" + }, + "Expiration": { + "type": "string", + "format": "date-time" + } + } + }, + "v1RegisterMethod": { + "type": "string", + "enum": [ + "AUTH_KEY", + "CLI", + "OIDC" + ], + "default": "AUTH_KEY" + } + } +} From 2d9271909526e0ccdef9a750e673e34e9b3c68e3 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Wed, 27 Oct 2021 06:48:30 +0000 Subject: [PATCH 028/300] Dont try to generate code on every make build --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 3ce7025c..9f5b1faa 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ # Calculate version version = $(shell ./scripts/version-at-commit.sh) -build: generate +build: go build -ldflags "-s -w -X github.com/juanfont/headscale/cmd/headscale/cli.Version=$(version)" cmd/headscale/headscale.go dev: lint test build From 6369cea10e33bd1505966777ee3696db3ef1ba3f Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Wed, 27 Oct 2021 06:58:16 +0000 Subject: [PATCH 029/300] Remove golint, its deprecated This commit removed `golint`, its deprecated: https://github.com/golang/lint and golangci-lint has overlapping features. --- Makefile | 1 - 1 file changed, 1 deletion(-) diff --git a/Makefile b/Makefile index 9f5b1faa..6bce4519 100644 --- a/Makefile +++ b/Makefile @@ -19,7 +19,6 @@ coverprofile_html: go tool cover -html=coverage.out lint: - golint golangci-lint run --timeout 5m compress: build From acd9ebbdf882937b09e45d19841a58e68ea51eb5 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Wed, 27 Oct 2021 07:06:39 +0000 Subject: [PATCH 030/300] Let lint ignore grpcv1.go as it is placeholder --- Makefile | 2 +- grpcv1.go | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 6bce4519..9605955c 100644 --- a/Makefile +++ b/Makefile @@ -19,7 +19,7 @@ coverprofile_html: go tool cover -html=coverage.out lint: - golangci-lint run --timeout 5m + golangci-lint run compress: build upx --brute headscale diff --git a/grpcv1.go b/grpcv1.go index d9bbf531..5fc2e1c8 100644 --- a/grpcv1.go +++ b/grpcv1.go @@ -1,3 +1,4 @@ +//nolint package headscale import ( From f7793721547291d1572ece96709c0695b73e10da Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Wed, 27 Oct 2021 07:07:19 +0000 Subject: [PATCH 031/300] Add golangcilint config --- .golangci.yaml | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .golangci.yaml diff --git a/.golangci.yaml b/.golangci.yaml new file mode 100644 index 00000000..8d05e483 --- /dev/null +++ b/.golangci.yaml @@ -0,0 +1,3 @@ +--- +run: + timeout: 5m From c9bd25d05c30c809624fe0bc114a5aed1a75c376 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Wed, 27 Oct 2021 07:07:44 +0000 Subject: [PATCH 032/300] Remove golint from github actions --- .github/workflows/lint.yml | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index c0286571..6b561d24 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -18,22 +18,3 @@ jobs: # below, but it's still much faster in the end than installing # golangci-lint manually in the `Run lint` step. - uses: golangci/golangci-lint-action@v2 - with: - args: --timeout 5m - - # Setup Go - - name: Setup Go - uses: actions/setup-go@v2 - with: - go-version: "1.16.3" # The Go version to download (if necessary) and use. - - # Install all the dependencies - - name: Install dependencies - run: | - go version - go install golang.org/x/lint/golint@latest - sudo apt update - sudo apt install -y make - - - name: Run lint - run: make lint From e91174e83f737eb013e6f3789caaa72cab970764 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Wed, 27 Oct 2021 07:08:24 +0000 Subject: [PATCH 033/300] Add gen explicitly to skip list --- .golangci.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.golangci.yaml b/.golangci.yaml index 8d05e483..a97c2bb5 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -1,3 +1,7 @@ --- run: timeout: 5m + +issues: + skip-dirs: + - gen From 5054ed41ac9caae5952a1095533ee4752e428c16 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Wed, 27 Oct 2021 07:10:32 +0000 Subject: [PATCH 034/300] Make ci lint fix if it can --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 9605955c..5fdd2a53 100644 --- a/Makefile +++ b/Makefile @@ -19,7 +19,7 @@ coverprofile_html: go tool cover -html=coverage.out lint: - golangci-lint run + golangci-lint run --fix compress: build upx --brute headscale From d086cf469137f8116579e776daf010a4e6c662d8 Mon Sep 17 00:00:00 2001 From: Ward Vandewege Date: Wed, 27 Oct 2021 17:51:42 -0400 Subject: [PATCH 035/300] Move the namespace argument back to a flag for the share and unshare commands. --- cmd/headscale/cli/nodes.go | 33 ++++++++++++++++++++++++++------- integration_test.go | 2 +- 2 files changed, 27 insertions(+), 8 deletions(-) diff --git a/cmd/headscale/cli/nodes.go b/cmd/headscale/cli/nodes.go index ba843f70..1db56191 100644 --- a/cmd/headscale/cli/nodes.go +++ b/cmd/headscale/cli/nodes.go @@ -19,14 +19,28 @@ func init() { rootCmd.AddCommand(nodeCmd) listNodesCmd.Flags().StringP("namespace", "n", "", "Filter by namespace") nodeCmd.AddCommand(listNodesCmd) - registerNodeCmd.Flags().StringP("namespace", "n", "", "Filter by namespace") + + registerNodeCmd.Flags().StringP("namespace", "n", "", "Namespace") err := registerNodeCmd.MarkFlagRequired("namespace") if err != nil { log.Fatalf(err.Error()) } nodeCmd.AddCommand(registerNodeCmd) + nodeCmd.AddCommand(deleteNodeCmd) + + shareMachineCmd.Flags().StringP("namespace", "n", "", "Namespace") + err = shareMachineCmd.MarkFlagRequired("namespace") + if err != nil { + log.Fatalf(err.Error()) + } nodeCmd.AddCommand(shareMachineCmd) + + unshareMachineCmd.Flags().StringP("namespace", "n", "", "Namespace") + err = unshareMachineCmd.MarkFlagRequired("namespace") + if err != nil { + log.Fatalf(err.Error()) + } nodeCmd.AddCommand(unshareMachineCmd) } @@ -199,6 +213,11 @@ var deleteNodeCmd = &cobra.Command{ } func sharingWorker(cmd *cobra.Command, args []string) (*headscale.Headscale, string, *headscale.Machine, *headscale.Namespace) { + n, err := cmd.Flags().GetString("namespace") + if err != nil { + log.Fatalf("Error getting namespace: %s", err) + } + output, _ := cmd.Flags().GetString("output") h, err := getHeadscaleApp() @@ -206,9 +225,9 @@ func sharingWorker(cmd *cobra.Command, args []string) (*headscale.Headscale, str log.Fatalf("Error initializing: %s", err) } - namespace, err := h.GetNamespace(args[1]) + namespace, err := h.GetNamespace(n) if err != nil { - log.Fatalf("Error fetching namespace %s: %s", args[1], err) + log.Fatalf("Error fetching namespace %s: %s", n, err) } id, err := strconv.Atoi(args[0]) @@ -224,10 +243,10 @@ func sharingWorker(cmd *cobra.Command, args []string) (*headscale.Headscale, str } var shareMachineCmd = &cobra.Command{ - Use: "share ID namespace", + Use: "share ID", Short: "Shares a node from the current namespace to the specified one", Args: func(cmd *cobra.Command, args []string) error { - if len(args) < 2 { + if len(args) < 1 { return fmt.Errorf("missing parameters") } return nil @@ -249,10 +268,10 @@ var shareMachineCmd = &cobra.Command{ } var unshareMachineCmd = &cobra.Command{ - Use: "unshare ID namespace", + Use: "unshare ID", Short: "Unshares a node from the specified namespace", Args: func(cmd *cobra.Command, args []string) error { - if len(args) < 2 { + if len(args) < 1 { return fmt.Errorf("missing parameters") } return nil diff --git a/integration_test.go b/integration_test.go index a1a5e953..7ec75df3 100644 --- a/integration_test.go +++ b/integration_test.go @@ -493,7 +493,7 @@ func (s *IntegrationTestSuite) TestSharedNodes() { result, err := executeCommand( &headscale, - []string{"headscale", "nodes", "share", fmt.Sprint(machine.ID), "main"}, + []string{"headscale", "nodes", "share", fmt.Sprint(machine.ID), "-n", "main"}, []string{}, ) assert.Nil(s.T(), err) From 6c01b86e4ce5cbc36dc012ca2fc86a9856dcef43 Mon Sep 17 00:00:00 2001 From: Ward Vandewege Date: Thu, 28 Oct 2021 08:39:27 -0400 Subject: [PATCH 036/300] Update cmd/headscale/cli/nodes.go Co-authored-by: Kristoffer Dalby --- cmd/headscale/cli/nodes.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd/headscale/cli/nodes.go b/cmd/headscale/cli/nodes.go index 1db56191..0e778bc6 100644 --- a/cmd/headscale/cli/nodes.go +++ b/cmd/headscale/cli/nodes.go @@ -213,7 +213,7 @@ var deleteNodeCmd = &cobra.Command{ } func sharingWorker(cmd *cobra.Command, args []string) (*headscale.Headscale, string, *headscale.Machine, *headscale.Namespace) { - n, err := cmd.Flags().GetString("namespace") + namespaceStr, err := cmd.Flags().GetString("namespace") if err != nil { log.Fatalf("Error getting namespace: %s", err) } @@ -225,7 +225,7 @@ func sharingWorker(cmd *cobra.Command, args []string) (*headscale.Headscale, str log.Fatalf("Error initializing: %s", err) } - namespace, err := h.GetNamespace(n) + namespace, err := h.GetNamespace(namespaceStr) if err != nil { log.Fatalf("Error fetching namespace %s: %s", n, err) } From b00a2729e3b250b30fd995647123e81614ffcd7f Mon Sep 17 00:00:00 2001 From: Ward Vandewege Date: Thu, 28 Oct 2021 08:39:42 -0400 Subject: [PATCH 037/300] Update cmd/headscale/cli/nodes.go Co-authored-by: Kristoffer Dalby --- cmd/headscale/cli/nodes.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd/headscale/cli/nodes.go b/cmd/headscale/cli/nodes.go index 0e778bc6..825ef232 100644 --- a/cmd/headscale/cli/nodes.go +++ b/cmd/headscale/cli/nodes.go @@ -121,8 +121,8 @@ var listNodesCmd = &cobra.Command{ } var allMachines []headscale.Machine - for _, n := range namespaces { - machines, err := h.ListMachinesInNamespace(n.Name) + for _, namespace := range namespaces { + machines, err := h.ListMachinesInNamespace(namespace.Name) if err != nil { log.Fatalf("Error fetching machines: %s", err) } From 25c67cf2aa8a18b4443400cae98d8d7899611293 Mon Sep 17 00:00:00 2001 From: Ward Vandewege Date: Thu, 28 Oct 2021 08:40:30 -0400 Subject: [PATCH 038/300] Update integration_test.go Co-authored-by: Kristoffer Dalby --- integration_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integration_test.go b/integration_test.go index 7ec75df3..524dd32d 100644 --- a/integration_test.go +++ b/integration_test.go @@ -493,7 +493,7 @@ func (s *IntegrationTestSuite) TestSharedNodes() { result, err := executeCommand( &headscale, - []string{"headscale", "nodes", "share", fmt.Sprint(machine.ID), "-n", "main"}, + []string{"headscale", "nodes", "share", fmt.Sprint(machine.ID), "--namespace", "main"}, []string{}, ) assert.Nil(s.T(), err) From f9187bdfc4e1c7c269622a3c595d393d26ae5f8e Mon Sep 17 00:00:00 2001 From: Ward Vandewege Date: Thu, 28 Oct 2021 09:30:41 -0400 Subject: [PATCH 039/300] Switch to named arguments for all `nodes` subcommands. Update docs accordingly. Fix integration test failure. --- api.go | 2 +- cmd/headscale/cli/nodes.go | 64 +++++++++++++++++++------------------- docs/Running.md | 6 ++-- integration_test.go | 2 +- 4 files changed, 37 insertions(+), 37 deletions(-) diff --git a/api.go b/api.go index a31cf529..0c1f3d41 100644 --- a/api.go +++ b/api.go @@ -43,7 +43,7 @@ func (h *Headscale) RegisterWebAPI(c *gin.Context) {

- headscale -n NAMESPACE nodes register %s + headscale -n NAMESPACE nodes register -k %s

diff --git a/cmd/headscale/cli/nodes.go b/cmd/headscale/cli/nodes.go index 825ef232..cdf37efb 100644 --- a/cmd/headscale/cli/nodes.go +++ b/cmd/headscale/cli/nodes.go @@ -25,8 +25,18 @@ func init() { if err != nil { log.Fatalf(err.Error()) } + registerNodeCmd.Flags().StringP("key", "k", "", "Key") + err = registerNodeCmd.MarkFlagRequired("key") + if err != nil { + log.Fatalf(err.Error()) + } nodeCmd.AddCommand(registerNodeCmd) + deleteNodeCmd.Flags().IntP("identifier", "i", 0, "Node identifier (ID)") + err = deleteNodeCmd.MarkFlagRequired("identifier") + if err != nil { + log.Fatalf(err.Error()) + } nodeCmd.AddCommand(deleteNodeCmd) shareMachineCmd.Flags().StringP("namespace", "n", "", "Namespace") @@ -34,6 +44,11 @@ func init() { if err != nil { log.Fatalf(err.Error()) } + shareMachineCmd.Flags().IntP("identifier", "i", 0, "Node identifier (ID)") + err = shareMachineCmd.MarkFlagRequired("identifier") + if err != nil { + log.Fatalf(err.Error()) + } nodeCmd.AddCommand(shareMachineCmd) unshareMachineCmd.Flags().StringP("namespace", "n", "", "Namespace") @@ -41,6 +56,11 @@ func init() { if err != nil { log.Fatalf(err.Error()) } + unshareMachineCmd.Flags().IntP("identifier", "i", 0, "Node identifier (ID)") + err = unshareMachineCmd.MarkFlagRequired("identifier") + if err != nil { + log.Fatalf(err.Error()) + } nodeCmd.AddCommand(unshareMachineCmd) } @@ -50,14 +70,8 @@ var nodeCmd = &cobra.Command{ } var registerNodeCmd = &cobra.Command{ - Use: "register machineID", + Use: "register", Short: "Registers a machine to your network", - Args: func(cmd *cobra.Command, args []string) error { - if len(args) < 1 { - return fmt.Errorf("missing parameters") - } - return nil - }, Run: func(cmd *cobra.Command, args []string) { n, err := cmd.Flags().GetString("namespace") if err != nil { @@ -69,7 +83,11 @@ var registerNodeCmd = &cobra.Command{ if err != nil { log.Fatalf("Error initializing: %s", err) } - m, err := h.RegisterMachine(args[0], n) + machineIDStr, err := cmd.Flags().GetString("key") + if err != nil { + log.Fatalf("Error getting machine ID: %s", err) + } + m, err := h.RegisterMachine(machineIDStr, n) if strings.HasPrefix(o, "json") { JsonOutput(m, err, o) return @@ -157,21 +175,15 @@ var listNodesCmd = &cobra.Command{ } var deleteNodeCmd = &cobra.Command{ - Use: "delete ID", + Use: "delete", Short: "Delete a node", - Args: func(cmd *cobra.Command, args []string) error { - if len(args) < 1 { - return fmt.Errorf("missing parameters") - } - return nil - }, Run: func(cmd *cobra.Command, args []string) { output, _ := cmd.Flags().GetString("output") h, err := getHeadscaleApp() if err != nil { log.Fatalf("Error initializing: %s", err) } - id, err := strconv.Atoi(args[0]) + id, err := cmd.Flags().GetInt("identifier") if err != nil { log.Fatalf("Error converting ID to integer: %s", err) } @@ -227,10 +239,10 @@ func sharingWorker(cmd *cobra.Command, args []string) (*headscale.Headscale, str namespace, err := h.GetNamespace(namespaceStr) if err != nil { - log.Fatalf("Error fetching namespace %s: %s", n, err) + log.Fatalf("Error fetching namespace %s: %s", namespaceStr, err) } - id, err := strconv.Atoi(args[0]) + id, err := cmd.Flags().GetInt("identifier") if err != nil { log.Fatalf("Error converting ID to integer: %s", err) } @@ -243,14 +255,8 @@ func sharingWorker(cmd *cobra.Command, args []string) (*headscale.Headscale, str } var shareMachineCmd = &cobra.Command{ - Use: "share ID", + Use: "share", Short: "Shares a node from the current namespace to the specified one", - Args: func(cmd *cobra.Command, args []string) error { - if len(args) < 1 { - return fmt.Errorf("missing parameters") - } - return nil - }, Run: func(cmd *cobra.Command, args []string) { h, output, machine, namespace := sharingWorker(cmd, args) err := h.AddSharedMachineToNamespace(machine, namespace) @@ -268,14 +274,8 @@ var shareMachineCmd = &cobra.Command{ } var unshareMachineCmd = &cobra.Command{ - Use: "unshare ID", + Use: "unshare", Short: "Unshares a node from the specified namespace", - Args: func(cmd *cobra.Command, args []string) error { - if len(args) < 1 { - return fmt.Errorf("missing parameters") - } - return nil - }, Run: func(cmd *cobra.Command, args []string) { h, output, machine, namespace := sharingWorker(cmd, args) err := h.RemoveSharedMachineFromNamespace(machine, namespace) diff --git a/docs/Running.md b/docs/Running.md index 08373653..dbb8704c 100644 --- a/docs/Running.md +++ b/docs/Running.md @@ -97,7 +97,7 @@ 9. In the server, register your machine to a namespace with the CLI ```shell - headscale -n myfirstnamespace nodes register YOURMACHINEKEY + headscale -n myfirstnamespace nodes register -k YOURMACHINEKEY ``` or docker: ```shell @@ -106,11 +106,11 @@ -v $(pwd)/config.json:/config.json \ -v $(pwd)/derp.yaml:/derp.yaml \ headscale/headscale:x.x.x \ - headscale -n myfirstnamespace nodes register YOURMACHINEKEY + headscale -n myfirstnamespace nodes register -k YOURMACHINEKEY ``` or if your server is already running in docker: ```shell - docker exec headscale -n myfirstnamespace nodes register YOURMACHINEKEY + docker exec headscale -n myfirstnamespace nodes register -k YOURMACHINEKEY ``` Alternatively, you can use Auth Keys to register your machines: diff --git a/integration_test.go b/integration_test.go index 524dd32d..f73d76f6 100644 --- a/integration_test.go +++ b/integration_test.go @@ -493,7 +493,7 @@ func (s *IntegrationTestSuite) TestSharedNodes() { result, err := executeCommand( &headscale, - []string{"headscale", "nodes", "share", fmt.Sprint(machine.ID), "--namespace", "main"}, + []string{"headscale", "nodes", "share", "--identifier", fmt.Sprint(machine.ID), "--namespace", "main"}, []string{}, ) assert.Nil(s.T(), err) From 2d252da221b3db0bb2d605f618d2d685f0035158 Mon Sep 17 00:00:00 2001 From: Raal Goff Date: Fri, 29 Oct 2021 21:35:07 +0800 Subject: [PATCH 040/300] suggested documentation and comments --- api.go | 11 +++++++++-- cmd/headscale/cli/utils.go | 17 ++++++++++------- machine.go | 6 ++++-- 3 files changed, 23 insertions(+), 11 deletions(-) diff --git a/api.go b/api.go index c7ae122c..36af5a06 100644 --- a/api.go +++ b/api.go @@ -111,7 +111,8 @@ func (h *Headscale) RegistrationHandler(c *gin.Context) { // We have the updated key! if m.NodeKey == wgkey.Key(req.NodeKey).HexString() { - // The client sends an Expiry in the past if the client is requesting a logout + // The client sends an Expiry in the past if the client is requesting to expire the key (aka logout) + // https://github.com/tailscale/tailscale/blob/main/tailcfg/tailcfg.go#L648 if !req.Expiry.IsZero() && req.Expiry.UTC().Before(now) { log.Info(). Str("handler", "Registration"). @@ -178,7 +179,13 @@ func (h *Headscale) RegistrationHandler(c *gin.Context) { strings.TrimSuffix(h.cfg.ServerURL, "/"), mKey.HexString()) } - m.RequestedExpiry = &req.Expiry // save the requested expiry time for retrieval later in the authentication flow + // When a client connects, it may request a specific expiry time in its + // RegisterRequest (https://github.com/tailscale/tailscale/blob/main/tailcfg/tailcfg.go#L634) + m.RequestedExpiry = &req.Expiry // RequestedExpiry is used to store the clients requested expiry time since the authentication flow is broken + // into two steps (which cant pass arbitrary data between them easily) and needs to be + // retrieved again after the user has authenticated. After the authentication flow + // completes, RequestedExpiry is copied into Expiry. + h.db.Save(&m) respBody, err := encode(resp, &mKey, h.privateKey) diff --git a/cmd/headscale/cli/utils.go b/cmd/headscale/cli/utils.go index 4a598e77..0ba43b28 100644 --- a/cmd/headscale/cli/utils.go +++ b/cmd/headscale/cli/utils.go @@ -161,14 +161,18 @@ func getHeadscaleApp() (*headscale.Headscale, error) { return nil, err } - // maxMachineRegistrationDuration is the maximum time a client can request for a client registration - maxMachineRegistrationDuration, _ := time.ParseDuration("10h") + // maxMachineRegistrationDuration is the maximum time headscale will allow a client to (optionally) request for + // the machine key expiry time. RegisterRequests with Expiry times that are more than + // maxMachineRegistrationDuration in the future will be clamped to (now + maxMachineRegistrationDuration) + maxMachineRegistrationDuration, _ := time.ParseDuration("10h") // use 10h here because it is the length of a standard business day plus a small amount of leeway if viper.GetDuration("max_machine_registration_duration") >= time.Second { maxMachineRegistrationDuration = viper.GetDuration("max_machine_registration_duration") } - // defaultMachineRegistrationDuration is the default time assigned to a client registration if one is not specified by the client - defaultMachineRegistrationDuration, _ := time.ParseDuration("8h") + // defaultMachineRegistrationDuration is the default time assigned to a machine registration if one is not + // specified by the tailscale client. It is the default amount of time a machine registration is valid for + // (ie the amount of time before the user has to re-authenticate when requesting a connection) + defaultMachineRegistrationDuration, _ := time.ParseDuration("8h") // use 8h here because it's the length of a standard business day if viper.GetDuration("default_machine_registration_duration") >= time.Second { defaultMachineRegistrationDuration = viper.GetDuration("default_machine_registration_duration") } @@ -212,9 +216,8 @@ func getHeadscaleApp() (*headscale.Headscale, error) { ClientSecret: viper.GetString("oidc.client_secret"), }, - MaxMachineRegistrationDuration: maxMachineRegistrationDuration, // the maximum duration a client may request for expiry time - DefaultMachineRegistrationDuration: defaultMachineRegistrationDuration, // if a client does not request a specific expiry time, use this duration - + MaxMachineRegistrationDuration: maxMachineRegistrationDuration, + DefaultMachineRegistrationDuration: defaultMachineRegistrationDuration, } cfg.OIDC.MatchMap = loadOIDCMatchMap() diff --git a/machine.go b/machine.go index a43fa8de..f4ce0afb 100644 --- a/machine.go +++ b/machine.go @@ -36,7 +36,7 @@ type Machine struct { LastSeen *time.Time LastSuccessfulUpdate *time.Time Expiry *time.Time - RequestedExpiry *time.Time // when a client connects, it may request a specific expiry time, use this field to store it + RequestedExpiry *time.Time HostInfo datatypes.JSON Endpoints datatypes.JSON @@ -63,7 +63,9 @@ func (m Machine) isExpired() bool { } // If the Machine is expired, updateMachineExpiry updates the Machine Expiry time to the maximum allowed duration, -// or the default duration if no Expiry time was requested by the client +// or the default duration if no Expiry time was requested by the client. The expiry time here does not (yet) cause +// a client to be disconnected, however they will have to re-auth the machine if they attempt to reconnect after the +// expiry time. func (h *Headscale) updateMachineExpiry(m *Machine) { if m.isExpired() { From 06700c1dc4f69c44f5b49a164a874b1e25355cf9 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Fri, 29 Oct 2021 16:42:56 +0000 Subject: [PATCH 041/300] Setup proto linting --- Makefile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Makefile b/Makefile index 5fdd2a53..92beaefb 100644 --- a/Makefile +++ b/Makefile @@ -21,6 +21,9 @@ coverprofile_html: lint: golangci-lint run --fix +proto-lint: + cd proto/ && buf lint + compress: build upx --brute headscale From 07bbeafa3b2a703f3dd2a6258463b90eef45e886 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Fri, 29 Oct 2021 16:43:10 +0000 Subject: [PATCH 042/300] Fix lint errors, add initial namespace rpc --- gen/go/headscale/v1/rpc.pb.go | 807 ++++++++++++++++++++ gen/go/headscale/v1/rpc.pb.gw.go | 414 ++++++++++ gen/go/headscale/v1/rpc_grpc.pb.go | 209 +++++ gen/go/v1/headscale.pb.go | 702 ----------------- gen/go/v1/headscale.pb.gw.go | 185 ----- gen/go/v1/headscale_grpc.pb.go | 101 --- gen/openapiv2/headscale/v1/rpc.swagger.json | 250 ++++++ gen/openapiv2/v1/headscale.swagger.json | 210 ----- proto/headscale/v1/rpc.proto | 106 +++ proto/v1/headscale.proto | 71 -- 10 files changed, 1786 insertions(+), 1269 deletions(-) create mode 100644 gen/go/headscale/v1/rpc.pb.go create mode 100644 gen/go/headscale/v1/rpc.pb.gw.go create mode 100644 gen/go/headscale/v1/rpc_grpc.pb.go delete mode 100644 gen/go/v1/headscale.pb.go delete mode 100644 gen/go/v1/headscale.pb.gw.go delete mode 100644 gen/go/v1/headscale_grpc.pb.go create mode 100644 gen/openapiv2/headscale/v1/rpc.swagger.json delete mode 100644 gen/openapiv2/v1/headscale.swagger.json create mode 100644 proto/headscale/v1/rpc.proto delete mode 100644 proto/v1/headscale.proto diff --git a/gen/go/headscale/v1/rpc.pb.go b/gen/go/headscale/v1/rpc.pb.go new file mode 100644 index 00000000..b510b961 --- /dev/null +++ b/gen/go/headscale/v1/rpc.pb.go @@ -0,0 +1,807 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.27.1 +// protoc v3.18.1 +// source: headscale/v1/rpc.proto + +package v1 + +import ( + _ "google.golang.org/genproto/googleapis/api/annotations" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + timestamppb "google.golang.org/protobuf/types/known/timestamppb" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type RegisterMethod int32 + +const ( + RegisterMethod_REGISTER_METHOD_UNSPECIFIED RegisterMethod = 0 + RegisterMethod_REGISTER_METHOD_AUTH_KEY RegisterMethod = 1 + RegisterMethod_REGISTER_METHOD_CLI RegisterMethod = 2 + RegisterMethod_REGISTER_METHOD_OIDC RegisterMethod = 3 +) + +// Enum value maps for RegisterMethod. +var ( + RegisterMethod_name = map[int32]string{ + 0: "REGISTER_METHOD_UNSPECIFIED", + 1: "REGISTER_METHOD_AUTH_KEY", + 2: "REGISTER_METHOD_CLI", + 3: "REGISTER_METHOD_OIDC", + } + RegisterMethod_value = map[string]int32{ + "REGISTER_METHOD_UNSPECIFIED": 0, + "REGISTER_METHOD_AUTH_KEY": 1, + "REGISTER_METHOD_CLI": 2, + "REGISTER_METHOD_OIDC": 3, + } +) + +func (x RegisterMethod) Enum() *RegisterMethod { + p := new(RegisterMethod) + *p = x + return p +} + +func (x RegisterMethod) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (RegisterMethod) Descriptor() protoreflect.EnumDescriptor { + return file_headscale_v1_rpc_proto_enumTypes[0].Descriptor() +} + +func (RegisterMethod) Type() protoreflect.EnumType { + return &file_headscale_v1_rpc_proto_enumTypes[0] +} + +func (x RegisterMethod) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use RegisterMethod.Descriptor instead. +func (RegisterMethod) EnumDescriptor() ([]byte, []int) { + return file_headscale_v1_rpc_proto_rawDescGZIP(), []int{0} +} + +type GetMachineRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + MachineId uint64 `protobuf:"varint,1,opt,name=machine_id,json=machineId,proto3" json:"machine_id,omitempty"` +} + +func (x *GetMachineRequest) Reset() { + *x = GetMachineRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_headscale_v1_rpc_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetMachineRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetMachineRequest) ProtoMessage() {} + +func (x *GetMachineRequest) ProtoReflect() protoreflect.Message { + mi := &file_headscale_v1_rpc_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetMachineRequest.ProtoReflect.Descriptor instead. +func (*GetMachineRequest) Descriptor() ([]byte, []int) { + return file_headscale_v1_rpc_proto_rawDescGZIP(), []int{0} +} + +func (x *GetMachineRequest) GetMachineId() uint64 { + if x != nil { + return x.MachineId + } + return 0 +} + +type GetMachineResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id uint64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` + MachineKey string `protobuf:"bytes,2,opt,name=machine_key,json=machineKey,proto3" json:"machine_key,omitempty"` + NodeKey string `protobuf:"bytes,3,opt,name=node_key,json=nodeKey,proto3" json:"node_key,omitempty"` + DiscoKey string `protobuf:"bytes,4,opt,name=disco_key,json=discoKey,proto3" json:"disco_key,omitempty"` + IpAddress string `protobuf:"bytes,5,opt,name=ip_address,json=ipAddress,proto3" json:"ip_address,omitempty"` + Name string `protobuf:"bytes,6,opt,name=name,proto3" json:"name,omitempty"` + NamespaceId uint32 `protobuf:"varint,7,opt,name=namespace_id,json=namespaceId,proto3" json:"namespace_id,omitempty"` + Registered bool `protobuf:"varint,8,opt,name=registered,proto3" json:"registered,omitempty"` + RegisterMethod RegisterMethod `protobuf:"varint,9,opt,name=register_method,json=registerMethod,proto3,enum=headscale.v1.RegisterMethod" json:"register_method,omitempty"` + AuthKeyId uint32 `protobuf:"varint,10,opt,name=auth_key_id,json=authKeyId,proto3" json:"auth_key_id,omitempty"` // PreAuthKey auth_key = 11; + LastSeen *timestamppb.Timestamp `protobuf:"bytes,12,opt,name=last_seen,json=lastSeen,proto3" json:"last_seen,omitempty"` + LastSuccessfulUpdate *timestamppb.Timestamp `protobuf:"bytes,13,opt,name=last_successful_update,json=lastSuccessfulUpdate,proto3" json:"last_successful_update,omitempty"` + Expiry *timestamppb.Timestamp `protobuf:"bytes,14,opt,name=expiry,proto3" json:"expiry,omitempty"` +} + +func (x *GetMachineResponse) Reset() { + *x = GetMachineResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_headscale_v1_rpc_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetMachineResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetMachineResponse) ProtoMessage() {} + +func (x *GetMachineResponse) ProtoReflect() protoreflect.Message { + mi := &file_headscale_v1_rpc_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetMachineResponse.ProtoReflect.Descriptor instead. +func (*GetMachineResponse) Descriptor() ([]byte, []int) { + return file_headscale_v1_rpc_proto_rawDescGZIP(), []int{1} +} + +func (x *GetMachineResponse) GetId() uint64 { + if x != nil { + return x.Id + } + return 0 +} + +func (x *GetMachineResponse) GetMachineKey() string { + if x != nil { + return x.MachineKey + } + return "" +} + +func (x *GetMachineResponse) GetNodeKey() string { + if x != nil { + return x.NodeKey + } + return "" +} + +func (x *GetMachineResponse) GetDiscoKey() string { + if x != nil { + return x.DiscoKey + } + return "" +} + +func (x *GetMachineResponse) GetIpAddress() string { + if x != nil { + return x.IpAddress + } + return "" +} + +func (x *GetMachineResponse) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *GetMachineResponse) GetNamespaceId() uint32 { + if x != nil { + return x.NamespaceId + } + return 0 +} + +func (x *GetMachineResponse) GetRegistered() bool { + if x != nil { + return x.Registered + } + return false +} + +func (x *GetMachineResponse) GetRegisterMethod() RegisterMethod { + if x != nil { + return x.RegisterMethod + } + return RegisterMethod_REGISTER_METHOD_UNSPECIFIED +} + +func (x *GetMachineResponse) GetAuthKeyId() uint32 { + if x != nil { + return x.AuthKeyId + } + return 0 +} + +func (x *GetMachineResponse) GetLastSeen() *timestamppb.Timestamp { + if x != nil { + return x.LastSeen + } + return nil +} + +func (x *GetMachineResponse) GetLastSuccessfulUpdate() *timestamppb.Timestamp { + if x != nil { + return x.LastSuccessfulUpdate + } + return nil +} + +func (x *GetMachineResponse) GetExpiry() *timestamppb.Timestamp { + if x != nil { + return x.Expiry + } + return nil +} + +type CreateNamespaceRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` +} + +func (x *CreateNamespaceRequest) Reset() { + *x = CreateNamespaceRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_headscale_v1_rpc_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CreateNamespaceRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateNamespaceRequest) ProtoMessage() {} + +func (x *CreateNamespaceRequest) ProtoReflect() protoreflect.Message { + mi := &file_headscale_v1_rpc_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CreateNamespaceRequest.ProtoReflect.Descriptor instead. +func (*CreateNamespaceRequest) Descriptor() ([]byte, []int) { + return file_headscale_v1_rpc_proto_rawDescGZIP(), []int{2} +} + +func (x *CreateNamespaceRequest) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +type CreateNamespaceResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` +} + +func (x *CreateNamespaceResponse) Reset() { + *x = CreateNamespaceResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_headscale_v1_rpc_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CreateNamespaceResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateNamespaceResponse) ProtoMessage() {} + +func (x *CreateNamespaceResponse) ProtoReflect() protoreflect.Message { + mi := &file_headscale_v1_rpc_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CreateNamespaceResponse.ProtoReflect.Descriptor instead. +func (*CreateNamespaceResponse) Descriptor() ([]byte, []int) { + return file_headscale_v1_rpc_proto_rawDescGZIP(), []int{3} +} + +func (x *CreateNamespaceResponse) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +type DeleteNamespaceRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` +} + +func (x *DeleteNamespaceRequest) Reset() { + *x = DeleteNamespaceRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_headscale_v1_rpc_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DeleteNamespaceRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeleteNamespaceRequest) ProtoMessage() {} + +func (x *DeleteNamespaceRequest) ProtoReflect() protoreflect.Message { + mi := &file_headscale_v1_rpc_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DeleteNamespaceRequest.ProtoReflect.Descriptor instead. +func (*DeleteNamespaceRequest) Descriptor() ([]byte, []int) { + return file_headscale_v1_rpc_proto_rawDescGZIP(), []int{4} +} + +func (x *DeleteNamespaceRequest) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +type DeleteNamespaceResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *DeleteNamespaceResponse) Reset() { + *x = DeleteNamespaceResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_headscale_v1_rpc_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DeleteNamespaceResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeleteNamespaceResponse) ProtoMessage() {} + +func (x *DeleteNamespaceResponse) ProtoReflect() protoreflect.Message { + mi := &file_headscale_v1_rpc_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DeleteNamespaceResponse.ProtoReflect.Descriptor instead. +func (*DeleteNamespaceResponse) Descriptor() ([]byte, []int) { + return file_headscale_v1_rpc_proto_rawDescGZIP(), []int{5} +} + +type ListNamespacesRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *ListNamespacesRequest) Reset() { + *x = ListNamespacesRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_headscale_v1_rpc_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListNamespacesRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListNamespacesRequest) ProtoMessage() {} + +func (x *ListNamespacesRequest) ProtoReflect() protoreflect.Message { + mi := &file_headscale_v1_rpc_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListNamespacesRequest.ProtoReflect.Descriptor instead. +func (*ListNamespacesRequest) Descriptor() ([]byte, []int) { + return file_headscale_v1_rpc_proto_rawDescGZIP(), []int{6} +} + +type ListNamespacesResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Namespaces []string `protobuf:"bytes,1,rep,name=namespaces,proto3" json:"namespaces,omitempty"` +} + +func (x *ListNamespacesResponse) Reset() { + *x = ListNamespacesResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_headscale_v1_rpc_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListNamespacesResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListNamespacesResponse) ProtoMessage() {} + +func (x *ListNamespacesResponse) ProtoReflect() protoreflect.Message { + mi := &file_headscale_v1_rpc_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListNamespacesResponse.ProtoReflect.Descriptor instead. +func (*ListNamespacesResponse) Descriptor() ([]byte, []int) { + return file_headscale_v1_rpc_proto_rawDescGZIP(), []int{7} +} + +func (x *ListNamespacesResponse) GetNamespaces() []string { + if x != nil { + return x.Namespaces + } + return nil +} + +var File_headscale_v1_rpc_proto protoreflect.FileDescriptor + +var file_headscale_v1_rpc_proto_rawDesc = []byte{ + 0x0a, 0x16, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x72, + 0x70, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0c, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, + 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, + 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, + 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x32, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x4d, 0x61, 0x63, 0x68, + 0x69, 0x6e, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x6d, 0x61, + 0x63, 0x68, 0x69, 0x6e, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, + 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x49, 0x64, 0x22, 0x99, 0x04, 0x0a, 0x12, 0x47, 0x65, + 0x74, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x02, 0x69, 0x64, + 0x12, 0x1f, 0x0a, 0x0b, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x4b, 0x65, + 0x79, 0x12, 0x19, 0x0a, 0x08, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x07, 0x6e, 0x6f, 0x64, 0x65, 0x4b, 0x65, 0x79, 0x12, 0x1b, 0x0a, 0x09, + 0x64, 0x69, 0x73, 0x63, 0x6f, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x08, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x4b, 0x65, 0x79, 0x12, 0x1d, 0x0a, 0x0a, 0x69, 0x70, 0x5f, + 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x69, + 0x70, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, + 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x21, 0x0a, 0x0c, + 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x07, 0x20, 0x01, + 0x28, 0x0d, 0x52, 0x0b, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x49, 0x64, 0x12, + 0x1e, 0x0a, 0x0a, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x65, 0x64, 0x18, 0x08, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x0a, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x65, 0x64, 0x12, + 0x45, 0x0a, 0x0f, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x6d, 0x65, 0x74, 0x68, + 0x6f, 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1c, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, + 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, + 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x52, 0x0e, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, + 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, 0x1e, 0x0a, 0x0b, 0x61, 0x75, 0x74, 0x68, 0x5f, 0x6b, + 0x65, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x61, 0x75, 0x74, + 0x68, 0x4b, 0x65, 0x79, 0x49, 0x64, 0x12, 0x37, 0x0a, 0x09, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x73, + 0x65, 0x65, 0x6e, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, + 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x08, 0x6c, 0x61, 0x73, 0x74, 0x53, 0x65, 0x65, 0x6e, 0x12, + 0x50, 0x0a, 0x16, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x66, + 0x75, 0x6c, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x14, 0x6c, 0x61, 0x73, + 0x74, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x66, 0x75, 0x6c, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x12, 0x32, 0x0a, 0x06, 0x65, 0x78, 0x70, 0x69, 0x72, 0x79, 0x18, 0x0e, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x06, 0x65, + 0x78, 0x70, 0x69, 0x72, 0x79, 0x22, 0x2c, 0x0a, 0x16, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4e, + 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x22, 0x2d, 0x0a, 0x17, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4e, 0x61, 0x6d, + 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, + 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x22, 0x2c, 0x0a, 0x16, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, + 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, + 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, + 0x22, 0x19, 0x0a, 0x17, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, + 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x17, 0x0a, 0x15, 0x4c, + 0x69, 0x73, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x22, 0x38, 0x0a, 0x16, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x61, 0x6d, 0x65, + 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1e, + 0x0a, 0x0a, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, + 0x28, 0x09, 0x52, 0x0a, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x2a, 0x82, + 0x01, 0x0a, 0x0e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x68, 0x6f, + 0x64, 0x12, 0x1f, 0x0a, 0x1b, 0x52, 0x45, 0x47, 0x49, 0x53, 0x54, 0x45, 0x52, 0x5f, 0x4d, 0x45, + 0x54, 0x48, 0x4f, 0x44, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, + 0x10, 0x00, 0x12, 0x1c, 0x0a, 0x18, 0x52, 0x45, 0x47, 0x49, 0x53, 0x54, 0x45, 0x52, 0x5f, 0x4d, + 0x45, 0x54, 0x48, 0x4f, 0x44, 0x5f, 0x41, 0x55, 0x54, 0x48, 0x5f, 0x4b, 0x45, 0x59, 0x10, 0x01, + 0x12, 0x17, 0x0a, 0x13, 0x52, 0x45, 0x47, 0x49, 0x53, 0x54, 0x45, 0x52, 0x5f, 0x4d, 0x45, 0x54, + 0x48, 0x4f, 0x44, 0x5f, 0x43, 0x4c, 0x49, 0x10, 0x02, 0x12, 0x18, 0x0a, 0x14, 0x52, 0x45, 0x47, + 0x49, 0x53, 0x54, 0x45, 0x52, 0x5f, 0x4d, 0x45, 0x54, 0x48, 0x4f, 0x44, 0x5f, 0x4f, 0x49, 0x44, + 0x43, 0x10, 0x03, 0x32, 0xfa, 0x03, 0x0a, 0x10, 0x48, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, + 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x75, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x4d, + 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x12, 0x1f, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, + 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, + 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, + 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x24, 0x82, 0xd3, 0xe4, 0x93, 0x02, + 0x1e, 0x12, 0x1c, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x6d, 0x61, 0x63, 0x68, 0x69, + 0x6e, 0x65, 0x2f, 0x7b, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x12, + 0x7c, 0x0a, 0x0f, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x12, 0x24, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, + 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, + 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, + 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4e, 0x61, + 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x1c, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x16, 0x22, 0x11, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, + 0x2f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x3a, 0x01, 0x2a, 0x12, 0x79, 0x0a, + 0x0f, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, + 0x12, 0x24, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, + 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, + 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, + 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x19, 0x82, + 0xd3, 0xe4, 0x93, 0x02, 0x13, 0x2a, 0x11, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x6e, + 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x76, 0x0a, 0x0e, 0x4c, 0x69, 0x73, 0x74, + 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x12, 0x23, 0x2e, 0x68, 0x65, 0x61, + 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x61, + 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x24, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, + 0x69, 0x73, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x19, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x13, 0x12, 0x11, 0x2f, + 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, + 0x42, 0x29, 0x5a, 0x27, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6a, + 0x75, 0x61, 0x6e, 0x66, 0x6f, 0x6e, 0x74, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, + 0x65, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x67, 0x6f, 0x2f, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x33, +} + +var ( + file_headscale_v1_rpc_proto_rawDescOnce sync.Once + file_headscale_v1_rpc_proto_rawDescData = file_headscale_v1_rpc_proto_rawDesc +) + +func file_headscale_v1_rpc_proto_rawDescGZIP() []byte { + file_headscale_v1_rpc_proto_rawDescOnce.Do(func() { + file_headscale_v1_rpc_proto_rawDescData = protoimpl.X.CompressGZIP(file_headscale_v1_rpc_proto_rawDescData) + }) + return file_headscale_v1_rpc_proto_rawDescData +} + +var file_headscale_v1_rpc_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_headscale_v1_rpc_proto_msgTypes = make([]protoimpl.MessageInfo, 8) +var file_headscale_v1_rpc_proto_goTypes = []interface{}{ + (RegisterMethod)(0), // 0: headscale.v1.RegisterMethod + (*GetMachineRequest)(nil), // 1: headscale.v1.GetMachineRequest + (*GetMachineResponse)(nil), // 2: headscale.v1.GetMachineResponse + (*CreateNamespaceRequest)(nil), // 3: headscale.v1.CreateNamespaceRequest + (*CreateNamespaceResponse)(nil), // 4: headscale.v1.CreateNamespaceResponse + (*DeleteNamespaceRequest)(nil), // 5: headscale.v1.DeleteNamespaceRequest + (*DeleteNamespaceResponse)(nil), // 6: headscale.v1.DeleteNamespaceResponse + (*ListNamespacesRequest)(nil), // 7: headscale.v1.ListNamespacesRequest + (*ListNamespacesResponse)(nil), // 8: headscale.v1.ListNamespacesResponse + (*timestamppb.Timestamp)(nil), // 9: google.protobuf.Timestamp +} +var file_headscale_v1_rpc_proto_depIdxs = []int32{ + 0, // 0: headscale.v1.GetMachineResponse.register_method:type_name -> headscale.v1.RegisterMethod + 9, // 1: headscale.v1.GetMachineResponse.last_seen:type_name -> google.protobuf.Timestamp + 9, // 2: headscale.v1.GetMachineResponse.last_successful_update:type_name -> google.protobuf.Timestamp + 9, // 3: headscale.v1.GetMachineResponse.expiry:type_name -> google.protobuf.Timestamp + 1, // 4: headscale.v1.HeadscaleService.GetMachine:input_type -> headscale.v1.GetMachineRequest + 3, // 5: headscale.v1.HeadscaleService.CreateNamespace:input_type -> headscale.v1.CreateNamespaceRequest + 5, // 6: headscale.v1.HeadscaleService.DeleteNamespace:input_type -> headscale.v1.DeleteNamespaceRequest + 7, // 7: headscale.v1.HeadscaleService.ListNamespaces:input_type -> headscale.v1.ListNamespacesRequest + 2, // 8: headscale.v1.HeadscaleService.GetMachine:output_type -> headscale.v1.GetMachineResponse + 4, // 9: headscale.v1.HeadscaleService.CreateNamespace:output_type -> headscale.v1.CreateNamespaceResponse + 6, // 10: headscale.v1.HeadscaleService.DeleteNamespace:output_type -> headscale.v1.DeleteNamespaceResponse + 8, // 11: headscale.v1.HeadscaleService.ListNamespaces:output_type -> headscale.v1.ListNamespacesResponse + 8, // [8:12] is the sub-list for method output_type + 4, // [4:8] is the sub-list for method input_type + 4, // [4:4] is the sub-list for extension type_name + 4, // [4:4] is the sub-list for extension extendee + 0, // [0:4] is the sub-list for field type_name +} + +func init() { file_headscale_v1_rpc_proto_init() } +func file_headscale_v1_rpc_proto_init() { + if File_headscale_v1_rpc_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_headscale_v1_rpc_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetMachineRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_headscale_v1_rpc_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetMachineResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_headscale_v1_rpc_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CreateNamespaceRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_headscale_v1_rpc_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CreateNamespaceResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_headscale_v1_rpc_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DeleteNamespaceRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_headscale_v1_rpc_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DeleteNamespaceResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_headscale_v1_rpc_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListNamespacesRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_headscale_v1_rpc_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListNamespacesResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_headscale_v1_rpc_proto_rawDesc, + NumEnums: 1, + NumMessages: 8, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_headscale_v1_rpc_proto_goTypes, + DependencyIndexes: file_headscale_v1_rpc_proto_depIdxs, + EnumInfos: file_headscale_v1_rpc_proto_enumTypes, + MessageInfos: file_headscale_v1_rpc_proto_msgTypes, + }.Build() + File_headscale_v1_rpc_proto = out.File + file_headscale_v1_rpc_proto_rawDesc = nil + file_headscale_v1_rpc_proto_goTypes = nil + file_headscale_v1_rpc_proto_depIdxs = nil +} diff --git a/gen/go/headscale/v1/rpc.pb.gw.go b/gen/go/headscale/v1/rpc.pb.gw.go new file mode 100644 index 00000000..773a85a4 --- /dev/null +++ b/gen/go/headscale/v1/rpc.pb.gw.go @@ -0,0 +1,414 @@ +// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT. +// source: headscale/v1/rpc.proto + +/* +Package v1 is a reverse proxy. + +It translates gRPC into RESTful JSON APIs. +*/ +package v1 + +import ( + "context" + "io" + "net/http" + + "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" + "github.com/grpc-ecosystem/grpc-gateway/v2/utilities" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/grpclog" + "google.golang.org/grpc/metadata" + "google.golang.org/grpc/status" + "google.golang.org/protobuf/proto" +) + +// Suppress "imported and not used" errors +var _ codes.Code +var _ io.Reader +var _ status.Status +var _ = runtime.String +var _ = utilities.NewDoubleArray +var _ = metadata.Join + +func request_HeadscaleService_GetMachine_0(ctx context.Context, marshaler runtime.Marshaler, client HeadscaleServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq GetMachineRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["machine_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "machine_id") + } + + protoReq.MachineId, err = runtime.Uint64(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "machine_id", err) + } + + msg, err := client.GetMachine(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_HeadscaleService_GetMachine_0(ctx context.Context, marshaler runtime.Marshaler, server HeadscaleServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq GetMachineRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["machine_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "machine_id") + } + + protoReq.MachineId, err = runtime.Uint64(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "machine_id", err) + } + + msg, err := server.GetMachine(ctx, &protoReq) + return msg, metadata, err + +} + +func request_HeadscaleService_CreateNamespace_0(ctx context.Context, marshaler runtime.Marshaler, client HeadscaleServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq CreateNamespaceRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.CreateNamespace(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_HeadscaleService_CreateNamespace_0(ctx context.Context, marshaler runtime.Marshaler, server HeadscaleServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq CreateNamespaceRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.CreateNamespace(ctx, &protoReq) + return msg, metadata, err + +} + +var ( + filter_HeadscaleService_DeleteNamespace_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)} +) + +func request_HeadscaleService_DeleteNamespace_0(ctx context.Context, marshaler runtime.Marshaler, client HeadscaleServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq DeleteNamespaceRequest + var metadata runtime.ServerMetadata + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_HeadscaleService_DeleteNamespace_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.DeleteNamespace(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_HeadscaleService_DeleteNamespace_0(ctx context.Context, marshaler runtime.Marshaler, server HeadscaleServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq DeleteNamespaceRequest + var metadata runtime.ServerMetadata + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_HeadscaleService_DeleteNamespace_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.DeleteNamespace(ctx, &protoReq) + return msg, metadata, err + +} + +func request_HeadscaleService_ListNamespaces_0(ctx context.Context, marshaler runtime.Marshaler, client HeadscaleServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq ListNamespacesRequest + var metadata runtime.ServerMetadata + + msg, err := client.ListNamespaces(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_HeadscaleService_ListNamespaces_0(ctx context.Context, marshaler runtime.Marshaler, server HeadscaleServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq ListNamespacesRequest + var metadata runtime.ServerMetadata + + msg, err := server.ListNamespaces(ctx, &protoReq) + return msg, metadata, err + +} + +// RegisterHeadscaleServiceHandlerServer registers the http handlers for service HeadscaleService to "mux". +// UnaryRPC :call HeadscaleServiceServer directly. +// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. +// Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterHeadscaleServiceHandlerFromEndpoint instead. +func RegisterHeadscaleServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux, server HeadscaleServiceServer) error { + + mux.Handle("GET", pattern_HeadscaleService_GetMachine_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/headscale.v1.HeadscaleService/GetMachine", runtime.WithHTTPPathPattern("/api/v1/machine/{machine_id}")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_HeadscaleService_GetMachine_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_HeadscaleService_GetMachine_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_HeadscaleService_CreateNamespace_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/headscale.v1.HeadscaleService/CreateNamespace", runtime.WithHTTPPathPattern("/api/v1/namespace")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_HeadscaleService_CreateNamespace_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_HeadscaleService_CreateNamespace_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("DELETE", pattern_HeadscaleService_DeleteNamespace_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/headscale.v1.HeadscaleService/DeleteNamespace", runtime.WithHTTPPathPattern("/api/v1/namespace")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_HeadscaleService_DeleteNamespace_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_HeadscaleService_DeleteNamespace_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_HeadscaleService_ListNamespaces_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/headscale.v1.HeadscaleService/ListNamespaces", runtime.WithHTTPPathPattern("/api/v1/namespace")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_HeadscaleService_ListNamespaces_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_HeadscaleService_ListNamespaces_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +// RegisterHeadscaleServiceHandlerFromEndpoint is same as RegisterHeadscaleServiceHandler but +// automatically dials to "endpoint" and closes the connection when "ctx" gets done. +func RegisterHeadscaleServiceHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) { + conn, err := grpc.Dial(endpoint, opts...) + if err != nil { + return err + } + defer func() { + if err != nil { + if cerr := conn.Close(); cerr != nil { + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) + } + return + } + go func() { + <-ctx.Done() + if cerr := conn.Close(); cerr != nil { + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) + } + }() + }() + + return RegisterHeadscaleServiceHandler(ctx, mux, conn) +} + +// RegisterHeadscaleServiceHandler registers the http handlers for service HeadscaleService to "mux". +// The handlers forward requests to the grpc endpoint over "conn". +func RegisterHeadscaleServiceHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error { + return RegisterHeadscaleServiceHandlerClient(ctx, mux, NewHeadscaleServiceClient(conn)) +} + +// RegisterHeadscaleServiceHandlerClient registers the http handlers for service HeadscaleService +// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "HeadscaleServiceClient". +// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "HeadscaleServiceClient" +// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in +// "HeadscaleServiceClient" to call the correct interceptors. +func RegisterHeadscaleServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, client HeadscaleServiceClient) error { + + mux.Handle("GET", pattern_HeadscaleService_GetMachine_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req, "/headscale.v1.HeadscaleService/GetMachine", runtime.WithHTTPPathPattern("/api/v1/machine/{machine_id}")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_HeadscaleService_GetMachine_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_HeadscaleService_GetMachine_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_HeadscaleService_CreateNamespace_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req, "/headscale.v1.HeadscaleService/CreateNamespace", runtime.WithHTTPPathPattern("/api/v1/namespace")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_HeadscaleService_CreateNamespace_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_HeadscaleService_CreateNamespace_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("DELETE", pattern_HeadscaleService_DeleteNamespace_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req, "/headscale.v1.HeadscaleService/DeleteNamespace", runtime.WithHTTPPathPattern("/api/v1/namespace")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_HeadscaleService_DeleteNamespace_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_HeadscaleService_DeleteNamespace_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_HeadscaleService_ListNamespaces_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req, "/headscale.v1.HeadscaleService/ListNamespaces", runtime.WithHTTPPathPattern("/api/v1/namespace")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_HeadscaleService_ListNamespaces_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_HeadscaleService_ListNamespaces_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +var ( + pattern_HeadscaleService_GetMachine_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"api", "v1", "machine", "machine_id"}, "")) + + pattern_HeadscaleService_CreateNamespace_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "v1", "namespace"}, "")) + + pattern_HeadscaleService_DeleteNamespace_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "v1", "namespace"}, "")) + + pattern_HeadscaleService_ListNamespaces_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "v1", "namespace"}, "")) +) + +var ( + forward_HeadscaleService_GetMachine_0 = runtime.ForwardResponseMessage + + forward_HeadscaleService_CreateNamespace_0 = runtime.ForwardResponseMessage + + forward_HeadscaleService_DeleteNamespace_0 = runtime.ForwardResponseMessage + + forward_HeadscaleService_ListNamespaces_0 = runtime.ForwardResponseMessage +) diff --git a/gen/go/headscale/v1/rpc_grpc.pb.go b/gen/go/headscale/v1/rpc_grpc.pb.go new file mode 100644 index 00000000..618c26d1 --- /dev/null +++ b/gen/go/headscale/v1/rpc_grpc.pb.go @@ -0,0 +1,209 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. + +package v1 + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +// HeadscaleServiceClient is the client API for HeadscaleService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type HeadscaleServiceClient interface { + GetMachine(ctx context.Context, in *GetMachineRequest, opts ...grpc.CallOption) (*GetMachineResponse, error) + CreateNamespace(ctx context.Context, in *CreateNamespaceRequest, opts ...grpc.CallOption) (*CreateNamespaceResponse, error) + DeleteNamespace(ctx context.Context, in *DeleteNamespaceRequest, opts ...grpc.CallOption) (*DeleteNamespaceResponse, error) + ListNamespaces(ctx context.Context, in *ListNamespacesRequest, opts ...grpc.CallOption) (*ListNamespacesResponse, error) +} + +type headscaleServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewHeadscaleServiceClient(cc grpc.ClientConnInterface) HeadscaleServiceClient { + return &headscaleServiceClient{cc} +} + +func (c *headscaleServiceClient) GetMachine(ctx context.Context, in *GetMachineRequest, opts ...grpc.CallOption) (*GetMachineResponse, error) { + out := new(GetMachineResponse) + err := c.cc.Invoke(ctx, "/headscale.v1.HeadscaleService/GetMachine", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *headscaleServiceClient) CreateNamespace(ctx context.Context, in *CreateNamespaceRequest, opts ...grpc.CallOption) (*CreateNamespaceResponse, error) { + out := new(CreateNamespaceResponse) + err := c.cc.Invoke(ctx, "/headscale.v1.HeadscaleService/CreateNamespace", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *headscaleServiceClient) DeleteNamespace(ctx context.Context, in *DeleteNamespaceRequest, opts ...grpc.CallOption) (*DeleteNamespaceResponse, error) { + out := new(DeleteNamespaceResponse) + err := c.cc.Invoke(ctx, "/headscale.v1.HeadscaleService/DeleteNamespace", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *headscaleServiceClient) ListNamespaces(ctx context.Context, in *ListNamespacesRequest, opts ...grpc.CallOption) (*ListNamespacesResponse, error) { + out := new(ListNamespacesResponse) + err := c.cc.Invoke(ctx, "/headscale.v1.HeadscaleService/ListNamespaces", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// HeadscaleServiceServer is the server API for HeadscaleService service. +// All implementations must embed UnimplementedHeadscaleServiceServer +// for forward compatibility +type HeadscaleServiceServer interface { + GetMachine(context.Context, *GetMachineRequest) (*GetMachineResponse, error) + CreateNamespace(context.Context, *CreateNamespaceRequest) (*CreateNamespaceResponse, error) + DeleteNamespace(context.Context, *DeleteNamespaceRequest) (*DeleteNamespaceResponse, error) + ListNamespaces(context.Context, *ListNamespacesRequest) (*ListNamespacesResponse, error) + mustEmbedUnimplementedHeadscaleServiceServer() +} + +// UnimplementedHeadscaleServiceServer must be embedded to have forward compatible implementations. +type UnimplementedHeadscaleServiceServer struct { +} + +func (UnimplementedHeadscaleServiceServer) GetMachine(context.Context, *GetMachineRequest) (*GetMachineResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetMachine not implemented") +} +func (UnimplementedHeadscaleServiceServer) CreateNamespace(context.Context, *CreateNamespaceRequest) (*CreateNamespaceResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method CreateNamespace not implemented") +} +func (UnimplementedHeadscaleServiceServer) DeleteNamespace(context.Context, *DeleteNamespaceRequest) (*DeleteNamespaceResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method DeleteNamespace not implemented") +} +func (UnimplementedHeadscaleServiceServer) ListNamespaces(context.Context, *ListNamespacesRequest) (*ListNamespacesResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ListNamespaces not implemented") +} +func (UnimplementedHeadscaleServiceServer) mustEmbedUnimplementedHeadscaleServiceServer() {} + +// UnsafeHeadscaleServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to HeadscaleServiceServer will +// result in compilation errors. +type UnsafeHeadscaleServiceServer interface { + mustEmbedUnimplementedHeadscaleServiceServer() +} + +func RegisterHeadscaleServiceServer(s grpc.ServiceRegistrar, srv HeadscaleServiceServer) { + s.RegisterService(&HeadscaleService_ServiceDesc, srv) +} + +func _HeadscaleService_GetMachine_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetMachineRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(HeadscaleServiceServer).GetMachine(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/headscale.v1.HeadscaleService/GetMachine", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(HeadscaleServiceServer).GetMachine(ctx, req.(*GetMachineRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _HeadscaleService_CreateNamespace_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CreateNamespaceRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(HeadscaleServiceServer).CreateNamespace(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/headscale.v1.HeadscaleService/CreateNamespace", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(HeadscaleServiceServer).CreateNamespace(ctx, req.(*CreateNamespaceRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _HeadscaleService_DeleteNamespace_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(DeleteNamespaceRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(HeadscaleServiceServer).DeleteNamespace(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/headscale.v1.HeadscaleService/DeleteNamespace", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(HeadscaleServiceServer).DeleteNamespace(ctx, req.(*DeleteNamespaceRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _HeadscaleService_ListNamespaces_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ListNamespacesRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(HeadscaleServiceServer).ListNamespaces(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/headscale.v1.HeadscaleService/ListNamespaces", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(HeadscaleServiceServer).ListNamespaces(ctx, req.(*ListNamespacesRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// HeadscaleService_ServiceDesc is the grpc.ServiceDesc for HeadscaleService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var HeadscaleService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "headscale.v1.HeadscaleService", + HandlerType: (*HeadscaleServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "GetMachine", + Handler: _HeadscaleService_GetMachine_Handler, + }, + { + MethodName: "CreateNamespace", + Handler: _HeadscaleService_CreateNamespace_Handler, + }, + { + MethodName: "DeleteNamespace", + Handler: _HeadscaleService_DeleteNamespace_Handler, + }, + { + MethodName: "ListNamespaces", + Handler: _HeadscaleService_ListNamespaces_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "headscale/v1/rpc.proto", +} diff --git a/gen/go/v1/headscale.pb.go b/gen/go/v1/headscale.pb.go deleted file mode 100644 index 104e3746..00000000 --- a/gen/go/v1/headscale.pb.go +++ /dev/null @@ -1,702 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.27.1 -// protoc v3.18.1 -// source: v1/headscale.proto - -package v1 - -import ( - _ "github.com/infobloxopen/protoc-gen-gorm/options" - _ "google.golang.org/genproto/googleapis/api/annotations" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - timestamppb "google.golang.org/protobuf/types/known/timestamppb" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -type RegisterMethod int32 - -const ( - RegisterMethod_AUTH_KEY RegisterMethod = 0 - RegisterMethod_CLI RegisterMethod = 1 - RegisterMethod_OIDC RegisterMethod = 2 -) - -// Enum value maps for RegisterMethod. -var ( - RegisterMethod_name = map[int32]string{ - 0: "AUTH_KEY", - 1: "CLI", - 2: "OIDC", - } - RegisterMethod_value = map[string]int32{ - "AUTH_KEY": 0, - "CLI": 1, - "OIDC": 2, - } -) - -func (x RegisterMethod) Enum() *RegisterMethod { - p := new(RegisterMethod) - *p = x - return p -} - -func (x RegisterMethod) String() string { - return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) -} - -func (RegisterMethod) Descriptor() protoreflect.EnumDescriptor { - return file_v1_headscale_proto_enumTypes[0].Descriptor() -} - -func (RegisterMethod) Type() protoreflect.EnumType { - return &file_v1_headscale_proto_enumTypes[0] -} - -func (x RegisterMethod) Number() protoreflect.EnumNumber { - return protoreflect.EnumNumber(x) -} - -// Deprecated: Use RegisterMethod.Descriptor instead. -func (RegisterMethod) EnumDescriptor() ([]byte, []int) { - return file_v1_headscale_proto_rawDescGZIP(), []int{0} -} - -type Namespace struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Name string `protobuf:"bytes,1,opt,name=Name,proto3" json:"Name,omitempty"` -} - -func (x *Namespace) Reset() { - *x = Namespace{} - if protoimpl.UnsafeEnabled { - mi := &file_v1_headscale_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Namespace) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Namespace) ProtoMessage() {} - -func (x *Namespace) ProtoReflect() protoreflect.Message { - mi := &file_v1_headscale_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Namespace.ProtoReflect.Descriptor instead. -func (*Namespace) Descriptor() ([]byte, []int) { - return file_v1_headscale_proto_rawDescGZIP(), []int{0} -} - -func (x *Namespace) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -type PreAuthKey struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - ID uint64 `protobuf:"varint,1,opt,name=ID,proto3" json:"ID,omitempty"` - Key string `protobuf:"bytes,2,opt,name=Key,proto3" json:"Key,omitempty"` - NamespaceID uint32 `protobuf:"varint,3,opt,name=NamespaceID,proto3" json:"NamespaceID,omitempty"` - Namespace *Namespace `protobuf:"bytes,4,opt,name=Namespace,proto3" json:"Namespace,omitempty"` - Reusable bool `protobuf:"varint,5,opt,name=Reusable,proto3" json:"Reusable,omitempty"` - Ephemeral bool `protobuf:"varint,6,opt,name=Ephemeral,proto3" json:"Ephemeral,omitempty"` - Used bool `protobuf:"varint,7,opt,name=Used,proto3" json:"Used,omitempty"` - CreatedAt *timestamppb.Timestamp `protobuf:"bytes,8,opt,name=CreatedAt,proto3" json:"CreatedAt,omitempty"` - Expiration *timestamppb.Timestamp `protobuf:"bytes,9,opt,name=Expiration,proto3" json:"Expiration,omitempty"` -} - -func (x *PreAuthKey) Reset() { - *x = PreAuthKey{} - if protoimpl.UnsafeEnabled { - mi := &file_v1_headscale_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *PreAuthKey) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*PreAuthKey) ProtoMessage() {} - -func (x *PreAuthKey) ProtoReflect() protoreflect.Message { - mi := &file_v1_headscale_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use PreAuthKey.ProtoReflect.Descriptor instead. -func (*PreAuthKey) Descriptor() ([]byte, []int) { - return file_v1_headscale_proto_rawDescGZIP(), []int{1} -} - -func (x *PreAuthKey) GetID() uint64 { - if x != nil { - return x.ID - } - return 0 -} - -func (x *PreAuthKey) GetKey() string { - if x != nil { - return x.Key - } - return "" -} - -func (x *PreAuthKey) GetNamespaceID() uint32 { - if x != nil { - return x.NamespaceID - } - return 0 -} - -func (x *PreAuthKey) GetNamespace() *Namespace { - if x != nil { - return x.Namespace - } - return nil -} - -func (x *PreAuthKey) GetReusable() bool { - if x != nil { - return x.Reusable - } - return false -} - -func (x *PreAuthKey) GetEphemeral() bool { - if x != nil { - return x.Ephemeral - } - return false -} - -func (x *PreAuthKey) GetUsed() bool { - if x != nil { - return x.Used - } - return false -} - -func (x *PreAuthKey) GetCreatedAt() *timestamppb.Timestamp { - if x != nil { - return x.CreatedAt - } - return nil -} - -func (x *PreAuthKey) GetExpiration() *timestamppb.Timestamp { - if x != nil { - return x.Expiration - } - return nil -} - -type GetMachineRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - MachineId uint64 `protobuf:"varint,1,opt,name=machine_id,json=machineId,proto3" json:"machine_id,omitempty"` -} - -func (x *GetMachineRequest) Reset() { - *x = GetMachineRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_v1_headscale_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *GetMachineRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*GetMachineRequest) ProtoMessage() {} - -func (x *GetMachineRequest) ProtoReflect() protoreflect.Message { - mi := &file_v1_headscale_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use GetMachineRequest.ProtoReflect.Descriptor instead. -func (*GetMachineRequest) Descriptor() ([]byte, []int) { - return file_v1_headscale_proto_rawDescGZIP(), []int{2} -} - -func (x *GetMachineRequest) GetMachineId() uint64 { - if x != nil { - return x.MachineId - } - return 0 -} - -type Machine struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - ID uint64 `protobuf:"varint,1,opt,name=ID,proto3" json:"ID,omitempty"` - MachineKey string `protobuf:"bytes,2,opt,name=MachineKey,proto3" json:"MachineKey,omitempty"` - NodeKey string `protobuf:"bytes,3,opt,name=NodeKey,proto3" json:"NodeKey,omitempty"` - DiscoKey string `protobuf:"bytes,4,opt,name=DiscoKey,proto3" json:"DiscoKey,omitempty"` - IPAddress string `protobuf:"bytes,5,opt,name=IPAddress,proto3" json:"IPAddress,omitempty"` - Name string `protobuf:"bytes,6,opt,name=Name,proto3" json:"Name,omitempty"` - NamespaceID uint32 `protobuf:"varint,7,opt,name=NamespaceID,proto3" json:"NamespaceID,omitempty"` - Registered bool `protobuf:"varint,8,opt,name=Registered,proto3" json:"Registered,omitempty"` - RegisterMethod RegisterMethod `protobuf:"varint,9,opt,name=RegisterMethod,proto3,enum=headscale.v1.RegisterMethod" json:"RegisterMethod,omitempty"` - AuthKeyID uint32 `protobuf:"varint,10,opt,name=AuthKeyID,proto3" json:"AuthKeyID,omitempty"` - AuthKey *PreAuthKey `protobuf:"bytes,11,opt,name=AuthKey,proto3" json:"AuthKey,omitempty"` - LastSeen *timestamppb.Timestamp `protobuf:"bytes,12,opt,name=LastSeen,proto3" json:"LastSeen,omitempty"` - LastSuccessfulUpdate *timestamppb.Timestamp `protobuf:"bytes,13,opt,name=LastSuccessfulUpdate,proto3" json:"LastSuccessfulUpdate,omitempty"` - Expiry *timestamppb.Timestamp `protobuf:"bytes,14,opt,name=Expiry,proto3" json:"Expiry,omitempty"` - HostInfo []byte `protobuf:"bytes,15,opt,name=HostInfo,proto3" json:"HostInfo,omitempty"` - Endpoints []byte `protobuf:"bytes,16,opt,name=Endpoints,proto3" json:"Endpoints,omitempty"` - EnabledRoutes []byte `protobuf:"bytes,17,opt,name=EnabledRoutes,proto3" json:"EnabledRoutes,omitempty"` - CreatedAt *timestamppb.Timestamp `protobuf:"bytes,18,opt,name=CreatedAt,proto3" json:"CreatedAt,omitempty"` - UpdatedAt *timestamppb.Timestamp `protobuf:"bytes,19,opt,name=UpdatedAt,proto3" json:"UpdatedAt,omitempty"` - DeletedAt *timestamppb.Timestamp `protobuf:"bytes,20,opt,name=DeletedAt,proto3" json:"DeletedAt,omitempty"` -} - -func (x *Machine) Reset() { - *x = Machine{} - if protoimpl.UnsafeEnabled { - mi := &file_v1_headscale_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Machine) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Machine) ProtoMessage() {} - -func (x *Machine) ProtoReflect() protoreflect.Message { - mi := &file_v1_headscale_proto_msgTypes[3] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Machine.ProtoReflect.Descriptor instead. -func (*Machine) Descriptor() ([]byte, []int) { - return file_v1_headscale_proto_rawDescGZIP(), []int{3} -} - -func (x *Machine) GetID() uint64 { - if x != nil { - return x.ID - } - return 0 -} - -func (x *Machine) GetMachineKey() string { - if x != nil { - return x.MachineKey - } - return "" -} - -func (x *Machine) GetNodeKey() string { - if x != nil { - return x.NodeKey - } - return "" -} - -func (x *Machine) GetDiscoKey() string { - if x != nil { - return x.DiscoKey - } - return "" -} - -func (x *Machine) GetIPAddress() string { - if x != nil { - return x.IPAddress - } - return "" -} - -func (x *Machine) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -func (x *Machine) GetNamespaceID() uint32 { - if x != nil { - return x.NamespaceID - } - return 0 -} - -func (x *Machine) GetRegistered() bool { - if x != nil { - return x.Registered - } - return false -} - -func (x *Machine) GetRegisterMethod() RegisterMethod { - if x != nil { - return x.RegisterMethod - } - return RegisterMethod_AUTH_KEY -} - -func (x *Machine) GetAuthKeyID() uint32 { - if x != nil { - return x.AuthKeyID - } - return 0 -} - -func (x *Machine) GetAuthKey() *PreAuthKey { - if x != nil { - return x.AuthKey - } - return nil -} - -func (x *Machine) GetLastSeen() *timestamppb.Timestamp { - if x != nil { - return x.LastSeen - } - return nil -} - -func (x *Machine) GetLastSuccessfulUpdate() *timestamppb.Timestamp { - if x != nil { - return x.LastSuccessfulUpdate - } - return nil -} - -func (x *Machine) GetExpiry() *timestamppb.Timestamp { - if x != nil { - return x.Expiry - } - return nil -} - -func (x *Machine) GetHostInfo() []byte { - if x != nil { - return x.HostInfo - } - return nil -} - -func (x *Machine) GetEndpoints() []byte { - if x != nil { - return x.Endpoints - } - return nil -} - -func (x *Machine) GetEnabledRoutes() []byte { - if x != nil { - return x.EnabledRoutes - } - return nil -} - -func (x *Machine) GetCreatedAt() *timestamppb.Timestamp { - if x != nil { - return x.CreatedAt - } - return nil -} - -func (x *Machine) GetUpdatedAt() *timestamppb.Timestamp { - if x != nil { - return x.UpdatedAt - } - return nil -} - -func (x *Machine) GetDeletedAt() *timestamppb.Timestamp { - if x != nil { - return x.DeletedAt - } - return nil -} - -var File_v1_headscale_proto protoreflect.FileDescriptor - -var file_v1_headscale_proto_rawDesc = []byte{ - 0x0a, 0x12, 0x76, 0x31, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0c, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, - 0x76, 0x31, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, - 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x1a, 0x12, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x67, 0x6f, 0x72, 0x6d, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x1f, 0x0a, 0x09, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, - 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0xcb, 0x02, 0x0a, 0x0a, 0x50, 0x72, 0x65, 0x41, 0x75, - 0x74, 0x68, 0x4b, 0x65, 0x79, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x04, 0x52, 0x02, 0x49, 0x44, 0x12, 0x10, 0x0a, 0x03, 0x4b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x03, 0x4b, 0x65, 0x79, 0x12, 0x20, 0x0a, 0x0b, 0x4e, 0x61, 0x6d, 0x65, 0x73, - 0x70, 0x61, 0x63, 0x65, 0x49, 0x44, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x4e, 0x61, - 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x49, 0x44, 0x12, 0x35, 0x0a, 0x09, 0x4e, 0x61, 0x6d, - 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x68, - 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x61, 0x6d, 0x65, - 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x09, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, - 0x12, 0x1a, 0x0a, 0x08, 0x52, 0x65, 0x75, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x05, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x08, 0x52, 0x65, 0x75, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x1c, 0x0a, 0x09, - 0x45, 0x70, 0x68, 0x65, 0x6d, 0x65, 0x72, 0x61, 0x6c, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x09, 0x45, 0x70, 0x68, 0x65, 0x6d, 0x65, 0x72, 0x61, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x55, 0x73, - 0x65, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x04, 0x55, 0x73, 0x65, 0x64, 0x12, 0x38, - 0x0a, 0x09, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x43, - 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x3a, 0x0a, 0x0a, 0x45, 0x78, 0x70, 0x69, - 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, - 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, - 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0a, 0x45, 0x78, 0x70, 0x69, 0x72, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x32, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x4d, 0x61, 0x63, 0x68, 0x69, - 0x6e, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x6d, 0x61, 0x63, - 0x68, 0x69, 0x6e, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x6d, - 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x49, 0x64, 0x22, 0xcd, 0x06, 0x0a, 0x07, 0x4d, 0x61, 0x63, - 0x68, 0x69, 0x6e, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, - 0x52, 0x02, 0x49, 0x44, 0x12, 0x1e, 0x0a, 0x0a, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x4b, - 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, - 0x65, 0x4b, 0x65, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x4e, 0x6f, 0x64, 0x65, 0x4b, 0x65, 0x79, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x4e, 0x6f, 0x64, 0x65, 0x4b, 0x65, 0x79, 0x12, 0x1a, - 0x0a, 0x08, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x4b, 0x65, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x08, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x4b, 0x65, 0x79, 0x12, 0x1c, 0x0a, 0x09, 0x49, 0x50, - 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x49, - 0x50, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, - 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, - 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x49, 0x44, 0x18, 0x07, 0x20, 0x01, 0x28, - 0x0d, 0x52, 0x0b, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x49, 0x44, 0x12, 0x1e, - 0x0a, 0x0a, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x65, 0x64, 0x18, 0x08, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x0a, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x65, 0x64, 0x12, 0x44, - 0x0a, 0x0e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, - 0x18, 0x09, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1c, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, - 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x4d, 0x65, - 0x74, 0x68, 0x6f, 0x64, 0x52, 0x0e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x4d, 0x65, - 0x74, 0x68, 0x6f, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x41, 0x75, 0x74, 0x68, 0x4b, 0x65, 0x79, 0x49, - 0x44, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x41, 0x75, 0x74, 0x68, 0x4b, 0x65, 0x79, - 0x49, 0x44, 0x12, 0x32, 0x0a, 0x07, 0x41, 0x75, 0x74, 0x68, 0x4b, 0x65, 0x79, 0x18, 0x0b, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, - 0x76, 0x31, 0x2e, 0x50, 0x72, 0x65, 0x41, 0x75, 0x74, 0x68, 0x4b, 0x65, 0x79, 0x52, 0x07, 0x41, - 0x75, 0x74, 0x68, 0x4b, 0x65, 0x79, 0x12, 0x36, 0x0a, 0x08, 0x4c, 0x61, 0x73, 0x74, 0x53, 0x65, - 0x65, 0x6e, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, - 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, - 0x74, 0x61, 0x6d, 0x70, 0x52, 0x08, 0x4c, 0x61, 0x73, 0x74, 0x53, 0x65, 0x65, 0x6e, 0x12, 0x4e, - 0x0a, 0x14, 0x4c, 0x61, 0x73, 0x74, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x66, 0x75, 0x6c, - 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, - 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, - 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x14, 0x4c, 0x61, 0x73, 0x74, 0x53, 0x75, - 0x63, 0x63, 0x65, 0x73, 0x73, 0x66, 0x75, 0x6c, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x32, - 0x0a, 0x06, 0x45, 0x78, 0x70, 0x69, 0x72, 0x79, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, - 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, - 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x06, 0x45, 0x78, 0x70, 0x69, - 0x72, 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x48, 0x6f, 0x73, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x18, 0x0f, - 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x48, 0x6f, 0x73, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1c, - 0x0a, 0x09, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x18, 0x10, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x09, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x12, 0x24, 0x0a, 0x0d, - 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x18, 0x11, 0x20, - 0x01, 0x28, 0x0c, 0x52, 0x0d, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x52, 0x6f, 0x75, 0x74, - 0x65, 0x73, 0x12, 0x38, 0x0a, 0x09, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x18, - 0x12, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, - 0x70, 0x52, 0x09, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x38, 0x0a, 0x09, - 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x18, 0x13, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x55, 0x70, 0x64, - 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x38, 0x0a, 0x09, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, - 0x64, 0x41, 0x74, 0x18, 0x14, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, - 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x41, 0x74, - 0x3a, 0x06, 0xba, 0xb9, 0x19, 0x02, 0x08, 0x01, 0x2a, 0x31, 0x0a, 0x0e, 0x52, 0x65, 0x67, 0x69, - 0x73, 0x74, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, 0x0c, 0x0a, 0x08, 0x41, 0x55, - 0x54, 0x48, 0x5f, 0x4b, 0x45, 0x59, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x43, 0x4c, 0x49, 0x10, - 0x01, 0x12, 0x08, 0x0a, 0x04, 0x4f, 0x49, 0x44, 0x43, 0x10, 0x02, 0x32, 0x7e, 0x0a, 0x10, 0x48, - 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, - 0x6a, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x12, 0x1f, 0x2e, - 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, - 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x15, - 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x61, - 0x63, 0x68, 0x69, 0x6e, 0x65, 0x22, 0x24, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1e, 0x12, 0x1c, 0x2f, - 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x2f, 0x7b, - 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x42, 0x29, 0x5a, 0x27, 0x67, - 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6a, 0x75, 0x61, 0x6e, 0x66, 0x6f, - 0x6e, 0x74, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2f, 0x67, 0x65, 0x6e, - 0x2f, 0x67, 0x6f, 0x2f, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_v1_headscale_proto_rawDescOnce sync.Once - file_v1_headscale_proto_rawDescData = file_v1_headscale_proto_rawDesc -) - -func file_v1_headscale_proto_rawDescGZIP() []byte { - file_v1_headscale_proto_rawDescOnce.Do(func() { - file_v1_headscale_proto_rawDescData = protoimpl.X.CompressGZIP(file_v1_headscale_proto_rawDescData) - }) - return file_v1_headscale_proto_rawDescData -} - -var file_v1_headscale_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_v1_headscale_proto_msgTypes = make([]protoimpl.MessageInfo, 4) -var file_v1_headscale_proto_goTypes = []interface{}{ - (RegisterMethod)(0), // 0: headscale.v1.RegisterMethod - (*Namespace)(nil), // 1: headscale.v1.Namespace - (*PreAuthKey)(nil), // 2: headscale.v1.PreAuthKey - (*GetMachineRequest)(nil), // 3: headscale.v1.GetMachineRequest - (*Machine)(nil), // 4: headscale.v1.Machine - (*timestamppb.Timestamp)(nil), // 5: google.protobuf.Timestamp -} -var file_v1_headscale_proto_depIdxs = []int32{ - 1, // 0: headscale.v1.PreAuthKey.Namespace:type_name -> headscale.v1.Namespace - 5, // 1: headscale.v1.PreAuthKey.CreatedAt:type_name -> google.protobuf.Timestamp - 5, // 2: headscale.v1.PreAuthKey.Expiration:type_name -> google.protobuf.Timestamp - 0, // 3: headscale.v1.Machine.RegisterMethod:type_name -> headscale.v1.RegisterMethod - 2, // 4: headscale.v1.Machine.AuthKey:type_name -> headscale.v1.PreAuthKey - 5, // 5: headscale.v1.Machine.LastSeen:type_name -> google.protobuf.Timestamp - 5, // 6: headscale.v1.Machine.LastSuccessfulUpdate:type_name -> google.protobuf.Timestamp - 5, // 7: headscale.v1.Machine.Expiry:type_name -> google.protobuf.Timestamp - 5, // 8: headscale.v1.Machine.CreatedAt:type_name -> google.protobuf.Timestamp - 5, // 9: headscale.v1.Machine.UpdatedAt:type_name -> google.protobuf.Timestamp - 5, // 10: headscale.v1.Machine.DeletedAt:type_name -> google.protobuf.Timestamp - 3, // 11: headscale.v1.HeadscaleService.GetMachine:input_type -> headscale.v1.GetMachineRequest - 4, // 12: headscale.v1.HeadscaleService.GetMachine:output_type -> headscale.v1.Machine - 12, // [12:13] is the sub-list for method output_type - 11, // [11:12] is the sub-list for method input_type - 11, // [11:11] is the sub-list for extension type_name - 11, // [11:11] is the sub-list for extension extendee - 0, // [0:11] is the sub-list for field type_name -} - -func init() { file_v1_headscale_proto_init() } -func file_v1_headscale_proto_init() { - if File_v1_headscale_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_v1_headscale_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Namespace); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_v1_headscale_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PreAuthKey); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_v1_headscale_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetMachineRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_v1_headscale_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Machine); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_v1_headscale_proto_rawDesc, - NumEnums: 1, - NumMessages: 4, - NumExtensions: 0, - NumServices: 1, - }, - GoTypes: file_v1_headscale_proto_goTypes, - DependencyIndexes: file_v1_headscale_proto_depIdxs, - EnumInfos: file_v1_headscale_proto_enumTypes, - MessageInfos: file_v1_headscale_proto_msgTypes, - }.Build() - File_v1_headscale_proto = out.File - file_v1_headscale_proto_rawDesc = nil - file_v1_headscale_proto_goTypes = nil - file_v1_headscale_proto_depIdxs = nil -} diff --git a/gen/go/v1/headscale.pb.gw.go b/gen/go/v1/headscale.pb.gw.go deleted file mode 100644 index 4ae6db39..00000000 --- a/gen/go/v1/headscale.pb.gw.go +++ /dev/null @@ -1,185 +0,0 @@ -// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT. -// source: v1/headscale.proto - -/* -Package v1 is a reverse proxy. - -It translates gRPC into RESTful JSON APIs. -*/ -package v1 - -import ( - "context" - "io" - "net/http" - - "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" - "github.com/grpc-ecosystem/grpc-gateway/v2/utilities" - "google.golang.org/grpc" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/grpclog" - "google.golang.org/grpc/metadata" - "google.golang.org/grpc/status" - "google.golang.org/protobuf/proto" -) - -// Suppress "imported and not used" errors -var _ codes.Code -var _ io.Reader -var _ status.Status -var _ = runtime.String -var _ = utilities.NewDoubleArray -var _ = metadata.Join - -func request_HeadscaleService_GetMachine_0(ctx context.Context, marshaler runtime.Marshaler, client HeadscaleServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq GetMachineRequest - var metadata runtime.ServerMetadata - - var ( - val string - ok bool - err error - _ = err - ) - - val, ok = pathParams["machine_id"] - if !ok { - return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "machine_id") - } - - protoReq.MachineId, err = runtime.Uint64(val) - if err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "machine_id", err) - } - - msg, err := client.GetMachine(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) - return msg, metadata, err - -} - -func local_request_HeadscaleService_GetMachine_0(ctx context.Context, marshaler runtime.Marshaler, server HeadscaleServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq GetMachineRequest - var metadata runtime.ServerMetadata - - var ( - val string - ok bool - err error - _ = err - ) - - val, ok = pathParams["machine_id"] - if !ok { - return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "machine_id") - } - - protoReq.MachineId, err = runtime.Uint64(val) - if err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "machine_id", err) - } - - msg, err := server.GetMachine(ctx, &protoReq) - return msg, metadata, err - -} - -// RegisterHeadscaleServiceHandlerServer registers the http handlers for service HeadscaleService to "mux". -// UnaryRPC :call HeadscaleServiceServer directly. -// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. -// Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterHeadscaleServiceHandlerFromEndpoint instead. -func RegisterHeadscaleServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux, server HeadscaleServiceServer) error { - - mux.Handle("GET", pattern_HeadscaleService_GetMachine_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(req.Context()) - defer cancel() - var stream runtime.ServerTransportStream - ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) - inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/headscale.v1.HeadscaleService/GetMachine", runtime.WithHTTPPathPattern("/api/v1/machine/{machine_id}")) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - resp, md, err := local_request_HeadscaleService_GetMachine_0(rctx, inboundMarshaler, server, req, pathParams) - md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) - ctx = runtime.NewServerMetadataContext(ctx, md) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - - forward_HeadscaleService_GetMachine_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) - - }) - - return nil -} - -// RegisterHeadscaleServiceHandlerFromEndpoint is same as RegisterHeadscaleServiceHandler but -// automatically dials to "endpoint" and closes the connection when "ctx" gets done. -func RegisterHeadscaleServiceHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) { - conn, err := grpc.Dial(endpoint, opts...) - if err != nil { - return err - } - defer func() { - if err != nil { - if cerr := conn.Close(); cerr != nil { - grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) - } - return - } - go func() { - <-ctx.Done() - if cerr := conn.Close(); cerr != nil { - grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) - } - }() - }() - - return RegisterHeadscaleServiceHandler(ctx, mux, conn) -} - -// RegisterHeadscaleServiceHandler registers the http handlers for service HeadscaleService to "mux". -// The handlers forward requests to the grpc endpoint over "conn". -func RegisterHeadscaleServiceHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error { - return RegisterHeadscaleServiceHandlerClient(ctx, mux, NewHeadscaleServiceClient(conn)) -} - -// RegisterHeadscaleServiceHandlerClient registers the http handlers for service HeadscaleService -// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "HeadscaleServiceClient". -// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "HeadscaleServiceClient" -// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in -// "HeadscaleServiceClient" to call the correct interceptors. -func RegisterHeadscaleServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, client HeadscaleServiceClient) error { - - mux.Handle("GET", pattern_HeadscaleService_GetMachine_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(req.Context()) - defer cancel() - inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateContext(ctx, mux, req, "/headscale.v1.HeadscaleService/GetMachine", runtime.WithHTTPPathPattern("/api/v1/machine/{machine_id}")) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - resp, md, err := request_HeadscaleService_GetMachine_0(rctx, inboundMarshaler, client, req, pathParams) - ctx = runtime.NewServerMetadataContext(ctx, md) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - - forward_HeadscaleService_GetMachine_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) - - }) - - return nil -} - -var ( - pattern_HeadscaleService_GetMachine_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"api", "v1", "machine", "machine_id"}, "")) -) - -var ( - forward_HeadscaleService_GetMachine_0 = runtime.ForwardResponseMessage -) diff --git a/gen/go/v1/headscale_grpc.pb.go b/gen/go/v1/headscale_grpc.pb.go deleted file mode 100644 index 3028d183..00000000 --- a/gen/go/v1/headscale_grpc.pb.go +++ /dev/null @@ -1,101 +0,0 @@ -// Code generated by protoc-gen-go-grpc. DO NOT EDIT. - -package v1 - -import ( - context "context" - grpc "google.golang.org/grpc" - codes "google.golang.org/grpc/codes" - status "google.golang.org/grpc/status" -) - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the grpc package it is being compiled against. -// Requires gRPC-Go v1.32.0 or later. -const _ = grpc.SupportPackageIsVersion7 - -// HeadscaleServiceClient is the client API for HeadscaleService service. -// -// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. -type HeadscaleServiceClient interface { - GetMachine(ctx context.Context, in *GetMachineRequest, opts ...grpc.CallOption) (*Machine, error) -} - -type headscaleServiceClient struct { - cc grpc.ClientConnInterface -} - -func NewHeadscaleServiceClient(cc grpc.ClientConnInterface) HeadscaleServiceClient { - return &headscaleServiceClient{cc} -} - -func (c *headscaleServiceClient) GetMachine(ctx context.Context, in *GetMachineRequest, opts ...grpc.CallOption) (*Machine, error) { - out := new(Machine) - err := c.cc.Invoke(ctx, "/headscale.v1.HeadscaleService/GetMachine", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -// HeadscaleServiceServer is the server API for HeadscaleService service. -// All implementations must embed UnimplementedHeadscaleServiceServer -// for forward compatibility -type HeadscaleServiceServer interface { - GetMachine(context.Context, *GetMachineRequest) (*Machine, error) - mustEmbedUnimplementedHeadscaleServiceServer() -} - -// UnimplementedHeadscaleServiceServer must be embedded to have forward compatible implementations. -type UnimplementedHeadscaleServiceServer struct { -} - -func (UnimplementedHeadscaleServiceServer) GetMachine(context.Context, *GetMachineRequest) (*Machine, error) { - return nil, status.Errorf(codes.Unimplemented, "method GetMachine not implemented") -} -func (UnimplementedHeadscaleServiceServer) mustEmbedUnimplementedHeadscaleServiceServer() {} - -// UnsafeHeadscaleServiceServer may be embedded to opt out of forward compatibility for this service. -// Use of this interface is not recommended, as added methods to HeadscaleServiceServer will -// result in compilation errors. -type UnsafeHeadscaleServiceServer interface { - mustEmbedUnimplementedHeadscaleServiceServer() -} - -func RegisterHeadscaleServiceServer(s grpc.ServiceRegistrar, srv HeadscaleServiceServer) { - s.RegisterService(&HeadscaleService_ServiceDesc, srv) -} - -func _HeadscaleService_GetMachine_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(GetMachineRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(HeadscaleServiceServer).GetMachine(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/headscale.v1.HeadscaleService/GetMachine", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(HeadscaleServiceServer).GetMachine(ctx, req.(*GetMachineRequest)) - } - return interceptor(ctx, in, info, handler) -} - -// HeadscaleService_ServiceDesc is the grpc.ServiceDesc for HeadscaleService service. -// It's only intended for direct use with grpc.RegisterService, -// and not to be introspected or modified (even as a copy) -var HeadscaleService_ServiceDesc = grpc.ServiceDesc{ - ServiceName: "headscale.v1.HeadscaleService", - HandlerType: (*HeadscaleServiceServer)(nil), - Methods: []grpc.MethodDesc{ - { - MethodName: "GetMachine", - Handler: _HeadscaleService_GetMachine_Handler, - }, - }, - Streams: []grpc.StreamDesc{}, - Metadata: "v1/headscale.proto", -} diff --git a/gen/openapiv2/headscale/v1/rpc.swagger.json b/gen/openapiv2/headscale/v1/rpc.swagger.json new file mode 100644 index 00000000..e9db7cf6 --- /dev/null +++ b/gen/openapiv2/headscale/v1/rpc.swagger.json @@ -0,0 +1,250 @@ +{ + "swagger": "2.0", + "info": { + "title": "headscale/v1/rpc.proto", + "version": "version not set" + }, + "tags": [ + { + "name": "HeadscaleService" + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "paths": { + "/api/v1/machine/{machineId}": { + "get": { + "operationId": "HeadscaleService_GetMachine", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1GetMachineResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "machineId", + "in": "path", + "required": true, + "type": "string", + "format": "uint64" + } + ], + "tags": [ + "HeadscaleService" + ] + } + }, + "/api/v1/namespace": { + "get": { + "operationId": "HeadscaleService_ListNamespaces", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ListNamespacesResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "tags": [ + "HeadscaleService" + ] + }, + "delete": { + "operationId": "HeadscaleService_DeleteNamespace", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1DeleteNamespaceResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "name", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "HeadscaleService" + ] + }, + "post": { + "operationId": "HeadscaleService_CreateNamespace", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1CreateNamespaceResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1CreateNamespaceRequest" + } + } + ], + "tags": [ + "HeadscaleService" + ] + } + } + }, + "definitions": { + "protobufAny": { + "type": "object", + "properties": { + "@type": { + "type": "string" + } + }, + "additionalProperties": {} + }, + "rpcStatus": { + "type": "object", + "properties": { + "code": { + "type": "integer", + "format": "int32" + }, + "message": { + "type": "string" + }, + "details": { + "type": "array", + "items": { + "$ref": "#/definitions/protobufAny" + } + } + } + }, + "v1CreateNamespaceRequest": { + "type": "object", + "properties": { + "name": { + "type": "string" + } + } + }, + "v1CreateNamespaceResponse": { + "type": "object", + "properties": { + "name": { + "type": "string" + } + } + }, + "v1DeleteNamespaceResponse": { + "type": "object" + }, + "v1GetMachineResponse": { + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "uint64" + }, + "machineKey": { + "type": "string" + }, + "nodeKey": { + "type": "string" + }, + "discoKey": { + "type": "string" + }, + "ipAddress": { + "type": "string" + }, + "name": { + "type": "string" + }, + "namespaceId": { + "type": "integer", + "format": "int64" + }, + "registered": { + "type": "boolean" + }, + "registerMethod": { + "$ref": "#/definitions/v1RegisterMethod" + }, + "authKeyId": { + "type": "integer", + "format": "int64" + }, + "lastSeen": { + "type": "string", + "format": "date-time" + }, + "lastSuccessfulUpdate": { + "type": "string", + "format": "date-time" + }, + "expiry": { + "type": "string", + "format": "date-time" + } + } + }, + "v1ListNamespacesResponse": { + "type": "object", + "properties": { + "namespaces": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "v1RegisterMethod": { + "type": "string", + "enum": [ + "REGISTER_METHOD_UNSPECIFIED", + "REGISTER_METHOD_AUTH_KEY", + "REGISTER_METHOD_CLI", + "REGISTER_METHOD_OIDC" + ], + "default": "REGISTER_METHOD_UNSPECIFIED" + } + } +} diff --git a/gen/openapiv2/v1/headscale.swagger.json b/gen/openapiv2/v1/headscale.swagger.json deleted file mode 100644 index a20225d3..00000000 --- a/gen/openapiv2/v1/headscale.swagger.json +++ /dev/null @@ -1,210 +0,0 @@ -{ - "swagger": "2.0", - "info": { - "title": "v1/headscale.proto", - "version": "version not set" - }, - "tags": [ - { - "name": "HeadscaleService" - } - ], - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "paths": { - "/api/v1/machine/{machineId}": { - "get": { - "operationId": "HeadscaleService_GetMachine", - "responses": { - "200": { - "description": "A successful response.", - "schema": { - "$ref": "#/definitions/v1Machine" - } - }, - "default": { - "description": "An unexpected error response.", - "schema": { - "$ref": "#/definitions/rpcStatus" - } - } - }, - "parameters": [ - { - "name": "machineId", - "in": "path", - "required": true, - "type": "string", - "format": "uint64" - } - ], - "tags": [ - "HeadscaleService" - ] - } - } - }, - "definitions": { - "protobufAny": { - "type": "object", - "properties": { - "@type": { - "type": "string" - } - }, - "additionalProperties": {} - }, - "rpcStatus": { - "type": "object", - "properties": { - "code": { - "type": "integer", - "format": "int32" - }, - "message": { - "type": "string" - }, - "details": { - "type": "array", - "items": { - "$ref": "#/definitions/protobufAny" - } - } - } - }, - "v1Machine": { - "type": "object", - "properties": { - "ID": { - "type": "string", - "format": "uint64" - }, - "MachineKey": { - "type": "string" - }, - "NodeKey": { - "type": "string" - }, - "DiscoKey": { - "type": "string" - }, - "IPAddress": { - "type": "string" - }, - "Name": { - "type": "string" - }, - "NamespaceID": { - "type": "integer", - "format": "int64" - }, - "Registered": { - "type": "boolean" - }, - "RegisterMethod": { - "$ref": "#/definitions/v1RegisterMethod" - }, - "AuthKeyID": { - "type": "integer", - "format": "int64" - }, - "AuthKey": { - "$ref": "#/definitions/v1PreAuthKey" - }, - "LastSeen": { - "type": "string", - "format": "date-time" - }, - "LastSuccessfulUpdate": { - "type": "string", - "format": "date-time" - }, - "Expiry": { - "type": "string", - "format": "date-time" - }, - "HostInfo": { - "type": "string", - "format": "byte" - }, - "Endpoints": { - "type": "string", - "format": "byte" - }, - "EnabledRoutes": { - "type": "string", - "format": "byte" - }, - "CreatedAt": { - "type": "string", - "format": "date-time" - }, - "UpdatedAt": { - "type": "string", - "format": "date-time" - }, - "DeletedAt": { - "type": "string", - "format": "date-time" - } - } - }, - "v1Namespace": { - "type": "object", - "properties": { - "Name": { - "type": "string" - } - } - }, - "v1PreAuthKey": { - "type": "object", - "properties": { - "ID": { - "type": "string", - "format": "uint64" - }, - "Key": { - "type": "string" - }, - "NamespaceID": { - "type": "integer", - "format": "int64" - }, - "Namespace": { - "$ref": "#/definitions/v1Namespace" - }, - "Reusable": { - "type": "boolean" - }, - "Ephemeral": { - "type": "boolean" - }, - "Used": { - "type": "boolean" - }, - "CreatedAt": { - "type": "string", - "format": "date-time" - }, - "Expiration": { - "type": "string", - "format": "date-time" - } - } - }, - "v1RegisterMethod": { - "type": "string", - "enum": [ - "AUTH_KEY", - "CLI", - "OIDC" - ], - "default": "AUTH_KEY" - } - } -} diff --git a/proto/headscale/v1/rpc.proto b/proto/headscale/v1/rpc.proto new file mode 100644 index 00000000..2e6b0a67 --- /dev/null +++ b/proto/headscale/v1/rpc.proto @@ -0,0 +1,106 @@ +syntax = "proto3"; +package headscale.v1; +option go_package = "github.com/juanfont/headscale/gen/go/v1"; + +import "google/protobuf/timestamp.proto"; +import "google/api/annotations.proto"; + +enum RegisterMethod { + REGISTER_METHOD_UNSPECIFIED = 0; + REGISTER_METHOD_AUTH_KEY = 1; + REGISTER_METHOD_CLI = 2; + REGISTER_METHOD_OIDC = 3; +} + +// message PreAuthKey { +// uint64 id = 1; +// string key = 2; +// uint32 namespace_id = 3; +// Namespace namespace = 4; +// bool reusable = 5; +// bool ephemeral = 6; +// bool used = 7; +// +// google.protobuf.Timestamp created_at = 8; +// google.protobuf.Timestamp expiration = 9; +// } + +message GetMachineRequest { + uint64 machine_id = 1; +} + +message GetMachineResponse { + uint64 id = 1; + string machine_key = 2; + string node_key = 3; + string disco_key = 4; + string ip_address = 5; + string name = 6; + uint32 namespace_id = 7; + + bool registered = 8; + RegisterMethod register_method = 9; + uint32 auth_key_id = 10; + // PreAuthKey auth_key = 11; + + google.protobuf.Timestamp last_seen = 12; + google.protobuf.Timestamp last_successful_update = 13; + google.protobuf.Timestamp expiry = 14; + + // bytes host_info = 15; + // bytes endpoints = 16; + // bytes enabled_routes = 17; + + // google.protobuf.Timestamp created_at = 18; + // google.protobuf.Timestamp updated_at = 19; + // google.protobuf.Timestamp deleted_at = 20; +} + +message CreateNamespaceRequest { + string name = 1; +} + +message CreateNamespaceResponse { + string name = 1; +} + +message DeleteNamespaceRequest { + string name = 1; +} + +message DeleteNamespaceResponse { +} + +message ListNamespacesRequest { +} + +message ListNamespacesResponse { + repeated string namespaces = 1; +} + +service HeadscaleService { + rpc GetMachine(GetMachineRequest) returns(GetMachineResponse) { + option(google.api.http) = { + get : "/api/v1/machine/{machine_id}" + }; + } + + rpc CreateNamespace(CreateNamespaceRequest) returns(CreateNamespaceResponse) { + option(google.api.http) = { + post : "/api/v1/namespace" + body : "*" + }; + } + + rpc DeleteNamespace(DeleteNamespaceRequest) returns(DeleteNamespaceResponse) { + option(google.api.http) = { + delete : "/api/v1/namespace" + }; + } + + rpc ListNamespaces(ListNamespacesRequest) returns(ListNamespacesResponse) { + option(google.api.http) = { + get : "/api/v1/namespace" + }; + } +} diff --git a/proto/v1/headscale.proto b/proto/v1/headscale.proto deleted file mode 100644 index b6356b8f..00000000 --- a/proto/v1/headscale.proto +++ /dev/null @@ -1,71 +0,0 @@ -syntax = "proto3"; -package headscale.v1; -option go_package = "github.com/juanfont/headscale/gen/go/v1"; - -import "google/protobuf/timestamp.proto"; -import "google/api/annotations.proto"; -import "options/gorm.proto"; - -enum RegisterMethod { - AUTH_KEY = 0; - CLI = 1; - OIDC = 2; -} - -message Namespace { - string Name = 1; -} - -message PreAuthKey { - uint64 ID = 1; - string Key = 2; - uint32 NamespaceID = 3; - Namespace Namespace = 4; - bool Reusable = 5; - bool Ephemeral = 6; - bool Used = 7; - - google.protobuf.Timestamp CreatedAt = 8; - google.protobuf.Timestamp Expiration = 9; -} - -message GetMachineRequest { - uint64 machine_id = 1; -} - -message Machine { - option(gorm.opts).ormable = true; - uint64 ID = 1; - string MachineKey = 2; - string NodeKey = 3; - string DiscoKey = 4; - string IPAddress = 5; - string Name = 6; - uint32 NamespaceID = 7; - - bool Registered = 8; - RegisterMethod RegisterMethod = 9; - uint32 AuthKeyID = 10; - PreAuthKey AuthKey = 11; - - google.protobuf.Timestamp LastSeen = 12; - google.protobuf.Timestamp LastSuccessfulUpdate = 13; - google.protobuf.Timestamp Expiry = 14; - - bytes HostInfo = 15; - bytes Endpoints = 16; - bytes EnabledRoutes = 17; - - google.protobuf.Timestamp CreatedAt = 18; - google.protobuf.Timestamp UpdatedAt = 19; - google.protobuf.Timestamp DeletedAt = 20; -} - -// Gin Router will prefix this with /api/v1 -service HeadscaleService { - rpc GetMachine(GetMachineRequest) returns(Machine) { - option(google.api.http) = { - get : "/api/v1/machine/{machine_id}" - }; - } -} From c7fa9b6e4a7593eb37d729f158225cf4139fe6fd Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Fri, 29 Oct 2021 16:44:32 +0000 Subject: [PATCH 043/300] Setup create, delete and list namespace over grpc --- grpcv1.go | 51 ++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 46 insertions(+), 5 deletions(-) diff --git a/grpcv1.go b/grpcv1.go index 5fc2e1c8..08c977b8 100644 --- a/grpcv1.go +++ b/grpcv1.go @@ -4,7 +4,7 @@ package headscale import ( "context" - apiV1 "github.com/juanfont/headscale/gen/go/v1" + apiV1 "github.com/juanfont/headscale/gen/go/headscale/v1" ) type headscaleV1APIServer struct { // apiV1.HeadscaleServiceServer @@ -21,14 +21,55 @@ func newHeadscaleV1APIServer(h *Headscale) apiV1.HeadscaleServiceServer { func (api headscaleV1APIServer) GetMachine( ctx context.Context, request *apiV1.GetMachineRequest, -) (*apiV1.Machine, error) { - m, err := api.h.GetMachineByID(request.MachineId) +) (*apiV1.GetMachineResponse, error) { + // m, err := api.h.GetMachineByID(request.MachineId) + // if err != nil { + // return nil, err + // } + + // TODO(kradalby): Make this function actually do something + return &apiV1.GetMachineResponse{Name: "test"}, nil +} + +func (api headscaleV1APIServer) CreateNamespace( + ctx context.Context, + request *apiV1.CreateNamespaceRequest, +) (*apiV1.CreateNamespaceResponse, error) { + namespace, err := api.h.CreateNamespace(request.Name) if err != nil { return nil, err } - // TODO(kradalby): Make this function actually do something - return &apiV1.Machine{Name: m.Name}, nil + return &apiV1.CreateNamespaceResponse{Name: namespace.Name}, nil +} + +func (api headscaleV1APIServer) DeleteNamespace( + ctx context.Context, + request *apiV1.DeleteNamespaceRequest, +) (*apiV1.DeleteNamespaceResponse, error) { + err := api.h.DestroyNamespace(request.Name) + if err != nil { + return nil, err + } + + return &apiV1.DeleteNamespaceResponse{}, nil +} + +func (api headscaleV1APIServer) ListNamespaces( + ctx context.Context, + request *apiV1.ListNamespacesRequest, +) (*apiV1.ListNamespacesResponse, error) { + namespaces, err := api.h.ListNamespaces() + if err != nil { + return nil, err + } + + response := make([]string, len(*namespaces)) + for index, namespace := range *namespaces { + response[index] = namespace.Name + } + + return &apiV1.ListNamespacesResponse{Namespaces: response}, nil } func (api headscaleV1APIServer) mustEmbedUnimplementedHeadscaleServiceServer() {} From a23d82e33af1117160a43d48249359eb54b55540 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Fri, 29 Oct 2021 16:45:06 +0000 Subject: [PATCH 044/300] Setup API and prepare for API keys This commit sets up the API and gRPC endpoints and adds authentication to them. Currently there is no actual authentication implemented but it has been prepared for API keys. In addition, there is a allow put in place for gRPC traffic over localhost. This has two purposes: 1. grpc-gateway, which is the base of the API, connects to the gRPC service over localhost. 2. We do not want to break current "on server" behaviour which allows users to use the cli on the server without any fuzz --- app.go | 175 +++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 163 insertions(+), 12 deletions(-) diff --git a/app.go b/app.go index dbe30168..eedc8739 100644 --- a/app.go +++ b/app.go @@ -5,6 +5,7 @@ import ( "crypto/tls" "errors" "fmt" + "io" "net" "net/http" "net/url" @@ -16,7 +17,7 @@ import ( "github.com/gin-gonic/gin" "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" - apiV1 "github.com/juanfont/headscale/gen/go/v1" + apiV1 "github.com/juanfont/headscale/gen/go/headscale/v1" "github.com/rs/zerolog/log" "github.com/soheilhy/cmux" ginprometheus "github.com/zsais/go-gin-prometheus" @@ -24,6 +25,12 @@ import ( "golang.org/x/crypto/acme/autocert" "golang.org/x/sync/errgroup" "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/credentials" + "google.golang.org/grpc/metadata" + "google.golang.org/grpc/peer" + "google.golang.org/grpc/reflection" + "google.golang.org/grpc/status" "gorm.io/gorm" "inet.af/netaddr" "tailscale.com/tailcfg" @@ -31,6 +38,12 @@ import ( "tailscale.com/types/wgkey" ) +const ( + LOCALHOST_V4 = "127.0.0.1" + LOCALHOST_V6 = "[::1]" + AUTH_PREFIX = "Bearer " +) + // Config contains the initial Headscale configuration. type Config struct { ServerURL string @@ -208,6 +221,110 @@ func (h *Headscale) watchForKVUpdatesWorker() { // more functions will come here in the future } +func IsLocalhost(host string) bool { + if strings.Contains(host, LOCALHOST_V4) || strings.Contains(host, LOCALHOST_V6) { + return true + } + + return false +} + +func (h *Headscale) grpcAuthenticationInterceptor(ctx context.Context, + req interface{}, + info *grpc.UnaryServerInfo, + handler grpc.UnaryHandler) (interface{}, error) { + + // Check if the request is coming from the on-server client. + // This is not secure, but it is to maintain maintainability + // with the "legacy" database-based client + // It is also neede for grpc-gateway to be able to connect to + // the server + p, _ := peer.FromContext(ctx) + + if IsLocalhost(p.Addr.String()) { + log.Trace().Caller().Str("client_address", p.Addr.String()).Msg("Client connected from localhost") + + return handler(ctx, req) + } + + log.Trace().Caller().Str("client_address", p.Addr.String()).Msg("Client is trying to authenticate") + + md, ok := metadata.FromIncomingContext(ctx) + if !ok { + log.Error().Caller().Str("client_address", p.Addr.String()).Msg("Retrieving metadata is failed") + return ctx, status.Errorf(codes.InvalidArgument, "Retrieving metadata is failed") + } + + authHeader, ok := md["authorization"] + if !ok { + log.Error().Caller().Str("client_address", p.Addr.String()).Msg("Authorization token is not supplied") + return ctx, status.Errorf(codes.Unauthenticated, "Authorization token is not supplied") + } + + token := authHeader[0] + + if !strings.HasPrefix(token, AUTH_PREFIX) { + log.Error(). + Caller(). + Str("client_address", p.Addr.String()). + Msg(`missing "Bearer " prefix in "Authorization" header`) + return ctx, status.Error(codes.Unauthenticated, `missing "Bearer " prefix in "Authorization" header`) + } + + // TODO(kradalby): Implement API key backend: + // - Table in the DB + // - Key name + // - Encrypted + // - Expiry + // + // Currently all other than localhost traffic is unauthorized, this is intentional to allow + // us to make use of gRPC for our CLI, but not having to implement any of the remote capabilities + // and API key auth + return ctx, status.Error(codes.Unauthenticated, "Authentication is not implemented yet") + + //if strings.TrimPrefix(token, AUTH_PREFIX) != a.Token { + // log.Error().Caller().Str("client_address", p.Addr.String()).Msg("invalid token") + // return ctx, status.Error(codes.Unauthenticated, "invalid token") + //} + + // return handler(ctx, req) +} + +func (h *Headscale) httpAuthenticationMiddleware(c *gin.Context) { + log.Trace(). + Caller(). + Str("client_address", c.ClientIP()). + Msg("HTTP authentication invoked") + + authHeader := c.GetHeader("authorization") + + if !strings.HasPrefix(authHeader, AUTH_PREFIX) { + log.Error(). + Caller(). + Str("client_address", c.ClientIP()). + Msg(`missing "Bearer " prefix in "Authorization" header`) + c.AbortWithStatus(http.StatusUnauthorized) + + return + } + + c.AbortWithStatus(http.StatusUnauthorized) + + // TODO(kradalby): Implement API key backend + // Currently all traffic is unauthorized, this is intentional to allow + // us to make use of gRPC for our CLI, but not having to implement any of the remote capabilities + // and API key auth + // + // if strings.TrimPrefix(authHeader, AUTH_PREFIX) != a.Token { + // log.Error().Caller().Str("client_address", c.ClientIP()).Msg("invalid token") + // c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"error", "unauthorized"}) + + // return + // } + + // c.Next() +} + // Serve launches a GIN server with the Headscale API. func (h *Headscale) Serve() error { var err error @@ -226,21 +343,25 @@ func (h *Headscale) Serve() error { // The two following listeners will be served on the same port below gracefully. m := cmux.New(l) // Match gRPC requests here - grpcListener := m.MatchWithWriters(cmux.HTTP2MatchHeaderFieldSendSettings("content-type", "application/grpc")) + grpcListener := m.MatchWithWriters( + cmux.HTTP2MatchHeaderFieldSendSettings("content-type", "application/grpc"), + cmux.HTTP2MatchHeaderFieldSendSettings("content-type", "application/grpc+proto"), + ) // Otherwise match regular http requests. httpListener := m.Match(cmux.Any()) - // Now create the grpc server with those options. - grpcServer := grpc.NewServer() - - // TODO(kradalby): register the new server when we have authentication ready - // apiV1.RegisterHeadscaleServiceServer(grpcServer, newHeadscaleV1APIServer(h)) - grpcGatewayMux := runtime.NewServeMux() - opts := []grpc.DialOption{grpc.WithInsecure()} + grpcDialOptions := []grpc.DialOption{grpc.WithInsecure()} - err = apiV1.RegisterHeadscaleServiceHandlerFromEndpoint(ctx, grpcGatewayMux, h.cfg.Addr, opts) + _, port, err := net.SplitHostPort(h.cfg.Addr) + if err != nil { + return err + } + + // Connect to the gRPC server over localhost to skip + // the authentication. + err = apiV1.RegisterHeadscaleServiceHandlerFromEndpoint(ctx, grpcGatewayMux, LOCALHOST_V4+":"+port, grpcDialOptions) if err != nil { return err } @@ -258,10 +379,15 @@ func (h *Headscale) Serve() error { r.GET("/apple", h.AppleMobileConfig) r.GET("/apple/:platform", h.ApplePlatformConfig) - r.Any("/api/v1/*any", gin.WrapF(grpcGatewayMux.ServeHTTP)) r.StaticFile("/swagger/swagger.json", "gen/openapiv2/v1/headscale.swagger.json") - updateMillisecondsWait := int64(5000) + api := r.Group("/api") + api.Use(h.httpAuthenticationMiddleware) + { + api.Any("/v1/*any", gin.WrapF(grpcGatewayMux.ServeHTTP)) + } + + r.NoRoute(stdoutHandler) // Fetch an initial DERP Map before we start serving h.DERPMap = GetDERPMap(h.cfg.DERP) @@ -273,6 +399,7 @@ func (h *Headscale) Serve() error { } // I HATE THIS + updateMillisecondsWait := int64(5000) go h.watchForKVUpdates(updateMillisecondsWait) go h.expireEphemeralNodes(updateMillisecondsWait) @@ -287,6 +414,12 @@ func (h *Headscale) Serve() error { WriteTimeout: 0, } + grpcOptions := []grpc.ServerOption{ + grpc.UnaryInterceptor( + h.grpcAuthenticationInterceptor, + ), + } + tlsConfig, err := h.getTLSSettings() if err != nil { log.Error().Err(err).Msg("Failed to set up TLS configuration") @@ -296,8 +429,15 @@ func (h *Headscale) Serve() error { if tlsConfig != nil { httpServer.TLSConfig = tlsConfig + + grpcOptions = append(grpcOptions, grpc.Creds(credentials.NewTLS(tlsConfig))) } + grpcServer := grpc.NewServer(grpcOptions...) + + apiV1.RegisterHeadscaleServiceServer(grpcServer, newHeadscaleV1APIServer(h)) + reflection.Register(grpcServer) + g := new(errgroup.Group) g.Go(func() error { return grpcServer.Serve(grpcListener) }) @@ -394,3 +534,14 @@ func (h *Headscale) getLastStateChange(namespaces ...string) time.Time { return times[0] } } + +func stdoutHandler(c *gin.Context) { + b, _ := io.ReadAll(c.Request.Body) + + log.Trace(). + Interface("header", c.Request.Header). + Interface("proto", c.Request.Proto). + Interface("url", c.Request.URL). + Bytes("body", b). + Msg("Request did not match") +} From 6d10be8fff95989dc52ec53bb478a0fbb51a1ad1 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Fri, 29 Oct 2021 16:49:44 +0000 Subject: [PATCH 045/300] Change order of print/nil check in integration test --- integration_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integration_test.go b/integration_test.go index 53092423..56088765 100644 --- a/integration_test.go +++ b/integration_test.go @@ -282,8 +282,8 @@ func (s *IntegrationTestSuite) SetupSuite() { []string{"headscale", "namespaces", "create", namespace}, []string{}, ) - assert.Nil(s.T(), err) fmt.Println("headscale create namespace result: ", result) + assert.Nil(s.T(), err) fmt.Printf("Creating pre auth key for %s\n", namespace) authKey, err := executeCommand( From 68dab0fe7b68e0abf8a3f78d42194c4f8b88de67 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Fri, 29 Oct 2021 17:04:58 +0000 Subject: [PATCH 046/300] Move localhost check to utils --- app.go | 8 -------- utils.go | 8 ++++++++ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/app.go b/app.go index eedc8739..c77a85a5 100644 --- a/app.go +++ b/app.go @@ -221,14 +221,6 @@ func (h *Headscale) watchForKVUpdatesWorker() { // more functions will come here in the future } -func IsLocalhost(host string) bool { - if strings.Contains(host, LOCALHOST_V4) || strings.Contains(host, LOCALHOST_V6) { - return true - } - - return false -} - func (h *Headscale) grpcAuthenticationInterceptor(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, diff --git a/utils.go b/utils.go index cbe1d870..1aa31712 100644 --- a/utils.go +++ b/utils.go @@ -156,3 +156,11 @@ func tailNodesToString(nodes []*tailcfg.Node) string { func tailMapResponseToString(resp tailcfg.MapResponse) string { return fmt.Sprintf("{ Node: %s, Peers: %s }", resp.Node.Name, tailNodesToString(resp.Peers)) } + +func IsLocalhost(host string) bool { + if strings.Contains(host, LOCALHOST_V4) || strings.Contains(host, LOCALHOST_V6) { + return true + } + + return false +} From 002b5c1dad9ba24baa4b54edab586c5f49136152 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Fri, 29 Oct 2021 17:08:21 +0000 Subject: [PATCH 047/300] Add grpc token auth struct --- cmd/headscale/cli/utils.go | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/cmd/headscale/cli/utils.go b/cmd/headscale/cli/utils.go index 0768e1eb..30d5d83a 100644 --- a/cmd/headscale/cli/utils.go +++ b/cmd/headscale/cli/utils.go @@ -312,3 +312,18 @@ func HasJsonOutputFlag() bool { } return false } + +type tokenAuth struct { + token string +} + +// Return value is mapped to request headers. +func (t tokenAuth) GetRequestMetadata(ctx context.Context, in ...string) (map[string]string, error) { + return map[string]string{ + "authorization": "Bearer " + t.token, + }, nil +} + +func (tokenAuth) RequireTransportSecurity() bool { + return true +} From eefd82a574b475c654e2a0a467fc2e828938f8cc Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Fri, 29 Oct 2021 17:09:06 +0000 Subject: [PATCH 048/300] Move config loading out of the headscale app setup --- cmd/headscale/cli/utils.go | 37 +++++++++++++++++++++++-------------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/cmd/headscale/cli/utils.go b/cmd/headscale/cli/utils.go index 30d5d83a..f2053c93 100644 --- a/cmd/headscale/cli/utils.go +++ b/cmd/headscale/cli/utils.go @@ -1,18 +1,23 @@ package cli import ( + "context" "encoding/json" "errors" "fmt" + "net" "net/url" "os" "path/filepath" + "strconv" "strings" "time" "github.com/juanfont/headscale" + apiV1 "github.com/juanfont/headscale/gen/go/headscale/v1" "github.com/rs/zerolog/log" "github.com/spf13/viper" + "google.golang.org/grpc" "inet.af/netaddr" "tailscale.com/tailcfg" "tailscale.com/types/dnstype" @@ -202,23 +207,11 @@ func absPath(path string) string { return path } -func getHeadscaleApp() (*headscale.Headscale, error) { - // Minimum inactivity time out is keepalive timeout (60s) plus a few seconds - // to avoid races - minInactivityTimeout, _ := time.ParseDuration("65s") - if viper.GetDuration("ephemeral_node_inactivity_timeout") <= minInactivityTimeout { - err := fmt.Errorf( - "ephemeral_node_inactivity_timeout (%s) is set too low, must be more than %s\n", - viper.GetString("ephemeral_node_inactivity_timeout"), - minInactivityTimeout, - ) - return nil, err - } - +func getHeadscaleConfig() headscale.Config { dnsConfig, baseDomain := GetDNSConfig() derpConfig := GetDERPConfig() - cfg := headscale.Config{ + return headscale.Config{ ServerURL: viper.GetString("server_url"), Addr: viper.GetString("listen_addr"), PrivateKeyPath: absPath(viper.GetString("private_key_path")), @@ -250,6 +243,22 @@ func getHeadscaleApp() (*headscale.Headscale, error) { ACMEEmail: viper.GetString("acme_email"), ACMEURL: viper.GetString("acme_url"), } +} + +func getHeadscaleApp() (*headscale.Headscale, error) { + // Minimum inactivity time out is keepalive timeout (60s) plus a few seconds + // to avoid races + minInactivityTimeout, _ := time.ParseDuration("65s") + if viper.GetDuration("ephemeral_node_inactivity_timeout") <= minInactivityTimeout { + err := fmt.Errorf( + "ephemeral_node_inactivity_timeout (%s) is set too low, must be more than %s\n", + viper.GetString("ephemeral_node_inactivity_timeout"), + minInactivityTimeout, + ) + return nil, err + } + + cfg := getHeadscaleConfig() h, err := headscale.NewHeadscale(cfg) if err != nil { From 81b8610dff579b1516f6fe579eff7e3811a9f332 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Fri, 29 Oct 2021 17:15:52 +0000 Subject: [PATCH 049/300] Add helper function to setup grpc client for cli --- cmd/headscale/cli/utils.go | 58 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/cmd/headscale/cli/utils.go b/cmd/headscale/cli/utils.go index f2053c93..829f4c68 100644 --- a/cmd/headscale/cli/utils.go +++ b/cmd/headscale/cli/utils.go @@ -281,6 +281,64 @@ func getHeadscaleApp() (*headscale.Headscale, error) { return h, nil } +func getHeadscaleGRPCClient() (apiV1.HeadscaleServiceClient, *grpc.ClientConn) { + grpcOptions := []grpc.DialOption{ + // TODO(kradalby): Make configurable + grpc.WithTimeout(5 * time.Second), + grpc.WithBlock(), + } + + address := os.Getenv("HEADSCALE_ADDRESS") + + // If the address is not set, we assume that we are on the server hosting headscale. + if address == "" { + log.Debug().Msgf("HEADSCALE_ADDRESS environment is not set, connecting to localhost.") + + cfg := getHeadscaleConfig() + + _, port, _ := net.SplitHostPort(cfg.Addr) + + address = "127.0.0.1" + ":" + port + + grpcOptions = append(grpcOptions, grpc.WithInsecure()) + } + + // If we are not connecting to a local server, require an API key for authentication + if !headscale.IsLocalhost(address) { + apiKey := os.Getenv("HEADSCALE_API_KEY") + if apiKey == "" { + log.Fatal().Msgf("HEADSCALE_API_KEY environment variable needs to be set.") + } + grpcOptions = append(grpcOptions, + grpc.WithPerRPCCredentials(tokenAuth{ + token: apiKey, + }), + ) + + insecureStr := os.Getenv("HEADSCALE_INSECURE") + if insecureStr != "" { + insecure, err := strconv.ParseBool(insecureStr) + if err != nil { + log.Fatal().Err(err).Msgf("Failed to parse HEADSCALE_INSECURE: %v", err) + } + + if insecure { + grpcOptions = append(grpcOptions, grpc.WithInsecure()) + } + } + } + + log.Trace().Caller().Str("address", address).Msg("Connecting via gRPC") + conn, err := grpc.Dial(address, grpcOptions...) + if err != nil { + log.Fatal().Err(err).Msgf("Could not connect: %v", err) + } + + client := apiV1.NewHeadscaleServiceClient(conn) + + return client, conn +} + func JsonOutput(result interface{}, errResult error, outputFormat string) { var j []byte var err error From 9ef031f0f841cb9fb93d7350857f9b7882f2b7f1 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Fri, 29 Oct 2021 17:16:54 +0000 Subject: [PATCH 050/300] Port create, delete and list of namespace to grpc --- cmd/headscale/cli/namespaces.go | 38 ++++++++++++++++++++++----------- 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/cmd/headscale/cli/namespaces.go b/cmd/headscale/cli/namespaces.go index 42870370..044347fe 100644 --- a/cmd/headscale/cli/namespaces.go +++ b/cmd/headscale/cli/namespaces.go @@ -1,12 +1,15 @@ package cli import ( + "context" "fmt" - "log" "strconv" "strings" + "time" + apiV1 "github.com/juanfont/headscale/gen/go/headscale/v1" "github.com/pterm/pterm" + "github.com/rs/zerolog/log" "github.com/spf13/cobra" ) @@ -34,13 +37,21 @@ var createNamespaceCmd = &cobra.Command{ }, Run: func(cmd *cobra.Command, args []string) { o, _ := cmd.Flags().GetString("output") - h, err := getHeadscaleApp() - if err != nil { - log.Fatalf("Error initializing: %s", err) - } - namespace, err := h.CreateNamespace(args[0]) + + client, conn := getHeadscaleGRPCClient() + defer conn.Close() + + log.Trace().Interface("client", client).Msg("Obtained gRPC client") + + ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) + defer cancel() + + request := &apiV1.CreateNamespaceRequest{Name: args[0]} + + log.Trace().Interface("request", request).Msg("Sending CreateNamespace request") + response, err := client.CreateNamespace(ctx, request) if strings.HasPrefix(o, "json") { - JsonOutput(namespace, err, o) + JsonOutput(response.Name, err, o) return } if err != nil { @@ -64,7 +75,7 @@ var destroyNamespaceCmd = &cobra.Command{ o, _ := cmd.Flags().GetString("output") h, err := getHeadscaleApp() if err != nil { - log.Fatalf("Error initializing: %s", err) + log.Fatal().Err(err).Msgf("Error initializing: %s", err) } err = h.DestroyNamespace(args[0]) if strings.HasPrefix(o, "json") { @@ -86,7 +97,7 @@ var listNamespacesCmd = &cobra.Command{ o, _ := cmd.Flags().GetString("output") h, err := getHeadscaleApp() if err != nil { - log.Fatalf("Error initializing: %s", err) + log.Fatal().Err(err).Msgf("Error initializing: %s", err) } namespaces, err := h.ListNamespaces() if strings.HasPrefix(o, "json") { @@ -100,11 +111,14 @@ var listNamespacesCmd = &cobra.Command{ d := pterm.TableData{{"ID", "Name", "Created"}} for _, n := range *namespaces { - d = append(d, []string{strconv.FormatUint(uint64(n.ID), 10), n.Name, n.CreatedAt.Format("2006-01-02 15:04:05")}) + d = append( + d, + []string{strconv.FormatUint(uint64(n.ID), 10), n.Name, n.CreatedAt.Format("2006-01-02 15:04:05")}, + ) } err = pterm.DefaultTable.WithHasHeader().WithData(d).Render() if err != nil { - log.Fatal(err) + log.Fatal().Err(err).Msg("") } }, } @@ -122,7 +136,7 @@ var renameNamespaceCmd = &cobra.Command{ o, _ := cmd.Flags().GetString("output") h, err := getHeadscaleApp() if err != nil { - log.Fatalf("Error initializing: %s", err) + log.Fatal().Err(err).Msgf("Error initializing: %s", err) } err = h.RenameNamespace(args[0], args[1]) if strings.HasPrefix(o, "json") { From 72fd2a2780388496ded857b566797855735c162e Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Fri, 29 Oct 2021 17:36:11 +0000 Subject: [PATCH 051/300] Fix lint error --- cmd/headscale/cli/utils.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/cmd/headscale/cli/utils.go b/cmd/headscale/cli/utils.go index 829f4c68..14ff2bf2 100644 --- a/cmd/headscale/cli/utils.go +++ b/cmd/headscale/cli/utils.go @@ -282,9 +282,11 @@ func getHeadscaleApp() (*headscale.Headscale, error) { } func getHeadscaleGRPCClient() (apiV1.HeadscaleServiceClient, *grpc.ClientConn) { + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + grpcOptions := []grpc.DialOption{ // TODO(kradalby): Make configurable - grpc.WithTimeout(5 * time.Second), grpc.WithBlock(), } @@ -329,7 +331,7 @@ func getHeadscaleGRPCClient() (apiV1.HeadscaleServiceClient, *grpc.ClientConn) { } log.Trace().Caller().Str("address", address).Msg("Connecting via gRPC") - conn, err := grpc.Dial(address, grpcOptions...) + conn, err := grpc.DialContext(ctx, address, grpcOptions...) if err != nil { log.Fatal().Err(err).Msgf("Could not connect: %v", err) } From 6aacada85231b5fa6a793018a150aac22611ff66 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Sat, 30 Oct 2021 14:08:16 +0000 Subject: [PATCH 052/300] Switch from gRPC localhost to socket This commit changes the way CLI and grpc-gateway communicates with the gRPC backend to socket, instead of localhost. Unauthenticated access now goes on the socket, while the network interface will require API key (in the future). --- .dockerignore | 2 + app.go | 36 ++++++++---- cmd/headscale/cli/utils.go | 27 ++++++--- config-example.yaml | 5 ++ proto/headscale/v1/rpc.proto | 106 ----------------------------------- utils.go | 8 --- 6 files changed, 50 insertions(+), 134 deletions(-) delete mode 100644 proto/headscale/v1/rpc.proto diff --git a/.dockerignore b/.dockerignore index 33f9aea2..057a20e7 100644 --- a/.dockerignore +++ b/.dockerignore @@ -14,3 +14,5 @@ docker-compose* README.md LICENSE .vscode + +*.sock diff --git a/app.go b/app.go index c77a85a5..94517d54 100644 --- a/app.go +++ b/app.go @@ -39,9 +39,7 @@ import ( ) const ( - LOCALHOST_V4 = "127.0.0.1" - LOCALHOST_V6 = "[::1]" - AUTH_PREFIX = "Bearer " + AUTH_PREFIX = "Bearer " ) // Config contains the initial Headscale configuration. @@ -75,6 +73,8 @@ type Config struct { ACMEEmail string DNSConfig *tailcfg.DNSConfig + + UnixSocket string } type DERPConfig struct { @@ -233,8 +233,9 @@ func (h *Headscale) grpcAuthenticationInterceptor(ctx context.Context, // the server p, _ := peer.FromContext(ctx) - if IsLocalhost(p.Addr.String()) { - log.Trace().Caller().Str("client_address", p.Addr.String()).Msg("Client connected from localhost") + // TODO(kradalby): Figure out what @ means (socket wise) and if it can be exploited + if p.Addr.String() == "@" { + log.Trace().Caller().Str("client_address", p.Addr.String()).Msg("Client connecting over socket") return handler(ctx, req) } @@ -326,14 +327,19 @@ func (h *Headscale) Serve() error { defer cancel() - l, err := net.Listen("tcp", h.cfg.Addr) + socketListener, err := net.Listen("unix", h.cfg.UnixSocket) + if err != nil { + panic(err) + } + + networkListener, err := net.Listen("tcp", h.cfg.Addr) if err != nil { panic(err) } // Create the cmux object that will multiplex 2 protocols on the same port. // The two following listeners will be served on the same port below gracefully. - m := cmux.New(l) + m := cmux.New(networkListener) // Match gRPC requests here grpcListener := m.MatchWithWriters( cmux.HTTP2MatchHeaderFieldSendSettings("content-type", "application/grpc"), @@ -344,16 +350,23 @@ func (h *Headscale) Serve() error { grpcGatewayMux := runtime.NewServeMux() - grpcDialOptions := []grpc.DialOption{grpc.WithInsecure()} - - _, port, err := net.SplitHostPort(h.cfg.Addr) + // Make the grpc-gateway connect to grpc over socket + grpcGatewayConn, err := grpc.Dial( + h.cfg.UnixSocket, + []grpc.DialOption{ + grpc.WithInsecure(), + grpc.WithDialer(func(addr string, timeout time.Duration) (net.Conn, error) { + return net.DialTimeout("unix", addr, timeout) + }), + }..., + ) if err != nil { return err } // Connect to the gRPC server over localhost to skip // the authentication. - err = apiV1.RegisterHeadscaleServiceHandlerFromEndpoint(ctx, grpcGatewayMux, LOCALHOST_V4+":"+port, grpcDialOptions) + err = apiV1.RegisterHeadscaleServiceHandler(ctx, grpcGatewayMux, grpcGatewayConn) if err != nil { return err } @@ -432,6 +445,7 @@ func (h *Headscale) Serve() error { g := new(errgroup.Group) + g.Go(func() error { return grpcServer.Serve(socketListener) }) g.Go(func() error { return grpcServer.Serve(grpcListener) }) g.Go(func() error { return httpServer.Serve(httpListener) }) g.Go(func() error { return m.Serve() }) diff --git a/cmd/headscale/cli/utils.go b/cmd/headscale/cli/utils.go index 14ff2bf2..1d6fdd61 100644 --- a/cmd/headscale/cli/utils.go +++ b/cmd/headscale/cli/utils.go @@ -48,6 +48,8 @@ func LoadConfig(path string) error { viper.SetDefault("dns_config", nil) + viper.SetDefault("unix_socket", "/var/run/headscale.sock") + err := viper.ReadInConfig() if err != nil { return fmt.Errorf("Fatal error reading config file: %s \n", err) @@ -242,6 +244,8 @@ func getHeadscaleConfig() headscale.Config { ACMEEmail: viper.GetString("acme_email"), ACMEURL: viper.GetString("acme_url"), + + UnixSocket: viper.GetString("unix_socket"), } } @@ -282,11 +286,11 @@ func getHeadscaleApp() (*headscale.Headscale, error) { } func getHeadscaleGRPCClient() (apiV1.HeadscaleServiceClient, *grpc.ClientConn) { + // TODO(kradalby): Make configurable ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() grpcOptions := []grpc.DialOption{ - // TODO(kradalby): Make configurable grpc.WithBlock(), } @@ -294,19 +298,24 @@ func getHeadscaleGRPCClient() (apiV1.HeadscaleServiceClient, *grpc.ClientConn) { // If the address is not set, we assume that we are on the server hosting headscale. if address == "" { - log.Debug().Msgf("HEADSCALE_ADDRESS environment is not set, connecting to localhost.") cfg := getHeadscaleConfig() - _, port, _ := net.SplitHostPort(cfg.Addr) + log.Debug(). + Str("socket", cfg.UnixSocket). + Msgf("HEADSCALE_ADDRESS environment is not set, connecting to unix socket.") - address = "127.0.0.1" + ":" + port + address = cfg.UnixSocket - grpcOptions = append(grpcOptions, grpc.WithInsecure()) - } - - // If we are not connecting to a local server, require an API key for authentication - if !headscale.IsLocalhost(address) { + grpcOptions = append( + grpcOptions, + grpc.WithInsecure(), + grpc.WithDialer(func(addr string, timeout time.Duration) (net.Conn, error) { + return net.DialTimeout("unix", addr, timeout) + }), + ) + } else { + // If we are not connecting to a local server, require an API key for authentication apiKey := os.Getenv("HEADSCALE_API_KEY") if apiKey == "" { log.Fatal().Msgf("HEADSCALE_API_KEY environment variable needs to be set.") diff --git a/config-example.yaml b/config-example.yaml index 59370eb5..0eaf4c2d 100644 --- a/config-example.yaml +++ b/config-example.yaml @@ -64,3 +64,8 @@ dns_config: magic_dns: true base_domain: example.com + +# Unix socket used for the CLI to connect without authentication +# Note: for local development, you probably want to change this to: +# unix_socket: ./headscale.sock +unix_socket: /var/run/headscale.sock diff --git a/proto/headscale/v1/rpc.proto b/proto/headscale/v1/rpc.proto deleted file mode 100644 index 2e6b0a67..00000000 --- a/proto/headscale/v1/rpc.proto +++ /dev/null @@ -1,106 +0,0 @@ -syntax = "proto3"; -package headscale.v1; -option go_package = "github.com/juanfont/headscale/gen/go/v1"; - -import "google/protobuf/timestamp.proto"; -import "google/api/annotations.proto"; - -enum RegisterMethod { - REGISTER_METHOD_UNSPECIFIED = 0; - REGISTER_METHOD_AUTH_KEY = 1; - REGISTER_METHOD_CLI = 2; - REGISTER_METHOD_OIDC = 3; -} - -// message PreAuthKey { -// uint64 id = 1; -// string key = 2; -// uint32 namespace_id = 3; -// Namespace namespace = 4; -// bool reusable = 5; -// bool ephemeral = 6; -// bool used = 7; -// -// google.protobuf.Timestamp created_at = 8; -// google.protobuf.Timestamp expiration = 9; -// } - -message GetMachineRequest { - uint64 machine_id = 1; -} - -message GetMachineResponse { - uint64 id = 1; - string machine_key = 2; - string node_key = 3; - string disco_key = 4; - string ip_address = 5; - string name = 6; - uint32 namespace_id = 7; - - bool registered = 8; - RegisterMethod register_method = 9; - uint32 auth_key_id = 10; - // PreAuthKey auth_key = 11; - - google.protobuf.Timestamp last_seen = 12; - google.protobuf.Timestamp last_successful_update = 13; - google.protobuf.Timestamp expiry = 14; - - // bytes host_info = 15; - // bytes endpoints = 16; - // bytes enabled_routes = 17; - - // google.protobuf.Timestamp created_at = 18; - // google.protobuf.Timestamp updated_at = 19; - // google.protobuf.Timestamp deleted_at = 20; -} - -message CreateNamespaceRequest { - string name = 1; -} - -message CreateNamespaceResponse { - string name = 1; -} - -message DeleteNamespaceRequest { - string name = 1; -} - -message DeleteNamespaceResponse { -} - -message ListNamespacesRequest { -} - -message ListNamespacesResponse { - repeated string namespaces = 1; -} - -service HeadscaleService { - rpc GetMachine(GetMachineRequest) returns(GetMachineResponse) { - option(google.api.http) = { - get : "/api/v1/machine/{machine_id}" - }; - } - - rpc CreateNamespace(CreateNamespaceRequest) returns(CreateNamespaceResponse) { - option(google.api.http) = { - post : "/api/v1/namespace" - body : "*" - }; - } - - rpc DeleteNamespace(DeleteNamespaceRequest) returns(DeleteNamespaceResponse) { - option(google.api.http) = { - delete : "/api/v1/namespace" - }; - } - - rpc ListNamespaces(ListNamespacesRequest) returns(ListNamespacesResponse) { - option(google.api.http) = { - get : "/api/v1/namespace" - }; - } -} diff --git a/utils.go b/utils.go index 1aa31712..cbe1d870 100644 --- a/utils.go +++ b/utils.go @@ -156,11 +156,3 @@ func tailNodesToString(nodes []*tailcfg.Node) string { func tailMapResponseToString(resp tailcfg.MapResponse) string { return fmt.Sprintf("{ Node: %s, Peers: %s }", resp.Node.Name, tailNodesToString(resp.Peers)) } - -func IsLocalhost(host string) bool { - if strings.Contains(host, LOCALHOST_V4) || strings.Contains(host, LOCALHOST_V6) { - return true - } - - return false -} From 434fac52b7f11aeb26094c25d0c0d3c859f77b3a Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Sat, 30 Oct 2021 14:29:03 +0000 Subject: [PATCH 053/300] Fix lint error --- app.go | 4 +--- cmd/headscale/cli/utils.go | 5 +---- utils.go | 7 +++++++ 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/app.go b/app.go index 94517d54..707c111e 100644 --- a/app.go +++ b/app.go @@ -355,9 +355,7 @@ func (h *Headscale) Serve() error { h.cfg.UnixSocket, []grpc.DialOption{ grpc.WithInsecure(), - grpc.WithDialer(func(addr string, timeout time.Duration) (net.Conn, error) { - return net.DialTimeout("unix", addr, timeout) - }), + grpc.WithContextDialer(GrpcSocketDialer), }..., ) if err != nil { diff --git a/cmd/headscale/cli/utils.go b/cmd/headscale/cli/utils.go index 1d6fdd61..8e044bf5 100644 --- a/cmd/headscale/cli/utils.go +++ b/cmd/headscale/cli/utils.go @@ -5,7 +5,6 @@ import ( "encoding/json" "errors" "fmt" - "net" "net/url" "os" "path/filepath" @@ -310,9 +309,7 @@ func getHeadscaleGRPCClient() (apiV1.HeadscaleServiceClient, *grpc.ClientConn) { grpcOptions = append( grpcOptions, grpc.WithInsecure(), - grpc.WithDialer(func(addr string, timeout time.Duration) (net.Conn, error) { - return net.DialTimeout("unix", addr, timeout) - }), + grpc.WithContextDialer(headscale.GrpcSocketDialer), ) } else { // If we are not connecting to a local server, require an API key for authentication diff --git a/utils.go b/utils.go index cbe1d870..555227ec 100644 --- a/utils.go +++ b/utils.go @@ -6,10 +6,12 @@ package headscale import ( + "context" "crypto/rand" "encoding/json" "fmt" "io" + "net" "strings" "golang.org/x/crypto/nacl/box" @@ -156,3 +158,8 @@ func tailNodesToString(nodes []*tailcfg.Node) string { func tailMapResponseToString(resp tailcfg.MapResponse) string { return fmt.Sprintf("{ Node: %s, Peers: %s }", resp.Node.Name, tailNodesToString(resp.Peers)) } + +func GrpcSocketDialer(ctx context.Context, addr string) (net.Conn, error) { + var d net.Dialer + return d.DialContext(ctx, "unix", addr) +} From 2b340e8fa4710a22b108660f906a3318dd86eba5 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Sat, 30 Oct 2021 14:29:41 +0000 Subject: [PATCH 054/300] Rename protofile --- .../v1/{rpc.pb.go => headscale.pb.go} | 320 +++++++++--------- .../v1/{rpc.pb.gw.go => headscale.pb.gw.go} | 2 +- .../{rpc_grpc.pb.go => headscale_grpc.pb.go} | 2 +- ...pc.swagger.json => headscale.swagger.json} | 2 +- proto/headscale/v1/headscale.proto | 106 ++++++ 5 files changed, 269 insertions(+), 163 deletions(-) rename gen/go/headscale/v1/{rpc.pb.go => headscale.pb.go} (58%) rename gen/go/headscale/v1/{rpc.pb.gw.go => headscale.pb.gw.go} (99%) rename gen/go/headscale/v1/{rpc_grpc.pb.go => headscale_grpc.pb.go} (99%) rename gen/openapiv2/headscale/v1/{rpc.swagger.json => headscale.swagger.json} (99%) create mode 100644 proto/headscale/v1/headscale.proto diff --git a/gen/go/headscale/v1/rpc.pb.go b/gen/go/headscale/v1/headscale.pb.go similarity index 58% rename from gen/go/headscale/v1/rpc.pb.go rename to gen/go/headscale/v1/headscale.pb.go index b510b961..e050e931 100644 --- a/gen/go/headscale/v1/rpc.pb.go +++ b/gen/go/headscale/v1/headscale.pb.go @@ -2,7 +2,7 @@ // versions: // protoc-gen-go v1.27.1 // protoc v3.18.1 -// source: headscale/v1/rpc.proto +// source: headscale/v1/headscale.proto package v1 @@ -58,11 +58,11 @@ func (x RegisterMethod) String() string { } func (RegisterMethod) Descriptor() protoreflect.EnumDescriptor { - return file_headscale_v1_rpc_proto_enumTypes[0].Descriptor() + return file_headscale_v1_headscale_proto_enumTypes[0].Descriptor() } func (RegisterMethod) Type() protoreflect.EnumType { - return &file_headscale_v1_rpc_proto_enumTypes[0] + return &file_headscale_v1_headscale_proto_enumTypes[0] } func (x RegisterMethod) Number() protoreflect.EnumNumber { @@ -71,7 +71,7 @@ func (x RegisterMethod) Number() protoreflect.EnumNumber { // Deprecated: Use RegisterMethod.Descriptor instead. func (RegisterMethod) EnumDescriptor() ([]byte, []int) { - return file_headscale_v1_rpc_proto_rawDescGZIP(), []int{0} + return file_headscale_v1_headscale_proto_rawDescGZIP(), []int{0} } type GetMachineRequest struct { @@ -85,7 +85,7 @@ type GetMachineRequest struct { func (x *GetMachineRequest) Reset() { *x = GetMachineRequest{} if protoimpl.UnsafeEnabled { - mi := &file_headscale_v1_rpc_proto_msgTypes[0] + mi := &file_headscale_v1_headscale_proto_msgTypes[0] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -98,7 +98,7 @@ func (x *GetMachineRequest) String() string { func (*GetMachineRequest) ProtoMessage() {} func (x *GetMachineRequest) ProtoReflect() protoreflect.Message { - mi := &file_headscale_v1_rpc_proto_msgTypes[0] + mi := &file_headscale_v1_headscale_proto_msgTypes[0] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -111,7 +111,7 @@ func (x *GetMachineRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetMachineRequest.ProtoReflect.Descriptor instead. func (*GetMachineRequest) Descriptor() ([]byte, []int) { - return file_headscale_v1_rpc_proto_rawDescGZIP(), []int{0} + return file_headscale_v1_headscale_proto_rawDescGZIP(), []int{0} } func (x *GetMachineRequest) GetMachineId() uint64 { @@ -144,7 +144,7 @@ type GetMachineResponse struct { func (x *GetMachineResponse) Reset() { *x = GetMachineResponse{} if protoimpl.UnsafeEnabled { - mi := &file_headscale_v1_rpc_proto_msgTypes[1] + mi := &file_headscale_v1_headscale_proto_msgTypes[1] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -157,7 +157,7 @@ func (x *GetMachineResponse) String() string { func (*GetMachineResponse) ProtoMessage() {} func (x *GetMachineResponse) ProtoReflect() protoreflect.Message { - mi := &file_headscale_v1_rpc_proto_msgTypes[1] + mi := &file_headscale_v1_headscale_proto_msgTypes[1] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -170,7 +170,7 @@ func (x *GetMachineResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetMachineResponse.ProtoReflect.Descriptor instead. func (*GetMachineResponse) Descriptor() ([]byte, []int) { - return file_headscale_v1_rpc_proto_rawDescGZIP(), []int{1} + return file_headscale_v1_headscale_proto_rawDescGZIP(), []int{1} } func (x *GetMachineResponse) GetId() uint64 { @@ -275,7 +275,7 @@ type CreateNamespaceRequest struct { func (x *CreateNamespaceRequest) Reset() { *x = CreateNamespaceRequest{} if protoimpl.UnsafeEnabled { - mi := &file_headscale_v1_rpc_proto_msgTypes[2] + mi := &file_headscale_v1_headscale_proto_msgTypes[2] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -288,7 +288,7 @@ func (x *CreateNamespaceRequest) String() string { func (*CreateNamespaceRequest) ProtoMessage() {} func (x *CreateNamespaceRequest) ProtoReflect() protoreflect.Message { - mi := &file_headscale_v1_rpc_proto_msgTypes[2] + mi := &file_headscale_v1_headscale_proto_msgTypes[2] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -301,7 +301,7 @@ func (x *CreateNamespaceRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateNamespaceRequest.ProtoReflect.Descriptor instead. func (*CreateNamespaceRequest) Descriptor() ([]byte, []int) { - return file_headscale_v1_rpc_proto_rawDescGZIP(), []int{2} + return file_headscale_v1_headscale_proto_rawDescGZIP(), []int{2} } func (x *CreateNamespaceRequest) GetName() string { @@ -322,7 +322,7 @@ type CreateNamespaceResponse struct { func (x *CreateNamespaceResponse) Reset() { *x = CreateNamespaceResponse{} if protoimpl.UnsafeEnabled { - mi := &file_headscale_v1_rpc_proto_msgTypes[3] + mi := &file_headscale_v1_headscale_proto_msgTypes[3] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -335,7 +335,7 @@ func (x *CreateNamespaceResponse) String() string { func (*CreateNamespaceResponse) ProtoMessage() {} func (x *CreateNamespaceResponse) ProtoReflect() protoreflect.Message { - mi := &file_headscale_v1_rpc_proto_msgTypes[3] + mi := &file_headscale_v1_headscale_proto_msgTypes[3] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -348,7 +348,7 @@ func (x *CreateNamespaceResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateNamespaceResponse.ProtoReflect.Descriptor instead. func (*CreateNamespaceResponse) Descriptor() ([]byte, []int) { - return file_headscale_v1_rpc_proto_rawDescGZIP(), []int{3} + return file_headscale_v1_headscale_proto_rawDescGZIP(), []int{3} } func (x *CreateNamespaceResponse) GetName() string { @@ -369,7 +369,7 @@ type DeleteNamespaceRequest struct { func (x *DeleteNamespaceRequest) Reset() { *x = DeleteNamespaceRequest{} if protoimpl.UnsafeEnabled { - mi := &file_headscale_v1_rpc_proto_msgTypes[4] + mi := &file_headscale_v1_headscale_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -382,7 +382,7 @@ func (x *DeleteNamespaceRequest) String() string { func (*DeleteNamespaceRequest) ProtoMessage() {} func (x *DeleteNamespaceRequest) ProtoReflect() protoreflect.Message { - mi := &file_headscale_v1_rpc_proto_msgTypes[4] + mi := &file_headscale_v1_headscale_proto_msgTypes[4] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -395,7 +395,7 @@ func (x *DeleteNamespaceRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteNamespaceRequest.ProtoReflect.Descriptor instead. func (*DeleteNamespaceRequest) Descriptor() ([]byte, []int) { - return file_headscale_v1_rpc_proto_rawDescGZIP(), []int{4} + return file_headscale_v1_headscale_proto_rawDescGZIP(), []int{4} } func (x *DeleteNamespaceRequest) GetName() string { @@ -414,7 +414,7 @@ type DeleteNamespaceResponse struct { func (x *DeleteNamespaceResponse) Reset() { *x = DeleteNamespaceResponse{} if protoimpl.UnsafeEnabled { - mi := &file_headscale_v1_rpc_proto_msgTypes[5] + mi := &file_headscale_v1_headscale_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -427,7 +427,7 @@ func (x *DeleteNamespaceResponse) String() string { func (*DeleteNamespaceResponse) ProtoMessage() {} func (x *DeleteNamespaceResponse) ProtoReflect() protoreflect.Message { - mi := &file_headscale_v1_rpc_proto_msgTypes[5] + mi := &file_headscale_v1_headscale_proto_msgTypes[5] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -440,7 +440,7 @@ func (x *DeleteNamespaceResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteNamespaceResponse.ProtoReflect.Descriptor instead. func (*DeleteNamespaceResponse) Descriptor() ([]byte, []int) { - return file_headscale_v1_rpc_proto_rawDescGZIP(), []int{5} + return file_headscale_v1_headscale_proto_rawDescGZIP(), []int{5} } type ListNamespacesRequest struct { @@ -452,7 +452,7 @@ type ListNamespacesRequest struct { func (x *ListNamespacesRequest) Reset() { *x = ListNamespacesRequest{} if protoimpl.UnsafeEnabled { - mi := &file_headscale_v1_rpc_proto_msgTypes[6] + mi := &file_headscale_v1_headscale_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -465,7 +465,7 @@ func (x *ListNamespacesRequest) String() string { func (*ListNamespacesRequest) ProtoMessage() {} func (x *ListNamespacesRequest) ProtoReflect() protoreflect.Message { - mi := &file_headscale_v1_rpc_proto_msgTypes[6] + mi := &file_headscale_v1_headscale_proto_msgTypes[6] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -478,7 +478,7 @@ func (x *ListNamespacesRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListNamespacesRequest.ProtoReflect.Descriptor instead. func (*ListNamespacesRequest) Descriptor() ([]byte, []int) { - return file_headscale_v1_rpc_proto_rawDescGZIP(), []int{6} + return file_headscale_v1_headscale_proto_rawDescGZIP(), []int{6} } type ListNamespacesResponse struct { @@ -492,7 +492,7 @@ type ListNamespacesResponse struct { func (x *ListNamespacesResponse) Reset() { *x = ListNamespacesResponse{} if protoimpl.UnsafeEnabled { - mi := &file_headscale_v1_rpc_proto_msgTypes[7] + mi := &file_headscale_v1_headscale_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -505,7 +505,7 @@ func (x *ListNamespacesResponse) String() string { func (*ListNamespacesResponse) ProtoMessage() {} func (x *ListNamespacesResponse) ProtoReflect() protoreflect.Message { - mi := &file_headscale_v1_rpc_proto_msgTypes[7] + mi := &file_headscale_v1_headscale_proto_msgTypes[7] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -518,7 +518,7 @@ func (x *ListNamespacesResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListNamespacesResponse.ProtoReflect.Descriptor instead. func (*ListNamespacesResponse) Descriptor() ([]byte, []int) { - return file_headscale_v1_rpc_proto_rawDescGZIP(), []int{7} + return file_headscale_v1_headscale_proto_rawDescGZIP(), []int{7} } func (x *ListNamespacesResponse) GetNamespaces() []string { @@ -528,129 +528,129 @@ func (x *ListNamespacesResponse) GetNamespaces() []string { return nil } -var File_headscale_v1_rpc_proto protoreflect.FileDescriptor +var File_headscale_v1_headscale_proto protoreflect.FileDescriptor -var file_headscale_v1_rpc_proto_rawDesc = []byte{ - 0x0a, 0x16, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x72, - 0x70, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0c, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, - 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, - 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, - 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x32, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x4d, 0x61, 0x63, 0x68, - 0x69, 0x6e, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x6d, 0x61, - 0x63, 0x68, 0x69, 0x6e, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, - 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x49, 0x64, 0x22, 0x99, 0x04, 0x0a, 0x12, 0x47, 0x65, - 0x74, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x02, 0x69, 0x64, - 0x12, 0x1f, 0x0a, 0x0b, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x4b, 0x65, - 0x79, 0x12, 0x19, 0x0a, 0x08, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x07, 0x6e, 0x6f, 0x64, 0x65, 0x4b, 0x65, 0x79, 0x12, 0x1b, 0x0a, 0x09, - 0x64, 0x69, 0x73, 0x63, 0x6f, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x08, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x4b, 0x65, 0x79, 0x12, 0x1d, 0x0a, 0x0a, 0x69, 0x70, 0x5f, - 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x69, - 0x70, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, - 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x21, 0x0a, 0x0c, - 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x07, 0x20, 0x01, - 0x28, 0x0d, 0x52, 0x0b, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x49, 0x64, 0x12, - 0x1e, 0x0a, 0x0a, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x65, 0x64, 0x18, 0x08, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x0a, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x65, 0x64, 0x12, - 0x45, 0x0a, 0x0f, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x6d, 0x65, 0x74, 0x68, - 0x6f, 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1c, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, - 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, - 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x52, 0x0e, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, - 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, 0x1e, 0x0a, 0x0b, 0x61, 0x75, 0x74, 0x68, 0x5f, 0x6b, - 0x65, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x61, 0x75, 0x74, - 0x68, 0x4b, 0x65, 0x79, 0x49, 0x64, 0x12, 0x37, 0x0a, 0x09, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x73, - 0x65, 0x65, 0x6e, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, - 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x08, 0x6c, 0x61, 0x73, 0x74, 0x53, 0x65, 0x65, 0x6e, 0x12, - 0x50, 0x0a, 0x16, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x66, - 0x75, 0x6c, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, +var file_headscale_v1_headscale_proto_rawDesc = []byte{ + 0x0a, 0x1c, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x68, + 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0c, + 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x1a, 0x1f, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, + 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x32, 0x0a, 0x11, 0x47, + 0x65, 0x74, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x1d, 0x0a, 0x0a, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x49, 0x64, 0x22, + 0x99, 0x04, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x04, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, + 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6d, 0x61, 0x63, + 0x68, 0x69, 0x6e, 0x65, 0x4b, 0x65, 0x79, 0x12, 0x19, 0x0a, 0x08, 0x6e, 0x6f, 0x64, 0x65, 0x5f, + 0x6b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6e, 0x6f, 0x64, 0x65, 0x4b, + 0x65, 0x79, 0x12, 0x1b, 0x0a, 0x09, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x5f, 0x6b, 0x65, 0x79, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x4b, 0x65, 0x79, 0x12, + 0x1d, 0x0a, 0x0a, 0x69, 0x70, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x09, 0x69, 0x70, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x12, + 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, + 0x69, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, + 0x61, 0x63, 0x65, 0x49, 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, + 0x72, 0x65, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x72, 0x65, 0x67, 0x69, 0x73, + 0x74, 0x65, 0x72, 0x65, 0x64, 0x12, 0x45, 0x0a, 0x0f, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, + 0x72, 0x5f, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1c, + 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, + 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x52, 0x0e, 0x72, 0x65, + 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, 0x1e, 0x0a, 0x0b, + 0x61, 0x75, 0x74, 0x68, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x0a, 0x20, 0x01, 0x28, + 0x0d, 0x52, 0x09, 0x61, 0x75, 0x74, 0x68, 0x4b, 0x65, 0x79, 0x49, 0x64, 0x12, 0x37, 0x0a, 0x09, + 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x65, 0x6e, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x14, 0x6c, 0x61, 0x73, - 0x74, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x66, 0x75, 0x6c, 0x55, 0x70, 0x64, 0x61, 0x74, - 0x65, 0x12, 0x32, 0x0a, 0x06, 0x65, 0x78, 0x70, 0x69, 0x72, 0x79, 0x18, 0x0e, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x06, 0x65, - 0x78, 0x70, 0x69, 0x72, 0x79, 0x22, 0x2c, 0x0a, 0x16, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4e, - 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, - 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, - 0x61, 0x6d, 0x65, 0x22, 0x2d, 0x0a, 0x17, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4e, 0x61, 0x6d, - 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, - 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, - 0x6d, 0x65, 0x22, 0x2c, 0x0a, 0x16, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, - 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, - 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, - 0x22, 0x19, 0x0a, 0x17, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, - 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x17, 0x0a, 0x15, 0x4c, - 0x69, 0x73, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x22, 0x38, 0x0a, 0x16, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x61, 0x6d, 0x65, - 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1e, - 0x0a, 0x0a, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, - 0x28, 0x09, 0x52, 0x0a, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x2a, 0x82, - 0x01, 0x0a, 0x0e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x68, 0x6f, - 0x64, 0x12, 0x1f, 0x0a, 0x1b, 0x52, 0x45, 0x47, 0x49, 0x53, 0x54, 0x45, 0x52, 0x5f, 0x4d, 0x45, - 0x54, 0x48, 0x4f, 0x44, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, - 0x10, 0x00, 0x12, 0x1c, 0x0a, 0x18, 0x52, 0x45, 0x47, 0x49, 0x53, 0x54, 0x45, 0x52, 0x5f, 0x4d, - 0x45, 0x54, 0x48, 0x4f, 0x44, 0x5f, 0x41, 0x55, 0x54, 0x48, 0x5f, 0x4b, 0x45, 0x59, 0x10, 0x01, - 0x12, 0x17, 0x0a, 0x13, 0x52, 0x45, 0x47, 0x49, 0x53, 0x54, 0x45, 0x52, 0x5f, 0x4d, 0x45, 0x54, - 0x48, 0x4f, 0x44, 0x5f, 0x43, 0x4c, 0x49, 0x10, 0x02, 0x12, 0x18, 0x0a, 0x14, 0x52, 0x45, 0x47, - 0x49, 0x53, 0x54, 0x45, 0x52, 0x5f, 0x4d, 0x45, 0x54, 0x48, 0x4f, 0x44, 0x5f, 0x4f, 0x49, 0x44, - 0x43, 0x10, 0x03, 0x32, 0xfa, 0x03, 0x0a, 0x10, 0x48, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, - 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x75, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x4d, - 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x12, 0x1f, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, - 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, - 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, - 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x24, 0x82, 0xd3, 0xe4, 0x93, 0x02, - 0x1e, 0x12, 0x1c, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x6d, 0x61, 0x63, 0x68, 0x69, - 0x6e, 0x65, 0x2f, 0x7b, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x12, - 0x7c, 0x0a, 0x0f, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, - 0x63, 0x65, 0x12, 0x24, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, - 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, - 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, + 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x08, 0x6c, 0x61, 0x73, + 0x74, 0x53, 0x65, 0x65, 0x6e, 0x12, 0x50, 0x0a, 0x16, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x73, 0x75, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x66, 0x75, 0x6c, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x18, + 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, + 0x70, 0x52, 0x14, 0x6c, 0x61, 0x73, 0x74, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x66, 0x75, + 0x6c, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x32, 0x0a, 0x06, 0x65, 0x78, 0x70, 0x69, 0x72, + 0x79, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, + 0x61, 0x6d, 0x70, 0x52, 0x06, 0x65, 0x78, 0x70, 0x69, 0x72, 0x79, 0x22, 0x2c, 0x0a, 0x16, 0x43, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x2d, 0x0a, 0x17, 0x43, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x2c, 0x0a, 0x16, 0x44, 0x65, 0x6c, 0x65, + 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x19, 0x0a, 0x17, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, + 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x17, 0x0a, 0x15, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x38, 0x0a, 0x16, 0x4c, 0x69, + 0x73, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, + 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, + 0x61, 0x63, 0x65, 0x73, 0x2a, 0x82, 0x01, 0x0a, 0x0e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, + 0x72, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, 0x1f, 0x0a, 0x1b, 0x52, 0x45, 0x47, 0x49, 0x53, + 0x54, 0x45, 0x52, 0x5f, 0x4d, 0x45, 0x54, 0x48, 0x4f, 0x44, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, + 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1c, 0x0a, 0x18, 0x52, 0x45, 0x47, 0x49, + 0x53, 0x54, 0x45, 0x52, 0x5f, 0x4d, 0x45, 0x54, 0x48, 0x4f, 0x44, 0x5f, 0x41, 0x55, 0x54, 0x48, + 0x5f, 0x4b, 0x45, 0x59, 0x10, 0x01, 0x12, 0x17, 0x0a, 0x13, 0x52, 0x45, 0x47, 0x49, 0x53, 0x54, + 0x45, 0x52, 0x5f, 0x4d, 0x45, 0x54, 0x48, 0x4f, 0x44, 0x5f, 0x43, 0x4c, 0x49, 0x10, 0x02, 0x12, + 0x18, 0x0a, 0x14, 0x52, 0x45, 0x47, 0x49, 0x53, 0x54, 0x45, 0x52, 0x5f, 0x4d, 0x45, 0x54, 0x48, + 0x4f, 0x44, 0x5f, 0x4f, 0x49, 0x44, 0x43, 0x10, 0x03, 0x32, 0xfa, 0x03, 0x0a, 0x10, 0x48, 0x65, + 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x75, + 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x12, 0x1f, 0x2e, 0x68, + 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4d, + 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, + 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, + 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x24, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1e, 0x12, 0x1c, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, + 0x2f, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x2f, 0x7b, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, + 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x12, 0x7c, 0x0a, 0x0f, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4e, + 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x24, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4e, 0x61, - 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x1c, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x16, 0x22, 0x11, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, - 0x2f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x3a, 0x01, 0x2a, 0x12, 0x79, 0x0a, - 0x0f, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, - 0x12, 0x24, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, - 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, - 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, - 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x19, 0x82, - 0xd3, 0xe4, 0x93, 0x02, 0x13, 0x2a, 0x11, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x6e, - 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x76, 0x0a, 0x0e, 0x4c, 0x69, 0x73, 0x74, - 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x12, 0x23, 0x2e, 0x68, 0x65, 0x61, - 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x61, - 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x24, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, - 0x69, 0x73, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x19, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x13, 0x12, 0x11, 0x2f, + 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, + 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1c, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x16, 0x22, 0x11, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, - 0x42, 0x29, 0x5a, 0x27, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6a, - 0x75, 0x61, 0x6e, 0x66, 0x6f, 0x6e, 0x74, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, - 0x65, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x67, 0x6f, 0x2f, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x33, + 0x3a, 0x01, 0x2a, 0x12, 0x79, 0x0a, 0x0f, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4e, 0x61, 0x6d, + 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x24, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, + 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, + 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x68, + 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, + 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x19, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x13, 0x2a, 0x11, 0x2f, 0x61, 0x70, + 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x76, + 0x0a, 0x0e, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, + 0x12, 0x23, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, + 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, + 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x19, 0x82, 0xd3, 0xe4, + 0x93, 0x02, 0x13, 0x12, 0x11, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x6e, 0x61, 0x6d, + 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x42, 0x29, 0x5a, 0x27, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, + 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6a, 0x75, 0x61, 0x6e, 0x66, 0x6f, 0x6e, 0x74, 0x2f, 0x68, 0x65, + 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x67, 0x6f, 0x2f, 0x76, + 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( - file_headscale_v1_rpc_proto_rawDescOnce sync.Once - file_headscale_v1_rpc_proto_rawDescData = file_headscale_v1_rpc_proto_rawDesc + file_headscale_v1_headscale_proto_rawDescOnce sync.Once + file_headscale_v1_headscale_proto_rawDescData = file_headscale_v1_headscale_proto_rawDesc ) -func file_headscale_v1_rpc_proto_rawDescGZIP() []byte { - file_headscale_v1_rpc_proto_rawDescOnce.Do(func() { - file_headscale_v1_rpc_proto_rawDescData = protoimpl.X.CompressGZIP(file_headscale_v1_rpc_proto_rawDescData) +func file_headscale_v1_headscale_proto_rawDescGZIP() []byte { + file_headscale_v1_headscale_proto_rawDescOnce.Do(func() { + file_headscale_v1_headscale_proto_rawDescData = protoimpl.X.CompressGZIP(file_headscale_v1_headscale_proto_rawDescData) }) - return file_headscale_v1_rpc_proto_rawDescData + return file_headscale_v1_headscale_proto_rawDescData } -var file_headscale_v1_rpc_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_headscale_v1_rpc_proto_msgTypes = make([]protoimpl.MessageInfo, 8) -var file_headscale_v1_rpc_proto_goTypes = []interface{}{ +var file_headscale_v1_headscale_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_headscale_v1_headscale_proto_msgTypes = make([]protoimpl.MessageInfo, 8) +var file_headscale_v1_headscale_proto_goTypes = []interface{}{ (RegisterMethod)(0), // 0: headscale.v1.RegisterMethod (*GetMachineRequest)(nil), // 1: headscale.v1.GetMachineRequest (*GetMachineResponse)(nil), // 2: headscale.v1.GetMachineResponse @@ -662,7 +662,7 @@ var file_headscale_v1_rpc_proto_goTypes = []interface{}{ (*ListNamespacesResponse)(nil), // 8: headscale.v1.ListNamespacesResponse (*timestamppb.Timestamp)(nil), // 9: google.protobuf.Timestamp } -var file_headscale_v1_rpc_proto_depIdxs = []int32{ +var file_headscale_v1_headscale_proto_depIdxs = []int32{ 0, // 0: headscale.v1.GetMachineResponse.register_method:type_name -> headscale.v1.RegisterMethod 9, // 1: headscale.v1.GetMachineResponse.last_seen:type_name -> google.protobuf.Timestamp 9, // 2: headscale.v1.GetMachineResponse.last_successful_update:type_name -> google.protobuf.Timestamp @@ -682,13 +682,13 @@ var file_headscale_v1_rpc_proto_depIdxs = []int32{ 0, // [0:4] is the sub-list for field type_name } -func init() { file_headscale_v1_rpc_proto_init() } -func file_headscale_v1_rpc_proto_init() { - if File_headscale_v1_rpc_proto != nil { +func init() { file_headscale_v1_headscale_proto_init() } +func file_headscale_v1_headscale_proto_init() { + if File_headscale_v1_headscale_proto != nil { return } if !protoimpl.UnsafeEnabled { - file_headscale_v1_rpc_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + file_headscale_v1_headscale_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*GetMachineRequest); i { case 0: return &v.state @@ -700,7 +700,7 @@ func file_headscale_v1_rpc_proto_init() { return nil } } - file_headscale_v1_rpc_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + file_headscale_v1_headscale_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*GetMachineResponse); i { case 0: return &v.state @@ -712,7 +712,7 @@ func file_headscale_v1_rpc_proto_init() { return nil } } - file_headscale_v1_rpc_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + file_headscale_v1_headscale_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*CreateNamespaceRequest); i { case 0: return &v.state @@ -724,7 +724,7 @@ func file_headscale_v1_rpc_proto_init() { return nil } } - file_headscale_v1_rpc_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + file_headscale_v1_headscale_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*CreateNamespaceResponse); i { case 0: return &v.state @@ -736,7 +736,7 @@ func file_headscale_v1_rpc_proto_init() { return nil } } - file_headscale_v1_rpc_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + file_headscale_v1_headscale_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*DeleteNamespaceRequest); i { case 0: return &v.state @@ -748,7 +748,7 @@ func file_headscale_v1_rpc_proto_init() { return nil } } - file_headscale_v1_rpc_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + file_headscale_v1_headscale_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*DeleteNamespaceResponse); i { case 0: return &v.state @@ -760,7 +760,7 @@ func file_headscale_v1_rpc_proto_init() { return nil } } - file_headscale_v1_rpc_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + file_headscale_v1_headscale_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ListNamespacesRequest); i { case 0: return &v.state @@ -772,7 +772,7 @@ func file_headscale_v1_rpc_proto_init() { return nil } } - file_headscale_v1_rpc_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + file_headscale_v1_headscale_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ListNamespacesResponse); i { case 0: return &v.state @@ -789,19 +789,19 @@ func file_headscale_v1_rpc_proto_init() { out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_headscale_v1_rpc_proto_rawDesc, + RawDescriptor: file_headscale_v1_headscale_proto_rawDesc, NumEnums: 1, NumMessages: 8, NumExtensions: 0, NumServices: 1, }, - GoTypes: file_headscale_v1_rpc_proto_goTypes, - DependencyIndexes: file_headscale_v1_rpc_proto_depIdxs, - EnumInfos: file_headscale_v1_rpc_proto_enumTypes, - MessageInfos: file_headscale_v1_rpc_proto_msgTypes, + GoTypes: file_headscale_v1_headscale_proto_goTypes, + DependencyIndexes: file_headscale_v1_headscale_proto_depIdxs, + EnumInfos: file_headscale_v1_headscale_proto_enumTypes, + MessageInfos: file_headscale_v1_headscale_proto_msgTypes, }.Build() - File_headscale_v1_rpc_proto = out.File - file_headscale_v1_rpc_proto_rawDesc = nil - file_headscale_v1_rpc_proto_goTypes = nil - file_headscale_v1_rpc_proto_depIdxs = nil + File_headscale_v1_headscale_proto = out.File + file_headscale_v1_headscale_proto_rawDesc = nil + file_headscale_v1_headscale_proto_goTypes = nil + file_headscale_v1_headscale_proto_depIdxs = nil } diff --git a/gen/go/headscale/v1/rpc.pb.gw.go b/gen/go/headscale/v1/headscale.pb.gw.go similarity index 99% rename from gen/go/headscale/v1/rpc.pb.gw.go rename to gen/go/headscale/v1/headscale.pb.gw.go index 773a85a4..226afe50 100644 --- a/gen/go/headscale/v1/rpc.pb.gw.go +++ b/gen/go/headscale/v1/headscale.pb.gw.go @@ -1,5 +1,5 @@ // Code generated by protoc-gen-grpc-gateway. DO NOT EDIT. -// source: headscale/v1/rpc.proto +// source: headscale/v1/headscale.proto /* Package v1 is a reverse proxy. diff --git a/gen/go/headscale/v1/rpc_grpc.pb.go b/gen/go/headscale/v1/headscale_grpc.pb.go similarity index 99% rename from gen/go/headscale/v1/rpc_grpc.pb.go rename to gen/go/headscale/v1/headscale_grpc.pb.go index 618c26d1..a613e8e9 100644 --- a/gen/go/headscale/v1/rpc_grpc.pb.go +++ b/gen/go/headscale/v1/headscale_grpc.pb.go @@ -205,5 +205,5 @@ var HeadscaleService_ServiceDesc = grpc.ServiceDesc{ }, }, Streams: []grpc.StreamDesc{}, - Metadata: "headscale/v1/rpc.proto", + Metadata: "headscale/v1/headscale.proto", } diff --git a/gen/openapiv2/headscale/v1/rpc.swagger.json b/gen/openapiv2/headscale/v1/headscale.swagger.json similarity index 99% rename from gen/openapiv2/headscale/v1/rpc.swagger.json rename to gen/openapiv2/headscale/v1/headscale.swagger.json index e9db7cf6..567a921f 100644 --- a/gen/openapiv2/headscale/v1/rpc.swagger.json +++ b/gen/openapiv2/headscale/v1/headscale.swagger.json @@ -1,7 +1,7 @@ { "swagger": "2.0", "info": { - "title": "headscale/v1/rpc.proto", + "title": "headscale/v1/headscale.proto", "version": "version not set" }, "tags": [ diff --git a/proto/headscale/v1/headscale.proto b/proto/headscale/v1/headscale.proto new file mode 100644 index 00000000..2e6b0a67 --- /dev/null +++ b/proto/headscale/v1/headscale.proto @@ -0,0 +1,106 @@ +syntax = "proto3"; +package headscale.v1; +option go_package = "github.com/juanfont/headscale/gen/go/v1"; + +import "google/protobuf/timestamp.proto"; +import "google/api/annotations.proto"; + +enum RegisterMethod { + REGISTER_METHOD_UNSPECIFIED = 0; + REGISTER_METHOD_AUTH_KEY = 1; + REGISTER_METHOD_CLI = 2; + REGISTER_METHOD_OIDC = 3; +} + +// message PreAuthKey { +// uint64 id = 1; +// string key = 2; +// uint32 namespace_id = 3; +// Namespace namespace = 4; +// bool reusable = 5; +// bool ephemeral = 6; +// bool used = 7; +// +// google.protobuf.Timestamp created_at = 8; +// google.protobuf.Timestamp expiration = 9; +// } + +message GetMachineRequest { + uint64 machine_id = 1; +} + +message GetMachineResponse { + uint64 id = 1; + string machine_key = 2; + string node_key = 3; + string disco_key = 4; + string ip_address = 5; + string name = 6; + uint32 namespace_id = 7; + + bool registered = 8; + RegisterMethod register_method = 9; + uint32 auth_key_id = 10; + // PreAuthKey auth_key = 11; + + google.protobuf.Timestamp last_seen = 12; + google.protobuf.Timestamp last_successful_update = 13; + google.protobuf.Timestamp expiry = 14; + + // bytes host_info = 15; + // bytes endpoints = 16; + // bytes enabled_routes = 17; + + // google.protobuf.Timestamp created_at = 18; + // google.protobuf.Timestamp updated_at = 19; + // google.protobuf.Timestamp deleted_at = 20; +} + +message CreateNamespaceRequest { + string name = 1; +} + +message CreateNamespaceResponse { + string name = 1; +} + +message DeleteNamespaceRequest { + string name = 1; +} + +message DeleteNamespaceResponse { +} + +message ListNamespacesRequest { +} + +message ListNamespacesResponse { + repeated string namespaces = 1; +} + +service HeadscaleService { + rpc GetMachine(GetMachineRequest) returns(GetMachineResponse) { + option(google.api.http) = { + get : "/api/v1/machine/{machine_id}" + }; + } + + rpc CreateNamespace(CreateNamespaceRequest) returns(CreateNamespaceResponse) { + option(google.api.http) = { + post : "/api/v1/namespace" + body : "*" + }; + } + + rpc DeleteNamespace(DeleteNamespaceRequest) returns(DeleteNamespaceResponse) { + option(google.api.http) = { + delete : "/api/v1/namespace" + }; + } + + rpc ListNamespaces(ListNamespacesRequest) returns(ListNamespacesResponse) { + option(google.api.http) = { + get : "/api/v1/namespace" + }; + } +} From 482a31b66b53e8258369925c40fb6cdba752a37c Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Sat, 30 Oct 2021 14:29:53 +0000 Subject: [PATCH 055/300] Setup swagger and swagger UI properly --- app.go | 4 ++-- swagger.go | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+), 2 deletions(-) create mode 100644 swagger.go diff --git a/app.go b/app.go index 707c111e..50343d3c 100644 --- a/app.go +++ b/app.go @@ -381,8 +381,8 @@ func (h *Headscale) Serve() error { r.POST("/machine/:id", h.RegistrationHandler) r.GET("/apple", h.AppleMobileConfig) r.GET("/apple/:platform", h.ApplePlatformConfig) - - r.StaticFile("/swagger/swagger.json", "gen/openapiv2/v1/headscale.swagger.json") + r.GET("/swagger", SwaggerUI) + r.GET("/swagger/v1/openapiv2.json", SwaggerAPIv1) api := r.Group("/api") api.Use(h.httpAuthenticationMiddleware) diff --git a/swagger.go b/swagger.go new file mode 100644 index 00000000..17f57697 --- /dev/null +++ b/swagger.go @@ -0,0 +1,65 @@ +package headscale + +import ( + "bytes" + _ "embed" + "net/http" + "text/template" + + "github.com/rs/zerolog/log" + + "github.com/gin-gonic/gin" +) + +//go:embed gen/openapiv2/headscale/v1/headscale.swagger.json +var apiV1JSON []byte + +func SwaggerUI(c *gin.Context) { + t := template.Must(template.New("swagger").Parse(` + + + + + + + + +
+ + +`)) + + var payload bytes.Buffer + if err := t.Execute(&payload, struct{}{}); err != nil { + log.Error(). + Caller(). + Err(err). + Msg("Could not render Swagger") + c.Data(http.StatusInternalServerError, "text/html; charset=utf-8", []byte("Could not render Swagger")) + return + } + + c.Data(http.StatusOK, "text/html; charset=utf-8", payload.Bytes()) +} + +func SwaggerAPIv1(c *gin.Context) { + c.Data(http.StatusOK, "application/json; charset=utf-8", apiV1JSON) +} From cd2914dbc9c1af4c929b363f56d0c3b6d5edfd3e Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Sat, 30 Oct 2021 15:35:58 +0000 Subject: [PATCH 056/300] Make note about oidc being experimental --- config-example.yaml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/config-example.yaml b/config-example.yaml index f28b4191..d4aa7815 100644 --- a/config-example.yaml +++ b/config-example.yaml @@ -66,10 +66,16 @@ dns_config: base_domain: example.com -# Experimental: OpenID Connect +# headscale supports experimental OpenID connect support, +# it is still being tested and might have some bugs, please +# help us test it. +# OpenID Connect # oidc: # issuer: "https://your-oidc.issuer.com/path" # client_id: "your-oidc-client-id" # client_secret: "your-oidc-client-secret" +# +# # Domain map is used to map incomming users (by their email) to +# # a namespace. The key can be a string, or regex. # domain_map: # ".*": default-namespace From bac81176b25b97d1cb0fb9b48657bf1aaf8d8fdb Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Sat, 30 Oct 2021 15:39:05 +0000 Subject: [PATCH 057/300] Remove lint from generated testcode --- oidc_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/oidc_test.go b/oidc_test.go index ddb44e4c..b501ff14 100644 --- a/oidc_test.go +++ b/oidc_test.go @@ -144,6 +144,7 @@ func TestHeadscale_getNamespaceFromEmail(t *testing.T) { want1: false, }, } + //nolint for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { h := &Headscale{ From 223c6118209cf38fd9a548bf4a0a84ac67d5eb5a Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 31 Oct 2021 09:34:07 +0000 Subject: [PATCH 058/300] docs(README): update contributors --- README.md | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index a3c09396..2e8f8277 100644 --- a/README.md +++ b/README.md @@ -91,6 +91,13 @@ Please have a look at the documentation under [`docs/`](docs/). ohdearaugustin + + + unreality/ +
+ unreality +
+ Aaron @@ -98,6 +105,8 @@ Please have a look at the documentation under [`docs/`](docs/). Aaron Bieber + + Paul @@ -105,8 +114,6 @@ Please have a look at the documentation under [`docs/`](docs/). Paul Tötterman - - Casey @@ -142,6 +149,8 @@ Please have a look at the documentation under [`docs/`](docs/). Felix Kronlage-Dammers + + Felix @@ -149,8 +158,6 @@ Please have a look at the documentation under [`docs/`](docs/). Felix Yan - - Shaanan @@ -186,6 +193,8 @@ Please have a look at the documentation under [`docs/`](docs/). Tjerk Woudsma + + Zakhar @@ -193,8 +202,6 @@ Please have a look at the documentation under [`docs/`](docs/). Zakhar Bessarab - - derelm/ From ca15a53fad29482f86392d1e002d1fa7af316eab Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Sun, 31 Oct 2021 09:58:01 +0000 Subject: [PATCH 059/300] Add timeout to integration test for execCommand to fail faster --- integration_test.go | 58 +++++++++++++++++++++++++++++++-------------- 1 file changed, 40 insertions(+), 18 deletions(-) diff --git a/integration_test.go b/integration_test.go index 07894188..1f30bcab 100644 --- a/integration_test.go +++ b/integration_test.go @@ -39,7 +39,7 @@ var ( headscale dockertest.Resource ) -var tailscaleVersions = []string{"1.14.3", "1.12.3"} +var tailscaleVersions = []string{"1.16.2", "1.14.3", "1.12.3"} type TestNamespace struct { count int @@ -99,26 +99,48 @@ func executeCommand(resource *dockertest.Resource, cmd []string, env []string) ( var stdout bytes.Buffer var stderr bytes.Buffer - exitCode, err := resource.Exec( - cmd, - dockertest.ExecOptions{ - Env: env, - StdOut: &stdout, - StdErr: &stderr, - }, - ) - if err != nil { - return "", err + // TODO(kradalby): Make configurable + timeout := 10 * time.Second + + type result struct { + exitCode int + err error } - if exitCode != 0 { - fmt.Println("Command: ", cmd) - fmt.Println("stdout: ", stdout.String()) - fmt.Println("stderr: ", stderr.String()) - return "", fmt.Errorf("command failed with: %s", stderr.String()) - } + resultChan := make(chan result, 1) - return stdout.String(), nil + // Run your long running function in it's own goroutine and pass back it's + // response into our channel. + go func() { + exitCode, err := resource.Exec( + cmd, + dockertest.ExecOptions{ + Env: env, + StdOut: &stdout, + StdErr: &stderr, + }, + ) + resultChan <- result{exitCode, err} + }() + + // Listen on our channel AND a timeout channel - which ever happens first. + select { + case res := <-resultChan: + if res.err != nil { + return "", res.err + } + + if res.exitCode != 0 { + fmt.Println("Command: ", cmd) + fmt.Println("stdout: ", stdout.String()) + fmt.Println("stderr: ", stderr.String()) + return "", fmt.Errorf("command failed with: %s", stderr.String()) + } + + return stdout.String(), nil + case <-time.After(timeout): + return "", fmt.Errorf("command timed out after %s", timeout) + } } func saveLog(resource *dockertest.Resource, basePath string) error { From 3f30bf1e33e136fe318c7358ea0836102661ab1b Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Sun, 31 Oct 2021 16:19:38 +0000 Subject: [PATCH 060/300] Ensure we set up TLS for http --- app.go | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/app.go b/app.go index 683d3a72..d82eae5d 100644 --- a/app.go +++ b/app.go @@ -474,7 +474,16 @@ func (h *Headscale) Serve() error { g.Go(func() error { return grpcServer.Serve(socketListener) }) g.Go(func() error { return grpcServer.Serve(grpcListener) }) - g.Go(func() error { return httpServer.Serve(httpListener) }) + + if tlsConfig != nil { + g.Go(func() error { + tlsl := tls.NewListener(httpListener, tlsConfig) + return httpServer.Serve(tlsl) + }) + } else { + g.Go(func() error { return httpServer.Serve(httpListener) }) + } + g.Go(func() error { return m.Serve() }) log.Info().Msgf("listening and serving (multiplexed HTTP and gRPC) on: %s", h.cfg.Addr) From 12f2a7cee0ec7f0f84f60967000940c56e679409 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Sun, 31 Oct 2021 16:26:51 +0000 Subject: [PATCH 061/300] Move context per cure's suggestion --- cmd/headscale/cli/namespaces.go | 8 ++++---- cmd/headscale/cli/utils.go | 6 +----- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/cmd/headscale/cli/namespaces.go b/cmd/headscale/cli/namespaces.go index 044347fe..1c4e3762 100644 --- a/cmd/headscale/cli/namespaces.go +++ b/cmd/headscale/cli/namespaces.go @@ -38,14 +38,14 @@ var createNamespaceCmd = &cobra.Command{ Run: func(cmd *cobra.Command, args []string) { o, _ := cmd.Flags().GetString("output") - client, conn := getHeadscaleGRPCClient() + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + + client, conn := getHeadscaleGRPCClient(ctx) defer conn.Close() log.Trace().Interface("client", client).Msg("Obtained gRPC client") - ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) - defer cancel() - request := &apiV1.CreateNamespaceRequest{Name: args[0]} log.Trace().Interface("request", request).Msg("Sending CreateNamespace request") diff --git a/cmd/headscale/cli/utils.go b/cmd/headscale/cli/utils.go index 035f508e..cd467697 100644 --- a/cmd/headscale/cli/utils.go +++ b/cmd/headscale/cli/utils.go @@ -316,11 +316,7 @@ func getHeadscaleApp() (*headscale.Headscale, error) { return h, nil } -func getHeadscaleGRPCClient() (apiV1.HeadscaleServiceClient, *grpc.ClientConn) { - // TODO(kradalby): Make configurable - ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) - defer cancel() - +func getHeadscaleGRPCClient(ctx context.Context) (apiV1.HeadscaleServiceClient, *grpc.ClientConn) { grpcOptions := []grpc.DialOption{ grpc.WithBlock(), } From 1c9b1ea91a772ac67df392636e7bfd0dfa1d100b Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Sun, 31 Oct 2021 16:34:20 +0000 Subject: [PATCH 062/300] Add todo --- app.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app.go b/app.go index d82eae5d..63c73ff7 100644 --- a/app.go +++ b/app.go @@ -473,6 +473,8 @@ func (h *Headscale) Serve() error { g := new(errgroup.Group) g.Go(func() error { return grpcServer.Serve(socketListener) }) + + // TODO(kradalby): Verify if we need the same TLS setup for gRPC as HTTP g.Go(func() error { return grpcServer.Serve(grpcListener) }) if tlsConfig != nil { From 8db45a4e75f7a1adb20cca7643f4e3030443a070 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Sun, 31 Oct 2021 19:52:34 +0000 Subject: [PATCH 063/300] Setup a seperate, non-tls, no auth, socket grpc --- app.go | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/app.go b/app.go index 63c73ff7..faaef8db 100644 --- a/app.go +++ b/app.go @@ -261,11 +261,11 @@ func (h *Headscale) grpcAuthenticationInterceptor(ctx context.Context, p, _ := peer.FromContext(ctx) // TODO(kradalby): Figure out what @ means (socket wise) and if it can be exploited - if p.Addr.String() == "@" { - log.Trace().Caller().Str("client_address", p.Addr.String()).Msg("Client connecting over socket") + // if p.Addr.String() == "@" { + // log.Trace().Caller().Str("client_address", p.Addr.String()).Msg("Client connecting over socket") - return handler(ctx, req) - } + // return handler(ctx, req) + // } log.Trace().Caller().Str("client_address", p.Addr.String()).Msg("Client is trying to authenticate") @@ -467,12 +467,17 @@ func (h *Headscale) Serve() error { grpcServer := grpc.NewServer(grpcOptions...) + // Start the local gRPC server without TLS and without authentication + grpcSocket := grpc.NewServer() + apiV1.RegisterHeadscaleServiceServer(grpcServer, newHeadscaleV1APIServer(h)) + apiV1.RegisterHeadscaleServiceServer(grpcSocket, newHeadscaleV1APIServer(h)) reflection.Register(grpcServer) + reflection.Register(grpcSocket) g := new(errgroup.Group) - g.Go(func() error { return grpcServer.Serve(socketListener) }) + g.Go(func() error { return grpcSocket.Serve(socketListener) }) // TODO(kradalby): Verify if we need the same TLS setup for gRPC as HTTP g.Go(func() error { return grpcServer.Serve(grpcListener) }) From 53df9afc2a8fff867bd57ac89d9a46b2cc727ef2 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Sun, 31 Oct 2021 19:54:38 +0000 Subject: [PATCH 064/300] Fix step naming error --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index f1773af9..ca4d4cf2 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -27,7 +27,7 @@ jobs: sudo apt update sudo apt install -y make - - name: Run lint + - name: Run build run: make build - uses: actions/upload-artifact@v2 From b91c115adebf7e5298f0e922ae4fbfd20f1613c4 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Sun, 31 Oct 2021 19:57:42 +0000 Subject: [PATCH 065/300] Remove "auth skip" for socket traffic --- app.go | 7 ------- 1 file changed, 7 deletions(-) diff --git a/app.go b/app.go index faaef8db..a28a2152 100644 --- a/app.go +++ b/app.go @@ -260,13 +260,6 @@ func (h *Headscale) grpcAuthenticationInterceptor(ctx context.Context, // the server p, _ := peer.FromContext(ctx) - // TODO(kradalby): Figure out what @ means (socket wise) and if it can be exploited - // if p.Addr.String() == "@" { - // log.Trace().Caller().Str("client_address", p.Addr.String()).Msg("Client connecting over socket") - - // return handler(ctx, req) - // } - log.Trace().Caller().Str("client_address", p.Addr.String()).Msg("Client is trying to authenticate") md, ok := metadata.FromIncomingContext(ctx) From 9954a3c599dadfc54f0447ea815d9b0f07b2298c Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Tue, 2 Nov 2021 21:46:15 +0000 Subject: [PATCH 066/300] Add handling for closing the socket --- app.go | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/app.go b/app.go index a28a2152..b61331a1 100644 --- a/app.go +++ b/app.go @@ -10,9 +10,11 @@ import ( "net/http" "net/url" "os" + "os/signal" "sort" "strings" "sync" + "syscall" "time" "github.com/coreos/go-oidc/v3/oidc" @@ -352,6 +354,19 @@ func (h *Headscale) Serve() error { panic(err) } + // Handle common process-killing signals so we can gracefully shut down: + sigc := make(chan os.Signal, 1) + signal.Notify(sigc, os.Interrupt, os.Kill, syscall.SIGTERM) + go func(c chan os.Signal) { + // Wait for a SIGINT or SIGKILL: + sig := <-c + log.Printf("Caught signal %s: shutting down.", sig) + // Stop listening (and unlink the socket if unix type): + socketListener.Close() + // And we're done: + os.Exit(0) + }(sigc) + networkListener, err := net.Listen("tcp", h.cfg.Addr) if err != nil { panic(err) From 7c774bc5470d9cf7a7ca567c4a69ccb0d748b171 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Tue, 2 Nov 2021 21:49:19 +0000 Subject: [PATCH 067/300] Remove flag that cant be trapped --- app.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app.go b/app.go index b61331a1..1f456665 100644 --- a/app.go +++ b/app.go @@ -356,7 +356,7 @@ func (h *Headscale) Serve() error { // Handle common process-killing signals so we can gracefully shut down: sigc := make(chan os.Signal, 1) - signal.Notify(sigc, os.Interrupt, os.Kill, syscall.SIGTERM) + signal.Notify(sigc, os.Interrupt, syscall.SIGTERM) go func(c chan os.Signal) { // Wait for a SIGINT or SIGKILL: sig := <-c From a6aa6a4f7b6431abb55f1e82265bc08318405012 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Thu, 4 Nov 2021 22:02:10 +0000 Subject: [PATCH 068/300] Add proto rpc interface for cli This commit adds proto rpc definitions for the communication needed for the CLI interface. This will allow us to move the rest of the CLI interface over to gRPC and in the future allow remote access --- proto/headscale/v1/device.proto | 83 ++++++++++++ proto/headscale/v1/headscale.proto | 198 +++++++++++++++++----------- proto/headscale/v1/machine.proto | 102 ++++++++++++++ proto/headscale/v1/namespace.proto | 50 +++++++ proto/headscale/v1/preauthkey.proto | 43 ++++++ proto/headscale/v1/routes.proto | 25 ++++ 6 files changed, 425 insertions(+), 76 deletions(-) create mode 100644 proto/headscale/v1/device.proto create mode 100644 proto/headscale/v1/machine.proto create mode 100644 proto/headscale/v1/namespace.proto create mode 100644 proto/headscale/v1/preauthkey.proto create mode 100644 proto/headscale/v1/routes.proto diff --git a/proto/headscale/v1/device.proto b/proto/headscale/v1/device.proto new file mode 100644 index 00000000..207ff374 --- /dev/null +++ b/proto/headscale/v1/device.proto @@ -0,0 +1,83 @@ +syntax = "proto3"; +package headscale.v1; +option go_package = "github.com/juanfont/headscale/gen/go/v1"; + +import "google/protobuf/timestamp.proto"; + +// This is a potential reimplementation of Tailscale's API +// https://github.com/tailscale/tailscale/blob/main/api.md + +message Latency { + float latency_ms = 1; + bool preferred = 2; +} + +message ClientSupports { + bool hair_pinning = 1; + bool ipv6 = 2; + bool pcp = 3; + bool pmp = 4; + bool udp = 5; + bool upnp = 6; +} + +message ClientConnectivity { + repeated string endpoints = 1; + string derp = 2; + bool mapping_varies_by_dest_ip = 3; + map latency = 4; + ClientSupports client_supports = 5; +} + +message GetDeviceRequest { + string id = 1; +} + +message GetDeviceResponse { + repeated string addresses = 1; + string id = 2; + string user = 3; + string name = 4; + string hostname = 5; + string client_version = 6; + bool update_available = 7; + string os = 8; + google.protobuf.Timestamp created = 9; + google.protobuf.Timestamp last_seen = 10; + bool key_expiry_disabled = 11; + google.protobuf.Timestamp expires = 12; + bool authorized = 13; + bool is_external = 14; + string machine_key = 15; + string node_key = 16; + bool blocks_incoming_connections = 17; + repeated string enabled_routes = 18; + repeated string advertised_routes = 19; + ClientConnectivity client_connectivity = 20; +} + +message DeleteDeviceRequest { + string id = 1; +} + +message DeleteDeviceResponse { +} + +message GetDeviceRoutesRequest { + string id = 1; +} + +message GetDeviceRoutesResponse { + repeated string enabled_routes = 1; + repeated string advertised_routes = 2; +} + +message EnableDeviceRoutesRequest { + string id = 1; + repeated string routes = 2; +} + +message EnableDeviceRoutesResponse { + repeated string enabled_routes = 1; + repeated string advertised_routes = 2; +} diff --git a/proto/headscale/v1/headscale.proto b/proto/headscale/v1/headscale.proto index 2e6b0a67..26fe2f96 100644 --- a/proto/headscale/v1/headscale.proto +++ b/proto/headscale/v1/headscale.proto @@ -2,86 +2,19 @@ syntax = "proto3"; package headscale.v1; option go_package = "github.com/juanfont/headscale/gen/go/v1"; -import "google/protobuf/timestamp.proto"; import "google/api/annotations.proto"; -enum RegisterMethod { - REGISTER_METHOD_UNSPECIFIED = 0; - REGISTER_METHOD_AUTH_KEY = 1; - REGISTER_METHOD_CLI = 2; - REGISTER_METHOD_OIDC = 3; -} - -// message PreAuthKey { -// uint64 id = 1; -// string key = 2; -// uint32 namespace_id = 3; -// Namespace namespace = 4; -// bool reusable = 5; -// bool ephemeral = 6; -// bool used = 7; -// -// google.protobuf.Timestamp created_at = 8; -// google.protobuf.Timestamp expiration = 9; -// } - -message GetMachineRequest { - uint64 machine_id = 1; -} - -message GetMachineResponse { - uint64 id = 1; - string machine_key = 2; - string node_key = 3; - string disco_key = 4; - string ip_address = 5; - string name = 6; - uint32 namespace_id = 7; - - bool registered = 8; - RegisterMethod register_method = 9; - uint32 auth_key_id = 10; - // PreAuthKey auth_key = 11; - - google.protobuf.Timestamp last_seen = 12; - google.protobuf.Timestamp last_successful_update = 13; - google.protobuf.Timestamp expiry = 14; - - // bytes host_info = 15; - // bytes endpoints = 16; - // bytes enabled_routes = 17; - - // google.protobuf.Timestamp created_at = 18; - // google.protobuf.Timestamp updated_at = 19; - // google.protobuf.Timestamp deleted_at = 20; -} - -message CreateNamespaceRequest { - string name = 1; -} - -message CreateNamespaceResponse { - string name = 1; -} - -message DeleteNamespaceRequest { - string name = 1; -} - -message DeleteNamespaceResponse { -} - -message ListNamespacesRequest { -} - -message ListNamespacesResponse { - repeated string namespaces = 1; -} +import "headscale/v1/namespace.proto"; +import "headscale/v1/preauthkey.proto"; +import "headscale/v1/machine.proto"; +import "headscale/v1/routes.proto"; +// import "headscale/v1/device.proto"; service HeadscaleService { - rpc GetMachine(GetMachineRequest) returns(GetMachineResponse) { + // --- Namespace start --- + rpc GetNamespace(GetNamespaceRequest) returns(GetNamespaceResponse) { option(google.api.http) = { - get : "/api/v1/machine/{machine_id}" + get : "/api/v1/namespace/{name}" }; } @@ -92,9 +25,15 @@ service HeadscaleService { }; } + rpc RenameNamespace(RenameNamespaceRequest) returns(RenameNamespaceResponse) { + option(google.api.http) = { + post : "/api/v1/namespace/{old_name}/rename/{new_name}" + }; + } + rpc DeleteNamespace(DeleteNamespaceRequest) returns(DeleteNamespaceResponse) { option(google.api.http) = { - delete : "/api/v1/namespace" + delete : "/api/v1/namespace/{name}" }; } @@ -103,4 +42,111 @@ service HeadscaleService { get : "/api/v1/namespace" }; } + // --- Namespace end --- + + // --- PreAuthKeys start --- + rpc CreatePreAuthKey(CreatePreAuthKeyRequest) returns(CreatePreAuthKeyResponse) { + option(google.api.http) = { + post : "/api/v1/preauthkey" + body : "*" + }; + } + + rpc ExpirePreAuthKey(ExpirePreAuthKeyRequest) returns(ExpirePreAuthKeyResponse) { + option(google.api.http) = { + post : "/api/v1/preauthkey/expire" + body : "*" + }; + } + + rpc ListPreAuthKeys(ListPreAuthKeysRequest) returns(ListPreAuthKeysResponse) { + option(google.api.http) = { + get : "/api/v1/preauthkey" + }; + } + // --- PreAuthKeys end --- + + // --- Machine start --- + rpc DebugCreateMachine(DebugCreateMachineRequest) returns(DebugCreateMachineResponse) { + option(google.api.http) = { + post : "/api/v1/debug/machine" + body : "*" + }; + } + + rpc GetMachine(GetMachineRequest) returns(GetMachineResponse) { + option(google.api.http) = { + get : "/api/v1/machine/{machine_id}" + }; + } + + rpc RegisterMachine(RegisterMachineRequest) returns(RegisterMachineResponse) { + option(google.api.http) = { + post : "/api/v1/machine/register" + }; + } + + rpc DeleteMachine(DeleteMachineRequest) returns(DeleteMachineResponse) { + option(google.api.http) = { + delete : "/api/v1/machine/{machine_id}" + }; + } + + rpc ListMachines(ListMachinesRequest) returns(ListMachinesResponse) { + option(google.api.http) = { + get : "/api/v1/machine" + }; + } + + rpc ShareMachine(ShareMachineRequest) returns(ShareMachineResponse) { + option(google.api.http) = { + post : "/api/v1/machine/{machine_id}/share/{namespace}" + }; + } + + rpc UnshareMachine(UnshareMachineRequest) returns(UnshareMachineResponse) { + option(google.api.http) = { + post : "/api/v1/machine/{machine_id}/unshare/{namespace}" + }; + } + // --- Machine end --- + + // --- Route start --- + rpc GetMachineRoute(GetMachineRouteRequest) returns(GetMachineRouteResponse) { + option(google.api.http) = { + get : "/api/v1/machine/{machine_id}/routes" + }; + } + + rpc EnableMachineRoutes(EnableMachineRoutesRequest) returns(EnableMachineRoutesResponse) { + option(google.api.http) = { + post : "/api/v1/machine/{machine_id}/routes" + }; + } + // --- Route end --- + + // Implement Tailscale API + // rpc GetDevice(GetDeviceRequest) returns(GetDeviceResponse) { + // option(google.api.http) = { + // get : "/api/v1/device/{id}" + // }; + // } + + // rpc DeleteDevice(DeleteDeviceRequest) returns(DeleteDeviceResponse) { + // option(google.api.http) = { + // delete : "/api/v1/device/{id}" + // }; + // } + + // rpc GetDeviceRoutes(GetDeviceRoutesRequest) returns(GetDeviceRoutesResponse) { + // option(google.api.http) = { + // get : "/api/v1/device/{id}/routes" + // }; + // } + + // rpc EnableDeviceRoutes(EnableDeviceRoutesRequest) returns(EnableDeviceRoutesResponse) { + // option(google.api.http) = { + // post : "/api/v1/device/{id}/routes" + // }; + // } } diff --git a/proto/headscale/v1/machine.proto b/proto/headscale/v1/machine.proto new file mode 100644 index 00000000..4e53c4ad --- /dev/null +++ b/proto/headscale/v1/machine.proto @@ -0,0 +1,102 @@ +syntax = "proto3"; +package headscale.v1; +option go_package = "github.com/juanfont/headscale/gen/go/v1"; + +import "google/protobuf/timestamp.proto"; +import "headscale/v1/namespace.proto"; +import "headscale/v1/preauthkey.proto"; + +enum RegisterMethod { + REGISTER_METHOD_UNSPECIFIED = 0; + REGISTER_METHOD_AUTH_KEY = 1; + REGISTER_METHOD_CLI = 2; + REGISTER_METHOD_OIDC = 3; +} + +message Machine { + uint64 id = 1; + string machine_key = 2; + string node_key = 3; + string disco_key = 4; + string ip_address = 5; + string name = 6; + Namespace namespace = 7; + + bool registered = 8; + RegisterMethod register_method = 9; + + google.protobuf.Timestamp last_seen = 10; + google.protobuf.Timestamp last_successful_update = 11; + google.protobuf.Timestamp expiry = 12; + + PreAuthKey pre_auth_key = 13; + + google.protobuf.Timestamp created_at = 14; + // google.protobuf.Timestamp updated_at = 14; + // google.protobuf.Timestamp deleted_at = 15; + + // bytes host_info = 15; + // bytes endpoints = 16; + // bytes enabled_routes = 17; +} + +message RegisterMachineRequest { + string namespace = 1; + string key = 2; +} + +message RegisterMachineResponse { + Machine machine = 1; +} + +message GetMachineRequest { + uint64 machine_id = 1; +} + +message GetMachineResponse { + Machine machine = 1; +} + +message DeleteMachineRequest { + uint64 machine_id = 1; +} + +message DeleteMachineResponse { +} + +message ListMachinesRequest { + string namespace = 1; +} + +message ListMachinesResponse { + repeated Machine machines = 1; +} + +message ShareMachineRequest { + uint64 machine_id = 1; + string namespace = 2; +} + +message ShareMachineResponse { + Machine machine = 1; +} + +message UnshareMachineRequest { + uint64 machine_id = 1; + string namespace = 2; +} + +message UnshareMachineResponse { + Machine machine = 1; +} + +message DebugCreateMachineRequest { + string namespace = 1; + string key = 2; + string name = 3; + repeated string routes = 4; +} + +message DebugCreateMachineResponse { + Machine machine = 1; +} diff --git a/proto/headscale/v1/namespace.proto b/proto/headscale/v1/namespace.proto new file mode 100644 index 00000000..997b74c3 --- /dev/null +++ b/proto/headscale/v1/namespace.proto @@ -0,0 +1,50 @@ +syntax = "proto3"; +package headscale.v1; +option go_package = "github.com/juanfont/headscale/gen/go/v1"; + +import "google/protobuf/timestamp.proto"; + +message Namespace { + string id = 1; + string name = 2; + google.protobuf.Timestamp created_at = 3; +} + +message GetNamespaceRequest { + string name = 1; +} + +message GetNamespaceResponse { + Namespace namespace = 1; +} + +message CreateNamespaceRequest { + string name = 1; +} + +message CreateNamespaceResponse { + Namespace namespace = 1; +} + +message RenameNamespaceRequest { + string old_name = 1; + string new_name = 2; +} + +message RenameNamespaceResponse { + Namespace namespace = 1; +} + +message DeleteNamespaceRequest { + string name = 1; +} + +message DeleteNamespaceResponse { +} + +message ListNamespacesRequest { +} + +message ListNamespacesResponse { + repeated Namespace namespaces = 1; +} diff --git a/proto/headscale/v1/preauthkey.proto b/proto/headscale/v1/preauthkey.proto new file mode 100644 index 00000000..195c3215 --- /dev/null +++ b/proto/headscale/v1/preauthkey.proto @@ -0,0 +1,43 @@ +syntax = "proto3"; +package headscale.v1; +option go_package = "github.com/juanfont/headscale/gen/go/v1"; + +import "google/protobuf/timestamp.proto"; + +message PreAuthKey { + string namespace = 1; + string id = 2; + string key = 3; + bool resuable = 4; + bool ephemeral = 5; + bool used = 6; + google.protobuf.Timestamp expiration = 7; + google.protobuf.Timestamp created_at = 8; +} + +message CreatePreAuthKeyRequest { + string namespace = 1; + bool resuable = 2; + bool ephemeral = 3; + google.protobuf.Timestamp expiration = 4; +} + +message CreatePreAuthKeyResponse { + PreAuthKey pre_auth_key = 1; +} + +message ExpirePreAuthKeyRequest { + string namespace = 1; + string key = 2; +} + +message ExpirePreAuthKeyResponse { +} + +message ListPreAuthKeysRequest { + string namespace = 1; +} + +message ListPreAuthKeysResponse { + repeated PreAuthKey pre_auth_keys = 1; +} diff --git a/proto/headscale/v1/routes.proto b/proto/headscale/v1/routes.proto new file mode 100644 index 00000000..353c4294 --- /dev/null +++ b/proto/headscale/v1/routes.proto @@ -0,0 +1,25 @@ +syntax = "proto3"; +package headscale.v1; +option go_package = "github.com/juanfont/headscale/gen/go/v1"; + +message Routes { + repeated string advertised_routes = 1; + repeated string enabled_routes = 2; +} + +message GetMachineRouteRequest { + uint64 machine_id = 1; +} + +message GetMachineRouteResponse { + Routes routes = 1; +} + +message EnableMachineRoutesRequest { + uint64 machine_id = 1; + repeated string routes = 2; +} + +message EnableMachineRoutesResponse { + Routes routes = 1; +} From 52703619892e8c4e6a11ddbda6337b492a231986 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Thu, 4 Nov 2021 22:07:59 +0000 Subject: [PATCH 069/300] Add generated files from protobuf --- gen/go/headscale/v1/device.pb.go | 1115 ++++++++++++++ gen/go/headscale/v1/headscale.pb.go | 981 +++--------- gen/go/headscale/v1/headscale.pb.gw.go | 1363 ++++++++++++++++- gen/go/headscale/v1/headscale_grpc.pb.go | 504 +++++- gen/go/headscale/v1/machine.pb.go | 1316 ++++++++++++++++ gen/go/headscale/v1/namespace.pb.go | 801 ++++++++++ gen/go/headscale/v1/preauthkey.pb.go | 640 ++++++++ gen/go/headscale/v1/routes.pb.go | 424 +++++ .../headscale/v1/device.swagger.json | 43 + .../headscale/v1/headscale.swagger.json | 717 ++++++++- .../headscale/v1/machine.swagger.json | 43 + .../headscale/v1/namespace.swagger.json | 43 + .../headscale/v1/preauthkey.swagger.json | 43 + .../headscale/v1/routes.swagger.json | 43 + 14 files changed, 7228 insertions(+), 848 deletions(-) create mode 100644 gen/go/headscale/v1/device.pb.go create mode 100644 gen/go/headscale/v1/machine.pb.go create mode 100644 gen/go/headscale/v1/namespace.pb.go create mode 100644 gen/go/headscale/v1/preauthkey.pb.go create mode 100644 gen/go/headscale/v1/routes.pb.go create mode 100644 gen/openapiv2/headscale/v1/device.swagger.json create mode 100644 gen/openapiv2/headscale/v1/machine.swagger.json create mode 100644 gen/openapiv2/headscale/v1/namespace.swagger.json create mode 100644 gen/openapiv2/headscale/v1/preauthkey.swagger.json create mode 100644 gen/openapiv2/headscale/v1/routes.swagger.json diff --git a/gen/go/headscale/v1/device.pb.go b/gen/go/headscale/v1/device.pb.go new file mode 100644 index 00000000..302c2653 --- /dev/null +++ b/gen/go/headscale/v1/device.pb.go @@ -0,0 +1,1115 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.27.1 +// protoc v3.18.1 +// source: headscale/v1/device.proto + +package v1 + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + timestamppb "google.golang.org/protobuf/types/known/timestamppb" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type Latency struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + LatencyMs float32 `protobuf:"fixed32,1,opt,name=latency_ms,json=latencyMs,proto3" json:"latency_ms,omitempty"` + Preferred bool `protobuf:"varint,2,opt,name=preferred,proto3" json:"preferred,omitempty"` +} + +func (x *Latency) Reset() { + *x = Latency{} + if protoimpl.UnsafeEnabled { + mi := &file_headscale_v1_device_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Latency) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Latency) ProtoMessage() {} + +func (x *Latency) ProtoReflect() protoreflect.Message { + mi := &file_headscale_v1_device_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Latency.ProtoReflect.Descriptor instead. +func (*Latency) Descriptor() ([]byte, []int) { + return file_headscale_v1_device_proto_rawDescGZIP(), []int{0} +} + +func (x *Latency) GetLatencyMs() float32 { + if x != nil { + return x.LatencyMs + } + return 0 +} + +func (x *Latency) GetPreferred() bool { + if x != nil { + return x.Preferred + } + return false +} + +type ClientSupports struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + HairPinning bool `protobuf:"varint,1,opt,name=hair_pinning,json=hairPinning,proto3" json:"hair_pinning,omitempty"` + Ipv6 bool `protobuf:"varint,2,opt,name=ipv6,proto3" json:"ipv6,omitempty"` + Pcp bool `protobuf:"varint,3,opt,name=pcp,proto3" json:"pcp,omitempty"` + Pmp bool `protobuf:"varint,4,opt,name=pmp,proto3" json:"pmp,omitempty"` + Udp bool `protobuf:"varint,5,opt,name=udp,proto3" json:"udp,omitempty"` + Upnp bool `protobuf:"varint,6,opt,name=upnp,proto3" json:"upnp,omitempty"` +} + +func (x *ClientSupports) Reset() { + *x = ClientSupports{} + if protoimpl.UnsafeEnabled { + mi := &file_headscale_v1_device_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ClientSupports) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ClientSupports) ProtoMessage() {} + +func (x *ClientSupports) ProtoReflect() protoreflect.Message { + mi := &file_headscale_v1_device_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ClientSupports.ProtoReflect.Descriptor instead. +func (*ClientSupports) Descriptor() ([]byte, []int) { + return file_headscale_v1_device_proto_rawDescGZIP(), []int{1} +} + +func (x *ClientSupports) GetHairPinning() bool { + if x != nil { + return x.HairPinning + } + return false +} + +func (x *ClientSupports) GetIpv6() bool { + if x != nil { + return x.Ipv6 + } + return false +} + +func (x *ClientSupports) GetPcp() bool { + if x != nil { + return x.Pcp + } + return false +} + +func (x *ClientSupports) GetPmp() bool { + if x != nil { + return x.Pmp + } + return false +} + +func (x *ClientSupports) GetUdp() bool { + if x != nil { + return x.Udp + } + return false +} + +func (x *ClientSupports) GetUpnp() bool { + if x != nil { + return x.Upnp + } + return false +} + +type ClientConnectivity struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Endpoints []string `protobuf:"bytes,1,rep,name=endpoints,proto3" json:"endpoints,omitempty"` + Derp string `protobuf:"bytes,2,opt,name=derp,proto3" json:"derp,omitempty"` + MappingVariesByDestIp bool `protobuf:"varint,3,opt,name=mapping_varies_by_dest_ip,json=mappingVariesByDestIp,proto3" json:"mapping_varies_by_dest_ip,omitempty"` + Latency map[string]*Latency `protobuf:"bytes,4,rep,name=latency,proto3" json:"latency,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + ClientSupports *ClientSupports `protobuf:"bytes,5,opt,name=client_supports,json=clientSupports,proto3" json:"client_supports,omitempty"` +} + +func (x *ClientConnectivity) Reset() { + *x = ClientConnectivity{} + if protoimpl.UnsafeEnabled { + mi := &file_headscale_v1_device_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ClientConnectivity) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ClientConnectivity) ProtoMessage() {} + +func (x *ClientConnectivity) ProtoReflect() protoreflect.Message { + mi := &file_headscale_v1_device_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ClientConnectivity.ProtoReflect.Descriptor instead. +func (*ClientConnectivity) Descriptor() ([]byte, []int) { + return file_headscale_v1_device_proto_rawDescGZIP(), []int{2} +} + +func (x *ClientConnectivity) GetEndpoints() []string { + if x != nil { + return x.Endpoints + } + return nil +} + +func (x *ClientConnectivity) GetDerp() string { + if x != nil { + return x.Derp + } + return "" +} + +func (x *ClientConnectivity) GetMappingVariesByDestIp() bool { + if x != nil { + return x.MappingVariesByDestIp + } + return false +} + +func (x *ClientConnectivity) GetLatency() map[string]*Latency { + if x != nil { + return x.Latency + } + return nil +} + +func (x *ClientConnectivity) GetClientSupports() *ClientSupports { + if x != nil { + return x.ClientSupports + } + return nil +} + +type GetDeviceRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` +} + +func (x *GetDeviceRequest) Reset() { + *x = GetDeviceRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_headscale_v1_device_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetDeviceRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetDeviceRequest) ProtoMessage() {} + +func (x *GetDeviceRequest) ProtoReflect() protoreflect.Message { + mi := &file_headscale_v1_device_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetDeviceRequest.ProtoReflect.Descriptor instead. +func (*GetDeviceRequest) Descriptor() ([]byte, []int) { + return file_headscale_v1_device_proto_rawDescGZIP(), []int{3} +} + +func (x *GetDeviceRequest) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +type GetDeviceResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Addresses []string `protobuf:"bytes,1,rep,name=addresses,proto3" json:"addresses,omitempty"` + Id string `protobuf:"bytes,2,opt,name=id,proto3" json:"id,omitempty"` + User string `protobuf:"bytes,3,opt,name=user,proto3" json:"user,omitempty"` + Name string `protobuf:"bytes,4,opt,name=name,proto3" json:"name,omitempty"` + Hostname string `protobuf:"bytes,5,opt,name=hostname,proto3" json:"hostname,omitempty"` + ClientVersion string `protobuf:"bytes,6,opt,name=client_version,json=clientVersion,proto3" json:"client_version,omitempty"` + UpdateAvailable bool `protobuf:"varint,7,opt,name=update_available,json=updateAvailable,proto3" json:"update_available,omitempty"` + Os string `protobuf:"bytes,8,opt,name=os,proto3" json:"os,omitempty"` + Created *timestamppb.Timestamp `protobuf:"bytes,9,opt,name=created,proto3" json:"created,omitempty"` + LastSeen *timestamppb.Timestamp `protobuf:"bytes,10,opt,name=last_seen,json=lastSeen,proto3" json:"last_seen,omitempty"` + KeyExpiryDisabled bool `protobuf:"varint,11,opt,name=key_expiry_disabled,json=keyExpiryDisabled,proto3" json:"key_expiry_disabled,omitempty"` + Expires *timestamppb.Timestamp `protobuf:"bytes,12,opt,name=expires,proto3" json:"expires,omitempty"` + Authorized bool `protobuf:"varint,13,opt,name=authorized,proto3" json:"authorized,omitempty"` + IsExternal bool `protobuf:"varint,14,opt,name=is_external,json=isExternal,proto3" json:"is_external,omitempty"` + MachineKey string `protobuf:"bytes,15,opt,name=machine_key,json=machineKey,proto3" json:"machine_key,omitempty"` + NodeKey string `protobuf:"bytes,16,opt,name=node_key,json=nodeKey,proto3" json:"node_key,omitempty"` + BlocksIncomingConnections bool `protobuf:"varint,17,opt,name=blocks_incoming_connections,json=blocksIncomingConnections,proto3" json:"blocks_incoming_connections,omitempty"` + EnabledRoutes []string `protobuf:"bytes,18,rep,name=enabled_routes,json=enabledRoutes,proto3" json:"enabled_routes,omitempty"` + AdvertisedRoutes []string `protobuf:"bytes,19,rep,name=advertised_routes,json=advertisedRoutes,proto3" json:"advertised_routes,omitempty"` + ClientConnectivity *ClientConnectivity `protobuf:"bytes,20,opt,name=client_connectivity,json=clientConnectivity,proto3" json:"client_connectivity,omitempty"` +} + +func (x *GetDeviceResponse) Reset() { + *x = GetDeviceResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_headscale_v1_device_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetDeviceResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetDeviceResponse) ProtoMessage() {} + +func (x *GetDeviceResponse) ProtoReflect() protoreflect.Message { + mi := &file_headscale_v1_device_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetDeviceResponse.ProtoReflect.Descriptor instead. +func (*GetDeviceResponse) Descriptor() ([]byte, []int) { + return file_headscale_v1_device_proto_rawDescGZIP(), []int{4} +} + +func (x *GetDeviceResponse) GetAddresses() []string { + if x != nil { + return x.Addresses + } + return nil +} + +func (x *GetDeviceResponse) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *GetDeviceResponse) GetUser() string { + if x != nil { + return x.User + } + return "" +} + +func (x *GetDeviceResponse) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *GetDeviceResponse) GetHostname() string { + if x != nil { + return x.Hostname + } + return "" +} + +func (x *GetDeviceResponse) GetClientVersion() string { + if x != nil { + return x.ClientVersion + } + return "" +} + +func (x *GetDeviceResponse) GetUpdateAvailable() bool { + if x != nil { + return x.UpdateAvailable + } + return false +} + +func (x *GetDeviceResponse) GetOs() string { + if x != nil { + return x.Os + } + return "" +} + +func (x *GetDeviceResponse) GetCreated() *timestamppb.Timestamp { + if x != nil { + return x.Created + } + return nil +} + +func (x *GetDeviceResponse) GetLastSeen() *timestamppb.Timestamp { + if x != nil { + return x.LastSeen + } + return nil +} + +func (x *GetDeviceResponse) GetKeyExpiryDisabled() bool { + if x != nil { + return x.KeyExpiryDisabled + } + return false +} + +func (x *GetDeviceResponse) GetExpires() *timestamppb.Timestamp { + if x != nil { + return x.Expires + } + return nil +} + +func (x *GetDeviceResponse) GetAuthorized() bool { + if x != nil { + return x.Authorized + } + return false +} + +func (x *GetDeviceResponse) GetIsExternal() bool { + if x != nil { + return x.IsExternal + } + return false +} + +func (x *GetDeviceResponse) GetMachineKey() string { + if x != nil { + return x.MachineKey + } + return "" +} + +func (x *GetDeviceResponse) GetNodeKey() string { + if x != nil { + return x.NodeKey + } + return "" +} + +func (x *GetDeviceResponse) GetBlocksIncomingConnections() bool { + if x != nil { + return x.BlocksIncomingConnections + } + return false +} + +func (x *GetDeviceResponse) GetEnabledRoutes() []string { + if x != nil { + return x.EnabledRoutes + } + return nil +} + +func (x *GetDeviceResponse) GetAdvertisedRoutes() []string { + if x != nil { + return x.AdvertisedRoutes + } + return nil +} + +func (x *GetDeviceResponse) GetClientConnectivity() *ClientConnectivity { + if x != nil { + return x.ClientConnectivity + } + return nil +} + +type DeleteDeviceRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` +} + +func (x *DeleteDeviceRequest) Reset() { + *x = DeleteDeviceRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_headscale_v1_device_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DeleteDeviceRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeleteDeviceRequest) ProtoMessage() {} + +func (x *DeleteDeviceRequest) ProtoReflect() protoreflect.Message { + mi := &file_headscale_v1_device_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DeleteDeviceRequest.ProtoReflect.Descriptor instead. +func (*DeleteDeviceRequest) Descriptor() ([]byte, []int) { + return file_headscale_v1_device_proto_rawDescGZIP(), []int{5} +} + +func (x *DeleteDeviceRequest) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +type DeleteDeviceResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *DeleteDeviceResponse) Reset() { + *x = DeleteDeviceResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_headscale_v1_device_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DeleteDeviceResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeleteDeviceResponse) ProtoMessage() {} + +func (x *DeleteDeviceResponse) ProtoReflect() protoreflect.Message { + mi := &file_headscale_v1_device_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DeleteDeviceResponse.ProtoReflect.Descriptor instead. +func (*DeleteDeviceResponse) Descriptor() ([]byte, []int) { + return file_headscale_v1_device_proto_rawDescGZIP(), []int{6} +} + +type GetDeviceRoutesRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` +} + +func (x *GetDeviceRoutesRequest) Reset() { + *x = GetDeviceRoutesRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_headscale_v1_device_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetDeviceRoutesRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetDeviceRoutesRequest) ProtoMessage() {} + +func (x *GetDeviceRoutesRequest) ProtoReflect() protoreflect.Message { + mi := &file_headscale_v1_device_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetDeviceRoutesRequest.ProtoReflect.Descriptor instead. +func (*GetDeviceRoutesRequest) Descriptor() ([]byte, []int) { + return file_headscale_v1_device_proto_rawDescGZIP(), []int{7} +} + +func (x *GetDeviceRoutesRequest) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +type GetDeviceRoutesResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + EnabledRoutes []string `protobuf:"bytes,1,rep,name=enabled_routes,json=enabledRoutes,proto3" json:"enabled_routes,omitempty"` + AdvertisedRoutes []string `protobuf:"bytes,2,rep,name=advertised_routes,json=advertisedRoutes,proto3" json:"advertised_routes,omitempty"` +} + +func (x *GetDeviceRoutesResponse) Reset() { + *x = GetDeviceRoutesResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_headscale_v1_device_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetDeviceRoutesResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetDeviceRoutesResponse) ProtoMessage() {} + +func (x *GetDeviceRoutesResponse) ProtoReflect() protoreflect.Message { + mi := &file_headscale_v1_device_proto_msgTypes[8] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetDeviceRoutesResponse.ProtoReflect.Descriptor instead. +func (*GetDeviceRoutesResponse) Descriptor() ([]byte, []int) { + return file_headscale_v1_device_proto_rawDescGZIP(), []int{8} +} + +func (x *GetDeviceRoutesResponse) GetEnabledRoutes() []string { + if x != nil { + return x.EnabledRoutes + } + return nil +} + +func (x *GetDeviceRoutesResponse) GetAdvertisedRoutes() []string { + if x != nil { + return x.AdvertisedRoutes + } + return nil +} + +type EnableDeviceRoutesRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Routes []string `protobuf:"bytes,2,rep,name=routes,proto3" json:"routes,omitempty"` +} + +func (x *EnableDeviceRoutesRequest) Reset() { + *x = EnableDeviceRoutesRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_headscale_v1_device_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *EnableDeviceRoutesRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*EnableDeviceRoutesRequest) ProtoMessage() {} + +func (x *EnableDeviceRoutesRequest) ProtoReflect() protoreflect.Message { + mi := &file_headscale_v1_device_proto_msgTypes[9] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use EnableDeviceRoutesRequest.ProtoReflect.Descriptor instead. +func (*EnableDeviceRoutesRequest) Descriptor() ([]byte, []int) { + return file_headscale_v1_device_proto_rawDescGZIP(), []int{9} +} + +func (x *EnableDeviceRoutesRequest) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *EnableDeviceRoutesRequest) GetRoutes() []string { + if x != nil { + return x.Routes + } + return nil +} + +type EnableDeviceRoutesResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + EnabledRoutes []string `protobuf:"bytes,1,rep,name=enabled_routes,json=enabledRoutes,proto3" json:"enabled_routes,omitempty"` + AdvertisedRoutes []string `protobuf:"bytes,2,rep,name=advertised_routes,json=advertisedRoutes,proto3" json:"advertised_routes,omitempty"` +} + +func (x *EnableDeviceRoutesResponse) Reset() { + *x = EnableDeviceRoutesResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_headscale_v1_device_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *EnableDeviceRoutesResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*EnableDeviceRoutesResponse) ProtoMessage() {} + +func (x *EnableDeviceRoutesResponse) ProtoReflect() protoreflect.Message { + mi := &file_headscale_v1_device_proto_msgTypes[10] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use EnableDeviceRoutesResponse.ProtoReflect.Descriptor instead. +func (*EnableDeviceRoutesResponse) Descriptor() ([]byte, []int) { + return file_headscale_v1_device_proto_rawDescGZIP(), []int{10} +} + +func (x *EnableDeviceRoutesResponse) GetEnabledRoutes() []string { + if x != nil { + return x.EnabledRoutes + } + return nil +} + +func (x *EnableDeviceRoutesResponse) GetAdvertisedRoutes() []string { + if x != nil { + return x.AdvertisedRoutes + } + return nil +} + +var File_headscale_v1_device_proto protoreflect.FileDescriptor + +var file_headscale_v1_device_proto_rawDesc = []byte{ + 0x0a, 0x19, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x64, + 0x65, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0c, 0x68, 0x65, 0x61, + 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, + 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x46, 0x0a, 0x07, 0x4c, 0x61, + 0x74, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x1d, 0x0a, 0x0a, 0x6c, 0x61, 0x74, 0x65, 0x6e, 0x63, 0x79, + 0x5f, 0x6d, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x02, 0x52, 0x09, 0x6c, 0x61, 0x74, 0x65, 0x6e, + 0x63, 0x79, 0x4d, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x72, 0x65, + 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x72, + 0x65, 0x64, 0x22, 0x91, 0x01, 0x0a, 0x0e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x53, 0x75, 0x70, + 0x70, 0x6f, 0x72, 0x74, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x68, 0x61, 0x69, 0x72, 0x5f, 0x70, 0x69, + 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x68, 0x61, 0x69, + 0x72, 0x50, 0x69, 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x12, 0x12, 0x0a, 0x04, 0x69, 0x70, 0x76, 0x36, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x04, 0x69, 0x70, 0x76, 0x36, 0x12, 0x10, 0x0a, 0x03, + 0x70, 0x63, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x03, 0x70, 0x63, 0x70, 0x12, 0x10, + 0x0a, 0x03, 0x70, 0x6d, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x03, 0x70, 0x6d, 0x70, + 0x12, 0x10, 0x0a, 0x03, 0x75, 0x64, 0x70, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x03, 0x75, + 0x64, 0x70, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x70, 0x6e, 0x70, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x04, 0x75, 0x70, 0x6e, 0x70, 0x22, 0xe3, 0x02, 0x0a, 0x12, 0x43, 0x6c, 0x69, 0x65, 0x6e, + 0x74, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x12, 0x1c, 0x0a, + 0x09, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, + 0x52, 0x09, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x64, + 0x65, 0x72, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x64, 0x65, 0x72, 0x70, 0x12, + 0x38, 0x0a, 0x19, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x5f, 0x76, 0x61, 0x72, 0x69, 0x65, + 0x73, 0x5f, 0x62, 0x79, 0x5f, 0x64, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x70, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x15, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x72, 0x69, 0x65, + 0x73, 0x42, 0x79, 0x44, 0x65, 0x73, 0x74, 0x49, 0x70, 0x12, 0x47, 0x0a, 0x07, 0x6c, 0x61, 0x74, + 0x65, 0x6e, 0x63, 0x79, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x68, 0x65, 0x61, + 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, + 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x2e, 0x4c, 0x61, 0x74, + 0x65, 0x6e, 0x63, 0x79, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, 0x6c, 0x61, 0x74, 0x65, 0x6e, + 0x63, 0x79, 0x12, 0x45, 0x0a, 0x0f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x73, 0x75, 0x70, + 0x70, 0x6f, 0x72, 0x74, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x68, 0x65, + 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, + 0x74, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x52, 0x0e, 0x63, 0x6c, 0x69, 0x65, 0x6e, + 0x74, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x1a, 0x51, 0x0a, 0x0c, 0x4c, 0x61, 0x74, + 0x65, 0x6e, 0x63, 0x79, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2b, 0x0a, 0x05, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x68, 0x65, 0x61, + 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x61, 0x74, 0x65, 0x6e, 0x63, + 0x79, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x22, 0x0a, 0x10, + 0x47, 0x65, 0x74, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, + 0x22, 0xa0, 0x06, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, + 0x73, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x61, 0x64, 0x64, 0x72, 0x65, + 0x73, 0x73, 0x65, 0x73, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, + 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, + 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x63, 0x6c, 0x69, 0x65, + 0x6e, 0x74, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0d, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, + 0x29, 0x0a, 0x10, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, + 0x62, 0x6c, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x75, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x6f, 0x73, + 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x6f, 0x73, 0x12, 0x34, 0x0a, 0x07, 0x63, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, + 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x07, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, + 0x12, 0x37, 0x0a, 0x09, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x65, 0x6e, 0x18, 0x0a, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, + 0x08, 0x6c, 0x61, 0x73, 0x74, 0x53, 0x65, 0x65, 0x6e, 0x12, 0x2e, 0x0a, 0x13, 0x6b, 0x65, 0x79, + 0x5f, 0x65, 0x78, 0x70, 0x69, 0x72, 0x79, 0x5f, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, + 0x18, 0x0b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x6b, 0x65, 0x79, 0x45, 0x78, 0x70, 0x69, 0x72, + 0x79, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x34, 0x0a, 0x07, 0x65, 0x78, 0x70, + 0x69, 0x72, 0x65, 0x73, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, + 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x07, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x12, + 0x1e, 0x0a, 0x0a, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x18, 0x0d, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x0a, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x12, + 0x1f, 0x0a, 0x0b, 0x69, 0x73, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x18, 0x0e, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x69, 0x73, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, + 0x12, 0x1f, 0x0a, 0x0b, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x18, + 0x0f, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x4b, 0x65, + 0x79, 0x12, 0x19, 0x0a, 0x08, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x10, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x07, 0x6e, 0x6f, 0x64, 0x65, 0x4b, 0x65, 0x79, 0x12, 0x3e, 0x0a, 0x1b, + 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x5f, 0x69, 0x6e, 0x63, 0x6f, 0x6d, 0x69, 0x6e, 0x67, 0x5f, + 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x11, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x19, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x49, 0x6e, 0x63, 0x6f, 0x6d, 0x69, 0x6e, + 0x67, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x25, 0x0a, 0x0e, + 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x18, 0x12, + 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x52, 0x6f, 0x75, + 0x74, 0x65, 0x73, 0x12, 0x2b, 0x0a, 0x11, 0x61, 0x64, 0x76, 0x65, 0x72, 0x74, 0x69, 0x73, 0x65, + 0x64, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x18, 0x13, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, + 0x61, 0x64, 0x76, 0x65, 0x72, 0x74, 0x69, 0x73, 0x65, 0x64, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, + 0x12, 0x51, 0x0a, 0x13, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, + 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x18, 0x14, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, + 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6c, 0x69, + 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x52, + 0x12, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x76, + 0x69, 0x74, 0x79, 0x22, 0x25, 0x0a, 0x13, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x44, 0x65, 0x76, + 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x22, 0x16, 0x0a, 0x14, 0x44, 0x65, + 0x6c, 0x65, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x28, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, + 0x6f, 0x75, 0x74, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, + 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x22, 0x6d, 0x0a, 0x17, + 0x47, 0x65, 0x74, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x65, 0x6e, 0x61, 0x62, 0x6c, + 0x65, 0x64, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, + 0x0d, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x12, 0x2b, + 0x0a, 0x11, 0x61, 0x64, 0x76, 0x65, 0x72, 0x74, 0x69, 0x73, 0x65, 0x64, 0x5f, 0x72, 0x6f, 0x75, + 0x74, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, 0x61, 0x64, 0x76, 0x65, 0x72, + 0x74, 0x69, 0x73, 0x65, 0x64, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x22, 0x43, 0x0a, 0x19, 0x45, + 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x65, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x6f, 0x75, 0x74, + 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x73, + 0x22, 0x70, 0x0a, 0x1a, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, + 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x25, + 0x0a, 0x0e, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x73, + 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x52, + 0x6f, 0x75, 0x74, 0x65, 0x73, 0x12, 0x2b, 0x0a, 0x11, 0x61, 0x64, 0x76, 0x65, 0x72, 0x74, 0x69, + 0x73, 0x65, 0x64, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, + 0x52, 0x10, 0x61, 0x64, 0x76, 0x65, 0x72, 0x74, 0x69, 0x73, 0x65, 0x64, 0x52, 0x6f, 0x75, 0x74, + 0x65, 0x73, 0x42, 0x29, 0x5a, 0x27, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, + 0x2f, 0x6a, 0x75, 0x61, 0x6e, 0x66, 0x6f, 0x6e, 0x74, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, + 0x61, 0x6c, 0x65, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x67, 0x6f, 0x2f, 0x76, 0x31, 0x62, 0x06, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_headscale_v1_device_proto_rawDescOnce sync.Once + file_headscale_v1_device_proto_rawDescData = file_headscale_v1_device_proto_rawDesc +) + +func file_headscale_v1_device_proto_rawDescGZIP() []byte { + file_headscale_v1_device_proto_rawDescOnce.Do(func() { + file_headscale_v1_device_proto_rawDescData = protoimpl.X.CompressGZIP(file_headscale_v1_device_proto_rawDescData) + }) + return file_headscale_v1_device_proto_rawDescData +} + +var file_headscale_v1_device_proto_msgTypes = make([]protoimpl.MessageInfo, 12) +var file_headscale_v1_device_proto_goTypes = []interface{}{ + (*Latency)(nil), // 0: headscale.v1.Latency + (*ClientSupports)(nil), // 1: headscale.v1.ClientSupports + (*ClientConnectivity)(nil), // 2: headscale.v1.ClientConnectivity + (*GetDeviceRequest)(nil), // 3: headscale.v1.GetDeviceRequest + (*GetDeviceResponse)(nil), // 4: headscale.v1.GetDeviceResponse + (*DeleteDeviceRequest)(nil), // 5: headscale.v1.DeleteDeviceRequest + (*DeleteDeviceResponse)(nil), // 6: headscale.v1.DeleteDeviceResponse + (*GetDeviceRoutesRequest)(nil), // 7: headscale.v1.GetDeviceRoutesRequest + (*GetDeviceRoutesResponse)(nil), // 8: headscale.v1.GetDeviceRoutesResponse + (*EnableDeviceRoutesRequest)(nil), // 9: headscale.v1.EnableDeviceRoutesRequest + (*EnableDeviceRoutesResponse)(nil), // 10: headscale.v1.EnableDeviceRoutesResponse + nil, // 11: headscale.v1.ClientConnectivity.LatencyEntry + (*timestamppb.Timestamp)(nil), // 12: google.protobuf.Timestamp +} +var file_headscale_v1_device_proto_depIdxs = []int32{ + 11, // 0: headscale.v1.ClientConnectivity.latency:type_name -> headscale.v1.ClientConnectivity.LatencyEntry + 1, // 1: headscale.v1.ClientConnectivity.client_supports:type_name -> headscale.v1.ClientSupports + 12, // 2: headscale.v1.GetDeviceResponse.created:type_name -> google.protobuf.Timestamp + 12, // 3: headscale.v1.GetDeviceResponse.last_seen:type_name -> google.protobuf.Timestamp + 12, // 4: headscale.v1.GetDeviceResponse.expires:type_name -> google.protobuf.Timestamp + 2, // 5: headscale.v1.GetDeviceResponse.client_connectivity:type_name -> headscale.v1.ClientConnectivity + 0, // 6: headscale.v1.ClientConnectivity.LatencyEntry.value:type_name -> headscale.v1.Latency + 7, // [7:7] is the sub-list for method output_type + 7, // [7:7] is the sub-list for method input_type + 7, // [7:7] is the sub-list for extension type_name + 7, // [7:7] is the sub-list for extension extendee + 0, // [0:7] is the sub-list for field type_name +} + +func init() { file_headscale_v1_device_proto_init() } +func file_headscale_v1_device_proto_init() { + if File_headscale_v1_device_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_headscale_v1_device_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Latency); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_headscale_v1_device_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ClientSupports); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_headscale_v1_device_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ClientConnectivity); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_headscale_v1_device_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetDeviceRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_headscale_v1_device_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetDeviceResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_headscale_v1_device_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DeleteDeviceRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_headscale_v1_device_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DeleteDeviceResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_headscale_v1_device_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetDeviceRoutesRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_headscale_v1_device_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetDeviceRoutesResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_headscale_v1_device_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*EnableDeviceRoutesRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_headscale_v1_device_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*EnableDeviceRoutesResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_headscale_v1_device_proto_rawDesc, + NumEnums: 0, + NumMessages: 12, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_headscale_v1_device_proto_goTypes, + DependencyIndexes: file_headscale_v1_device_proto_depIdxs, + MessageInfos: file_headscale_v1_device_proto_msgTypes, + }.Build() + File_headscale_v1_device_proto = out.File + file_headscale_v1_device_proto_rawDesc = nil + file_headscale_v1_device_proto_goTypes = nil + file_headscale_v1_device_proto_depIdxs = nil +} diff --git a/gen/go/headscale/v1/headscale.pb.go b/gen/go/headscale/v1/headscale.pb.go index e050e931..56911b6b 100644 --- a/gen/go/headscale/v1/headscale.pb.go +++ b/gen/go/headscale/v1/headscale.pb.go @@ -10,9 +10,7 @@ import ( _ "google.golang.org/genproto/googleapis/api/annotations" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" - timestamppb "google.golang.org/protobuf/types/known/timestamppb" reflect "reflect" - sync "sync" ) const ( @@ -22,664 +20,245 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) -type RegisterMethod int32 - -const ( - RegisterMethod_REGISTER_METHOD_UNSPECIFIED RegisterMethod = 0 - RegisterMethod_REGISTER_METHOD_AUTH_KEY RegisterMethod = 1 - RegisterMethod_REGISTER_METHOD_CLI RegisterMethod = 2 - RegisterMethod_REGISTER_METHOD_OIDC RegisterMethod = 3 -) - -// Enum value maps for RegisterMethod. -var ( - RegisterMethod_name = map[int32]string{ - 0: "REGISTER_METHOD_UNSPECIFIED", - 1: "REGISTER_METHOD_AUTH_KEY", - 2: "REGISTER_METHOD_CLI", - 3: "REGISTER_METHOD_OIDC", - } - RegisterMethod_value = map[string]int32{ - "REGISTER_METHOD_UNSPECIFIED": 0, - "REGISTER_METHOD_AUTH_KEY": 1, - "REGISTER_METHOD_CLI": 2, - "REGISTER_METHOD_OIDC": 3, - } -) - -func (x RegisterMethod) Enum() *RegisterMethod { - p := new(RegisterMethod) - *p = x - return p -} - -func (x RegisterMethod) String() string { - return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) -} - -func (RegisterMethod) Descriptor() protoreflect.EnumDescriptor { - return file_headscale_v1_headscale_proto_enumTypes[0].Descriptor() -} - -func (RegisterMethod) Type() protoreflect.EnumType { - return &file_headscale_v1_headscale_proto_enumTypes[0] -} - -func (x RegisterMethod) Number() protoreflect.EnumNumber { - return protoreflect.EnumNumber(x) -} - -// Deprecated: Use RegisterMethod.Descriptor instead. -func (RegisterMethod) EnumDescriptor() ([]byte, []int) { - return file_headscale_v1_headscale_proto_rawDescGZIP(), []int{0} -} - -type GetMachineRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - MachineId uint64 `protobuf:"varint,1,opt,name=machine_id,json=machineId,proto3" json:"machine_id,omitempty"` -} - -func (x *GetMachineRequest) Reset() { - *x = GetMachineRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_headscale_v1_headscale_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *GetMachineRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*GetMachineRequest) ProtoMessage() {} - -func (x *GetMachineRequest) ProtoReflect() protoreflect.Message { - mi := &file_headscale_v1_headscale_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use GetMachineRequest.ProtoReflect.Descriptor instead. -func (*GetMachineRequest) Descriptor() ([]byte, []int) { - return file_headscale_v1_headscale_proto_rawDescGZIP(), []int{0} -} - -func (x *GetMachineRequest) GetMachineId() uint64 { - if x != nil { - return x.MachineId - } - return 0 -} - -type GetMachineResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Id uint64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` - MachineKey string `protobuf:"bytes,2,opt,name=machine_key,json=machineKey,proto3" json:"machine_key,omitempty"` - NodeKey string `protobuf:"bytes,3,opt,name=node_key,json=nodeKey,proto3" json:"node_key,omitempty"` - DiscoKey string `protobuf:"bytes,4,opt,name=disco_key,json=discoKey,proto3" json:"disco_key,omitempty"` - IpAddress string `protobuf:"bytes,5,opt,name=ip_address,json=ipAddress,proto3" json:"ip_address,omitempty"` - Name string `protobuf:"bytes,6,opt,name=name,proto3" json:"name,omitempty"` - NamespaceId uint32 `protobuf:"varint,7,opt,name=namespace_id,json=namespaceId,proto3" json:"namespace_id,omitempty"` - Registered bool `protobuf:"varint,8,opt,name=registered,proto3" json:"registered,omitempty"` - RegisterMethod RegisterMethod `protobuf:"varint,9,opt,name=register_method,json=registerMethod,proto3,enum=headscale.v1.RegisterMethod" json:"register_method,omitempty"` - AuthKeyId uint32 `protobuf:"varint,10,opt,name=auth_key_id,json=authKeyId,proto3" json:"auth_key_id,omitempty"` // PreAuthKey auth_key = 11; - LastSeen *timestamppb.Timestamp `protobuf:"bytes,12,opt,name=last_seen,json=lastSeen,proto3" json:"last_seen,omitempty"` - LastSuccessfulUpdate *timestamppb.Timestamp `protobuf:"bytes,13,opt,name=last_successful_update,json=lastSuccessfulUpdate,proto3" json:"last_successful_update,omitempty"` - Expiry *timestamppb.Timestamp `protobuf:"bytes,14,opt,name=expiry,proto3" json:"expiry,omitempty"` -} - -func (x *GetMachineResponse) Reset() { - *x = GetMachineResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_headscale_v1_headscale_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *GetMachineResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*GetMachineResponse) ProtoMessage() {} - -func (x *GetMachineResponse) ProtoReflect() protoreflect.Message { - mi := &file_headscale_v1_headscale_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use GetMachineResponse.ProtoReflect.Descriptor instead. -func (*GetMachineResponse) Descriptor() ([]byte, []int) { - return file_headscale_v1_headscale_proto_rawDescGZIP(), []int{1} -} - -func (x *GetMachineResponse) GetId() uint64 { - if x != nil { - return x.Id - } - return 0 -} - -func (x *GetMachineResponse) GetMachineKey() string { - if x != nil { - return x.MachineKey - } - return "" -} - -func (x *GetMachineResponse) GetNodeKey() string { - if x != nil { - return x.NodeKey - } - return "" -} - -func (x *GetMachineResponse) GetDiscoKey() string { - if x != nil { - return x.DiscoKey - } - return "" -} - -func (x *GetMachineResponse) GetIpAddress() string { - if x != nil { - return x.IpAddress - } - return "" -} - -func (x *GetMachineResponse) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -func (x *GetMachineResponse) GetNamespaceId() uint32 { - if x != nil { - return x.NamespaceId - } - return 0 -} - -func (x *GetMachineResponse) GetRegistered() bool { - if x != nil { - return x.Registered - } - return false -} - -func (x *GetMachineResponse) GetRegisterMethod() RegisterMethod { - if x != nil { - return x.RegisterMethod - } - return RegisterMethod_REGISTER_METHOD_UNSPECIFIED -} - -func (x *GetMachineResponse) GetAuthKeyId() uint32 { - if x != nil { - return x.AuthKeyId - } - return 0 -} - -func (x *GetMachineResponse) GetLastSeen() *timestamppb.Timestamp { - if x != nil { - return x.LastSeen - } - return nil -} - -func (x *GetMachineResponse) GetLastSuccessfulUpdate() *timestamppb.Timestamp { - if x != nil { - return x.LastSuccessfulUpdate - } - return nil -} - -func (x *GetMachineResponse) GetExpiry() *timestamppb.Timestamp { - if x != nil { - return x.Expiry - } - return nil -} - -type CreateNamespaceRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` -} - -func (x *CreateNamespaceRequest) Reset() { - *x = CreateNamespaceRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_headscale_v1_headscale_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *CreateNamespaceRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*CreateNamespaceRequest) ProtoMessage() {} - -func (x *CreateNamespaceRequest) ProtoReflect() protoreflect.Message { - mi := &file_headscale_v1_headscale_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use CreateNamespaceRequest.ProtoReflect.Descriptor instead. -func (*CreateNamespaceRequest) Descriptor() ([]byte, []int) { - return file_headscale_v1_headscale_proto_rawDescGZIP(), []int{2} -} - -func (x *CreateNamespaceRequest) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -type CreateNamespaceResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` -} - -func (x *CreateNamespaceResponse) Reset() { - *x = CreateNamespaceResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_headscale_v1_headscale_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *CreateNamespaceResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*CreateNamespaceResponse) ProtoMessage() {} - -func (x *CreateNamespaceResponse) ProtoReflect() protoreflect.Message { - mi := &file_headscale_v1_headscale_proto_msgTypes[3] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use CreateNamespaceResponse.ProtoReflect.Descriptor instead. -func (*CreateNamespaceResponse) Descriptor() ([]byte, []int) { - return file_headscale_v1_headscale_proto_rawDescGZIP(), []int{3} -} - -func (x *CreateNamespaceResponse) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -type DeleteNamespaceRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` -} - -func (x *DeleteNamespaceRequest) Reset() { - *x = DeleteNamespaceRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_headscale_v1_headscale_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *DeleteNamespaceRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*DeleteNamespaceRequest) ProtoMessage() {} - -func (x *DeleteNamespaceRequest) ProtoReflect() protoreflect.Message { - mi := &file_headscale_v1_headscale_proto_msgTypes[4] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use DeleteNamespaceRequest.ProtoReflect.Descriptor instead. -func (*DeleteNamespaceRequest) Descriptor() ([]byte, []int) { - return file_headscale_v1_headscale_proto_rawDescGZIP(), []int{4} -} - -func (x *DeleteNamespaceRequest) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -type DeleteNamespaceResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields -} - -func (x *DeleteNamespaceResponse) Reset() { - *x = DeleteNamespaceResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_headscale_v1_headscale_proto_msgTypes[5] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *DeleteNamespaceResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*DeleteNamespaceResponse) ProtoMessage() {} - -func (x *DeleteNamespaceResponse) ProtoReflect() protoreflect.Message { - mi := &file_headscale_v1_headscale_proto_msgTypes[5] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use DeleteNamespaceResponse.ProtoReflect.Descriptor instead. -func (*DeleteNamespaceResponse) Descriptor() ([]byte, []int) { - return file_headscale_v1_headscale_proto_rawDescGZIP(), []int{5} -} - -type ListNamespacesRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields -} - -func (x *ListNamespacesRequest) Reset() { - *x = ListNamespacesRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_headscale_v1_headscale_proto_msgTypes[6] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ListNamespacesRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ListNamespacesRequest) ProtoMessage() {} - -func (x *ListNamespacesRequest) ProtoReflect() protoreflect.Message { - mi := &file_headscale_v1_headscale_proto_msgTypes[6] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ListNamespacesRequest.ProtoReflect.Descriptor instead. -func (*ListNamespacesRequest) Descriptor() ([]byte, []int) { - return file_headscale_v1_headscale_proto_rawDescGZIP(), []int{6} -} - -type ListNamespacesResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Namespaces []string `protobuf:"bytes,1,rep,name=namespaces,proto3" json:"namespaces,omitempty"` -} - -func (x *ListNamespacesResponse) Reset() { - *x = ListNamespacesResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_headscale_v1_headscale_proto_msgTypes[7] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ListNamespacesResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ListNamespacesResponse) ProtoMessage() {} - -func (x *ListNamespacesResponse) ProtoReflect() protoreflect.Message { - mi := &file_headscale_v1_headscale_proto_msgTypes[7] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ListNamespacesResponse.ProtoReflect.Descriptor instead. -func (*ListNamespacesResponse) Descriptor() ([]byte, []int) { - return file_headscale_v1_headscale_proto_rawDescGZIP(), []int{7} -} - -func (x *ListNamespacesResponse) GetNamespaces() []string { - if x != nil { - return x.Namespaces - } - return nil -} - var File_headscale_v1_headscale_proto protoreflect.FileDescriptor var file_headscale_v1_headscale_proto_rawDesc = []byte{ 0x0a, 0x1c, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0c, - 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x1a, 0x1f, 0x67, 0x6f, - 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, - 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x67, - 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x32, 0x0a, 0x11, 0x47, - 0x65, 0x74, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x12, 0x1d, 0x0a, 0x0a, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x49, 0x64, 0x22, - 0x99, 0x04, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x04, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, - 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6d, 0x61, 0x63, - 0x68, 0x69, 0x6e, 0x65, 0x4b, 0x65, 0x79, 0x12, 0x19, 0x0a, 0x08, 0x6e, 0x6f, 0x64, 0x65, 0x5f, - 0x6b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6e, 0x6f, 0x64, 0x65, 0x4b, - 0x65, 0x79, 0x12, 0x1b, 0x0a, 0x09, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x5f, 0x6b, 0x65, 0x79, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x4b, 0x65, 0x79, 0x12, - 0x1d, 0x0a, 0x0a, 0x69, 0x70, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x05, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x09, 0x69, 0x70, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x12, - 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, - 0x6d, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, - 0x69, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, - 0x61, 0x63, 0x65, 0x49, 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, - 0x72, 0x65, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x72, 0x65, 0x67, 0x69, 0x73, - 0x74, 0x65, 0x72, 0x65, 0x64, 0x12, 0x45, 0x0a, 0x0f, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, - 0x72, 0x5f, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1c, - 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, - 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x52, 0x0e, 0x72, 0x65, - 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, 0x1e, 0x0a, 0x0b, - 0x61, 0x75, 0x74, 0x68, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x0a, 0x20, 0x01, 0x28, - 0x0d, 0x52, 0x09, 0x61, 0x75, 0x74, 0x68, 0x4b, 0x65, 0x79, 0x49, 0x64, 0x12, 0x37, 0x0a, 0x09, - 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x65, 0x6e, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x08, 0x6c, 0x61, 0x73, - 0x74, 0x53, 0x65, 0x65, 0x6e, 0x12, 0x50, 0x0a, 0x16, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x73, 0x75, - 0x63, 0x63, 0x65, 0x73, 0x73, 0x66, 0x75, 0x6c, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x18, - 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, - 0x70, 0x52, 0x14, 0x6c, 0x61, 0x73, 0x74, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x66, 0x75, - 0x6c, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x32, 0x0a, 0x06, 0x65, 0x78, 0x70, 0x69, 0x72, - 0x79, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, - 0x61, 0x6d, 0x70, 0x52, 0x06, 0x65, 0x78, 0x70, 0x69, 0x72, 0x79, 0x22, 0x2c, 0x0a, 0x16, 0x43, + 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x1a, 0x1c, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x68, 0x65, 0x61, 0x64, + 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1d, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, + 0x61, 0x6c, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x72, 0x65, 0x61, 0x75, 0x74, 0x68, 0x6b, 0x65, + 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1a, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, + 0x6c, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x1a, 0x19, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2f, 0x76, + 0x31, 0x2f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x32, 0xec, + 0x11, 0x0a, 0x10, 0x48, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x53, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x12, 0x77, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, + 0x61, 0x63, 0x65, 0x12, 0x21, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, + 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, + 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x20, 0x82, 0xd3, 0xe4, 0x93, + 0x02, 0x1a, 0x12, 0x18, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x6e, 0x61, 0x6d, 0x65, + 0x73, 0x70, 0x61, 0x63, 0x65, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x12, 0x7c, 0x0a, 0x0f, + 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, + 0x24, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x2d, 0x0a, 0x17, 0x43, 0x72, 0x65, - 0x61, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x2c, 0x0a, 0x16, 0x44, 0x65, 0x6c, 0x65, - 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x19, 0x0a, 0x17, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, - 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x17, 0x0a, 0x15, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, - 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x38, 0x0a, 0x16, 0x4c, 0x69, - 0x73, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, - 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, - 0x61, 0x63, 0x65, 0x73, 0x2a, 0x82, 0x01, 0x0a, 0x0e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, - 0x72, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, 0x1f, 0x0a, 0x1b, 0x52, 0x45, 0x47, 0x49, 0x53, - 0x54, 0x45, 0x52, 0x5f, 0x4d, 0x45, 0x54, 0x48, 0x4f, 0x44, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, - 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1c, 0x0a, 0x18, 0x52, 0x45, 0x47, 0x49, - 0x53, 0x54, 0x45, 0x52, 0x5f, 0x4d, 0x45, 0x54, 0x48, 0x4f, 0x44, 0x5f, 0x41, 0x55, 0x54, 0x48, - 0x5f, 0x4b, 0x45, 0x59, 0x10, 0x01, 0x12, 0x17, 0x0a, 0x13, 0x52, 0x45, 0x47, 0x49, 0x53, 0x54, - 0x45, 0x52, 0x5f, 0x4d, 0x45, 0x54, 0x48, 0x4f, 0x44, 0x5f, 0x43, 0x4c, 0x49, 0x10, 0x02, 0x12, - 0x18, 0x0a, 0x14, 0x52, 0x45, 0x47, 0x49, 0x53, 0x54, 0x45, 0x52, 0x5f, 0x4d, 0x45, 0x54, 0x48, - 0x4f, 0x44, 0x5f, 0x4f, 0x49, 0x44, 0x43, 0x10, 0x03, 0x32, 0xfa, 0x03, 0x0a, 0x10, 0x48, 0x65, - 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x75, - 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x12, 0x1f, 0x2e, 0x68, - 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4d, - 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, - 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, - 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x24, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1e, 0x12, 0x1c, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, - 0x2f, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x2f, 0x7b, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, - 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x12, 0x7c, 0x0a, 0x0f, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4e, - 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x24, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, - 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4e, 0x61, - 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, - 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, - 0x65, 0x61, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1c, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x16, 0x22, 0x11, 0x2f, - 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, - 0x3a, 0x01, 0x2a, 0x12, 0x79, 0x0a, 0x0f, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4e, 0x61, 0x6d, - 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x24, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, - 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, - 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x68, - 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, - 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x19, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x13, 0x2a, 0x11, 0x2f, 0x61, 0x70, - 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x76, - 0x0a, 0x0e, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, + 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, + 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1c, 0x82, 0xd3, + 0xe4, 0x93, 0x02, 0x16, 0x22, 0x11, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x6e, 0x61, + 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x3a, 0x01, 0x2a, 0x12, 0x96, 0x01, 0x0a, 0x0f, 0x52, + 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x24, + 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, + 0x6e, 0x61, 0x6d, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, + 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, + 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x36, 0x82, 0xd3, 0xe4, + 0x93, 0x02, 0x30, 0x22, 0x2e, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x6e, 0x61, 0x6d, + 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x2f, 0x7b, 0x6f, 0x6c, 0x64, 0x5f, 0x6e, 0x61, 0x6d, 0x65, + 0x7d, 0x2f, 0x72, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x2f, 0x7b, 0x6e, 0x65, 0x77, 0x5f, 0x6e, 0x61, + 0x6d, 0x65, 0x7d, 0x12, 0x80, 0x01, 0x0a, 0x0f, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4e, 0x61, + 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x24, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, + 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4e, 0x61, 0x6d, + 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, + 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, + 0x65, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x20, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1a, 0x2a, 0x18, 0x2f, 0x61, + 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x2f, + 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x12, 0x76, 0x0a, 0x0e, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x61, + 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x12, 0x23, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, + 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x61, 0x6d, 0x65, + 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, + 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, + 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x19, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x13, 0x12, 0x11, 0x2f, 0x61, 0x70, + 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x80, + 0x01, 0x0a, 0x10, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x72, 0x65, 0x41, 0x75, 0x74, 0x68, + 0x4b, 0x65, 0x79, 0x12, 0x25, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, + 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x72, 0x65, 0x41, 0x75, 0x74, 0x68, + 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x68, 0x65, 0x61, + 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x50, 0x72, 0x65, 0x41, 0x75, 0x74, 0x68, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x1d, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x17, 0x22, 0x12, 0x2f, 0x61, 0x70, 0x69, + 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x72, 0x65, 0x61, 0x75, 0x74, 0x68, 0x6b, 0x65, 0x79, 0x3a, 0x01, + 0x2a, 0x12, 0x87, 0x01, 0x0a, 0x10, 0x45, 0x78, 0x70, 0x69, 0x72, 0x65, 0x50, 0x72, 0x65, 0x41, + 0x75, 0x74, 0x68, 0x4b, 0x65, 0x79, 0x12, 0x25, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, + 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x78, 0x70, 0x69, 0x72, 0x65, 0x50, 0x72, 0x65, 0x41, + 0x75, 0x74, 0x68, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, + 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x78, 0x70, + 0x69, 0x72, 0x65, 0x50, 0x72, 0x65, 0x41, 0x75, 0x74, 0x68, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x24, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1e, 0x22, 0x19, 0x2f, + 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x72, 0x65, 0x61, 0x75, 0x74, 0x68, 0x6b, 0x65, + 0x79, 0x2f, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x3a, 0x01, 0x2a, 0x12, 0x7a, 0x0a, 0x0f, 0x4c, + 0x69, 0x73, 0x74, 0x50, 0x72, 0x65, 0x41, 0x75, 0x74, 0x68, 0x4b, 0x65, 0x79, 0x73, 0x12, 0x24, + 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, + 0x73, 0x74, 0x50, 0x72, 0x65, 0x41, 0x75, 0x74, 0x68, 0x4b, 0x65, 0x79, 0x73, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, + 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x65, 0x41, 0x75, 0x74, 0x68, 0x4b, + 0x65, 0x79, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1a, 0x82, 0xd3, 0xe4, + 0x93, 0x02, 0x14, 0x12, 0x12, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x72, 0x65, + 0x61, 0x75, 0x74, 0x68, 0x6b, 0x65, 0x79, 0x12, 0x89, 0x01, 0x0a, 0x12, 0x44, 0x65, 0x62, 0x75, + 0x67, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x12, 0x27, + 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, + 0x62, 0x75, 0x67, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, + 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x62, 0x75, 0x67, 0x43, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x20, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1a, 0x22, 0x15, 0x2f, 0x61, 0x70, 0x69, 0x2f, + 0x76, 0x31, 0x2f, 0x64, 0x65, 0x62, 0x75, 0x67, 0x2f, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, + 0x3a, 0x01, 0x2a, 0x12, 0x75, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, + 0x65, 0x12, 0x1f, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, + 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, + 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x24, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1e, 0x12, 0x1c, 0x2f, 0x61, + 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x2f, 0x7b, 0x6d, + 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x12, 0x80, 0x01, 0x0a, 0x0f, 0x52, + 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x12, 0x24, + 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, + 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, + 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x4d, 0x61, 0x63, 0x68, + 0x69, 0x6e, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x20, 0x82, 0xd3, 0xe4, + 0x93, 0x02, 0x1a, 0x22, 0x18, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x6d, 0x61, 0x63, + 0x68, 0x69, 0x6e, 0x65, 0x2f, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x12, 0x7e, 0x0a, + 0x0d, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x12, 0x22, + 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, + 0x6c, 0x65, 0x74, 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, + 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x24, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1e, 0x2a, + 0x1c, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, + 0x2f, 0x7b, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x12, 0x6e, 0x0a, + 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x73, 0x12, 0x21, 0x2e, + 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, + 0x74, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x22, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, + 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x17, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x11, 0x12, 0x0f, 0x2f, 0x61, + 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x12, 0x8d, 0x01, + 0x0a, 0x0c, 0x53, 0x68, 0x61, 0x72, 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x12, 0x21, + 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x68, + 0x61, 0x72, 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x22, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, + 0x2e, 0x53, 0x68, 0x61, 0x72, 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x36, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x30, 0x22, 0x2e, 0x2f, + 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x2f, 0x7b, + 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x73, 0x68, 0x61, 0x72, + 0x65, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x7d, 0x12, 0x95, 0x01, + 0x0a, 0x0e, 0x55, 0x6e, 0x73, 0x68, 0x61, 0x72, 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x12, 0x23, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, - 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x52, 0x65, + 0x55, 0x6e, 0x73, 0x68, 0x61, 0x72, 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, - 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, - 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x19, 0x82, 0xd3, 0xe4, - 0x93, 0x02, 0x13, 0x12, 0x11, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x6e, 0x61, 0x6d, - 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x42, 0x29, 0x5a, 0x27, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, - 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6a, 0x75, 0x61, 0x6e, 0x66, 0x6f, 0x6e, 0x74, 0x2f, 0x68, 0x65, - 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x67, 0x6f, 0x2f, 0x76, - 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x6e, 0x73, 0x68, 0x61, 0x72, 0x65, 0x4d, 0x61, 0x63, 0x68, + 0x69, 0x6e, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x38, 0x82, 0xd3, 0xe4, + 0x93, 0x02, 0x32, 0x22, 0x30, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x6d, 0x61, 0x63, + 0x68, 0x69, 0x6e, 0x65, 0x2f, 0x7b, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x5f, 0x69, 0x64, + 0x7d, 0x2f, 0x75, 0x6e, 0x73, 0x68, 0x61, 0x72, 0x65, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x73, + 0x70, 0x61, 0x63, 0x65, 0x7d, 0x12, 0x8b, 0x01, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x4d, 0x61, 0x63, + 0x68, 0x69, 0x6e, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x12, 0x24, 0x2e, 0x68, 0x65, 0x61, 0x64, + 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x61, 0x63, 0x68, + 0x69, 0x6e, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x25, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, + 0x65, 0x74, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x25, 0x12, 0x23, + 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x2f, + 0x7b, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x72, 0x6f, 0x75, + 0x74, 0x65, 0x73, 0x12, 0x97, 0x01, 0x0a, 0x13, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x4d, 0x61, + 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x12, 0x28, 0x2e, 0x68, 0x65, + 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6e, 0x61, 0x62, 0x6c, + 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, + 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, + 0x6e, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x2b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x25, 0x22, 0x23, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, + 0x31, 0x2f, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x2f, 0x7b, 0x6d, 0x61, 0x63, 0x68, 0x69, + 0x6e, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x42, 0x29, 0x5a, + 0x27, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6a, 0x75, 0x61, 0x6e, + 0x66, 0x6f, 0x6e, 0x74, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2f, 0x67, + 0x65, 0x6e, 0x2f, 0x67, 0x6f, 0x2f, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } -var ( - file_headscale_v1_headscale_proto_rawDescOnce sync.Once - file_headscale_v1_headscale_proto_rawDescData = file_headscale_v1_headscale_proto_rawDesc -) - -func file_headscale_v1_headscale_proto_rawDescGZIP() []byte { - file_headscale_v1_headscale_proto_rawDescOnce.Do(func() { - file_headscale_v1_headscale_proto_rawDescData = protoimpl.X.CompressGZIP(file_headscale_v1_headscale_proto_rawDescData) - }) - return file_headscale_v1_headscale_proto_rawDescData -} - -var file_headscale_v1_headscale_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_headscale_v1_headscale_proto_msgTypes = make([]protoimpl.MessageInfo, 8) var file_headscale_v1_headscale_proto_goTypes = []interface{}{ - (RegisterMethod)(0), // 0: headscale.v1.RegisterMethod - (*GetMachineRequest)(nil), // 1: headscale.v1.GetMachineRequest - (*GetMachineResponse)(nil), // 2: headscale.v1.GetMachineResponse - (*CreateNamespaceRequest)(nil), // 3: headscale.v1.CreateNamespaceRequest - (*CreateNamespaceResponse)(nil), // 4: headscale.v1.CreateNamespaceResponse - (*DeleteNamespaceRequest)(nil), // 5: headscale.v1.DeleteNamespaceRequest - (*DeleteNamespaceResponse)(nil), // 6: headscale.v1.DeleteNamespaceResponse - (*ListNamespacesRequest)(nil), // 7: headscale.v1.ListNamespacesRequest - (*ListNamespacesResponse)(nil), // 8: headscale.v1.ListNamespacesResponse - (*timestamppb.Timestamp)(nil), // 9: google.protobuf.Timestamp + (*GetNamespaceRequest)(nil), // 0: headscale.v1.GetNamespaceRequest + (*CreateNamespaceRequest)(nil), // 1: headscale.v1.CreateNamespaceRequest + (*RenameNamespaceRequest)(nil), // 2: headscale.v1.RenameNamespaceRequest + (*DeleteNamespaceRequest)(nil), // 3: headscale.v1.DeleteNamespaceRequest + (*ListNamespacesRequest)(nil), // 4: headscale.v1.ListNamespacesRequest + (*CreatePreAuthKeyRequest)(nil), // 5: headscale.v1.CreatePreAuthKeyRequest + (*ExpirePreAuthKeyRequest)(nil), // 6: headscale.v1.ExpirePreAuthKeyRequest + (*ListPreAuthKeysRequest)(nil), // 7: headscale.v1.ListPreAuthKeysRequest + (*DebugCreateMachineRequest)(nil), // 8: headscale.v1.DebugCreateMachineRequest + (*GetMachineRequest)(nil), // 9: headscale.v1.GetMachineRequest + (*RegisterMachineRequest)(nil), // 10: headscale.v1.RegisterMachineRequest + (*DeleteMachineRequest)(nil), // 11: headscale.v1.DeleteMachineRequest + (*ListMachinesRequest)(nil), // 12: headscale.v1.ListMachinesRequest + (*ShareMachineRequest)(nil), // 13: headscale.v1.ShareMachineRequest + (*UnshareMachineRequest)(nil), // 14: headscale.v1.UnshareMachineRequest + (*GetMachineRouteRequest)(nil), // 15: headscale.v1.GetMachineRouteRequest + (*EnableMachineRoutesRequest)(nil), // 16: headscale.v1.EnableMachineRoutesRequest + (*GetNamespaceResponse)(nil), // 17: headscale.v1.GetNamespaceResponse + (*CreateNamespaceResponse)(nil), // 18: headscale.v1.CreateNamespaceResponse + (*RenameNamespaceResponse)(nil), // 19: headscale.v1.RenameNamespaceResponse + (*DeleteNamespaceResponse)(nil), // 20: headscale.v1.DeleteNamespaceResponse + (*ListNamespacesResponse)(nil), // 21: headscale.v1.ListNamespacesResponse + (*CreatePreAuthKeyResponse)(nil), // 22: headscale.v1.CreatePreAuthKeyResponse + (*ExpirePreAuthKeyResponse)(nil), // 23: headscale.v1.ExpirePreAuthKeyResponse + (*ListPreAuthKeysResponse)(nil), // 24: headscale.v1.ListPreAuthKeysResponse + (*DebugCreateMachineResponse)(nil), // 25: headscale.v1.DebugCreateMachineResponse + (*GetMachineResponse)(nil), // 26: headscale.v1.GetMachineResponse + (*RegisterMachineResponse)(nil), // 27: headscale.v1.RegisterMachineResponse + (*DeleteMachineResponse)(nil), // 28: headscale.v1.DeleteMachineResponse + (*ListMachinesResponse)(nil), // 29: headscale.v1.ListMachinesResponse + (*ShareMachineResponse)(nil), // 30: headscale.v1.ShareMachineResponse + (*UnshareMachineResponse)(nil), // 31: headscale.v1.UnshareMachineResponse + (*GetMachineRouteResponse)(nil), // 32: headscale.v1.GetMachineRouteResponse + (*EnableMachineRoutesResponse)(nil), // 33: headscale.v1.EnableMachineRoutesResponse } var file_headscale_v1_headscale_proto_depIdxs = []int32{ - 0, // 0: headscale.v1.GetMachineResponse.register_method:type_name -> headscale.v1.RegisterMethod - 9, // 1: headscale.v1.GetMachineResponse.last_seen:type_name -> google.protobuf.Timestamp - 9, // 2: headscale.v1.GetMachineResponse.last_successful_update:type_name -> google.protobuf.Timestamp - 9, // 3: headscale.v1.GetMachineResponse.expiry:type_name -> google.protobuf.Timestamp - 1, // 4: headscale.v1.HeadscaleService.GetMachine:input_type -> headscale.v1.GetMachineRequest - 3, // 5: headscale.v1.HeadscaleService.CreateNamespace:input_type -> headscale.v1.CreateNamespaceRequest - 5, // 6: headscale.v1.HeadscaleService.DeleteNamespace:input_type -> headscale.v1.DeleteNamespaceRequest - 7, // 7: headscale.v1.HeadscaleService.ListNamespaces:input_type -> headscale.v1.ListNamespacesRequest - 2, // 8: headscale.v1.HeadscaleService.GetMachine:output_type -> headscale.v1.GetMachineResponse - 4, // 9: headscale.v1.HeadscaleService.CreateNamespace:output_type -> headscale.v1.CreateNamespaceResponse - 6, // 10: headscale.v1.HeadscaleService.DeleteNamespace:output_type -> headscale.v1.DeleteNamespaceResponse - 8, // 11: headscale.v1.HeadscaleService.ListNamespaces:output_type -> headscale.v1.ListNamespacesResponse - 8, // [8:12] is the sub-list for method output_type - 4, // [4:8] is the sub-list for method input_type - 4, // [4:4] is the sub-list for extension type_name - 4, // [4:4] is the sub-list for extension extendee - 0, // [0:4] is the sub-list for field type_name + 0, // 0: headscale.v1.HeadscaleService.GetNamespace:input_type -> headscale.v1.GetNamespaceRequest + 1, // 1: headscale.v1.HeadscaleService.CreateNamespace:input_type -> headscale.v1.CreateNamespaceRequest + 2, // 2: headscale.v1.HeadscaleService.RenameNamespace:input_type -> headscale.v1.RenameNamespaceRequest + 3, // 3: headscale.v1.HeadscaleService.DeleteNamespace:input_type -> headscale.v1.DeleteNamespaceRequest + 4, // 4: headscale.v1.HeadscaleService.ListNamespaces:input_type -> headscale.v1.ListNamespacesRequest + 5, // 5: headscale.v1.HeadscaleService.CreatePreAuthKey:input_type -> headscale.v1.CreatePreAuthKeyRequest + 6, // 6: headscale.v1.HeadscaleService.ExpirePreAuthKey:input_type -> headscale.v1.ExpirePreAuthKeyRequest + 7, // 7: headscale.v1.HeadscaleService.ListPreAuthKeys:input_type -> headscale.v1.ListPreAuthKeysRequest + 8, // 8: headscale.v1.HeadscaleService.DebugCreateMachine:input_type -> headscale.v1.DebugCreateMachineRequest + 9, // 9: headscale.v1.HeadscaleService.GetMachine:input_type -> headscale.v1.GetMachineRequest + 10, // 10: headscale.v1.HeadscaleService.RegisterMachine:input_type -> headscale.v1.RegisterMachineRequest + 11, // 11: headscale.v1.HeadscaleService.DeleteMachine:input_type -> headscale.v1.DeleteMachineRequest + 12, // 12: headscale.v1.HeadscaleService.ListMachines:input_type -> headscale.v1.ListMachinesRequest + 13, // 13: headscale.v1.HeadscaleService.ShareMachine:input_type -> headscale.v1.ShareMachineRequest + 14, // 14: headscale.v1.HeadscaleService.UnshareMachine:input_type -> headscale.v1.UnshareMachineRequest + 15, // 15: headscale.v1.HeadscaleService.GetMachineRoute:input_type -> headscale.v1.GetMachineRouteRequest + 16, // 16: headscale.v1.HeadscaleService.EnableMachineRoutes:input_type -> headscale.v1.EnableMachineRoutesRequest + 17, // 17: headscale.v1.HeadscaleService.GetNamespace:output_type -> headscale.v1.GetNamespaceResponse + 18, // 18: headscale.v1.HeadscaleService.CreateNamespace:output_type -> headscale.v1.CreateNamespaceResponse + 19, // 19: headscale.v1.HeadscaleService.RenameNamespace:output_type -> headscale.v1.RenameNamespaceResponse + 20, // 20: headscale.v1.HeadscaleService.DeleteNamespace:output_type -> headscale.v1.DeleteNamespaceResponse + 21, // 21: headscale.v1.HeadscaleService.ListNamespaces:output_type -> headscale.v1.ListNamespacesResponse + 22, // 22: headscale.v1.HeadscaleService.CreatePreAuthKey:output_type -> headscale.v1.CreatePreAuthKeyResponse + 23, // 23: headscale.v1.HeadscaleService.ExpirePreAuthKey:output_type -> headscale.v1.ExpirePreAuthKeyResponse + 24, // 24: headscale.v1.HeadscaleService.ListPreAuthKeys:output_type -> headscale.v1.ListPreAuthKeysResponse + 25, // 25: headscale.v1.HeadscaleService.DebugCreateMachine:output_type -> headscale.v1.DebugCreateMachineResponse + 26, // 26: headscale.v1.HeadscaleService.GetMachine:output_type -> headscale.v1.GetMachineResponse + 27, // 27: headscale.v1.HeadscaleService.RegisterMachine:output_type -> headscale.v1.RegisterMachineResponse + 28, // 28: headscale.v1.HeadscaleService.DeleteMachine:output_type -> headscale.v1.DeleteMachineResponse + 29, // 29: headscale.v1.HeadscaleService.ListMachines:output_type -> headscale.v1.ListMachinesResponse + 30, // 30: headscale.v1.HeadscaleService.ShareMachine:output_type -> headscale.v1.ShareMachineResponse + 31, // 31: headscale.v1.HeadscaleService.UnshareMachine:output_type -> headscale.v1.UnshareMachineResponse + 32, // 32: headscale.v1.HeadscaleService.GetMachineRoute:output_type -> headscale.v1.GetMachineRouteResponse + 33, // 33: headscale.v1.HeadscaleService.EnableMachineRoutes:output_type -> headscale.v1.EnableMachineRoutesResponse + 17, // [17:34] is the sub-list for method output_type + 0, // [0:17] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name } func init() { file_headscale_v1_headscale_proto_init() } @@ -687,118 +266,22 @@ func file_headscale_v1_headscale_proto_init() { if File_headscale_v1_headscale_proto != nil { return } - if !protoimpl.UnsafeEnabled { - file_headscale_v1_headscale_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetMachineRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_headscale_v1_headscale_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetMachineResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_headscale_v1_headscale_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CreateNamespaceRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_headscale_v1_headscale_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CreateNamespaceResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_headscale_v1_headscale_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DeleteNamespaceRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_headscale_v1_headscale_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DeleteNamespaceResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_headscale_v1_headscale_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ListNamespacesRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_headscale_v1_headscale_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ListNamespacesResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } + file_headscale_v1_namespace_proto_init() + file_headscale_v1_preauthkey_proto_init() + file_headscale_v1_machine_proto_init() + file_headscale_v1_routes_proto_init() type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_headscale_v1_headscale_proto_rawDesc, - NumEnums: 1, - NumMessages: 8, + NumEnums: 0, + NumMessages: 0, NumExtensions: 0, NumServices: 1, }, GoTypes: file_headscale_v1_headscale_proto_goTypes, DependencyIndexes: file_headscale_v1_headscale_proto_depIdxs, - EnumInfos: file_headscale_v1_headscale_proto_enumTypes, - MessageInfos: file_headscale_v1_headscale_proto_msgTypes, }.Build() File_headscale_v1_headscale_proto = out.File file_headscale_v1_headscale_proto_rawDesc = nil diff --git a/gen/go/headscale/v1/headscale.pb.gw.go b/gen/go/headscale/v1/headscale.pb.gw.go index 226afe50..ba2d492f 100644 --- a/gen/go/headscale/v1/headscale.pb.gw.go +++ b/gen/go/headscale/v1/headscale.pb.gw.go @@ -31,6 +31,372 @@ var _ = runtime.String var _ = utilities.NewDoubleArray var _ = metadata.Join +func request_HeadscaleService_GetNamespace_0(ctx context.Context, marshaler runtime.Marshaler, client HeadscaleServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq GetNamespaceRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["name"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "name") + } + + protoReq.Name, err = runtime.String(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "name", err) + } + + msg, err := client.GetNamespace(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_HeadscaleService_GetNamespace_0(ctx context.Context, marshaler runtime.Marshaler, server HeadscaleServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq GetNamespaceRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["name"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "name") + } + + protoReq.Name, err = runtime.String(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "name", err) + } + + msg, err := server.GetNamespace(ctx, &protoReq) + return msg, metadata, err + +} + +func request_HeadscaleService_CreateNamespace_0(ctx context.Context, marshaler runtime.Marshaler, client HeadscaleServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq CreateNamespaceRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.CreateNamespace(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_HeadscaleService_CreateNamespace_0(ctx context.Context, marshaler runtime.Marshaler, server HeadscaleServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq CreateNamespaceRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.CreateNamespace(ctx, &protoReq) + return msg, metadata, err + +} + +func request_HeadscaleService_RenameNamespace_0(ctx context.Context, marshaler runtime.Marshaler, client HeadscaleServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq RenameNamespaceRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["old_name"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "old_name") + } + + protoReq.OldName, err = runtime.String(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "old_name", err) + } + + val, ok = pathParams["new_name"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "new_name") + } + + protoReq.NewName, err = runtime.String(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "new_name", err) + } + + msg, err := client.RenameNamespace(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_HeadscaleService_RenameNamespace_0(ctx context.Context, marshaler runtime.Marshaler, server HeadscaleServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq RenameNamespaceRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["old_name"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "old_name") + } + + protoReq.OldName, err = runtime.String(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "old_name", err) + } + + val, ok = pathParams["new_name"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "new_name") + } + + protoReq.NewName, err = runtime.String(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "new_name", err) + } + + msg, err := server.RenameNamespace(ctx, &protoReq) + return msg, metadata, err + +} + +func request_HeadscaleService_DeleteNamespace_0(ctx context.Context, marshaler runtime.Marshaler, client HeadscaleServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq DeleteNamespaceRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["name"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "name") + } + + protoReq.Name, err = runtime.String(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "name", err) + } + + msg, err := client.DeleteNamespace(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_HeadscaleService_DeleteNamespace_0(ctx context.Context, marshaler runtime.Marshaler, server HeadscaleServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq DeleteNamespaceRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["name"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "name") + } + + protoReq.Name, err = runtime.String(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "name", err) + } + + msg, err := server.DeleteNamespace(ctx, &protoReq) + return msg, metadata, err + +} + +func request_HeadscaleService_ListNamespaces_0(ctx context.Context, marshaler runtime.Marshaler, client HeadscaleServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq ListNamespacesRequest + var metadata runtime.ServerMetadata + + msg, err := client.ListNamespaces(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_HeadscaleService_ListNamespaces_0(ctx context.Context, marshaler runtime.Marshaler, server HeadscaleServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq ListNamespacesRequest + var metadata runtime.ServerMetadata + + msg, err := server.ListNamespaces(ctx, &protoReq) + return msg, metadata, err + +} + +func request_HeadscaleService_CreatePreAuthKey_0(ctx context.Context, marshaler runtime.Marshaler, client HeadscaleServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq CreatePreAuthKeyRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.CreatePreAuthKey(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_HeadscaleService_CreatePreAuthKey_0(ctx context.Context, marshaler runtime.Marshaler, server HeadscaleServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq CreatePreAuthKeyRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.CreatePreAuthKey(ctx, &protoReq) + return msg, metadata, err + +} + +func request_HeadscaleService_ExpirePreAuthKey_0(ctx context.Context, marshaler runtime.Marshaler, client HeadscaleServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq ExpirePreAuthKeyRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.ExpirePreAuthKey(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_HeadscaleService_ExpirePreAuthKey_0(ctx context.Context, marshaler runtime.Marshaler, server HeadscaleServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq ExpirePreAuthKeyRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.ExpirePreAuthKey(ctx, &protoReq) + return msg, metadata, err + +} + +var ( + filter_HeadscaleService_ListPreAuthKeys_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)} +) + +func request_HeadscaleService_ListPreAuthKeys_0(ctx context.Context, marshaler runtime.Marshaler, client HeadscaleServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq ListPreAuthKeysRequest + var metadata runtime.ServerMetadata + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_HeadscaleService_ListPreAuthKeys_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.ListPreAuthKeys(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_HeadscaleService_ListPreAuthKeys_0(ctx context.Context, marshaler runtime.Marshaler, server HeadscaleServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq ListPreAuthKeysRequest + var metadata runtime.ServerMetadata + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_HeadscaleService_ListPreAuthKeys_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.ListPreAuthKeys(ctx, &protoReq) + return msg, metadata, err + +} + +func request_HeadscaleService_DebugCreateMachine_0(ctx context.Context, marshaler runtime.Marshaler, client HeadscaleServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq DebugCreateMachineRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.DebugCreateMachine(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_HeadscaleService_DebugCreateMachine_0(ctx context.Context, marshaler runtime.Marshaler, server HeadscaleServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq DebugCreateMachineRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.DebugCreateMachine(ctx, &protoReq) + return msg, metadata, err + +} + func request_HeadscaleService_GetMachine_0(ctx context.Context, marshaler runtime.Marshaler, client HeadscaleServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { var protoReq GetMachineRequest var metadata runtime.ServerMetadata @@ -83,90 +449,392 @@ func local_request_HeadscaleService_GetMachine_0(ctx context.Context, marshaler } -func request_HeadscaleService_CreateNamespace_0(ctx context.Context, marshaler runtime.Marshaler, client HeadscaleServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq CreateNamespaceRequest +var ( + filter_HeadscaleService_RegisterMachine_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)} +) + +func request_HeadscaleService_RegisterMachine_0(ctx context.Context, marshaler runtime.Marshaler, client HeadscaleServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq RegisterMachineRequest var metadata runtime.ServerMetadata - newReader, berr := utilities.IOReaderFactory(req.Body) - if berr != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } - if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_HeadscaleService_RegisterMachine_0); err != nil { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } - msg, err := client.CreateNamespace(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + msg, err := client.RegisterMachine(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) return msg, metadata, err } -func local_request_HeadscaleService_CreateNamespace_0(ctx context.Context, marshaler runtime.Marshaler, server HeadscaleServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq CreateNamespaceRequest +func local_request_HeadscaleService_RegisterMachine_0(ctx context.Context, marshaler runtime.Marshaler, server HeadscaleServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq RegisterMachineRequest var metadata runtime.ServerMetadata - newReader, berr := utilities.IOReaderFactory(req.Body) - if berr != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } - if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_HeadscaleService_RegisterMachine_0); err != nil { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } - msg, err := server.CreateNamespace(ctx, &protoReq) + msg, err := server.RegisterMachine(ctx, &protoReq) + return msg, metadata, err + +} + +func request_HeadscaleService_DeleteMachine_0(ctx context.Context, marshaler runtime.Marshaler, client HeadscaleServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq DeleteMachineRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["machine_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "machine_id") + } + + protoReq.MachineId, err = runtime.Uint64(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "machine_id", err) + } + + msg, err := client.DeleteMachine(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_HeadscaleService_DeleteMachine_0(ctx context.Context, marshaler runtime.Marshaler, server HeadscaleServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq DeleteMachineRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["machine_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "machine_id") + } + + protoReq.MachineId, err = runtime.Uint64(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "machine_id", err) + } + + msg, err := server.DeleteMachine(ctx, &protoReq) return msg, metadata, err } var ( - filter_HeadscaleService_DeleteNamespace_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)} + filter_HeadscaleService_ListMachines_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)} ) -func request_HeadscaleService_DeleteNamespace_0(ctx context.Context, marshaler runtime.Marshaler, client HeadscaleServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq DeleteNamespaceRequest +func request_HeadscaleService_ListMachines_0(ctx context.Context, marshaler runtime.Marshaler, client HeadscaleServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq ListMachinesRequest var metadata runtime.ServerMetadata if err := req.ParseForm(); err != nil { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } - if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_HeadscaleService_DeleteNamespace_0); err != nil { + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_HeadscaleService_ListMachines_0); err != nil { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } - msg, err := client.DeleteNamespace(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + msg, err := client.ListMachines(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) return msg, metadata, err } -func local_request_HeadscaleService_DeleteNamespace_0(ctx context.Context, marshaler runtime.Marshaler, server HeadscaleServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq DeleteNamespaceRequest +func local_request_HeadscaleService_ListMachines_0(ctx context.Context, marshaler runtime.Marshaler, server HeadscaleServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq ListMachinesRequest var metadata runtime.ServerMetadata if err := req.ParseForm(); err != nil { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } - if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_HeadscaleService_DeleteNamespace_0); err != nil { + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_HeadscaleService_ListMachines_0); err != nil { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } - msg, err := server.DeleteNamespace(ctx, &protoReq) + msg, err := server.ListMachines(ctx, &protoReq) return msg, metadata, err } -func request_HeadscaleService_ListNamespaces_0(ctx context.Context, marshaler runtime.Marshaler, client HeadscaleServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq ListNamespacesRequest +func request_HeadscaleService_ShareMachine_0(ctx context.Context, marshaler runtime.Marshaler, client HeadscaleServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq ShareMachineRequest var metadata runtime.ServerMetadata - msg, err := client.ListNamespaces(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["machine_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "machine_id") + } + + protoReq.MachineId, err = runtime.Uint64(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "machine_id", err) + } + + val, ok = pathParams["namespace"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "namespace") + } + + protoReq.Namespace, err = runtime.String(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "namespace", err) + } + + msg, err := client.ShareMachine(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) return msg, metadata, err } -func local_request_HeadscaleService_ListNamespaces_0(ctx context.Context, marshaler runtime.Marshaler, server HeadscaleServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq ListNamespacesRequest +func local_request_HeadscaleService_ShareMachine_0(ctx context.Context, marshaler runtime.Marshaler, server HeadscaleServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq ShareMachineRequest var metadata runtime.ServerMetadata - msg, err := server.ListNamespaces(ctx, &protoReq) + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["machine_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "machine_id") + } + + protoReq.MachineId, err = runtime.Uint64(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "machine_id", err) + } + + val, ok = pathParams["namespace"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "namespace") + } + + protoReq.Namespace, err = runtime.String(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "namespace", err) + } + + msg, err := server.ShareMachine(ctx, &protoReq) + return msg, metadata, err + +} + +func request_HeadscaleService_UnshareMachine_0(ctx context.Context, marshaler runtime.Marshaler, client HeadscaleServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq UnshareMachineRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["machine_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "machine_id") + } + + protoReq.MachineId, err = runtime.Uint64(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "machine_id", err) + } + + val, ok = pathParams["namespace"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "namespace") + } + + protoReq.Namespace, err = runtime.String(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "namespace", err) + } + + msg, err := client.UnshareMachine(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_HeadscaleService_UnshareMachine_0(ctx context.Context, marshaler runtime.Marshaler, server HeadscaleServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq UnshareMachineRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["machine_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "machine_id") + } + + protoReq.MachineId, err = runtime.Uint64(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "machine_id", err) + } + + val, ok = pathParams["namespace"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "namespace") + } + + protoReq.Namespace, err = runtime.String(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "namespace", err) + } + + msg, err := server.UnshareMachine(ctx, &protoReq) + return msg, metadata, err + +} + +func request_HeadscaleService_GetMachineRoute_0(ctx context.Context, marshaler runtime.Marshaler, client HeadscaleServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq GetMachineRouteRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["machine_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "machine_id") + } + + protoReq.MachineId, err = runtime.Uint64(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "machine_id", err) + } + + msg, err := client.GetMachineRoute(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_HeadscaleService_GetMachineRoute_0(ctx context.Context, marshaler runtime.Marshaler, server HeadscaleServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq GetMachineRouteRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["machine_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "machine_id") + } + + protoReq.MachineId, err = runtime.Uint64(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "machine_id", err) + } + + msg, err := server.GetMachineRoute(ctx, &protoReq) + return msg, metadata, err + +} + +var ( + filter_HeadscaleService_EnableMachineRoutes_0 = &utilities.DoubleArray{Encoding: map[string]int{"machine_id": 0}, Base: []int{1, 1, 0}, Check: []int{0, 1, 2}} +) + +func request_HeadscaleService_EnableMachineRoutes_0(ctx context.Context, marshaler runtime.Marshaler, client HeadscaleServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq EnableMachineRoutesRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["machine_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "machine_id") + } + + protoReq.MachineId, err = runtime.Uint64(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "machine_id", err) + } + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_HeadscaleService_EnableMachineRoutes_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.EnableMachineRoutes(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_HeadscaleService_EnableMachineRoutes_0(ctx context.Context, marshaler runtime.Marshaler, server HeadscaleServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq EnableMachineRoutesRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["machine_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "machine_id") + } + + protoReq.MachineId, err = runtime.Uint64(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "machine_id", err) + } + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_HeadscaleService_EnableMachineRoutes_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.EnableMachineRoutes(ctx, &protoReq) return msg, metadata, err } @@ -177,18 +845,18 @@ func local_request_HeadscaleService_ListNamespaces_0(ctx context.Context, marsha // Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterHeadscaleServiceHandlerFromEndpoint instead. func RegisterHeadscaleServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux, server HeadscaleServiceServer) error { - mux.Handle("GET", pattern_HeadscaleService_GetMachine_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + mux.Handle("GET", pattern_HeadscaleService_GetNamespace_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() var stream runtime.ServerTransportStream ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/headscale.v1.HeadscaleService/GetMachine", runtime.WithHTTPPathPattern("/api/v1/machine/{machine_id}")) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/headscale.v1.HeadscaleService/GetNamespace", runtime.WithHTTPPathPattern("/api/v1/namespace/{name}")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := local_request_HeadscaleService_GetMachine_0(rctx, inboundMarshaler, server, req, pathParams) + resp, md, err := local_request_HeadscaleService_GetNamespace_0(rctx, inboundMarshaler, server, req, pathParams) md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) ctx = runtime.NewServerMetadataContext(ctx, md) if err != nil { @@ -196,7 +864,7 @@ func RegisterHeadscaleServiceHandlerServer(ctx context.Context, mux *runtime.Ser return } - forward_HeadscaleService_GetMachine_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_HeadscaleService_GetNamespace_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -223,13 +891,36 @@ func RegisterHeadscaleServiceHandlerServer(ctx context.Context, mux *runtime.Ser }) + mux.Handle("POST", pattern_HeadscaleService_RenameNamespace_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/headscale.v1.HeadscaleService/RenameNamespace", runtime.WithHTTPPathPattern("/api/v1/namespace/{old_name}/rename/{new_name}")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_HeadscaleService_RenameNamespace_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_HeadscaleService_RenameNamespace_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + mux.Handle("DELETE", pattern_HeadscaleService_DeleteNamespace_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() var stream runtime.ServerTransportStream ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/headscale.v1.HeadscaleService/DeleteNamespace", runtime.WithHTTPPathPattern("/api/v1/namespace")) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/headscale.v1.HeadscaleService/DeleteNamespace", runtime.WithHTTPPathPattern("/api/v1/namespace/{name}")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -269,6 +960,282 @@ func RegisterHeadscaleServiceHandlerServer(ctx context.Context, mux *runtime.Ser }) + mux.Handle("POST", pattern_HeadscaleService_CreatePreAuthKey_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/headscale.v1.HeadscaleService/CreatePreAuthKey", runtime.WithHTTPPathPattern("/api/v1/preauthkey")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_HeadscaleService_CreatePreAuthKey_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_HeadscaleService_CreatePreAuthKey_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_HeadscaleService_ExpirePreAuthKey_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/headscale.v1.HeadscaleService/ExpirePreAuthKey", runtime.WithHTTPPathPattern("/api/v1/preauthkey/expire")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_HeadscaleService_ExpirePreAuthKey_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_HeadscaleService_ExpirePreAuthKey_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_HeadscaleService_ListPreAuthKeys_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/headscale.v1.HeadscaleService/ListPreAuthKeys", runtime.WithHTTPPathPattern("/api/v1/preauthkey")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_HeadscaleService_ListPreAuthKeys_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_HeadscaleService_ListPreAuthKeys_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_HeadscaleService_DebugCreateMachine_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/headscale.v1.HeadscaleService/DebugCreateMachine", runtime.WithHTTPPathPattern("/api/v1/debug/machine")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_HeadscaleService_DebugCreateMachine_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_HeadscaleService_DebugCreateMachine_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_HeadscaleService_GetMachine_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/headscale.v1.HeadscaleService/GetMachine", runtime.WithHTTPPathPattern("/api/v1/machine/{machine_id}")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_HeadscaleService_GetMachine_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_HeadscaleService_GetMachine_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_HeadscaleService_RegisterMachine_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/headscale.v1.HeadscaleService/RegisterMachine", runtime.WithHTTPPathPattern("/api/v1/machine/register")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_HeadscaleService_RegisterMachine_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_HeadscaleService_RegisterMachine_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("DELETE", pattern_HeadscaleService_DeleteMachine_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/headscale.v1.HeadscaleService/DeleteMachine", runtime.WithHTTPPathPattern("/api/v1/machine/{machine_id}")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_HeadscaleService_DeleteMachine_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_HeadscaleService_DeleteMachine_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_HeadscaleService_ListMachines_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/headscale.v1.HeadscaleService/ListMachines", runtime.WithHTTPPathPattern("/api/v1/machine")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_HeadscaleService_ListMachines_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_HeadscaleService_ListMachines_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_HeadscaleService_ShareMachine_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/headscale.v1.HeadscaleService/ShareMachine", runtime.WithHTTPPathPattern("/api/v1/machine/{machine_id}/share/{namespace}")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_HeadscaleService_ShareMachine_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_HeadscaleService_ShareMachine_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_HeadscaleService_UnshareMachine_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/headscale.v1.HeadscaleService/UnshareMachine", runtime.WithHTTPPathPattern("/api/v1/machine/{machine_id}/unshare/{namespace}")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_HeadscaleService_UnshareMachine_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_HeadscaleService_UnshareMachine_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_HeadscaleService_GetMachineRoute_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/headscale.v1.HeadscaleService/GetMachineRoute", runtime.WithHTTPPathPattern("/api/v1/machine/{machine_id}/routes")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_HeadscaleService_GetMachineRoute_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_HeadscaleService_GetMachineRoute_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_HeadscaleService_EnableMachineRoutes_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/headscale.v1.HeadscaleService/EnableMachineRoutes", runtime.WithHTTPPathPattern("/api/v1/machine/{machine_id}/routes")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_HeadscaleService_EnableMachineRoutes_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_HeadscaleService_EnableMachineRoutes_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + return nil } @@ -310,23 +1277,23 @@ func RegisterHeadscaleServiceHandler(ctx context.Context, mux *runtime.ServeMux, // "HeadscaleServiceClient" to call the correct interceptors. func RegisterHeadscaleServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, client HeadscaleServiceClient) error { - mux.Handle("GET", pattern_HeadscaleService_GetMachine_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + mux.Handle("GET", pattern_HeadscaleService_GetNamespace_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateContext(ctx, mux, req, "/headscale.v1.HeadscaleService/GetMachine", runtime.WithHTTPPathPattern("/api/v1/machine/{machine_id}")) + rctx, err := runtime.AnnotateContext(ctx, mux, req, "/headscale.v1.HeadscaleService/GetNamespace", runtime.WithHTTPPathPattern("/api/v1/namespace/{name}")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := request_HeadscaleService_GetMachine_0(rctx, inboundMarshaler, client, req, pathParams) + resp, md, err := request_HeadscaleService_GetNamespace_0(rctx, inboundMarshaler, client, req, pathParams) ctx = runtime.NewServerMetadataContext(ctx, md) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - forward_HeadscaleService_GetMachine_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_HeadscaleService_GetNamespace_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -350,11 +1317,31 @@ func RegisterHeadscaleServiceHandlerClient(ctx context.Context, mux *runtime.Ser }) + mux.Handle("POST", pattern_HeadscaleService_RenameNamespace_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req, "/headscale.v1.HeadscaleService/RenameNamespace", runtime.WithHTTPPathPattern("/api/v1/namespace/{old_name}/rename/{new_name}")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_HeadscaleService_RenameNamespace_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_HeadscaleService_RenameNamespace_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + mux.Handle("DELETE", pattern_HeadscaleService_DeleteNamespace_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateContext(ctx, mux, req, "/headscale.v1.HeadscaleService/DeleteNamespace", runtime.WithHTTPPathPattern("/api/v1/namespace")) + rctx, err := runtime.AnnotateContext(ctx, mux, req, "/headscale.v1.HeadscaleService/DeleteNamespace", runtime.WithHTTPPathPattern("/api/v1/namespace/{name}")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -390,25 +1377,317 @@ func RegisterHeadscaleServiceHandlerClient(ctx context.Context, mux *runtime.Ser }) + mux.Handle("POST", pattern_HeadscaleService_CreatePreAuthKey_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req, "/headscale.v1.HeadscaleService/CreatePreAuthKey", runtime.WithHTTPPathPattern("/api/v1/preauthkey")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_HeadscaleService_CreatePreAuthKey_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_HeadscaleService_CreatePreAuthKey_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_HeadscaleService_ExpirePreAuthKey_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req, "/headscale.v1.HeadscaleService/ExpirePreAuthKey", runtime.WithHTTPPathPattern("/api/v1/preauthkey/expire")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_HeadscaleService_ExpirePreAuthKey_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_HeadscaleService_ExpirePreAuthKey_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_HeadscaleService_ListPreAuthKeys_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req, "/headscale.v1.HeadscaleService/ListPreAuthKeys", runtime.WithHTTPPathPattern("/api/v1/preauthkey")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_HeadscaleService_ListPreAuthKeys_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_HeadscaleService_ListPreAuthKeys_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_HeadscaleService_DebugCreateMachine_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req, "/headscale.v1.HeadscaleService/DebugCreateMachine", runtime.WithHTTPPathPattern("/api/v1/debug/machine")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_HeadscaleService_DebugCreateMachine_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_HeadscaleService_DebugCreateMachine_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_HeadscaleService_GetMachine_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req, "/headscale.v1.HeadscaleService/GetMachine", runtime.WithHTTPPathPattern("/api/v1/machine/{machine_id}")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_HeadscaleService_GetMachine_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_HeadscaleService_GetMachine_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_HeadscaleService_RegisterMachine_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req, "/headscale.v1.HeadscaleService/RegisterMachine", runtime.WithHTTPPathPattern("/api/v1/machine/register")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_HeadscaleService_RegisterMachine_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_HeadscaleService_RegisterMachine_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("DELETE", pattern_HeadscaleService_DeleteMachine_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req, "/headscale.v1.HeadscaleService/DeleteMachine", runtime.WithHTTPPathPattern("/api/v1/machine/{machine_id}")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_HeadscaleService_DeleteMachine_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_HeadscaleService_DeleteMachine_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_HeadscaleService_ListMachines_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req, "/headscale.v1.HeadscaleService/ListMachines", runtime.WithHTTPPathPattern("/api/v1/machine")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_HeadscaleService_ListMachines_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_HeadscaleService_ListMachines_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_HeadscaleService_ShareMachine_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req, "/headscale.v1.HeadscaleService/ShareMachine", runtime.WithHTTPPathPattern("/api/v1/machine/{machine_id}/share/{namespace}")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_HeadscaleService_ShareMachine_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_HeadscaleService_ShareMachine_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_HeadscaleService_UnshareMachine_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req, "/headscale.v1.HeadscaleService/UnshareMachine", runtime.WithHTTPPathPattern("/api/v1/machine/{machine_id}/unshare/{namespace}")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_HeadscaleService_UnshareMachine_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_HeadscaleService_UnshareMachine_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_HeadscaleService_GetMachineRoute_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req, "/headscale.v1.HeadscaleService/GetMachineRoute", runtime.WithHTTPPathPattern("/api/v1/machine/{machine_id}/routes")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_HeadscaleService_GetMachineRoute_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_HeadscaleService_GetMachineRoute_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_HeadscaleService_EnableMachineRoutes_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req, "/headscale.v1.HeadscaleService/EnableMachineRoutes", runtime.WithHTTPPathPattern("/api/v1/machine/{machine_id}/routes")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_HeadscaleService_EnableMachineRoutes_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_HeadscaleService_EnableMachineRoutes_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + return nil } var ( - pattern_HeadscaleService_GetMachine_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"api", "v1", "machine", "machine_id"}, "")) + pattern_HeadscaleService_GetNamespace_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"api", "v1", "namespace", "name"}, "")) pattern_HeadscaleService_CreateNamespace_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "v1", "namespace"}, "")) - pattern_HeadscaleService_DeleteNamespace_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "v1", "namespace"}, "")) + pattern_HeadscaleService_RenameNamespace_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3, 2, 4, 1, 0, 4, 1, 5, 5}, []string{"api", "v1", "namespace", "old_name", "rename", "new_name"}, "")) + + pattern_HeadscaleService_DeleteNamespace_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"api", "v1", "namespace", "name"}, "")) pattern_HeadscaleService_ListNamespaces_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "v1", "namespace"}, "")) + + pattern_HeadscaleService_CreatePreAuthKey_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "v1", "preauthkey"}, "")) + + pattern_HeadscaleService_ExpirePreAuthKey_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"api", "v1", "preauthkey", "expire"}, "")) + + pattern_HeadscaleService_ListPreAuthKeys_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "v1", "preauthkey"}, "")) + + pattern_HeadscaleService_DebugCreateMachine_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"api", "v1", "debug", "machine"}, "")) + + pattern_HeadscaleService_GetMachine_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"api", "v1", "machine", "machine_id"}, "")) + + pattern_HeadscaleService_RegisterMachine_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"api", "v1", "machine", "register"}, "")) + + pattern_HeadscaleService_DeleteMachine_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"api", "v1", "machine", "machine_id"}, "")) + + pattern_HeadscaleService_ListMachines_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "v1", "machine"}, "")) + + pattern_HeadscaleService_ShareMachine_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3, 2, 4, 1, 0, 4, 1, 5, 5}, []string{"api", "v1", "machine", "machine_id", "share", "namespace"}, "")) + + pattern_HeadscaleService_UnshareMachine_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3, 2, 4, 1, 0, 4, 1, 5, 5}, []string{"api", "v1", "machine", "machine_id", "unshare", "namespace"}, "")) + + pattern_HeadscaleService_GetMachineRoute_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3, 2, 4}, []string{"api", "v1", "machine", "machine_id", "routes"}, "")) + + pattern_HeadscaleService_EnableMachineRoutes_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3, 2, 4}, []string{"api", "v1", "machine", "machine_id", "routes"}, "")) ) var ( - forward_HeadscaleService_GetMachine_0 = runtime.ForwardResponseMessage + forward_HeadscaleService_GetNamespace_0 = runtime.ForwardResponseMessage forward_HeadscaleService_CreateNamespace_0 = runtime.ForwardResponseMessage + forward_HeadscaleService_RenameNamespace_0 = runtime.ForwardResponseMessage + forward_HeadscaleService_DeleteNamespace_0 = runtime.ForwardResponseMessage forward_HeadscaleService_ListNamespaces_0 = runtime.ForwardResponseMessage + + forward_HeadscaleService_CreatePreAuthKey_0 = runtime.ForwardResponseMessage + + forward_HeadscaleService_ExpirePreAuthKey_0 = runtime.ForwardResponseMessage + + forward_HeadscaleService_ListPreAuthKeys_0 = runtime.ForwardResponseMessage + + forward_HeadscaleService_DebugCreateMachine_0 = runtime.ForwardResponseMessage + + forward_HeadscaleService_GetMachine_0 = runtime.ForwardResponseMessage + + forward_HeadscaleService_RegisterMachine_0 = runtime.ForwardResponseMessage + + forward_HeadscaleService_DeleteMachine_0 = runtime.ForwardResponseMessage + + forward_HeadscaleService_ListMachines_0 = runtime.ForwardResponseMessage + + forward_HeadscaleService_ShareMachine_0 = runtime.ForwardResponseMessage + + forward_HeadscaleService_UnshareMachine_0 = runtime.ForwardResponseMessage + + forward_HeadscaleService_GetMachineRoute_0 = runtime.ForwardResponseMessage + + forward_HeadscaleService_EnableMachineRoutes_0 = runtime.ForwardResponseMessage ) diff --git a/gen/go/headscale/v1/headscale_grpc.pb.go b/gen/go/headscale/v1/headscale_grpc.pb.go index a613e8e9..06a98b49 100644 --- a/gen/go/headscale/v1/headscale_grpc.pb.go +++ b/gen/go/headscale/v1/headscale_grpc.pb.go @@ -18,10 +18,27 @@ const _ = grpc.SupportPackageIsVersion7 // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. type HeadscaleServiceClient interface { - GetMachine(ctx context.Context, in *GetMachineRequest, opts ...grpc.CallOption) (*GetMachineResponse, error) + // --- Namespace start --- + GetNamespace(ctx context.Context, in *GetNamespaceRequest, opts ...grpc.CallOption) (*GetNamespaceResponse, error) CreateNamespace(ctx context.Context, in *CreateNamespaceRequest, opts ...grpc.CallOption) (*CreateNamespaceResponse, error) + RenameNamespace(ctx context.Context, in *RenameNamespaceRequest, opts ...grpc.CallOption) (*RenameNamespaceResponse, error) DeleteNamespace(ctx context.Context, in *DeleteNamespaceRequest, opts ...grpc.CallOption) (*DeleteNamespaceResponse, error) ListNamespaces(ctx context.Context, in *ListNamespacesRequest, opts ...grpc.CallOption) (*ListNamespacesResponse, error) + // --- PreAuthKeys start --- + CreatePreAuthKey(ctx context.Context, in *CreatePreAuthKeyRequest, opts ...grpc.CallOption) (*CreatePreAuthKeyResponse, error) + ExpirePreAuthKey(ctx context.Context, in *ExpirePreAuthKeyRequest, opts ...grpc.CallOption) (*ExpirePreAuthKeyResponse, error) + ListPreAuthKeys(ctx context.Context, in *ListPreAuthKeysRequest, opts ...grpc.CallOption) (*ListPreAuthKeysResponse, error) + // --- Machine start --- + DebugCreateMachine(ctx context.Context, in *DebugCreateMachineRequest, opts ...grpc.CallOption) (*DebugCreateMachineResponse, error) + GetMachine(ctx context.Context, in *GetMachineRequest, opts ...grpc.CallOption) (*GetMachineResponse, error) + RegisterMachine(ctx context.Context, in *RegisterMachineRequest, opts ...grpc.CallOption) (*RegisterMachineResponse, error) + DeleteMachine(ctx context.Context, in *DeleteMachineRequest, opts ...grpc.CallOption) (*DeleteMachineResponse, error) + ListMachines(ctx context.Context, in *ListMachinesRequest, opts ...grpc.CallOption) (*ListMachinesResponse, error) + ShareMachine(ctx context.Context, in *ShareMachineRequest, opts ...grpc.CallOption) (*ShareMachineResponse, error) + UnshareMachine(ctx context.Context, in *UnshareMachineRequest, opts ...grpc.CallOption) (*UnshareMachineResponse, error) + // --- Route start --- + GetMachineRoute(ctx context.Context, in *GetMachineRouteRequest, opts ...grpc.CallOption) (*GetMachineRouteResponse, error) + EnableMachineRoutes(ctx context.Context, in *EnableMachineRoutesRequest, opts ...grpc.CallOption) (*EnableMachineRoutesResponse, error) } type headscaleServiceClient struct { @@ -32,9 +49,9 @@ func NewHeadscaleServiceClient(cc grpc.ClientConnInterface) HeadscaleServiceClie return &headscaleServiceClient{cc} } -func (c *headscaleServiceClient) GetMachine(ctx context.Context, in *GetMachineRequest, opts ...grpc.CallOption) (*GetMachineResponse, error) { - out := new(GetMachineResponse) - err := c.cc.Invoke(ctx, "/headscale.v1.HeadscaleService/GetMachine", in, out, opts...) +func (c *headscaleServiceClient) GetNamespace(ctx context.Context, in *GetNamespaceRequest, opts ...grpc.CallOption) (*GetNamespaceResponse, error) { + out := new(GetNamespaceResponse) + err := c.cc.Invoke(ctx, "/headscale.v1.HeadscaleService/GetNamespace", in, out, opts...) if err != nil { return nil, err } @@ -50,6 +67,15 @@ func (c *headscaleServiceClient) CreateNamespace(ctx context.Context, in *Create return out, nil } +func (c *headscaleServiceClient) RenameNamespace(ctx context.Context, in *RenameNamespaceRequest, opts ...grpc.CallOption) (*RenameNamespaceResponse, error) { + out := new(RenameNamespaceResponse) + err := c.cc.Invoke(ctx, "/headscale.v1.HeadscaleService/RenameNamespace", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *headscaleServiceClient) DeleteNamespace(ctx context.Context, in *DeleteNamespaceRequest, opts ...grpc.CallOption) (*DeleteNamespaceResponse, error) { out := new(DeleteNamespaceResponse) err := c.cc.Invoke(ctx, "/headscale.v1.HeadscaleService/DeleteNamespace", in, out, opts...) @@ -68,14 +94,139 @@ func (c *headscaleServiceClient) ListNamespaces(ctx context.Context, in *ListNam return out, nil } +func (c *headscaleServiceClient) CreatePreAuthKey(ctx context.Context, in *CreatePreAuthKeyRequest, opts ...grpc.CallOption) (*CreatePreAuthKeyResponse, error) { + out := new(CreatePreAuthKeyResponse) + err := c.cc.Invoke(ctx, "/headscale.v1.HeadscaleService/CreatePreAuthKey", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *headscaleServiceClient) ExpirePreAuthKey(ctx context.Context, in *ExpirePreAuthKeyRequest, opts ...grpc.CallOption) (*ExpirePreAuthKeyResponse, error) { + out := new(ExpirePreAuthKeyResponse) + err := c.cc.Invoke(ctx, "/headscale.v1.HeadscaleService/ExpirePreAuthKey", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *headscaleServiceClient) ListPreAuthKeys(ctx context.Context, in *ListPreAuthKeysRequest, opts ...grpc.CallOption) (*ListPreAuthKeysResponse, error) { + out := new(ListPreAuthKeysResponse) + err := c.cc.Invoke(ctx, "/headscale.v1.HeadscaleService/ListPreAuthKeys", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *headscaleServiceClient) DebugCreateMachine(ctx context.Context, in *DebugCreateMachineRequest, opts ...grpc.CallOption) (*DebugCreateMachineResponse, error) { + out := new(DebugCreateMachineResponse) + err := c.cc.Invoke(ctx, "/headscale.v1.HeadscaleService/DebugCreateMachine", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *headscaleServiceClient) GetMachine(ctx context.Context, in *GetMachineRequest, opts ...grpc.CallOption) (*GetMachineResponse, error) { + out := new(GetMachineResponse) + err := c.cc.Invoke(ctx, "/headscale.v1.HeadscaleService/GetMachine", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *headscaleServiceClient) RegisterMachine(ctx context.Context, in *RegisterMachineRequest, opts ...grpc.CallOption) (*RegisterMachineResponse, error) { + out := new(RegisterMachineResponse) + err := c.cc.Invoke(ctx, "/headscale.v1.HeadscaleService/RegisterMachine", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *headscaleServiceClient) DeleteMachine(ctx context.Context, in *DeleteMachineRequest, opts ...grpc.CallOption) (*DeleteMachineResponse, error) { + out := new(DeleteMachineResponse) + err := c.cc.Invoke(ctx, "/headscale.v1.HeadscaleService/DeleteMachine", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *headscaleServiceClient) ListMachines(ctx context.Context, in *ListMachinesRequest, opts ...grpc.CallOption) (*ListMachinesResponse, error) { + out := new(ListMachinesResponse) + err := c.cc.Invoke(ctx, "/headscale.v1.HeadscaleService/ListMachines", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *headscaleServiceClient) ShareMachine(ctx context.Context, in *ShareMachineRequest, opts ...grpc.CallOption) (*ShareMachineResponse, error) { + out := new(ShareMachineResponse) + err := c.cc.Invoke(ctx, "/headscale.v1.HeadscaleService/ShareMachine", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *headscaleServiceClient) UnshareMachine(ctx context.Context, in *UnshareMachineRequest, opts ...grpc.CallOption) (*UnshareMachineResponse, error) { + out := new(UnshareMachineResponse) + err := c.cc.Invoke(ctx, "/headscale.v1.HeadscaleService/UnshareMachine", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *headscaleServiceClient) GetMachineRoute(ctx context.Context, in *GetMachineRouteRequest, opts ...grpc.CallOption) (*GetMachineRouteResponse, error) { + out := new(GetMachineRouteResponse) + err := c.cc.Invoke(ctx, "/headscale.v1.HeadscaleService/GetMachineRoute", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *headscaleServiceClient) EnableMachineRoutes(ctx context.Context, in *EnableMachineRoutesRequest, opts ...grpc.CallOption) (*EnableMachineRoutesResponse, error) { + out := new(EnableMachineRoutesResponse) + err := c.cc.Invoke(ctx, "/headscale.v1.HeadscaleService/EnableMachineRoutes", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // HeadscaleServiceServer is the server API for HeadscaleService service. // All implementations must embed UnimplementedHeadscaleServiceServer // for forward compatibility type HeadscaleServiceServer interface { - GetMachine(context.Context, *GetMachineRequest) (*GetMachineResponse, error) + // --- Namespace start --- + GetNamespace(context.Context, *GetNamespaceRequest) (*GetNamespaceResponse, error) CreateNamespace(context.Context, *CreateNamespaceRequest) (*CreateNamespaceResponse, error) + RenameNamespace(context.Context, *RenameNamespaceRequest) (*RenameNamespaceResponse, error) DeleteNamespace(context.Context, *DeleteNamespaceRequest) (*DeleteNamespaceResponse, error) ListNamespaces(context.Context, *ListNamespacesRequest) (*ListNamespacesResponse, error) + // --- PreAuthKeys start --- + CreatePreAuthKey(context.Context, *CreatePreAuthKeyRequest) (*CreatePreAuthKeyResponse, error) + ExpirePreAuthKey(context.Context, *ExpirePreAuthKeyRequest) (*ExpirePreAuthKeyResponse, error) + ListPreAuthKeys(context.Context, *ListPreAuthKeysRequest) (*ListPreAuthKeysResponse, error) + // --- Machine start --- + DebugCreateMachine(context.Context, *DebugCreateMachineRequest) (*DebugCreateMachineResponse, error) + GetMachine(context.Context, *GetMachineRequest) (*GetMachineResponse, error) + RegisterMachine(context.Context, *RegisterMachineRequest) (*RegisterMachineResponse, error) + DeleteMachine(context.Context, *DeleteMachineRequest) (*DeleteMachineResponse, error) + ListMachines(context.Context, *ListMachinesRequest) (*ListMachinesResponse, error) + ShareMachine(context.Context, *ShareMachineRequest) (*ShareMachineResponse, error) + UnshareMachine(context.Context, *UnshareMachineRequest) (*UnshareMachineResponse, error) + // --- Route start --- + GetMachineRoute(context.Context, *GetMachineRouteRequest) (*GetMachineRouteResponse, error) + EnableMachineRoutes(context.Context, *EnableMachineRoutesRequest) (*EnableMachineRoutesResponse, error) mustEmbedUnimplementedHeadscaleServiceServer() } @@ -83,18 +234,57 @@ type HeadscaleServiceServer interface { type UnimplementedHeadscaleServiceServer struct { } -func (UnimplementedHeadscaleServiceServer) GetMachine(context.Context, *GetMachineRequest) (*GetMachineResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method GetMachine not implemented") +func (UnimplementedHeadscaleServiceServer) GetNamespace(context.Context, *GetNamespaceRequest) (*GetNamespaceResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetNamespace not implemented") } func (UnimplementedHeadscaleServiceServer) CreateNamespace(context.Context, *CreateNamespaceRequest) (*CreateNamespaceResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method CreateNamespace not implemented") } +func (UnimplementedHeadscaleServiceServer) RenameNamespace(context.Context, *RenameNamespaceRequest) (*RenameNamespaceResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method RenameNamespace not implemented") +} func (UnimplementedHeadscaleServiceServer) DeleteNamespace(context.Context, *DeleteNamespaceRequest) (*DeleteNamespaceResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method DeleteNamespace not implemented") } func (UnimplementedHeadscaleServiceServer) ListNamespaces(context.Context, *ListNamespacesRequest) (*ListNamespacesResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method ListNamespaces not implemented") } +func (UnimplementedHeadscaleServiceServer) CreatePreAuthKey(context.Context, *CreatePreAuthKeyRequest) (*CreatePreAuthKeyResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method CreatePreAuthKey not implemented") +} +func (UnimplementedHeadscaleServiceServer) ExpirePreAuthKey(context.Context, *ExpirePreAuthKeyRequest) (*ExpirePreAuthKeyResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ExpirePreAuthKey not implemented") +} +func (UnimplementedHeadscaleServiceServer) ListPreAuthKeys(context.Context, *ListPreAuthKeysRequest) (*ListPreAuthKeysResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ListPreAuthKeys not implemented") +} +func (UnimplementedHeadscaleServiceServer) DebugCreateMachine(context.Context, *DebugCreateMachineRequest) (*DebugCreateMachineResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method DebugCreateMachine not implemented") +} +func (UnimplementedHeadscaleServiceServer) GetMachine(context.Context, *GetMachineRequest) (*GetMachineResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetMachine not implemented") +} +func (UnimplementedHeadscaleServiceServer) RegisterMachine(context.Context, *RegisterMachineRequest) (*RegisterMachineResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method RegisterMachine not implemented") +} +func (UnimplementedHeadscaleServiceServer) DeleteMachine(context.Context, *DeleteMachineRequest) (*DeleteMachineResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method DeleteMachine not implemented") +} +func (UnimplementedHeadscaleServiceServer) ListMachines(context.Context, *ListMachinesRequest) (*ListMachinesResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ListMachines not implemented") +} +func (UnimplementedHeadscaleServiceServer) ShareMachine(context.Context, *ShareMachineRequest) (*ShareMachineResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ShareMachine not implemented") +} +func (UnimplementedHeadscaleServiceServer) UnshareMachine(context.Context, *UnshareMachineRequest) (*UnshareMachineResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method UnshareMachine not implemented") +} +func (UnimplementedHeadscaleServiceServer) GetMachineRoute(context.Context, *GetMachineRouteRequest) (*GetMachineRouteResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetMachineRoute not implemented") +} +func (UnimplementedHeadscaleServiceServer) EnableMachineRoutes(context.Context, *EnableMachineRoutesRequest) (*EnableMachineRoutesResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method EnableMachineRoutes not implemented") +} func (UnimplementedHeadscaleServiceServer) mustEmbedUnimplementedHeadscaleServiceServer() {} // UnsafeHeadscaleServiceServer may be embedded to opt out of forward compatibility for this service. @@ -108,20 +298,20 @@ func RegisterHeadscaleServiceServer(s grpc.ServiceRegistrar, srv HeadscaleServic s.RegisterService(&HeadscaleService_ServiceDesc, srv) } -func _HeadscaleService_GetMachine_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(GetMachineRequest) +func _HeadscaleService_GetNamespace_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetNamespaceRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(HeadscaleServiceServer).GetMachine(ctx, in) + return srv.(HeadscaleServiceServer).GetNamespace(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/headscale.v1.HeadscaleService/GetMachine", + FullMethod: "/headscale.v1.HeadscaleService/GetNamespace", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(HeadscaleServiceServer).GetMachine(ctx, req.(*GetMachineRequest)) + return srv.(HeadscaleServiceServer).GetNamespace(ctx, req.(*GetNamespaceRequest)) } return interceptor(ctx, in, info, handler) } @@ -144,6 +334,24 @@ func _HeadscaleService_CreateNamespace_Handler(srv interface{}, ctx context.Cont return interceptor(ctx, in, info, handler) } +func _HeadscaleService_RenameNamespace_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(RenameNamespaceRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(HeadscaleServiceServer).RenameNamespace(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/headscale.v1.HeadscaleService/RenameNamespace", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(HeadscaleServiceServer).RenameNamespace(ctx, req.(*RenameNamespaceRequest)) + } + return interceptor(ctx, in, info, handler) +} + func _HeadscaleService_DeleteNamespace_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(DeleteNamespaceRequest) if err := dec(in); err != nil { @@ -180,6 +388,222 @@ func _HeadscaleService_ListNamespaces_Handler(srv interface{}, ctx context.Conte return interceptor(ctx, in, info, handler) } +func _HeadscaleService_CreatePreAuthKey_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CreatePreAuthKeyRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(HeadscaleServiceServer).CreatePreAuthKey(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/headscale.v1.HeadscaleService/CreatePreAuthKey", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(HeadscaleServiceServer).CreatePreAuthKey(ctx, req.(*CreatePreAuthKeyRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _HeadscaleService_ExpirePreAuthKey_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ExpirePreAuthKeyRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(HeadscaleServiceServer).ExpirePreAuthKey(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/headscale.v1.HeadscaleService/ExpirePreAuthKey", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(HeadscaleServiceServer).ExpirePreAuthKey(ctx, req.(*ExpirePreAuthKeyRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _HeadscaleService_ListPreAuthKeys_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ListPreAuthKeysRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(HeadscaleServiceServer).ListPreAuthKeys(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/headscale.v1.HeadscaleService/ListPreAuthKeys", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(HeadscaleServiceServer).ListPreAuthKeys(ctx, req.(*ListPreAuthKeysRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _HeadscaleService_DebugCreateMachine_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(DebugCreateMachineRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(HeadscaleServiceServer).DebugCreateMachine(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/headscale.v1.HeadscaleService/DebugCreateMachine", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(HeadscaleServiceServer).DebugCreateMachine(ctx, req.(*DebugCreateMachineRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _HeadscaleService_GetMachine_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetMachineRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(HeadscaleServiceServer).GetMachine(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/headscale.v1.HeadscaleService/GetMachine", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(HeadscaleServiceServer).GetMachine(ctx, req.(*GetMachineRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _HeadscaleService_RegisterMachine_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(RegisterMachineRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(HeadscaleServiceServer).RegisterMachine(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/headscale.v1.HeadscaleService/RegisterMachine", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(HeadscaleServiceServer).RegisterMachine(ctx, req.(*RegisterMachineRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _HeadscaleService_DeleteMachine_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(DeleteMachineRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(HeadscaleServiceServer).DeleteMachine(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/headscale.v1.HeadscaleService/DeleteMachine", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(HeadscaleServiceServer).DeleteMachine(ctx, req.(*DeleteMachineRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _HeadscaleService_ListMachines_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ListMachinesRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(HeadscaleServiceServer).ListMachines(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/headscale.v1.HeadscaleService/ListMachines", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(HeadscaleServiceServer).ListMachines(ctx, req.(*ListMachinesRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _HeadscaleService_ShareMachine_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ShareMachineRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(HeadscaleServiceServer).ShareMachine(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/headscale.v1.HeadscaleService/ShareMachine", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(HeadscaleServiceServer).ShareMachine(ctx, req.(*ShareMachineRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _HeadscaleService_UnshareMachine_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UnshareMachineRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(HeadscaleServiceServer).UnshareMachine(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/headscale.v1.HeadscaleService/UnshareMachine", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(HeadscaleServiceServer).UnshareMachine(ctx, req.(*UnshareMachineRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _HeadscaleService_GetMachineRoute_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetMachineRouteRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(HeadscaleServiceServer).GetMachineRoute(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/headscale.v1.HeadscaleService/GetMachineRoute", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(HeadscaleServiceServer).GetMachineRoute(ctx, req.(*GetMachineRouteRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _HeadscaleService_EnableMachineRoutes_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(EnableMachineRoutesRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(HeadscaleServiceServer).EnableMachineRoutes(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/headscale.v1.HeadscaleService/EnableMachineRoutes", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(HeadscaleServiceServer).EnableMachineRoutes(ctx, req.(*EnableMachineRoutesRequest)) + } + return interceptor(ctx, in, info, handler) +} + // HeadscaleService_ServiceDesc is the grpc.ServiceDesc for HeadscaleService service. // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) @@ -188,13 +612,17 @@ var HeadscaleService_ServiceDesc = grpc.ServiceDesc{ HandlerType: (*HeadscaleServiceServer)(nil), Methods: []grpc.MethodDesc{ { - MethodName: "GetMachine", - Handler: _HeadscaleService_GetMachine_Handler, + MethodName: "GetNamespace", + Handler: _HeadscaleService_GetNamespace_Handler, }, { MethodName: "CreateNamespace", Handler: _HeadscaleService_CreateNamespace_Handler, }, + { + MethodName: "RenameNamespace", + Handler: _HeadscaleService_RenameNamespace_Handler, + }, { MethodName: "DeleteNamespace", Handler: _HeadscaleService_DeleteNamespace_Handler, @@ -203,6 +631,54 @@ var HeadscaleService_ServiceDesc = grpc.ServiceDesc{ MethodName: "ListNamespaces", Handler: _HeadscaleService_ListNamespaces_Handler, }, + { + MethodName: "CreatePreAuthKey", + Handler: _HeadscaleService_CreatePreAuthKey_Handler, + }, + { + MethodName: "ExpirePreAuthKey", + Handler: _HeadscaleService_ExpirePreAuthKey_Handler, + }, + { + MethodName: "ListPreAuthKeys", + Handler: _HeadscaleService_ListPreAuthKeys_Handler, + }, + { + MethodName: "DebugCreateMachine", + Handler: _HeadscaleService_DebugCreateMachine_Handler, + }, + { + MethodName: "GetMachine", + Handler: _HeadscaleService_GetMachine_Handler, + }, + { + MethodName: "RegisterMachine", + Handler: _HeadscaleService_RegisterMachine_Handler, + }, + { + MethodName: "DeleteMachine", + Handler: _HeadscaleService_DeleteMachine_Handler, + }, + { + MethodName: "ListMachines", + Handler: _HeadscaleService_ListMachines_Handler, + }, + { + MethodName: "ShareMachine", + Handler: _HeadscaleService_ShareMachine_Handler, + }, + { + MethodName: "UnshareMachine", + Handler: _HeadscaleService_UnshareMachine_Handler, + }, + { + MethodName: "GetMachineRoute", + Handler: _HeadscaleService_GetMachineRoute_Handler, + }, + { + MethodName: "EnableMachineRoutes", + Handler: _HeadscaleService_EnableMachineRoutes_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "headscale/v1/headscale.proto", diff --git a/gen/go/headscale/v1/machine.pb.go b/gen/go/headscale/v1/machine.pb.go new file mode 100644 index 00000000..b5ec2cda --- /dev/null +++ b/gen/go/headscale/v1/machine.pb.go @@ -0,0 +1,1316 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.27.1 +// protoc v3.18.1 +// source: headscale/v1/machine.proto + +package v1 + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + timestamppb "google.golang.org/protobuf/types/known/timestamppb" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type RegisterMethod int32 + +const ( + RegisterMethod_REGISTER_METHOD_UNSPECIFIED RegisterMethod = 0 + RegisterMethod_REGISTER_METHOD_AUTH_KEY RegisterMethod = 1 + RegisterMethod_REGISTER_METHOD_CLI RegisterMethod = 2 + RegisterMethod_REGISTER_METHOD_OIDC RegisterMethod = 3 +) + +// Enum value maps for RegisterMethod. +var ( + RegisterMethod_name = map[int32]string{ + 0: "REGISTER_METHOD_UNSPECIFIED", + 1: "REGISTER_METHOD_AUTH_KEY", + 2: "REGISTER_METHOD_CLI", + 3: "REGISTER_METHOD_OIDC", + } + RegisterMethod_value = map[string]int32{ + "REGISTER_METHOD_UNSPECIFIED": 0, + "REGISTER_METHOD_AUTH_KEY": 1, + "REGISTER_METHOD_CLI": 2, + "REGISTER_METHOD_OIDC": 3, + } +) + +func (x RegisterMethod) Enum() *RegisterMethod { + p := new(RegisterMethod) + *p = x + return p +} + +func (x RegisterMethod) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (RegisterMethod) Descriptor() protoreflect.EnumDescriptor { + return file_headscale_v1_machine_proto_enumTypes[0].Descriptor() +} + +func (RegisterMethod) Type() protoreflect.EnumType { + return &file_headscale_v1_machine_proto_enumTypes[0] +} + +func (x RegisterMethod) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use RegisterMethod.Descriptor instead. +func (RegisterMethod) EnumDescriptor() ([]byte, []int) { + return file_headscale_v1_machine_proto_rawDescGZIP(), []int{0} +} + +type Machine struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id uint64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` + MachineKey string `protobuf:"bytes,2,opt,name=machine_key,json=machineKey,proto3" json:"machine_key,omitempty"` + NodeKey string `protobuf:"bytes,3,opt,name=node_key,json=nodeKey,proto3" json:"node_key,omitempty"` + DiscoKey string `protobuf:"bytes,4,opt,name=disco_key,json=discoKey,proto3" json:"disco_key,omitempty"` + IpAddress string `protobuf:"bytes,5,opt,name=ip_address,json=ipAddress,proto3" json:"ip_address,omitempty"` + Name string `protobuf:"bytes,6,opt,name=name,proto3" json:"name,omitempty"` + Namespace *Namespace `protobuf:"bytes,7,opt,name=namespace,proto3" json:"namespace,omitempty"` + Registered bool `protobuf:"varint,8,opt,name=registered,proto3" json:"registered,omitempty"` + RegisterMethod RegisterMethod `protobuf:"varint,9,opt,name=register_method,json=registerMethod,proto3,enum=headscale.v1.RegisterMethod" json:"register_method,omitempty"` + LastSeen *timestamppb.Timestamp `protobuf:"bytes,10,opt,name=last_seen,json=lastSeen,proto3" json:"last_seen,omitempty"` + LastSuccessfulUpdate *timestamppb.Timestamp `protobuf:"bytes,11,opt,name=last_successful_update,json=lastSuccessfulUpdate,proto3" json:"last_successful_update,omitempty"` + Expiry *timestamppb.Timestamp `protobuf:"bytes,12,opt,name=expiry,proto3" json:"expiry,omitempty"` + PreAuthKey *PreAuthKey `protobuf:"bytes,13,opt,name=pre_auth_key,json=preAuthKey,proto3" json:"pre_auth_key,omitempty"` + CreatedAt *timestamppb.Timestamp `protobuf:"bytes,14,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` +} + +func (x *Machine) Reset() { + *x = Machine{} + if protoimpl.UnsafeEnabled { + mi := &file_headscale_v1_machine_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Machine) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Machine) ProtoMessage() {} + +func (x *Machine) ProtoReflect() protoreflect.Message { + mi := &file_headscale_v1_machine_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Machine.ProtoReflect.Descriptor instead. +func (*Machine) Descriptor() ([]byte, []int) { + return file_headscale_v1_machine_proto_rawDescGZIP(), []int{0} +} + +func (x *Machine) GetId() uint64 { + if x != nil { + return x.Id + } + return 0 +} + +func (x *Machine) GetMachineKey() string { + if x != nil { + return x.MachineKey + } + return "" +} + +func (x *Machine) GetNodeKey() string { + if x != nil { + return x.NodeKey + } + return "" +} + +func (x *Machine) GetDiscoKey() string { + if x != nil { + return x.DiscoKey + } + return "" +} + +func (x *Machine) GetIpAddress() string { + if x != nil { + return x.IpAddress + } + return "" +} + +func (x *Machine) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *Machine) GetNamespace() *Namespace { + if x != nil { + return x.Namespace + } + return nil +} + +func (x *Machine) GetRegistered() bool { + if x != nil { + return x.Registered + } + return false +} + +func (x *Machine) GetRegisterMethod() RegisterMethod { + if x != nil { + return x.RegisterMethod + } + return RegisterMethod_REGISTER_METHOD_UNSPECIFIED +} + +func (x *Machine) GetLastSeen() *timestamppb.Timestamp { + if x != nil { + return x.LastSeen + } + return nil +} + +func (x *Machine) GetLastSuccessfulUpdate() *timestamppb.Timestamp { + if x != nil { + return x.LastSuccessfulUpdate + } + return nil +} + +func (x *Machine) GetExpiry() *timestamppb.Timestamp { + if x != nil { + return x.Expiry + } + return nil +} + +func (x *Machine) GetPreAuthKey() *PreAuthKey { + if x != nil { + return x.PreAuthKey + } + return nil +} + +func (x *Machine) GetCreatedAt() *timestamppb.Timestamp { + if x != nil { + return x.CreatedAt + } + return nil +} + +type RegisterMachineRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Namespace string `protobuf:"bytes,1,opt,name=namespace,proto3" json:"namespace,omitempty"` + Key string `protobuf:"bytes,2,opt,name=key,proto3" json:"key,omitempty"` +} + +func (x *RegisterMachineRequest) Reset() { + *x = RegisterMachineRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_headscale_v1_machine_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RegisterMachineRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RegisterMachineRequest) ProtoMessage() {} + +func (x *RegisterMachineRequest) ProtoReflect() protoreflect.Message { + mi := &file_headscale_v1_machine_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RegisterMachineRequest.ProtoReflect.Descriptor instead. +func (*RegisterMachineRequest) Descriptor() ([]byte, []int) { + return file_headscale_v1_machine_proto_rawDescGZIP(), []int{1} +} + +func (x *RegisterMachineRequest) GetNamespace() string { + if x != nil { + return x.Namespace + } + return "" +} + +func (x *RegisterMachineRequest) GetKey() string { + if x != nil { + return x.Key + } + return "" +} + +type RegisterMachineResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Machine *Machine `protobuf:"bytes,1,opt,name=machine,proto3" json:"machine,omitempty"` +} + +func (x *RegisterMachineResponse) Reset() { + *x = RegisterMachineResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_headscale_v1_machine_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RegisterMachineResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RegisterMachineResponse) ProtoMessage() {} + +func (x *RegisterMachineResponse) ProtoReflect() protoreflect.Message { + mi := &file_headscale_v1_machine_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RegisterMachineResponse.ProtoReflect.Descriptor instead. +func (*RegisterMachineResponse) Descriptor() ([]byte, []int) { + return file_headscale_v1_machine_proto_rawDescGZIP(), []int{2} +} + +func (x *RegisterMachineResponse) GetMachine() *Machine { + if x != nil { + return x.Machine + } + return nil +} + +type GetMachineRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + MachineId uint64 `protobuf:"varint,1,opt,name=machine_id,json=machineId,proto3" json:"machine_id,omitempty"` +} + +func (x *GetMachineRequest) Reset() { + *x = GetMachineRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_headscale_v1_machine_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetMachineRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetMachineRequest) ProtoMessage() {} + +func (x *GetMachineRequest) ProtoReflect() protoreflect.Message { + mi := &file_headscale_v1_machine_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetMachineRequest.ProtoReflect.Descriptor instead. +func (*GetMachineRequest) Descriptor() ([]byte, []int) { + return file_headscale_v1_machine_proto_rawDescGZIP(), []int{3} +} + +func (x *GetMachineRequest) GetMachineId() uint64 { + if x != nil { + return x.MachineId + } + return 0 +} + +type GetMachineResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Machine *Machine `protobuf:"bytes,1,opt,name=machine,proto3" json:"machine,omitempty"` +} + +func (x *GetMachineResponse) Reset() { + *x = GetMachineResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_headscale_v1_machine_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetMachineResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetMachineResponse) ProtoMessage() {} + +func (x *GetMachineResponse) ProtoReflect() protoreflect.Message { + mi := &file_headscale_v1_machine_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetMachineResponse.ProtoReflect.Descriptor instead. +func (*GetMachineResponse) Descriptor() ([]byte, []int) { + return file_headscale_v1_machine_proto_rawDescGZIP(), []int{4} +} + +func (x *GetMachineResponse) GetMachine() *Machine { + if x != nil { + return x.Machine + } + return nil +} + +type DeleteMachineRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + MachineId uint64 `protobuf:"varint,1,opt,name=machine_id,json=machineId,proto3" json:"machine_id,omitempty"` +} + +func (x *DeleteMachineRequest) Reset() { + *x = DeleteMachineRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_headscale_v1_machine_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DeleteMachineRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeleteMachineRequest) ProtoMessage() {} + +func (x *DeleteMachineRequest) ProtoReflect() protoreflect.Message { + mi := &file_headscale_v1_machine_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DeleteMachineRequest.ProtoReflect.Descriptor instead. +func (*DeleteMachineRequest) Descriptor() ([]byte, []int) { + return file_headscale_v1_machine_proto_rawDescGZIP(), []int{5} +} + +func (x *DeleteMachineRequest) GetMachineId() uint64 { + if x != nil { + return x.MachineId + } + return 0 +} + +type DeleteMachineResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *DeleteMachineResponse) Reset() { + *x = DeleteMachineResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_headscale_v1_machine_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DeleteMachineResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeleteMachineResponse) ProtoMessage() {} + +func (x *DeleteMachineResponse) ProtoReflect() protoreflect.Message { + mi := &file_headscale_v1_machine_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DeleteMachineResponse.ProtoReflect.Descriptor instead. +func (*DeleteMachineResponse) Descriptor() ([]byte, []int) { + return file_headscale_v1_machine_proto_rawDescGZIP(), []int{6} +} + +type ListMachinesRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Namespace string `protobuf:"bytes,1,opt,name=namespace,proto3" json:"namespace,omitempty"` +} + +func (x *ListMachinesRequest) Reset() { + *x = ListMachinesRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_headscale_v1_machine_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListMachinesRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListMachinesRequest) ProtoMessage() {} + +func (x *ListMachinesRequest) ProtoReflect() protoreflect.Message { + mi := &file_headscale_v1_machine_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListMachinesRequest.ProtoReflect.Descriptor instead. +func (*ListMachinesRequest) Descriptor() ([]byte, []int) { + return file_headscale_v1_machine_proto_rawDescGZIP(), []int{7} +} + +func (x *ListMachinesRequest) GetNamespace() string { + if x != nil { + return x.Namespace + } + return "" +} + +type ListMachinesResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Machines []*Machine `protobuf:"bytes,1,rep,name=machines,proto3" json:"machines,omitempty"` +} + +func (x *ListMachinesResponse) Reset() { + *x = ListMachinesResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_headscale_v1_machine_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListMachinesResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListMachinesResponse) ProtoMessage() {} + +func (x *ListMachinesResponse) ProtoReflect() protoreflect.Message { + mi := &file_headscale_v1_machine_proto_msgTypes[8] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListMachinesResponse.ProtoReflect.Descriptor instead. +func (*ListMachinesResponse) Descriptor() ([]byte, []int) { + return file_headscale_v1_machine_proto_rawDescGZIP(), []int{8} +} + +func (x *ListMachinesResponse) GetMachines() []*Machine { + if x != nil { + return x.Machines + } + return nil +} + +type ShareMachineRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + MachineId uint64 `protobuf:"varint,1,opt,name=machine_id,json=machineId,proto3" json:"machine_id,omitempty"` + Namespace string `protobuf:"bytes,2,opt,name=namespace,proto3" json:"namespace,omitempty"` +} + +func (x *ShareMachineRequest) Reset() { + *x = ShareMachineRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_headscale_v1_machine_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ShareMachineRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ShareMachineRequest) ProtoMessage() {} + +func (x *ShareMachineRequest) ProtoReflect() protoreflect.Message { + mi := &file_headscale_v1_machine_proto_msgTypes[9] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ShareMachineRequest.ProtoReflect.Descriptor instead. +func (*ShareMachineRequest) Descriptor() ([]byte, []int) { + return file_headscale_v1_machine_proto_rawDescGZIP(), []int{9} +} + +func (x *ShareMachineRequest) GetMachineId() uint64 { + if x != nil { + return x.MachineId + } + return 0 +} + +func (x *ShareMachineRequest) GetNamespace() string { + if x != nil { + return x.Namespace + } + return "" +} + +type ShareMachineResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Machine *Machine `protobuf:"bytes,1,opt,name=machine,proto3" json:"machine,omitempty"` +} + +func (x *ShareMachineResponse) Reset() { + *x = ShareMachineResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_headscale_v1_machine_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ShareMachineResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ShareMachineResponse) ProtoMessage() {} + +func (x *ShareMachineResponse) ProtoReflect() protoreflect.Message { + mi := &file_headscale_v1_machine_proto_msgTypes[10] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ShareMachineResponse.ProtoReflect.Descriptor instead. +func (*ShareMachineResponse) Descriptor() ([]byte, []int) { + return file_headscale_v1_machine_proto_rawDescGZIP(), []int{10} +} + +func (x *ShareMachineResponse) GetMachine() *Machine { + if x != nil { + return x.Machine + } + return nil +} + +type UnshareMachineRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + MachineId uint64 `protobuf:"varint,1,opt,name=machine_id,json=machineId,proto3" json:"machine_id,omitempty"` + Namespace string `protobuf:"bytes,2,opt,name=namespace,proto3" json:"namespace,omitempty"` +} + +func (x *UnshareMachineRequest) Reset() { + *x = UnshareMachineRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_headscale_v1_machine_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UnshareMachineRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UnshareMachineRequest) ProtoMessage() {} + +func (x *UnshareMachineRequest) ProtoReflect() protoreflect.Message { + mi := &file_headscale_v1_machine_proto_msgTypes[11] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UnshareMachineRequest.ProtoReflect.Descriptor instead. +func (*UnshareMachineRequest) Descriptor() ([]byte, []int) { + return file_headscale_v1_machine_proto_rawDescGZIP(), []int{11} +} + +func (x *UnshareMachineRequest) GetMachineId() uint64 { + if x != nil { + return x.MachineId + } + return 0 +} + +func (x *UnshareMachineRequest) GetNamespace() string { + if x != nil { + return x.Namespace + } + return "" +} + +type UnshareMachineResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Machine *Machine `protobuf:"bytes,1,opt,name=machine,proto3" json:"machine,omitempty"` +} + +func (x *UnshareMachineResponse) Reset() { + *x = UnshareMachineResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_headscale_v1_machine_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UnshareMachineResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UnshareMachineResponse) ProtoMessage() {} + +func (x *UnshareMachineResponse) ProtoReflect() protoreflect.Message { + mi := &file_headscale_v1_machine_proto_msgTypes[12] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UnshareMachineResponse.ProtoReflect.Descriptor instead. +func (*UnshareMachineResponse) Descriptor() ([]byte, []int) { + return file_headscale_v1_machine_proto_rawDescGZIP(), []int{12} +} + +func (x *UnshareMachineResponse) GetMachine() *Machine { + if x != nil { + return x.Machine + } + return nil +} + +type DebugCreateMachineRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Namespace string `protobuf:"bytes,1,opt,name=namespace,proto3" json:"namespace,omitempty"` + Key string `protobuf:"bytes,2,opt,name=key,proto3" json:"key,omitempty"` + Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"` + Routes []string `protobuf:"bytes,4,rep,name=routes,proto3" json:"routes,omitempty"` +} + +func (x *DebugCreateMachineRequest) Reset() { + *x = DebugCreateMachineRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_headscale_v1_machine_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DebugCreateMachineRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DebugCreateMachineRequest) ProtoMessage() {} + +func (x *DebugCreateMachineRequest) ProtoReflect() protoreflect.Message { + mi := &file_headscale_v1_machine_proto_msgTypes[13] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DebugCreateMachineRequest.ProtoReflect.Descriptor instead. +func (*DebugCreateMachineRequest) Descriptor() ([]byte, []int) { + return file_headscale_v1_machine_proto_rawDescGZIP(), []int{13} +} + +func (x *DebugCreateMachineRequest) GetNamespace() string { + if x != nil { + return x.Namespace + } + return "" +} + +func (x *DebugCreateMachineRequest) GetKey() string { + if x != nil { + return x.Key + } + return "" +} + +func (x *DebugCreateMachineRequest) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *DebugCreateMachineRequest) GetRoutes() []string { + if x != nil { + return x.Routes + } + return nil +} + +type DebugCreateMachineResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Machine *Machine `protobuf:"bytes,1,opt,name=machine,proto3" json:"machine,omitempty"` +} + +func (x *DebugCreateMachineResponse) Reset() { + *x = DebugCreateMachineResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_headscale_v1_machine_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DebugCreateMachineResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DebugCreateMachineResponse) ProtoMessage() {} + +func (x *DebugCreateMachineResponse) ProtoReflect() protoreflect.Message { + mi := &file_headscale_v1_machine_proto_msgTypes[14] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DebugCreateMachineResponse.ProtoReflect.Descriptor instead. +func (*DebugCreateMachineResponse) Descriptor() ([]byte, []int) { + return file_headscale_v1_machine_proto_rawDescGZIP(), []int{14} +} + +func (x *DebugCreateMachineResponse) GetMachine() *Machine { + if x != nil { + return x.Machine + } + return nil +} + +var File_headscale_v1_machine_proto protoreflect.FileDescriptor + +var file_headscale_v1_machine_proto_rawDesc = []byte{ + 0x0a, 0x1a, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x6d, + 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0c, 0x68, 0x65, + 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, + 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x68, 0x65, 0x61, + 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, + 0x61, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1d, 0x68, 0x65, 0x61, 0x64, 0x73, + 0x63, 0x61, 0x6c, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x72, 0x65, 0x61, 0x75, 0x74, 0x68, 0x6b, + 0x65, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xf9, 0x04, 0x0a, 0x07, 0x4d, 0x61, 0x63, + 0x68, 0x69, 0x6e, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, + 0x52, 0x02, 0x69, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x5f, + 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6d, 0x61, 0x63, 0x68, 0x69, + 0x6e, 0x65, 0x4b, 0x65, 0x79, 0x12, 0x19, 0x0a, 0x08, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x6b, 0x65, + 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6e, 0x6f, 0x64, 0x65, 0x4b, 0x65, 0x79, + 0x12, 0x1b, 0x0a, 0x09, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x08, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x4b, 0x65, 0x79, 0x12, 0x1d, 0x0a, + 0x0a, 0x69, 0x70, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x09, 0x69, 0x70, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x12, 0x0a, 0x04, + 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, + 0x12, 0x35, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x07, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, + 0x76, 0x31, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x09, 0x6e, 0x61, + 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x72, 0x65, 0x67, 0x69, 0x73, + 0x74, 0x65, 0x72, 0x65, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x72, 0x65, 0x67, + 0x69, 0x73, 0x74, 0x65, 0x72, 0x65, 0x64, 0x12, 0x45, 0x0a, 0x0f, 0x72, 0x65, 0x67, 0x69, 0x73, + 0x74, 0x65, 0x72, 0x5f, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0e, + 0x32, 0x1c, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, + 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x52, 0x0e, + 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, 0x37, + 0x0a, 0x09, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x65, 0x6e, 0x18, 0x0a, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x08, 0x6c, + 0x61, 0x73, 0x74, 0x53, 0x65, 0x65, 0x6e, 0x12, 0x50, 0x0a, 0x16, 0x6c, 0x61, 0x73, 0x74, 0x5f, + 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x66, 0x75, 0x6c, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, + 0x61, 0x6d, 0x70, 0x52, 0x14, 0x6c, 0x61, 0x73, 0x74, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x66, 0x75, 0x6c, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x32, 0x0a, 0x06, 0x65, 0x78, 0x70, + 0x69, 0x72, 0x79, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, + 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x06, 0x65, 0x78, 0x70, 0x69, 0x72, 0x79, 0x12, 0x3a, 0x0a, + 0x0c, 0x70, 0x72, 0x65, 0x5f, 0x61, 0x75, 0x74, 0x68, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x0d, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, + 0x76, 0x31, 0x2e, 0x50, 0x72, 0x65, 0x41, 0x75, 0x74, 0x68, 0x4b, 0x65, 0x79, 0x52, 0x0a, 0x70, + 0x72, 0x65, 0x41, 0x75, 0x74, 0x68, 0x4b, 0x65, 0x79, 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, + 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x64, 0x41, 0x74, 0x22, 0x48, 0x0a, 0x16, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, + 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, + 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x10, 0x0a, 0x03, + 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x22, 0x4a, + 0x0a, 0x17, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, + 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2f, 0x0a, 0x07, 0x6d, 0x61, 0x63, + 0x68, 0x69, 0x6e, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x68, 0x65, 0x61, + 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, + 0x65, 0x52, 0x07, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x22, 0x32, 0x0a, 0x11, 0x47, 0x65, + 0x74, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x1d, 0x0a, 0x0a, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x04, 0x52, 0x09, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x49, 0x64, 0x22, 0x45, + 0x0a, 0x12, 0x47, 0x65, 0x74, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2f, 0x0a, 0x07, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, + 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x07, 0x6d, 0x61, + 0x63, 0x68, 0x69, 0x6e, 0x65, 0x22, 0x35, 0x0a, 0x14, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4d, + 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, + 0x0a, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x04, 0x52, 0x09, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x49, 0x64, 0x22, 0x17, 0x0a, 0x15, + 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x33, 0x0a, 0x13, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x61, 0x63, + 0x68, 0x69, 0x6e, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, + 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x22, 0x49, 0x0a, 0x14, 0x4c, 0x69, + 0x73, 0x74, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x31, 0x0a, 0x08, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x73, 0x18, 0x01, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, + 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x08, 0x6d, 0x61, 0x63, + 0x68, 0x69, 0x6e, 0x65, 0x73, 0x22, 0x52, 0x0a, 0x13, 0x53, 0x68, 0x61, 0x72, 0x65, 0x4d, 0x61, + 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, + 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, + 0x52, 0x09, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x6e, + 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, + 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x22, 0x47, 0x0a, 0x14, 0x53, 0x68, 0x61, + 0x72, 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x2f, 0x0a, 0x07, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, + 0x31, 0x2e, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x07, 0x6d, 0x61, 0x63, 0x68, 0x69, + 0x6e, 0x65, 0x22, 0x54, 0x0a, 0x15, 0x55, 0x6e, 0x73, 0x68, 0x61, 0x72, 0x65, 0x4d, 0x61, 0x63, + 0x68, 0x69, 0x6e, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x6d, + 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, + 0x09, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x61, + 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, + 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x22, 0x49, 0x0a, 0x16, 0x55, 0x6e, 0x73, 0x68, + 0x61, 0x72, 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x2f, 0x0a, 0x07, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, + 0x76, 0x31, 0x2e, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x07, 0x6d, 0x61, 0x63, 0x68, + 0x69, 0x6e, 0x65, 0x22, 0x77, 0x0a, 0x19, 0x44, 0x65, 0x62, 0x75, 0x67, 0x43, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x10, + 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, + 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, + 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x18, 0x04, + 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x22, 0x4d, 0x0a, 0x1a, + 0x44, 0x65, 0x62, 0x75, 0x67, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, + 0x6e, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2f, 0x0a, 0x07, 0x6d, 0x61, + 0x63, 0x68, 0x69, 0x6e, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x68, 0x65, + 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x61, 0x63, 0x68, 0x69, + 0x6e, 0x65, 0x52, 0x07, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x2a, 0x82, 0x01, 0x0a, 0x0e, + 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, 0x1f, + 0x0a, 0x1b, 0x52, 0x45, 0x47, 0x49, 0x53, 0x54, 0x45, 0x52, 0x5f, 0x4d, 0x45, 0x54, 0x48, 0x4f, + 0x44, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, + 0x1c, 0x0a, 0x18, 0x52, 0x45, 0x47, 0x49, 0x53, 0x54, 0x45, 0x52, 0x5f, 0x4d, 0x45, 0x54, 0x48, + 0x4f, 0x44, 0x5f, 0x41, 0x55, 0x54, 0x48, 0x5f, 0x4b, 0x45, 0x59, 0x10, 0x01, 0x12, 0x17, 0x0a, + 0x13, 0x52, 0x45, 0x47, 0x49, 0x53, 0x54, 0x45, 0x52, 0x5f, 0x4d, 0x45, 0x54, 0x48, 0x4f, 0x44, + 0x5f, 0x43, 0x4c, 0x49, 0x10, 0x02, 0x12, 0x18, 0x0a, 0x14, 0x52, 0x45, 0x47, 0x49, 0x53, 0x54, + 0x45, 0x52, 0x5f, 0x4d, 0x45, 0x54, 0x48, 0x4f, 0x44, 0x5f, 0x4f, 0x49, 0x44, 0x43, 0x10, 0x03, + 0x42, 0x29, 0x5a, 0x27, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6a, + 0x75, 0x61, 0x6e, 0x66, 0x6f, 0x6e, 0x74, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, + 0x65, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x67, 0x6f, 0x2f, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x33, +} + +var ( + file_headscale_v1_machine_proto_rawDescOnce sync.Once + file_headscale_v1_machine_proto_rawDescData = file_headscale_v1_machine_proto_rawDesc +) + +func file_headscale_v1_machine_proto_rawDescGZIP() []byte { + file_headscale_v1_machine_proto_rawDescOnce.Do(func() { + file_headscale_v1_machine_proto_rawDescData = protoimpl.X.CompressGZIP(file_headscale_v1_machine_proto_rawDescData) + }) + return file_headscale_v1_machine_proto_rawDescData +} + +var file_headscale_v1_machine_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_headscale_v1_machine_proto_msgTypes = make([]protoimpl.MessageInfo, 15) +var file_headscale_v1_machine_proto_goTypes = []interface{}{ + (RegisterMethod)(0), // 0: headscale.v1.RegisterMethod + (*Machine)(nil), // 1: headscale.v1.Machine + (*RegisterMachineRequest)(nil), // 2: headscale.v1.RegisterMachineRequest + (*RegisterMachineResponse)(nil), // 3: headscale.v1.RegisterMachineResponse + (*GetMachineRequest)(nil), // 4: headscale.v1.GetMachineRequest + (*GetMachineResponse)(nil), // 5: headscale.v1.GetMachineResponse + (*DeleteMachineRequest)(nil), // 6: headscale.v1.DeleteMachineRequest + (*DeleteMachineResponse)(nil), // 7: headscale.v1.DeleteMachineResponse + (*ListMachinesRequest)(nil), // 8: headscale.v1.ListMachinesRequest + (*ListMachinesResponse)(nil), // 9: headscale.v1.ListMachinesResponse + (*ShareMachineRequest)(nil), // 10: headscale.v1.ShareMachineRequest + (*ShareMachineResponse)(nil), // 11: headscale.v1.ShareMachineResponse + (*UnshareMachineRequest)(nil), // 12: headscale.v1.UnshareMachineRequest + (*UnshareMachineResponse)(nil), // 13: headscale.v1.UnshareMachineResponse + (*DebugCreateMachineRequest)(nil), // 14: headscale.v1.DebugCreateMachineRequest + (*DebugCreateMachineResponse)(nil), // 15: headscale.v1.DebugCreateMachineResponse + (*Namespace)(nil), // 16: headscale.v1.Namespace + (*timestamppb.Timestamp)(nil), // 17: google.protobuf.Timestamp + (*PreAuthKey)(nil), // 18: headscale.v1.PreAuthKey +} +var file_headscale_v1_machine_proto_depIdxs = []int32{ + 16, // 0: headscale.v1.Machine.namespace:type_name -> headscale.v1.Namespace + 0, // 1: headscale.v1.Machine.register_method:type_name -> headscale.v1.RegisterMethod + 17, // 2: headscale.v1.Machine.last_seen:type_name -> google.protobuf.Timestamp + 17, // 3: headscale.v1.Machine.last_successful_update:type_name -> google.protobuf.Timestamp + 17, // 4: headscale.v1.Machine.expiry:type_name -> google.protobuf.Timestamp + 18, // 5: headscale.v1.Machine.pre_auth_key:type_name -> headscale.v1.PreAuthKey + 17, // 6: headscale.v1.Machine.created_at:type_name -> google.protobuf.Timestamp + 1, // 7: headscale.v1.RegisterMachineResponse.machine:type_name -> headscale.v1.Machine + 1, // 8: headscale.v1.GetMachineResponse.machine:type_name -> headscale.v1.Machine + 1, // 9: headscale.v1.ListMachinesResponse.machines:type_name -> headscale.v1.Machine + 1, // 10: headscale.v1.ShareMachineResponse.machine:type_name -> headscale.v1.Machine + 1, // 11: headscale.v1.UnshareMachineResponse.machine:type_name -> headscale.v1.Machine + 1, // 12: headscale.v1.DebugCreateMachineResponse.machine:type_name -> headscale.v1.Machine + 13, // [13:13] is the sub-list for method output_type + 13, // [13:13] is the sub-list for method input_type + 13, // [13:13] is the sub-list for extension type_name + 13, // [13:13] is the sub-list for extension extendee + 0, // [0:13] is the sub-list for field type_name +} + +func init() { file_headscale_v1_machine_proto_init() } +func file_headscale_v1_machine_proto_init() { + if File_headscale_v1_machine_proto != nil { + return + } + file_headscale_v1_namespace_proto_init() + file_headscale_v1_preauthkey_proto_init() + if !protoimpl.UnsafeEnabled { + file_headscale_v1_machine_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Machine); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_headscale_v1_machine_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RegisterMachineRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_headscale_v1_machine_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RegisterMachineResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_headscale_v1_machine_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetMachineRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_headscale_v1_machine_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetMachineResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_headscale_v1_machine_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DeleteMachineRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_headscale_v1_machine_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DeleteMachineResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_headscale_v1_machine_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListMachinesRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_headscale_v1_machine_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListMachinesResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_headscale_v1_machine_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ShareMachineRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_headscale_v1_machine_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ShareMachineResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_headscale_v1_machine_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UnshareMachineRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_headscale_v1_machine_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UnshareMachineResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_headscale_v1_machine_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DebugCreateMachineRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_headscale_v1_machine_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DebugCreateMachineResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_headscale_v1_machine_proto_rawDesc, + NumEnums: 1, + NumMessages: 15, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_headscale_v1_machine_proto_goTypes, + DependencyIndexes: file_headscale_v1_machine_proto_depIdxs, + EnumInfos: file_headscale_v1_machine_proto_enumTypes, + MessageInfos: file_headscale_v1_machine_proto_msgTypes, + }.Build() + File_headscale_v1_machine_proto = out.File + file_headscale_v1_machine_proto_rawDesc = nil + file_headscale_v1_machine_proto_goTypes = nil + file_headscale_v1_machine_proto_depIdxs = nil +} diff --git a/gen/go/headscale/v1/namespace.pb.go b/gen/go/headscale/v1/namespace.pb.go new file mode 100644 index 00000000..f8af539e --- /dev/null +++ b/gen/go/headscale/v1/namespace.pb.go @@ -0,0 +1,801 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.27.1 +// protoc v3.18.1 +// source: headscale/v1/namespace.proto + +package v1 + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + timestamppb "google.golang.org/protobuf/types/known/timestamppb" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type Namespace struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + CreatedAt *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` +} + +func (x *Namespace) Reset() { + *x = Namespace{} + if protoimpl.UnsafeEnabled { + mi := &file_headscale_v1_namespace_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Namespace) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Namespace) ProtoMessage() {} + +func (x *Namespace) ProtoReflect() protoreflect.Message { + mi := &file_headscale_v1_namespace_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Namespace.ProtoReflect.Descriptor instead. +func (*Namespace) Descriptor() ([]byte, []int) { + return file_headscale_v1_namespace_proto_rawDescGZIP(), []int{0} +} + +func (x *Namespace) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *Namespace) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *Namespace) GetCreatedAt() *timestamppb.Timestamp { + if x != nil { + return x.CreatedAt + } + return nil +} + +type GetNamespaceRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` +} + +func (x *GetNamespaceRequest) Reset() { + *x = GetNamespaceRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_headscale_v1_namespace_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetNamespaceRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetNamespaceRequest) ProtoMessage() {} + +func (x *GetNamespaceRequest) ProtoReflect() protoreflect.Message { + mi := &file_headscale_v1_namespace_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetNamespaceRequest.ProtoReflect.Descriptor instead. +func (*GetNamespaceRequest) Descriptor() ([]byte, []int) { + return file_headscale_v1_namespace_proto_rawDescGZIP(), []int{1} +} + +func (x *GetNamespaceRequest) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +type GetNamespaceResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Namespace *Namespace `protobuf:"bytes,1,opt,name=namespace,proto3" json:"namespace,omitempty"` +} + +func (x *GetNamespaceResponse) Reset() { + *x = GetNamespaceResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_headscale_v1_namespace_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetNamespaceResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetNamespaceResponse) ProtoMessage() {} + +func (x *GetNamespaceResponse) ProtoReflect() protoreflect.Message { + mi := &file_headscale_v1_namespace_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetNamespaceResponse.ProtoReflect.Descriptor instead. +func (*GetNamespaceResponse) Descriptor() ([]byte, []int) { + return file_headscale_v1_namespace_proto_rawDescGZIP(), []int{2} +} + +func (x *GetNamespaceResponse) GetNamespace() *Namespace { + if x != nil { + return x.Namespace + } + return nil +} + +type CreateNamespaceRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` +} + +func (x *CreateNamespaceRequest) Reset() { + *x = CreateNamespaceRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_headscale_v1_namespace_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CreateNamespaceRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateNamespaceRequest) ProtoMessage() {} + +func (x *CreateNamespaceRequest) ProtoReflect() protoreflect.Message { + mi := &file_headscale_v1_namespace_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CreateNamespaceRequest.ProtoReflect.Descriptor instead. +func (*CreateNamespaceRequest) Descriptor() ([]byte, []int) { + return file_headscale_v1_namespace_proto_rawDescGZIP(), []int{3} +} + +func (x *CreateNamespaceRequest) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +type CreateNamespaceResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Namespace *Namespace `protobuf:"bytes,1,opt,name=namespace,proto3" json:"namespace,omitempty"` +} + +func (x *CreateNamespaceResponse) Reset() { + *x = CreateNamespaceResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_headscale_v1_namespace_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CreateNamespaceResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateNamespaceResponse) ProtoMessage() {} + +func (x *CreateNamespaceResponse) ProtoReflect() protoreflect.Message { + mi := &file_headscale_v1_namespace_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CreateNamespaceResponse.ProtoReflect.Descriptor instead. +func (*CreateNamespaceResponse) Descriptor() ([]byte, []int) { + return file_headscale_v1_namespace_proto_rawDescGZIP(), []int{4} +} + +func (x *CreateNamespaceResponse) GetNamespace() *Namespace { + if x != nil { + return x.Namespace + } + return nil +} + +type RenameNamespaceRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + OldName string `protobuf:"bytes,1,opt,name=old_name,json=oldName,proto3" json:"old_name,omitempty"` + NewName string `protobuf:"bytes,2,opt,name=new_name,json=newName,proto3" json:"new_name,omitempty"` +} + +func (x *RenameNamespaceRequest) Reset() { + *x = RenameNamespaceRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_headscale_v1_namespace_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RenameNamespaceRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RenameNamespaceRequest) ProtoMessage() {} + +func (x *RenameNamespaceRequest) ProtoReflect() protoreflect.Message { + mi := &file_headscale_v1_namespace_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RenameNamespaceRequest.ProtoReflect.Descriptor instead. +func (*RenameNamespaceRequest) Descriptor() ([]byte, []int) { + return file_headscale_v1_namespace_proto_rawDescGZIP(), []int{5} +} + +func (x *RenameNamespaceRequest) GetOldName() string { + if x != nil { + return x.OldName + } + return "" +} + +func (x *RenameNamespaceRequest) GetNewName() string { + if x != nil { + return x.NewName + } + return "" +} + +type RenameNamespaceResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Namespace *Namespace `protobuf:"bytes,1,opt,name=namespace,proto3" json:"namespace,omitempty"` +} + +func (x *RenameNamespaceResponse) Reset() { + *x = RenameNamespaceResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_headscale_v1_namespace_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RenameNamespaceResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RenameNamespaceResponse) ProtoMessage() {} + +func (x *RenameNamespaceResponse) ProtoReflect() protoreflect.Message { + mi := &file_headscale_v1_namespace_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RenameNamespaceResponse.ProtoReflect.Descriptor instead. +func (*RenameNamespaceResponse) Descriptor() ([]byte, []int) { + return file_headscale_v1_namespace_proto_rawDescGZIP(), []int{6} +} + +func (x *RenameNamespaceResponse) GetNamespace() *Namespace { + if x != nil { + return x.Namespace + } + return nil +} + +type DeleteNamespaceRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` +} + +func (x *DeleteNamespaceRequest) Reset() { + *x = DeleteNamespaceRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_headscale_v1_namespace_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DeleteNamespaceRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeleteNamespaceRequest) ProtoMessage() {} + +func (x *DeleteNamespaceRequest) ProtoReflect() protoreflect.Message { + mi := &file_headscale_v1_namespace_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DeleteNamespaceRequest.ProtoReflect.Descriptor instead. +func (*DeleteNamespaceRequest) Descriptor() ([]byte, []int) { + return file_headscale_v1_namespace_proto_rawDescGZIP(), []int{7} +} + +func (x *DeleteNamespaceRequest) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +type DeleteNamespaceResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *DeleteNamespaceResponse) Reset() { + *x = DeleteNamespaceResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_headscale_v1_namespace_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DeleteNamespaceResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeleteNamespaceResponse) ProtoMessage() {} + +func (x *DeleteNamespaceResponse) ProtoReflect() protoreflect.Message { + mi := &file_headscale_v1_namespace_proto_msgTypes[8] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DeleteNamespaceResponse.ProtoReflect.Descriptor instead. +func (*DeleteNamespaceResponse) Descriptor() ([]byte, []int) { + return file_headscale_v1_namespace_proto_rawDescGZIP(), []int{8} +} + +type ListNamespacesRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *ListNamespacesRequest) Reset() { + *x = ListNamespacesRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_headscale_v1_namespace_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListNamespacesRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListNamespacesRequest) ProtoMessage() {} + +func (x *ListNamespacesRequest) ProtoReflect() protoreflect.Message { + mi := &file_headscale_v1_namespace_proto_msgTypes[9] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListNamespacesRequest.ProtoReflect.Descriptor instead. +func (*ListNamespacesRequest) Descriptor() ([]byte, []int) { + return file_headscale_v1_namespace_proto_rawDescGZIP(), []int{9} +} + +type ListNamespacesResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Namespaces []*Namespace `protobuf:"bytes,1,rep,name=namespaces,proto3" json:"namespaces,omitempty"` +} + +func (x *ListNamespacesResponse) Reset() { + *x = ListNamespacesResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_headscale_v1_namespace_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListNamespacesResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListNamespacesResponse) ProtoMessage() {} + +func (x *ListNamespacesResponse) ProtoReflect() protoreflect.Message { + mi := &file_headscale_v1_namespace_proto_msgTypes[10] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListNamespacesResponse.ProtoReflect.Descriptor instead. +func (*ListNamespacesResponse) Descriptor() ([]byte, []int) { + return file_headscale_v1_namespace_proto_rawDescGZIP(), []int{10} +} + +func (x *ListNamespacesResponse) GetNamespaces() []*Namespace { + if x != nil { + return x.Namespaces + } + return nil +} + +var File_headscale_v1_namespace_proto protoreflect.FileDescriptor + +var file_headscale_v1_namespace_proto_rawDesc = []byte{ + 0x0a, 0x1c, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x6e, + 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0c, + 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x1a, 0x1f, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, + 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x6a, 0x0a, + 0x09, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x39, + 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, + 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x22, 0x29, 0x0a, 0x13, 0x47, 0x65, 0x74, + 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, + 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x4d, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x73, + 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x35, 0x0a, 0x09, + 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x17, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4e, + 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, + 0x61, 0x63, 0x65, 0x22, 0x2c, 0x0a, 0x16, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4e, 0x61, 0x6d, + 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, + 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, + 0x65, 0x22, 0x50, 0x0a, 0x17, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, + 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x35, 0x0a, 0x09, + 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x17, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4e, + 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, + 0x61, 0x63, 0x65, 0x22, 0x4e, 0x0a, 0x16, 0x52, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x4e, 0x61, 0x6d, + 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x19, 0x0a, + 0x08, 0x6f, 0x6c, 0x64, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x07, 0x6f, 0x6c, 0x64, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x6e, 0x65, 0x77, 0x5f, + 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6e, 0x65, 0x77, 0x4e, + 0x61, 0x6d, 0x65, 0x22, 0x50, 0x0a, 0x17, 0x52, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x4e, 0x61, 0x6d, + 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x35, + 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x17, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, + 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, + 0x73, 0x70, 0x61, 0x63, 0x65, 0x22, 0x2c, 0x0a, 0x16, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4e, + 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x22, 0x19, 0x0a, 0x17, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4e, 0x61, 0x6d, + 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x17, + 0x0a, 0x15, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x51, 0x0a, 0x16, 0x4c, 0x69, 0x73, 0x74, 0x4e, + 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x37, 0x0a, 0x0a, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x18, + 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, + 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x0a, + 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x42, 0x29, 0x5a, 0x27, 0x67, 0x69, + 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6a, 0x75, 0x61, 0x6e, 0x66, 0x6f, 0x6e, + 0x74, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2f, 0x67, 0x65, 0x6e, 0x2f, + 0x67, 0x6f, 0x2f, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_headscale_v1_namespace_proto_rawDescOnce sync.Once + file_headscale_v1_namespace_proto_rawDescData = file_headscale_v1_namespace_proto_rawDesc +) + +func file_headscale_v1_namespace_proto_rawDescGZIP() []byte { + file_headscale_v1_namespace_proto_rawDescOnce.Do(func() { + file_headscale_v1_namespace_proto_rawDescData = protoimpl.X.CompressGZIP(file_headscale_v1_namespace_proto_rawDescData) + }) + return file_headscale_v1_namespace_proto_rawDescData +} + +var file_headscale_v1_namespace_proto_msgTypes = make([]protoimpl.MessageInfo, 11) +var file_headscale_v1_namespace_proto_goTypes = []interface{}{ + (*Namespace)(nil), // 0: headscale.v1.Namespace + (*GetNamespaceRequest)(nil), // 1: headscale.v1.GetNamespaceRequest + (*GetNamespaceResponse)(nil), // 2: headscale.v1.GetNamespaceResponse + (*CreateNamespaceRequest)(nil), // 3: headscale.v1.CreateNamespaceRequest + (*CreateNamespaceResponse)(nil), // 4: headscale.v1.CreateNamespaceResponse + (*RenameNamespaceRequest)(nil), // 5: headscale.v1.RenameNamespaceRequest + (*RenameNamespaceResponse)(nil), // 6: headscale.v1.RenameNamespaceResponse + (*DeleteNamespaceRequest)(nil), // 7: headscale.v1.DeleteNamespaceRequest + (*DeleteNamespaceResponse)(nil), // 8: headscale.v1.DeleteNamespaceResponse + (*ListNamespacesRequest)(nil), // 9: headscale.v1.ListNamespacesRequest + (*ListNamespacesResponse)(nil), // 10: headscale.v1.ListNamespacesResponse + (*timestamppb.Timestamp)(nil), // 11: google.protobuf.Timestamp +} +var file_headscale_v1_namespace_proto_depIdxs = []int32{ + 11, // 0: headscale.v1.Namespace.created_at:type_name -> google.protobuf.Timestamp + 0, // 1: headscale.v1.GetNamespaceResponse.namespace:type_name -> headscale.v1.Namespace + 0, // 2: headscale.v1.CreateNamespaceResponse.namespace:type_name -> headscale.v1.Namespace + 0, // 3: headscale.v1.RenameNamespaceResponse.namespace:type_name -> headscale.v1.Namespace + 0, // 4: headscale.v1.ListNamespacesResponse.namespaces:type_name -> headscale.v1.Namespace + 5, // [5:5] is the sub-list for method output_type + 5, // [5:5] is the sub-list for method input_type + 5, // [5:5] is the sub-list for extension type_name + 5, // [5:5] is the sub-list for extension extendee + 0, // [0:5] is the sub-list for field type_name +} + +func init() { file_headscale_v1_namespace_proto_init() } +func file_headscale_v1_namespace_proto_init() { + if File_headscale_v1_namespace_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_headscale_v1_namespace_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Namespace); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_headscale_v1_namespace_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetNamespaceRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_headscale_v1_namespace_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetNamespaceResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_headscale_v1_namespace_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CreateNamespaceRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_headscale_v1_namespace_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CreateNamespaceResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_headscale_v1_namespace_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RenameNamespaceRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_headscale_v1_namespace_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RenameNamespaceResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_headscale_v1_namespace_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DeleteNamespaceRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_headscale_v1_namespace_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DeleteNamespaceResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_headscale_v1_namespace_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListNamespacesRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_headscale_v1_namespace_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListNamespacesResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_headscale_v1_namespace_proto_rawDesc, + NumEnums: 0, + NumMessages: 11, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_headscale_v1_namespace_proto_goTypes, + DependencyIndexes: file_headscale_v1_namespace_proto_depIdxs, + MessageInfos: file_headscale_v1_namespace_proto_msgTypes, + }.Build() + File_headscale_v1_namespace_proto = out.File + file_headscale_v1_namespace_proto_rawDesc = nil + file_headscale_v1_namespace_proto_goTypes = nil + file_headscale_v1_namespace_proto_depIdxs = nil +} diff --git a/gen/go/headscale/v1/preauthkey.pb.go b/gen/go/headscale/v1/preauthkey.pb.go new file mode 100644 index 00000000..a94befdf --- /dev/null +++ b/gen/go/headscale/v1/preauthkey.pb.go @@ -0,0 +1,640 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.27.1 +// protoc v3.18.1 +// source: headscale/v1/preauthkey.proto + +package v1 + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + timestamppb "google.golang.org/protobuf/types/known/timestamppb" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type PreAuthKey struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Namespace string `protobuf:"bytes,1,opt,name=namespace,proto3" json:"namespace,omitempty"` + Id string `protobuf:"bytes,2,opt,name=id,proto3" json:"id,omitempty"` + Key string `protobuf:"bytes,3,opt,name=key,proto3" json:"key,omitempty"` + Resuable bool `protobuf:"varint,4,opt,name=resuable,proto3" json:"resuable,omitempty"` + Ephemeral bool `protobuf:"varint,5,opt,name=ephemeral,proto3" json:"ephemeral,omitempty"` + Used bool `protobuf:"varint,6,opt,name=used,proto3" json:"used,omitempty"` + Expiration *timestamppb.Timestamp `protobuf:"bytes,7,opt,name=expiration,proto3" json:"expiration,omitempty"` + CreatedAt *timestamppb.Timestamp `protobuf:"bytes,8,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` +} + +func (x *PreAuthKey) Reset() { + *x = PreAuthKey{} + if protoimpl.UnsafeEnabled { + mi := &file_headscale_v1_preauthkey_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PreAuthKey) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PreAuthKey) ProtoMessage() {} + +func (x *PreAuthKey) ProtoReflect() protoreflect.Message { + mi := &file_headscale_v1_preauthkey_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PreAuthKey.ProtoReflect.Descriptor instead. +func (*PreAuthKey) Descriptor() ([]byte, []int) { + return file_headscale_v1_preauthkey_proto_rawDescGZIP(), []int{0} +} + +func (x *PreAuthKey) GetNamespace() string { + if x != nil { + return x.Namespace + } + return "" +} + +func (x *PreAuthKey) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *PreAuthKey) GetKey() string { + if x != nil { + return x.Key + } + return "" +} + +func (x *PreAuthKey) GetResuable() bool { + if x != nil { + return x.Resuable + } + return false +} + +func (x *PreAuthKey) GetEphemeral() bool { + if x != nil { + return x.Ephemeral + } + return false +} + +func (x *PreAuthKey) GetUsed() bool { + if x != nil { + return x.Used + } + return false +} + +func (x *PreAuthKey) GetExpiration() *timestamppb.Timestamp { + if x != nil { + return x.Expiration + } + return nil +} + +func (x *PreAuthKey) GetCreatedAt() *timestamppb.Timestamp { + if x != nil { + return x.CreatedAt + } + return nil +} + +type CreatePreAuthKeyRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Namespace string `protobuf:"bytes,1,opt,name=namespace,proto3" json:"namespace,omitempty"` + Resuable bool `protobuf:"varint,2,opt,name=resuable,proto3" json:"resuable,omitempty"` + Ephemeral bool `protobuf:"varint,3,opt,name=ephemeral,proto3" json:"ephemeral,omitempty"` + Expiration *timestamppb.Timestamp `protobuf:"bytes,4,opt,name=expiration,proto3" json:"expiration,omitempty"` +} + +func (x *CreatePreAuthKeyRequest) Reset() { + *x = CreatePreAuthKeyRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_headscale_v1_preauthkey_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CreatePreAuthKeyRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreatePreAuthKeyRequest) ProtoMessage() {} + +func (x *CreatePreAuthKeyRequest) ProtoReflect() protoreflect.Message { + mi := &file_headscale_v1_preauthkey_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CreatePreAuthKeyRequest.ProtoReflect.Descriptor instead. +func (*CreatePreAuthKeyRequest) Descriptor() ([]byte, []int) { + return file_headscale_v1_preauthkey_proto_rawDescGZIP(), []int{1} +} + +func (x *CreatePreAuthKeyRequest) GetNamespace() string { + if x != nil { + return x.Namespace + } + return "" +} + +func (x *CreatePreAuthKeyRequest) GetResuable() bool { + if x != nil { + return x.Resuable + } + return false +} + +func (x *CreatePreAuthKeyRequest) GetEphemeral() bool { + if x != nil { + return x.Ephemeral + } + return false +} + +func (x *CreatePreAuthKeyRequest) GetExpiration() *timestamppb.Timestamp { + if x != nil { + return x.Expiration + } + return nil +} + +type CreatePreAuthKeyResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + PreAuthKey *PreAuthKey `protobuf:"bytes,1,opt,name=pre_auth_key,json=preAuthKey,proto3" json:"pre_auth_key,omitempty"` +} + +func (x *CreatePreAuthKeyResponse) Reset() { + *x = CreatePreAuthKeyResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_headscale_v1_preauthkey_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CreatePreAuthKeyResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreatePreAuthKeyResponse) ProtoMessage() {} + +func (x *CreatePreAuthKeyResponse) ProtoReflect() protoreflect.Message { + mi := &file_headscale_v1_preauthkey_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CreatePreAuthKeyResponse.ProtoReflect.Descriptor instead. +func (*CreatePreAuthKeyResponse) Descriptor() ([]byte, []int) { + return file_headscale_v1_preauthkey_proto_rawDescGZIP(), []int{2} +} + +func (x *CreatePreAuthKeyResponse) GetPreAuthKey() *PreAuthKey { + if x != nil { + return x.PreAuthKey + } + return nil +} + +type ExpirePreAuthKeyRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Namespace string `protobuf:"bytes,1,opt,name=namespace,proto3" json:"namespace,omitempty"` + Key string `protobuf:"bytes,2,opt,name=key,proto3" json:"key,omitempty"` +} + +func (x *ExpirePreAuthKeyRequest) Reset() { + *x = ExpirePreAuthKeyRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_headscale_v1_preauthkey_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ExpirePreAuthKeyRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ExpirePreAuthKeyRequest) ProtoMessage() {} + +func (x *ExpirePreAuthKeyRequest) ProtoReflect() protoreflect.Message { + mi := &file_headscale_v1_preauthkey_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ExpirePreAuthKeyRequest.ProtoReflect.Descriptor instead. +func (*ExpirePreAuthKeyRequest) Descriptor() ([]byte, []int) { + return file_headscale_v1_preauthkey_proto_rawDescGZIP(), []int{3} +} + +func (x *ExpirePreAuthKeyRequest) GetNamespace() string { + if x != nil { + return x.Namespace + } + return "" +} + +func (x *ExpirePreAuthKeyRequest) GetKey() string { + if x != nil { + return x.Key + } + return "" +} + +type ExpirePreAuthKeyResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *ExpirePreAuthKeyResponse) Reset() { + *x = ExpirePreAuthKeyResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_headscale_v1_preauthkey_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ExpirePreAuthKeyResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ExpirePreAuthKeyResponse) ProtoMessage() {} + +func (x *ExpirePreAuthKeyResponse) ProtoReflect() protoreflect.Message { + mi := &file_headscale_v1_preauthkey_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ExpirePreAuthKeyResponse.ProtoReflect.Descriptor instead. +func (*ExpirePreAuthKeyResponse) Descriptor() ([]byte, []int) { + return file_headscale_v1_preauthkey_proto_rawDescGZIP(), []int{4} +} + +type ListPreAuthKeysRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Namespace string `protobuf:"bytes,1,opt,name=namespace,proto3" json:"namespace,omitempty"` +} + +func (x *ListPreAuthKeysRequest) Reset() { + *x = ListPreAuthKeysRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_headscale_v1_preauthkey_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListPreAuthKeysRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListPreAuthKeysRequest) ProtoMessage() {} + +func (x *ListPreAuthKeysRequest) ProtoReflect() protoreflect.Message { + mi := &file_headscale_v1_preauthkey_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListPreAuthKeysRequest.ProtoReflect.Descriptor instead. +func (*ListPreAuthKeysRequest) Descriptor() ([]byte, []int) { + return file_headscale_v1_preauthkey_proto_rawDescGZIP(), []int{5} +} + +func (x *ListPreAuthKeysRequest) GetNamespace() string { + if x != nil { + return x.Namespace + } + return "" +} + +type ListPreAuthKeysResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + PreAuthKeys []*PreAuthKey `protobuf:"bytes,1,rep,name=pre_auth_keys,json=preAuthKeys,proto3" json:"pre_auth_keys,omitempty"` +} + +func (x *ListPreAuthKeysResponse) Reset() { + *x = ListPreAuthKeysResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_headscale_v1_preauthkey_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListPreAuthKeysResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListPreAuthKeysResponse) ProtoMessage() {} + +func (x *ListPreAuthKeysResponse) ProtoReflect() protoreflect.Message { + mi := &file_headscale_v1_preauthkey_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListPreAuthKeysResponse.ProtoReflect.Descriptor instead. +func (*ListPreAuthKeysResponse) Descriptor() ([]byte, []int) { + return file_headscale_v1_preauthkey_proto_rawDescGZIP(), []int{6} +} + +func (x *ListPreAuthKeysResponse) GetPreAuthKeys() []*PreAuthKey { + if x != nil { + return x.PreAuthKeys + } + return nil +} + +var File_headscale_v1_preauthkey_proto protoreflect.FileDescriptor + +var file_headscale_v1_preauthkey_proto_rawDesc = []byte{ + 0x0a, 0x1d, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x70, + 0x72, 0x65, 0x61, 0x75, 0x74, 0x68, 0x6b, 0x65, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, + 0x0c, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x1a, 0x1f, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, + 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x91, + 0x02, 0x0a, 0x0a, 0x50, 0x72, 0x65, 0x41, 0x75, 0x74, 0x68, 0x4b, 0x65, 0x79, 0x12, 0x1c, 0x0a, + 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, + 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x6b, + 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x1a, 0x0a, + 0x08, 0x72, 0x65, 0x73, 0x75, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x08, 0x72, 0x65, 0x73, 0x75, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x65, 0x70, 0x68, + 0x65, 0x6d, 0x65, 0x72, 0x61, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x65, 0x70, + 0x68, 0x65, 0x6d, 0x65, 0x72, 0x61, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x64, 0x18, + 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x04, 0x75, 0x73, 0x65, 0x64, 0x12, 0x3a, 0x0a, 0x0a, 0x65, + 0x78, 0x70, 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0a, 0x65, 0x78, 0x70, + 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, + 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, + 0x41, 0x74, 0x22, 0xad, 0x01, 0x0a, 0x17, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x72, 0x65, + 0x41, 0x75, 0x74, 0x68, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, + 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x1a, 0x0a, 0x08, + 0x72, 0x65, 0x73, 0x75, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, + 0x72, 0x65, 0x73, 0x75, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x65, 0x70, 0x68, 0x65, + 0x6d, 0x65, 0x72, 0x61, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x65, 0x70, 0x68, + 0x65, 0x6d, 0x65, 0x72, 0x61, 0x6c, 0x12, 0x3a, 0x0a, 0x0a, 0x65, 0x78, 0x70, 0x69, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, + 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0a, 0x65, 0x78, 0x70, 0x69, 0x72, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x22, 0x56, 0x0a, 0x18, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x72, 0x65, 0x41, + 0x75, 0x74, 0x68, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3a, + 0x0a, 0x0c, 0x70, 0x72, 0x65, 0x5f, 0x61, 0x75, 0x74, 0x68, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, + 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x65, 0x41, 0x75, 0x74, 0x68, 0x4b, 0x65, 0x79, 0x52, 0x0a, + 0x70, 0x72, 0x65, 0x41, 0x75, 0x74, 0x68, 0x4b, 0x65, 0x79, 0x22, 0x49, 0x0a, 0x17, 0x45, 0x78, + 0x70, 0x69, 0x72, 0x65, 0x50, 0x72, 0x65, 0x41, 0x75, 0x74, 0x68, 0x4b, 0x65, 0x79, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, + 0x61, 0x63, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x03, 0x6b, 0x65, 0x79, 0x22, 0x1a, 0x0a, 0x18, 0x45, 0x78, 0x70, 0x69, 0x72, 0x65, 0x50, + 0x72, 0x65, 0x41, 0x75, 0x74, 0x68, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x36, 0x0a, 0x16, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x65, 0x41, 0x75, 0x74, 0x68, + 0x4b, 0x65, 0x79, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x6e, + 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, + 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x22, 0x57, 0x0a, 0x17, 0x4c, 0x69, 0x73, + 0x74, 0x50, 0x72, 0x65, 0x41, 0x75, 0x74, 0x68, 0x4b, 0x65, 0x79, 0x73, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3c, 0x0a, 0x0d, 0x70, 0x72, 0x65, 0x5f, 0x61, 0x75, 0x74, 0x68, + 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x68, 0x65, + 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x65, 0x41, 0x75, + 0x74, 0x68, 0x4b, 0x65, 0x79, 0x52, 0x0b, 0x70, 0x72, 0x65, 0x41, 0x75, 0x74, 0x68, 0x4b, 0x65, + 0x79, 0x73, 0x42, 0x29, 0x5a, 0x27, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, + 0x2f, 0x6a, 0x75, 0x61, 0x6e, 0x66, 0x6f, 0x6e, 0x74, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, + 0x61, 0x6c, 0x65, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x67, 0x6f, 0x2f, 0x76, 0x31, 0x62, 0x06, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_headscale_v1_preauthkey_proto_rawDescOnce sync.Once + file_headscale_v1_preauthkey_proto_rawDescData = file_headscale_v1_preauthkey_proto_rawDesc +) + +func file_headscale_v1_preauthkey_proto_rawDescGZIP() []byte { + file_headscale_v1_preauthkey_proto_rawDescOnce.Do(func() { + file_headscale_v1_preauthkey_proto_rawDescData = protoimpl.X.CompressGZIP(file_headscale_v1_preauthkey_proto_rawDescData) + }) + return file_headscale_v1_preauthkey_proto_rawDescData +} + +var file_headscale_v1_preauthkey_proto_msgTypes = make([]protoimpl.MessageInfo, 7) +var file_headscale_v1_preauthkey_proto_goTypes = []interface{}{ + (*PreAuthKey)(nil), // 0: headscale.v1.PreAuthKey + (*CreatePreAuthKeyRequest)(nil), // 1: headscale.v1.CreatePreAuthKeyRequest + (*CreatePreAuthKeyResponse)(nil), // 2: headscale.v1.CreatePreAuthKeyResponse + (*ExpirePreAuthKeyRequest)(nil), // 3: headscale.v1.ExpirePreAuthKeyRequest + (*ExpirePreAuthKeyResponse)(nil), // 4: headscale.v1.ExpirePreAuthKeyResponse + (*ListPreAuthKeysRequest)(nil), // 5: headscale.v1.ListPreAuthKeysRequest + (*ListPreAuthKeysResponse)(nil), // 6: headscale.v1.ListPreAuthKeysResponse + (*timestamppb.Timestamp)(nil), // 7: google.protobuf.Timestamp +} +var file_headscale_v1_preauthkey_proto_depIdxs = []int32{ + 7, // 0: headscale.v1.PreAuthKey.expiration:type_name -> google.protobuf.Timestamp + 7, // 1: headscale.v1.PreAuthKey.created_at:type_name -> google.protobuf.Timestamp + 7, // 2: headscale.v1.CreatePreAuthKeyRequest.expiration:type_name -> google.protobuf.Timestamp + 0, // 3: headscale.v1.CreatePreAuthKeyResponse.pre_auth_key:type_name -> headscale.v1.PreAuthKey + 0, // 4: headscale.v1.ListPreAuthKeysResponse.pre_auth_keys:type_name -> headscale.v1.PreAuthKey + 5, // [5:5] is the sub-list for method output_type + 5, // [5:5] is the sub-list for method input_type + 5, // [5:5] is the sub-list for extension type_name + 5, // [5:5] is the sub-list for extension extendee + 0, // [0:5] is the sub-list for field type_name +} + +func init() { file_headscale_v1_preauthkey_proto_init() } +func file_headscale_v1_preauthkey_proto_init() { + if File_headscale_v1_preauthkey_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_headscale_v1_preauthkey_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PreAuthKey); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_headscale_v1_preauthkey_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CreatePreAuthKeyRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_headscale_v1_preauthkey_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CreatePreAuthKeyResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_headscale_v1_preauthkey_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ExpirePreAuthKeyRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_headscale_v1_preauthkey_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ExpirePreAuthKeyResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_headscale_v1_preauthkey_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListPreAuthKeysRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_headscale_v1_preauthkey_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListPreAuthKeysResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_headscale_v1_preauthkey_proto_rawDesc, + NumEnums: 0, + NumMessages: 7, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_headscale_v1_preauthkey_proto_goTypes, + DependencyIndexes: file_headscale_v1_preauthkey_proto_depIdxs, + MessageInfos: file_headscale_v1_preauthkey_proto_msgTypes, + }.Build() + File_headscale_v1_preauthkey_proto = out.File + file_headscale_v1_preauthkey_proto_rawDesc = nil + file_headscale_v1_preauthkey_proto_goTypes = nil + file_headscale_v1_preauthkey_proto_depIdxs = nil +} diff --git a/gen/go/headscale/v1/routes.pb.go b/gen/go/headscale/v1/routes.pb.go new file mode 100644 index 00000000..e32e1d15 --- /dev/null +++ b/gen/go/headscale/v1/routes.pb.go @@ -0,0 +1,424 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.27.1 +// protoc v3.18.1 +// source: headscale/v1/routes.proto + +package v1 + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type Routes struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + AdvertisedRoutes []string `protobuf:"bytes,1,rep,name=advertised_routes,json=advertisedRoutes,proto3" json:"advertised_routes,omitempty"` + EnabledRoutes []string `protobuf:"bytes,2,rep,name=enabled_routes,json=enabledRoutes,proto3" json:"enabled_routes,omitempty"` +} + +func (x *Routes) Reset() { + *x = Routes{} + if protoimpl.UnsafeEnabled { + mi := &file_headscale_v1_routes_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Routes) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Routes) ProtoMessage() {} + +func (x *Routes) ProtoReflect() protoreflect.Message { + mi := &file_headscale_v1_routes_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Routes.ProtoReflect.Descriptor instead. +func (*Routes) Descriptor() ([]byte, []int) { + return file_headscale_v1_routes_proto_rawDescGZIP(), []int{0} +} + +func (x *Routes) GetAdvertisedRoutes() []string { + if x != nil { + return x.AdvertisedRoutes + } + return nil +} + +func (x *Routes) GetEnabledRoutes() []string { + if x != nil { + return x.EnabledRoutes + } + return nil +} + +type GetMachineRouteRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + MachineId uint64 `protobuf:"varint,1,opt,name=machine_id,json=machineId,proto3" json:"machine_id,omitempty"` +} + +func (x *GetMachineRouteRequest) Reset() { + *x = GetMachineRouteRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_headscale_v1_routes_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetMachineRouteRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetMachineRouteRequest) ProtoMessage() {} + +func (x *GetMachineRouteRequest) ProtoReflect() protoreflect.Message { + mi := &file_headscale_v1_routes_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetMachineRouteRequest.ProtoReflect.Descriptor instead. +func (*GetMachineRouteRequest) Descriptor() ([]byte, []int) { + return file_headscale_v1_routes_proto_rawDescGZIP(), []int{1} +} + +func (x *GetMachineRouteRequest) GetMachineId() uint64 { + if x != nil { + return x.MachineId + } + return 0 +} + +type GetMachineRouteResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Routes *Routes `protobuf:"bytes,1,opt,name=routes,proto3" json:"routes,omitempty"` +} + +func (x *GetMachineRouteResponse) Reset() { + *x = GetMachineRouteResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_headscale_v1_routes_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetMachineRouteResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetMachineRouteResponse) ProtoMessage() {} + +func (x *GetMachineRouteResponse) ProtoReflect() protoreflect.Message { + mi := &file_headscale_v1_routes_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetMachineRouteResponse.ProtoReflect.Descriptor instead. +func (*GetMachineRouteResponse) Descriptor() ([]byte, []int) { + return file_headscale_v1_routes_proto_rawDescGZIP(), []int{2} +} + +func (x *GetMachineRouteResponse) GetRoutes() *Routes { + if x != nil { + return x.Routes + } + return nil +} + +type EnableMachineRoutesRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + MachineId uint64 `protobuf:"varint,1,opt,name=machine_id,json=machineId,proto3" json:"machine_id,omitempty"` + Routes []string `protobuf:"bytes,2,rep,name=routes,proto3" json:"routes,omitempty"` +} + +func (x *EnableMachineRoutesRequest) Reset() { + *x = EnableMachineRoutesRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_headscale_v1_routes_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *EnableMachineRoutesRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*EnableMachineRoutesRequest) ProtoMessage() {} + +func (x *EnableMachineRoutesRequest) ProtoReflect() protoreflect.Message { + mi := &file_headscale_v1_routes_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use EnableMachineRoutesRequest.ProtoReflect.Descriptor instead. +func (*EnableMachineRoutesRequest) Descriptor() ([]byte, []int) { + return file_headscale_v1_routes_proto_rawDescGZIP(), []int{3} +} + +func (x *EnableMachineRoutesRequest) GetMachineId() uint64 { + if x != nil { + return x.MachineId + } + return 0 +} + +func (x *EnableMachineRoutesRequest) GetRoutes() []string { + if x != nil { + return x.Routes + } + return nil +} + +type EnableMachineRoutesResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Routes *Routes `protobuf:"bytes,1,opt,name=routes,proto3" json:"routes,omitempty"` +} + +func (x *EnableMachineRoutesResponse) Reset() { + *x = EnableMachineRoutesResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_headscale_v1_routes_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *EnableMachineRoutesResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*EnableMachineRoutesResponse) ProtoMessage() {} + +func (x *EnableMachineRoutesResponse) ProtoReflect() protoreflect.Message { + mi := &file_headscale_v1_routes_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use EnableMachineRoutesResponse.ProtoReflect.Descriptor instead. +func (*EnableMachineRoutesResponse) Descriptor() ([]byte, []int) { + return file_headscale_v1_routes_proto_rawDescGZIP(), []int{4} +} + +func (x *EnableMachineRoutesResponse) GetRoutes() *Routes { + if x != nil { + return x.Routes + } + return nil +} + +var File_headscale_v1_routes_proto protoreflect.FileDescriptor + +var file_headscale_v1_routes_proto_rawDesc = []byte{ + 0x0a, 0x19, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x72, + 0x6f, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0c, 0x68, 0x65, 0x61, + 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x22, 0x5c, 0x0a, 0x06, 0x52, 0x6f, 0x75, + 0x74, 0x65, 0x73, 0x12, 0x2b, 0x0a, 0x11, 0x61, 0x64, 0x76, 0x65, 0x72, 0x74, 0x69, 0x73, 0x65, + 0x64, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, + 0x61, 0x64, 0x76, 0x65, 0x72, 0x74, 0x69, 0x73, 0x65, 0x64, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, + 0x12, 0x25, 0x0a, 0x0e, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x5f, 0x72, 0x6f, 0x75, 0x74, + 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, + 0x64, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x22, 0x37, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x4d, 0x61, + 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x5f, 0x69, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x49, 0x64, + 0x22, 0x47, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x6f, + 0x75, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2c, 0x0a, 0x06, 0x72, + 0x6f, 0x75, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x68, 0x65, + 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x65, + 0x73, 0x52, 0x06, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x22, 0x53, 0x0a, 0x1a, 0x45, 0x6e, 0x61, + 0x62, 0x6c, 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x6d, 0x61, 0x63, 0x68, 0x69, + 0x6e, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x6d, 0x61, 0x63, + 0x68, 0x69, 0x6e, 0x65, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x73, + 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x22, 0x4b, + 0x0a, 0x1b, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, + 0x6f, 0x75, 0x74, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2c, 0x0a, + 0x06, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, + 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x6f, 0x75, + 0x74, 0x65, 0x73, 0x52, 0x06, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x42, 0x29, 0x5a, 0x27, 0x67, + 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6a, 0x75, 0x61, 0x6e, 0x66, 0x6f, + 0x6e, 0x74, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2f, 0x67, 0x65, 0x6e, + 0x2f, 0x67, 0x6f, 0x2f, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_headscale_v1_routes_proto_rawDescOnce sync.Once + file_headscale_v1_routes_proto_rawDescData = file_headscale_v1_routes_proto_rawDesc +) + +func file_headscale_v1_routes_proto_rawDescGZIP() []byte { + file_headscale_v1_routes_proto_rawDescOnce.Do(func() { + file_headscale_v1_routes_proto_rawDescData = protoimpl.X.CompressGZIP(file_headscale_v1_routes_proto_rawDescData) + }) + return file_headscale_v1_routes_proto_rawDescData +} + +var file_headscale_v1_routes_proto_msgTypes = make([]protoimpl.MessageInfo, 5) +var file_headscale_v1_routes_proto_goTypes = []interface{}{ + (*Routes)(nil), // 0: headscale.v1.Routes + (*GetMachineRouteRequest)(nil), // 1: headscale.v1.GetMachineRouteRequest + (*GetMachineRouteResponse)(nil), // 2: headscale.v1.GetMachineRouteResponse + (*EnableMachineRoutesRequest)(nil), // 3: headscale.v1.EnableMachineRoutesRequest + (*EnableMachineRoutesResponse)(nil), // 4: headscale.v1.EnableMachineRoutesResponse +} +var file_headscale_v1_routes_proto_depIdxs = []int32{ + 0, // 0: headscale.v1.GetMachineRouteResponse.routes:type_name -> headscale.v1.Routes + 0, // 1: headscale.v1.EnableMachineRoutesResponse.routes:type_name -> headscale.v1.Routes + 2, // [2:2] is the sub-list for method output_type + 2, // [2:2] is the sub-list for method input_type + 2, // [2:2] is the sub-list for extension type_name + 2, // [2:2] is the sub-list for extension extendee + 0, // [0:2] is the sub-list for field type_name +} + +func init() { file_headscale_v1_routes_proto_init() } +func file_headscale_v1_routes_proto_init() { + if File_headscale_v1_routes_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_headscale_v1_routes_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Routes); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_headscale_v1_routes_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetMachineRouteRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_headscale_v1_routes_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetMachineRouteResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_headscale_v1_routes_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*EnableMachineRoutesRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_headscale_v1_routes_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*EnableMachineRoutesResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_headscale_v1_routes_proto_rawDesc, + NumEnums: 0, + NumMessages: 5, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_headscale_v1_routes_proto_goTypes, + DependencyIndexes: file_headscale_v1_routes_proto_depIdxs, + MessageInfos: file_headscale_v1_routes_proto_msgTypes, + }.Build() + File_headscale_v1_routes_proto = out.File + file_headscale_v1_routes_proto_rawDesc = nil + file_headscale_v1_routes_proto_goTypes = nil + file_headscale_v1_routes_proto_depIdxs = nil +} diff --git a/gen/openapiv2/headscale/v1/device.swagger.json b/gen/openapiv2/headscale/v1/device.swagger.json new file mode 100644 index 00000000..5360527a --- /dev/null +++ b/gen/openapiv2/headscale/v1/device.swagger.json @@ -0,0 +1,43 @@ +{ + "swagger": "2.0", + "info": { + "title": "headscale/v1/device.proto", + "version": "version not set" + }, + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "paths": {}, + "definitions": { + "protobufAny": { + "type": "object", + "properties": { + "@type": { + "type": "string" + } + }, + "additionalProperties": {} + }, + "rpcStatus": { + "type": "object", + "properties": { + "code": { + "type": "integer", + "format": "int32" + }, + "message": { + "type": "string" + }, + "details": { + "type": "array", + "items": { + "$ref": "#/definitions/protobufAny" + } + } + } + } + } +} diff --git a/gen/openapiv2/headscale/v1/headscale.swagger.json b/gen/openapiv2/headscale/v1/headscale.swagger.json index 567a921f..b838635e 100644 --- a/gen/openapiv2/headscale/v1/headscale.swagger.json +++ b/gen/openapiv2/headscale/v1/headscale.swagger.json @@ -16,6 +16,91 @@ "application/json" ], "paths": { + "/api/v1/debug/machine": { + "post": { + "summary": "--- Machine start ---", + "operationId": "HeadscaleService_DebugCreateMachine", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1DebugCreateMachineResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1DebugCreateMachineRequest" + } + } + ], + "tags": [ + "HeadscaleService" + ] + } + }, + "/api/v1/machine": { + "get": { + "operationId": "HeadscaleService_ListMachines", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ListMachinesResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "namespace", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "HeadscaleService" + ] + } + }, + "/api/v1/machine/register": { + "post": { + "operationId": "HeadscaleService_RegisterMachine", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1RegisterMachineResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "tags": [ + "HeadscaleService" + ] + } + }, "/api/v1/machine/{machineId}": { "get": { "operationId": "HeadscaleService_GetMachine", @@ -45,6 +130,170 @@ "tags": [ "HeadscaleService" ] + }, + "delete": { + "operationId": "HeadscaleService_DeleteMachine", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1DeleteMachineResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "machineId", + "in": "path", + "required": true, + "type": "string", + "format": "uint64" + } + ], + "tags": [ + "HeadscaleService" + ] + } + }, + "/api/v1/machine/{machineId}/routes": { + "get": { + "summary": "--- Route start ---", + "operationId": "HeadscaleService_GetMachineRoute", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1GetMachineRouteResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "machineId", + "in": "path", + "required": true, + "type": "string", + "format": "uint64" + } + ], + "tags": [ + "HeadscaleService" + ] + }, + "post": { + "operationId": "HeadscaleService_EnableMachineRoutes", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1EnableMachineRoutesResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "machineId", + "in": "path", + "required": true, + "type": "string", + "format": "uint64" + } + ], + "tags": [ + "HeadscaleService" + ] + } + }, + "/api/v1/machine/{machineId}/share/{namespace}": { + "post": { + "operationId": "HeadscaleService_ShareMachine", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ShareMachineResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "machineId", + "in": "path", + "required": true, + "type": "string", + "format": "uint64" + }, + { + "name": "namespace", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "HeadscaleService" + ] + } + }, + "/api/v1/machine/{machineId}/unshare/{namespace}": { + "post": { + "operationId": "HeadscaleService_UnshareMachine", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1UnshareMachineResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "machineId", + "in": "path", + "required": true, + "type": "string", + "format": "uint64" + }, + { + "name": "namespace", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "HeadscaleService" + ] } }, "/api/v1/namespace": { @@ -68,34 +317,6 @@ "HeadscaleService" ] }, - "delete": { - "operationId": "HeadscaleService_DeleteNamespace", - "responses": { - "200": { - "description": "A successful response.", - "schema": { - "$ref": "#/definitions/v1DeleteNamespaceResponse" - } - }, - "default": { - "description": "An unexpected error response.", - "schema": { - "$ref": "#/definitions/rpcStatus" - } - } - }, - "parameters": [ - { - "name": "name", - "in": "query", - "required": false, - "type": "string" - } - ], - "tags": [ - "HeadscaleService" - ] - }, "post": { "operationId": "HeadscaleService_CreateNamespace", "responses": { @@ -126,6 +347,194 @@ "HeadscaleService" ] } + }, + "/api/v1/namespace/{name}": { + "get": { + "summary": "--- Namespace start ---", + "operationId": "HeadscaleService_GetNamespace", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1GetNamespaceResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "name", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "HeadscaleService" + ] + }, + "delete": { + "operationId": "HeadscaleService_DeleteNamespace", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1DeleteNamespaceResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "name", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "HeadscaleService" + ] + } + }, + "/api/v1/namespace/{oldName}/rename/{newName}": { + "post": { + "operationId": "HeadscaleService_RenameNamespace", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1RenameNamespaceResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "oldName", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "newName", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "HeadscaleService" + ] + } + }, + "/api/v1/preauthkey": { + "get": { + "operationId": "HeadscaleService_ListPreAuthKeys", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ListPreAuthKeysResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "namespace", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "HeadscaleService" + ] + }, + "post": { + "summary": "--- PreAuthKeys start ---", + "operationId": "HeadscaleService_CreatePreAuthKey", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1CreatePreAuthKeyResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1CreatePreAuthKeyRequest" + } + } + ], + "tags": [ + "HeadscaleService" + ] + } + }, + "/api/v1/preauthkey/expire": { + "post": { + "operationId": "HeadscaleService_ExpirePreAuthKey", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ExpirePreAuthKeyResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1ExpirePreAuthKeyRequest" + } + } + ], + "tags": [ + "HeadscaleService" + ] + } } }, "definitions": { @@ -167,15 +576,151 @@ "v1CreateNamespaceResponse": { "type": "object", "properties": { - "name": { - "type": "string" + "namespace": { + "$ref": "#/definitions/v1Namespace" } } }, + "v1CreatePreAuthKeyRequest": { + "type": "object", + "properties": { + "namespace": { + "type": "string" + }, + "resuable": { + "type": "boolean" + }, + "ephemeral": { + "type": "boolean" + }, + "expiration": { + "type": "string", + "format": "date-time" + } + } + }, + "v1CreatePreAuthKeyResponse": { + "type": "object", + "properties": { + "preAuthKey": { + "$ref": "#/definitions/v1PreAuthKey" + } + } + }, + "v1DebugCreateMachineRequest": { + "type": "object", + "properties": { + "namespace": { + "type": "string" + }, + "key": { + "type": "string" + }, + "name": { + "type": "string" + }, + "routes": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "v1DebugCreateMachineResponse": { + "type": "object", + "properties": { + "machine": { + "$ref": "#/definitions/v1Machine" + } + } + }, + "v1DeleteMachineResponse": { + "type": "object" + }, "v1DeleteNamespaceResponse": { "type": "object" }, + "v1EnableMachineRoutesResponse": { + "type": "object", + "properties": { + "routes": { + "$ref": "#/definitions/v1Routes" + } + } + }, + "v1ExpirePreAuthKeyRequest": { + "type": "object", + "properties": { + "namespace": { + "type": "string" + }, + "key": { + "type": "string" + } + } + }, + "v1ExpirePreAuthKeyResponse": { + "type": "object" + }, "v1GetMachineResponse": { + "type": "object", + "properties": { + "machine": { + "$ref": "#/definitions/v1Machine" + } + } + }, + "v1GetMachineRouteResponse": { + "type": "object", + "properties": { + "routes": { + "$ref": "#/definitions/v1Routes" + } + } + }, + "v1GetNamespaceResponse": { + "type": "object", + "properties": { + "namespace": { + "$ref": "#/definitions/v1Namespace" + } + } + }, + "v1ListMachinesResponse": { + "type": "object", + "properties": { + "machines": { + "type": "array", + "items": { + "$ref": "#/definitions/v1Machine" + } + } + } + }, + "v1ListNamespacesResponse": { + "type": "object", + "properties": { + "namespaces": { + "type": "array", + "items": { + "$ref": "#/definitions/v1Namespace" + } + } + } + }, + "v1ListPreAuthKeysResponse": { + "type": "object", + "properties": { + "preAuthKeys": { + "type": "array", + "items": { + "$ref": "#/definitions/v1PreAuthKey" + } + } + } + }, + "v1Machine": { "type": "object", "properties": { "id": { @@ -197,9 +742,8 @@ "name": { "type": "string" }, - "namespaceId": { - "type": "integer", - "format": "int64" + "namespace": { + "$ref": "#/definitions/v1Namespace" }, "registered": { "type": "boolean" @@ -207,10 +751,6 @@ "registerMethod": { "$ref": "#/definitions/v1RegisterMethod" }, - "authKeyId": { - "type": "integer", - "format": "int64" - }, "lastSeen": { "type": "string", "format": "date-time" @@ -222,17 +762,67 @@ "expiry": { "type": "string", "format": "date-time" + }, + "preAuthKey": { + "$ref": "#/definitions/v1PreAuthKey" + }, + "createdAt": { + "type": "string", + "format": "date-time" } } }, - "v1ListNamespacesResponse": { + "v1Namespace": { "type": "object", "properties": { - "namespaces": { - "type": "array", - "items": { - "type": "string" - } + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "createdAt": { + "type": "string", + "format": "date-time" + } + } + }, + "v1PreAuthKey": { + "type": "object", + "properties": { + "namespace": { + "type": "string" + }, + "id": { + "type": "string" + }, + "key": { + "type": "string" + }, + "resuable": { + "type": "boolean" + }, + "ephemeral": { + "type": "boolean" + }, + "used": { + "type": "boolean" + }, + "expiration": { + "type": "string", + "format": "date-time" + }, + "createdAt": { + "type": "string", + "format": "date-time" + } + } + }, + "v1RegisterMachineResponse": { + "type": "object", + "properties": { + "machine": { + "$ref": "#/definitions/v1Machine" } } }, @@ -245,6 +835,47 @@ "REGISTER_METHOD_OIDC" ], "default": "REGISTER_METHOD_UNSPECIFIED" + }, + "v1RenameNamespaceResponse": { + "type": "object", + "properties": { + "namespace": { + "$ref": "#/definitions/v1Namespace" + } + } + }, + "v1Routes": { + "type": "object", + "properties": { + "advertisedRoutes": { + "type": "array", + "items": { + "type": "string" + } + }, + "enabledRoutes": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "v1ShareMachineResponse": { + "type": "object", + "properties": { + "machine": { + "$ref": "#/definitions/v1Machine" + } + } + }, + "v1UnshareMachineResponse": { + "type": "object", + "properties": { + "machine": { + "$ref": "#/definitions/v1Machine" + } + } } } } diff --git a/gen/openapiv2/headscale/v1/machine.swagger.json b/gen/openapiv2/headscale/v1/machine.swagger.json new file mode 100644 index 00000000..714624b8 --- /dev/null +++ b/gen/openapiv2/headscale/v1/machine.swagger.json @@ -0,0 +1,43 @@ +{ + "swagger": "2.0", + "info": { + "title": "headscale/v1/machine.proto", + "version": "version not set" + }, + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "paths": {}, + "definitions": { + "protobufAny": { + "type": "object", + "properties": { + "@type": { + "type": "string" + } + }, + "additionalProperties": {} + }, + "rpcStatus": { + "type": "object", + "properties": { + "code": { + "type": "integer", + "format": "int32" + }, + "message": { + "type": "string" + }, + "details": { + "type": "array", + "items": { + "$ref": "#/definitions/protobufAny" + } + } + } + } + } +} diff --git a/gen/openapiv2/headscale/v1/namespace.swagger.json b/gen/openapiv2/headscale/v1/namespace.swagger.json new file mode 100644 index 00000000..13687f0a --- /dev/null +++ b/gen/openapiv2/headscale/v1/namespace.swagger.json @@ -0,0 +1,43 @@ +{ + "swagger": "2.0", + "info": { + "title": "headscale/v1/namespace.proto", + "version": "version not set" + }, + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "paths": {}, + "definitions": { + "protobufAny": { + "type": "object", + "properties": { + "@type": { + "type": "string" + } + }, + "additionalProperties": {} + }, + "rpcStatus": { + "type": "object", + "properties": { + "code": { + "type": "integer", + "format": "int32" + }, + "message": { + "type": "string" + }, + "details": { + "type": "array", + "items": { + "$ref": "#/definitions/protobufAny" + } + } + } + } + } +} diff --git a/gen/openapiv2/headscale/v1/preauthkey.swagger.json b/gen/openapiv2/headscale/v1/preauthkey.swagger.json new file mode 100644 index 00000000..ef16319c --- /dev/null +++ b/gen/openapiv2/headscale/v1/preauthkey.swagger.json @@ -0,0 +1,43 @@ +{ + "swagger": "2.0", + "info": { + "title": "headscale/v1/preauthkey.proto", + "version": "version not set" + }, + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "paths": {}, + "definitions": { + "protobufAny": { + "type": "object", + "properties": { + "@type": { + "type": "string" + } + }, + "additionalProperties": {} + }, + "rpcStatus": { + "type": "object", + "properties": { + "code": { + "type": "integer", + "format": "int32" + }, + "message": { + "type": "string" + }, + "details": { + "type": "array", + "items": { + "$ref": "#/definitions/protobufAny" + } + } + } + } + } +} diff --git a/gen/openapiv2/headscale/v1/routes.swagger.json b/gen/openapiv2/headscale/v1/routes.swagger.json new file mode 100644 index 00000000..34eda676 --- /dev/null +++ b/gen/openapiv2/headscale/v1/routes.swagger.json @@ -0,0 +1,43 @@ +{ + "swagger": "2.0", + "info": { + "title": "headscale/v1/routes.proto", + "version": "version not set" + }, + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "paths": {}, + "definitions": { + "protobufAny": { + "type": "object", + "properties": { + "@type": { + "type": "string" + } + }, + "additionalProperties": {} + }, + "rpcStatus": { + "type": "object", + "properties": { + "code": { + "type": "integer", + "format": "int32" + }, + "message": { + "type": "string" + }, + "details": { + "type": "array", + "items": { + "$ref": "#/definitions/protobufAny" + } + } + } + } + } +} From 4226da3d6b65291ea433272a4b9769ee782fe2b5 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Thu, 4 Nov 2021 22:08:45 +0000 Subject: [PATCH 070/300] Add "debug" command This commit adds a debug command tree, intended to host commands used for debugging and testing. It adds a create node/machine command which will be used later to create machines that can be used to test the registration command. --- cmd/headscale/cli/debug.go | 93 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 cmd/headscale/cli/debug.go diff --git a/cmd/headscale/cli/debug.go b/cmd/headscale/cli/debug.go new file mode 100644 index 00000000..8dfe0c41 --- /dev/null +++ b/cmd/headscale/cli/debug.go @@ -0,0 +1,93 @@ +package cli + +import ( + "context" + "fmt" + "time" + + v1 "github.com/juanfont/headscale/gen/go/headscale/v1" + "github.com/rs/zerolog/log" + "github.com/spf13/cobra" +) + +func init() { + rootCmd.AddCommand(debugCmd) + + createNodeCmd.Flags().StringP("name", "", "", "Name") + err := createNodeCmd.MarkFlagRequired("name") + if err != nil { + log.Fatal().Err(err).Msg("") + } + createNodeCmd.Flags().StringP("namespace", "n", "", "Namespace") + err = createNodeCmd.MarkFlagRequired("namespace") + if err != nil { + log.Fatal().Err(err).Msg("") + } + createNodeCmd.Flags().StringP("key", "k", "", "Key") + err = createNodeCmd.MarkFlagRequired("key") + if err != nil { + log.Fatal().Err(err).Msg("") + } + createNodeCmd.Flags().StringSliceP("route", "r", []string{}, "List (or repeated flags) of routes to advertise") + + debugCmd.AddCommand(createNodeCmd) +} + +var debugCmd = &cobra.Command{ + Use: "debug", + Short: "debug and testing commands", + Long: "debug contains extra commands used for debugging and testing headscale", +} + +var createNodeCmd = &cobra.Command{ + Use: "create-node", + Short: "Create a node (machine) that can be registered with `nodes register <>` command", + Run: func(cmd *cobra.Command, args []string) { + output, _ := cmd.Flags().GetString("output") + + namespace, err := cmd.Flags().GetString("namespace") + if err != nil { + ErrorOutput(err, fmt.Sprintf("Error getting namespace: %s", err), output) + return + } + + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + + client, conn := getHeadscaleGRPCClient(ctx) + defer conn.Close() + + name, err := cmd.Flags().GetString("name") + if err != nil { + ErrorOutput(err, fmt.Sprintf("Error getting node from flag: %s", err), output) + return + } + + machineKey, err := cmd.Flags().GetString("key") + if err != nil { + ErrorOutput(err, fmt.Sprintf("Error getting key from flag: %s", err), output) + return + } + + routes, err := cmd.Flags().GetStringSlice("route") + if err != nil { + ErrorOutput(err, fmt.Sprintf("Error getting routes from flag: %s", err), output) + return + } + + request := &v1.DebugCreateMachineRequest{ + Key: machineKey, + Name: name, + Namespace: namespace, + Routes: routes, + } + + response, err := client.DebugCreateMachine(ctx, request) + if err != nil { + ErrorOutput(err, fmt.Sprintf("Cannot create machine: %s", err), output) + return + } + + SuccessOutput(response.Machine, "Machine created", output) + }, +} From 67adea5cab2a7124bd3951d6fb60a369cf99d5ae Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Thu, 4 Nov 2021 22:10:57 +0000 Subject: [PATCH 071/300] Move common integration test commands into common file --- integration_common_test.go | 69 ++++++++++++++ integration_test.go | 178 ++++++++++++++----------------------- 2 files changed, 134 insertions(+), 113 deletions(-) create mode 100644 integration_common_test.go diff --git a/integration_common_test.go b/integration_common_test.go new file mode 100644 index 00000000..d52d7eb4 --- /dev/null +++ b/integration_common_test.go @@ -0,0 +1,69 @@ +//go:build integration +// +build integration + +package headscale + +import ( + "bytes" + "fmt" + "time" + + "github.com/ory/dockertest/v3" + "github.com/ory/dockertest/v3/docker" +) + +func ExecuteCommand(resource *dockertest.Resource, cmd []string, env []string) (string, error) { + var stdout bytes.Buffer + var stderr bytes.Buffer + + // TODO(kradalby): Make configurable + timeout := 10 * time.Second + + type result struct { + exitCode int + err error + } + + resultChan := make(chan result, 1) + + // Run your long running function in it's own goroutine and pass back it's + // response into our channel. + go func() { + exitCode, err := resource.Exec( + cmd, + dockertest.ExecOptions{ + Env: append(env, "LOG_LEVEL=error"), + StdOut: &stdout, + StdErr: &stderr, + }, + ) + resultChan <- result{exitCode, err} + }() + + // Listen on our channel AND a timeout channel - which ever happens first. + select { + case res := <-resultChan: + if res.err != nil { + return "", res.err + } + + if res.exitCode != 0 { + fmt.Println("Command: ", cmd) + fmt.Println("stdout: ", stdout.String()) + fmt.Println("stderr: ", stderr.String()) + return "", fmt.Errorf("command failed with: %s", stderr.String()) + } + + return stdout.String(), nil + case <-time.After(timeout): + return "", fmt.Errorf("command timed out after %s", timeout) + } +} + +func DockerRestartPolicy(config *docker.HostConfig) { + // set AutoRemove to true so that stopped container goes away by itself + config.AutoRemove = true + config.RestartPolicy = docker.RestartPolicy{ + Name: "no", + } +} diff --git a/integration_test.go b/integration_test.go index 1f30bcab..9c572583 100644 --- a/integration_test.go +++ b/integration_test.go @@ -18,6 +18,7 @@ import ( "testing" "time" + v1 "github.com/juanfont/headscale/gen/go/headscale/v1" "github.com/ory/dockertest/v3" "github.com/ory/dockertest/v3/docker" "github.com/stretchr/testify/assert" @@ -28,17 +29,6 @@ import ( "inet.af/netaddr" ) -var ( - integrationTmpDir string - ih Headscale -) - -var ( - pool dockertest.Pool - network dockertest.Network - headscale dockertest.Resource -) - var tailscaleVersions = []string{"1.16.2", "1.14.3", "1.12.3"} type TestNamespace struct { @@ -50,6 +40,10 @@ type IntegrationTestSuite struct { suite.Suite stats *suite.SuiteInformation + pool dockertest.Pool + network dockertest.Network + headscale dockertest.Resource + namespaces map[string]TestNamespace } @@ -74,76 +68,28 @@ func TestIntegrationTestSuite(t *testing.T) { // we have potentially saved the logs. for _, scales := range s.namespaces { for _, tailscale := range scales.tailscales { - if err := pool.Purge(&tailscale); err != nil { + if err := s.pool.Purge(&tailscale); err != nil { log.Printf("Could not purge resource: %s\n", err) } } } if !s.stats.Passed() { - err := saveLog(&headscale, "test_output") + err := s.saveLog(&s.headscale, "test_output") if err != nil { log.Printf("Could not save log: %s\n", err) } } - if err := pool.Purge(&headscale); err != nil { + if err := s.pool.Purge(&s.headscale); err != nil { log.Printf("Could not purge resource: %s\n", err) } - if err := network.Close(); err != nil { + if err := s.network.Close(); err != nil { log.Printf("Could not close network: %s\n", err) } } -func executeCommand(resource *dockertest.Resource, cmd []string, env []string) (string, error) { - var stdout bytes.Buffer - var stderr bytes.Buffer - - // TODO(kradalby): Make configurable - timeout := 10 * time.Second - - type result struct { - exitCode int - err error - } - - resultChan := make(chan result, 1) - - // Run your long running function in it's own goroutine and pass back it's - // response into our channel. - go func() { - exitCode, err := resource.Exec( - cmd, - dockertest.ExecOptions{ - Env: env, - StdOut: &stdout, - StdErr: &stderr, - }, - ) - resultChan <- result{exitCode, err} - }() - - // Listen on our channel AND a timeout channel - which ever happens first. - select { - case res := <-resultChan: - if res.err != nil { - return "", res.err - } - - if res.exitCode != 0 { - fmt.Println("Command: ", cmd) - fmt.Println("stdout: ", stdout.String()) - fmt.Println("stderr: ", stderr.String()) - return "", fmt.Errorf("command failed with: %s", stderr.String()) - } - - return stdout.String(), nil - case <-time.After(timeout): - return "", fmt.Errorf("command timed out after %s", timeout) - } -} - -func saveLog(resource *dockertest.Resource, basePath string) error { +func (s *IntegrationTestSuite) saveLog(resource *dockertest.Resource, basePath string) error { err := os.MkdirAll(basePath, os.ModePerm) if err != nil { return err @@ -152,7 +98,7 @@ func saveLog(resource *dockertest.Resource, basePath string) error { var stdout bytes.Buffer var stderr bytes.Buffer - err = pool.Client.Logs( + err = s.pool.Client.Logs( docker.LogsOptions{ Context: context.TODO(), Container: resource.Container.ID, @@ -185,15 +131,9 @@ func saveLog(resource *dockertest.Resource, basePath string) error { return nil } -func dockerRestartPolicy(config *docker.HostConfig) { - // set AutoRemove to true so that stopped container goes away by itself - config.AutoRemove = true - config.RestartPolicy = docker.RestartPolicy{ - Name: "no", - } -} - -func tailscaleContainer(namespace, identifier, version string) (string, *dockertest.Resource) { +func (s *IntegrationTestSuite) tailscaleContainer( + namespace, identifier, version string, +) (string, *dockertest.Resource) { tailscaleBuildOptions := &dockertest.BuildOptions{ Dockerfile: "Dockerfile.tailscale", ContextDir: ".", @@ -207,11 +147,11 @@ func tailscaleContainer(namespace, identifier, version string) (string, *dockert hostname := fmt.Sprintf("%s-tailscale-%s-%s", namespace, strings.Replace(version, ".", "-", -1), identifier) tailscaleOptions := &dockertest.RunOptions{ Name: hostname, - Networks: []*dockertest.Network{&network}, + Networks: []*dockertest.Network{&s.network}, Cmd: []string{"tailscaled", "--tun=userspace-networking", "--socks5-server=localhost:1055"}, } - pts, err := pool.BuildAndRunWithBuildOptions(tailscaleBuildOptions, tailscaleOptions, dockerRestartPolicy) + pts, err := s.pool.BuildAndRunWithBuildOptions(tailscaleBuildOptions, tailscaleOptions, DockerRestartPolicy) if err != nil { log.Fatalf("Could not start resource: %s", err) } @@ -227,13 +167,13 @@ func (s *IntegrationTestSuite) SetupSuite() { } if ppool, err := dockertest.NewPool(""); err == nil { - pool = *ppool + s.pool = *ppool } else { log.Fatalf("Could not connect to docker: %s", err) } - if pnetwork, err := pool.CreateNetwork("headscale-test"); err == nil { - network = *pnetwork + if pnetwork, err := s.pool.CreateNetwork("headscale-test"); err == nil { + s.network = *pnetwork } else { log.Fatalf("Could not create network: %s", err) } @@ -253,13 +193,13 @@ func (s *IntegrationTestSuite) SetupSuite() { Mounts: []string{ fmt.Sprintf("%s/integration_test/etc:/etc/headscale", currentPath), }, - Networks: []*dockertest.Network{&network}, + Networks: []*dockertest.Network{&s.network}, Cmd: []string{"headscale", "serve"}, } fmt.Println("Creating headscale container") - if pheadscale, err := pool.BuildAndRunWithBuildOptions(headscaleBuildOptions, headscaleOptions, dockerRestartPolicy); err == nil { - headscale = *pheadscale + if pheadscale, err := s.pool.BuildAndRunWithBuildOptions(headscaleBuildOptions, headscaleOptions, DockerRestartPolicy); err == nil { + s.headscale = *pheadscale } else { log.Fatalf("Could not start resource: %s", err) } @@ -270,15 +210,15 @@ func (s *IntegrationTestSuite) SetupSuite() { for i := 0; i < scales.count; i++ { version := tailscaleVersions[i%len(tailscaleVersions)] - hostname, container := tailscaleContainer(namespace, fmt.Sprint(i), version) + hostname, container := s.tailscaleContainer(namespace, fmt.Sprint(i), version) scales.tailscales[hostname] = *container } } fmt.Println("Waiting for headscale to be ready") - hostEndpoint := fmt.Sprintf("localhost:%s", headscale.GetPort("8080/tcp")) + hostEndpoint := fmt.Sprintf("localhost:%s", s.headscale.GetPort("8080/tcp")) - if err := pool.Retry(func() error { + if err := s.pool.Retry(func() error { url := fmt.Sprintf("http://%s/health", hostEndpoint) resp, err := http.Get(url) if err != nil { @@ -299,8 +239,8 @@ func (s *IntegrationTestSuite) SetupSuite() { for namespace, scales := range s.namespaces { fmt.Printf("Creating headscale namespace: %s\n", namespace) - result, err := executeCommand( - &headscale, + result, err := ExecuteCommand( + &s.headscale, []string{"headscale", "namespaces", "create", namespace}, []string{}, ) @@ -308,8 +248,8 @@ func (s *IntegrationTestSuite) SetupSuite() { assert.Nil(s.T(), err) fmt.Printf("Creating pre auth key for %s\n", namespace) - authKey, err := executeCommand( - &headscale, + preAuthResult, err := ExecuteCommand( + &s.headscale, []string{ "headscale", "--namespace", @@ -319,11 +259,17 @@ func (s *IntegrationTestSuite) SetupSuite() { "--reusable", "--expiration", "24h", + "--output", + "json", }, - []string{}, + []string{"LOG_LEVEL=error"}, ) assert.Nil(s.T(), err) + var preAuthKey v1.PreAuthKey + err = json.Unmarshal([]byte(preAuthResult), &preAuthKey) + assert.Nil(s.T(), err) + headscaleEndpoint := "http://headscale:8080" fmt.Printf("Joining tailscale containers to headscale at %s\n", headscaleEndpoint) @@ -334,14 +280,14 @@ func (s *IntegrationTestSuite) SetupSuite() { "-login-server", headscaleEndpoint, "--authkey", - strings.TrimSuffix(authKey, "\n"), + preAuthKey.Key, "--hostname", hostname, } fmt.Println("Join command:", command) fmt.Printf("Running join command for %s\n", hostname) - result, err := executeCommand( + result, err := ExecuteCommand( &tailscale, command, []string{}, @@ -367,8 +313,8 @@ func (s *IntegrationTestSuite) HandleStats(suiteName string, stats *suite.SuiteI func (s *IntegrationTestSuite) TestListNodes() { for namespace, scales := range s.namespaces { fmt.Println("Listing nodes") - result, err := executeCommand( - &headscale, + result, err := ExecuteCommand( + &s.headscale, []string{"headscale", "--namespace", namespace, "nodes", "list"}, []string{}, ) @@ -419,7 +365,7 @@ func (s *IntegrationTestSuite) TestStatus() { command := []string{"tailscale", "status", "--json"} fmt.Printf("Getting status for %s\n", hostname) - result, err := executeCommand( + result, err := ExecuteCommand( &tailscale, command, []string{}, @@ -481,7 +427,7 @@ func (s *IntegrationTestSuite) TestPingAllPeers() { } fmt.Printf("Pinging from %s (%s) to %s (%s)\n", hostname, ips[hostname], peername, ip) - result, err := executeCommand( + result, err := ExecuteCommand( &tailscale, command, []string{}, @@ -500,22 +446,28 @@ func (s *IntegrationTestSuite) TestSharedNodes() { main := s.namespaces["main"] shared := s.namespaces["shared"] - result, err := executeCommand( - &headscale, - []string{"headscale", "nodes", "list", "-o", "json", "--namespace", "shared"}, + result, err := ExecuteCommand( + &s.headscale, + []string{"headscale", "nodes", "list", "--output", "json", "--namespace", "shared"}, []string{}, ) assert.Nil(s.T(), err) - var machineList []Machine + var machineList []v1.Machine err = json.Unmarshal([]byte(result), &machineList) assert.Nil(s.T(), err) for _, machine := range machineList { - result, err := executeCommand( - &headscale, - []string{"headscale", "nodes", "share", "--identifier", fmt.Sprint(machine.ID), "--namespace", "main"}, + result, err := ExecuteCommand( + &s.headscale, + []string{ + "headscale", + "nodes", + "share", + "--identifier", fmt.Sprint(machine.Id), + "--namespace", "main", + }, []string{}, ) assert.Nil(s.T(), err) @@ -523,8 +475,8 @@ func (s *IntegrationTestSuite) TestSharedNodes() { fmt.Println("Shared node with result: ", result) } - result, err = executeCommand( - &headscale, + result, err = ExecuteCommand( + &s.headscale, []string{"headscale", "nodes", "list", "--namespace", "main"}, []string{}, ) @@ -568,7 +520,7 @@ func (s *IntegrationTestSuite) TestSharedNodes() { } fmt.Printf("Pinging from %s (%s) to %s (%s)\n", hostname, mainIps[hostname], peername, ip) - result, err := executeCommand( + result, err := ExecuteCommand( &tailscale, command, []string{}, @@ -591,7 +543,7 @@ func (s *IntegrationTestSuite) TestTailDrop() { for hostname, tailscale := range scales.tailscales { command := []string{"touch", fmt.Sprintf("/tmp/file_from_%s", hostname)} - _, err := executeCommand( + _, err := ExecuteCommand( &tailscale, command, []string{}, @@ -628,7 +580,7 @@ func (s *IntegrationTestSuite) TestTailDrop() { fmt.Sprintf("%s/v0/put/file_from_%s", peerAPI, hostname), } fmt.Printf("Sending file from %s (%s) to %s (%s)\n", hostname, ips[hostname], peername, ip) - _, err = executeCommand( + _, err = ExecuteCommand( &tailscale, command, []string{"ALL_PROXY=socks5://localhost:1055"}, @@ -655,7 +607,7 @@ func (s *IntegrationTestSuite) TestTailDrop() { "get", "/tmp/", } - _, err := executeCommand( + _, err := ExecuteCommand( &tailscale, command, []string{}, @@ -669,7 +621,7 @@ func (s *IntegrationTestSuite) TestTailDrop() { fmt.Sprintf("/tmp/file_from_%s", peername), } fmt.Printf("Checking file in %s (%s) from %s (%s)\n", hostname, ips[hostname], peername, ip) - result, err := executeCommand( + result, err := ExecuteCommand( &tailscale, command, []string{}, @@ -707,7 +659,7 @@ func (s *IntegrationTestSuite) TestMagicDNS() { peername, ip, ) - result, err := executeCommand( + result, err := ExecuteCommand( &tailscale, command, []string{}, @@ -727,7 +679,7 @@ func getIPs(tailscales map[string]dockertest.Resource) (map[string]netaddr.IP, e for hostname, tailscale := range tailscales { command := []string{"tailscale", "ip"} - result, err := executeCommand( + result, err := ExecuteCommand( &tailscale, command, []string{}, @@ -755,7 +707,7 @@ func getAPIURLs(tailscales map[string]dockertest.Resource) (map[netaddr.IP]strin "/run/tailscale/tailscaled.sock", "http://localhost/localapi/v0/file-targets", } - result, err := executeCommand( + result, err := ExecuteCommand( &tailscale, command, []string{}, From 787814ea89b677f28b77435f687b9e357bb1d9e9 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Thu, 4 Nov 2021 22:11:38 +0000 Subject: [PATCH 072/300] Consolidate machine related lookups This commit moves the routes lookup functions to be subcommands of Machine, making them a lot simpler and more specific/composable. It also moves the register command from cli.go into machine, so we can clear out the extra file. Finally a toProto function has been added to convert between the machine database model and the proto/rpc model. --- cli.go | 43 --------- machine.go | 249 ++++++++++++++++++++++++++++++++++++++++++++++++++--- routes.go | 18 +--- 3 files changed, 239 insertions(+), 71 deletions(-) delete mode 100644 cli.go diff --git a/cli.go b/cli.go deleted file mode 100644 index 8610b334..00000000 --- a/cli.go +++ /dev/null @@ -1,43 +0,0 @@ -package headscale - -import ( - "errors" - - "gorm.io/gorm" - "tailscale.com/types/wgkey" -) - -// RegisterMachine is executed from the CLI to register a new Machine using its MachineKey -func (h *Headscale) RegisterMachine(key string, namespace string) (*Machine, error) { - ns, err := h.GetNamespace(namespace) - if err != nil { - return nil, err - } - mKey, err := wgkey.ParseHex(key) - if err != nil { - return nil, err - } - - m := Machine{} - if result := h.db.First(&m, "machine_key = ?", mKey.HexString()); errors.Is(result.Error, gorm.ErrRecordNotFound) { - return nil, errors.New("Machine not found") - } - - h.updateMachineExpiry(&m) // update the machine's expiry before bailing if its already registered - - if m.isAlreadyRegistered() { - return nil, errors.New("Machine already registered") - } - - ip, err := h.getAvailableIP() - if err != nil { - return nil, err - } - m.IPAddress = ip.String() - m.NamespaceID = ns.ID - m.Registered = true - m.RegisterMethod = "cli" - h.db.Save(&m) - - return &m, nil -} diff --git a/machine.go b/machine.go index ccd30e3e..557ab5b6 100644 --- a/machine.go +++ b/machine.go @@ -2,6 +2,7 @@ package headscale import ( "encoding/json" + "errors" "fmt" "sort" "strconv" @@ -10,8 +11,11 @@ import ( "github.com/fatih/set" "github.com/rs/zerolog/log" + "google.golang.org/protobuf/types/known/timestamppb" + v1 "github.com/juanfont/headscale/gen/go/headscale/v1" "gorm.io/datatypes" + "gorm.io/gorm" "inet.af/netaddr" "tailscale.com/tailcfg" "tailscale.com/types/wgkey" @@ -91,7 +95,7 @@ func (h *Headscale) updateMachineExpiry(m *Machine) { func (h *Headscale) getDirectPeers(m *Machine) (Machines, error) { log.Trace(). - Str("func", "getDirectPeers"). + Caller(). Str("machine", m.Name). Msg("Finding direct peers") @@ -105,7 +109,7 @@ func (h *Headscale) getDirectPeers(m *Machine) (Machines, error) { sort.Slice(machines, func(i, j int) bool { return machines[i].ID < machines[j].ID }) log.Trace(). - Str("func", "getDirectmachines"). + Caller(). Str("machine", m.Name). Msgf("Found direct machines: %s", machines.String()) return machines, nil @@ -114,7 +118,7 @@ func (h *Headscale) getDirectPeers(m *Machine) (Machines, error) { // getShared fetches machines that are shared to the `Namespace` of the machine we are getting peers for func (h *Headscale) getShared(m *Machine) (Machines, error) { log.Trace(). - Str("func", "getShared"). + Caller(). Str("machine", m.Name). Msg("Finding shared peers") @@ -132,7 +136,7 @@ func (h *Headscale) getShared(m *Machine) (Machines, error) { sort.Slice(peers, func(i, j int) bool { return peers[i].ID < peers[j].ID }) log.Trace(). - Str("func", "getShared"). + Caller(). Str("machine", m.Name). Msgf("Found shared peers: %s", peers.String()) return peers, nil @@ -141,7 +145,7 @@ func (h *Headscale) getShared(m *Machine) (Machines, error) { // getSharedTo fetches the machines of the namespaces this machine is shared in func (h *Headscale) getSharedTo(m *Machine) (Machines, error) { log.Trace(). - Str("func", "getSharedTo"). + Caller(). Str("machine", m.Name). Msg("Finding peers in namespaces this machine is shared with") @@ -157,13 +161,13 @@ func (h *Headscale) getSharedTo(m *Machine) (Machines, error) { if err != nil { return Machines{}, err } - peers = append(peers, *namespaceMachines...) + peers = append(peers, namespaceMachines...) } sort.Slice(peers, func(i, j int) bool { return peers[i].ID < peers[j].ID }) log.Trace(). - Str("func", "getSharedTo"). + Caller(). Str("machine", m.Name). Msgf("Found peers we are shared with: %s", peers.String()) return peers, nil @@ -173,7 +177,7 @@ func (h *Headscale) getPeers(m *Machine) (Machines, error) { direct, err := h.getDirectPeers(m) if err != nil { log.Error(). - Str("func", "getPeers"). + Caller(). Err(err). Msg("Cannot fetch peers") return Machines{}, err @@ -182,7 +186,7 @@ func (h *Headscale) getPeers(m *Machine) (Machines, error) { shared, err := h.getShared(m) if err != nil { log.Error(). - Str("func", "getShared"). + Caller(). Err(err). Msg("Cannot fetch peers") return Machines{}, err @@ -191,7 +195,7 @@ func (h *Headscale) getPeers(m *Machine) (Machines, error) { sharedTo, err := h.getSharedTo(m) if err != nil { log.Error(). - Str("func", "sharedTo"). + Caller(). Err(err). Msg("Cannot fetch peers") return Machines{}, err @@ -203,13 +207,21 @@ func (h *Headscale) getPeers(m *Machine) (Machines, error) { sort.Slice(peers, func(i, j int) bool { return peers[i].ID < peers[j].ID }) log.Trace(). - Str("func", "getShared"). + Caller(). Str("machine", m.Name). Msgf("Found total peers: %s", peers.String()) return peers, nil } +func (h *Headscale) ListMachines() ([]Machine, error) { + machines := []Machine{} + if err := h.db.Preload("AuthKey").Preload("AuthKey.Namespace").Preload("Namespace").Find(&machines).Error; err != nil { + return nil, err + } + return machines, nil +} + // GetMachine finds a Machine by name and namespace and returns the Machine struct func (h *Headscale) GetMachine(namespace string, name string) (*Machine, error) { machines, err := h.ListMachinesInNamespace(namespace) @@ -217,7 +229,7 @@ func (h *Headscale) GetMachine(namespace string, name string) (*Machine, error) return nil, err } - for _, m := range *machines { + for _, m := range machines { if m.Name == name { return &m, nil } @@ -326,7 +338,7 @@ func (h *Headscale) isOutdated(m *Machine) bool { lastChange := h.getLastStateChange(namespaces...) log.Trace(). - Str("func", "keepAlive"). + Caller(). Str("machine", m.Name). Time("last_successful_update", *m.LastSuccessfulUpdate). Time("last_state_change", lastChange). @@ -405,7 +417,7 @@ func (m Machine) toNode(baseDomain string, dnsConfig *tailcfg.DNSConfig, include ip, err := netaddr.ParseIPPrefix(fmt.Sprintf("%s/32", m.IPAddress)) if err != nil { log.Trace(). - Str("func", "toNode"). + Caller(). Str("ip", m.IPAddress). Msgf("Failed to parse IP Prefix from IP: %s", m.IPAddress) return nil, err @@ -508,3 +520,212 @@ func (m Machine) toNode(baseDomain string, dnsConfig *tailcfg.DNSConfig, include } return &n, nil } + +func (m *Machine) toProto() *v1.Machine { + machine := &v1.Machine{ + Id: m.ID, + MachineKey: m.MachineKey, + + NodeKey: m.NodeKey, + DiscoKey: m.DiscoKey, + IpAddress: m.IPAddress, + Name: m.Name, + Namespace: m.Namespace.toProto(), + + Registered: m.Registered, + + // TODO(kradalby): Implement register method enum converter + // RegisterMethod: , + + CreatedAt: timestamppb.New(m.CreatedAt), + } + + if m.AuthKey != nil { + machine.PreAuthKey = m.AuthKey.toProto() + } + + if m.LastSeen != nil { + machine.LastSeen = timestamppb.New(*m.LastSeen) + } + + if m.LastSuccessfulUpdate != nil { + machine.LastSuccessfulUpdate = timestamppb.New(*m.LastSuccessfulUpdate) + } + + if m.Expiry != nil { + machine.Expiry = timestamppb.New(*m.Expiry) + } + + return machine +} + +// RegisterMachine is executed from the CLI to register a new Machine using its MachineKey +func (h *Headscale) RegisterMachine(key string, namespace string) (*Machine, error) { + ns, err := h.GetNamespace(namespace) + if err != nil { + return nil, err + } + mKey, err := wgkey.ParseHex(key) + if err != nil { + return nil, err + } + + m := Machine{} + if result := h.db.First(&m, "machine_key = ?", mKey.HexString()); errors.Is(result.Error, gorm.ErrRecordNotFound) { + return nil, errors.New("Machine not found") + } + + log.Trace(). + Caller(). + Str("machine", m.Name). + Msg("Attempting to register machine") + + if m.isAlreadyRegistered() { + err := errors.New("Machine already registered") + log.Error(). + Caller(). + Err(err). + Str("machine", m.Name). + Msg("Attempting to register machine") + + return nil, err + } + + ip, err := h.getAvailableIP() + if err != nil { + log.Error(). + Caller(). + Err(err). + Str("machine", m.Name). + Msg("Could not find IP for the new machine") + return nil, err + } + + log.Trace(). + Caller(). + Str("machine", m.Name). + Str("ip", ip.String()). + Msg("Found IP for host") + + m.IPAddress = ip.String() + m.NamespaceID = ns.ID + m.Registered = true + m.RegisterMethod = "cli" + h.db.Save(&m) + + log.Trace(). + Caller(). + Str("machine", m.Name). + Str("ip", ip.String()). + Msg("Machine registered with the database") + + return &m, nil +} + +func (m *Machine) GetAdvertisedRoutes() ([]netaddr.IPPrefix, error) { + hostInfo, err := m.GetHostInfo() + if err != nil { + return nil, err + } + return hostInfo.RoutableIPs, nil +} + +func (m *Machine) GetEnabledRoutes() ([]netaddr.IPPrefix, error) { + data, err := m.EnabledRoutes.MarshalJSON() + if err != nil { + return nil, err + } + + routesStr := []string{} + err = json.Unmarshal(data, &routesStr) + if err != nil { + return nil, err + } + + routes := make([]netaddr.IPPrefix, len(routesStr)) + for index, routeStr := range routesStr { + route, err := netaddr.ParseIPPrefix(routeStr) + if err != nil { + return nil, err + } + routes[index] = route + } + + return routes, nil +} + +func (m *Machine) IsRoutesEnabled(routeStr string) bool { + route, err := netaddr.ParseIPPrefix(routeStr) + if err != nil { + return false + } + + enabledRoutes, err := m.GetEnabledRoutes() + if err != nil { + return false + } + + for _, enabledRoute := range enabledRoutes { + if route == enabledRoute { + return true + } + } + return false +} + +// EnableNodeRoute enables new routes based on a list of new routes. It will _replace_ the +// previous list of routes. +func (h *Headscale) EnableRoutes(m *Machine, routeStrs ...string) error { + newRoutes := make([]netaddr.IPPrefix, len(routeStrs)) + for index, routeStr := range routeStrs { + route, err := netaddr.ParseIPPrefix(routeStr) + if err != nil { + return err + } + + newRoutes[index] = route + } + + availableRoutes, err := m.GetAdvertisedRoutes() + if err != nil { + return err + } + + for _, newRoute := range newRoutes { + if !containsIpPrefix(availableRoutes, newRoute) { + return fmt.Errorf("route (%s) is not available on node %s", m.Name, newRoute) + } + } + + routes, err := json.Marshal(newRoutes) + if err != nil { + return err + } + + m.EnabledRoutes = datatypes.JSON(routes) + h.db.Save(&m) + + err = h.RequestMapUpdates(m.NamespaceID) + if err != nil { + return err + } + + return nil +} + +func (m *Machine) RoutesToProto() (*v1.Routes, error) { + availableRoutes, err := m.GetAdvertisedRoutes() + if err != nil { + return nil, err + } + + enabledRoutes, err := m.GetEnabledRoutes() + if err != nil { + return nil, err + } + + return &v1.Routes{ + AdvertisedRoutes: ipPrefixToString(availableRoutes), + EnabledRoutes: ipPrefixToString(enabledRoutes), + }, nil +} diff --git a/routes.go b/routes.go index 0ef01780..f07b709a 100644 --- a/routes.go +++ b/routes.go @@ -3,13 +3,12 @@ package headscale import ( "encoding/json" "fmt" - "strconv" - "github.com/pterm/pterm" "gorm.io/datatypes" "inet.af/netaddr" ) +// Deprecated: use machine function instead // GetAdvertisedNodeRoutes returns the subnet routes advertised by a node (identified by // namespace and node name) func (h *Headscale) GetAdvertisedNodeRoutes(namespace string, nodeName string) (*[]netaddr.IPPrefix, error) { @@ -25,6 +24,7 @@ func (h *Headscale) GetAdvertisedNodeRoutes(namespace string, nodeName string) ( return &hostInfo.RoutableIPs, nil } +// Deprecated: use machine function instead // GetEnabledNodeRoutes returns the subnet routes enabled by a node (identified by // namespace and node name) func (h *Headscale) GetEnabledNodeRoutes(namespace string, nodeName string) ([]netaddr.IPPrefix, error) { @@ -56,6 +56,7 @@ func (h *Headscale) GetEnabledNodeRoutes(namespace string, nodeName string) ([]n return routes, nil } +// Deprecated: use machine function instead // IsNodeRouteEnabled checks if a certain route has been enabled func (h *Headscale) IsNodeRouteEnabled(namespace string, nodeName string, routeStr string) bool { route, err := netaddr.ParseIPPrefix(routeStr) @@ -76,6 +77,7 @@ func (h *Headscale) IsNodeRouteEnabled(namespace string, nodeName string, routeS return false } +// Deprecated: use EnableRoute in machine.go // EnableNodeRoute enables a subnet route advertised by a node (identified by // namespace and node name) func (h *Headscale) EnableNodeRoute(namespace string, nodeName string, routeStr string) error { @@ -129,15 +131,3 @@ func (h *Headscale) EnableNodeRoute(namespace string, nodeName string, routeStr return nil } - -// RoutesToPtables converts the list of routes to a nice table -func (h *Headscale) RoutesToPtables(namespace string, nodeName string, availableRoutes []netaddr.IPPrefix) pterm.TableData { - d := pterm.TableData{{"Route", "Enabled"}} - - for _, route := range availableRoutes { - enabled := h.IsNodeRouteEnabled(namespace, nodeName, route.String()) - - d = append(d, []string{route.String(), strconv.FormatBool(enabled)}) - } - return d -} From 77f5f8bd1cedd9c5bb3cbb20c8918b18ddfbaf08 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Thu, 4 Nov 2021 22:14:39 +0000 Subject: [PATCH 073/300] Simplify and streamline preauth commands for new cli/rpc/api --- preauth_keys.go | 40 ++++++++++++++++++++++++++++++++-------- preauth_keys_test.go | 10 +++++----- 2 files changed, 37 insertions(+), 13 deletions(-) diff --git a/preauth_keys.go b/preauth_keys.go index de10cdb7..304e345b 100644 --- a/preauth_keys.go +++ b/preauth_keys.go @@ -4,14 +4,20 @@ import ( "crypto/rand" "encoding/hex" "errors" + "strconv" "time" + "google.golang.org/protobuf/types/known/timestamppb" "gorm.io/gorm" + + v1 "github.com/juanfont/headscale/gen/go/headscale/v1" ) -const errorAuthKeyNotFound = Error("AuthKey not found") -const errorAuthKeyExpired = Error("AuthKey expired") -const errSingleUseAuthKeyHasBeenUsed = Error("AuthKey has already been used") +const ( + errorAuthKeyNotFound = Error("AuthKey not found") + errorAuthKeyExpired = Error("AuthKey expired") + errSingleUseAuthKeyHasBeenUsed = Error("AuthKey has already been used") +) // PreAuthKey describes a pre-authorization key usable in a particular namespace type PreAuthKey struct { @@ -28,7 +34,12 @@ type PreAuthKey struct { } // CreatePreAuthKey creates a new PreAuthKey in a namespace, and returns it -func (h *Headscale) CreatePreAuthKey(namespaceName string, reusable bool, ephemeral bool, expiration *time.Time) (*PreAuthKey, error) { +func (h *Headscale) CreatePreAuthKey( + namespaceName string, + reusable bool, + ephemeral bool, + expiration *time.Time, +) (*PreAuthKey, error) { n, err := h.GetNamespace(namespaceName) if err != nil { return nil, err @@ -54,8 +65,8 @@ func (h *Headscale) CreatePreAuthKey(namespaceName string, reusable bool, epheme return &k, nil } -// GetPreAuthKeys returns the list of PreAuthKeys for a namespace -func (h *Headscale) GetPreAuthKeys(namespaceName string) (*[]PreAuthKey, error) { +// ListPreAuthKeys returns the list of PreAuthKeys for a namespace +func (h *Headscale) ListPreAuthKeys(namespaceName string) ([]PreAuthKey, error) { n, err := h.GetNamespace(namespaceName) if err != nil { return nil, err @@ -65,7 +76,7 @@ func (h *Headscale) GetPreAuthKeys(namespaceName string) (*[]PreAuthKey, error) if err := h.db.Preload("Namespace").Where(&PreAuthKey{NamespaceID: n.ID}).Find(&keys).Error; err != nil { return nil, err } - return &keys, nil + return keys, nil } // GetPreAuthKey returns a PreAuthKey for a given key @@ -83,7 +94,7 @@ func (h *Headscale) GetPreAuthKey(namespace string, key string) (*PreAuthKey, er } // MarkExpirePreAuthKey marks a PreAuthKey as expired -func (h *Headscale) MarkExpirePreAuthKey(k *PreAuthKey) error { +func (h *Headscale) ExpirePreAuthKey(k *PreAuthKey) error { if err := h.db.Model(&k).Update("Expiration", time.Now()).Error; err != nil { return err } @@ -126,3 +137,16 @@ func (h *Headscale) generateKey() (string, error) { } return hex.EncodeToString(bytes), nil } + +func (key *PreAuthKey) toProto() *v1.PreAuthKey { + return &v1.PreAuthKey{ + Namespace: key.Namespace.Name, + Id: strconv.FormatUint(key.ID, 10), + Key: key.Key, + Resuable: key.Reusable, + Ephemeral: key.Ephemeral, + Used: key.Used, + Expiration: timestamppb.New(*key.Expiration), + CreatedAt: timestamppb.New(*key.CreatedAt), + } +} diff --git a/preauth_keys_test.go b/preauth_keys_test.go index f8973eaf..dceec00b 100644 --- a/preauth_keys_test.go +++ b/preauth_keys_test.go @@ -24,15 +24,15 @@ func (*Suite) TestCreatePreAuthKey(c *check.C) { // Make sure the Namespace association is populated c.Assert(k.Namespace.Name, check.Equals, n.Name) - _, err = h.GetPreAuthKeys("bogus") + _, err = h.ListPreAuthKeys("bogus") c.Assert(err, check.NotNil) - keys, err := h.GetPreAuthKeys(n.Name) + keys, err := h.ListPreAuthKeys(n.Name) c.Assert(err, check.IsNil) - c.Assert(len(*keys), check.Equals, 1) + c.Assert(len(keys), check.Equals, 1) // Make sure the Namespace association is populated - c.Assert((*keys)[0].Namespace.Name, check.Equals, n.Name) + c.Assert((keys)[0].Namespace.Name, check.Equals, n.Name) } func (*Suite) TestExpiredPreAuthKey(c *check.C) { @@ -172,7 +172,7 @@ func (*Suite) TestExpirePreauthKey(c *check.C) { c.Assert(err, check.IsNil) c.Assert(pak.Expiration, check.IsNil) - err = h.MarkExpirePreAuthKey(pak) + err = h.ExpirePreAuthKey(pak) c.Assert(err, check.IsNil) c.Assert(pak.Expiration, check.NotNil) From 95690e614e42d45dd453f22c73033263b9581ac5 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Thu, 4 Nov 2021 22:15:17 +0000 Subject: [PATCH 074/300] Simplify and streamline namespace functions for new cli/rpc/api --- namespaces.go | 33 +++++++++++++++++++++++---------- namespaces_test.go | 4 ++-- 2 files changed, 25 insertions(+), 12 deletions(-) diff --git a/namespaces.go b/namespaces.go index d7c1e035..66deb1a2 100644 --- a/namespaces.go +++ b/namespaces.go @@ -4,16 +4,21 @@ import ( "encoding/json" "errors" "fmt" + "strconv" "time" + v1 "github.com/juanfont/headscale/gen/go/headscale/v1" "github.com/rs/zerolog/log" + "google.golang.org/protobuf/types/known/timestamppb" "gorm.io/gorm" "tailscale.com/tailcfg" ) -const errorNamespaceExists = Error("Namespace already exists") -const errorNamespaceNotFound = Error("Namespace not found") -const errorNamespaceNotEmpty = Error("Namespace not empty") +const ( + errorNamespaceExists = Error("Namespace already exists") + errorNamespaceNotFound = Error("Namespace not found") + errorNamespaceNotEmpty = Error("Namespace not empty") +) // Namespace is the way Headscale implements the concept of users in Tailscale // @@ -54,7 +59,7 @@ func (h *Headscale) DestroyNamespace(name string) error { if err != nil { return err } - if len(*m) > 0 { + if len(m) > 0 { return errorNamespaceNotEmpty } @@ -104,16 +109,16 @@ func (h *Headscale) GetNamespace(name string) (*Namespace, error) { } // ListNamespaces gets all the existing namespaces -func (h *Headscale) ListNamespaces() (*[]Namespace, error) { +func (h *Headscale) ListNamespaces() ([]Namespace, error) { namespaces := []Namespace{} if err := h.db.Find(&namespaces).Error; err != nil { return nil, err } - return &namespaces, nil + return namespaces, nil } // ListMachinesInNamespace gets all the nodes in a given namespace -func (h *Headscale) ListMachinesInNamespace(name string) (*[]Machine, error) { +func (h *Headscale) ListMachinesInNamespace(name string) ([]Machine, error) { n, err := h.GetNamespace(name) if err != nil { return nil, err @@ -123,11 +128,11 @@ func (h *Headscale) ListMachinesInNamespace(name string) (*[]Machine, error) { if err := h.db.Preload("AuthKey").Preload("AuthKey.Namespace").Preload("Namespace").Where(&Machine{NamespaceID: n.ID}).Find(&machines).Error; err != nil { return nil, err } - return &machines, nil + return machines, nil } // ListSharedMachinesInNamespace returns all the machines that are shared to the specified namespace -func (h *Headscale) ListSharedMachinesInNamespace(name string) (*[]Machine, error) { +func (h *Headscale) ListSharedMachinesInNamespace(name string) ([]Machine, error) { namespace, err := h.GetNamespace(name) if err != nil { return nil, err @@ -145,7 +150,7 @@ func (h *Headscale) ListSharedMachinesInNamespace(name string) (*[]Machine, erro } machines = append(machines, *machine) } - return &machines, nil + return machines, nil } // SetMachineNamespace assigns a Machine to a namespace @@ -275,3 +280,11 @@ func getMapResponseUserProfiles(m Machine, peers Machines) []tailcfg.UserProfile } return profiles } + +func (n *Namespace) toProto() *v1.Namespace { + return &v1.Namespace{ + Id: strconv.FormatUint(uint64(n.ID), 10), + Name: n.Name, + CreatedAt: timestamppb.New(n.CreatedAt), + } +} diff --git a/namespaces_test.go b/namespaces_test.go index 2a211da9..7ce4850e 100644 --- a/namespaces_test.go +++ b/namespaces_test.go @@ -12,7 +12,7 @@ func (s *Suite) TestCreateAndDestroyNamespace(c *check.C) { ns, err := h.ListNamespaces() c.Assert(err, check.IsNil) - c.Assert(len(*ns), check.Equals, 1) + c.Assert(len(ns), check.Equals, 1) err = h.DestroyNamespace("test") c.Assert(err, check.IsNil) @@ -55,7 +55,7 @@ func (s *Suite) TestRenameNamespace(c *check.C) { ns, err := h.ListNamespaces() c.Assert(err, check.IsNil) - c.Assert(len(*ns), check.Equals, 1) + c.Assert(len(ns), check.Equals, 1) err = h.RenameNamespace("test", "test_renamed") c.Assert(err, check.IsNil) From 5526ccc6969311e08e30ad5f7ded369c0ef1edf9 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Thu, 4 Nov 2021 22:15:46 +0000 Subject: [PATCH 075/300] Namespaces are no longer a pointer --- derp.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/derp.go b/derp.go index 39e63210..7f65832c 100644 --- a/derp.go +++ b/derp.go @@ -144,7 +144,7 @@ func (h *Headscale) scheduledDERPMapUpdateWorker(cancelChan <-chan struct{}) { Msg("Failed to fetch namespaces") } - for _, namespace := range *namespaces { + for _, namespace := range namespaces { h.setLastStateChangeToNow(namespace.Name) } } From 94dbaa6822a8225183a54fd8dcb4cdeb424e9df2 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Thu, 4 Nov 2021 22:16:56 +0000 Subject: [PATCH 076/300] Clean up the return of "pointer list" This commit is getting rid of a bunch of returned list pointers. --- acls.go | 52 +++++++++---------- acls_test.go | 49 +++++++++--------- oidc_test.go | 2 +- sharing_test.go | 130 +++++++++++++++++++++++++++++++++++++++++------- 4 files changed, 164 insertions(+), 69 deletions(-) diff --git a/acls.go b/acls.go index fea72a7f..4d4d45b3 100644 --- a/acls.go +++ b/acls.go @@ -15,13 +15,15 @@ import ( "tailscale.com/tailcfg" ) -const errorEmptyPolicy = Error("empty policy") -const errorInvalidAction = Error("invalid action") -const errorInvalidUserSection = Error("invalid user section") -const errorInvalidGroup = Error("invalid group") -const errorInvalidTag = Error("invalid tag") -const errorInvalidNamespace = Error("invalid namespace") -const errorInvalidPortFormat = Error("invalid port format") +const ( + errorEmptyPolicy = Error("empty policy") + errorInvalidAction = Error("invalid action") + errorInvalidUserSection = Error("invalid user section") + errorInvalidGroup = Error("invalid group") + errorInvalidTag = Error("invalid tag") + errorInvalidNamespace = Error("invalid namespace") + errorInvalidPortFormat = Error("invalid port format") +) // LoadACLPolicy loads the ACL policy from the specify path, and generates the ACL rules func (h *Headscale) LoadACLPolicy(path string) error { @@ -53,7 +55,7 @@ func (h *Headscale) LoadACLPolicy(path string) error { return nil } -func (h *Headscale) generateACLRules() (*[]tailcfg.FilterRule, error) { +func (h *Headscale) generateACLRules() ([]tailcfg.FilterRule, error) { rules := []tailcfg.FilterRule{} for i, a := range h.aclPolicy.ACLs { @@ -71,7 +73,7 @@ func (h *Headscale) generateACLRules() (*[]tailcfg.FilterRule, error) { Msgf("Error parsing ACL %d, User %d", i, j) return nil, err } - srcIPs = append(srcIPs, *srcs...) + srcIPs = append(srcIPs, srcs...) } r.SrcIPs = srcIPs @@ -83,7 +85,7 @@ func (h *Headscale) generateACLRules() (*[]tailcfg.FilterRule, error) { Msgf("Error parsing ACL %d, Port %d", i, j) return nil, err } - destPorts = append(destPorts, *dests...) + destPorts = append(destPorts, dests...) } rules = append(rules, tailcfg.FilterRule{ @@ -92,14 +94,14 @@ func (h *Headscale) generateACLRules() (*[]tailcfg.FilterRule, error) { }) } - return &rules, nil + return rules, nil } -func (h *Headscale) generateACLPolicySrcIP(u string) (*[]string, error) { +func (h *Headscale) generateACLPolicySrcIP(u string) ([]string, error) { return h.expandAlias(u) } -func (h *Headscale) generateACLPolicyDestPorts(d string) (*[]tailcfg.NetPortRange, error) { +func (h *Headscale) generateACLPolicyDestPorts(d string) ([]tailcfg.NetPortRange, error) { tokens := strings.Split(d, ":") if len(tokens) < 2 || len(tokens) > 3 { return nil, errorInvalidPortFormat @@ -128,7 +130,7 @@ func (h *Headscale) generateACLPolicyDestPorts(d string) (*[]tailcfg.NetPortRang } dests := []tailcfg.NetPortRange{} - for _, d := range *expanded { + for _, d := range expanded { for _, p := range *ports { pr := tailcfg.NetPortRange{ IP: d, @@ -137,12 +139,12 @@ func (h *Headscale) generateACLPolicyDestPorts(d string) (*[]tailcfg.NetPortRang dests = append(dests, pr) } } - return &dests, nil + return dests, nil } -func (h *Headscale) expandAlias(s string) (*[]string, error) { +func (h *Headscale) expandAlias(s string) ([]string, error) { if s == "*" { - return &[]string{"*"}, nil + return []string{"*"}, nil } if strings.HasPrefix(s, "group:") { @@ -155,11 +157,11 @@ func (h *Headscale) expandAlias(s string) (*[]string, error) { if err != nil { return nil, errorInvalidNamespace } - for _, node := range *nodes { + for _, node := range nodes { ips = append(ips, node.IPAddress) } } - return &ips, nil + return ips, nil } if strings.HasPrefix(s, "tag:") { @@ -195,7 +197,7 @@ func (h *Headscale) expandAlias(s string) (*[]string, error) { } } } - return &ips, nil + return ips, nil } n, err := h.GetNamespace(s) @@ -205,24 +207,24 @@ func (h *Headscale) expandAlias(s string) (*[]string, error) { return nil, err } ips := []string{} - for _, n := range *nodes { + for _, n := range nodes { ips = append(ips, n.IPAddress) } - return &ips, nil + return ips, nil } if h, ok := h.aclPolicy.Hosts[s]; ok { - return &[]string{h.String()}, nil + return []string{h.String()}, nil } ip, err := netaddr.ParseIP(s) if err == nil { - return &[]string{ip.String()}, nil + return []string{ip.String()}, nil } cidr, err := netaddr.ParseIPPrefix(s) if err == nil { - return &[]string{cidr.String()}, nil + return []string{cidr.String()}, nil } return nil, errorInvalidUserSection diff --git a/acls_test.go b/acls_test.go index dc5b4b31..da7f3ecc 100644 --- a/acls_test.go +++ b/acls_test.go @@ -12,7 +12,6 @@ func (s *Suite) TestWrongPath(c *check.C) { func (s *Suite) TestBrokenHuJson(c *check.C) { err := h.LoadACLPolicy("./tests/acls/broken.hujson") c.Assert(err, check.NotNil) - } func (s *Suite) TestInvalidPolicyHuson(c *check.C) { @@ -57,10 +56,10 @@ func (s *Suite) TestPortRange(c *check.C) { c.Assert(err, check.IsNil) c.Assert(rules, check.NotNil) - c.Assert(*rules, check.HasLen, 1) - c.Assert((*rules)[0].DstPorts, check.HasLen, 1) - c.Assert((*rules)[0].DstPorts[0].Ports.First, check.Equals, uint16(5400)) - c.Assert((*rules)[0].DstPorts[0].Ports.Last, check.Equals, uint16(5500)) + c.Assert(rules, check.HasLen, 1) + c.Assert((rules)[0].DstPorts, check.HasLen, 1) + c.Assert((rules)[0].DstPorts[0].Ports.First, check.Equals, uint16(5400)) + c.Assert((rules)[0].DstPorts[0].Ports.Last, check.Equals, uint16(5500)) } func (s *Suite) TestPortWildcard(c *check.C) { @@ -71,12 +70,12 @@ func (s *Suite) TestPortWildcard(c *check.C) { c.Assert(err, check.IsNil) c.Assert(rules, check.NotNil) - c.Assert(*rules, check.HasLen, 1) - c.Assert((*rules)[0].DstPorts, check.HasLen, 1) - c.Assert((*rules)[0].DstPorts[0].Ports.First, check.Equals, uint16(0)) - c.Assert((*rules)[0].DstPorts[0].Ports.Last, check.Equals, uint16(65535)) - c.Assert((*rules)[0].SrcIPs, check.HasLen, 1) - c.Assert((*rules)[0].SrcIPs[0], check.Equals, "*") + c.Assert(rules, check.HasLen, 1) + c.Assert((rules)[0].DstPorts, check.HasLen, 1) + c.Assert((rules)[0].DstPorts[0].Ports.First, check.Equals, uint16(0)) + c.Assert((rules)[0].DstPorts[0].Ports.Last, check.Equals, uint16(65535)) + c.Assert((rules)[0].SrcIPs, check.HasLen, 1) + c.Assert((rules)[0].SrcIPs[0], check.Equals, "*") } func (s *Suite) TestPortNamespace(c *check.C) { @@ -110,13 +109,13 @@ func (s *Suite) TestPortNamespace(c *check.C) { c.Assert(err, check.IsNil) c.Assert(rules, check.NotNil) - c.Assert(*rules, check.HasLen, 1) - c.Assert((*rules)[0].DstPorts, check.HasLen, 1) - c.Assert((*rules)[0].DstPorts[0].Ports.First, check.Equals, uint16(0)) - c.Assert((*rules)[0].DstPorts[0].Ports.Last, check.Equals, uint16(65535)) - c.Assert((*rules)[0].SrcIPs, check.HasLen, 1) - c.Assert((*rules)[0].SrcIPs[0], check.Not(check.Equals), "not an ip") - c.Assert((*rules)[0].SrcIPs[0], check.Equals, ip.String()) + c.Assert(rules, check.HasLen, 1) + c.Assert((rules)[0].DstPorts, check.HasLen, 1) + c.Assert((rules)[0].DstPorts[0].Ports.First, check.Equals, uint16(0)) + c.Assert((rules)[0].DstPorts[0].Ports.Last, check.Equals, uint16(65535)) + c.Assert((rules)[0].SrcIPs, check.HasLen, 1) + c.Assert((rules)[0].SrcIPs[0], check.Not(check.Equals), "not an ip") + c.Assert((rules)[0].SrcIPs[0], check.Equals, ip.String()) } func (s *Suite) TestPortGroup(c *check.C) { @@ -150,11 +149,11 @@ func (s *Suite) TestPortGroup(c *check.C) { c.Assert(err, check.IsNil) c.Assert(rules, check.NotNil) - c.Assert(*rules, check.HasLen, 1) - c.Assert((*rules)[0].DstPorts, check.HasLen, 1) - c.Assert((*rules)[0].DstPorts[0].Ports.First, check.Equals, uint16(0)) - c.Assert((*rules)[0].DstPorts[0].Ports.Last, check.Equals, uint16(65535)) - c.Assert((*rules)[0].SrcIPs, check.HasLen, 1) - c.Assert((*rules)[0].SrcIPs[0], check.Not(check.Equals), "not an ip") - c.Assert((*rules)[0].SrcIPs[0], check.Equals, ip.String()) + c.Assert(rules, check.HasLen, 1) + c.Assert((rules)[0].DstPorts, check.HasLen, 1) + c.Assert((rules)[0].DstPorts[0].Ports.First, check.Equals, uint16(0)) + c.Assert((rules)[0].DstPorts[0].Ports.Last, check.Equals, uint16(65535)) + c.Assert((rules)[0].SrcIPs, check.HasLen, 1) + c.Assert((rules)[0].SrcIPs[0], check.Not(check.Equals), "not an ip") + c.Assert((rules)[0].SrcIPs[0], check.Equals, ip.String()) } diff --git a/oidc_test.go b/oidc_test.go index b501ff14..c7a29ce9 100644 --- a/oidc_test.go +++ b/oidc_test.go @@ -22,7 +22,7 @@ func TestHeadscale_getNamespaceFromEmail(t *testing.T) { publicKey *wgkey.Key privateKey *wgkey.Private aclPolicy *ACLPolicy - aclRules *[]tailcfg.FilterRule + aclRules []tailcfg.FilterRule lastStateChange sync.Map oidcProvider *oidc.Provider oauth2Config *oauth2.Config diff --git a/sharing_test.go b/sharing_test.go index 1133fd92..4d9e4092 100644 --- a/sharing_test.go +++ b/sharing_test.go @@ -35,8 +35,20 @@ func CreateNodeNamespace(c *check.C, namespace, node, key, IP string) (*Namespac } func (s *Suite) TestBasicSharedNodesInNamespace(c *check.C) { - n1, m1 := CreateNodeNamespace(c, "shared1", "test_get_shared_nodes_1", "686824e749f3b7f2a5927ee6c1e422aee5292592d9179a271ed7b3e659b44a66", "100.64.0.1") - _, m2 := CreateNodeNamespace(c, "shared2", "test_get_shared_nodes_2", "dec46ef9dc45c7d2f03bfcd5a640d9e24e3cc68ce3d9da223867c9bc6d5e9863", "100.64.0.2") + n1, m1 := CreateNodeNamespace( + c, + "shared1", + "test_get_shared_nodes_1", + "686824e749f3b7f2a5927ee6c1e422aee5292592d9179a271ed7b3e659b44a66", + "100.64.0.1", + ) + _, m2 := CreateNodeNamespace( + c, + "shared2", + "test_get_shared_nodes_2", + "dec46ef9dc45c7d2f03bfcd5a640d9e24e3cc68ce3d9da223867c9bc6d5e9863", + "100.64.0.2", + ) p1s, err := h.getPeers(m1) c.Assert(err, check.IsNil) @@ -52,7 +64,13 @@ func (s *Suite) TestBasicSharedNodesInNamespace(c *check.C) { } func (s *Suite) TestSameNamespace(c *check.C) { - n1, m1 := CreateNodeNamespace(c, "shared1", "test_get_shared_nodes_1", "686824e749f3b7f2a5927ee6c1e422aee5292592d9179a271ed7b3e659b44a66", "100.64.0.1") + n1, m1 := CreateNodeNamespace( + c, + "shared1", + "test_get_shared_nodes_1", + "686824e749f3b7f2a5927ee6c1e422aee5292592d9179a271ed7b3e659b44a66", + "100.64.0.1", + ) p1s, err := h.getPeers(m1) c.Assert(err, check.IsNil) @@ -63,8 +81,20 @@ func (s *Suite) TestSameNamespace(c *check.C) { } func (s *Suite) TestUnshare(c *check.C) { - n1, m1 := CreateNodeNamespace(c, "shared1", "test_unshare_1", "686824e749f3b7f2a5927ee6c1e422aee5292592d9179a271ed7b3e659b44a66", "100.64.0.1") - _, m2 := CreateNodeNamespace(c, "shared2", "test_unshare_2", "dec46ef9dc45c7d2f03bfcd5a640d9e24e3cc68ce3d9da223867c9bc6d5e9863", "100.64.0.2") + n1, m1 := CreateNodeNamespace( + c, + "shared1", + "test_unshare_1", + "686824e749f3b7f2a5927ee6c1e422aee5292592d9179a271ed7b3e659b44a66", + "100.64.0.1", + ) + _, m2 := CreateNodeNamespace( + c, + "shared2", + "test_unshare_2", + "dec46ef9dc45c7d2f03bfcd5a640d9e24e3cc68ce3d9da223867c9bc6d5e9863", + "100.64.0.2", + ) p1s, err := h.getPeers(m1) c.Assert(err, check.IsNil) @@ -92,8 +122,20 @@ func (s *Suite) TestUnshare(c *check.C) { } func (s *Suite) TestAlreadyShared(c *check.C) { - n1, m1 := CreateNodeNamespace(c, "shared1", "test_get_shared_nodes_1", "686824e749f3b7f2a5927ee6c1e422aee5292592d9179a271ed7b3e659b44a66", "100.64.0.1") - _, m2 := CreateNodeNamespace(c, "shared2", "test_get_shared_nodes_2", "dec46ef9dc45c7d2f03bfcd5a640d9e24e3cc68ce3d9da223867c9bc6d5e9863", "100.64.0.2") + n1, m1 := CreateNodeNamespace( + c, + "shared1", + "test_get_shared_nodes_1", + "686824e749f3b7f2a5927ee6c1e422aee5292592d9179a271ed7b3e659b44a66", + "100.64.0.1", + ) + _, m2 := CreateNodeNamespace( + c, + "shared2", + "test_get_shared_nodes_2", + "dec46ef9dc45c7d2f03bfcd5a640d9e24e3cc68ce3d9da223867c9bc6d5e9863", + "100.64.0.2", + ) p1s, err := h.getPeers(m1) c.Assert(err, check.IsNil) @@ -106,8 +148,20 @@ func (s *Suite) TestAlreadyShared(c *check.C) { } func (s *Suite) TestDoNotIncludeRoutesOnShared(c *check.C) { - n1, m1 := CreateNodeNamespace(c, "shared1", "test_get_shared_nodes_1", "686824e749f3b7f2a5927ee6c1e422aee5292592d9179a271ed7b3e659b44a66", "100.64.0.1") - _, m2 := CreateNodeNamespace(c, "shared2", "test_get_shared_nodes_2", "dec46ef9dc45c7d2f03bfcd5a640d9e24e3cc68ce3d9da223867c9bc6d5e9863", "100.64.0.2") + n1, m1 := CreateNodeNamespace( + c, + "shared1", + "test_get_shared_nodes_1", + "686824e749f3b7f2a5927ee6c1e422aee5292592d9179a271ed7b3e659b44a66", + "100.64.0.1", + ) + _, m2 := CreateNodeNamespace( + c, + "shared2", + "test_get_shared_nodes_2", + "dec46ef9dc45c7d2f03bfcd5a640d9e24e3cc68ce3d9da223867c9bc6d5e9863", + "100.64.0.2", + ) p1s, err := h.getPeers(m1) c.Assert(err, check.IsNil) @@ -123,9 +177,27 @@ func (s *Suite) TestDoNotIncludeRoutesOnShared(c *check.C) { } func (s *Suite) TestComplexSharingAcrossNamespaces(c *check.C) { - n1, m1 := CreateNodeNamespace(c, "shared1", "test_get_shared_nodes_1", "686824e749f3b7f2a5927ee6c1e422aee5292592d9179a271ed7b3e659b44a66", "100.64.0.1") - _, m2 := CreateNodeNamespace(c, "shared2", "test_get_shared_nodes_2", "dec46ef9dc45c7d2f03bfcd5a640d9e24e3cc68ce3d9da223867c9bc6d5e9863", "100.64.0.2") - _, m3 := CreateNodeNamespace(c, "shared3", "test_get_shared_nodes_3", "6e704bee83eb93db6fc2c417d7882964cd3f8cc87082cbb645982e34020c76c8", "100.64.0.3") + n1, m1 := CreateNodeNamespace( + c, + "shared1", + "test_get_shared_nodes_1", + "686824e749f3b7f2a5927ee6c1e422aee5292592d9179a271ed7b3e659b44a66", + "100.64.0.1", + ) + _, m2 := CreateNodeNamespace( + c, + "shared2", + "test_get_shared_nodes_2", + "dec46ef9dc45c7d2f03bfcd5a640d9e24e3cc68ce3d9da223867c9bc6d5e9863", + "100.64.0.2", + ) + _, m3 := CreateNodeNamespace( + c, + "shared3", + "test_get_shared_nodes_3", + "6e704bee83eb93db6fc2c417d7882964cd3f8cc87082cbb645982e34020c76c8", + "100.64.0.3", + ) pak4, err := h.CreatePreAuthKey(n1.Name, false, false, nil) c.Assert(err, check.IsNil) @@ -172,15 +244,37 @@ func (s *Suite) TestComplexSharingAcrossNamespaces(c *check.C) { pSharedTo, err := h.getPeers(m2) c.Assert(err, check.IsNil) - c.Assert(len(pSharedTo), check.Equals, 2) // node2 should see node1 (sharedTo) and node4 (sharedTo), as is shared in namespace1 + c.Assert( + len(pSharedTo), + check.Equals, + 2, + ) // node2 should see node1 (sharedTo) and node4 (sharedTo), as is shared in namespace1 c.Assert(pSharedTo[0].Name, check.Equals, m1.Name) c.Assert(pSharedTo[1].Name, check.Equals, m4.Name) } func (s *Suite) TestDeleteSharedMachine(c *check.C) { - n1, m1 := CreateNodeNamespace(c, "shared1", "test_get_shared_nodes_1", "686824e749f3b7f2a5927ee6c1e422aee5292592d9179a271ed7b3e659b44a66", "100.64.0.1") - _, m2 := CreateNodeNamespace(c, "shared2", "test_get_shared_nodes_2", "dec46ef9dc45c7d2f03bfcd5a640d9e24e3cc68ce3d9da223867c9bc6d5e9863", "100.64.0.2") - _, m3 := CreateNodeNamespace(c, "shared3", "test_get_shared_nodes_3", "6e704bee83eb93db6fc2c417d7882964cd3f8cc87082cbb645982e34020c76c8", "100.64.0.3") + n1, m1 := CreateNodeNamespace( + c, + "shared1", + "test_get_shared_nodes_1", + "686824e749f3b7f2a5927ee6c1e422aee5292592d9179a271ed7b3e659b44a66", + "100.64.0.1", + ) + _, m2 := CreateNodeNamespace( + c, + "shared2", + "test_get_shared_nodes_2", + "dec46ef9dc45c7d2f03bfcd5a640d9e24e3cc68ce3d9da223867c9bc6d5e9863", + "100.64.0.2", + ) + _, m3 := CreateNodeNamespace( + c, + "shared3", + "test_get_shared_nodes_3", + "6e704bee83eb93db6fc2c417d7882964cd3f8cc87082cbb645982e34020c76c8", + "100.64.0.3", + ) pak4n1, err := h.CreatePreAuthKey(n1.Name, false, false, nil) c.Assert(err, check.IsNil) @@ -226,12 +320,12 @@ func (s *Suite) TestDeleteSharedMachine(c *check.C) { sharedMachines, err := h.ListSharedMachinesInNamespace(n1.Name) c.Assert(err, check.IsNil) - c.Assert(len(*sharedMachines), check.Equals, 1) + c.Assert(len(sharedMachines), check.Equals, 1) err = h.DeleteMachine(m2) c.Assert(err, check.IsNil) sharedMachines, err = h.ListSharedMachinesInNamespace(n1.Name) c.Assert(err, check.IsNil) - c.Assert(len(*sharedMachines), check.Equals, 0) + c.Assert(len(sharedMachines), check.Equals, 0) } From 9acc3e0e73693ced0ce526b37b3366571d7135fe Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Thu, 4 Nov 2021 22:17:44 +0000 Subject: [PATCH 077/300] Add a set of ip prefix convert helpers --- utils.go | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/utils.go b/utils.go index 555227ec..ad0a72d7 100644 --- a/utils.go +++ b/utils.go @@ -163,3 +163,38 @@ func GrpcSocketDialer(ctx context.Context, addr string) (net.Conn, error) { var d net.Dialer return d.DialContext(ctx, "unix", addr) } + +func ipPrefixToString(prefixes []netaddr.IPPrefix) []string { + result := make([]string, len(prefixes)) + + for index, prefix := range prefixes { + result[index] = prefix.String() + } + + return result +} + +func stringToIpPrefix(prefixes []string) ([]netaddr.IPPrefix, error) { + result := make([]netaddr.IPPrefix, len(prefixes)) + + for index, prefixStr := range prefixes { + prefix, err := netaddr.ParseIPPrefix(prefixStr) + if err != nil { + return []netaddr.IPPrefix{}, err + } + + result[index] = prefix + } + + return result, nil +} + +func containsIpPrefix(prefixes []netaddr.IPPrefix, prefix netaddr.IPPrefix) bool { + for _, p := range prefixes { + if prefix == p { + return true + } + } + + return false +} From c2eb3f4d3605b25584644cfd365ab6caec92d198 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Thu, 4 Nov 2021 22:18:06 +0000 Subject: [PATCH 078/300] Use long command in example and remove pointerlist --- api.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api.go b/api.go index ad87a7e9..490ce258 100644 --- a/api.go +++ b/api.go @@ -44,7 +44,7 @@ func (h *Headscale) RegisterWebAPI(c *gin.Context) {

- headscale -n NAMESPACE nodes register -k %s + headscale -n NAMESPACE nodes register --key %s

@@ -306,7 +306,7 @@ func (h *Headscale) getMapResponse(mKey wgkey.Key, req tailcfg.MapRequest, m *Ma Peers: nodePeers, DNSConfig: dnsConfig, Domain: h.cfg.BaseDomain, - PacketFilter: *h.aclRules, + PacketFilter: h.aclRules, DERPMap: h.DERPMap, UserProfiles: profiles, } From 706ff59d70f91dfc133d483a772006aea8b386fd Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Thu, 4 Nov 2021 22:18:55 +0000 Subject: [PATCH 079/300] Clean pointer list in app.go, add grpc logging and simplify naming --- app.go | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/app.go b/app.go index 1f456665..97333b1f 100644 --- a/app.go +++ b/app.go @@ -22,8 +22,10 @@ import ( "golang.org/x/oauth2" "github.com/gin-gonic/gin" + "github.com/grpc-ecosystem/go-grpc-middleware" "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" - apiV1 "github.com/juanfont/headscale/gen/go/headscale/v1" + v1 "github.com/juanfont/headscale/gen/go/headscale/v1" + "github.com/philip-bui/grpc-zerolog" "github.com/rs/zerolog/log" "github.com/soheilhy/cmux" ginprometheus "github.com/zsais/go-gin-prometheus" @@ -115,7 +117,7 @@ type Headscale struct { DERPMap *tailcfg.DERPMap aclPolicy *ACLPolicy - aclRules *[]tailcfg.FilterRule + aclRules []tailcfg.FilterRule lastStateChange sync.Map @@ -154,7 +156,7 @@ func NewHeadscale(cfg Config) (*Headscale, error) { dbString: dbString, privateKey: privKey, publicKey: &pubKey, - aclRules: &tailcfg.FilterAllowAll, // default allowall + aclRules: tailcfg.FilterAllowAll, // default allowall } err = h.initDB() @@ -209,7 +211,7 @@ func (h *Headscale) expireEphemeralNodesWorker() { return } - for _, ns := range *namespaces { + for _, ns := range namespaces { machines, err := h.ListMachinesInNamespace(ns.Name) if err != nil { log.Error().Err(err).Str("namespace", ns.Name).Msg("Error listing machines in namespace") @@ -217,7 +219,7 @@ func (h *Headscale) expireEphemeralNodesWorker() { return } - for _, m := range *machines { + for _, m := range machines { if m.AuthKey != nil && m.LastSeen != nil && m.AuthKey.Ephemeral && time.Now().After(m.LastSeen.Add(h.cfg.EphemeralNodeInactivityTimeout)) { log.Info().Str("machine", m.Name).Msg("Ephemeral client removed from database") @@ -399,7 +401,7 @@ func (h *Headscale) Serve() error { // Connect to the gRPC server over localhost to skip // the authentication. - err = apiV1.RegisterHeadscaleServiceHandler(ctx, grpcGatewayMux, grpcGatewayConn) + err = v1.RegisterHeadscaleServiceHandler(ctx, grpcGatewayMux, grpcGatewayConn) if err != nil { return err } @@ -456,7 +458,10 @@ func (h *Headscale) Serve() error { grpcOptions := []grpc.ServerOption{ grpc.UnaryInterceptor( - h.grpcAuthenticationInterceptor, + grpc_middleware.ChainUnaryServer( + h.grpcAuthenticationInterceptor, + zerolog.NewUnaryServerInterceptor(), + ), ), } @@ -476,10 +481,10 @@ func (h *Headscale) Serve() error { grpcServer := grpc.NewServer(grpcOptions...) // Start the local gRPC server without TLS and without authentication - grpcSocket := grpc.NewServer() + grpcSocket := grpc.NewServer(zerolog.UnaryInterceptor()) - apiV1.RegisterHeadscaleServiceServer(grpcServer, newHeadscaleV1APIServer(h)) - apiV1.RegisterHeadscaleServiceServer(grpcSocket, newHeadscaleV1APIServer(h)) + v1.RegisterHeadscaleServiceServer(grpcServer, newHeadscaleV1APIServer(h)) + v1.RegisterHeadscaleServiceServer(grpcSocket, newHeadscaleV1APIServer(h)) reflection.Register(grpcServer) reflection.Register(grpcSocket) From 3eed356d70780318077ac52cc25a5f9c0086c9cf Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Thu, 4 Nov 2021 22:19:27 +0000 Subject: [PATCH 080/300] Implement rpc calls with new helper functions, implementing the proto spec --- grpcv1.go | 351 +++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 324 insertions(+), 27 deletions(-) diff --git a/grpcv1.go b/grpcv1.go index 08c977b8..0a28fbe6 100644 --- a/grpcv1.go +++ b/grpcv1.go @@ -3,73 +3,370 @@ package headscale import ( "context" + "encoding/json" + "time" - apiV1 "github.com/juanfont/headscale/gen/go/headscale/v1" + "github.com/juanfont/headscale/gen/go/headscale/v1" + "github.com/rs/zerolog/log" + "gorm.io/datatypes" + "tailscale.com/tailcfg" ) -type headscaleV1APIServer struct { // apiV1.HeadscaleServiceServer - apiV1.UnimplementedHeadscaleServiceServer +type headscaleV1APIServer struct { // v1.HeadscaleServiceServer + v1.UnimplementedHeadscaleServiceServer h *Headscale } -func newHeadscaleV1APIServer(h *Headscale) apiV1.HeadscaleServiceServer { +func newHeadscaleV1APIServer(h *Headscale) v1.HeadscaleServiceServer { return headscaleV1APIServer{ h: h, } } -func (api headscaleV1APIServer) GetMachine( +func (api headscaleV1APIServer) GetNamespace( ctx context.Context, - request *apiV1.GetMachineRequest, -) (*apiV1.GetMachineResponse, error) { - // m, err := api.h.GetMachineByID(request.MachineId) - // if err != nil { - // return nil, err - // } + request *v1.GetNamespaceRequest, +) (*v1.GetNamespaceResponse, error) { + namespace, err := api.h.GetNamespace(request.GetName()) + if err != nil { + return nil, err + } - // TODO(kradalby): Make this function actually do something - return &apiV1.GetMachineResponse{Name: "test"}, nil + return &v1.GetNamespaceResponse{Namespace: namespace.toProto()}, nil } func (api headscaleV1APIServer) CreateNamespace( ctx context.Context, - request *apiV1.CreateNamespaceRequest, -) (*apiV1.CreateNamespaceResponse, error) { - namespace, err := api.h.CreateNamespace(request.Name) + request *v1.CreateNamespaceRequest, +) (*v1.CreateNamespaceResponse, error) { + namespace, err := api.h.CreateNamespace(request.GetName()) if err != nil { return nil, err } - return &apiV1.CreateNamespaceResponse{Name: namespace.Name}, nil + return &v1.CreateNamespaceResponse{Namespace: namespace.toProto()}, nil +} + +func (api headscaleV1APIServer) RenameNamespace( + ctx context.Context, + request *v1.RenameNamespaceRequest, +) (*v1.RenameNamespaceResponse, error) { + err := api.h.RenameNamespace(request.GetOldName(), request.GetNewName()) + if err != nil { + return nil, err + } + + namespace, err := api.h.GetNamespace(request.GetNewName()) + if err != nil { + return nil, err + } + + return &v1.RenameNamespaceResponse{Namespace: namespace.toProto()}, nil } func (api headscaleV1APIServer) DeleteNamespace( ctx context.Context, - request *apiV1.DeleteNamespaceRequest, -) (*apiV1.DeleteNamespaceResponse, error) { - err := api.h.DestroyNamespace(request.Name) + request *v1.DeleteNamespaceRequest, +) (*v1.DeleteNamespaceResponse, error) { + err := api.h.DestroyNamespace(request.GetName()) if err != nil { return nil, err } - return &apiV1.DeleteNamespaceResponse{}, nil + return &v1.DeleteNamespaceResponse{}, nil } func (api headscaleV1APIServer) ListNamespaces( ctx context.Context, - request *apiV1.ListNamespacesRequest, -) (*apiV1.ListNamespacesResponse, error) { + request *v1.ListNamespacesRequest, +) (*v1.ListNamespacesResponse, error) { namespaces, err := api.h.ListNamespaces() if err != nil { return nil, err } - response := make([]string, len(*namespaces)) - for index, namespace := range *namespaces { - response[index] = namespace.Name + response := make([]*v1.Namespace, len(namespaces)) + for index, namespace := range namespaces { + response[index] = namespace.toProto() } - return &apiV1.ListNamespacesResponse{Namespaces: response}, nil + log.Trace().Caller().Interface("namespaces", response).Msg("") + + return &v1.ListNamespacesResponse{Namespaces: response}, nil +} + +func (api headscaleV1APIServer) CreatePreAuthKey( + ctx context.Context, + request *v1.CreatePreAuthKeyRequest, +) (*v1.CreatePreAuthKeyResponse, error) { + expiration := request.GetExpiration().AsTime() + preAuthKey, err := api.h.CreatePreAuthKey( + request.GetNamespace(), + request.GetResuable(), + request.GetEphemeral(), + &expiration, + ) + if err != nil { + return nil, err + } + + return &v1.CreatePreAuthKeyResponse{PreAuthKey: preAuthKey.toProto()}, nil +} + +func (api headscaleV1APIServer) ExpirePreAuthKey( + ctx context.Context, + request *v1.ExpirePreAuthKeyRequest, +) (*v1.ExpirePreAuthKeyResponse, error) { + preAuthKey, err := api.h.GetPreAuthKey(request.GetNamespace(), request.Key) + if err != nil { + return nil, err + } + + err = api.h.ExpirePreAuthKey(preAuthKey) + if err != nil { + return nil, err + } + + return &v1.ExpirePreAuthKeyResponse{}, nil +} + +func (api headscaleV1APIServer) ListPreAuthKeys( + ctx context.Context, + request *v1.ListPreAuthKeysRequest, +) (*v1.ListPreAuthKeysResponse, error) { + preAuthKeys, err := api.h.ListPreAuthKeys(request.GetNamespace()) + if err != nil { + return nil, err + } + + response := make([]*v1.PreAuthKey, len(preAuthKeys)) + for index, key := range preAuthKeys { + response[index] = key.toProto() + } + + return &v1.ListPreAuthKeysResponse{PreAuthKeys: response}, nil +} + +func (api headscaleV1APIServer) RegisterMachine( + ctx context.Context, + request *v1.RegisterMachineRequest, +) (*v1.RegisterMachineResponse, error) { + machine, err := api.h.RegisterMachine( + request.GetKey(), + request.GetNamespace(), + ) + if err != nil { + return nil, err + } + + return &v1.RegisterMachineResponse{Machine: machine.toProto()}, nil +} + +func (api headscaleV1APIServer) GetMachine( + ctx context.Context, + request *v1.GetMachineRequest, +) (*v1.GetMachineResponse, error) { + machine, err := api.h.GetMachineByID(request.GetMachineId()) + if err != nil { + return nil, err + } + + return &v1.GetMachineResponse{Machine: machine.toProto()}, nil +} + +func (api headscaleV1APIServer) DeleteMachine( + ctx context.Context, + request *v1.DeleteMachineRequest, +) (*v1.DeleteMachineResponse, error) { + machine, err := api.h.GetMachineByID(request.GetMachineId()) + if err != nil { + return nil, err + } + + err = api.h.DeleteMachine( + machine, + ) + if err != nil { + return nil, err + } + + return &v1.DeleteMachineResponse{}, nil +} + +func (api headscaleV1APIServer) ListMachines( + ctx context.Context, + request *v1.ListMachinesRequest, +) (*v1.ListMachinesResponse, error) { + if request.GetNamespace() != "" { + machines, err := api.h.ListMachinesInNamespace(request.GetNamespace()) + if err != nil { + return nil, err + } + + sharedMachines, err := api.h.ListSharedMachinesInNamespace(request.GetNamespace()) + if err != nil { + return nil, err + } + + machines = append(machines, sharedMachines...) + + response := make([]*v1.Machine, len(machines)) + for index, machine := range machines { + response[index] = machine.toProto() + } + + return &v1.ListMachinesResponse{Machines: response}, nil + } + + machines, err := api.h.ListMachines() + if err != nil { + return nil, err + } + + response := make([]*v1.Machine, len(machines)) + for index, machine := range machines { + response[index] = machine.toProto() + } + + return &v1.ListMachinesResponse{Machines: response}, nil +} + +func (api headscaleV1APIServer) ShareMachine( + ctx context.Context, + request *v1.ShareMachineRequest, +) (*v1.ShareMachineResponse, error) { + destinationNamespace, err := api.h.GetNamespace(request.GetNamespace()) + if err != nil { + return nil, err + } + + machine, err := api.h.GetMachineByID(request.GetMachineId()) + if err != nil { + return nil, err + } + + err = api.h.AddSharedMachineToNamespace(machine, destinationNamespace) + if err != nil { + return nil, err + } + + return &v1.ShareMachineResponse{Machine: machine.toProto()}, nil +} + +func (api headscaleV1APIServer) UnshareMachine( + ctx context.Context, + request *v1.UnshareMachineRequest, +) (*v1.UnshareMachineResponse, error) { + destinationNamespace, err := api.h.GetNamespace(request.GetNamespace()) + if err != nil { + return nil, err + } + + machine, err := api.h.GetMachineByID(request.GetMachineId()) + if err != nil { + return nil, err + } + + err = api.h.RemoveSharedMachineFromNamespace(machine, destinationNamespace) + if err != nil { + return nil, err + } + + return &v1.UnshareMachineResponse{Machine: machine.toProto()}, nil +} + +func (api headscaleV1APIServer) GetMachineRoute( + ctx context.Context, + request *v1.GetMachineRouteRequest, +) (*v1.GetMachineRouteResponse, error) { + machine, err := api.h.GetMachineByID(request.GetMachineId()) + if err != nil { + return nil, err + } + + routes, err := machine.RoutesToProto() + if err != nil { + return nil, err + } + + return &v1.GetMachineRouteResponse{ + Routes: routes, + }, nil +} + +func (api headscaleV1APIServer) EnableMachineRoutes( + ctx context.Context, + request *v1.EnableMachineRoutesRequest, +) (*v1.EnableMachineRoutesResponse, error) { + machine, err := api.h.GetMachineByID(request.GetMachineId()) + if err != nil { + return nil, err + } + + err = api.h.EnableRoutes(machine, request.GetRoutes()...) + if err != nil { + return nil, err + } + + routes, err := machine.RoutesToProto() + if err != nil { + return nil, err + } + + return &v1.EnableMachineRoutesResponse{ + Routes: routes, + }, nil +} + +// The following service calls are for testing and debugging +func (api headscaleV1APIServer) DebugCreateMachine( + ctx context.Context, + request *v1.DebugCreateMachineRequest, +) (*v1.DebugCreateMachineResponse, error) { + namespace, err := api.h.GetNamespace(request.GetNamespace()) + if err != nil { + return nil, err + } + + routes, err := stringToIpPrefix(request.GetRoutes()) + if err != nil { + return nil, err + } + + log.Trace().Caller().Interface("route-prefix", routes).Interface("route-str", request.GetRoutes()).Msg("") + + hostinfo := tailcfg.Hostinfo{ + RoutableIPs: routes, + OS: "TestOS", + Hostname: "DebugTestMachine", + } + + log.Trace().Caller().Interface("hostinfo", hostinfo).Msg("") + + hostinfoJson, err := json.Marshal(hostinfo) + if err != nil { + return nil, err + } + + newMachine := Machine{ + MachineKey: request.GetKey(), + Name: request.GetName(), + Namespace: *namespace, + + Expiry: &time.Time{}, + LastSeen: &time.Time{}, + LastSuccessfulUpdate: &time.Time{}, + + HostInfo: datatypes.JSON(hostinfoJson), + } + + // log.Trace().Caller().Interface("machine", newMachine).Msg("") + + if err := api.h.db.Create(&newMachine).Error; err != nil { + return nil, err + } + + return &v1.DebugCreateMachineResponse{Machine: newMachine.toProto()}, nil } func (api headscaleV1APIServer) mustEmbedUnimplementedHeadscaleServiceServer() {} From 319237910bb8cd6f02275f668a03e7421be6370f Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Thu, 4 Nov 2021 22:28:35 +0000 Subject: [PATCH 081/300] Resolve new dependencies --- go.mod | 44 +++++---- go.sum | 295 +++++++++++++++++++-------------------------------------- 2 files changed, 127 insertions(+), 212 deletions(-) diff --git a/go.mod b/go.mod index 296def85..6056c8bc 100644 --- a/go.mod +++ b/go.mod @@ -6,6 +6,7 @@ require ( github.com/AlecAivazis/survey/v2 v2.3.2 github.com/Microsoft/go-winio v0.5.0 // indirect github.com/cenkalti/backoff/v4 v4.1.1 // indirect + github.com/cespare/xxhash/v2 v2.1.2 // indirect github.com/containerd/continuity v0.1.0 // indirect github.com/coreos/go-oidc/v3 v3.1.0 github.com/docker/cli v20.10.8+incompatible // indirect @@ -13,44 +14,55 @@ require ( github.com/efekarakus/termcolor v1.0.1 github.com/fatih/set v0.2.1 github.com/gin-gonic/gin v1.7.4 - github.com/gofrs/uuid v4.0.0+incompatible + github.com/go-playground/validator/v10 v10.9.0 // indirect + github.com/gofrs/uuid v4.1.0+incompatible github.com/google/go-github v17.0.0+incompatible // indirect github.com/google/go-querystring v1.1.0 // indirect + github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 github.com/grpc-ecosystem/grpc-gateway/v2 v2.6.0 github.com/hako/durafmt v0.0.0-20210608085754-5c1018a4e16b + github.com/hashicorp/go-version v1.2.0 // indirect github.com/infobloxopen/protoc-gen-gorm v1.0.1 - github.com/klauspost/compress v1.13.5 + github.com/json-iterator/go v1.1.12 // indirect + github.com/klauspost/compress v1.13.6 github.com/lib/pq v1.10.3 // indirect + github.com/mattn/go-isatty v0.0.14 // indirect github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6 // indirect github.com/opencontainers/runc v1.0.2 // indirect github.com/ory/dockertest/v3 v3.7.0 github.com/patrickmn/go-cache v2.1.0+incompatible + github.com/philip-bui/grpc-zerolog v1.0.1 github.com/prometheus/client_golang v1.11.0 + github.com/prometheus/common v0.32.1 // indirect + github.com/prometheus/procfs v0.7.3 // indirect github.com/pterm/pterm v0.12.30 - github.com/rs/zerolog v1.25.0 + github.com/rs/zerolog v1.26.0 github.com/soheilhy/cmux v0.1.5 github.com/spf13/cobra v1.2.1 github.com/spf13/viper v1.8.1 github.com/stretchr/testify v1.7.0 - github.com/tailscale/hujson v0.0.0-20210818175511-7360507a6e88 + github.com/tailscale/hujson v0.0.0-20210923003652-c3758b31534b github.com/tcnksm/go-latest v0.0.0-20170313132115-e3007ae9052e + github.com/ugorji/go v1.2.6 // indirect github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect github.com/zsais/go-gin-prometheus v0.1.0 - golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 - golang.org/x/net v0.0.0-20210913180222-943fd674d43e // indirect - golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f + go4.org/mem v0.0.0-20210711025021-927187094b94 // indirect + golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 + golang.org/x/net v0.0.0-20211104170005-ce137452f963 // indirect + golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 golang.org/x/sync v0.0.0-20210220032951-036812b2e83c - golang.org/x/sys v0.0.0-20210910150752-751e447fb3d0 // indirect - google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83 - google.golang.org/grpc v1.40.0 + golang.org/x/sys v0.0.0-20211103235746-7861aae1554b // indirect + google.golang.org/genproto v0.0.0-20211104193956-4c6863e31247 + google.golang.org/grpc v1.42.0 google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0 google.golang.org/protobuf v1.27.1 gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c + gopkg.in/square/go-jose.v2 v2.6.0 // indirect gopkg.in/yaml.v2 v2.4.0 - gorm.io/datatypes v1.0.2 - gorm.io/driver/postgres v1.1.1 - gorm.io/driver/sqlite v1.1.5 - gorm.io/gorm v1.21.15 - inet.af/netaddr v0.0.0-20210903134321-85fa6c94624e - tailscale.com v1.14.2 + gorm.io/datatypes v1.0.3 + gorm.io/driver/postgres v1.2.1 + gorm.io/driver/sqlite v1.2.3 + gorm.io/gorm v1.22.2 + inet.af/netaddr v0.0.0-20211027220019-c74959edd3b6 + tailscale.com v1.14.6 ) diff --git a/go.sum b/go.sum index 96eb50bd..ae1e0935 100644 --- a/go.sum +++ b/go.sum @@ -40,6 +40,7 @@ cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RX cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= contrib.go.opencensus.io/exporter/ocagent v0.7.0/go.mod h1:IshRmMJBhDfFj5Y67nVhMYTTIze91RUeT73ipWKs/GY= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +filippo.io/mkcert v1.4.3/go.mod h1:64ke566uBwAQcdK3vRDABgsgVHqrfORPTw6YytZCTxk= github.com/AlecAivazis/survey/v2 v2.3.2 h1:TqTB+aDDCLYhf9/bD2TwSO8u8jDSmMUd2SUVO4gCnU8= github.com/AlecAivazis/survey/v2 v2.3.2/go.mod h1:TH2kPCDU3Kqq7pLbnCWwZXDBjnhZtmsCle5EiYDJ2fg= github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= @@ -50,7 +51,6 @@ github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= github.com/Djarvur/go-err113 v0.0.0-20200511133814-5174e21577d5/go.mod h1:4UJr5HIiMZrwgkSPdsjy2uOQExX/WEILpIrO9UPGuXs= github.com/Djarvur/go-err113 v0.1.0/go.mod h1:4UJr5HIiMZrwgkSPdsjy2uOQExX/WEILpIrO9UPGuXs= -github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= github.com/MarvinJWendt/testza v0.1.0/go.mod h1:7AxNvlfeHP7Z/hDQ5JtE3OKYT3XFUeLCDE2DQninSqs= github.com/MarvinJWendt/testza v0.2.1 h1:eitywm1lzygA2KCyn55jFVdOaXj5I9LeOsLNeifd2Kw= github.com/MarvinJWendt/testza v0.2.1/go.mod h1:God7bhG8n6uQxwdScay+gjm9/LnO4D3kkcZX4hv9Rp8= @@ -73,11 +73,7 @@ github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8 github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/OpenPeeDeeP/depguard v1.0.1/go.mod h1:xsIw86fROiiwelg+jB2uM9PiKihMMmUx/1V+TNhjQvM= github.com/PuerkitoBio/goquery v1.5.1/go.mod h1:GsLWisAFVj4WgDibEWF4pvYnkVQBpKBKeU+7zCJoLcc= -github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= -github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= -github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= -github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs= github.com/alecthomas/kingpin v2.2.6+incompatible/go.mod h1:59OFYbFVLKQKq+mqrL6Rw5bR0c3ACQaawgXx0QYndlE= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= @@ -91,20 +87,14 @@ github.com/andybalholm/cascadia v1.1.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9Pq github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= -github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= -github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= -github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= github.com/atomicgo/cursor v0.0.1 h1:xdogsqa6YYlLfM+GyClC/Lchf7aiMerFiZQn7soTOoU= github.com/atomicgo/cursor v0.0.1/go.mod h1:cBON2QmmrysudxNBFthvMtN32r3jxVRIvzkUiF/RuIk= -github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= -github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.38.52/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= -github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= @@ -117,34 +107,33 @@ github.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqO github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb/go.mod h1:PkYb9DJNAwrSvRx5DYA+gUcOIgTGVMNkfSCbZM8cWpI= github.com/bombsimon/wsl/v3 v3.1.0/go.mod h1:st10JtZYLE4D5sC7b8xV4zTKZwAQjCH/Hy2Pm1FNZIc= github.com/bufbuild/buf v0.37.0/go.mod h1:lQ1m2HkIaGOFba6w/aC3KYBHhKEOESP3gaAEpS3dAFM= -github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= github.com/cavaliercoder/go-cpio v0.0.0-20180626203310-925f9528c45e/go.mod h1:oDpT4efm8tSYHXV5tHSdRvBet/b/QzxZ+XyyPehvm3A= -github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4= -github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= github.com/cenkalti/backoff/v4 v4.1.0/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= github.com/cenkalti/backoff/v4 v4.1.1 h1:G2HAfAmvm/GcKan2oOQpBXOd2tT2G57ZnZGWa1PxPBQ= github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= -github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= +github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/checkpoint-restore/go-criu/v5 v5.0.0/go.mod h1:cfwC0EG7HMUenopBsUf9d89JlCLQIfgVcNsNN0t6T2M= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/cilium/ebpf v0.5.0/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs= github.com/cilium/ebpf v0.6.2/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs= -github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I= github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= -github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= -github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= github.com/containerd/console v1.0.2/go.mod h1:ytZPjGgY2oeTkAONYafi2kSj0aYggsf8acV1PGKCbzQ= github.com/containerd/continuity v0.0.0-20190827140505-75bee3e2ccb6/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= github.com/containerd/continuity v0.1.0 h1:UFRRY5JemiAhPZrr/uE0n8fMTLcZsUvySPr1+D7pgr8= @@ -157,11 +146,9 @@ github.com/coreos/go-oidc/v3 v3.1.0 h1:6avEvcdvTa1qYsOZ6I5PRkSYHzpTNWgKYmaJfaYbr github.com/coreos/go-oidc/v3 v3.1.0/go.mod h1:rEJ/idjfUyfkBit1eI1fvyr+64/g9dcKpAm8MJMesvo= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= -github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= -github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= @@ -179,8 +166,8 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/denis-tingajkin/go-header v0.3.1/go.mod h1:sq/2IxMhaZX+RRcgHfCRx/m0M5na0fBt4/CRe7Lrji0= github.com/denisenkom/go-mssqldb v0.0.0-20191124224453-732737034ffd/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU= github.com/denisenkom/go-mssqldb v0.9.0/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU= -github.com/denisenkom/go-mssqldb v0.10.0 h1:QykgLZBorFE95+gO3u9esLd0BmbvpWp0/waNNZfHBM8= -github.com/denisenkom/go-mssqldb v0.10.0/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU= +github.com/denisenkom/go-mssqldb v0.11.0 h1:9rHa233rhdOyrz2GcP9NM+gi2psgJZ4GWDpL/7ND8HI= +github.com/denisenkom/go-mssqldb v0.11.0/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgrijalva/jwt-go v3.2.1-0.20200107013213-dc14462fd587+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= @@ -194,17 +181,11 @@ github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKoh github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= -github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dvyukov/go-fuzz v0.0.0-20210103155950-6a8e9d1f2415/go.mod h1:11Gm+ccJnvAhCNLlf5+cS9KjtbaD5I5zaZpFMsTHWTw= -github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= -github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= -github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= -github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= github.com/efekarakus/termcolor v1.0.1 h1:YAKFO3bnLrqZGTWyNLcYoSIAQFKVOmbqmDnwsU/znzg= github.com/efekarakus/termcolor v1.0.1/go.mod h1:AitrZNrE4nPO538fRsqf+p0WgLdAsGN5pUNrHEPsEMM= github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o= -github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= @@ -212,6 +193,7 @@ github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5y github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= +github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5 h1:Yzb9+7DPaBjB8zlTR87/ElzFsnQfuHnVUVqpZZIcV5Y= github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5/go.mod h1:a2zkGnVExMxdzMo3M0Hi/3sEU+cWnZpSni0O6/Yb/P0= @@ -222,8 +204,6 @@ github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGE github.com/fatih/set v0.2.1 h1:nn2CaJyknWE/6txyUDGwysr3G5QC6xWB/PtVjPBbeaA= github.com/fatih/set v0.2.1/go.mod h1:+RKtMCH+favT2+3YecHGxcc0b4KyVWA1QWWJUs4E0CI= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= -github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= -github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= github.com/frankban/quicktest v1.13.0/go.mod h1:qLE0fzW0VuyUAJgPU19zByoIr0HtCHN/r/VLSOOIySU= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= @@ -248,7 +228,6 @@ github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2 github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= @@ -258,12 +237,15 @@ github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dT github.com/go-ole/go-ole v1.2.5/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A= github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= -github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q= github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= -github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no= +github.com/go-playground/locales v0.14.0 h1:u50s323jtVGugKlcYeyzC0etD1HifMjqmJqb8WugfUU= +github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs= github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= -github.com/go-playground/validator/v10 v10.4.1 h1:pH2c5ADXtd66mxoE0Zm9SUhxE20r7aM3F26W0hOn+GE= +github.com/go-playground/universal-translator v0.18.0 h1:82dyy6p4OuJq4/CByFNOn/jYrnRPArHwAcmLoJZxyho= +github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA= github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4= +github.com/go-playground/validator/v10 v10.9.0 h1:NgTtmN58D0m8+UuxtYmGztBJB7VnPgjj221I1QHci2A= +github.com/go-playground/validator/v10 v10.9.0/go.mod h1:74x4gJWsvQexRdW8Pn3dXSGrTK4nAUsbPlLADvpJkos= github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE= @@ -283,12 +265,10 @@ github.com/go-xmlfmt/xmlfmt v0.0.0-20191208150333-d5b6f63a941b/go.mod h1:aUCEOzz github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gofrs/flock v0.8.0/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= -github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= -github.com/gofrs/uuid v4.0.0+incompatible h1:1SD/1F5pU8p29ybwgQSwpQk+mwdRrXCYuPhW6m+TnJw= github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= -github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= +github.com/gofrs/uuid v4.1.0+incompatible h1:sIa2eCvUTwgjbqXrPLfNwUf9S3i3mpH1O1atV+iL/Wk= +github.com/gofrs/uuid v4.1.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= @@ -297,7 +277,6 @@ github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2V github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/glog v1.0.0 h1:nfP3RFugxnNRyKgeWd4oI1nYvXpxrx8ck8ZrcizshdQ= github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4= -github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -328,7 +307,6 @@ github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaS github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2/go.mod h1:k9Qvh+8juN+UKMCS/3jFtGICgW8O96FVaZsaxdzDkR4= github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a/go.mod h1:ryS0uhF+x9jgbj/N71xsEqODy9BN81/GonCZiOzirOk= @@ -401,10 +379,6 @@ github.com/gordonklaus/ineffassign v0.0.0-20200309095847-7953dde2c7bf/go.mod h1: github.com/goreleaser/chglog v0.1.2/go.mod h1:tTZsFuSZK4epDXfjMkxzcGbrIOXprf0JFp47BjIr3B8= github.com/goreleaser/fileglob v0.3.1/go.mod h1:kNcPrPzjCp+Ox3jmXLU5QEsjhqrtLBm6OnXAif8KRl8= github.com/goreleaser/nfpm v1.10.3/go.mod h1:EEC7YD5wi+ol0MiAshpgPANBOkjXDl7wqTLVk68OBsk= -github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= -github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= -github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= -github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gostaticanalysis/analysisutil v0.0.0-20190318220348-4088753ea4d3/go.mod h1:eEOZF4jCKGi+aprrirO9e7WKB3beBRtWgqGunKl6pKE= @@ -414,11 +388,11 @@ github.com/gostaticanalysis/analysisutil v0.6.1/go.mod h1:18U/DLpRgIUd459wGxVHE0 github.com/gostaticanalysis/comment v1.3.0/go.mod h1:xMicKDx7XRXYdVwY9f9wQpDJVnqWxw9wCauCMKp+IBI= github.com/gostaticanalysis/comment v1.4.1/go.mod h1:ih6ZxzTHLdadaiSnF5WY3dxUoXfXAlTaRzuaNDlSado= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= -github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-middleware v1.2.2/go.mod h1:EaizFBKfUKtMIF5iaDEhniwNedqGo9FuLFzppDr3uwI= +github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 h1:+9834+KizmvFV7pXQGSXQTsaWhq2GjuNUt0aUU0YBYw= +github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= -github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.14.6/go.mod h1:zdiPV4Yse/1gnckTHtghG4GkDEdKCRJduHpTxT3/jcw= github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= @@ -429,9 +403,7 @@ github.com/grpc-ecosystem/grpc-gateway/v2 v2.6.0/go.mod h1:qrJPVzv9YlhsrxJc3P/Q8 github.com/hako/durafmt v0.0.0-20210608085754-5c1018a4e16b h1:wDUNC2eKiL35DbLvsDhiblTUXHxcOPwQSCzi7xpQUN4= github.com/hako/durafmt v0.0.0-20210608085754-5c1018a4e16b/go.mod h1:VzxiSdG6j1pi7rwGm/xYI5RbtpBgM8sARDXlvEvxlu0= github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= -github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE= github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= -github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= @@ -457,7 +429,6 @@ github.com/hinshun/vt10x v0.0.0-20180616224451-1954e6464174 h1:WlZsjVhE8Af9IcZDG github.com/hinshun/vt10x v0.0.0-20180616224451-1954e6464174/go.mod h1:DqJ97dSdRW1W22yXSB90986pcOyQ7r45iio1KN2ez1A= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/huandu/xstrings v1.3.2/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= -github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= github.com/hugelgupf/socketpair v0.0.0-20190730060125-05d35a94e714/go.mod h1:2Goc3h8EklBH5mspfHFxBnEoURQCGzQQH1ga9Myjvis= github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= @@ -468,7 +439,6 @@ github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU= github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= -github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= github.com/infobloxopen/atlas-app-toolkit v0.24.1-0.20210416193901-4c7518b07e08/go.mod h1:9BTHnpff654rY1J8KxSUOLJ+ZUDn2Vi3mmk26gQDo1M= github.com/infobloxopen/protoc-gen-gorm v1.0.1 h1:IjvQ02gZSll+CjpWjxkLqrpxnvKAGfs5dXRJEpfZx2s= github.com/infobloxopen/protoc-gen-gorm v1.0.1/go.mod h1:gTu86stnDQXwcNqLG9WNJfl3IPUIhxmGNqJ8z4826uo= @@ -481,11 +451,7 @@ github.com/jackc/chunkreader/v2 v2.0.1/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgO github.com/jackc/pgconn v0.0.0-20190420214824-7e0022ef6ba3/go.mod h1:jkELnwuX+w9qN5YIfX0fl88Ehu4XC3keFuOJJk9pcnA= github.com/jackc/pgconn v0.0.0-20190824142844-760dd75542eb/go.mod h1:lLjNuW/+OfW9/pnVKPazfWOgNfH2aPem8YQ7ilXGvJE= github.com/jackc/pgconn v0.0.0-20190831204454-2fabfa3c18b7/go.mod h1:ZJKsE/KZfsUgOEh9hBm+xYTstcNHg7UPMVJqRfQxq4s= -github.com/jackc/pgconn v1.4.0/go.mod h1:Y2O3ZDF0q4mMacyWV3AstPJpeHXWGEetiFttmq5lahk= -github.com/jackc/pgconn v1.5.0/go.mod h1:QeD3lBfpTFe8WUnPZWN5KY/mB8FGMIYRdd8P8Jr0fAI= -github.com/jackc/pgconn v1.5.1-0.20200601181101-fa742c524853/go.mod h1:QeD3lBfpTFe8WUnPZWN5KY/mB8FGMIYRdd8P8Jr0fAI= github.com/jackc/pgconn v1.8.0/go.mod h1:1C2Pb36bGIP9QHGBYCjnyhqu7Rv3sGshaQUvmfGIB/o= -github.com/jackc/pgconn v1.8.1/go.mod h1:JV6m6b6jhjdmzchES0drzCcYcAHS1OPD5xu3OZ/lE2g= github.com/jackc/pgconn v1.9.0/go.mod h1:YctiPyvzfU11JFxoXokUOOKQXQmDMoJL9vJzHH8/2JY= github.com/jackc/pgconn v1.9.1-0.20210724152538-d89c8390a530/go.mod h1:4z2w8XhRbP1hYxkpTuBjTS3ne3J48K83+u0zoyvg2pI= github.com/jackc/pgconn v1.10.0 h1:4EYhlDVEMsJ30nNj0mmgwIUXoq7e9sMJrVC2ED6QlCU= @@ -504,37 +470,25 @@ github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190420180111-c116219b62db/go.mod github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190609003834-432c2951c711/go.mod h1:uH0AWtUmuShn0bcesswc4aBTWGvw0cAxIJp+6OB//Wg= github.com/jackc/pgproto3/v2 v2.0.0-rc3/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM= github.com/jackc/pgproto3/v2 v2.0.0-rc3.0.20190831210041-4c03ce451f29/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM= -github.com/jackc/pgproto3/v2 v2.0.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= github.com/jackc/pgproto3/v2 v2.0.6/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= github.com/jackc/pgproto3/v2 v2.1.1 h1:7PQ/4gLoqnl87ZxL7xjO0DR5gYuviDCZxQJsUlFW1eI= github.com/jackc/pgproto3/v2 v2.1.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= -github.com/jackc/pgservicefile v0.0.0-20200307190119-3430c5407db8/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E= github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b h1:C8S2+VttkHFdOOCXJe+YGfa4vHYwlt4Zx+IVXQ97jYg= github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E= github.com/jackc/pgtype v0.0.0-20190421001408-4ed0de4755e0/go.mod h1:hdSHsc1V01CGwFsrv11mJRHWJ6aifDLfdV3aVjFF0zg= github.com/jackc/pgtype v0.0.0-20190824184912-ab885b375b90/go.mod h1:KcahbBH1nCMSo2DXpzsoWOAfFkdEtEJpPbVLq8eE+mc= github.com/jackc/pgtype v0.0.0-20190828014616-a8802b16cc59/go.mod h1:MWlu30kVJrUS8lot6TQqcg7mtthZ9T0EoIBFiJcmcyw= -github.com/jackc/pgtype v1.2.0/go.mod h1:5m2OfMh1wTK7x+Fk952IDmI4nw3nPrvtQdM0ZT4WpC0= -github.com/jackc/pgtype v1.3.1-0.20200510190516-8cd94a14c75a/go.mod h1:vaogEUkALtxZMCH411K+tKzNpwzCKU+AnPzBKZ+I+Po= -github.com/jackc/pgtype v1.3.1-0.20200606141011-f6355165a91c/go.mod h1:cvk9Bgu/VzJ9/lxTO5R5sf80p0DiucVtN7ZxvaC4GmQ= -github.com/jackc/pgtype v1.7.0/go.mod h1:ZnHF+rMePVqDKaOfJVI4Q8IVvAQMryDlDkZnKOI75BE= github.com/jackc/pgtype v1.8.1-0.20210724151600-32e20a603178/go.mod h1:C516IlIV9NKqfsMCXTdChteoXmwgUceqaLfjg2e3NlM= github.com/jackc/pgtype v1.8.1 h1:9k0IXtdJXHJbyAWQgbWr1lU+MEhPXZz6RIXxfR5oxXs= github.com/jackc/pgtype v1.8.1/go.mod h1:LUMuVrfsFfdKGLw+AFFVv6KtHOFMwRgDDzBt76IqCA4= github.com/jackc/pgx/v4 v4.0.0-20190420224344-cc3461e65d96/go.mod h1:mdxmSJJuR08CZQyj1PVQBHy9XOp5p8/SHH6a0psbY9Y= github.com/jackc/pgx/v4 v4.0.0-20190421002000-1b8f0016e912/go.mod h1:no/Y67Jkk/9WuGR0JG/JseM9irFbnEPbuWV2EELPNuM= github.com/jackc/pgx/v4 v4.0.0-pre1.0.20190824185557-6972a5742186/go.mod h1:X+GQnOEnf1dqHGpw7JmHqHc1NxDoalibchSk9/RWuDc= -github.com/jackc/pgx/v4 v4.5.0/go.mod h1:EpAKPLdnTorwmPUUsqrPxy5fphV18j9q3wrfRXgo+kA= -github.com/jackc/pgx/v4 v4.6.1-0.20200510190926-94ba730bb1e9/go.mod h1:t3/cdRQl6fOLDxqtlyhe9UWgfIi9R8+8v8GKV5TRA/o= -github.com/jackc/pgx/v4 v4.6.1-0.20200606145419-4e5062306904/go.mod h1:ZDaNWkt9sW1JMiNn0kdYBaLelIhw7Pg4qd+Vk6tw7Hg= -github.com/jackc/pgx/v4 v4.11.0/go.mod h1:i62xJgdrtVDsnL3U8ekyrQXEwGNTRoG7/8r+CIdYfcc= github.com/jackc/pgx/v4 v4.12.1-0.20210724153913-640aa07df17c/go.mod h1:1QD0+tgSXP7iUjYm9C1NxKhny7lq6ee99u/z+IHFcgs= github.com/jackc/pgx/v4 v4.13.0 h1:JCjhT5vmhMAf/YwBHLvrBn4OGdIQBiFG6ym8Zmdx570= github.com/jackc/pgx/v4 v4.13.0/go.mod h1:9P4X524sErlaxj0XSGZk7s+LD0eOyu1ZDUrrpznYDF0= github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= -github.com/jackc/puddle v1.1.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= -github.com/jackc/puddle v1.1.1/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= @@ -551,7 +505,6 @@ github.com/jinzhu/now v1.1.2 h1:eVKgfIdy9b6zbWBMgFpfDPoAMifwSZagU9HmEU6zgiI= github.com/jinzhu/now v1.1.2/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= github.com/jirfag/go-printf-func-name v0.0.0-20191110105641-45db9963cdd3/go.mod h1:HEWGJkRDzjJY2sqdDwxccsGicWEf9BQOZsq2tV+xzM0= github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af/go.mod h1:HEWGJkRDzjJY2sqdDwxccsGicWEf9BQOZsq2tV+xzM0= -github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= github.com/jmoiron/sqlx v1.2.0/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks= @@ -569,12 +522,11 @@ github.com/jsimonetti/rtnetlink v0.0.0-20210122163228-8d122574c736/go.mod h1:ZXp github.com/jsimonetti/rtnetlink v0.0.0-20210212075122-66c871082f2b/go.mod h1:8w9Rh8m+aHZIG69YPGGem1i5VzoyRC8nw2kA8B+ik5U= github.com/jsimonetti/rtnetlink v0.0.0-20210525051524-4cc836578190/go.mod h1:NmKSdU4VGSiv1bMsdqNALI4RSvvjtz65tTMCnD05qLo= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.11 h1:uVUAXhF2To8cbw/3xN3pxj6kk7TYKs98NIrTqPlMWAQ= github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= @@ -592,8 +544,8 @@ github.com/klauspost/compress v1.10.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYs github.com/klauspost/compress v1.11.0/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.11.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.12.2/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= -github.com/klauspost/compress v1.13.5 h1:9O69jUPDcsT9fEm74W92rZL9FQY7rCdaXVneq+yyzl4= -github.com/klauspost/compress v1.13.5/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= +github.com/klauspost/compress v1.13.6 h1:P76CopJELS0TiO2mebmnzgWaajssP/EszplttgQxcgc= +github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= github.com/klauspost/pgzip v1.2.5/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= @@ -601,8 +553,9 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxv github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= +github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.4/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.8 h1:AkaSdXYQOWeaO3neb8EM634ahkXXe3jYbVh/F9lq+GI= @@ -612,24 +565,21 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kunwardeep/paralleltest v1.0.2/go.mod h1:ZPqNm1fVHPllh5LPVujzbVz1JN2GhLxSfY+oqUsvG30= github.com/kyoh86/exportloopref v0.1.8/go.mod h1:1tUcJeiioIs7VWe5gcOObrux3lb66+sBqGZrRkMwPgg= -github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y= github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= +github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w= +github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY= github.com/lib/pq v0.0.0-20180327071824-d34b9ff171c2/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= -github.com/lib/pq v1.3.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.3.1-0.20200116171513-9eb3fc897d6f/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/lib/pq v1.10.3 h1:v9QZf2Sn6AmjXtQeFpdoq/eaNtYP6IN+7lcrygsIAtg= github.com/lib/pq v1.10.3/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= -github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= -github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= github.com/logrusorgru/aurora v0.0.0-20181002194514-a7b3b318ed4e/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4= github.com/lxn/walk v0.0.0-20210112085537-c389da54e794/go.mod h1:E23UucZGqpuUANJooIbHWCufXvOcT6E7Stq81gU+CSQ= github.com/lxn/win v0.0.0-20210218163916-a377121e959e/go.mod h1:KxxjdtRkfNoYDCUP5ryK7XJJNTnpC8atvtmTheChOtk= -github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= github.com/magefile/mage v1.10.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= @@ -647,24 +597,21 @@ github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8= github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= -github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= -github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= -github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= +github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= +github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/mattn/go-sqlite3 v1.14.0/go.mod h1:JIl7NbARA7phWnGvh0LKTyg7S9BA+6gx71ShQilpsus= -github.com/mattn/go-sqlite3 v1.14.5/go.mod h1:WVKg1VTActs4Qso6iwGbiFih2UIHo0ENGwNd0Lj+XmI= github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= -github.com/mattn/go-sqlite3 v1.14.8 h1:gDp86IdQsN/xWjIEmr9MF6o9mpksUgh0fu+9ByFxzIU= -github.com/mattn/go-sqlite3 v1.14.8/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= +github.com/mattn/go-sqlite3 v1.14.9 h1:10HX2Td0ocZpYEjhilsuo6WWtUqttj2Kb0KtD86/KYA= +github.com/mattn/go-sqlite3 v1.14.9/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= @@ -714,35 +661,24 @@ github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/moricho/tparallel v0.2.1/go.mod h1:fXEIZxG2vdfl0ZF8b42f5a78EhjjD5mX8qUplsoSU4k= github.com/mozilla/tls-observatory v0.0.0-20200317151703-4fa42e1c2dee/go.mod h1:SrKMQvPiws7F7iqYp8/TX+IhxCYhzr6N/1yb8cwHsGk= github.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/nakabonne/nestif v0.3.0/go.mod h1:dI314BppzXjJ4HsCnbo7XzrJHPszZsjnk5wEBSYHI2c= -github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= -github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU= -github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k= -github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w= -github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= -github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= -github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= github.com/nbutton23/zxcvbn-go v0.0.0-20180912185939-ae427f1e4c1d/go.mod h1:o96djdrsSGy3AWPyBgZMAGfxZNfgntdJG+11KU4QvbU= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/nishanths/exhaustive v0.1.0/go.mod h1:S1j9110vxV1ECdCudXRkeMnFQ/DQk9ajLT0Uf2MYZQQ= github.com/nishanths/predeclared v0.0.0-20200524104333-86fad755b4d3/go.mod h1:nt3d53pc1VYcphSCIaYAJtnPYnr3Zyn8fMq2wvPGPso= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= -github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= -github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= -github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.14.1/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= -github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.10.2/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= @@ -757,17 +693,9 @@ github.com/opencontainers/runc v1.0.2 h1:opHZMaswlyxz1OuGpBE53Dwe4/xF7EZTY0A2L/F github.com/opencontainers/runc v1.0.2/go.mod h1:aTaHFFwQXuA71CiyxOdFFIorAoemI04suvGRQFzWTD0= github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/selinux v1.8.2/go.mod h1:MUIHuUEvKB1wtJjQdOyYRgOnLD2xAPP8dBsCoU0KuF8= -github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis= -github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74= -github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= -github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA= -github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= -github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= -github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= github.com/ory/dockertest/v3 v3.7.0 h1:Bijzonc69Ont3OU0a3TWKJ1Rzlh3TsDXP1JrTAkSmsM= github.com/ory/dockertest/v3 v3.7.0/go.mod h1:PvCCgnP7AfBZeVrzwiUTjZx/IUXlGLC1zQlUQrLIlUE= -github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc= github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ= @@ -778,18 +706,17 @@ github.com/pelletier/go-toml v1.6.0/go.mod h1:5N711Q9dKgbdkxHL+MEfF31hpT7l0S0s/t github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc= github.com/pelletier/go-toml v1.9.3 h1:zeC5b1GviRUyKYd6OJPvBU/mcVDVoL1OhT17FCt5dSQ= github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= -github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= github.com/peterbourgon/ff/v2 v2.0.0/go.mod h1:xjwr+t+SjWm4L46fcj/D+Ap+6ME7+HqFzaP22pP5Ggk= github.com/peterbourgon/ff/v3 v3.0.0/go.mod h1:UILIFjRH5a/ar8TjXYLTkIvSvekZqPm5Eb/qbGk6CT0= github.com/phayes/checkstyle v0.0.0-20170904204023-bfd46e6a821d/go.mod h1:3OzsM7FXDQlpCiw2j81fOmAwQLnZnLGXVKUzeKQXIAw= -github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= -github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= +github.com/philip-bui/grpc-zerolog v1.0.1 h1:EMacvLRUd2O1K0eWod27ZP5CY1iTNkhBDLSN+Q4JEvA= +github.com/philip-bui/grpc-zerolog v1.0.1/go.mod h1:qXbiq/2X4ZUMMshsqlWyTHOcw7ns+GZmlqZZN05ZHcQ= github.com/pkg/diff v0.0.0-20200914180035-5b29258ca4f7/go.mod h1:zO8QMzTeZd5cpnIkz/Gn6iK0jDfGicM1nynOkkPIl28= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= github.com/pkg/profile v1.5.0/go.mod h1:qBsxPvzyUincmltOk6iyRVxHYg4adc0OFOv72ZdLa18= github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= github.com/pkg/sftp v1.13.0/go.mod h1:41g+FIPlQUTDCveupEmEA65IoiQFrtgCeDopC4ajGIM= @@ -799,36 +726,30 @@ github.com/polyfloyd/go-errorlint v0.0.0-20201006195004-351e25ade6e3/go.mod h1:w github.com/polyfloyd/go-errorlint v0.0.0-20201127212506-19bd8db6546f/go.mod h1:wi9BfjxjF/bwiZ701TzmfKu6UKC357IOAtNr0Td0Lvw= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= -github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= github.com/prometheus/client_golang v1.11.0 h1:HNkLOAEQMIDv/K+04rukrLx6ch7msSRwf3/SASFAGtQ= github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= -github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= -github.com/prometheus/common v0.26.0 h1:iMAkS2TDoNWnKM+Kopnx/8tnEStIfpYA0ur0xQzzhMQ= github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= +github.com/prometheus/common v0.32.1 h1:hWIdL3N2HoUx3B8j3YN9mWor0qhY/NlEKZEaXxuIRh4= +github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= -github.com/prometheus/procfs v0.6.0 h1:mxy4L2jP6qMonqmq+aTtOx1ifVWUgG/TAmntgbh3xv4= github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= +github.com/prometheus/procfs v0.7.3 h1:4jVXhlkAyzOScmCkXBTOLRLTz8EeU+eyjrwB/EPq0VU= +github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/pterm/pterm v0.12.27/go.mod h1:PhQ89w4i95rhgE+xedAoqous6K9X+r6aSOI2eFF7DZI= github.com/pterm/pterm v0.12.29/go.mod h1:WI3qxgvoQFFGKGjGnJR849gU0TsEOvKn5Q8LlY1U7lg= @@ -839,7 +760,6 @@ github.com/quasilyte/go-ruleguard v0.2.0/go.mod h1:2RT/tf0Ce0UDj5y243iWKosQogJd8 github.com/quasilyte/go-ruleguard v0.2.1/go.mod h1:hN2rVc/uS4bQhQKTio2XaSJSafJwqBUWWwtssT3cQmc= github.com/quasilyte/regex/syntax v0.0.0-20200407221936-30656e2c4a95/go.mod h1:rlzQ04UMyJXu/aOvhd8qT+hvDrFpiwqp8MRXDY9szc0= github.com/quasilyte/regex/syntax v0.0.0-20200805063351-8f842688393c/go.mod h1:rlzQ04UMyJXu/aOvhd8qT+hvDrFpiwqp8MRXDY9szc0= -github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= @@ -848,17 +768,18 @@ github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFR github.com/rogpeppe/go-internal v1.5.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.6.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= +github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8= +github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= github.com/rs/xid v1.3.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU= github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc= -github.com/rs/zerolog v1.25.0 h1:Rj7XygbUHKUlDPcVdoLyR91fJBsduXj5fRxyqIQj/II= -github.com/rs/zerolog v1.25.0/go.mod h1:7KHcEGe0QZPOm2IE4Kpb5rTh6n1h2hIgS5OOnu1rUaI= +github.com/rs/zerolog v1.26.0 h1:ORM4ibhEZeTeQlCojCK2kPz1ogAY4bGs4tD+SaAdGaE= +github.com/rs/zerolog v1.26.0/go.mod h1:yBiM87lvSqX8h0Ww4sdzNSkVYZ8dL2xjZJG1lAuGZEo= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryancurrah/gomodguard v1.1.0/go.mod h1:4O8tr7hBODaGE6VIhfJDHcwzh5GUccKSJBU0UMXJFVM= github.com/ryanrolds/sqlclosecheck v0.3.0/go.mod h1:1gREqxyTGR3lVtpngyFo3hZAgk0KCtEdgEkHwDbigdA= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= -github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= github.com/sassoftware/go-rpmutils v0.0.0-20190420191620-a8f1baeba37b/go.mod h1:am+Fp8Bt506lA3Rk3QCmSqmYmLMnPDhdDUcosQCAx+I= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= @@ -870,7 +791,6 @@ github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c/go.mod h1:/PevMnwAx github.com/shirou/gopsutil v0.0.0-20190901111213-e4ec7b275ada/go.mod h1:WWnYX4lzhCH5h/3YBfyVA3VbLYjlMZZAQcW9ojMexNc= github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4/go.mod h1:qsXQc7+bwAM3Q1u/4XEfrquwF8Lw7D7y5cD8CuHnfIc= github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= -github.com/shopspring/decimal v0.0.0-20200227202807-02e2044944cc/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= github.com/shopspring/decimal v1.2.0 h1:abSATXmQEYyShuxI4/vyW3tV1MrKAJzCZ/0zLUXYbsQ= github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk= @@ -892,7 +812,6 @@ github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4k github.com/soheilhy/cmux v0.1.5 h1:jjzc5WVemNEDTLwv9tlmemhC73tI08BNOIGwBOo10Js= github.com/soheilhy/cmux v0.1.5/go.mod h1:T7TcVDs9LWfQgPlPsdngu6I6QIoyIFZDDC6sNE1GqG0= github.com/sonatard/noctx v0.0.1/go.mod h1:9D2D/EoULe8Yy2joDHJj7bv3sZoq9AaSb8B4lqBjiZI= -github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= github.com/sourcegraph/go-diff v0.6.1/go.mod h1:iBszgVvyxdc8SFZ7gm69go2KDdt3ag071iBaWPF6cjs= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= @@ -903,7 +822,6 @@ github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng= github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= -github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= github.com/spf13/cobra v1.0.1-0.20201006035406-b97b5ead31f7/go.mod h1:yk5b0mALVusDL5fMM6Rd1wgnoO5jUPhwsQ6LQAJTidQ= github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJQMI= @@ -912,7 +830,6 @@ github.com/spf13/cobra v1.2.1/go.mod h1:ExllRjgxM/piMAM+3tAZvg8fsklGAf3tPfi+i8t6 github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= -github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= @@ -922,12 +839,10 @@ github.com/spf13/viper v1.7.1/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5q github.com/spf13/viper v1.8.1 h1:Kq1fyeebqsBfbjZj4EL7gj2IO0mMaiyjYUWcUsl2O44= github.com/spf13/viper v1.8.1/go.mod h1:o0Pch8wJ9BVSWGQMbra6iw0oQ5oktSIBaujf1rJH9Ns= github.com/ssgreg/nlreturn/v2 v2.1.0/go.mod h1:E/iiPB78hV7Szg2YfRgyIrk1AD6JVMTRkkxBiELzh2I= -github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= -github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= -github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= +github.com/stretchr/objx v0.3.0 h1:NGXK3lHquSN08v5vWalVI/L8XU9hdzE/G6xsrze47As= github.com/stretchr/objx v0.3.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/testify v1.2.1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= @@ -944,8 +859,8 @@ github.com/tailscale/certstore v0.0.0-20210528134328-066c94b793d3/go.mod h1:2P+h github.com/tailscale/depaware v0.0.0-20201214215404-77d1e9757027/go.mod h1:p9lPsd+cx33L3H9nNoecRRxPssFKUwwI50I3pZ0yT+8= github.com/tailscale/goupnp v1.0.1-0.20210804011211-c64d0f06ea05/go.mod h1:PdCqy9JzfWMJf1H5UJW2ip33/d4YkoKN0r67yKH1mG8= github.com/tailscale/hujson v0.0.0-20200924210142-dde312d0d6a2/go.mod h1:STqf+YV0ADdzk4ejtXFsGqDpATP9JoL0OB+hiFQbkdE= -github.com/tailscale/hujson v0.0.0-20210818175511-7360507a6e88 h1:q5Sxx79nhG4xWsYEJBlLdqo1hNhUV31/NhA4qQ1SKAY= -github.com/tailscale/hujson v0.0.0-20210818175511-7360507a6e88/go.mod h1:iTDXJsA6A2wNNjurgic2rk+is6uzU4U2NLm4T+edr6M= +github.com/tailscale/hujson v0.0.0-20210923003652-c3758b31534b h1:bvys7zUACfrQZBUAinXREfu9jUgq6KcNQcQnUkzl3yc= +github.com/tailscale/hujson v0.0.0-20210923003652-c3758b31534b/go.mod h1:iTDXJsA6A2wNNjurgic2rk+is6uzU4U2NLm4T+edr6M= github.com/tcnksm/go-httpstat v0.2.0/go.mod h1:s3JVJFtQxtBEBC9dwcdTTXS9xFnM3SXAZwPG41aurT8= github.com/tcnksm/go-latest v0.0.0-20170313132115-e3007ae9052e h1:IWllFTiDjjLIf2oeKxpIUmtiDV5sn71VgeQgg6vcE7k= github.com/tcnksm/go-latest v0.0.0-20170313132115-e3007ae9052e/go.mod h1:d7u6HkTYKSv5m6MCKkOQlHwaShTMl3HjqSGW3XtVhXM= @@ -955,7 +870,6 @@ github.com/tetafro/godot v1.3.0/go.mod h1:/7NLHhv08H1+8DNj0MElpAACw1ajsCuf3TKNQx github.com/tetafro/godot v1.3.2/go.mod h1:ah7jjYmOMnIjS9ku2krapvGQrFNtTLo9Z/qB3dGU1eU= github.com/timakin/bodyclose v0.0.0-20190930140734-f7f2e9bca95e/go.mod h1:Qimiffbc6q9tBWlVV6x0P9sat/ao1xEkREYPPj9hphk= github.com/timakin/bodyclose v0.0.0-20200424151742-cb6215831a94/go.mod h1:Qimiffbc6q9tBWlVV6x0P9sat/ao1xEkREYPPj9hphk= -github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tomarrell/wrapcheck v0.0.0-20200807122107-df9e8bcb914d/go.mod h1:yiFB6fFoV7saXirUGfuK+cPtUh4NX/Hf5y2WC2lehu0= github.com/tomarrell/wrapcheck v0.0.0-20201130113247-1683564d9756/go.mod h1:yiFB6fFoV7saXirUGfuK+cPtUh4NX/Hf5y2WC2lehu0= @@ -964,14 +878,15 @@ github.com/toqueteos/webbrowser v1.2.0/go.mod h1:XWoZq4cyp9WeUeak7w7LXRUQf1F1ATJ github.com/twitchtv/twirp v7.1.0+incompatible/go.mod h1:RRJoFSAmTEh2weEqWtpPE3vFK5YBhA6bqp2l1kfCC5A= github.com/u-root/uio v0.0.0-20210528114334-82958018845c/go.mod h1:LpEX5FO/cB+WF4TYGY1V5qktpaZLkKkSegbr0V4eYXA= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= -github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo= github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= -github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs= +github.com/ugorji/go v1.2.6 h1:tGiWC9HENWE2tqYycIqFTNorMmFRVhNwCpDOpWqnk8E= +github.com/ugorji/go v1.2.6/go.mod h1:anCg0y61KIhDlPZmnH+so+RQbysYVyDko0IMgJv0Nn0= github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= +github.com/ugorji/go/codec v1.2.6 h1:7kbGefxLoDBuYXOms4yD7223OpNMMPNPZxXk5TvFcyQ= +github.com/ugorji/go/codec v1.2.6/go.mod h1:V6TCNZ4PHqoHGFZuSG1W8nrCzzdgA2DozYxWFFpvxTw= github.com/ulikunitz/xz v0.5.7/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= github.com/ultraware/funlen v0.0.3/go.mod h1:Dp4UiAus7Wdb9KUZsYWZEWiRzGuM2kXM1lPbfaF6xhA= github.com/ultraware/whitespace v0.0.4/go.mod h1:aVMh/gQve5Maj9hQ/hg+F75lr/X5A89uZnzAmWSineA= -github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/uudashr/gocognit v1.0.1/go.mod h1:j44Ayx2KW4+oB6SWMv8KsmHzZrOInQav7D3cQMJ5JUM= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= @@ -999,18 +914,15 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= github.com/ziutek/telnet v0.0.0-20180329124119-c3b780dc415b/go.mod h1:IZpXDfkJ6tWD3PhBK5YzgQT+xJWh7OsdwiG8hA2MkO4= github.com/zsais/go-gin-prometheus v0.1.0 h1:bkLv1XCdzqVgQ36ScgRi09MA2UC1t3tAB6nsfErsGO4= github.com/zsais/go-gin-prometheus v0.1.0/go.mod h1:Slirjzuz8uM8Cw0jmPNqbneoqcUtY2GGjn2bEd4NRLY= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= -go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= -go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ= -go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= -go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= @@ -1035,13 +947,16 @@ go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ= go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= -go4.org/intern v0.0.0-20210108033219-3eb7198706b2 h1:VFTf+jjIgsldaz/Mr00VaCSswHJrI2hIjQygE/W4IMg= go4.org/intern v0.0.0-20210108033219-3eb7198706b2/go.mod h1:vLqJ+12kCw61iCWsPto0EOHhBS+o4rO5VIucbc9g2Cc= -go4.org/mem v0.0.0-20201119185036-c04c5a6ff174 h1:vSug/WNOi2+4jrKdivxayTN/zd8EA1UrStjpWvvo1jk= +go4.org/intern v0.0.0-20211027215823-ae77deb06f29 h1:UXLjNohABv4S58tHmeuIZDO6e3mHpW2Dx33gaNt03LE= +go4.org/intern v0.0.0-20211027215823-ae77deb06f29/go.mod h1:cS2ma+47FKrLPdXFpr7CuxiTW3eyJbWew4qx0qtQWDA= go4.org/mem v0.0.0-20201119185036-c04c5a6ff174/go.mod h1:reUoABIJ9ikfM5sgtSF3Wushcza7+WeD01VB9Lirh3g= +go4.org/mem v0.0.0-20210711025021-927187094b94 h1:OAAkygi2Js191AJP1Ds42MhJRgeofeKGjuoUqNp1QC4= +go4.org/mem v0.0.0-20210711025021-927187094b94/go.mod h1:reUoABIJ9ikfM5sgtSF3Wushcza7+WeD01VB9Lirh3g= go4.org/unsafe/assume-no-moving-gc v0.0.0-20201222175341-b30ae309168e/go.mod h1:FftLjUGFEDu5k8lt0ddY+HcrH/qU/0qk+H8j9/nTl3E= -go4.org/unsafe/assume-no-moving-gc v0.0.0-20201222180813-1025295fd063 h1:1tk03FUNpulq2cuWpXZWj649rwJpk0d20rxWiopKRmc= go4.org/unsafe/assume-no-moving-gc v0.0.0-20201222180813-1025295fd063/go.mod h1:FftLjUGFEDu5k8lt0ddY+HcrH/qU/0qk+H8j9/nTl3E= +go4.org/unsafe/assume-no-moving-gc v0.0.0-20211027215541-db492cf91b37 h1:Tx9kY6yUkLge/pFG7IEMwDZy6CS2ajFc9TvQdPCW0uA= +go4.org/unsafe/assume-no-moving-gc v0.0.0-20211027215541-db492cf91b37/go.mod h1:FftLjUGFEDu5k8lt0ddY+HcrH/qU/0qk+H8j9/nTl3E= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -1051,13 +966,10 @@ golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaE golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191205180655-e7c4368fe9dd/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= @@ -1065,11 +977,10 @@ golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWP golang.org/x/crypto v0.0.0-20201208171446-5f87f3452ae9/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= -golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 h1:HWj/xjIHfjYU5nVXpTM0s39J9CbLn7Cc5a7IC5rwsMQ= -golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 h1:7I4JAnoQBe7ZtJcBaYHi5UtiO8tQHbUSXxL+pnGRANg= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1115,7 +1026,6 @@ golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -1164,8 +1074,9 @@ golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLd golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210913180222-943fd674d43e h1:+b/22bPvDYt4NPDcy4xAGCmON713ONAWFeY3Z7I3tR8= -golang.org/x/net v0.0.0-20210913180222-943fd674d43e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211104170005-ce137452f963 h1:8gJUadZl+kWvZBqG/LautX0X6qe5qTC2VI/3V3NBRAY= +golang.org/x/net v0.0.0-20211104170005-ce137452f963/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1179,8 +1090,10 @@ golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210427180440-81ed05c6b58c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f h1:Qmd2pbz05z7z6lm0DrgQVVPuBm92jqujBKMHMOlOQEw= +golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 h1:RerP+noqYHUQ8CMRcPlC2nvTa4dcBIjegkuWdcUDuqg= +golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1200,7 +1113,6 @@ golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190221075227-b4e8571b14e0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1229,7 +1141,6 @@ golang.org/x/sys v0.0.0-20191113165036-4c7a9d0fe056/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1285,9 +1196,12 @@ golang.org/x/sys v0.0.0-20210525143221-35b2ab0089ea/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210817190340-bfb29a6856f2/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210910150752-751e447fb3d0 h1:xrCZDmdtoloIiooiA9q0OQb9r8HejIHYoHGhGCe1pGg= -golang.org/x/sys v0.0.0-20210910150752-751e447fb3d0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211103235746-7861aae1554b h1:1VkfZQv42XQlA/jchYumAnv1UPo6RgF9rJFkTgZIxO4= +golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -1305,14 +1219,12 @@ golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7-0.20210524175448-3115f89c4b99/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20210611083556-38a9dc6acbc6/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190110163146-51295c7ec13a/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -1394,6 +1306,7 @@ golang.org/x/tools v0.0.0-20201013201025-64a9e34f3752/go.mod h1:z6u4i615ZeAfBE4X golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201118003311-bd56c0adb394/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201121010211-780cb80bd7fb/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201124202034-299f270db459/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201211185031-d93e913c1a58/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= @@ -1402,6 +1315,7 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo= golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1411,7 +1325,6 @@ golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1N golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.zx2c4.com/wireguard v0.0.0-20210624150102-15b24b6179e0/go.mod h1:laHzsbfMhGSobUmruXWAyMKKHSqvIcrqZJMyHD+/3O8= golang.zx2c4.com/wireguard/windows v0.3.16/go.mod h1:f80rkFY2CKQklps1GHE15k/M4Tq78aofbr1iQM5MTVY= -google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= @@ -1436,7 +1349,6 @@ google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBz google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= google.golang.org/api v0.44.0/go.mod h1:EBOGZqzyhtvMDoxwS97ctnh0zUmYY6CxqXsc1AvkYD8= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= @@ -1449,7 +1361,6 @@ google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRn google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= @@ -1492,17 +1403,14 @@ google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= google.golang.org/genproto v0.0.0-20210426193834-eac7f76ac494/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= -google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83 h1:3V2dxSZpz4zozWWUq36vUxXEKnSYitEH2LdsAx+RUmg= google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= +google.golang.org/genproto v0.0.0-20211104193956-4c6863e31247 h1:ZONpjmFT5e+I/0/xE3XXbG5OIvX2hRYzol04MhKBl2E= +google.golang.org/genproto v0.0.0-20211104193956-4c6863e31247/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= -google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= @@ -1521,8 +1429,9 @@ google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAG google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/grpc v1.40.0 h1:AGJ0Ih4mHjSeibYkFGh1dD9KJ/eOtZ93I6hoHhukQ5Q= google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= +google.golang.org/grpc v1.42.0 h1:XT2/MFpuPFsEX2fWh3YQtHkZ+WYZFQRfaUgLZYj/p6A= +google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.0.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0 h1:M1YKkFIboKNieVO5DLUEVzQfGwJD30Nv2jfUgzb5UcE= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= @@ -1551,17 +1460,16 @@ gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s= gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.62.0 h1:duBzk771uxoUuOlyRLkHsygud9+5lrlGjdFBb4mSKDU= gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= -gopkg.in/square/go-jose.v2 v2.5.1 h1:7odma5RETjNHWJnR32wx8t+Io4djHE1PqxCFx3iiZ2w= gopkg.in/square/go-jose.v2 v2.5.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= +gopkg.in/square/go-jose.v2 v2.6.0 h1:NGk74WTnPKBNUhNzQX7PYcTLUjoq7mzKk2OKbvwk2iI= +gopkg.in/square/go-jose.v2 v2.6.0/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= @@ -1578,27 +1486,22 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gorm.io/datatypes v1.0.2 h1:ChZ5VfWGB23qEr1kZosidvG9CF9HIczwoxLhBS7Ebs4= -gorm.io/datatypes v1.0.2/go.mod h1:1O1JVE4grFGcQTOGQbIBitiXUP6Sv84/KZU7eWeUv1k= -gorm.io/driver/mysql v1.1.2 h1:OofcyE2lga734MxwcCW9uB4mWNXMr50uaGRVwQL2B0M= -gorm.io/driver/mysql v1.1.2/go.mod h1:4P/X9vSc3WTrhTLZ259cpFd6xKNYiSSdSZngkSBGIMM= -gorm.io/driver/postgres v1.1.0/go.mod h1:hXQIwafeRjJvUm+OMxcFWyswJ/vevcpPLlGocwAwuqw= -gorm.io/driver/postgres v1.1.1 h1:tWLmqYCyaoh89fi7DhM6QggujrOnmfo3H98AzgNAAu0= -gorm.io/driver/postgres v1.1.1/go.mod h1:tpe2xN7aCst1NUdYyWQyxPtnHC+Zfp6NEux9PXD1OU0= -gorm.io/driver/sqlite v1.1.4/go.mod h1:mJCeTFr7+crvS+TRnWc5Z3UvwxUN1BGBLMrf5LA9DYw= -gorm.io/driver/sqlite v1.1.5 h1:JU8G59VyKu1x1RMQgjefQnkZjDe9wHc1kARDZPu5dZs= -gorm.io/driver/sqlite v1.1.5/go.mod h1:NpaYMcVKEh6vLJ47VP6T7Weieu4H1Drs3dGD/K6GrGc= -gorm.io/driver/sqlserver v1.0.9 h1:P7Dm/BKqsrOjyhRSnLXvG2g1W/eJUgxdrdBwgJw3tEg= -gorm.io/driver/sqlserver v1.0.9/go.mod h1:iBdxY2CepkTt9Q1r84RbZA1qCai300Qlp8kQf9qE9II= -gorm.io/gorm v1.20.7/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw= -gorm.io/gorm v1.21.9/go.mod h1:F+OptMscr0P2F2qU97WT1WimdH9GaQPoDW7AYd5i2Y0= +gorm.io/datatypes v1.0.3 h1:cbFm8OiE50PZK1Zj9+bROQQpsFipE9bPFxxxkKgj3e4= +gorm.io/datatypes v1.0.3/go.mod h1:bi/3zc2D4dyUkiB+xhrirAv95+u4CXI+OE/YK43Jntg= +gorm.io/driver/mysql v1.1.3 h1:+5g1UElqN0sr2gZqmg9djlu1zT3cErHiscc6+IbLHgw= +gorm.io/driver/mysql v1.1.3/go.mod h1:4P/X9vSc3WTrhTLZ259cpFd6xKNYiSSdSZngkSBGIMM= +gorm.io/driver/postgres v1.2.1 h1:JDQKnF7MC51dgL09Vbydc5kl83KkVDlcXfSPJ+xhh68= +gorm.io/driver/postgres v1.2.1/go.mod h1:SHRZhu+D0tLOHV5qbxZRUM6kBcf3jp/kxPz2mYMTsNY= +gorm.io/driver/sqlite v1.2.3 h1:OwKm0xRAnsZMWAl5BtXJ9BsXAZHIt802DOTVMQuzWN8= +gorm.io/driver/sqlite v1.2.3/go.mod h1:wkiGvZF3le/8vjCRYg0bT8TSw6APZ5rtgKW8uQYE3sc= +gorm.io/driver/sqlserver v1.2.0 h1:5cPirBlvocwzzJ6SDqjkHraKfwnKn5I6Ss/WTMtI+io= +gorm.io/driver/sqlserver v1.2.0/go.mod h1:nixq0OB3iLXZDiPv6JSOjWuPgpyaRpOIIevYtA4Ulb4= gorm.io/gorm v1.21.12/go.mod h1:F+OptMscr0P2F2qU97WT1WimdH9GaQPoDW7AYd5i2Y0= -gorm.io/gorm v1.21.14/go.mod h1:F+OptMscr0P2F2qU97WT1WimdH9GaQPoDW7AYd5i2Y0= -gorm.io/gorm v1.21.15 h1:gAyaDoPw0lCyrSFWhBlahbUA1U4P5RViC1uIqoB+1Rk= -gorm.io/gorm v1.21.15/go.mod h1:F+OptMscr0P2F2qU97WT1WimdH9GaQPoDW7AYd5i2Y0= +gorm.io/gorm v1.22.0/go.mod h1:F+OptMscr0P2F2qU97WT1WimdH9GaQPoDW7AYd5i2Y0= +gorm.io/gorm v1.22.2 h1:1iKcvyJnR5bHydBhDqTwasOkoo6+o4Ms5cknSt6qP7I= +gorm.io/gorm v1.22.2/go.mod h1:F+OptMscr0P2F2qU97WT1WimdH9GaQPoDW7AYd5i2Y0= gotest.tools/v3 v3.0.2 h1:kG1BFyqVHuQoVQiR1bWGnfz/fmHvvuiSPIV7rvl360E= gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= -honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= @@ -1608,10 +1511,11 @@ honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9 honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.6/go.mod h1:pyyisuGw24ruLjrr1ddx39WE0y9OooInRzEYLhQB2YY= honnef.co/go/tools v0.1.4/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las= +howett.net/plist v0.0.0-20181124034731-591f970eefbb/go.mod h1:vMygbs4qMhSZSc4lCUl2OEE+rDiIIJAIdR4m7MiMcm0= inet.af/netaddr v0.0.0-20210515010201-ad03edc7c841/go.mod h1:z0nx+Dh+7N7CC8V5ayHtHGpZpxLQZZxkIaaz6HN65Ls= inet.af/netaddr v0.0.0-20210721214506-ce7a8ad02cc1/go.mod h1:z0nx+Dh+7N7CC8V5ayHtHGpZpxLQZZxkIaaz6HN65Ls= -inet.af/netaddr v0.0.0-20210903134321-85fa6c94624e h1:tvgqez5ZQoBBiBAGNU/fmJy247yB/7++kcLOEoMYup0= -inet.af/netaddr v0.0.0-20210903134321-85fa6c94624e/go.mod h1:z0nx+Dh+7N7CC8V5ayHtHGpZpxLQZZxkIaaz6HN65Ls= +inet.af/netaddr v0.0.0-20211027220019-c74959edd3b6 h1:acCzuUSQ79tGsM/O50VRFySfMm19IoMKL+sZztZkCxw= +inet.af/netaddr v0.0.0-20211027220019-c74959edd3b6/go.mod h1:y3MGhcFMlh0KZPMuXXow8mpjxxAk3yoDNsp4cQz54i8= inet.af/netstack v0.0.0-20210622165351-29b14ebc044e/go.mod h1:fG3G1dekmK8oDX3iVzt8c0zICLMLSN8SjdxbXVt0WjU= inet.af/peercred v0.0.0-20210318190834-4259e17bb763/go.mod h1:FjawnflS/udxX+SvpsMgZfdqx2aykOlkISeAsADi5IU= inet.af/wf v0.0.0-20210516214145-a5343001b756/go.mod h1:ViGMZRA6+RA318D7GCncrjv5gHUrPYrNDejjU12tikA= @@ -1623,7 +1527,6 @@ mvdan.cc/unparam v0.0.0-20200501210554-b37ab49443f7/go.mod h1:HGC5lll35J70Y5v7vC rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= -sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= -sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= -tailscale.com v1.14.2 h1:iSbnr+3eVt0ZsRJQG+KLw46K8Hq2fbCMSH/dGoJXnkY= -tailscale.com v1.14.2/go.mod h1:WbJAb2AwrBO8jGQgxZ8E2mj3l628a3ysdPV7bJHBKlY= +software.sslmate.com/src/go-pkcs12 v0.0.0-20180114231543-2291e8f0f237/go.mod h1:/xvNRWUqm0+/ZMiF4EX00vrSCMsE4/NHb+Pt3freEeQ= +tailscale.com v1.14.6 h1:xhpDI3hks1lz80Tq7gxybdM0vt8NSuWEFpQeBqBZJhw= +tailscale.com v1.14.6/go.mod h1:3F94TfP5nSn9M40v7jEQB+QI3m/4trasLDF3Dcljs8o= From cd34a5d6f3fae5ff9ea641fdbae1bfa506779134 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Thu, 4 Nov 2021 22:31:47 +0000 Subject: [PATCH 082/300] Expand json output to support yaml, make more generic --- cmd/headscale/cli/utils.go | 60 +++++++++++++++++++------------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/cmd/headscale/cli/utils.go b/cmd/headscale/cli/utils.go index cd467697..90479bcd 100644 --- a/cmd/headscale/cli/utils.go +++ b/cmd/headscale/cli/utils.go @@ -14,19 +14,16 @@ import ( "time" "github.com/juanfont/headscale" - apiV1 "github.com/juanfont/headscale/gen/go/headscale/v1" + v1 "github.com/juanfont/headscale/gen/go/headscale/v1" "github.com/rs/zerolog/log" "github.com/spf13/viper" "google.golang.org/grpc" + "gopkg.in/yaml.v2" "inet.af/netaddr" "tailscale.com/tailcfg" "tailscale.com/types/dnstype" ) -type ErrorOutput struct { - Error string -} - func LoadConfig(path string) error { viper.SetConfigName("config") if path == "" { @@ -316,7 +313,7 @@ func getHeadscaleApp() (*headscale.Headscale, error) { return h, nil } -func getHeadscaleGRPCClient(ctx context.Context) (apiV1.HeadscaleServiceClient, *grpc.ClientConn) { +func getHeadscaleGRPCClient(ctx context.Context) (v1.HeadscaleServiceClient, *grpc.ClientConn) { grpcOptions := []grpc.DialOption{ grpc.WithBlock(), } @@ -370,46 +367,49 @@ func getHeadscaleGRPCClient(ctx context.Context) (apiV1.HeadscaleServiceClient, log.Fatal().Err(err).Msgf("Could not connect: %v", err) } - client := apiV1.NewHeadscaleServiceClient(conn) + client := v1.NewHeadscaleServiceClient(conn) return client, conn } -func JsonOutput(result interface{}, errResult error, outputFormat string) { +func SuccessOutput(result interface{}, override string, outputFormat string) { var j []byte var err error switch outputFormat { case "json": - if errResult != nil { - j, err = json.MarshalIndent(ErrorOutput{errResult.Error()}, "", "\t") - if err != nil { - log.Fatal().Err(err) - } - } else { - j, err = json.MarshalIndent(result, "", "\t") - if err != nil { - log.Fatal().Err(err) - } + j, err = json.MarshalIndent(result, "", "\t") + if err != nil { + log.Fatal().Err(err) } case "json-line": - if errResult != nil { - j, err = json.Marshal(ErrorOutput{errResult.Error()}) - if err != nil { - log.Fatal().Err(err) - } - } else { - j, err = json.Marshal(result) - if err != nil { - log.Fatal().Err(err) - } + j, err = json.Marshal(result) + if err != nil { + log.Fatal().Err(err) } + case "yaml": + j, err = yaml.Marshal(result) + if err != nil { + log.Fatal().Err(err) + } + default: + fmt.Println(override) + return } + fmt.Println(string(j)) } -func HasJsonOutputFlag() bool { +func ErrorOutput(errResult error, override string, outputFormat string) { + type errOutput struct { + Error string `json:"error"` + } + + SuccessOutput(errOutput{errResult.Error()}, override, outputFormat) +} + +func HasMachineOutputFlag() bool { for _, arg := range os.Args { - if arg == "json" || arg == "json-line" { + if arg == "json" || arg == "json-line" || arg == "yaml" { return true } } From 9e9049307e2b0f6da173fa0fcdaa3e4b36a792e8 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Thu, 4 Nov 2021 22:32:13 +0000 Subject: [PATCH 083/300] Simplify loglevel parser, turn off logs when machine output is set --- cmd/headscale/headscale.go | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/cmd/headscale/headscale.go b/cmd/headscale/headscale.go index 6b1a8437..ed4644f3 100644 --- a/cmd/headscale/headscale.go +++ b/cmd/headscale/headscale.go @@ -46,24 +46,23 @@ func main() { log.Fatal().Err(err) } + machineOutput := cli.HasMachineOutputFlag() + logLevel := viper.GetString("log_level") - switch logLevel { - case "trace": - zerolog.SetGlobalLevel(zerolog.TraceLevel) - case "debug": - zerolog.SetGlobalLevel(zerolog.DebugLevel) - case "info": - zerolog.SetGlobalLevel(zerolog.InfoLevel) - case "warn": - zerolog.SetGlobalLevel(zerolog.WarnLevel) - case "error": - zerolog.SetGlobalLevel(zerolog.ErrorLevel) - default: + level, err := zerolog.ParseLevel(logLevel) + if err != nil { zerolog.SetGlobalLevel(zerolog.DebugLevel) + } else { + zerolog.SetGlobalLevel(level) } - jsonOutput := cli.HasJsonOutputFlag() - if !viper.GetBool("disable_check_updates") && !jsonOutput { + // If the user has requested a "machine" readable format, + // then disable login so the output remains valid. + if machineOutput { + zerolog.SetGlobalLevel(zerolog.Disabled) + } + + if !viper.GetBool("disable_check_updates") && !machineOutput { if (runtime.GOOS == "linux" || runtime.GOOS == "darwin") && cli.Version != "dev" { githubTag := &latest.GithubTag{ Owner: "juanfont", @@ -71,8 +70,11 @@ func main() { } res, err := latest.Check(githubTag, cli.Version) if err == nil && res.Outdated { - fmt.Printf("An updated version of Headscale has been found (%s vs. your current %s). Check it out https://github.com/juanfont/headscale/releases\n", - res.Current, cli.Version) + fmt.Printf( + "An updated version of Headscale has been found (%s vs. your current %s). Check it out https://github.com/juanfont/headscale/releases\n", + res.Current, + cli.Version, + ) } } } From dce82f43238c35154119a966e5170e01903a8622 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Thu, 4 Nov 2021 22:41:55 +0000 Subject: [PATCH 084/300] Use new json wrapper for version command --- cmd/headscale/cli/version.go | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/cmd/headscale/cli/version.go b/cmd/headscale/cli/version.go index c018b142..2b440af3 100644 --- a/cmd/headscale/cli/version.go +++ b/cmd/headscale/cli/version.go @@ -1,9 +1,6 @@ package cli import ( - "fmt" - "strings" - "github.com/spf13/cobra" ) @@ -18,11 +15,7 @@ var versionCmd = &cobra.Command{ Short: "Print the version.", Long: "The version of headscale.", Run: func(cmd *cobra.Command, args []string) { - o, _ := cmd.Flags().GetString("output") - if strings.HasPrefix(o, "json") { - JsonOutput(map[string]string{"version": Version}, nil, o) - return - } - fmt.Println(Version) + output, _ := cmd.Flags().GetString("output") + SuccessOutput(map[string]string{"version": Version}, Version, output) }, } From 79871d24636ac86d15f021374ed6e14cafbf4144 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Thu, 4 Nov 2021 22:42:21 +0000 Subject: [PATCH 085/300] Make namespace command use gRPC This commit is a first in a series of commits migrating the command interfaces to use the new gRPC client. As a part of this commit, they have been streamlined and each command _should_ be a bit more similar and use consistent output. By using the new output function, we now make sure its always json (errors and everything) if the user asks for JSON. --- cmd/headscale/cli/namespaces.go | 111 ++++++++++++++++++-------------- 1 file changed, 64 insertions(+), 47 deletions(-) diff --git a/cmd/headscale/cli/namespaces.go b/cmd/headscale/cli/namespaces.go index 1c4e3762..427df624 100644 --- a/cmd/headscale/cli/namespaces.go +++ b/cmd/headscale/cli/namespaces.go @@ -3,11 +3,9 @@ package cli import ( "context" "fmt" - "strconv" - "strings" "time" - apiV1 "github.com/juanfont/headscale/gen/go/headscale/v1" + v1 "github.com/juanfont/headscale/gen/go/headscale/v1" "github.com/pterm/pterm" "github.com/rs/zerolog/log" "github.com/spf13/cobra" @@ -36,7 +34,9 @@ var createNamespaceCmd = &cobra.Command{ return nil }, Run: func(cmd *cobra.Command, args []string) { - o, _ := cmd.Flags().GetString("output") + output, _ := cmd.Flags().GetString("output") + + namespaceName := args[0] ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() @@ -46,19 +46,16 @@ var createNamespaceCmd = &cobra.Command{ log.Trace().Interface("client", client).Msg("Obtained gRPC client") - request := &apiV1.CreateNamespaceRequest{Name: args[0]} + request := &v1.CreateNamespaceRequest{Name: namespaceName} log.Trace().Interface("request", request).Msg("Sending CreateNamespace request") response, err := client.CreateNamespace(ctx, request) - if strings.HasPrefix(o, "json") { - JsonOutput(response.Name, err, o) - return - } if err != nil { - fmt.Printf("Error creating namespace: %s\n", err) + ErrorOutput(err, fmt.Sprintf("Cannot create namespace: %s", err), output) return } - fmt.Printf("Namespace created\n") + + SuccessOutput(response.Namespace, "Namespace created", output) }, } @@ -72,21 +69,25 @@ var destroyNamespaceCmd = &cobra.Command{ return nil }, Run: func(cmd *cobra.Command, args []string) { - o, _ := cmd.Flags().GetString("output") - h, err := getHeadscaleApp() + output, _ := cmd.Flags().GetString("output") + + namespaceName := args[0] + + ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) + defer cancel() + + client, conn := getHeadscaleGRPCClient(ctx) + defer conn.Close() + + request := &v1.DeleteNamespaceRequest{Name: namespaceName} + + response, err := client.DeleteNamespace(ctx, request) if err != nil { - log.Fatal().Err(err).Msgf("Error initializing: %s", err) - } - err = h.DestroyNamespace(args[0]) - if strings.HasPrefix(o, "json") { - JsonOutput(map[string]string{"Result": "Namespace destroyed"}, err, o) + ErrorOutput(err, fmt.Sprintf("Cannot destroy namespace: %s", err), output) return } - if err != nil { - fmt.Printf("Error destroying namespace: %s\n", err) - return - } - fmt.Printf("Namespace destroyed\n") + + SuccessOutput(response, "Namespace destroyed", output) }, } @@ -94,31 +95,42 @@ var listNamespacesCmd = &cobra.Command{ Use: "list", Short: "List all the namespaces", Run: func(cmd *cobra.Command, args []string) { - o, _ := cmd.Flags().GetString("output") - h, err := getHeadscaleApp() + output, _ := cmd.Flags().GetString("output") + + ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) + defer cancel() + + client, conn := getHeadscaleGRPCClient(ctx) + defer conn.Close() + + request := &v1.ListNamespacesRequest{} + + response, err := client.ListNamespaces(ctx, request) if err != nil { - log.Fatal().Err(err).Msgf("Error initializing: %s", err) - } - namespaces, err := h.ListNamespaces() - if strings.HasPrefix(o, "json") { - JsonOutput(namespaces, err, o) + ErrorOutput(err, fmt.Sprintf("Cannot get namespaces: %s", err), output) return } - if err != nil { - fmt.Println(err) + + if output != "" { + SuccessOutput(response.Namespaces, "", output) return } d := pterm.TableData{{"ID", "Name", "Created"}} - for _, n := range *namespaces { + for _, namespace := range response.GetNamespaces() { d = append( d, - []string{strconv.FormatUint(uint64(n.ID), 10), n.Name, n.CreatedAt.Format("2006-01-02 15:04:05")}, + []string{ + namespace.GetId(), + namespace.GetName(), + namespace.GetCreatedAt().AsTime().Format("2006-01-02 15:04:05"), + }, ) } err = pterm.DefaultTable.WithHasHeader().WithData(d).Render() if err != nil { - log.Fatal().Err(err).Msg("") + ErrorOutput(err, fmt.Sprintf("Failed to render pterm table: %s", err), output) + return } }, } @@ -133,20 +145,25 @@ var renameNamespaceCmd = &cobra.Command{ return nil }, Run: func(cmd *cobra.Command, args []string) { - o, _ := cmd.Flags().GetString("output") - h, err := getHeadscaleApp() - if err != nil { - log.Fatal().Err(err).Msgf("Error initializing: %s", err) + output, _ := cmd.Flags().GetString("output") + + ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) + defer cancel() + + client, conn := getHeadscaleGRPCClient(ctx) + defer conn.Close() + + request := &v1.RenameNamespaceRequest{ + OldName: args[0], + NewName: args[1], } - err = h.RenameNamespace(args[0], args[1]) - if strings.HasPrefix(o, "json") { - JsonOutput(map[string]string{"Result": "Namespace renamed"}, err, o) + + response, err := client.RenameNamespace(ctx, request) + if err != nil { + ErrorOutput(err, fmt.Sprintf("Cannot rename namespace: %s", err), output) return } - if err != nil { - fmt.Printf("Error renaming namespace: %s\n", err) - return - } - fmt.Printf("Namespace renamed\n") + + SuccessOutput(response.Namespace, "Namespace renamed", output) }, } From 7b0d2dfb4ac22da6c31363eaf038bf4a302899e2 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Thu, 4 Nov 2021 22:44:35 +0000 Subject: [PATCH 086/300] Convert nodes command to use gRPC --- cmd/headscale/cli/nodes.go | 300 +++++++++++++++++++++---------------- 1 file changed, 171 insertions(+), 129 deletions(-) diff --git a/cmd/headscale/cli/nodes.go b/cmd/headscale/cli/nodes.go index cdf37efb..70fae835 100644 --- a/cmd/headscale/cli/nodes.go +++ b/cmd/headscale/cli/nodes.go @@ -1,14 +1,14 @@ package cli import ( + "context" "fmt" "log" "strconv" - "strings" "time" survey "github.com/AlecAivazis/survey/v2" - "github.com/juanfont/headscale" + v1 "github.com/juanfont/headscale/gen/go/headscale/v1" "github.com/pterm/pterm" "github.com/spf13/cobra" "tailscale.com/tailcfg" @@ -73,30 +73,37 @@ var registerNodeCmd = &cobra.Command{ Use: "register", Short: "Registers a machine to your network", Run: func(cmd *cobra.Command, args []string) { - n, err := cmd.Flags().GetString("namespace") + output, _ := cmd.Flags().GetString("output") + namespace, err := cmd.Flags().GetString("namespace") if err != nil { - log.Fatalf("Error getting namespace: %s", err) + ErrorOutput(err, fmt.Sprintf("Error getting namespace: %s", err), output) + return } - o, _ := cmd.Flags().GetString("output") - h, err := getHeadscaleApp() + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + + client, conn := getHeadscaleGRPCClient(ctx) + defer conn.Close() + + machineKey, err := cmd.Flags().GetString("key") if err != nil { - log.Fatalf("Error initializing: %s", err) - } - machineIDStr, err := cmd.Flags().GetString("key") - if err != nil { - log.Fatalf("Error getting machine ID: %s", err) - } - m, err := h.RegisterMachine(machineIDStr, n) - if strings.HasPrefix(o, "json") { - JsonOutput(m, err, o) + ErrorOutput(err, fmt.Sprintf("Error getting machine key from flag: %s", err), output) return } + + request := &v1.RegisterMachineRequest{ + Key: machineKey, + Namespace: namespace, + } + + response, err := client.RegisterMachine(ctx, request) if err != nil { - fmt.Printf("Cannot register machine: %s\n", err) + ErrorOutput(err, fmt.Sprintf("Cannot register machine: %s\n", err), output) return } - fmt.Printf("Machine registered\n") + + SuccessOutput(response.Machine, "Machine register", output) }, } @@ -104,72 +111,44 @@ var listNodesCmd = &cobra.Command{ Use: "list", Short: "List nodes", Run: func(cmd *cobra.Command, args []string) { - n, err := cmd.Flags().GetString("namespace") + output, _ := cmd.Flags().GetString("output") + namespace, err := cmd.Flags().GetString("namespace") if err != nil { - log.Fatalf("Error getting namespace: %s", err) - } - o, _ := cmd.Flags().GetString("output") - - h, err := getHeadscaleApp() - if err != nil { - log.Fatalf("Error initializing: %s", err) - } - - var namespaces []headscale.Namespace - var namespace *headscale.Namespace - var sharedMachines *[]headscale.Machine - if len(n) == 0 { - // no namespace provided, list all - tmp, err := h.ListNamespaces() - if err != nil { - log.Fatalf("Error fetching namespace: %s", err) - } - namespaces = *tmp - } else { - namespace, err = h.GetNamespace(n) - if err != nil { - log.Fatalf("Error fetching namespace: %s", err) - } - namespaces = append(namespaces, *namespace) - - sharedMachines, err = h.ListSharedMachinesInNamespace(n) - if err != nil { - log.Fatalf("Error fetching shared machines: %s", err) - } - } - - var allMachines []headscale.Machine - for _, namespace := range namespaces { - machines, err := h.ListMachinesInNamespace(namespace.Name) - if err != nil { - log.Fatalf("Error fetching machines: %s", err) - } - allMachines = append(allMachines, *machines...) - } - - // listing sharedMachines is only relevant when a particular namespace is - // requested - if sharedMachines != nil { - allMachines = append(allMachines, *sharedMachines...) - } - - if strings.HasPrefix(o, "json") { - JsonOutput(allMachines, err, o) + ErrorOutput(err, fmt.Sprintf("Error getting namespace: %s", err), output) return } - if err != nil { - log.Fatalf("Error getting nodes: %s", err) + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + + client, conn := getHeadscaleGRPCClient(ctx) + defer conn.Close() + + request := &v1.ListMachinesRequest{ + Namespace: namespace, } - d, err := nodesToPtables(namespace, allMachines) + response, err := client.ListMachines(ctx, request) if err != nil { - log.Fatalf("Error converting to table: %s", err) + ErrorOutput(err, fmt.Sprintf("Cannot get nodes: %s", err), output) + return + } + + if output != "" { + SuccessOutput(response.Machines, "", output) + return + } + + d, err := nodesToPtables(namespace, response.Machines) + if err != nil { + ErrorOutput(err, fmt.Sprintf("Error converting to table: %s", err), output) + return } err = pterm.DefaultTable.WithHasHeader().WithData(d).Render() if err != nil { - log.Fatal(err) + ErrorOutput(err, fmt.Sprintf("Failed to render pterm table: %s", err), output) + return } }, } @@ -179,24 +158,38 @@ var deleteNodeCmd = &cobra.Command{ Short: "Delete a node", Run: func(cmd *cobra.Command, args []string) { output, _ := cmd.Flags().GetString("output") - h, err := getHeadscaleApp() - if err != nil { - log.Fatalf("Error initializing: %s", err) - } + id, err := cmd.Flags().GetInt("identifier") if err != nil { - log.Fatalf("Error converting ID to integer: %s", err) + ErrorOutput(err, fmt.Sprintf("Error converting ID to integer: %s", err), output) + return } - m, err := h.GetMachineByID(uint64(id)) + + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + + client, conn := getHeadscaleGRPCClient(ctx) + defer conn.Close() + + getRequest := &v1.GetMachineRequest{ + MachineId: uint64(id), + } + + getResponse, err := client.GetMachine(ctx, getRequest) if err != nil { - log.Fatalf("Error getting node: %s", err) + ErrorOutput(err, fmt.Sprintf("Error getting node node: %s", err), output) + return + } + + deleteRequest := &v1.DeleteMachineRequest{ + MachineId: uint64(id), } confirm := false force, _ := cmd.Flags().GetBool("force") if !force { prompt := &survey.Confirm{ - Message: fmt.Sprintf("Do you want to remove the node %s?", m.Name), + Message: fmt.Sprintf("Do you want to remove the node %s?", getResponse.GetMachine().Name), } err = survey.AskOne(prompt, &confirm) if err != nil { @@ -205,71 +198,96 @@ var deleteNodeCmd = &cobra.Command{ } if confirm || force { - err = h.DeleteMachine(m) - if strings.HasPrefix(output, "json") { - JsonOutput(map[string]string{"Result": "Node deleted"}, err, output) + response, err := client.DeleteMachine(ctx, deleteRequest) + if output != "" { + SuccessOutput(response, "", output) return } if err != nil { - log.Fatalf("Error deleting node: %s", err) - } - fmt.Printf("Node deleted\n") - } else { - if strings.HasPrefix(output, "json") { - JsonOutput(map[string]string{"Result": "Node not deleted"}, err, output) + ErrorOutput(err, fmt.Sprintf("Error deleting node: %s", err), output) return } - fmt.Printf("Node not deleted\n") + SuccessOutput(map[string]string{"Result": "Node deleted"}, "Node deleted", output) + } else { + SuccessOutput(map[string]string{"Result": "Node not deleted"}, "Node not deleted", output) } }, } -func sharingWorker(cmd *cobra.Command, args []string) (*headscale.Headscale, string, *headscale.Machine, *headscale.Namespace) { +func sharingWorker( + cmd *cobra.Command, + args []string, +) (string, *v1.Machine, *v1.Namespace, error) { + output, _ := cmd.Flags().GetString("output") namespaceStr, err := cmd.Flags().GetString("namespace") if err != nil { - log.Fatalf("Error getting namespace: %s", err) + ErrorOutput(err, fmt.Sprintf("Error getting namespace: %s", err), output) + return "", nil, nil, err } - output, _ := cmd.Flags().GetString("output") + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() - h, err := getHeadscaleApp() - if err != nil { - log.Fatalf("Error initializing: %s", err) - } - - namespace, err := h.GetNamespace(namespaceStr) - if err != nil { - log.Fatalf("Error fetching namespace %s: %s", namespaceStr, err) - } + client, conn := getHeadscaleGRPCClient(ctx) + defer conn.Close() id, err := cmd.Flags().GetInt("identifier") if err != nil { - log.Fatalf("Error converting ID to integer: %s", err) - } - machine, err := h.GetMachineByID(uint64(id)) - if err != nil { - log.Fatalf("Error getting node: %s", err) + ErrorOutput(err, fmt.Sprintf("Error converting ID to integer: %s", err), output) + return "", nil, nil, err } - return h, output, machine, namespace + machineRequest := &v1.GetMachineRequest{ + MachineId: uint64(id), + } + + machineResponse, err := client.GetMachine(ctx, machineRequest) + if err != nil { + ErrorOutput(err, fmt.Sprintf("Error getting node node: %s", err), output) + return "", nil, nil, err + } + + namespaceRequest := &v1.GetNamespaceRequest{ + Name: namespaceStr, + } + + namespaceResponse, err := client.GetNamespace(ctx, namespaceRequest) + if err != nil { + ErrorOutput(err, fmt.Sprintf("Error getting node node: %s", err), output) + return "", nil, nil, err + } + + return output, machineResponse.GetMachine(), namespaceResponse.GetNamespace(), nil } var shareMachineCmd = &cobra.Command{ Use: "share", Short: "Shares a node from the current namespace to the specified one", Run: func(cmd *cobra.Command, args []string) { - h, output, machine, namespace := sharingWorker(cmd, args) - err := h.AddSharedMachineToNamespace(machine, namespace) - if strings.HasPrefix(output, "json") { - JsonOutput(map[string]string{"Result": "Node shared"}, err, output) - return - } + output, machine, namespace, err := sharingWorker(cmd, args) if err != nil { - fmt.Printf("Error sharing node: %s\n", err) + ErrorOutput(err, fmt.Sprintf("Failed to fetch namespace or machine: %s", err), output) return } - fmt.Println("Node shared!") + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + + client, conn := getHeadscaleGRPCClient(ctx) + defer conn.Close() + + request := &v1.ShareMachineRequest{ + MachineId: machine.Id, + Namespace: namespace.Name, + } + + response, err := client.ShareMachine(ctx, request) + if err != nil { + ErrorOutput(err, fmt.Sprintf("Error sharing node: %s", err), output) + return + } + + SuccessOutput(response.Machine, "Node shared", output) }, } @@ -277,33 +295,45 @@ var unshareMachineCmd = &cobra.Command{ Use: "unshare", Short: "Unshares a node from the specified namespace", Run: func(cmd *cobra.Command, args []string) { - h, output, machine, namespace := sharingWorker(cmd, args) - err := h.RemoveSharedMachineFromNamespace(machine, namespace) - if strings.HasPrefix(output, "json") { - JsonOutput(map[string]string{"Result": "Node unshared"}, err, output) - return - } + output, machine, namespace, err := sharingWorker(cmd, args) if err != nil { - fmt.Printf("Error unsharing node: %s\n", err) + ErrorOutput(err, fmt.Sprintf("Failed to fetch namespace or machine: %s", err), output) return } - fmt.Println("Node unshared!") + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + + client, conn := getHeadscaleGRPCClient(ctx) + defer conn.Close() + + request := &v1.UnshareMachineRequest{ + MachineId: machine.Id, + Namespace: namespace.Name, + } + + response, err := client.UnshareMachine(ctx, request) + if err != nil { + ErrorOutput(err, fmt.Sprintf("Error unsharing node: %s", err), output) + return + } + + SuccessOutput(response.Machine, "Node shared", output) }, } -func nodesToPtables(currentNamespace *headscale.Namespace, machines []headscale.Machine) (pterm.TableData, error) { +func nodesToPtables(currentNamespace string, machines []*v1.Machine) (pterm.TableData, error) { d := pterm.TableData{{"ID", "Name", "NodeKey", "Namespace", "IP address", "Ephemeral", "Last seen", "Online"}} for _, machine := range machines { var ephemeral bool - if machine.AuthKey != nil && machine.AuthKey.Ephemeral { + if machine.PreAuthKey != nil && machine.PreAuthKey.Ephemeral { ephemeral = true } var lastSeen time.Time var lastSeenTime string if machine.LastSeen != nil { - lastSeen = *machine.LastSeen + lastSeen = machine.LastSeen.AsTime() lastSeenTime = lastSeen.Format("2006-01-02 15:04:05") } nKey, err := wgkey.ParseHex(machine.NodeKey) @@ -320,13 +350,25 @@ func nodesToPtables(currentNamespace *headscale.Namespace, machines []headscale. } var namespace string - if (currentNamespace == nil) || (currentNamespace.ID == machine.NamespaceID) { + if currentNamespace == machine.Namespace.Name { namespace = pterm.LightMagenta(machine.Namespace.Name) } else { // Shared into this namespace namespace = pterm.LightYellow(machine.Namespace.Name) } - d = append(d, []string{strconv.FormatUint(machine.ID, 10), machine.Name, nodeKey.ShortString(), namespace, machine.IPAddress, strconv.FormatBool(ephemeral), lastSeenTime, online}) + d = append( + d, + []string{ + strconv.FormatUint(machine.Id, 10), + machine.Name, + nodeKey.ShortString(), + namespace, + machine.IpAddress, + strconv.FormatBool(ephemeral), + lastSeenTime, + online, + }, + ) } return d, nil } From 77a973878cee520051510629cfc075d7834e0642 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Thu, 4 Nov 2021 22:44:49 +0000 Subject: [PATCH 087/300] Convert preauthkeys command to use gRPC --- cmd/headscale/cli/preauthkeys.go | 125 +++++++++++++++++-------------- 1 file changed, 69 insertions(+), 56 deletions(-) diff --git a/cmd/headscale/cli/preauthkeys.go b/cmd/headscale/cli/preauthkeys.go index d7cebec1..e8252419 100644 --- a/cmd/headscale/cli/preauthkeys.go +++ b/cmd/headscale/cli/preauthkeys.go @@ -1,15 +1,17 @@ package cli import ( + "context" "fmt" "log" "strconv" - "strings" "time" "github.com/hako/durafmt" + v1 "github.com/juanfont/headscale/gen/go/headscale/v1" "github.com/pterm/pterm" "github.com/spf13/cobra" + "google.golang.org/protobuf/types/known/timestamppb" ) func init() { @@ -24,7 +26,8 @@ func init() { preauthkeysCmd.AddCommand(expirePreAuthKeyCmd) createPreAuthKeyCmd.PersistentFlags().Bool("reusable", false, "Make the preauthkey reusable") createPreAuthKeyCmd.PersistentFlags().Bool("ephemeral", false, "Preauthkey for ephemeral nodes") - createPreAuthKeyCmd.Flags().StringP("expiration", "e", "", "Human-readable expiration of the key (30m, 24h, 365d...)") + createPreAuthKeyCmd.Flags(). + StringP("expiration", "e", "", "Human-readable expiration of the key (30m, 24h, 365d...)") } var preauthkeysCmd = &cobra.Command{ @@ -36,49 +39,57 @@ var listPreAuthKeys = &cobra.Command{ Use: "list", Short: "List the preauthkeys for this namespace", Run: func(cmd *cobra.Command, args []string) { + output, _ := cmd.Flags().GetString("output") + n, err := cmd.Flags().GetString("namespace") if err != nil { - log.Fatalf("Error getting namespace: %s", err) - } - o, _ := cmd.Flags().GetString("output") - - h, err := getHeadscaleApp() - if err != nil { - log.Fatalf("Error initializing: %s", err) - } - keys, err := h.GetPreAuthKeys(n) - if strings.HasPrefix(o, "json") { - JsonOutput(keys, err, o) + ErrorOutput(err, fmt.Sprintf("Error getting namespace: %s", err), output) return } + ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) + defer cancel() + + client, conn := getHeadscaleGRPCClient(ctx) + defer conn.Close() + + request := &v1.ListPreAuthKeysRequest{ + Namespace: n, + } + + response, err := client.ListPreAuthKeys(ctx, request) if err != nil { - fmt.Printf("Error getting the list of keys: %s\n", err) + ErrorOutput(err, fmt.Sprintf("Error getting the list of keys: %s", err), output) + return + } + + if output != "" { + SuccessOutput(response.PreAuthKeys, "", output) return } d := pterm.TableData{{"ID", "Key", "Reusable", "Ephemeral", "Used", "Expiration", "Created"}} - for _, k := range *keys { + for _, k := range response.PreAuthKeys { expiration := "-" - if k.Expiration != nil { - expiration = k.Expiration.Format("2006-01-02 15:04:05") + if k.GetExpiration() != nil { + expiration = k.Expiration.AsTime().Format("2006-01-02 15:04:05") } var reusable string - if k.Ephemeral { + if k.GetEphemeral() { reusable = "N/A" } else { - reusable = fmt.Sprintf("%v", k.Reusable) + reusable = fmt.Sprintf("%v", k.GetResuable()) } d = append(d, []string{ - strconv.FormatUint(k.ID, 10), - k.Key, + k.GetId(), + k.GetKey(), reusable, - strconv.FormatBool(k.Ephemeral), - fmt.Sprintf("%v", k.Used), + strconv.FormatBool(k.GetEphemeral()), + strconv.FormatBool(k.GetUsed()), expiration, - k.CreatedAt.Format("2006-01-02 15:04:05"), + k.GetCreatedAt().AsTime().Format("2006-01-02 15:04:05"), }) } @@ -93,16 +104,14 @@ var createPreAuthKeyCmd = &cobra.Command{ Use: "create", Short: "Creates a new preauthkey in the specified namespace", Run: func(cmd *cobra.Command, args []string) { + output, _ := cmd.Flags().GetString("output") + n, err := cmd.Flags().GetString("namespace") if err != nil { - log.Fatalf("Error getting namespace: %s", err) + ErrorOutput(err, fmt.Sprintf("Error getting namespace: %s", err), output) + return } - o, _ := cmd.Flags().GetString("output") - h, err := getHeadscaleApp() - if err != nil { - log.Fatalf("Error initializing: %s", err) - } reusable, _ := cmd.Flags().GetBool("reusable") ephemeral, _ := cmd.Flags().GetBool("ephemeral") @@ -117,16 +126,26 @@ var createPreAuthKeyCmd = &cobra.Command{ expiration = &exp } - k, err := h.CreatePreAuthKey(n, reusable, ephemeral, expiration) - if strings.HasPrefix(o, "json") { - JsonOutput(k, err, o) - return + ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) + defer cancel() + + client, conn := getHeadscaleGRPCClient(ctx) + defer conn.Close() + + request := &v1.CreatePreAuthKeyRequest{ + Namespace: n, + Resuable: reusable, + Ephemeral: ephemeral, + Expiration: timestamppb.New(*expiration), } + + response, err := client.CreatePreAuthKey(ctx, request) if err != nil { - fmt.Println(err) + ErrorOutput(err, fmt.Sprintf("Cannot create Pre Auth Key: %s\n", err), output) return } - fmt.Printf("%s\n", k.Key) + + SuccessOutput(response.PreAuthKey, response.PreAuthKey.Key, output) }, } @@ -140,35 +159,29 @@ var expirePreAuthKeyCmd = &cobra.Command{ return nil }, Run: func(cmd *cobra.Command, args []string) { + output, _ := cmd.Flags().GetString("output") n, err := cmd.Flags().GetString("namespace") if err != nil { log.Fatalf("Error getting namespace: %s", err) } - o, _ := cmd.Flags().GetString("output") - h, err := getHeadscaleApp() - if err != nil { - log.Fatalf("Error initializing: %s", err) + ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) + defer cancel() + + client, conn := getHeadscaleGRPCClient(ctx) + defer conn.Close() + + request := &v1.ExpirePreAuthKeyRequest{ + Namespace: n, + Key: args[0], } - k, err := h.GetPreAuthKey(n, args[0]) + response, err := client.ExpirePreAuthKey(ctx, request) if err != nil { - if strings.HasPrefix(o, "json") { - JsonOutput(k, err, o) - return - } - log.Fatalf("Error getting the key: %s", err) - } - - err = h.MarkExpirePreAuthKey(k) - if strings.HasPrefix(o, "json") { - JsonOutput(k, err, o) + ErrorOutput(err, fmt.Sprintf("Cannot expire Pre Auth Key: %s\n", err), output) return } - if err != nil { - fmt.Println(err) - return - } - fmt.Println("Expired") + + SuccessOutput(response, "Key expired", output) }, } From be4256b1d04f2484ee8234da1e6b3fbf8fc5e3b1 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Thu, 4 Nov 2021 22:44:59 +0000 Subject: [PATCH 088/300] Convert routes command to use gRPC --- cmd/headscale/cli/routes.go | 200 ++++++++++++++++++++---------------- 1 file changed, 110 insertions(+), 90 deletions(-) diff --git a/cmd/headscale/cli/routes.go b/cmd/headscale/cli/routes.go index 72010864..4a935cf9 100644 --- a/cmd/headscale/cli/routes.go +++ b/cmd/headscale/cli/routes.go @@ -1,26 +1,37 @@ package cli import ( + "context" "fmt" "log" - "strings" + "strconv" + "time" + v1 "github.com/juanfont/headscale/gen/go/headscale/v1" "github.com/pterm/pterm" "github.com/spf13/cobra" ) func init() { rootCmd.AddCommand(routesCmd) - routesCmd.PersistentFlags().StringP("namespace", "n", "", "Namespace") - err := routesCmd.MarkPersistentFlagRequired("namespace") + + listRoutesCmd.Flags().Uint64P("identifier", "i", 0, "Node identifier (ID)") + err := listRoutesCmd.MarkFlagRequired("identifier") + if err != nil { + log.Fatalf(err.Error()) + } + routesCmd.AddCommand(listRoutesCmd) + + enableRouteCmd.Flags().StringSliceP("route", "r", []string{}, "List (or repeated flags) of routes to enable") + enableRouteCmd.Flags().Uint64P("identifier", "i", 0, "Node identifier (ID)") + err = enableRouteCmd.MarkFlagRequired("identifier") if err != nil { log.Fatalf(err.Error()) } - enableRouteCmd.Flags().BoolP("all", "a", false, "Enable all routes advertised by the node") - - routesCmd.AddCommand(listRoutesCmd) routesCmd.AddCommand(enableRouteCmd) + + nodeCmd.AddCommand(routesCmd) } var routesCmd = &cobra.Command{ @@ -29,119 +40,128 @@ var routesCmd = &cobra.Command{ } var listRoutesCmd = &cobra.Command{ - Use: "list NODE", - Short: "List the routes exposed by this node", - Args: func(cmd *cobra.Command, args []string) error { - if len(args) < 1 { - return fmt.Errorf("Missing parameters") - } - return nil - }, + Use: "list", + Short: "List routes advertised and enabled by a given node", Run: func(cmd *cobra.Command, args []string) { - n, err := cmd.Flags().GetString("namespace") - if err != nil { - log.Fatalf("Error getting namespace: %s", err) - } - o, _ := cmd.Flags().GetString("output") + output, _ := cmd.Flags().GetString("output") - h, err := getHeadscaleApp() + machineId, err := cmd.Flags().GetUint64("identifier") if err != nil { - log.Fatalf("Error initializing: %s", err) - } - - availableRoutes, err := h.GetAdvertisedNodeRoutes(n, args[0]) - if err != nil { - fmt.Println(err) + ErrorOutput(err, fmt.Sprintf("Error getting machine id from flag: %s", err), output) return } - if strings.HasPrefix(o, "json") { - // TODO: Add enable/disabled information to this interface - JsonOutput(availableRoutes, err, o) + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + + client, conn := getHeadscaleGRPCClient(ctx) + defer conn.Close() + + request := &v1.GetMachineRouteRequest{ + MachineId: machineId, + } + + response, err := client.GetMachineRoute(ctx, request) + if err != nil { + ErrorOutput(err, fmt.Sprintf("Cannot get nodes: %s", err), output) return } - d := h.RoutesToPtables(n, args[0], *availableRoutes) + if output != "" { + SuccessOutput(response.Routes, "", output) + return + } + + d := routesToPtables(response.Routes) + if err != nil { + ErrorOutput(err, fmt.Sprintf("Error converting to table: %s", err), output) + return + } err = pterm.DefaultTable.WithHasHeader().WithData(d).Render() if err != nil { - log.Fatal(err) + ErrorOutput(err, fmt.Sprintf("Failed to render pterm table: %s", err), output) + return } }, } var enableRouteCmd = &cobra.Command{ - Use: "enable node-name route", - Short: "Allows exposing a route declared by this node to the rest of the nodes", - Args: func(cmd *cobra.Command, args []string) error { - all, err := cmd.Flags().GetBool("all") - if err != nil { - log.Fatalf("Error getting namespace: %s", err) - } - - if all { - if len(args) < 1 { - return fmt.Errorf("Missing parameters") - } - return nil - } else { - if len(args) < 2 { - return fmt.Errorf("Missing parameters") - } - return nil - } - }, + Use: "enable", + Short: "Set the enabled routes for a given node", + Long: `This command will take a list of routes that will _replace_ +the current set of routes on a given node. +If you would like to disable a route, simply run the command again, but +omit the route you do not want to enable. + `, Run: func(cmd *cobra.Command, args []string) { - n, err := cmd.Flags().GetString("namespace") + output, _ := cmd.Flags().GetString("output") + machineId, err := cmd.Flags().GetUint64("identifier") if err != nil { - log.Fatalf("Error getting namespace: %s", err) + ErrorOutput(err, fmt.Sprintf("Error getting machine id from flag: %s", err), output) + return } - o, _ := cmd.Flags().GetString("output") - - all, err := cmd.Flags().GetBool("all") + routes, err := cmd.Flags().GetStringSlice("route") if err != nil { - log.Fatalf("Error getting namespace: %s", err) + ErrorOutput(err, fmt.Sprintf("Error getting routes from flag: %s", err), output) + return } - h, err := getHeadscaleApp() - if err != nil { - log.Fatalf("Error initializing: %s", err) + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + + client, conn := getHeadscaleGRPCClient(ctx) + defer conn.Close() + + request := &v1.EnableMachineRoutesRequest{ + MachineId: machineId, + Routes: routes, } - if all { - availableRoutes, err := h.GetAdvertisedNodeRoutes(n, args[0]) - if err != nil { - fmt.Println(err) - return - } + response, err := client.EnableMachineRoutes(ctx, request) + if err != nil { + ErrorOutput(err, fmt.Sprintf("Cannot register machine: %s\n", err), output) + return + } - for _, availableRoute := range *availableRoutes { - err = h.EnableNodeRoute(n, args[0], availableRoute.String()) - if err != nil { - fmt.Println(err) - return - } + if output != "" { + SuccessOutput(response.Routes, "", output) + return + } - if strings.HasPrefix(o, "json") { - JsonOutput(availableRoute, err, o) - } else { - fmt.Printf("Enabled route %s\n", availableRoute) - } - } - } else { - err = h.EnableNodeRoute(n, args[0], args[1]) + d := routesToPtables(response.Routes) + if err != nil { + ErrorOutput(err, fmt.Sprintf("Error converting to table: %s", err), output) + return + } - if strings.HasPrefix(o, "json") { - JsonOutput(args[1], err, o) - return - } - - if err != nil { - fmt.Println(err) - return - } - fmt.Printf("Enabled route %s\n", args[1]) + err = pterm.DefaultTable.WithHasHeader().WithData(d).Render() + if err != nil { + ErrorOutput(err, fmt.Sprintf("Failed to render pterm table: %s", err), output) + return } }, } + +// routesToPtables converts the list of routes to a nice table +func routesToPtables(routes *v1.Routes) pterm.TableData { + d := pterm.TableData{{"Route", "Enabled"}} + + for _, route := range routes.GetAdvertisedRoutes() { + enabled := isStringInSlice(routes.EnabledRoutes, route) + + d = append(d, []string{route, strconv.FormatBool(enabled)}) + } + return d +} + +func isStringInSlice(strs []string, s string) bool { + for _, s2 := range strs { + if s == s2 { + return true + } + } + + return false +} From 8df41b069ffcae219d6df1e1b472f9aa11128dce Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Thu, 4 Nov 2021 22:45:08 +0000 Subject: [PATCH 089/300] Formatting --- cmd/headscale/cli/root.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cmd/headscale/cli/root.go b/cmd/headscale/cli/root.go index 794cd0d0..ef047f93 100644 --- a/cmd/headscale/cli/root.go +++ b/cmd/headscale/cli/root.go @@ -8,7 +8,8 @@ import ( ) func init() { - rootCmd.PersistentFlags().StringP("output", "o", "", "Output format. Empty for human-readable, 'json' or 'json-line'") + rootCmd.PersistentFlags(). + StringP("output", "o", "", "Output format. Empty for human-readable, 'json' or 'json-line'") rootCmd.PersistentFlags().Bool("force", false, "Disable prompts and forces the execution") } From 204f99dd51c5612e1ef4b5f24d6e473a389e8590 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Thu, 4 Nov 2021 22:45:15 +0000 Subject: [PATCH 090/300] Add CLI integration tests This PR adds a new part to the integration test suite which spins up a new headscale and runs through a scenario of test cases for each command. The intent is to check that all commands work as intended and produce the expected output. I think they have been pretty well covered, but would appreciate additional test cases if I have missed some. Please note: headscale is set up, and teared down for _each_ "test function" in this file, this means that its more suitable for specific cases. --- integration_cli_test.go | 869 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 869 insertions(+) create mode 100644 integration_cli_test.go diff --git a/integration_cli_test.go b/integration_cli_test.go new file mode 100644 index 00000000..4b408093 --- /dev/null +++ b/integration_cli_test.go @@ -0,0 +1,869 @@ +//go:build integration +// +build integration + +package headscale + +import ( + "encoding/json" + "fmt" + "log" + "net/http" + "os" + "testing" + "time" + + v1 "github.com/juanfont/headscale/gen/go/headscale/v1" + "github.com/ory/dockertest/v3" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/suite" +) + +type IntegrationCLITestSuite struct { + suite.Suite + stats *suite.SuiteInformation + + pool dockertest.Pool + network dockertest.Network + headscale dockertest.Resource + env []string +} + +func TestCLIIntegrationTestSuite(t *testing.T) { + s := new(IntegrationCLITestSuite) + + suite.Run(t, s) +} + +func (s *IntegrationCLITestSuite) SetupTest() { + var err error + + if ppool, err := dockertest.NewPool(""); err == nil { + s.pool = *ppool + } else { + log.Fatalf("Could not connect to docker: %s", err) + } + + if pnetwork, err := s.pool.CreateNetwork("headscale-test"); err == nil { + s.network = *pnetwork + } else { + log.Fatalf("Could not create network: %s", err) + } + + headscaleBuildOptions := &dockertest.BuildOptions{ + Dockerfile: "Dockerfile", + ContextDir: ".", + } + + currentPath, err := os.Getwd() + if err != nil { + log.Fatalf("Could not determine current path: %s", err) + } + + headscaleOptions := &dockertest.RunOptions{ + Name: "headscale", + Mounts: []string{ + fmt.Sprintf("%s/integration_test/etc:/etc/headscale", currentPath), + }, + Networks: []*dockertest.Network{&s.network}, + Cmd: []string{"headscale", "serve"}, + } + + fmt.Println("Creating headscale container") + if pheadscale, err := s.pool.BuildAndRunWithBuildOptions(headscaleBuildOptions, headscaleOptions, DockerRestartPolicy); err == nil { + s.headscale = *pheadscale + } else { + log.Fatalf("Could not start resource: %s", err) + } + fmt.Println("Created headscale container") + + fmt.Println("Waiting for headscale to be ready") + hostEndpoint := fmt.Sprintf("localhost:%s", s.headscale.GetPort("8080/tcp")) + + if err := s.pool.Retry(func() error { + url := fmt.Sprintf("http://%s/health", hostEndpoint) + resp, err := http.Get(url) + if err != nil { + return err + } + if resp.StatusCode != http.StatusOK { + return fmt.Errorf("status code not OK") + } + return nil + }); err != nil { + // TODO(kradalby): If we cannot access headscale, or any other fatal error during + // test setup, we need to abort and tear down. However, testify does not seem to + // support that at the moment: + // https://github.com/stretchr/testify/issues/849 + return // fmt.Errorf("Could not connect to headscale: %s", err) + } + fmt.Println("headscale container is ready") +} + +func (s *IntegrationCLITestSuite) TearDownTest() { + if err := s.pool.Purge(&s.headscale); err != nil { + log.Printf("Could not purge resource: %s\n", err) + } + + if err := s.network.Close(); err != nil { + log.Printf("Could not close network: %s\n", err) + } +} + +func (s *IntegrationCLITestSuite) HandleStats(suiteName string, stats *suite.SuiteInformation) { + s.stats = stats +} + +func (s *IntegrationCLITestSuite) createNamespace(name string) (*v1.Namespace, error) { + result, err := ExecuteCommand( + &s.headscale, + []string{ + "headscale", + "namespaces", + "create", + name, + "--output", + "json", + }, + []string{}, + ) + if err != nil { + return nil, err + } + + var namespace v1.Namespace + err = json.Unmarshal([]byte(result), &namespace) + if err != nil { + return nil, err + } + + return &namespace, nil +} + +func (s *IntegrationCLITestSuite) TestNamespaceCommand() { + names := []string{"namespace1", "otherspace", "tasty"} + namespaces := make([]*v1.Namespace, len(names)) + + for index, namespaceName := range names { + + namespace, err := s.createNamespace(namespaceName) + assert.Nil(s.T(), err) + + namespaces[index] = namespace + } + + assert.Len(s.T(), namespaces, len(names)) + + assert.Equal(s.T(), names[0], namespaces[0].Name) + assert.Equal(s.T(), names[1], namespaces[1].Name) + assert.Equal(s.T(), names[2], namespaces[2].Name) + + // Test list namespaces + listResult, err := ExecuteCommand( + &s.headscale, + []string{ + "headscale", + "namespaces", + "list", + "--output", + "json", + }, + []string{}, + ) + assert.Nil(s.T(), err) + + var listedNamespaces []v1.Namespace + err = json.Unmarshal([]byte(listResult), &listedNamespaces) + assert.Nil(s.T(), err) + + assert.Equal(s.T(), names[0], listedNamespaces[0].Name) + assert.Equal(s.T(), names[1], listedNamespaces[1].Name) + assert.Equal(s.T(), names[2], listedNamespaces[2].Name) + + // Test rename namespace + renameResult, err := ExecuteCommand( + &s.headscale, + []string{ + "headscale", + "namespaces", + "rename", + "--output", + "json", + "tasty", + "newname", + }, + []string{}, + ) + assert.Nil(s.T(), err) + + var renamedNamespace v1.Namespace + err = json.Unmarshal([]byte(renameResult), &renamedNamespace) + assert.Nil(s.T(), err) + + assert.Equal(s.T(), renamedNamespace.Name, "newname") + + // Test list after rename namespaces + listAfterRenameResult, err := ExecuteCommand( + &s.headscale, + []string{ + "headscale", + "namespaces", + "list", + "--output", + "json", + }, + []string{}, + ) + assert.Nil(s.T(), err) + + var listedAfterRenameNamespaces []v1.Namespace + err = json.Unmarshal([]byte(listAfterRenameResult), &listedAfterRenameNamespaces) + assert.Nil(s.T(), err) + + assert.Equal(s.T(), names[0], listedAfterRenameNamespaces[0].Name) + assert.Equal(s.T(), names[1], listedAfterRenameNamespaces[1].Name) + assert.Equal(s.T(), "newname", listedAfterRenameNamespaces[2].Name) +} + +func (s *IntegrationCLITestSuite) TestPreAuthKeyCommand() { + count := 5 + + namespace, err := s.createNamespace("pre-auth-key-namespace") + + keys := make([]*v1.PreAuthKey, count) + assert.Nil(s.T(), err) + + for i := 0; i < count; i++ { + preAuthResult, err := ExecuteCommand( + &s.headscale, + []string{ + "headscale", + "preauthkeys", + "--namespace", + namespace.Name, + "create", + "--reusable", + "--expiration", + "24h", + "--output", + "json", + }, + []string{}, + ) + assert.Nil(s.T(), err) + + var preAuthKey v1.PreAuthKey + err = json.Unmarshal([]byte(preAuthResult), &preAuthKey) + assert.Nil(s.T(), err) + + keys[i] = &preAuthKey + } + + assert.Len(s.T(), keys, 5) + + // Test list of keys + listResult, err := ExecuteCommand( + &s.headscale, + []string{ + "headscale", + "preauthkeys", + "--namespace", + namespace.Name, + "list", + "--output", + "json", + }, + []string{}, + ) + assert.Nil(s.T(), err) + + var listedPreAuthKeys []v1.PreAuthKey + err = json.Unmarshal([]byte(listResult), &listedPreAuthKeys) + assert.Nil(s.T(), err) + + assert.Equal(s.T(), "1", listedPreAuthKeys[0].Id) + assert.Equal(s.T(), "2", listedPreAuthKeys[1].Id) + assert.Equal(s.T(), "3", listedPreAuthKeys[2].Id) + assert.Equal(s.T(), "4", listedPreAuthKeys[3].Id) + assert.Equal(s.T(), "5", listedPreAuthKeys[4].Id) + + assert.NotEmpty(s.T(), listedPreAuthKeys[0].Key) + assert.NotEmpty(s.T(), listedPreAuthKeys[1].Key) + assert.NotEmpty(s.T(), listedPreAuthKeys[2].Key) + assert.NotEmpty(s.T(), listedPreAuthKeys[3].Key) + assert.NotEmpty(s.T(), listedPreAuthKeys[4].Key) + + assert.True(s.T(), listedPreAuthKeys[0].Expiration.AsTime().After(time.Now())) + assert.True(s.T(), listedPreAuthKeys[1].Expiration.AsTime().After(time.Now())) + assert.True(s.T(), listedPreAuthKeys[2].Expiration.AsTime().After(time.Now())) + assert.True(s.T(), listedPreAuthKeys[3].Expiration.AsTime().After(time.Now())) + assert.True(s.T(), listedPreAuthKeys[4].Expiration.AsTime().After(time.Now())) + + // Expire three keys + for i := 0; i < 3; i++ { + _, err := ExecuteCommand( + &s.headscale, + []string{ + "headscale", + "preauthkeys", + "--namespace", + namespace.Name, + "expire", + listedPreAuthKeys[i].Key, + }, + []string{}, + ) + assert.Nil(s.T(), err) + } + + // Test list pre auth keys after expire + listAfterExpireResult, err := ExecuteCommand( + &s.headscale, + []string{ + "headscale", + "preauthkeys", + "--namespace", + namespace.Name, + "list", + "--output", + "json", + }, + []string{}, + ) + assert.Nil(s.T(), err) + + var listedAfterExpirePreAuthKeys []v1.PreAuthKey + err = json.Unmarshal([]byte(listAfterExpireResult), &listedAfterExpirePreAuthKeys) + assert.Nil(s.T(), err) + + assert.True(s.T(), listedAfterExpirePreAuthKeys[0].Expiration.AsTime().Before(time.Now())) + assert.True(s.T(), listedAfterExpirePreAuthKeys[1].Expiration.AsTime().Before(time.Now())) + assert.True(s.T(), listedAfterExpirePreAuthKeys[2].Expiration.AsTime().Before(time.Now())) + assert.True(s.T(), listedAfterExpirePreAuthKeys[3].Expiration.AsTime().After(time.Now())) + assert.True(s.T(), listedAfterExpirePreAuthKeys[4].Expiration.AsTime().After(time.Now())) +} + +func (s *IntegrationCLITestSuite) TestNodeCommand() { + namespace, err := s.createNamespace("machine-namespace") + assert.Nil(s.T(), err) + + sharedNamespace, err := s.createNamespace("shared-namespace") + assert.Nil(s.T(), err) + + // Randomly generated machine keys + machineKeys := []string{ + "9b2ffa7e08cc421a3d2cca9012280f6a236fd0de0b4ce005b30a98ad930306fe", + "6abd00bb5fdda622db51387088c68e97e71ce58e7056aa54f592b6a8219d524c", + "f08305b4ee4250b95a70f3b7504d048d75d899993c624a26d422c67af0422507", + "8bc13285cee598acf76b1824a6f4490f7f2e3751b201e28aeb3b07fe81d5b4a1", + "cf7b0fd05da556fdc3bab365787b506fd82d64a70745db70e00e86c1b1c03084", + } + machines := make([]*v1.Machine, len(machineKeys)) + assert.Nil(s.T(), err) + + for index, machineKey := range machineKeys { + _, err := ExecuteCommand( + &s.headscale, + []string{ + "headscale", + "debug", + "create-node", + "--name", + fmt.Sprintf("machine-%d", index+1), + "--namespace", + namespace.Name, + "--key", + machineKey, + "--output", + "json", + }, + []string{}, + ) + assert.Nil(s.T(), err) + + machineResult, err := ExecuteCommand( + &s.headscale, + []string{ + "headscale", + "nodes", + "--namespace", + namespace.Name, + "register", + "--key", + machineKey, + "--output", + "json", + }, + []string{}, + ) + assert.Nil(s.T(), err) + + var machine v1.Machine + err = json.Unmarshal([]byte(machineResult), &machine) + assert.Nil(s.T(), err) + + machines[index] = &machine + } + + assert.Len(s.T(), machines, len(machineKeys)) + + // Test list all nodes after added shared + listAllResult, err := ExecuteCommand( + &s.headscale, + []string{ + "headscale", + "nodes", + "list", + "--output", + "json", + }, + []string{}, + ) + assert.Nil(s.T(), err) + + var listAll []v1.Machine + err = json.Unmarshal([]byte(listAllResult), &listAll) + assert.Nil(s.T(), err) + + assert.Len(s.T(), listAll, 5) + + assert.Equal(s.T(), uint64(1), listAll[0].Id) + assert.Equal(s.T(), uint64(2), listAll[1].Id) + assert.Equal(s.T(), uint64(3), listAll[2].Id) + assert.Equal(s.T(), uint64(4), listAll[3].Id) + assert.Equal(s.T(), uint64(5), listAll[4].Id) + + assert.Equal(s.T(), "machine-1", listAll[0].Name) + assert.Equal(s.T(), "machine-2", listAll[1].Name) + assert.Equal(s.T(), "machine-3", listAll[2].Name) + assert.Equal(s.T(), "machine-4", listAll[3].Name) + assert.Equal(s.T(), "machine-5", listAll[4].Name) + + assert.True(s.T(), listAll[0].Registered) + assert.True(s.T(), listAll[1].Registered) + assert.True(s.T(), listAll[2].Registered) + assert.True(s.T(), listAll[3].Registered) + assert.True(s.T(), listAll[4].Registered) + + sharedMachineKeys := []string{ + "b5b444774186d4217adcec407563a1223929465ee2c68a4da13af0d0185b4f8e", + "dc721977ac7415aafa87f7d4574cbe07c6b171834a6d37375782bdc1fb6b3584", + } + sharedMachines := make([]*v1.Machine, len(sharedMachineKeys)) + assert.Nil(s.T(), err) + + for index, machineKey := range sharedMachineKeys { + _, err := ExecuteCommand( + &s.headscale, + []string{ + "headscale", + "debug", + "create-node", + "--name", + fmt.Sprintf("shared-machine-%d", index+1), + "--namespace", + namespace.Name, + "--key", + machineKey, + "--output", + "json", + }, + []string{}, + ) + assert.Nil(s.T(), err) + + machineResult, err := ExecuteCommand( + &s.headscale, + []string{ + "headscale", + "nodes", + "--namespace", + sharedNamespace.Name, + "register", + "--key", + machineKey, + "--output", + "json", + }, + []string{}, + ) + assert.Nil(s.T(), err) + + var machine v1.Machine + err = json.Unmarshal([]byte(machineResult), &machine) + assert.Nil(s.T(), err) + + sharedMachines[index] = &machine + } + + assert.Len(s.T(), sharedMachines, len(sharedMachineKeys)) + + // Test list all nodes after added shared + listAllWithSharedResult, err := ExecuteCommand( + &s.headscale, + []string{ + "headscale", + "nodes", + "list", + "--output", + "json", + }, + []string{}, + ) + assert.Nil(s.T(), err) + + var listAllWithShared []v1.Machine + err = json.Unmarshal([]byte(listAllWithSharedResult), &listAllWithShared) + assert.Nil(s.T(), err) + + // All nodes, machines + shared + assert.Len(s.T(), listAllWithShared, 7) + + assert.Equal(s.T(), uint64(6), listAllWithShared[5].Id) + assert.Equal(s.T(), uint64(7), listAllWithShared[6].Id) + + assert.Equal(s.T(), "shared-machine-1", listAllWithShared[5].Name) + assert.Equal(s.T(), "shared-machine-2", listAllWithShared[6].Name) + + assert.True(s.T(), listAllWithShared[5].Registered) + assert.True(s.T(), listAllWithShared[6].Registered) + + // Test list all nodes after added shared + listOnlySharedMachineNamespaceResult, err := ExecuteCommand( + &s.headscale, + []string{ + "headscale", + "nodes", + "list", + "--namespace", + sharedNamespace.Name, + "--output", + "json", + }, + []string{}, + ) + assert.Nil(s.T(), err) + + var listOnlySharedMachineNamespace []v1.Machine + err = json.Unmarshal([]byte(listOnlySharedMachineNamespaceResult), &listOnlySharedMachineNamespace) + assert.Nil(s.T(), err) + + assert.Len(s.T(), listOnlySharedMachineNamespace, 2) + + assert.Equal(s.T(), uint64(6), listOnlySharedMachineNamespace[0].Id) + assert.Equal(s.T(), uint64(7), listOnlySharedMachineNamespace[1].Id) + + assert.Equal(s.T(), "shared-machine-1", listOnlySharedMachineNamespace[0].Name) + assert.Equal(s.T(), "shared-machine-2", listOnlySharedMachineNamespace[1].Name) + + assert.True(s.T(), listOnlySharedMachineNamespace[0].Registered) + assert.True(s.T(), listOnlySharedMachineNamespace[1].Registered) + + // Delete a machines + _, err = ExecuteCommand( + &s.headscale, + []string{ + "headscale", + "nodes", + "delete", + "--identifier", + // Delete the last added machine + "4", + "--output", + "json", + "--force", + }, + []string{}, + ) + assert.Nil(s.T(), err) + + // Test: list main namespace after machine is deleted + listOnlyMachineNamespaceAfterDeleteResult, err := ExecuteCommand( + &s.headscale, + []string{ + "headscale", + "nodes", + "list", + "--namespace", + namespace.Name, + "--output", + "json", + }, + []string{}, + ) + assert.Nil(s.T(), err) + + var listOnlyMachineNamespaceAfterDelete []v1.Machine + err = json.Unmarshal([]byte(listOnlyMachineNamespaceAfterDeleteResult), &listOnlyMachineNamespaceAfterDelete) + assert.Nil(s.T(), err) + + assert.Len(s.T(), listOnlyMachineNamespaceAfterDelete, 4) + + // test: share node + + shareMachineResult, err := ExecuteCommand( + &s.headscale, + []string{ + "headscale", + "nodes", + "share", + "--namespace", + namespace.Name, + "--identifier", + "7", + "--output", + "json", + }, + []string{}, + ) + assert.Nil(s.T(), err) + + var shareMachine v1.Machine + err = json.Unmarshal([]byte(shareMachineResult), &shareMachine) + assert.Nil(s.T(), err) + + assert.Equal(s.T(), uint64(7), shareMachine.Id) + + assert.Equal(s.T(), "shared-machine-2", shareMachine.Name) + + assert.True(s.T(), shareMachine.Registered) + + // Test: list main namespace after machine has been shared + listOnlyMachineNamespaceAfterShareResult, err := ExecuteCommand( + &s.headscale, + []string{ + "headscale", + "nodes", + "list", + "--namespace", + namespace.Name, + "--output", + "json", + }, + []string{}, + ) + assert.Nil(s.T(), err) + + var listOnlyMachineNamespaceAfterShare []v1.Machine + err = json.Unmarshal([]byte(listOnlyMachineNamespaceAfterShareResult), &listOnlyMachineNamespaceAfterShare) + assert.Nil(s.T(), err) + + assert.Len(s.T(), listOnlyMachineNamespaceAfterShare, 5) + + assert.Equal(s.T(), uint64(7), listOnlyMachineNamespaceAfterShare[4].Id) + + assert.Equal(s.T(), "shared-machine-2", listOnlyMachineNamespaceAfterShare[4].Name) + + assert.True(s.T(), listOnlyMachineNamespaceAfterShare[4].Registered) + + // test: unshare node + + unshareMachineResult, err := ExecuteCommand( + &s.headscale, + []string{ + "headscale", + "nodes", + "unshare", + "--namespace", + namespace.Name, + "--identifier", + "7", + "--output", + "json", + }, + []string{}, + ) + assert.Nil(s.T(), err) + + var unshareMachine v1.Machine + err = json.Unmarshal([]byte(unshareMachineResult), &unshareMachine) + assert.Nil(s.T(), err) + + assert.Equal(s.T(), uint64(7), unshareMachine.Id) + + assert.Equal(s.T(), "shared-machine-2", unshareMachine.Name) + + assert.True(s.T(), unshareMachine.Registered) + + // Test: list main namespace after machine has been shared + listOnlyMachineNamespaceAfterUnshareResult, err := ExecuteCommand( + &s.headscale, + []string{ + "headscale", + "nodes", + "list", + "--namespace", + namespace.Name, + "--output", + "json", + }, + []string{}, + ) + assert.Nil(s.T(), err) + + var listOnlyMachineNamespaceAfterUnshare []v1.Machine + err = json.Unmarshal([]byte(listOnlyMachineNamespaceAfterUnshareResult), &listOnlyMachineNamespaceAfterUnshare) + assert.Nil(s.T(), err) + + assert.Len(s.T(), listOnlyMachineNamespaceAfterUnshare, 4) +} + +func (s *IntegrationCLITestSuite) TestRouteCommand() { + namespace, err := s.createNamespace("routes-namespace") + assert.Nil(s.T(), err) + + // Randomly generated machine keys + machineKey := "9b2ffa7e08cc421a3d2cca9012280f6a236fd0de0b4ce005b30a98ad930306fe" + + _, err = ExecuteCommand( + &s.headscale, + []string{ + "headscale", + "debug", + "create-node", + "--name", + "route-machine", + "--namespace", + namespace.Name, + "--key", + machineKey, + "--route", + "10.0.0.0/8", + "--route", + "192.168.1.0/24", + "--output", + "json", + }, + []string{}, + ) + assert.Nil(s.T(), err) + + machineResult, err := ExecuteCommand( + &s.headscale, + []string{ + "headscale", + "nodes", + "--namespace", + namespace.Name, + "register", + "--key", + machineKey, + "--output", + "json", + }, + []string{}, + ) + assert.Nil(s.T(), err) + + var machine v1.Machine + err = json.Unmarshal([]byte(machineResult), &machine) + assert.Nil(s.T(), err) + + assert.Equal(s.T(), uint64(1), machine.Id) + assert.Equal(s.T(), "route-machine", machine.Name) + assert.True(s.T(), machine.Registered) + + listAllResult, err := ExecuteCommand( + &s.headscale, + []string{ + "headscale", + "routes", + "list", + "--output", + "json", + "--identifier", + "0", + }, + []string{}, + ) + assert.Nil(s.T(), err) + + var listAll v1.Routes + err = json.Unmarshal([]byte(listAllResult), &listAll) + assert.Nil(s.T(), err) + + assert.Len(s.T(), listAll.AdvertisedRoutes, 2) + assert.Contains(s.T(), listAll.AdvertisedRoutes, "10.0.0.0/8") + assert.Contains(s.T(), listAll.AdvertisedRoutes, "192.168.1.0/24") + + assert.Empty(s.T(), listAll.EnabledRoutes) + + enableTwoRoutesResult, err := ExecuteCommand( + &s.headscale, + []string{ + "headscale", + "routes", + "enable", + "--output", + "json", + "--identifier", + "0", + "--route", + "10.0.0.0/8", + "--route", + "192.168.1.0/24", + }, + []string{}, + ) + assert.Nil(s.T(), err) + + var enableTwoRoutes v1.Routes + err = json.Unmarshal([]byte(enableTwoRoutesResult), &enableTwoRoutes) + assert.Nil(s.T(), err) + + assert.Len(s.T(), enableTwoRoutes.AdvertisedRoutes, 2) + assert.Contains(s.T(), enableTwoRoutes.AdvertisedRoutes, "10.0.0.0/8") + assert.Contains(s.T(), enableTwoRoutes.AdvertisedRoutes, "192.168.1.0/24") + + assert.Len(s.T(), enableTwoRoutes.EnabledRoutes, 2) + assert.Contains(s.T(), enableTwoRoutes.EnabledRoutes, "10.0.0.0/8") + assert.Contains(s.T(), enableTwoRoutes.EnabledRoutes, "192.168.1.0/24") + + // Enable only one route, effectively disabling one of the routes + enableOneRouteResult, err := ExecuteCommand( + &s.headscale, + []string{ + "headscale", + "routes", + "enable", + "--output", + "json", + "--identifier", + "0", + "--route", + "10.0.0.0/8", + }, + []string{}, + ) + assert.Nil(s.T(), err) + + var enableOneRoute v1.Routes + err = json.Unmarshal([]byte(enableOneRouteResult), &enableOneRoute) + assert.Nil(s.T(), err) + + assert.Len(s.T(), enableOneRoute.AdvertisedRoutes, 2) + assert.Contains(s.T(), enableOneRoute.AdvertisedRoutes, "10.0.0.0/8") + assert.Contains(s.T(), enableOneRoute.AdvertisedRoutes, "192.168.1.0/24") + + assert.Len(s.T(), enableOneRoute.EnabledRoutes, 1) + assert.Contains(s.T(), enableOneRoute.EnabledRoutes, "10.0.0.0/8") + + // Enable only one route, effectively disabling one of the routes + failEnableNonAdvertisedRoute, err := ExecuteCommand( + &s.headscale, + []string{ + "headscale", + "routes", + "enable", + "--output", + "json", + "--identifier", + "0", + "--route", + "11.0.0.0/8", + }, + []string{}, + ) + assert.Nil(s.T(), err) + + assert.Contains(s.T(), string(failEnableNonAdvertisedRoute), "route (route-machine) is not available on node") +} From 3ad2350c798a7a4027f4ecd43d8b44f82c767d37 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Fri, 5 Nov 2021 07:24:00 +0000 Subject: [PATCH 091/300] Fix new version of hujson --- acls.go | 9 ++++++++- acls_types.go | 9 ++++++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/acls.go b/acls.go index 4d4d45b3..cb02e044 100644 --- a/acls.go +++ b/acls.go @@ -38,7 +38,14 @@ func (h *Headscale) LoadACLPolicy(path string) error { if err != nil { return err } - err = hujson.Unmarshal(b, &policy) + + ast, err := hujson.Parse(b) + if err != nil { + return err + } + ast.Standardize() + b = ast.Pack() + err = json.Unmarshal(b, &policy) if err != nil { return err } diff --git a/acls_types.go b/acls_types.go index 01e42d50..67b74e73 100644 --- a/acls_types.go +++ b/acls_types.go @@ -1,6 +1,7 @@ package headscale import ( + "encoding/json" "strings" "github.com/tailscale/hujson" @@ -43,7 +44,13 @@ type ACLTest struct { func (h *Hosts) UnmarshalJSON(data []byte) error { hosts := Hosts{} hs := make(map[string]string) - err := hujson.Unmarshal(data, &hs) + ast, err := hujson.Parse(data) + if err != nil { + return err + } + ast.Standardize() + data = ast.Pack() + err = json.Unmarshal(data, &hs) if err != nil { return err } From 8115f50d0368ff75c9f246b81f14f0be20324b56 Mon Sep 17 00:00:00 2001 From: Abraham Ingersoll Date: Sat, 6 Nov 2021 07:43:41 +0000 Subject: [PATCH 092/300] Typo in golang URL --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 709f0ad5..e9f7990f 100644 --- a/README.md +++ b/README.md @@ -62,7 +62,7 @@ Please have a look at the documentation under [`docs/`](docs/). ## Contributing -To contribute to Headscale you would need the lastest version of [Go](golang.org) and [Buf](https://buf.build)(Protobuf generator). +To contribute to Headscale you would need the lastest version of [Go](https://golang.org) and [Buf](https://buf.build)(Protobuf generator). ### Install development tools From 26718e83083ac47842c5d71b23069e3329b6aa97 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Sat, 6 Nov 2021 20:23:04 +0000 Subject: [PATCH 093/300] Revert gorm upgrade --- go.mod | 9 ++- go.sum | 177 +++++++++++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 164 insertions(+), 22 deletions(-) diff --git a/go.mod b/go.mod index 6056c8bc..bd2d3b73 100644 --- a/go.mod +++ b/go.mod @@ -21,7 +21,6 @@ require ( github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 github.com/grpc-ecosystem/grpc-gateway/v2 v2.6.0 github.com/hako/durafmt v0.0.0-20210608085754-5c1018a4e16b - github.com/hashicorp/go-version v1.2.0 // indirect github.com/infobloxopen/protoc-gen-gorm v1.0.1 github.com/json-iterator/go v1.1.12 // indirect github.com/klauspost/compress v1.13.6 @@ -59,10 +58,10 @@ require ( gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c gopkg.in/square/go-jose.v2 v2.6.0 // indirect gopkg.in/yaml.v2 v2.4.0 - gorm.io/datatypes v1.0.3 - gorm.io/driver/postgres v1.2.1 - gorm.io/driver/sqlite v1.2.3 - gorm.io/gorm v1.22.2 + gorm.io/datatypes v1.0.2 + gorm.io/driver/postgres v1.1.1 + gorm.io/driver/sqlite v1.1.5 + gorm.io/gorm v1.21.15 inet.af/netaddr v0.0.0-20211027220019-c74959edd3b6 tailscale.com v1.14.6 ) diff --git a/go.sum b/go.sum index ae1e0935..5859516d 100644 --- a/go.sum +++ b/go.sum @@ -51,6 +51,7 @@ github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= github.com/Djarvur/go-err113 v0.0.0-20200511133814-5174e21577d5/go.mod h1:4UJr5HIiMZrwgkSPdsjy2uOQExX/WEILpIrO9UPGuXs= github.com/Djarvur/go-err113 v0.1.0/go.mod h1:4UJr5HIiMZrwgkSPdsjy2uOQExX/WEILpIrO9UPGuXs= +github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= github.com/MarvinJWendt/testza v0.1.0/go.mod h1:7AxNvlfeHP7Z/hDQ5JtE3OKYT3XFUeLCDE2DQninSqs= github.com/MarvinJWendt/testza v0.2.1 h1:eitywm1lzygA2KCyn55jFVdOaXj5I9LeOsLNeifd2Kw= github.com/MarvinJWendt/testza v0.2.1/go.mod h1:God7bhG8n6uQxwdScay+gjm9/LnO4D3kkcZX4hv9Rp8= @@ -73,7 +74,11 @@ github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8 github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/OpenPeeDeeP/depguard v1.0.1/go.mod h1:xsIw86fROiiwelg+jB2uM9PiKihMMmUx/1V+TNhjQvM= github.com/PuerkitoBio/goquery v1.5.1/go.mod h1:GsLWisAFVj4WgDibEWF4pvYnkVQBpKBKeU+7zCJoLcc= +github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= +github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= +github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= +github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs= github.com/alecthomas/kingpin v2.2.6+incompatible/go.mod h1:59OFYbFVLKQKq+mqrL6Rw5bR0c3ACQaawgXx0QYndlE= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= @@ -87,14 +92,20 @@ github.com/andybalholm/cascadia v1.1.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9Pq github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= +github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= +github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= github.com/atomicgo/cursor v0.0.1 h1:xdogsqa6YYlLfM+GyClC/Lchf7aiMerFiZQn7soTOoU= github.com/atomicgo/cursor v0.0.1/go.mod h1:cBON2QmmrysudxNBFthvMtN32r3jxVRIvzkUiF/RuIk= +github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= +github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.38.52/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= +github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= @@ -107,7 +118,10 @@ github.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqO github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb/go.mod h1:PkYb9DJNAwrSvRx5DYA+gUcOIgTGVMNkfSCbZM8cWpI= github.com/bombsimon/wsl/v3 v3.1.0/go.mod h1:st10JtZYLE4D5sC7b8xV4zTKZwAQjCH/Hy2Pm1FNZIc= github.com/bufbuild/buf v0.37.0/go.mod h1:lQ1m2HkIaGOFba6w/aC3KYBHhKEOESP3gaAEpS3dAFM= +github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= github.com/cavaliercoder/go-cpio v0.0.0-20180626203310-925f9528c45e/go.mod h1:oDpT4efm8tSYHXV5tHSdRvBet/b/QzxZ+XyyPehvm3A= +github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4= +github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= github.com/cenkalti/backoff/v4 v4.1.0/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= github.com/cenkalti/backoff/v4 v4.1.1 h1:G2HAfAmvm/GcKan2oOQpBXOd2tT2G57ZnZGWa1PxPBQ= github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= @@ -123,6 +137,7 @@ github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5P github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/cilium/ebpf v0.5.0/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs= github.com/cilium/ebpf v0.6.2/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs= +github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= @@ -134,6 +149,8 @@ github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWH github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I= github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= +github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= +github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= github.com/containerd/console v1.0.2/go.mod h1:ytZPjGgY2oeTkAONYafi2kSj0aYggsf8acV1PGKCbzQ= github.com/containerd/continuity v0.0.0-20190827140505-75bee3e2ccb6/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= github.com/containerd/continuity v0.1.0 h1:UFRRY5JemiAhPZrr/uE0n8fMTLcZsUvySPr1+D7pgr8= @@ -146,9 +163,11 @@ github.com/coreos/go-oidc/v3 v3.1.0 h1:6avEvcdvTa1qYsOZ6I5PRkSYHzpTNWgKYmaJfaYbr github.com/coreos/go-oidc/v3 v3.1.0/go.mod h1:rEJ/idjfUyfkBit1eI1fvyr+64/g9dcKpAm8MJMesvo= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= @@ -166,8 +185,8 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/denis-tingajkin/go-header v0.3.1/go.mod h1:sq/2IxMhaZX+RRcgHfCRx/m0M5na0fBt4/CRe7Lrji0= github.com/denisenkom/go-mssqldb v0.0.0-20191124224453-732737034ffd/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU= github.com/denisenkom/go-mssqldb v0.9.0/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU= -github.com/denisenkom/go-mssqldb v0.11.0 h1:9rHa233rhdOyrz2GcP9NM+gi2psgJZ4GWDpL/7ND8HI= -github.com/denisenkom/go-mssqldb v0.11.0/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU= +github.com/denisenkom/go-mssqldb v0.10.0 h1:QykgLZBorFE95+gO3u9esLd0BmbvpWp0/waNNZfHBM8= +github.com/denisenkom/go-mssqldb v0.10.0/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgrijalva/jwt-go v3.2.1-0.20200107013213-dc14462fd587+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= @@ -181,11 +200,17 @@ github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKoh github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= +github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dvyukov/go-fuzz v0.0.0-20210103155950-6a8e9d1f2415/go.mod h1:11Gm+ccJnvAhCNLlf5+cS9KjtbaD5I5zaZpFMsTHWTw= +github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= +github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= +github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= +github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= github.com/efekarakus/termcolor v1.0.1 h1:YAKFO3bnLrqZGTWyNLcYoSIAQFKVOmbqmDnwsU/znzg= github.com/efekarakus/termcolor v1.0.1/go.mod h1:AitrZNrE4nPO538fRsqf+p0WgLdAsGN5pUNrHEPsEMM= github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o= +github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= @@ -204,6 +229,8 @@ github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGE github.com/fatih/set v0.2.1 h1:nn2CaJyknWE/6txyUDGwysr3G5QC6xWB/PtVjPBbeaA= github.com/fatih/set v0.2.1/go.mod h1:+RKtMCH+favT2+3YecHGxcc0b4KyVWA1QWWJUs4E0CI= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= +github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= +github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= github.com/frankban/quicktest v1.13.0/go.mod h1:qLE0fzW0VuyUAJgPU19zByoIr0HtCHN/r/VLSOOIySU= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= @@ -228,6 +255,7 @@ github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2 github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= @@ -265,10 +293,13 @@ github.com/go-xmlfmt/xmlfmt v0.0.0-20191208150333-d5b6f63a941b/go.mod h1:aUCEOzz github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gofrs/flock v0.8.0/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= +github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gofrs/uuid v4.1.0+incompatible h1:sIa2eCvUTwgjbqXrPLfNwUf9S3i3mpH1O1atV+iL/Wk= github.com/gofrs/uuid v4.1.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= +github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= @@ -277,6 +308,7 @@ github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2V github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/glog v1.0.0 h1:nfP3RFugxnNRyKgeWd4oI1nYvXpxrx8ck8ZrcizshdQ= github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4= +github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -307,6 +339,7 @@ github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaS github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2/go.mod h1:k9Qvh+8juN+UKMCS/3jFtGICgW8O96FVaZsaxdzDkR4= github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a/go.mod h1:ryS0uhF+x9jgbj/N71xsEqODy9BN81/GonCZiOzirOk= @@ -379,6 +412,10 @@ github.com/gordonklaus/ineffassign v0.0.0-20200309095847-7953dde2c7bf/go.mod h1: github.com/goreleaser/chglog v0.1.2/go.mod h1:tTZsFuSZK4epDXfjMkxzcGbrIOXprf0JFp47BjIr3B8= github.com/goreleaser/fileglob v0.3.1/go.mod h1:kNcPrPzjCp+Ox3jmXLU5QEsjhqrtLBm6OnXAif8KRl8= github.com/goreleaser/nfpm v1.10.3/go.mod h1:EEC7YD5wi+ol0MiAshpgPANBOkjXDl7wqTLVk68OBsk= +github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= +github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gostaticanalysis/analysisutil v0.0.0-20190318220348-4088753ea4d3/go.mod h1:eEOZF4jCKGi+aprrirO9e7WKB3beBRtWgqGunKl6pKE= @@ -388,11 +425,13 @@ github.com/gostaticanalysis/analysisutil v0.6.1/go.mod h1:18U/DLpRgIUd459wGxVHE0 github.com/gostaticanalysis/comment v1.3.0/go.mod h1:xMicKDx7XRXYdVwY9f9wQpDJVnqWxw9wCauCMKp+IBI= github.com/gostaticanalysis/comment v1.4.1/go.mod h1:ih6ZxzTHLdadaiSnF5WY3dxUoXfXAlTaRzuaNDlSado= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-middleware v1.2.2/go.mod h1:EaizFBKfUKtMIF5iaDEhniwNedqGo9FuLFzppDr3uwI= github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 h1:+9834+KizmvFV7pXQGSXQTsaWhq2GjuNUt0aUU0YBYw= github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.14.6/go.mod h1:zdiPV4Yse/1gnckTHtghG4GkDEdKCRJduHpTxT3/jcw= github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= @@ -403,7 +442,9 @@ github.com/grpc-ecosystem/grpc-gateway/v2 v2.6.0/go.mod h1:qrJPVzv9YlhsrxJc3P/Q8 github.com/hako/durafmt v0.0.0-20210608085754-5c1018a4e16b h1:wDUNC2eKiL35DbLvsDhiblTUXHxcOPwQSCzi7xpQUN4= github.com/hako/durafmt v0.0.0-20210608085754-5c1018a4e16b/go.mod h1:VzxiSdG6j1pi7rwGm/xYI5RbtpBgM8sARDXlvEvxlu0= github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= +github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE= github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= +github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= @@ -429,6 +470,7 @@ github.com/hinshun/vt10x v0.0.0-20180616224451-1954e6464174 h1:WlZsjVhE8Af9IcZDG github.com/hinshun/vt10x v0.0.0-20180616224451-1954e6464174/go.mod h1:DqJ97dSdRW1W22yXSB90986pcOyQ7r45iio1KN2ez1A= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/huandu/xstrings v1.3.2/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= +github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= github.com/hugelgupf/socketpair v0.0.0-20190730060125-05d35a94e714/go.mod h1:2Goc3h8EklBH5mspfHFxBnEoURQCGzQQH1ga9Myjvis= github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= @@ -439,6 +481,7 @@ github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU= github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= github.com/infobloxopen/atlas-app-toolkit v0.24.1-0.20210416193901-4c7518b07e08/go.mod h1:9BTHnpff654rY1J8KxSUOLJ+ZUDn2Vi3mmk26gQDo1M= github.com/infobloxopen/protoc-gen-gorm v1.0.1 h1:IjvQ02gZSll+CjpWjxkLqrpxnvKAGfs5dXRJEpfZx2s= github.com/infobloxopen/protoc-gen-gorm v1.0.1/go.mod h1:gTu86stnDQXwcNqLG9WNJfl3IPUIhxmGNqJ8z4826uo= @@ -451,7 +494,11 @@ github.com/jackc/chunkreader/v2 v2.0.1/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgO github.com/jackc/pgconn v0.0.0-20190420214824-7e0022ef6ba3/go.mod h1:jkELnwuX+w9qN5YIfX0fl88Ehu4XC3keFuOJJk9pcnA= github.com/jackc/pgconn v0.0.0-20190824142844-760dd75542eb/go.mod h1:lLjNuW/+OfW9/pnVKPazfWOgNfH2aPem8YQ7ilXGvJE= github.com/jackc/pgconn v0.0.0-20190831204454-2fabfa3c18b7/go.mod h1:ZJKsE/KZfsUgOEh9hBm+xYTstcNHg7UPMVJqRfQxq4s= +github.com/jackc/pgconn v1.4.0/go.mod h1:Y2O3ZDF0q4mMacyWV3AstPJpeHXWGEetiFttmq5lahk= +github.com/jackc/pgconn v1.5.0/go.mod h1:QeD3lBfpTFe8WUnPZWN5KY/mB8FGMIYRdd8P8Jr0fAI= +github.com/jackc/pgconn v1.5.1-0.20200601181101-fa742c524853/go.mod h1:QeD3lBfpTFe8WUnPZWN5KY/mB8FGMIYRdd8P8Jr0fAI= github.com/jackc/pgconn v1.8.0/go.mod h1:1C2Pb36bGIP9QHGBYCjnyhqu7Rv3sGshaQUvmfGIB/o= +github.com/jackc/pgconn v1.8.1/go.mod h1:JV6m6b6jhjdmzchES0drzCcYcAHS1OPD5xu3OZ/lE2g= github.com/jackc/pgconn v1.9.0/go.mod h1:YctiPyvzfU11JFxoXokUOOKQXQmDMoJL9vJzHH8/2JY= github.com/jackc/pgconn v1.9.1-0.20210724152538-d89c8390a530/go.mod h1:4z2w8XhRbP1hYxkpTuBjTS3ne3J48K83+u0zoyvg2pI= github.com/jackc/pgconn v1.10.0 h1:4EYhlDVEMsJ30nNj0mmgwIUXoq7e9sMJrVC2ED6QlCU= @@ -470,25 +517,37 @@ github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190420180111-c116219b62db/go.mod github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190609003834-432c2951c711/go.mod h1:uH0AWtUmuShn0bcesswc4aBTWGvw0cAxIJp+6OB//Wg= github.com/jackc/pgproto3/v2 v2.0.0-rc3/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM= github.com/jackc/pgproto3/v2 v2.0.0-rc3.0.20190831210041-4c03ce451f29/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM= +github.com/jackc/pgproto3/v2 v2.0.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= github.com/jackc/pgproto3/v2 v2.0.6/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= github.com/jackc/pgproto3/v2 v2.1.1 h1:7PQ/4gLoqnl87ZxL7xjO0DR5gYuviDCZxQJsUlFW1eI= github.com/jackc/pgproto3/v2 v2.1.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= +github.com/jackc/pgservicefile v0.0.0-20200307190119-3430c5407db8/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E= github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b h1:C8S2+VttkHFdOOCXJe+YGfa4vHYwlt4Zx+IVXQ97jYg= github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E= github.com/jackc/pgtype v0.0.0-20190421001408-4ed0de4755e0/go.mod h1:hdSHsc1V01CGwFsrv11mJRHWJ6aifDLfdV3aVjFF0zg= github.com/jackc/pgtype v0.0.0-20190824184912-ab885b375b90/go.mod h1:KcahbBH1nCMSo2DXpzsoWOAfFkdEtEJpPbVLq8eE+mc= github.com/jackc/pgtype v0.0.0-20190828014616-a8802b16cc59/go.mod h1:MWlu30kVJrUS8lot6TQqcg7mtthZ9T0EoIBFiJcmcyw= +github.com/jackc/pgtype v1.2.0/go.mod h1:5m2OfMh1wTK7x+Fk952IDmI4nw3nPrvtQdM0ZT4WpC0= +github.com/jackc/pgtype v1.3.1-0.20200510190516-8cd94a14c75a/go.mod h1:vaogEUkALtxZMCH411K+tKzNpwzCKU+AnPzBKZ+I+Po= +github.com/jackc/pgtype v1.3.1-0.20200606141011-f6355165a91c/go.mod h1:cvk9Bgu/VzJ9/lxTO5R5sf80p0DiucVtN7ZxvaC4GmQ= +github.com/jackc/pgtype v1.7.0/go.mod h1:ZnHF+rMePVqDKaOfJVI4Q8IVvAQMryDlDkZnKOI75BE= github.com/jackc/pgtype v1.8.1-0.20210724151600-32e20a603178/go.mod h1:C516IlIV9NKqfsMCXTdChteoXmwgUceqaLfjg2e3NlM= github.com/jackc/pgtype v1.8.1 h1:9k0IXtdJXHJbyAWQgbWr1lU+MEhPXZz6RIXxfR5oxXs= github.com/jackc/pgtype v1.8.1/go.mod h1:LUMuVrfsFfdKGLw+AFFVv6KtHOFMwRgDDzBt76IqCA4= github.com/jackc/pgx/v4 v4.0.0-20190420224344-cc3461e65d96/go.mod h1:mdxmSJJuR08CZQyj1PVQBHy9XOp5p8/SHH6a0psbY9Y= github.com/jackc/pgx/v4 v4.0.0-20190421002000-1b8f0016e912/go.mod h1:no/Y67Jkk/9WuGR0JG/JseM9irFbnEPbuWV2EELPNuM= github.com/jackc/pgx/v4 v4.0.0-pre1.0.20190824185557-6972a5742186/go.mod h1:X+GQnOEnf1dqHGpw7JmHqHc1NxDoalibchSk9/RWuDc= +github.com/jackc/pgx/v4 v4.5.0/go.mod h1:EpAKPLdnTorwmPUUsqrPxy5fphV18j9q3wrfRXgo+kA= +github.com/jackc/pgx/v4 v4.6.1-0.20200510190926-94ba730bb1e9/go.mod h1:t3/cdRQl6fOLDxqtlyhe9UWgfIi9R8+8v8GKV5TRA/o= +github.com/jackc/pgx/v4 v4.6.1-0.20200606145419-4e5062306904/go.mod h1:ZDaNWkt9sW1JMiNn0kdYBaLelIhw7Pg4qd+Vk6tw7Hg= +github.com/jackc/pgx/v4 v4.11.0/go.mod h1:i62xJgdrtVDsnL3U8ekyrQXEwGNTRoG7/8r+CIdYfcc= github.com/jackc/pgx/v4 v4.12.1-0.20210724153913-640aa07df17c/go.mod h1:1QD0+tgSXP7iUjYm9C1NxKhny7lq6ee99u/z+IHFcgs= github.com/jackc/pgx/v4 v4.13.0 h1:JCjhT5vmhMAf/YwBHLvrBn4OGdIQBiFG6ym8Zmdx570= github.com/jackc/pgx/v4 v4.13.0/go.mod h1:9P4X524sErlaxj0XSGZk7s+LD0eOyu1ZDUrrpznYDF0= github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= +github.com/jackc/puddle v1.1.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= +github.com/jackc/puddle v1.1.1/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= @@ -505,6 +564,7 @@ github.com/jinzhu/now v1.1.2 h1:eVKgfIdy9b6zbWBMgFpfDPoAMifwSZagU9HmEU6zgiI= github.com/jinzhu/now v1.1.2/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= github.com/jirfag/go-printf-func-name v0.0.0-20191110105641-45db9963cdd3/go.mod h1:HEWGJkRDzjJY2sqdDwxccsGicWEf9BQOZsq2tV+xzM0= github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af/go.mod h1:HEWGJkRDzjJY2sqdDwxccsGicWEf9BQOZsq2tV+xzM0= +github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= github.com/jmoiron/sqlx v1.2.0/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks= @@ -522,6 +582,8 @@ github.com/jsimonetti/rtnetlink v0.0.0-20210122163228-8d122574c736/go.mod h1:ZXp github.com/jsimonetti/rtnetlink v0.0.0-20210212075122-66c871082f2b/go.mod h1:8w9Rh8m+aHZIG69YPGGem1i5VzoyRC8nw2kA8B+ik5U= github.com/jsimonetti/rtnetlink v0.0.0-20210525051524-4cc836578190/go.mod h1:NmKSdU4VGSiv1bMsdqNALI4RSvvjtz65tTMCnD05qLo= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= @@ -573,13 +635,17 @@ github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.3.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.3.1-0.20200116171513-9eb3fc897d6f/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/lib/pq v1.10.3 h1:v9QZf2Sn6AmjXtQeFpdoq/eaNtYP6IN+7lcrygsIAtg= github.com/lib/pq v1.10.3/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= +github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= github.com/logrusorgru/aurora v0.0.0-20181002194514-a7b3b318ed4e/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4= github.com/lxn/walk v0.0.0-20210112085537-c389da54e794/go.mod h1:E23UucZGqpuUANJooIbHWCufXvOcT6E7Stq81gU+CSQ= github.com/lxn/win v0.0.0-20210218163916-a377121e959e/go.mod h1:KxxjdtRkfNoYDCUP5ryK7XJJNTnpC8atvtmTheChOtk= +github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= github.com/magefile/mage v1.10.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= @@ -597,21 +663,25 @@ github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8= github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/mattn/go-sqlite3 v1.14.0/go.mod h1:JIl7NbARA7phWnGvh0LKTyg7S9BA+6gx71ShQilpsus= +github.com/mattn/go-sqlite3 v1.14.5/go.mod h1:WVKg1VTActs4Qso6iwGbiFih2UIHo0ENGwNd0Lj+XmI= github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= -github.com/mattn/go-sqlite3 v1.14.9 h1:10HX2Td0ocZpYEjhilsuo6WWtUqttj2Kb0KtD86/KYA= -github.com/mattn/go-sqlite3 v1.14.9/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= +github.com/mattn/go-sqlite3 v1.14.8 h1:gDp86IdQsN/xWjIEmr9MF6o9mpksUgh0fu+9ByFxzIU= +github.com/mattn/go-sqlite3 v1.14.8/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= @@ -670,15 +740,27 @@ github.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2 github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/nakabonne/nestif v0.3.0/go.mod h1:dI314BppzXjJ4HsCnbo7XzrJHPszZsjnk5wEBSYHI2c= +github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= +github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU= +github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k= +github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w= +github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= +github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= +github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= github.com/nbutton23/zxcvbn-go v0.0.0-20180912185939-ae427f1e4c1d/go.mod h1:o96djdrsSGy3AWPyBgZMAGfxZNfgntdJG+11KU4QvbU= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/nishanths/exhaustive v0.1.0/go.mod h1:S1j9110vxV1ECdCudXRkeMnFQ/DQk9ajLT0Uf2MYZQQ= github.com/nishanths/predeclared v0.0.0-20200524104333-86fad755b4d3/go.mod h1:nt3d53pc1VYcphSCIaYAJtnPYnr3Zyn8fMq2wvPGPso= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= +github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= +github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.14.1/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.10.2/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= @@ -693,9 +775,17 @@ github.com/opencontainers/runc v1.0.2 h1:opHZMaswlyxz1OuGpBE53Dwe4/xF7EZTY0A2L/F github.com/opencontainers/runc v1.0.2/go.mod h1:aTaHFFwQXuA71CiyxOdFFIorAoemI04suvGRQFzWTD0= github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/selinux v1.8.2/go.mod h1:MUIHuUEvKB1wtJjQdOyYRgOnLD2xAPP8dBsCoU0KuF8= +github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis= +github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74= +github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA= +github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= +github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= +github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= github.com/ory/dockertest/v3 v3.7.0 h1:Bijzonc69Ont3OU0a3TWKJ1Rzlh3TsDXP1JrTAkSmsM= github.com/ory/dockertest/v3 v3.7.0/go.mod h1:PvCCgnP7AfBZeVrzwiUTjZx/IUXlGLC1zQlUQrLIlUE= +github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc= github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ= @@ -706,17 +796,21 @@ github.com/pelletier/go-toml v1.6.0/go.mod h1:5N711Q9dKgbdkxHL+MEfF31hpT7l0S0s/t github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc= github.com/pelletier/go-toml v1.9.3 h1:zeC5b1GviRUyKYd6OJPvBU/mcVDVoL1OhT17FCt5dSQ= github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= +github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= github.com/peterbourgon/ff/v2 v2.0.0/go.mod h1:xjwr+t+SjWm4L46fcj/D+Ap+6ME7+HqFzaP22pP5Ggk= github.com/peterbourgon/ff/v3 v3.0.0/go.mod h1:UILIFjRH5a/ar8TjXYLTkIvSvekZqPm5Eb/qbGk6CT0= github.com/phayes/checkstyle v0.0.0-20170904204023-bfd46e6a821d/go.mod h1:3OzsM7FXDQlpCiw2j81fOmAwQLnZnLGXVKUzeKQXIAw= github.com/philip-bui/grpc-zerolog v1.0.1 h1:EMacvLRUd2O1K0eWod27ZP5CY1iTNkhBDLSN+Q4JEvA= github.com/philip-bui/grpc-zerolog v1.0.1/go.mod h1:qXbiq/2X4ZUMMshsqlWyTHOcw7ns+GZmlqZZN05ZHcQ= +github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= +github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pkg/diff v0.0.0-20200914180035-5b29258ca4f7/go.mod h1:zO8QMzTeZd5cpnIkz/Gn6iK0jDfGicM1nynOkkPIl28= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= github.com/pkg/profile v1.5.0/go.mod h1:qBsxPvzyUincmltOk6iyRVxHYg4adc0OFOv72ZdLa18= github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= github.com/pkg/sftp v1.13.0/go.mod h1:41g+FIPlQUTDCveupEmEA65IoiQFrtgCeDopC4ajGIM= @@ -726,26 +820,34 @@ github.com/polyfloyd/go-errorlint v0.0.0-20201006195004-351e25ade6e3/go.mod h1:w github.com/polyfloyd/go-errorlint v0.0.0-20201127212506-19bd8db6546f/go.mod h1:wi9BfjxjF/bwiZ701TzmfKu6UKC357IOAtNr0Td0Lvw= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= +github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= github.com/prometheus/client_golang v1.11.0 h1:HNkLOAEQMIDv/K+04rukrLx6ch7msSRwf3/SASFAGtQ= github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= github.com/prometheus/common v0.32.1 h1:hWIdL3N2HoUx3B8j3YN9mWor0qhY/NlEKZEaXxuIRh4= github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/procfs v0.7.3 h1:4jVXhlkAyzOScmCkXBTOLRLTz8EeU+eyjrwB/EPq0VU= @@ -760,6 +862,7 @@ github.com/quasilyte/go-ruleguard v0.2.0/go.mod h1:2RT/tf0Ce0UDj5y243iWKosQogJd8 github.com/quasilyte/go-ruleguard v0.2.1/go.mod h1:hN2rVc/uS4bQhQKTio2XaSJSafJwqBUWWwtssT3cQmc= github.com/quasilyte/regex/syntax v0.0.0-20200407221936-30656e2c4a95/go.mod h1:rlzQ04UMyJXu/aOvhd8qT+hvDrFpiwqp8MRXDY9szc0= github.com/quasilyte/regex/syntax v0.0.0-20200805063351-8f842688393c/go.mod h1:rlzQ04UMyJXu/aOvhd8qT+hvDrFpiwqp8MRXDY9szc0= +github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= @@ -780,6 +883,7 @@ github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQD github.com/ryancurrah/gomodguard v1.1.0/go.mod h1:4O8tr7hBODaGE6VIhfJDHcwzh5GUccKSJBU0UMXJFVM= github.com/ryanrolds/sqlclosecheck v0.3.0/go.mod h1:1gREqxyTGR3lVtpngyFo3hZAgk0KCtEdgEkHwDbigdA= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= github.com/sassoftware/go-rpmutils v0.0.0-20190420191620-a8f1baeba37b/go.mod h1:am+Fp8Bt506lA3Rk3QCmSqmYmLMnPDhdDUcosQCAx+I= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= @@ -791,6 +895,7 @@ github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c/go.mod h1:/PevMnwAx github.com/shirou/gopsutil v0.0.0-20190901111213-e4ec7b275ada/go.mod h1:WWnYX4lzhCH5h/3YBfyVA3VbLYjlMZZAQcW9ojMexNc= github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4/go.mod h1:qsXQc7+bwAM3Q1u/4XEfrquwF8Lw7D7y5cD8CuHnfIc= github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= +github.com/shopspring/decimal v0.0.0-20200227202807-02e2044944cc/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= github.com/shopspring/decimal v1.2.0 h1:abSATXmQEYyShuxI4/vyW3tV1MrKAJzCZ/0zLUXYbsQ= github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk= @@ -812,6 +917,7 @@ github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4k github.com/soheilhy/cmux v0.1.5 h1:jjzc5WVemNEDTLwv9tlmemhC73tI08BNOIGwBOo10Js= github.com/soheilhy/cmux v0.1.5/go.mod h1:T7TcVDs9LWfQgPlPsdngu6I6QIoyIFZDDC6sNE1GqG0= github.com/sonatard/noctx v0.0.1/go.mod h1:9D2D/EoULe8Yy2joDHJj7bv3sZoq9AaSb8B4lqBjiZI= +github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= github.com/sourcegraph/go-diff v0.6.1/go.mod h1:iBszgVvyxdc8SFZ7gm69go2KDdt3ag071iBaWPF6cjs= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= @@ -822,6 +928,7 @@ github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng= github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= github.com/spf13/cobra v1.0.1-0.20201006035406-b97b5ead31f7/go.mod h1:yk5b0mALVusDL5fMM6Rd1wgnoO5jUPhwsQ6LQAJTidQ= github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJQMI= @@ -830,6 +937,7 @@ github.com/spf13/cobra v1.2.1/go.mod h1:ExllRjgxM/piMAM+3tAZvg8fsklGAf3tPfi+i8t6 github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= +github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= @@ -839,6 +947,9 @@ github.com/spf13/viper v1.7.1/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5q github.com/spf13/viper v1.8.1 h1:Kq1fyeebqsBfbjZj4EL7gj2IO0mMaiyjYUWcUsl2O44= github.com/spf13/viper v1.8.1/go.mod h1:o0Pch8wJ9BVSWGQMbra6iw0oQ5oktSIBaujf1rJH9Ns= github.com/ssgreg/nlreturn/v2 v2.1.0/go.mod h1:E/iiPB78hV7Szg2YfRgyIrk1AD6JVMTRkkxBiELzh2I= +github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= +github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= +github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= @@ -870,6 +981,7 @@ github.com/tetafro/godot v1.3.0/go.mod h1:/7NLHhv08H1+8DNj0MElpAACw1ajsCuf3TKNQx github.com/tetafro/godot v1.3.2/go.mod h1:ah7jjYmOMnIjS9ku2krapvGQrFNtTLo9Z/qB3dGU1eU= github.com/timakin/bodyclose v0.0.0-20190930140734-f7f2e9bca95e/go.mod h1:Qimiffbc6q9tBWlVV6x0P9sat/ao1xEkREYPPj9hphk= github.com/timakin/bodyclose v0.0.0-20200424151742-cb6215831a94/go.mod h1:Qimiffbc6q9tBWlVV6x0P9sat/ao1xEkREYPPj9hphk= +github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tomarrell/wrapcheck v0.0.0-20200807122107-df9e8bcb914d/go.mod h1:yiFB6fFoV7saXirUGfuK+cPtUh4NX/Hf5y2WC2lehu0= github.com/tomarrell/wrapcheck v0.0.0-20201130113247-1683564d9756/go.mod h1:yiFB6fFoV7saXirUGfuK+cPtUh4NX/Hf5y2WC2lehu0= @@ -887,6 +999,7 @@ github.com/ugorji/go/codec v1.2.6/go.mod h1:V6TCNZ4PHqoHGFZuSG1W8nrCzzdgA2DozYxW github.com/ulikunitz/xz v0.5.7/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= github.com/ultraware/funlen v0.0.3/go.mod h1:Dp4UiAus7Wdb9KUZsYWZEWiRzGuM2kXM1lPbfaF6xhA= github.com/ultraware/whitespace v0.0.4/go.mod h1:aVMh/gQve5Maj9hQ/hg+F75lr/X5A89uZnzAmWSineA= +github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/uudashr/gocognit v1.0.1/go.mod h1:j44Ayx2KW4+oB6SWMv8KsmHzZrOInQav7D3cQMJ5JUM= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= @@ -920,9 +1033,13 @@ github.com/ziutek/telnet v0.0.0-20180329124119-c3b780dc415b/go.mod h1:IZpXDfkJ6t github.com/zsais/go-gin-prometheus v0.1.0 h1:bkLv1XCdzqVgQ36ScgRi09MA2UC1t3tAB6nsfErsGO4= github.com/zsais/go-gin-prometheus v0.1.0/go.mod h1:Slirjzuz8uM8Cw0jmPNqbneoqcUtY2GGjn2bEd4NRLY= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ= +go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= +go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= @@ -966,10 +1083,13 @@ golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaE golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191205180655-e7c4368fe9dd/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= @@ -977,8 +1097,10 @@ golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWP golang.org/x/crypto v0.0.0-20201208171446-5f87f3452ae9/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= +golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 h1:7I4JAnoQBe7ZtJcBaYHi5UtiO8tQHbUSXxL+pnGRANg= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -1026,6 +1148,7 @@ golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -1113,6 +1236,7 @@ golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190221075227-b4e8571b14e0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1141,6 +1265,7 @@ golang.org/x/sys v0.0.0-20191113165036-4c7a9d0fe056/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1219,12 +1344,14 @@ golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7-0.20210524175448-3115f89c4b99/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20210611083556-38a9dc6acbc6/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190110163146-51295c7ec13a/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -1325,6 +1452,7 @@ golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1N golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.zx2c4.com/wireguard v0.0.0-20210624150102-15b24b6179e0/go.mod h1:laHzsbfMhGSobUmruXWAyMKKHSqvIcrqZJMyHD+/3O8= golang.zx2c4.com/wireguard/windows v0.3.16/go.mod h1:f80rkFY2CKQklps1GHE15k/M4Tq78aofbr1iQM5MTVY= +google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= @@ -1349,6 +1477,7 @@ google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBz google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= google.golang.org/api v0.44.0/go.mod h1:EBOGZqzyhtvMDoxwS97ctnh0zUmYY6CxqXsc1AvkYD8= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= @@ -1361,6 +1490,7 @@ google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRn google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= @@ -1406,11 +1536,15 @@ google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxH google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= google.golang.org/genproto v0.0.0-20211104193956-4c6863e31247 h1:ZONpjmFT5e+I/0/xE3XXbG5OIvX2hRYzol04MhKBl2E= google.golang.org/genproto v0.0.0-20211104193956-4c6863e31247/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= @@ -1460,8 +1594,10 @@ gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s= gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.62.0 h1:duBzk771uxoUuOlyRLkHsygud9+5lrlGjdFBb4mSKDU= @@ -1486,22 +1622,27 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gorm.io/datatypes v1.0.3 h1:cbFm8OiE50PZK1Zj9+bROQQpsFipE9bPFxxxkKgj3e4= -gorm.io/datatypes v1.0.3/go.mod h1:bi/3zc2D4dyUkiB+xhrirAv95+u4CXI+OE/YK43Jntg= -gorm.io/driver/mysql v1.1.3 h1:+5g1UElqN0sr2gZqmg9djlu1zT3cErHiscc6+IbLHgw= -gorm.io/driver/mysql v1.1.3/go.mod h1:4P/X9vSc3WTrhTLZ259cpFd6xKNYiSSdSZngkSBGIMM= -gorm.io/driver/postgres v1.2.1 h1:JDQKnF7MC51dgL09Vbydc5kl83KkVDlcXfSPJ+xhh68= -gorm.io/driver/postgres v1.2.1/go.mod h1:SHRZhu+D0tLOHV5qbxZRUM6kBcf3jp/kxPz2mYMTsNY= -gorm.io/driver/sqlite v1.2.3 h1:OwKm0xRAnsZMWAl5BtXJ9BsXAZHIt802DOTVMQuzWN8= -gorm.io/driver/sqlite v1.2.3/go.mod h1:wkiGvZF3le/8vjCRYg0bT8TSw6APZ5rtgKW8uQYE3sc= -gorm.io/driver/sqlserver v1.2.0 h1:5cPirBlvocwzzJ6SDqjkHraKfwnKn5I6Ss/WTMtI+io= -gorm.io/driver/sqlserver v1.2.0/go.mod h1:nixq0OB3iLXZDiPv6JSOjWuPgpyaRpOIIevYtA4Ulb4= +gorm.io/datatypes v1.0.2 h1:ChZ5VfWGB23qEr1kZosidvG9CF9HIczwoxLhBS7Ebs4= +gorm.io/datatypes v1.0.2/go.mod h1:1O1JVE4grFGcQTOGQbIBitiXUP6Sv84/KZU7eWeUv1k= +gorm.io/driver/mysql v1.1.2 h1:OofcyE2lga734MxwcCW9uB4mWNXMr50uaGRVwQL2B0M= +gorm.io/driver/mysql v1.1.2/go.mod h1:4P/X9vSc3WTrhTLZ259cpFd6xKNYiSSdSZngkSBGIMM= +gorm.io/driver/postgres v1.1.0/go.mod h1:hXQIwafeRjJvUm+OMxcFWyswJ/vevcpPLlGocwAwuqw= +gorm.io/driver/postgres v1.1.1 h1:tWLmqYCyaoh89fi7DhM6QggujrOnmfo3H98AzgNAAu0= +gorm.io/driver/postgres v1.1.1/go.mod h1:tpe2xN7aCst1NUdYyWQyxPtnHC+Zfp6NEux9PXD1OU0= +gorm.io/driver/sqlite v1.1.4/go.mod h1:mJCeTFr7+crvS+TRnWc5Z3UvwxUN1BGBLMrf5LA9DYw= +gorm.io/driver/sqlite v1.1.5 h1:JU8G59VyKu1x1RMQgjefQnkZjDe9wHc1kARDZPu5dZs= +gorm.io/driver/sqlite v1.1.5/go.mod h1:NpaYMcVKEh6vLJ47VP6T7Weieu4H1Drs3dGD/K6GrGc= +gorm.io/driver/sqlserver v1.0.9 h1:P7Dm/BKqsrOjyhRSnLXvG2g1W/eJUgxdrdBwgJw3tEg= +gorm.io/driver/sqlserver v1.0.9/go.mod h1:iBdxY2CepkTt9Q1r84RbZA1qCai300Qlp8kQf9qE9II= +gorm.io/gorm v1.20.7/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw= +gorm.io/gorm v1.21.9/go.mod h1:F+OptMscr0P2F2qU97WT1WimdH9GaQPoDW7AYd5i2Y0= gorm.io/gorm v1.21.12/go.mod h1:F+OptMscr0P2F2qU97WT1WimdH9GaQPoDW7AYd5i2Y0= -gorm.io/gorm v1.22.0/go.mod h1:F+OptMscr0P2F2qU97WT1WimdH9GaQPoDW7AYd5i2Y0= -gorm.io/gorm v1.22.2 h1:1iKcvyJnR5bHydBhDqTwasOkoo6+o4Ms5cknSt6qP7I= -gorm.io/gorm v1.22.2/go.mod h1:F+OptMscr0P2F2qU97WT1WimdH9GaQPoDW7AYd5i2Y0= +gorm.io/gorm v1.21.14/go.mod h1:F+OptMscr0P2F2qU97WT1WimdH9GaQPoDW7AYd5i2Y0= +gorm.io/gorm v1.21.15 h1:gAyaDoPw0lCyrSFWhBlahbUA1U4P5RViC1uIqoB+1Rk= +gorm.io/gorm v1.21.15/go.mod h1:F+OptMscr0P2F2qU97WT1WimdH9GaQPoDW7AYd5i2Y0= gotest.tools/v3 v3.0.2 h1:kG1BFyqVHuQoVQiR1bWGnfz/fmHvvuiSPIV7rvl360E= gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= +honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= @@ -1527,6 +1668,8 @@ mvdan.cc/unparam v0.0.0-20200501210554-b37ab49443f7/go.mod h1:HGC5lll35J70Y5v7vC rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= +sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= software.sslmate.com/src/go-pkcs12 v0.0.0-20180114231543-2291e8f0f237/go.mod h1:/xvNRWUqm0+/ZMiF4EX00vrSCMsE4/NHb+Pt3freEeQ= +sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= tailscale.com v1.14.6 h1:xhpDI3hks1lz80Tq7gxybdM0vt8NSuWEFpQeBqBZJhw= tailscale.com v1.14.6/go.mod h1:3F94TfP5nSn9M40v7jEQB+QI3m/4trasLDF3Dcljs8o= From 3720da6386759488f7a913b6cc5f75abd7c5b1f1 Mon Sep 17 00:00:00 2001 From: "Alessandro (Ale) Segala" <43508+ItalyPaleAle@users.noreply.github.com> Date: Sat, 6 Nov 2021 23:18:13 +0000 Subject: [PATCH 094/300] Using distroless base image for Docker --- Dockerfile | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/Dockerfile b/Dockerfile index 9590070b..05dde755 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,3 @@ -FROM bufbuild/buf:1.0.0-rc6 as buf - FROM golang:1.17.1-bullseye AS build ENV GOPATH /go WORKDIR /go/src/headscale @@ -12,15 +10,10 @@ COPY . . RUN go install -a -ldflags="-extldflags=-static" -tags netgo,sqlite_omit_load_extension ./cmd/headscale RUN test -e /go/bin/headscale -FROM ubuntu:20.04 +FROM gcr.io/distroless/base -RUN apt-get update \ - && apt-get install -y ca-certificates \ - && update-ca-certificates \ - && rm -rf /var/lib/apt/lists/* - -COPY --from=build /go/bin/headscale /usr/local/bin/headscale +COPY --from=build /go/bin/headscale /headscale ENV TZ UTC EXPOSE 8080/tcp -CMD ["headscale"] +CMD ["/headscale"] From a6d487de0099d1aaf8dbf05de69028c81c72a2ac Mon Sep 17 00:00:00 2001 From: "Alessandro (Ale) Segala" <43508+ItalyPaleAle@users.noreply.github.com> Date: Sat, 6 Nov 2021 23:19:56 +0000 Subject: [PATCH 095/300] Using debian11-based distroless image --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 05dde755..8a201420 100644 --- a/Dockerfile +++ b/Dockerfile @@ -10,7 +10,7 @@ COPY . . RUN go install -a -ldflags="-extldflags=-static" -tags netgo,sqlite_omit_load_extension ./cmd/headscale RUN test -e /go/bin/headscale -FROM gcr.io/distroless/base +FROM gcr.io/distroless/base-debian11 COPY --from=build /go/bin/headscale /headscale ENV TZ UTC From a249d3fe39152602dd4da97d6de1ded4c607084a Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Sun, 7 Nov 2021 08:58:03 +0000 Subject: [PATCH 096/300] Fix color for current namespace in nodes command --- cmd/headscale/cli/nodes.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/headscale/cli/nodes.go b/cmd/headscale/cli/nodes.go index 70fae835..b60e0a51 100644 --- a/cmd/headscale/cli/nodes.go +++ b/cmd/headscale/cli/nodes.go @@ -350,7 +350,7 @@ func nodesToPtables(currentNamespace string, machines []*v1.Machine) (pterm.Tabl } var namespace string - if currentNamespace == machine.Namespace.Name { + if currentNamespace == "" || (currentNamespace == machine.Namespace.Name) { namespace = pterm.LightMagenta(machine.Namespace.Name) } else { // Shared into this namespace From ce3f79a3bf7c80e4ed66eb5de43854c87a6b4621 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Sun, 7 Nov 2021 08:58:45 +0000 Subject: [PATCH 097/300] Add yaml to output help --- cmd/headscale/cli/root.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/headscale/cli/root.go b/cmd/headscale/cli/root.go index ef047f93..e5115f3d 100644 --- a/cmd/headscale/cli/root.go +++ b/cmd/headscale/cli/root.go @@ -9,7 +9,7 @@ import ( func init() { rootCmd.PersistentFlags(). - StringP("output", "o", "", "Output format. Empty for human-readable, 'json' or 'json-line'") + StringP("output", "o", "", "Output format. Empty for human-readable, 'json', 'json-line' or 'yaml'") rootCmd.PersistentFlags().Bool("force", false, "Disable prompts and forces the execution") } From 2dfd42f80c2829abb5366417669870b149d22f4d Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Sun, 7 Nov 2021 09:41:14 +0000 Subject: [PATCH 098/300] Attempt to dry up CLI client, add proepr config This commit is trying to DRY up the initiation of the gRPC client in each command: It renames the function to CLI instead of GRPC as it actually set up a CLI client, not a generic grpc client It also moves the configuration of address, timeout (which is now consistent) and api to use Viper, allowing users to set it via env vars and configuration file --- app.go | 9 ++++++ cmd/headscale/cli/debug.go | 6 +--- cmd/headscale/cli/namespaces.go | 18 +++--------- cmd/headscale/cli/nodes.go | 25 ++++------------- cmd/headscale/cli/preauthkeys.go | 13 ++------- cmd/headscale/cli/routes.go | 10 ++----- cmd/headscale/cli/utils.go | 48 +++++++++++++++++++------------- 7 files changed, 54 insertions(+), 75 deletions(-) diff --git a/app.go b/app.go index 97333b1f..c0f43981 100644 --- a/app.go +++ b/app.go @@ -86,6 +86,8 @@ type Config struct { OIDC OIDCConfig + CLI CLIConfig + MaxMachineRegistrationDuration time.Duration DefaultMachineRegistrationDuration time.Duration } @@ -104,6 +106,13 @@ type DERPConfig struct { UpdateFrequency time.Duration } +type CLIConfig struct { + Address string + APIKey string + Insecure bool + Timeout time.Duration +} + // Headscale represents the base app of the service. type Headscale struct { cfg Config diff --git a/cmd/headscale/cli/debug.go b/cmd/headscale/cli/debug.go index 8dfe0c41..0e5d59b0 100644 --- a/cmd/headscale/cli/debug.go +++ b/cmd/headscale/cli/debug.go @@ -1,9 +1,7 @@ package cli import ( - "context" "fmt" - "time" v1 "github.com/juanfont/headscale/gen/go/headscale/v1" "github.com/rs/zerolog/log" @@ -51,10 +49,8 @@ var createNodeCmd = &cobra.Command{ return } - ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + ctx, client, conn, cancel := getHeadscaleCLIClient() defer cancel() - - client, conn := getHeadscaleGRPCClient(ctx) defer conn.Close() name, err := cmd.Flags().GetString("name") diff --git a/cmd/headscale/cli/namespaces.go b/cmd/headscale/cli/namespaces.go index 427df624..77e0b476 100644 --- a/cmd/headscale/cli/namespaces.go +++ b/cmd/headscale/cli/namespaces.go @@ -1,9 +1,7 @@ package cli import ( - "context" "fmt" - "time" v1 "github.com/juanfont/headscale/gen/go/headscale/v1" "github.com/pterm/pterm" @@ -38,10 +36,8 @@ var createNamespaceCmd = &cobra.Command{ namespaceName := args[0] - ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + ctx, client, conn, cancel := getHeadscaleCLIClient() defer cancel() - - client, conn := getHeadscaleGRPCClient(ctx) defer conn.Close() log.Trace().Interface("client", client).Msg("Obtained gRPC client") @@ -73,10 +69,8 @@ var destroyNamespaceCmd = &cobra.Command{ namespaceName := args[0] - ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) + ctx, client, conn, cancel := getHeadscaleCLIClient() defer cancel() - - client, conn := getHeadscaleGRPCClient(ctx) defer conn.Close() request := &v1.DeleteNamespaceRequest{Name: namespaceName} @@ -97,10 +91,8 @@ var listNamespacesCmd = &cobra.Command{ Run: func(cmd *cobra.Command, args []string) { output, _ := cmd.Flags().GetString("output") - ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) + ctx, client, conn, cancel := getHeadscaleCLIClient() defer cancel() - - client, conn := getHeadscaleGRPCClient(ctx) defer conn.Close() request := &v1.ListNamespacesRequest{} @@ -147,10 +139,8 @@ var renameNamespaceCmd = &cobra.Command{ Run: func(cmd *cobra.Command, args []string) { output, _ := cmd.Flags().GetString("output") - ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) + ctx, client, conn, cancel := getHeadscaleCLIClient() defer cancel() - - client, conn := getHeadscaleGRPCClient(ctx) defer conn.Close() request := &v1.RenameNamespaceRequest{ diff --git a/cmd/headscale/cli/nodes.go b/cmd/headscale/cli/nodes.go index b60e0a51..4edeb855 100644 --- a/cmd/headscale/cli/nodes.go +++ b/cmd/headscale/cli/nodes.go @@ -1,7 +1,6 @@ package cli import ( - "context" "fmt" "log" "strconv" @@ -80,10 +79,8 @@ var registerNodeCmd = &cobra.Command{ return } - ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + ctx, client, conn, cancel := getHeadscaleCLIClient() defer cancel() - - client, conn := getHeadscaleGRPCClient(ctx) defer conn.Close() machineKey, err := cmd.Flags().GetString("key") @@ -118,10 +115,8 @@ var listNodesCmd = &cobra.Command{ return } - ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + ctx, client, conn, cancel := getHeadscaleCLIClient() defer cancel() - - client, conn := getHeadscaleGRPCClient(ctx) defer conn.Close() request := &v1.ListMachinesRequest{ @@ -165,10 +160,8 @@ var deleteNodeCmd = &cobra.Command{ return } - ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + ctx, client, conn, cancel := getHeadscaleCLIClient() defer cancel() - - client, conn := getHeadscaleGRPCClient(ctx) defer conn.Close() getRequest := &v1.GetMachineRequest{ @@ -225,10 +218,8 @@ func sharingWorker( return "", nil, nil, err } - ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + ctx, client, conn, cancel := getHeadscaleCLIClient() defer cancel() - - client, conn := getHeadscaleGRPCClient(ctx) defer conn.Close() id, err := cmd.Flags().GetInt("identifier") @@ -270,10 +261,8 @@ var shareMachineCmd = &cobra.Command{ return } - ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + ctx, client, conn, cancel := getHeadscaleCLIClient() defer cancel() - - client, conn := getHeadscaleGRPCClient(ctx) defer conn.Close() request := &v1.ShareMachineRequest{ @@ -301,10 +290,8 @@ var unshareMachineCmd = &cobra.Command{ return } - ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + ctx, client, conn, cancel := getHeadscaleCLIClient() defer cancel() - - client, conn := getHeadscaleGRPCClient(ctx) defer conn.Close() request := &v1.UnshareMachineRequest{ diff --git a/cmd/headscale/cli/preauthkeys.go b/cmd/headscale/cli/preauthkeys.go index e8252419..413dbdc5 100644 --- a/cmd/headscale/cli/preauthkeys.go +++ b/cmd/headscale/cli/preauthkeys.go @@ -1,7 +1,6 @@ package cli import ( - "context" "fmt" "log" "strconv" @@ -47,10 +46,8 @@ var listPreAuthKeys = &cobra.Command{ return } - ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) + ctx, client, conn, cancel := getHeadscaleCLIClient() defer cancel() - - client, conn := getHeadscaleGRPCClient(ctx) defer conn.Close() request := &v1.ListPreAuthKeysRequest{ @@ -126,10 +123,8 @@ var createPreAuthKeyCmd = &cobra.Command{ expiration = &exp } - ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) + ctx, client, conn, cancel := getHeadscaleCLIClient() defer cancel() - - client, conn := getHeadscaleGRPCClient(ctx) defer conn.Close() request := &v1.CreatePreAuthKeyRequest{ @@ -165,10 +160,8 @@ var expirePreAuthKeyCmd = &cobra.Command{ log.Fatalf("Error getting namespace: %s", err) } - ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) + ctx, client, conn, cancel := getHeadscaleCLIClient() defer cancel() - - client, conn := getHeadscaleGRPCClient(ctx) defer conn.Close() request := &v1.ExpirePreAuthKeyRequest{ diff --git a/cmd/headscale/cli/routes.go b/cmd/headscale/cli/routes.go index 4a935cf9..d200160b 100644 --- a/cmd/headscale/cli/routes.go +++ b/cmd/headscale/cli/routes.go @@ -1,11 +1,9 @@ package cli import ( - "context" "fmt" "log" "strconv" - "time" v1 "github.com/juanfont/headscale/gen/go/headscale/v1" "github.com/pterm/pterm" @@ -51,10 +49,8 @@ var listRoutesCmd = &cobra.Command{ return } - ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + ctx, client, conn, cancel := getHeadscaleCLIClient() defer cancel() - - client, conn := getHeadscaleGRPCClient(ctx) defer conn.Close() request := &v1.GetMachineRouteRequest{ @@ -108,10 +104,8 @@ omit the route you do not want to enable. return } - ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + ctx, client, conn, cancel := getHeadscaleCLIClient() defer cancel() - - client, conn := getHeadscaleGRPCClient(ctx) defer conn.Close() request := &v1.EnableMachineRoutesRequest{ diff --git a/cmd/headscale/cli/utils.go b/cmd/headscale/cli/utils.go index 90479bcd..30f1a789 100644 --- a/cmd/headscale/cli/utils.go +++ b/cmd/headscale/cli/utils.go @@ -9,7 +9,6 @@ import ( "os" "path/filepath" "regexp" - "strconv" "strings" "time" @@ -34,6 +33,9 @@ func LoadConfig(path string) error { // For testing viper.AddConfigPath(path) } + + viper.SetEnvPrefix("headscale") + viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_")) viper.AutomaticEnv() viper.SetDefault("tls_letsencrypt_cache_dir", "/var/www/.cache") @@ -47,6 +49,9 @@ func LoadConfig(path string) error { viper.SetDefault("unix_socket", "/var/run/headscale.sock") + viper.SetDefault("cli.insecure", false) + viper.SetDefault("cli.timeout", "5s") + err := viper.ReadInConfig() if err != nil { return fmt.Errorf("Fatal error reading config file: %s \n", err) @@ -270,6 +275,13 @@ func getHeadscaleConfig() headscale.Config { ClientSecret: viper.GetString("oidc.client_secret"), }, + CLI: headscale.CLIConfig{ + Address: viper.GetString("cli.address"), + APIKey: viper.GetString("cli.api_key"), + Insecure: viper.GetBool("cli.insecure"), + Timeout: viper.GetDuration("cli.timeout"), + }, + MaxMachineRegistrationDuration: maxMachineRegistrationDuration, DefaultMachineRegistrationDuration: defaultMachineRegistrationDuration, } @@ -313,21 +325,27 @@ func getHeadscaleApp() (*headscale.Headscale, error) { return h, nil } -func getHeadscaleGRPCClient(ctx context.Context) (v1.HeadscaleServiceClient, *grpc.ClientConn) { +func getHeadscaleCLIClient() (context.Context, v1.HeadscaleServiceClient, *grpc.ClientConn, context.CancelFunc) { + cfg := getHeadscaleConfig() + + log.Debug(). + Dur("timeout", cfg.CLI.Timeout). + Msgf("Setting timeout") + + ctx, cancel := context.WithTimeout(context.Background(), cfg.CLI.Timeout) + grpcOptions := []grpc.DialOption{ grpc.WithBlock(), } - address := os.Getenv("HEADSCALE_ADDRESS") + address := cfg.CLI.Address // If the address is not set, we assume that we are on the server hosting headscale. if address == "" { - cfg := getHeadscaleConfig() - log.Debug(). Str("socket", cfg.UnixSocket). - Msgf("HEADSCALE_ADDRESS environment is not set, connecting to unix socket.") + Msgf("HEADSCALE_CLI_ADDRESS environment is not set, connecting to unix socket.") address = cfg.UnixSocket @@ -338,9 +356,9 @@ func getHeadscaleGRPCClient(ctx context.Context) (v1.HeadscaleServiceClient, *gr ) } else { // If we are not connecting to a local server, require an API key for authentication - apiKey := os.Getenv("HEADSCALE_API_KEY") + apiKey := cfg.CLI.APIKey if apiKey == "" { - log.Fatal().Msgf("HEADSCALE_API_KEY environment variable needs to be set.") + log.Fatal().Msgf("HEADSCALE_CLI_API_KEY environment variable needs to be set.") } grpcOptions = append(grpcOptions, grpc.WithPerRPCCredentials(tokenAuth{ @@ -348,16 +366,8 @@ func getHeadscaleGRPCClient(ctx context.Context) (v1.HeadscaleServiceClient, *gr }), ) - insecureStr := os.Getenv("HEADSCALE_INSECURE") - if insecureStr != "" { - insecure, err := strconv.ParseBool(insecureStr) - if err != nil { - log.Fatal().Err(err).Msgf("Failed to parse HEADSCALE_INSECURE: %v", err) - } - - if insecure { - grpcOptions = append(grpcOptions, grpc.WithInsecure()) - } + if cfg.CLI.Insecure { + grpcOptions = append(grpcOptions, grpc.WithInsecure()) } } @@ -369,7 +379,7 @@ func getHeadscaleGRPCClient(ctx context.Context) (v1.HeadscaleServiceClient, *gr client := v1.NewHeadscaleServiceClient(conn) - return client, conn + return ctx, client, conn, cancel } func SuccessOutput(result interface{}, override string, outputFormat string) { From b15efb52014e14132c873f4ccb4a74cdef43d97d Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Sun, 7 Nov 2021 09:55:32 +0000 Subject: [PATCH 099/300] Ensure unix socket is removed before we startup --- app.go | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/app.go b/app.go index c0f43981..89d605cb 100644 --- a/app.go +++ b/app.go @@ -351,6 +351,16 @@ func (h *Headscale) httpAuthenticationMiddleware(c *gin.Context) { // c.Next() } +// ensureUnixSocketIsAbsent will check if the given path for headscales unix socket is clear +// and will remove it if it is not. +func (h *Headscale) ensureUnixSocketIsAbsent() error { + // File does not exist, all fine + if _, err := os.Stat(h.cfg.UnixSocket); errors.Is(err, os.ErrNotExist) { + return nil + } + return os.Remove(h.cfg.UnixSocket) +} + // Serve launches a GIN server with the Headscale API. func (h *Headscale) Serve() error { var err error @@ -360,6 +370,11 @@ func (h *Headscale) Serve() error { defer cancel() + err = h.ensureUnixSocketIsAbsent() + if err != nil { + panic(err) + } + socketListener, err := net.Listen("unix", h.cfg.UnixSocket) if err != nil { panic(err) From b11acad1c9fc08c8fa01a9685a115fbce4e894db Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Sun, 7 Nov 2021 09:57:39 +0000 Subject: [PATCH 100/300] Fix typo --- cmd/headscale/cli/nodes.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/headscale/cli/nodes.go b/cmd/headscale/cli/nodes.go index 4edeb855..7103f9e6 100644 --- a/cmd/headscale/cli/nodes.go +++ b/cmd/headscale/cli/nodes.go @@ -305,7 +305,7 @@ var unshareMachineCmd = &cobra.Command{ return } - SuccessOutput(response.Machine, "Node shared", output) + SuccessOutput(response.Machine, "Node unshared", output) }, } From d47b83f80bc2cbdb172519bf6bd8fc2dd479622f Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Sun, 7 Nov 2021 10:15:32 +0000 Subject: [PATCH 101/300] Unwrap grpc errors to make nicer user facing errors --- cmd/headscale/cli/debug.go | 3 ++- cmd/headscale/cli/namespaces.go | 9 +++++---- cmd/headscale/cli/nodes.go | 15 ++++++++------- cmd/headscale/cli/routes.go | 5 +++-- 4 files changed, 18 insertions(+), 14 deletions(-) diff --git a/cmd/headscale/cli/debug.go b/cmd/headscale/cli/debug.go index 0e5d59b0..e140156b 100644 --- a/cmd/headscale/cli/debug.go +++ b/cmd/headscale/cli/debug.go @@ -6,6 +6,7 @@ import ( v1 "github.com/juanfont/headscale/gen/go/headscale/v1" "github.com/rs/zerolog/log" "github.com/spf13/cobra" + "google.golang.org/grpc/status" ) func init() { @@ -80,7 +81,7 @@ var createNodeCmd = &cobra.Command{ response, err := client.DebugCreateMachine(ctx, request) if err != nil { - ErrorOutput(err, fmt.Sprintf("Cannot create machine: %s", err), output) + ErrorOutput(err, fmt.Sprintf("Cannot create machine: %s", status.Convert(err).Message()), output) return } diff --git a/cmd/headscale/cli/namespaces.go b/cmd/headscale/cli/namespaces.go index 77e0b476..752638a7 100644 --- a/cmd/headscale/cli/namespaces.go +++ b/cmd/headscale/cli/namespaces.go @@ -7,6 +7,7 @@ import ( "github.com/pterm/pterm" "github.com/rs/zerolog/log" "github.com/spf13/cobra" + "google.golang.org/grpc/status" ) func init() { @@ -47,7 +48,7 @@ var createNamespaceCmd = &cobra.Command{ log.Trace().Interface("request", request).Msg("Sending CreateNamespace request") response, err := client.CreateNamespace(ctx, request) if err != nil { - ErrorOutput(err, fmt.Sprintf("Cannot create namespace: %s", err), output) + ErrorOutput(err, fmt.Sprintf("Cannot create namespace: %s", status.Convert(err).Message()), output) return } @@ -77,7 +78,7 @@ var destroyNamespaceCmd = &cobra.Command{ response, err := client.DeleteNamespace(ctx, request) if err != nil { - ErrorOutput(err, fmt.Sprintf("Cannot destroy namespace: %s", err), output) + ErrorOutput(err, fmt.Sprintf("Cannot destroy namespace: %s", status.Convert(err).Message()), output) return } @@ -99,7 +100,7 @@ var listNamespacesCmd = &cobra.Command{ response, err := client.ListNamespaces(ctx, request) if err != nil { - ErrorOutput(err, fmt.Sprintf("Cannot get namespaces: %s", err), output) + ErrorOutput(err, fmt.Sprintf("Cannot get namespaces: %s", status.Convert(err).Message()), output) return } @@ -150,7 +151,7 @@ var renameNamespaceCmd = &cobra.Command{ response, err := client.RenameNamespace(ctx, request) if err != nil { - ErrorOutput(err, fmt.Sprintf("Cannot rename namespace: %s", err), output) + ErrorOutput(err, fmt.Sprintf("Cannot rename namespace: %s", status.Convert(err).Message()), output) return } diff --git a/cmd/headscale/cli/nodes.go b/cmd/headscale/cli/nodes.go index 7103f9e6..60d2c2f8 100644 --- a/cmd/headscale/cli/nodes.go +++ b/cmd/headscale/cli/nodes.go @@ -10,6 +10,7 @@ import ( v1 "github.com/juanfont/headscale/gen/go/headscale/v1" "github.com/pterm/pterm" "github.com/spf13/cobra" + "google.golang.org/grpc/status" "tailscale.com/tailcfg" "tailscale.com/types/wgkey" ) @@ -125,7 +126,7 @@ var listNodesCmd = &cobra.Command{ response, err := client.ListMachines(ctx, request) if err != nil { - ErrorOutput(err, fmt.Sprintf("Cannot get nodes: %s", err), output) + ErrorOutput(err, fmt.Sprintf("Cannot get nodes: %s", status.Convert(err).Message()), output) return } @@ -170,7 +171,7 @@ var deleteNodeCmd = &cobra.Command{ getResponse, err := client.GetMachine(ctx, getRequest) if err != nil { - ErrorOutput(err, fmt.Sprintf("Error getting node node: %s", err), output) + ErrorOutput(err, fmt.Sprintf("Error getting node node: %s", status.Convert(err).Message()), output) return } @@ -197,7 +198,7 @@ var deleteNodeCmd = &cobra.Command{ return } if err != nil { - ErrorOutput(err, fmt.Sprintf("Error deleting node: %s", err), output) + ErrorOutput(err, fmt.Sprintf("Error deleting node: %s", status.Convert(err).Message()), output) return } SuccessOutput(map[string]string{"Result": "Node deleted"}, "Node deleted", output) @@ -234,7 +235,7 @@ func sharingWorker( machineResponse, err := client.GetMachine(ctx, machineRequest) if err != nil { - ErrorOutput(err, fmt.Sprintf("Error getting node node: %s", err), output) + ErrorOutput(err, fmt.Sprintf("Error getting node node: %s", status.Convert(err).Message()), output) return "", nil, nil, err } @@ -244,7 +245,7 @@ func sharingWorker( namespaceResponse, err := client.GetNamespace(ctx, namespaceRequest) if err != nil { - ErrorOutput(err, fmt.Sprintf("Error getting node node: %s", err), output) + ErrorOutput(err, fmt.Sprintf("Error getting node node: %s", status.Convert(err).Message()), output) return "", nil, nil, err } @@ -272,7 +273,7 @@ var shareMachineCmd = &cobra.Command{ response, err := client.ShareMachine(ctx, request) if err != nil { - ErrorOutput(err, fmt.Sprintf("Error sharing node: %s", err), output) + ErrorOutput(err, fmt.Sprintf("Error sharing node: %s", status.Convert(err).Message()), output) return } @@ -301,7 +302,7 @@ var unshareMachineCmd = &cobra.Command{ response, err := client.UnshareMachine(ctx, request) if err != nil { - ErrorOutput(err, fmt.Sprintf("Error unsharing node: %s", err), output) + ErrorOutput(err, fmt.Sprintf("Error unsharing node: %s", status.Convert(err).Message()), output) return } diff --git a/cmd/headscale/cli/routes.go b/cmd/headscale/cli/routes.go index d200160b..9f2e4e24 100644 --- a/cmd/headscale/cli/routes.go +++ b/cmd/headscale/cli/routes.go @@ -8,6 +8,7 @@ import ( v1 "github.com/juanfont/headscale/gen/go/headscale/v1" "github.com/pterm/pterm" "github.com/spf13/cobra" + "google.golang.org/grpc/status" ) func init() { @@ -59,7 +60,7 @@ var listRoutesCmd = &cobra.Command{ response, err := client.GetMachineRoute(ctx, request) if err != nil { - ErrorOutput(err, fmt.Sprintf("Cannot get nodes: %s", err), output) + ErrorOutput(err, fmt.Sprintf("Cannot get nodes: %s", status.Convert(err).Message()), output) return } @@ -115,7 +116,7 @@ omit the route you do not want to enable. response, err := client.EnableMachineRoutes(ctx, request) if err != nil { - ErrorOutput(err, fmt.Sprintf("Cannot register machine: %s\n", err), output) + ErrorOutput(err, fmt.Sprintf("Cannot register machine: %s\n", status.Convert(err).Message()), output) return } From 9a26fa7989d80356a12fdf79d9b39136f15b937c Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Sun, 7 Nov 2021 10:40:05 +0000 Subject: [PATCH 102/300] Ensure logging is off for integration test commands --- integration_common_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integration_common_test.go b/integration_common_test.go index d52d7eb4..71d48669 100644 --- a/integration_common_test.go +++ b/integration_common_test.go @@ -32,7 +32,7 @@ func ExecuteCommand(resource *dockertest.Resource, cmd []string, env []string) ( exitCode, err := resource.Exec( cmd, dockertest.ExecOptions{ - Env: append(env, "LOG_LEVEL=error"), + Env: append(env, "HEADSCALE_LOG_LEVEL=disabled"), StdOut: &stdout, StdErr: &stderr, }, From 6076656373e0af6db3948008ea302368cf8eb5d0 Mon Sep 17 00:00:00 2001 From: "Alessandro (Ale) Segala" <43508+ItalyPaleAle@users.noreply.github.com> Date: Sun, 7 Nov 2021 18:57:37 +0000 Subject: [PATCH 103/300] Updated docs --- docs/Running.md | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/docs/Running.md b/docs/Running.md index b784aba9..4b67cd25 100644 --- a/docs/Running.md +++ b/docs/Running.md @@ -58,7 +58,7 @@ -v $(pwd)/config:/etc/headscale/ \ -p 127.0.0.1:8080:8080 \ headscale/headscale:x.x.x \ - headscale namespaces create myfirstnamespace + /headscale namespaces create myfirstnamespace ``` or if your server is already running in docker: @@ -79,7 +79,8 @@ docker run \ -v $(pwd)/config:/etc/headscale/ \ -p 127.0.0.1:8080:8080 \ - headscale/headscale:x.x.x headscale serve + headscale/headscale:x.x.x \ + /headscale serve ``` ## Nodes configuration @@ -90,7 +91,9 @@ If you used tailscale.com before in your nodes, make sure you clear the tailscal rm -fr /var/lib/tailscale systemctl start tailscaled ``` + ### Adding node based on MACHINEKEY + 1. Add your first machine ```shell @@ -108,11 +111,12 @@ If you used tailscale.com before in your nodes, make sure you clear the tailscal docker run \ -v $(pwd)/config:/etc/headscale/ \ headscale/headscale:x.x.x \ - headscale -n myfirstnamespace nodes register -k YOURMACHINEKEY + /headscale -n myfirstnamespace nodes register -k YOURMACHINEKEY ``` or if your server is already running in docker: ```shell - docker exec headscale -n myfirstnamespace nodes register -k YOURMACHINEKEY + docker exec \ + /headscale -n myfirstnamespace nodes register -k YOURMACHINEKEY ``` ### Alternative: adding node with AUTHKEY @@ -129,13 +133,14 @@ If you used tailscale.com before in your nodes, make sure you clear the tailscal docker run \ -v $(pwd)/config:/etc/headscale/ \ headscale/headscale:x.x.x \ - headscale -n myfirstnamespace preauthkeys create --reusable --expiration 24h + /headscale -n myfirstnamespace preauthkeys create --reusable --expiration 24h ``` or if your server is already running in docker: ```shell - docker exec headscale -n myfirstnamespace preauthkeys create --reusable --expiration 24h + docker exec \ + /headscale -n myfirstnamespace preauthkeys create --reusable --expiration 24h ``` 2. Use the authkey on your node to register it From 67953bfe2f54c4231e95d77987eb8f39e3f3fc46 Mon Sep 17 00:00:00 2001 From: "Alessandro (Ale) Segala" <43508+ItalyPaleAle@users.noreply.github.com> Date: Sun, 7 Nov 2021 19:09:51 +0000 Subject: [PATCH 104/300] Fixed integration tests --- integration_test.go | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/integration_test.go b/integration_test.go index 1f30bcab..49ce44ca 100644 --- a/integration_test.go +++ b/integration_test.go @@ -254,7 +254,7 @@ func (s *IntegrationTestSuite) SetupSuite() { fmt.Sprintf("%s/integration_test/etc:/etc/headscale", currentPath), }, Networks: []*dockertest.Network{&network}, - Cmd: []string{"headscale", "serve"}, + Cmd: []string{"/headscale", "serve"}, } fmt.Println("Creating headscale container") @@ -301,7 +301,7 @@ func (s *IntegrationTestSuite) SetupSuite() { fmt.Printf("Creating headscale namespace: %s\n", namespace) result, err := executeCommand( &headscale, - []string{"headscale", "namespaces", "create", namespace}, + []string{"/headscale", "namespaces", "create", namespace}, []string{}, ) fmt.Println("headscale create namespace result: ", result) @@ -311,7 +311,7 @@ func (s *IntegrationTestSuite) SetupSuite() { authKey, err := executeCommand( &headscale, []string{ - "headscale", + "/headscale", "--namespace", namespace, "preauthkeys", @@ -369,7 +369,7 @@ func (s *IntegrationTestSuite) TestListNodes() { fmt.Println("Listing nodes") result, err := executeCommand( &headscale, - []string{"headscale", "--namespace", namespace, "nodes", "list"}, + []string{"/headscale", "--namespace", namespace, "nodes", "list"}, []string{}, ) assert.Nil(s.T(), err) @@ -502,7 +502,7 @@ func (s *IntegrationTestSuite) TestSharedNodes() { result, err := executeCommand( &headscale, - []string{"headscale", "nodes", "list", "-o", "json", "--namespace", "shared"}, + []string{"/headscale", "nodes", "list", "-o", "json", "--namespace", "shared"}, []string{}, ) assert.Nil(s.T(), err) @@ -515,7 +515,7 @@ func (s *IntegrationTestSuite) TestSharedNodes() { result, err := executeCommand( &headscale, - []string{"headscale", "nodes", "share", "--identifier", fmt.Sprint(machine.ID), "--namespace", "main"}, + []string{"/headscale", "nodes", "share", "--identifier", fmt.Sprint(machine.ID), "--namespace", "main"}, []string{}, ) assert.Nil(s.T(), err) @@ -525,7 +525,7 @@ func (s *IntegrationTestSuite) TestSharedNodes() { result, err = executeCommand( &headscale, - []string{"headscale", "nodes", "list", "--namespace", "main"}, + []string{"/headscale", "nodes", "list", "--namespace", "main"}, []string{}, ) assert.Nil(s.T(), err) From dce6b8d72e8670b18d329b9c874de0c1ac308b39 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Mon, 8 Nov 2021 08:02:01 +0000 Subject: [PATCH 105/300] Add test case and fix nil pointer in preauthkeys command without expiration --- cmd/headscale/cli/preauthkeys.go | 48 ++++++++++++++-------------- grpcv1.go | 6 +++- integration_cli_test.go | 54 ++++++++++++++++++++++++++++++++ 3 files changed, 82 insertions(+), 26 deletions(-) diff --git a/cmd/headscale/cli/preauthkeys.go b/cmd/headscale/cli/preauthkeys.go index 413dbdc5..06f61974 100644 --- a/cmd/headscale/cli/preauthkeys.go +++ b/cmd/headscale/cli/preauthkeys.go @@ -2,13 +2,12 @@ package cli import ( "fmt" - "log" "strconv" "time" - "github.com/hako/durafmt" v1 "github.com/juanfont/headscale/gen/go/headscale/v1" "github.com/pterm/pterm" + "github.com/rs/zerolog/log" "github.com/spf13/cobra" "google.golang.org/protobuf/types/known/timestamppb" ) @@ -18,7 +17,7 @@ func init() { preauthkeysCmd.PersistentFlags().StringP("namespace", "n", "", "Namespace") err := preauthkeysCmd.MarkPersistentFlagRequired("namespace") if err != nil { - log.Fatalf(err.Error()) + log.Fatal().Err(err).Msg("") } preauthkeysCmd.AddCommand(listPreAuthKeys) preauthkeysCmd.AddCommand(createPreAuthKeyCmd) @@ -26,7 +25,7 @@ func init() { createPreAuthKeyCmd.PersistentFlags().Bool("reusable", false, "Make the preauthkey reusable") createPreAuthKeyCmd.PersistentFlags().Bool("ephemeral", false, "Preauthkey for ephemeral nodes") createPreAuthKeyCmd.Flags(). - StringP("expiration", "e", "", "Human-readable expiration of the key (30m, 24h, 365d...)") + DurationP("expiration", "e", 24*time.Hour, "Human-readable expiration of the key (30m, 24h, 365d...)") } var preauthkeysCmd = &cobra.Command{ @@ -92,7 +91,8 @@ var listPreAuthKeys = &cobra.Command{ } err = pterm.DefaultTable.WithHasHeader().WithData(d).Render() if err != nil { - log.Fatal(err) + ErrorOutput(err, fmt.Sprintf("Failed to render pterm table: %s", err), output) + return } }, } @@ -103,7 +103,7 @@ var createPreAuthKeyCmd = &cobra.Command{ Run: func(cmd *cobra.Command, args []string) { output, _ := cmd.Flags().GetString("output") - n, err := cmd.Flags().GetString("namespace") + namespace, err := cmd.Flags().GetString("namespace") if err != nil { ErrorOutput(err, fmt.Sprintf("Error getting namespace: %s", err), output) return @@ -112,28 +112,25 @@ var createPreAuthKeyCmd = &cobra.Command{ reusable, _ := cmd.Flags().GetBool("reusable") ephemeral, _ := cmd.Flags().GetBool("ephemeral") - e, _ := cmd.Flags().GetString("expiration") - var expiration *time.Time - if e != "" { - duration, err := durafmt.ParseStringShort(e) - if err != nil { - log.Fatalf("Error parsing expiration: %s", err) - } - exp := time.Now().UTC().Add(duration.Duration()) - expiration = &exp + request := &v1.CreatePreAuthKeyRequest{ + Namespace: namespace, + Resuable: reusable, + Ephemeral: ephemeral, + } + + if cmd.Flags().Changed("expiration") { + duration, _ := cmd.Flags().GetDuration("expiration") + expiration := time.Now().UTC().Add(duration) + + log.Trace().Dur("expiration", duration).Msg("expiration has been set") + + request.Expiration = timestamppb.New(expiration) } ctx, client, conn, cancel := getHeadscaleCLIClient() defer cancel() defer conn.Close() - request := &v1.CreatePreAuthKeyRequest{ - Namespace: n, - Resuable: reusable, - Ephemeral: ephemeral, - Expiration: timestamppb.New(*expiration), - } - response, err := client.CreatePreAuthKey(ctx, request) if err != nil { ErrorOutput(err, fmt.Sprintf("Cannot create Pre Auth Key: %s\n", err), output) @@ -155,9 +152,10 @@ var expirePreAuthKeyCmd = &cobra.Command{ }, Run: func(cmd *cobra.Command, args []string) { output, _ := cmd.Flags().GetString("output") - n, err := cmd.Flags().GetString("namespace") + namespace, err := cmd.Flags().GetString("namespace") if err != nil { - log.Fatalf("Error getting namespace: %s", err) + ErrorOutput(err, fmt.Sprintf("Error getting namespace: %s", err), output) + return } ctx, client, conn, cancel := getHeadscaleCLIClient() @@ -165,7 +163,7 @@ var expirePreAuthKeyCmd = &cobra.Command{ defer conn.Close() request := &v1.ExpirePreAuthKeyRequest{ - Namespace: n, + Namespace: namespace, Key: args[0], } diff --git a/grpcv1.go b/grpcv1.go index 0a28fbe6..dfb86425 100644 --- a/grpcv1.go +++ b/grpcv1.go @@ -99,7 +99,11 @@ func (api headscaleV1APIServer) CreatePreAuthKey( ctx context.Context, request *v1.CreatePreAuthKeyRequest, ) (*v1.CreatePreAuthKeyResponse, error) { - expiration := request.GetExpiration().AsTime() + var expiration time.Time + if request.GetExpiration() != nil { + expiration = request.GetExpiration().AsTime() + } + preAuthKey, err := api.h.CreatePreAuthKey( request.GetNamespace(), request.GetResuable(), diff --git a/integration_cli_test.go b/integration_cli_test.go index 4b408093..20b6ce34 100644 --- a/integration_cli_test.go +++ b/integration_cli_test.go @@ -298,6 +298,12 @@ func (s *IntegrationCLITestSuite) TestPreAuthKeyCommand() { assert.True(s.T(), listedPreAuthKeys[3].Expiration.AsTime().After(time.Now())) assert.True(s.T(), listedPreAuthKeys[4].Expiration.AsTime().After(time.Now())) + assert.True(s.T(), listedPreAuthKeys[0].Expiration.AsTime().Before(time.Now().Add(time.Hour*26))) + assert.True(s.T(), listedPreAuthKeys[1].Expiration.AsTime().Before(time.Now().Add(time.Hour*26))) + assert.True(s.T(), listedPreAuthKeys[2].Expiration.AsTime().Before(time.Now().Add(time.Hour*26))) + assert.True(s.T(), listedPreAuthKeys[3].Expiration.AsTime().Before(time.Now().Add(time.Hour*26))) + assert.True(s.T(), listedPreAuthKeys[4].Expiration.AsTime().Before(time.Now().Add(time.Hour*26))) + // Expire three keys for i := 0; i < 3; i++ { _, err := ExecuteCommand( @@ -342,6 +348,54 @@ func (s *IntegrationCLITestSuite) TestPreAuthKeyCommand() { assert.True(s.T(), listedAfterExpirePreAuthKeys[4].Expiration.AsTime().After(time.Now())) } +func (s *IntegrationCLITestSuite) TestPreAuthKeyCommandWithoutExpiry() { + namespace, err := s.createNamespace("pre-auth-key-without-exp-namespace") + assert.Nil(s.T(), err) + + preAuthResult, err := ExecuteCommand( + &s.headscale, + []string{ + "headscale", + "preauthkeys", + "--namespace", + namespace.Name, + "create", + "--reusable", + "--output", + "json", + }, + []string{}, + ) + assert.Nil(s.T(), err) + + var preAuthKey v1.PreAuthKey + err = json.Unmarshal([]byte(preAuthResult), &preAuthKey) + assert.Nil(s.T(), err) + + // Test list of keys + listResult, err := ExecuteCommand( + &s.headscale, + []string{ + "headscale", + "preauthkeys", + "--namespace", + namespace.Name, + "list", + "--output", + "json", + }, + []string{}, + ) + assert.Nil(s.T(), err) + + var listedPreAuthKeys []v1.PreAuthKey + err = json.Unmarshal([]byte(listResult), &listedPreAuthKeys) + assert.Nil(s.T(), err) + + assert.Len(s.T(), listedPreAuthKeys, 1) + assert.True(s.T(), time.Time{}.Equal(listedPreAuthKeys[0].Expiration.AsTime())) +} + func (s *IntegrationCLITestSuite) TestNodeCommand() { namespace, err := s.createNamespace("machine-namespace") assert.Nil(s.T(), err) From e1f45f9d077a8fff26ec5c3adcd20b4b9d20ebce Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Mon, 8 Nov 2021 18:27:57 +0000 Subject: [PATCH 106/300] Remove unused dep --- go.mod | 1 - 1 file changed, 1 deletion(-) diff --git a/go.mod b/go.mod index bd2d3b73..65a8582e 100644 --- a/go.mod +++ b/go.mod @@ -20,7 +20,6 @@ require ( github.com/google/go-querystring v1.1.0 // indirect github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 github.com/grpc-ecosystem/grpc-gateway/v2 v2.6.0 - github.com/hako/durafmt v0.0.0-20210608085754-5c1018a4e16b github.com/infobloxopen/protoc-gen-gorm v1.0.1 github.com/json-iterator/go v1.1.12 // indirect github.com/klauspost/compress v1.13.6 From b210858dc583fa9a3b09f2f3760c346474fc5493 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Mon, 8 Nov 2021 18:28:06 +0000 Subject: [PATCH 107/300] Remove unused dep --- go.sum | 2 -- 1 file changed, 2 deletions(-) diff --git a/go.sum b/go.sum index 5859516d..a34ef217 100644 --- a/go.sum +++ b/go.sum @@ -439,8 +439,6 @@ github.com/grpc-ecosystem/grpc-gateway/v2 v2.3.0/go.mod h1:d2gYTOTUQklu06xp0AJYY github.com/grpc-ecosystem/grpc-gateway/v2 v2.4.0/go.mod h1:IOyTYjcIO0rkmnGBfJTL0NJ11exy/Tc2QEuv7hCXp24= github.com/grpc-ecosystem/grpc-gateway/v2 v2.6.0 h1:rgxjzoDmDXw5q8HONgyHhBas4to0/XWRo/gPpJhsUNQ= github.com/grpc-ecosystem/grpc-gateway/v2 v2.6.0/go.mod h1:qrJPVzv9YlhsrxJc3P/Q85nr0w1lIRikTl4JlhdDH5w= -github.com/hako/durafmt v0.0.0-20210608085754-5c1018a4e16b h1:wDUNC2eKiL35DbLvsDhiblTUXHxcOPwQSCzi7xpQUN4= -github.com/hako/durafmt v0.0.0-20210608085754-5c1018a4e16b/go.mod h1:VzxiSdG6j1pi7rwGm/xYI5RbtpBgM8sARDXlvEvxlu0= github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE= github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= From 43af11c46a54aeb487a6a6b3d4bae34c91cdd51e Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Mon, 8 Nov 2021 20:47:40 +0000 Subject: [PATCH 108/300] Fix typo in generated code --- gen/go/headscale/v1/preauthkey.pb.go | 20 +++++++++---------- .../headscale/v1/headscale.swagger.json | 4 ++-- proto/headscale/v1/preauthkey.proto | 4 ++-- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/gen/go/headscale/v1/preauthkey.pb.go b/gen/go/headscale/v1/preauthkey.pb.go index a94befdf..82b16bf8 100644 --- a/gen/go/headscale/v1/preauthkey.pb.go +++ b/gen/go/headscale/v1/preauthkey.pb.go @@ -29,7 +29,7 @@ type PreAuthKey struct { Namespace string `protobuf:"bytes,1,opt,name=namespace,proto3" json:"namespace,omitempty"` Id string `protobuf:"bytes,2,opt,name=id,proto3" json:"id,omitempty"` Key string `protobuf:"bytes,3,opt,name=key,proto3" json:"key,omitempty"` - Resuable bool `protobuf:"varint,4,opt,name=resuable,proto3" json:"resuable,omitempty"` + Reusable bool `protobuf:"varint,4,opt,name=reusable,proto3" json:"reusable,omitempty"` Ephemeral bool `protobuf:"varint,5,opt,name=ephemeral,proto3" json:"ephemeral,omitempty"` Used bool `protobuf:"varint,6,opt,name=used,proto3" json:"used,omitempty"` Expiration *timestamppb.Timestamp `protobuf:"bytes,7,opt,name=expiration,proto3" json:"expiration,omitempty"` @@ -89,9 +89,9 @@ func (x *PreAuthKey) GetKey() string { return "" } -func (x *PreAuthKey) GetResuable() bool { +func (x *PreAuthKey) GetReusable() bool { if x != nil { - return x.Resuable + return x.Reusable } return false } @@ -130,7 +130,7 @@ type CreatePreAuthKeyRequest struct { unknownFields protoimpl.UnknownFields Namespace string `protobuf:"bytes,1,opt,name=namespace,proto3" json:"namespace,omitempty"` - Resuable bool `protobuf:"varint,2,opt,name=resuable,proto3" json:"resuable,omitempty"` + Reusable bool `protobuf:"varint,2,opt,name=reusable,proto3" json:"reusable,omitempty"` Ephemeral bool `protobuf:"varint,3,opt,name=ephemeral,proto3" json:"ephemeral,omitempty"` Expiration *timestamppb.Timestamp `protobuf:"bytes,4,opt,name=expiration,proto3" json:"expiration,omitempty"` } @@ -174,9 +174,9 @@ func (x *CreatePreAuthKeyRequest) GetNamespace() string { return "" } -func (x *CreatePreAuthKeyRequest) GetResuable() bool { +func (x *CreatePreAuthKeyRequest) GetReusable() bool { if x != nil { - return x.Resuable + return x.Reusable } return false } @@ -442,8 +442,8 @@ var file_headscale_v1_preauthkey_proto_rawDesc = []byte{ 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x1a, 0x0a, - 0x08, 0x72, 0x65, 0x73, 0x75, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x08, 0x72, 0x65, 0x73, 0x75, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x65, 0x70, 0x68, + 0x08, 0x72, 0x65, 0x75, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x08, 0x72, 0x65, 0x75, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x65, 0x70, 0x68, 0x65, 0x6d, 0x65, 0x72, 0x61, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x65, 0x70, 0x68, 0x65, 0x6d, 0x65, 0x72, 0x61, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x04, 0x75, 0x73, 0x65, 0x64, 0x12, 0x3a, 0x0a, 0x0a, 0x65, @@ -458,8 +458,8 @@ var file_headscale_v1_preauthkey_proto_rawDesc = []byte{ 0x41, 0x75, 0x74, 0x68, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x1a, 0x0a, 0x08, - 0x72, 0x65, 0x73, 0x75, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, - 0x72, 0x65, 0x73, 0x75, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x65, 0x70, 0x68, 0x65, + 0x72, 0x65, 0x75, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, + 0x72, 0x65, 0x75, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x65, 0x70, 0x68, 0x65, 0x6d, 0x65, 0x72, 0x61, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x65, 0x70, 0x68, 0x65, 0x6d, 0x65, 0x72, 0x61, 0x6c, 0x12, 0x3a, 0x0a, 0x0a, 0x65, 0x78, 0x70, 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, diff --git a/gen/openapiv2/headscale/v1/headscale.swagger.json b/gen/openapiv2/headscale/v1/headscale.swagger.json index b838635e..f1e95cad 100644 --- a/gen/openapiv2/headscale/v1/headscale.swagger.json +++ b/gen/openapiv2/headscale/v1/headscale.swagger.json @@ -587,7 +587,7 @@ "namespace": { "type": "string" }, - "resuable": { + "reusable": { "type": "boolean" }, "ephemeral": { @@ -799,7 +799,7 @@ "key": { "type": "string" }, - "resuable": { + "reusable": { "type": "boolean" }, "ephemeral": { diff --git a/proto/headscale/v1/preauthkey.proto b/proto/headscale/v1/preauthkey.proto index 195c3215..a945ba01 100644 --- a/proto/headscale/v1/preauthkey.proto +++ b/proto/headscale/v1/preauthkey.proto @@ -8,7 +8,7 @@ message PreAuthKey { string namespace = 1; string id = 2; string key = 3; - bool resuable = 4; + bool reusable = 4; bool ephemeral = 5; bool used = 6; google.protobuf.Timestamp expiration = 7; @@ -17,7 +17,7 @@ message PreAuthKey { message CreatePreAuthKeyRequest { string namespace = 1; - bool resuable = 2; + bool reusable = 2; bool ephemeral = 3; google.protobuf.Timestamp expiration = 4; } From 63711354599651ea33d29ff872ef5f12b8d46907 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Mon, 8 Nov 2021 20:48:20 +0000 Subject: [PATCH 109/300] Try to address issue raised by cure --- preauth_keys.go | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/preauth_keys.go b/preauth_keys.go index 304e345b..1cb9c112 100644 --- a/preauth_keys.go +++ b/preauth_keys.go @@ -139,14 +139,22 @@ func (h *Headscale) generateKey() (string, error) { } func (key *PreAuthKey) toProto() *v1.PreAuthKey { - return &v1.PreAuthKey{ - Namespace: key.Namespace.Name, - Id: strconv.FormatUint(key.ID, 10), - Key: key.Key, - Resuable: key.Reusable, - Ephemeral: key.Ephemeral, - Used: key.Used, - Expiration: timestamppb.New(*key.Expiration), - CreatedAt: timestamppb.New(*key.CreatedAt), + protoKey := v1.PreAuthKey{ + Namespace: key.Namespace.Name, + Id: strconv.FormatUint(key.ID, 10), + Key: key.Key, + Ephemeral: key.Ephemeral, + Reusable: key.Reusable, + Used: key.Used, } + + if key.Expiration != nil { + protoKey.Expiration = timestamppb.New(*key.Expiration) + } + + if key.CreatedAt != nil { + protoKey.CreatedAt = timestamppb.New(*key.CreatedAt) + } + + return &protoKey } From 0803c407a9fd25719644d993b927d7dff61edb8b Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Mon, 8 Nov 2021 20:49:03 +0000 Subject: [PATCH 110/300] Fix Reusable typo, add tests for Augustines scenario --- cmd/headscale/cli/nodes.go | 2 +- cmd/headscale/cli/preauthkeys.go | 10 +++- grpcv1.go | 3 +- integration_cli_test.go | 91 ++++++++++++++++++++++++++++++++ integration_test.go | 1 + 5 files changed, 103 insertions(+), 4 deletions(-) diff --git a/cmd/headscale/cli/nodes.go b/cmd/headscale/cli/nodes.go index 60d2c2f8..9b3f4243 100644 --- a/cmd/headscale/cli/nodes.go +++ b/cmd/headscale/cli/nodes.go @@ -97,7 +97,7 @@ var registerNodeCmd = &cobra.Command{ response, err := client.RegisterMachine(ctx, request) if err != nil { - ErrorOutput(err, fmt.Sprintf("Cannot register machine: %s\n", err), output) + ErrorOutput(err, fmt.Sprintf("Cannot register machine: %s\n", status.Convert(err).Message()), output) return } diff --git a/cmd/headscale/cli/preauthkeys.go b/cmd/headscale/cli/preauthkeys.go index 06f61974..a07e9610 100644 --- a/cmd/headscale/cli/preauthkeys.go +++ b/cmd/headscale/cli/preauthkeys.go @@ -75,7 +75,7 @@ var listPreAuthKeys = &cobra.Command{ if k.GetEphemeral() { reusable = "N/A" } else { - reusable = fmt.Sprintf("%v", k.GetResuable()) + reusable = fmt.Sprintf("%v", k.GetReusable()) } d = append(d, []string{ @@ -112,9 +112,15 @@ var createPreAuthKeyCmd = &cobra.Command{ reusable, _ := cmd.Flags().GetBool("reusable") ephemeral, _ := cmd.Flags().GetBool("ephemeral") + log.Trace(). + Bool("reusable", reusable). + Bool("ephemeral", ephemeral). + Str("namespace", namespace). + Msg("Preparing to create preauthkey") + request := &v1.CreatePreAuthKeyRequest{ Namespace: namespace, - Resuable: reusable, + Reusable: reusable, Ephemeral: ephemeral, } diff --git a/grpcv1.go b/grpcv1.go index dfb86425..998f0c0e 100644 --- a/grpcv1.go +++ b/grpcv1.go @@ -106,7 +106,7 @@ func (api headscaleV1APIServer) CreatePreAuthKey( preAuthKey, err := api.h.CreatePreAuthKey( request.GetNamespace(), - request.GetResuable(), + request.GetReusable(), request.GetEphemeral(), &expiration, ) @@ -155,6 +155,7 @@ func (api headscaleV1APIServer) RegisterMachine( ctx context.Context, request *v1.RegisterMachineRequest, ) (*v1.RegisterMachineResponse, error) { + log.Trace().Str("namespace", request.GetNamespace()).Str("machine_key", request.GetKey()).Msg("Registering machine") machine, err := api.h.RegisterMachine( request.GetKey(), request.GetNamespace(), diff --git a/integration_cli_test.go b/integration_cli_test.go index 20b6ce34..e1b16727 100644 --- a/integration_cli_test.go +++ b/integration_cli_test.go @@ -396,6 +396,97 @@ func (s *IntegrationCLITestSuite) TestPreAuthKeyCommandWithoutExpiry() { assert.True(s.T(), time.Time{}.Equal(listedPreAuthKeys[0].Expiration.AsTime())) } +func (s *IntegrationCLITestSuite) TestPreAuthKeyCommandReusableEphemeral() { + namespace, err := s.createNamespace("pre-auth-key-reus-ephm-namespace") + assert.Nil(s.T(), err) + + preAuthReusableResult, err := ExecuteCommand( + &s.headscale, + []string{ + "headscale", + "preauthkeys", + "--namespace", + namespace.Name, + "create", + "--reusable=true", + "--output", + "json", + }, + []string{}, + ) + assert.Nil(s.T(), err) + + var preAuthReusableKey v1.PreAuthKey + err = json.Unmarshal([]byte(preAuthReusableResult), &preAuthReusableKey) + assert.Nil(s.T(), err) + + assert.True(s.T(), preAuthReusableKey.GetReusable()) + assert.False(s.T(), preAuthReusableKey.GetEphemeral()) + + preAuthEphemeralResult, err := ExecuteCommand( + &s.headscale, + []string{ + "headscale", + "preauthkeys", + "--namespace", + namespace.Name, + "create", + "--ephemeral=true", + "--output", + "json", + }, + []string{}, + ) + assert.Nil(s.T(), err) + + var preAuthEphemeralKey v1.PreAuthKey + err = json.Unmarshal([]byte(preAuthEphemeralResult), &preAuthEphemeralKey) + assert.Nil(s.T(), err) + + assert.True(s.T(), preAuthEphemeralKey.GetEphemeral()) + assert.False(s.T(), preAuthEphemeralKey.GetReusable()) + + // TODO(kradalby): Evaluate if we need a case to test for reusable and ephemeral + // preAuthReusableAndEphemeralResult, err := ExecuteCommand( + // &s.headscale, + // []string{ + // "headscale", + // "preauthkeys", + // "--namespace", + // namespace.Name, + // "create", + // "--ephemeral", + // "--reusable", + // "--output", + // "json", + // }, + // []string{}, + // ) + // assert.NotNil(s.T(), err) + + // Test list of keys + listResult, err := ExecuteCommand( + &s.headscale, + []string{ + "headscale", + "preauthkeys", + "--namespace", + namespace.Name, + "list", + "--output", + "json", + }, + []string{}, + ) + assert.Nil(s.T(), err) + + var listedPreAuthKeys []v1.PreAuthKey + err = json.Unmarshal([]byte(listResult), &listedPreAuthKeys) + assert.Nil(s.T(), err) + + assert.Len(s.T(), listedPreAuthKeys, 2) +} + func (s *IntegrationCLITestSuite) TestNodeCommand() { namespace, err := s.createNamespace("machine-namespace") assert.Nil(s.T(), err) diff --git a/integration_test.go b/integration_test.go index 9c572583..c4f6bb41 100644 --- a/integration_test.go +++ b/integration_test.go @@ -269,6 +269,7 @@ func (s *IntegrationTestSuite) SetupSuite() { var preAuthKey v1.PreAuthKey err = json.Unmarshal([]byte(preAuthResult), &preAuthKey) assert.Nil(s.T(), err) + assert.True(s.T(), preAuthKey.Reusable) headscaleEndpoint := "http://headscale:8080" From 49893305b4736587cec9401ef30a4597a41b2438 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Mon, 8 Nov 2021 22:06:25 +0000 Subject: [PATCH 111/300] Only turn on response log in grpc in trace mode --- app.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/app.go b/app.go index 89d605cb..c2260627 100644 --- a/app.go +++ b/app.go @@ -26,6 +26,7 @@ import ( "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" v1 "github.com/juanfont/headscale/gen/go/headscale/v1" "github.com/philip-bui/grpc-zerolog" + zl "github.com/rs/zerolog" "github.com/rs/zerolog/log" "github.com/soheilhy/cmux" ginprometheus "github.com/zsais/go-gin-prometheus" @@ -480,6 +481,12 @@ func (h *Headscale) Serve() error { WriteTimeout: 0, } + if zl.GlobalLevel() == zl.TraceLevel { + zerolog.RespLog = true + } else { + zerolog.RespLog = false + } + grpcOptions := []grpc.ServerOption{ grpc.UnaryInterceptor( grpc_middleware.ChainUnaryServer( From 83e72ec57d18227a8ddb0d3a06c8e657bc352549 Mon Sep 17 00:00:00 2001 From: "Alessandro (Ale) Segala" <43508+ItalyPaleAle@users.noreply.github.com> Date: Tue, 9 Nov 2021 16:20:58 +0000 Subject: [PATCH 112/300] Allow running headscale without leading / --- Dockerfile | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 8a201420..58c3a38b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,3 +1,4 @@ +# Builder image FROM golang:1.17.1-bullseye AS build ENV GOPATH /go WORKDIR /go/src/headscale @@ -10,10 +11,12 @@ COPY . . RUN go install -a -ldflags="-extldflags=-static" -tags netgo,sqlite_omit_load_extension ./cmd/headscale RUN test -e /go/bin/headscale +# Production image FROM gcr.io/distroless/base-debian11 COPY --from=build /go/bin/headscale /headscale ENV TZ UTC +ENV PATH / EXPOSE 8080/tcp -CMD ["/headscale"] +CMD ["headscale"] From 3b34c7b89afb240047385dcfef8ace0bc700230a Mon Sep 17 00:00:00 2001 From: "Alessandro (Ale) Segala" <43508+ItalyPaleAle@users.noreply.github.com> Date: Tue, 9 Nov 2021 16:23:36 +0000 Subject: [PATCH 113/300] Removed / from docker commands in docs Essentially reverts 6076656373e0af6db3948008ea302368cf8eb5d0 --- docs/Running.md | 37 ++++++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/docs/Running.md b/docs/Running.md index 4b67cd25..014ef401 100644 --- a/docs/Running.md +++ b/docs/Running.md @@ -21,7 +21,8 @@ 3. Get yourself a DB - a) Get a Postgres DB running in docker + a) Get a Postgres DB running in Docker: + ```shell docker run --name headscale \ -e POSTGRES_DB=headscale @@ -30,7 +31,9 @@ -p 5432:5432 \ -d postgres ``` - or b) Prepare a SQLite DB file + + or b) Prepare a SQLite DB file: + ```shell touch config/db.sqlite ``` @@ -51,20 +54,21 @@ headscale namespaces create myfirstnamespace ``` - or docker: + or Docker: ```shell docker run \ -v $(pwd)/config:/etc/headscale/ \ -p 127.0.0.1:8080:8080 \ headscale/headscale:x.x.x \ - /headscale namespaces create myfirstnamespace + headscale namespaces create myfirstnamespace ``` - or if your server is already running in docker: + or if your server is already running in Docker: ```shell - docker exec headscale namespaces create myfirstnamespace + docker exec \ + headscale namespaces create myfirstnamespace ``` 6. Run the server @@ -73,15 +77,16 @@ headscale serve ``` - or docker: + or Docker: ```shell docker run \ -v $(pwd)/config:/etc/headscale/ \ -p 127.0.0.1:8080:8080 \ headscale/headscale:x.x.x \ - /headscale serve + headscale serve ``` + ## Nodes configuration If you used tailscale.com before in your nodes, make sure you clear the tailscaled data folder @@ -111,12 +116,13 @@ If you used tailscale.com before in your nodes, make sure you clear the tailscal docker run \ -v $(pwd)/config:/etc/headscale/ \ headscale/headscale:x.x.x \ - /headscale -n myfirstnamespace nodes register -k YOURMACHINEKEY + headscale -n myfirstnamespace nodes register -k YOURMACHINEKEY ``` - or if your server is already running in docker: + or if your server is already running in Docker: + ```shell docker exec \ - /headscale -n myfirstnamespace nodes register -k YOURMACHINEKEY + headscale -n myfirstnamespace nodes register -k YOURMACHINEKEY ``` ### Alternative: adding node with AUTHKEY @@ -133,17 +139,18 @@ If you used tailscale.com before in your nodes, make sure you clear the tailscal docker run \ -v $(pwd)/config:/etc/headscale/ \ headscale/headscale:x.x.x \ - /headscale -n myfirstnamespace preauthkeys create --reusable --expiration 24h + headscale -n myfirstnamespace preauthkeys create --reusable --expiration 24h ``` - or if your server is already running in docker: + or if your server is already running in Docker: ```shell docker exec \ - /headscale -n myfirstnamespace preauthkeys create --reusable --expiration 24h + headscale -n myfirstnamespace preauthkeys create --reusable --expiration 24h ``` -2. Use the authkey on your node to register it +2. Use the authkey on your node to register it: + ```shell tailscale up --login-server YOUR_HEADSCALE_URL --authkey YOURAUTHKEY ``` From c290ce4b91369c809ad6e244df9b500d87d8c18f Mon Sep 17 00:00:00 2001 From: "Alessandro (Ale) Segala" <43508+ItalyPaleAle@users.noreply.github.com> Date: Tue, 9 Nov 2021 16:24:10 +0000 Subject: [PATCH 114/300] Revert "Fixed integration tests" This reverts commit 67953bfe2f54c4231e95d77987eb8f39e3f3fc46. --- integration_test.go | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/integration_test.go b/integration_test.go index 49ce44ca..1f30bcab 100644 --- a/integration_test.go +++ b/integration_test.go @@ -254,7 +254,7 @@ func (s *IntegrationTestSuite) SetupSuite() { fmt.Sprintf("%s/integration_test/etc:/etc/headscale", currentPath), }, Networks: []*dockertest.Network{&network}, - Cmd: []string{"/headscale", "serve"}, + Cmd: []string{"headscale", "serve"}, } fmt.Println("Creating headscale container") @@ -301,7 +301,7 @@ func (s *IntegrationTestSuite) SetupSuite() { fmt.Printf("Creating headscale namespace: %s\n", namespace) result, err := executeCommand( &headscale, - []string{"/headscale", "namespaces", "create", namespace}, + []string{"headscale", "namespaces", "create", namespace}, []string{}, ) fmt.Println("headscale create namespace result: ", result) @@ -311,7 +311,7 @@ func (s *IntegrationTestSuite) SetupSuite() { authKey, err := executeCommand( &headscale, []string{ - "/headscale", + "headscale", "--namespace", namespace, "preauthkeys", @@ -369,7 +369,7 @@ func (s *IntegrationTestSuite) TestListNodes() { fmt.Println("Listing nodes") result, err := executeCommand( &headscale, - []string{"/headscale", "--namespace", namespace, "nodes", "list"}, + []string{"headscale", "--namespace", namespace, "nodes", "list"}, []string{}, ) assert.Nil(s.T(), err) @@ -502,7 +502,7 @@ func (s *IntegrationTestSuite) TestSharedNodes() { result, err := executeCommand( &headscale, - []string{"/headscale", "nodes", "list", "-o", "json", "--namespace", "shared"}, + []string{"headscale", "nodes", "list", "-o", "json", "--namespace", "shared"}, []string{}, ) assert.Nil(s.T(), err) @@ -515,7 +515,7 @@ func (s *IntegrationTestSuite) TestSharedNodes() { result, err := executeCommand( &headscale, - []string{"/headscale", "nodes", "share", "--identifier", fmt.Sprint(machine.ID), "--namespace", "main"}, + []string{"headscale", "nodes", "share", "--identifier", fmt.Sprint(machine.ID), "--namespace", "main"}, []string{}, ) assert.Nil(s.T(), err) @@ -525,7 +525,7 @@ func (s *IntegrationTestSuite) TestSharedNodes() { result, err = executeCommand( &headscale, - []string{"/headscale", "nodes", "list", "--namespace", "main"}, + []string{"headscale", "nodes", "list", "--namespace", "main"}, []string{}, ) assert.Nil(s.T(), err) From f44138c944c35edf3a6ab8f2b4249992ef9ef96c Mon Sep 17 00:00:00 2001 From: "Alessandro (Ale) Segala" <43508+ItalyPaleAle@users.noreply.github.com> Date: Fri, 12 Nov 2021 02:20:46 +0000 Subject: [PATCH 115/300] Added debug container --- Dockerfile.debug | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 Dockerfile.debug diff --git a/Dockerfile.debug b/Dockerfile.debug new file mode 100644 index 00000000..2d99faec --- /dev/null +++ b/Dockerfile.debug @@ -0,0 +1,24 @@ +# Builder image +FROM golang:1.17.1-bullseye AS build +ENV GOPATH /go +WORKDIR /go/src/headscale + +COPY go.mod go.sum /go/src/headscale/ +RUN go mod download + +COPY . . + +RUN go install -a -ldflags="-extldflags=-static" -tags netgo,sqlite_omit_load_extension ./cmd/headscale +RUN test -e /go/bin/headscale + +# Debug image +FROM gcr.io/distroless/base-debian11:debug + +COPY --from=build /go/bin/headscale /headscale +ENV TZ UTC +ENV PATH="/:$PATH" + +# Need to reset the entrypoint or everything will run as a busybox script +ENTRYPOINT [] +EXPOSE 8080/tcp +CMD ["headscale"] From 6b3114ad6fb893660f2575b37b73f1f053b40ee5 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Sat, 13 Nov 2021 08:11:55 +0000 Subject: [PATCH 116/300] Run prettier --- README.md | 6 +- derp-example.yaml | 18 ++-- docs/Running.md | 21 ++-- k8s/README.md | 3 +- k8s/base/ingress.yaml | 20 ++-- k8s/base/kustomization.yaml | 70 ++++++------ k8s/base/service.yaml | 6 +- k8s/postgres/deployment.yaml | 124 +++++++++++----------- k8s/postgres/kustomization.yaml | 14 +-- k8s/postgres/postgres-service.yaml | 6 +- k8s/postgres/postgres-statefulset.yaml | 62 +++++------ k8s/production-tls/ingress-patch.yaml | 6 +- k8s/production-tls/kustomization.yaml | 10 +- k8s/production-tls/production-issuer.yaml | 6 +- k8s/sqlite/kustomization.yaml | 4 +- k8s/sqlite/statefulset.yaml | 122 ++++++++++----------- k8s/staging-tls/ingress-patch.yaml | 6 +- k8s/staging-tls/kustomization.yaml | 10 +- k8s/staging-tls/staging-issuer.yaml | 6 +- 19 files changed, 263 insertions(+), 257 deletions(-) diff --git a/README.md b/README.md index e9f7990f..c99b54d7 100644 --- a/README.md +++ b/README.md @@ -54,7 +54,6 @@ Suggestions/PRs welcomed! Please have a look at the documentation under [`docs/`](docs/). - ## Disclaimer 1. We have nothing to do with Tailscale, or Tailscale Inc. @@ -70,7 +69,7 @@ To contribute to Headscale you would need the lastest version of [Go](https://go - Buf - Protobuf tools: -```shell +```shell make install-protobuf-plugins ``` @@ -81,6 +80,7 @@ Some parts of the project requires the generation of Go code from Protobuf (if c ```shell make generate ``` + **Note**: Please check in changes from `gen/` in a separate commit to make it easier to review. To run the tests: @@ -261,5 +261,3 @@ make build - - diff --git a/derp-example.yaml b/derp-example.yaml index bbf7cc8d..a9901bef 100644 --- a/derp-example.yaml +++ b/derp-example.yaml @@ -1,15 +1,15 @@ # If you plan to somehow use headscale, please deploy your own DERP infra: https://tailscale.com/kb/1118/custom-derp-servers/ -regions: +regions: 900: regionid: 900 regioncode: custom regionname: My Region nodes: - - name: 1a - regionid: 1 - hostname: myderp.mydomain.no - ipv4: 123.123.123.123 - ipv6: "2604:a880:400:d1::828:b001" - stunport: 0 - stunonly: false - derptestport: 0 + - name: 1a + regionid: 1 + hostname: myderp.mydomain.no + ipv4: 123.123.123.123 + ipv6: "2604:a880:400:d1::828:b001" + stunport: 0 + stunonly: false + derptestport: 0 diff --git a/docs/Running.md b/docs/Running.md index b784aba9..9969a614 100644 --- a/docs/Running.md +++ b/docs/Running.md @@ -1,6 +1,7 @@ # Running headscale ## Server configuration + 1. Download the headscale binary https://github.com/juanfont/headscale/releases, and place it somewhere in your $PATH or use the docker container ```shell @@ -18,10 +19,11 @@ ```shell mkdir config ``` - + 3. Get yourself a DB a) Get a Postgres DB running in docker + ```shell docker run --name headscale \ -e POSTGRES_DB=headscale @@ -30,7 +32,9 @@ -p 5432:5432 \ -d postgres ``` + or b) Prepare a SQLite DB file + ```shell touch config/db.sqlite ``` @@ -41,7 +45,7 @@ wg genkey > config/private.key cp config.yaml.[sqlite|postgres].example config/config.yaml - + cp derp-example.yaml config/derp.yaml ``` @@ -81,16 +85,19 @@ -p 127.0.0.1:8080:8080 \ headscale/headscale:x.x.x headscale serve ``` + ## Nodes configuration If you used tailscale.com before in your nodes, make sure you clear the tailscaled data folder - ```shell - systemctl stop tailscaled - rm -fr /var/lib/tailscale - systemctl start tailscaled - ``` +```shell +systemctl stop tailscaled +rm -fr /var/lib/tailscale +systemctl start tailscaled +``` + ### Adding node based on MACHINEKEY + 1. Add your first machine ```shell diff --git a/k8s/README.md b/k8s/README.md index 45574b48..78e9ef2c 100644 --- a/k8s/README.md +++ b/k8s/README.md @@ -24,6 +24,7 @@ Configure DERP servers by editing `base/site/derp.yaml` if needed. You'll somehow need to get `headscale:latest` into your cluster image registry. An easy way to do this with k3s: + - Reconfigure k3s to use docker instead of containerd (`k3s server --docker`) - `docker build -t headscale:latest ..` from here @@ -61,7 +62,7 @@ Use the wrapper script to remotely operate headscale to perform administrative tasks like creating namespaces, authkeys, etc. ``` -[c@nix-slate:~/Projects/headscale/k8s]$ ./headscale.bash +[c@nix-slate:~/Projects/headscale/k8s]$ ./headscale.bash headscale is an open source implementation of the Tailscale control server diff --git a/k8s/base/ingress.yaml b/k8s/base/ingress.yaml index a279bc1c..51da3427 100644 --- a/k8s/base/ingress.yaml +++ b/k8s/base/ingress.yaml @@ -6,13 +6,13 @@ metadata: kubernetes.io/ingress.class: traefik spec: rules: - - host: $(PUBLIC_HOSTNAME) - http: - paths: - - backend: - service: - name: headscale - port: - number: 8080 - path: / - pathType: Prefix + - host: $(PUBLIC_HOSTNAME) + http: + paths: + - backend: + service: + name: headscale + port: + number: 8080 + path: / + pathType: Prefix diff --git a/k8s/base/kustomization.yaml b/k8s/base/kustomization.yaml index 54d66e54..93278f7d 100644 --- a/k8s/base/kustomization.yaml +++ b/k8s/base/kustomization.yaml @@ -1,42 +1,42 @@ namespace: headscale resources: -- configmap.yaml -- ingress.yaml -- service.yaml + - configmap.yaml + - ingress.yaml + - service.yaml generatorOptions: disableNameSuffixHash: true configMapGenerator: -- name: headscale-site - files: - - derp.yaml=site/derp.yaml - envs: - - site/public.env -- name: headscale-etc - literals: - - config.json={} + - name: headscale-site + files: + - derp.yaml=site/derp.yaml + envs: + - site/public.env + - name: headscale-etc + literals: + - config.json={} secretGenerator: -- name: headscale - files: - - secrets/private-key + - name: headscale + files: + - secrets/private-key vars: -- name: PUBLIC_PROTO - objRef: - kind: ConfigMap - name: headscale-site - apiVersion: v1 - fieldRef: - fieldPath: data.public-proto -- name: PUBLIC_HOSTNAME - objRef: - kind: ConfigMap - name: headscale-site - apiVersion: v1 - fieldRef: - fieldPath: data.public-hostname -- name: CONTACT_EMAIL - objRef: - kind: ConfigMap - name: headscale-site - apiVersion: v1 - fieldRef: - fieldPath: data.contact-email + - name: PUBLIC_PROTO + objRef: + kind: ConfigMap + name: headscale-site + apiVersion: v1 + fieldRef: + fieldPath: data.public-proto + - name: PUBLIC_HOSTNAME + objRef: + kind: ConfigMap + name: headscale-site + apiVersion: v1 + fieldRef: + fieldPath: data.public-hostname + - name: CONTACT_EMAIL + objRef: + kind: ConfigMap + name: headscale-site + apiVersion: v1 + fieldRef: + fieldPath: data.contact-email diff --git a/k8s/base/service.yaml b/k8s/base/service.yaml index 7fdf738f..39e67253 100644 --- a/k8s/base/service.yaml +++ b/k8s/base/service.yaml @@ -8,6 +8,6 @@ spec: selector: app: headscale ports: - - name: http - targetPort: http - port: 8080 + - name: http + targetPort: http + port: 8080 diff --git a/k8s/postgres/deployment.yaml b/k8s/postgres/deployment.yaml index dd45d05b..661d87ed 100644 --- a/k8s/postgres/deployment.yaml +++ b/k8s/postgres/deployment.yaml @@ -13,66 +13,66 @@ spec: app: headscale spec: containers: - - name: headscale - image: "headscale:latest" - imagePullPolicy: IfNotPresent - command: ["/go/bin/headscale", "serve"] - env: - - name: SERVER_URL - value: $(PUBLIC_PROTO)://$(PUBLIC_HOSTNAME) - - name: LISTEN_ADDR - valueFrom: - configMapKeyRef: - name: headscale-config - key: listen_addr - - name: PRIVATE_KEY_PATH - value: /vol/secret/private-key - - name: DERP_MAP_PATH - value: /vol/config/derp.yaml - - name: EPHEMERAL_NODE_INACTIVITY_TIMEOUT - valueFrom: - configMapKeyRef: - name: headscale-config - key: ephemeral_node_inactivity_timeout - - name: DB_TYPE - value: postgres - - name: DB_HOST - value: postgres.headscale.svc.cluster.local - - name: DB_PORT - value: "5432" - - name: DB_USER - value: headscale - - name: DB_PASS - valueFrom: - secretKeyRef: - name: postgresql - key: password - - name: DB_NAME - value: headscale - ports: - - name: http - protocol: TCP - containerPort: 8080 - livenessProbe: - tcpSocket: - port: http - initialDelaySeconds: 30 - timeoutSeconds: 5 - periodSeconds: 15 - volumeMounts: - - name: config - mountPath: /vol/config - - name: secret - mountPath: /vol/secret - - name: etc - mountPath: /etc/headscale + - name: headscale + image: "headscale:latest" + imagePullPolicy: IfNotPresent + command: ["/go/bin/headscale", "serve"] + env: + - name: SERVER_URL + value: $(PUBLIC_PROTO)://$(PUBLIC_HOSTNAME) + - name: LISTEN_ADDR + valueFrom: + configMapKeyRef: + name: headscale-config + key: listen_addr + - name: PRIVATE_KEY_PATH + value: /vol/secret/private-key + - name: DERP_MAP_PATH + value: /vol/config/derp.yaml + - name: EPHEMERAL_NODE_INACTIVITY_TIMEOUT + valueFrom: + configMapKeyRef: + name: headscale-config + key: ephemeral_node_inactivity_timeout + - name: DB_TYPE + value: postgres + - name: DB_HOST + value: postgres.headscale.svc.cluster.local + - name: DB_PORT + value: "5432" + - name: DB_USER + value: headscale + - name: DB_PASS + valueFrom: + secretKeyRef: + name: postgresql + key: password + - name: DB_NAME + value: headscale + ports: + - name: http + protocol: TCP + containerPort: 8080 + livenessProbe: + tcpSocket: + port: http + initialDelaySeconds: 30 + timeoutSeconds: 5 + periodSeconds: 15 + volumeMounts: + - name: config + mountPath: /vol/config + - name: secret + mountPath: /vol/secret + - name: etc + mountPath: /etc/headscale volumes: - - name: config - configMap: - name: headscale-site - - name: etc - configMap: - name: headscale-etc - - name: secret - secret: - secretName: headscale + - name: config + configMap: + name: headscale-site + - name: etc + configMap: + name: headscale-etc + - name: secret + secret: + secretName: headscale diff --git a/k8s/postgres/kustomization.yaml b/k8s/postgres/kustomization.yaml index 8bd6c40c..e732e3b9 100644 --- a/k8s/postgres/kustomization.yaml +++ b/k8s/postgres/kustomization.yaml @@ -1,13 +1,13 @@ namespace: headscale bases: -- ../base + - ../base resources: -- deployment.yaml -- postgres-service.yaml -- postgres-statefulset.yaml + - deployment.yaml + - postgres-service.yaml + - postgres-statefulset.yaml generatorOptions: disableNameSuffixHash: true secretGenerator: -- name: postgresql - files: - - secrets/password + - name: postgresql + files: + - secrets/password diff --git a/k8s/postgres/postgres-service.yaml b/k8s/postgres/postgres-service.yaml index e2f486cc..6252e7f9 100644 --- a/k8s/postgres/postgres-service.yaml +++ b/k8s/postgres/postgres-service.yaml @@ -8,6 +8,6 @@ spec: selector: app: postgres ports: - - name: postgres - targetPort: postgres - port: 5432 + - name: postgres + targetPort: postgres + port: 5432 diff --git a/k8s/postgres/postgres-statefulset.yaml b/k8s/postgres/postgres-statefulset.yaml index 25285c5e..b81c9bf0 100644 --- a/k8s/postgres/postgres-statefulset.yaml +++ b/k8s/postgres/postgres-statefulset.yaml @@ -14,36 +14,36 @@ spec: app: postgres spec: containers: - - name: postgres - image: "postgres:13" - imagePullPolicy: IfNotPresent - env: - - name: POSTGRES_PASSWORD - valueFrom: - secretKeyRef: - name: postgresql - key: password - - name: POSTGRES_USER - value: headscale - ports: - name: postgres - protocol: TCP - containerPort: 5432 - livenessProbe: - tcpSocket: - port: 5432 - initialDelaySeconds: 30 - timeoutSeconds: 5 - periodSeconds: 15 - volumeMounts: - - name: pgdata - mountPath: /var/lib/postgresql/data + image: "postgres:13" + imagePullPolicy: IfNotPresent + env: + - name: POSTGRES_PASSWORD + valueFrom: + secretKeyRef: + name: postgresql + key: password + - name: POSTGRES_USER + value: headscale + ports: + - name: postgres + protocol: TCP + containerPort: 5432 + livenessProbe: + tcpSocket: + port: 5432 + initialDelaySeconds: 30 + timeoutSeconds: 5 + periodSeconds: 15 + volumeMounts: + - name: pgdata + mountPath: /var/lib/postgresql/data volumeClaimTemplates: - - metadata: - name: pgdata - spec: - storageClassName: local-path - accessModes: ["ReadWriteOnce"] - resources: - requests: - storage: 1Gi + - metadata: + name: pgdata + spec: + storageClassName: local-path + accessModes: ["ReadWriteOnce"] + resources: + requests: + storage: 1Gi diff --git a/k8s/production-tls/ingress-patch.yaml b/k8s/production-tls/ingress-patch.yaml index 387c7364..9e6177fb 100644 --- a/k8s/production-tls/ingress-patch.yaml +++ b/k8s/production-tls/ingress-patch.yaml @@ -6,6 +6,6 @@ metadata: traefik.ingress.kubernetes.io/router.tls: "true" spec: tls: - - hosts: - - $(PUBLIC_HOSTNAME) - secretName: production-cert + - hosts: + - $(PUBLIC_HOSTNAME) + secretName: production-cert diff --git a/k8s/production-tls/kustomization.yaml b/k8s/production-tls/kustomization.yaml index f57cb540..d3147f5f 100644 --- a/k8s/production-tls/kustomization.yaml +++ b/k8s/production-tls/kustomization.yaml @@ -1,9 +1,9 @@ namespace: headscale bases: -- ../base + - ../base resources: -- production-issuer.yaml + - production-issuer.yaml patches: -- path: ingress-patch.yaml - target: - kind: Ingress + - path: ingress-patch.yaml + target: + kind: Ingress diff --git a/k8s/production-tls/production-issuer.yaml b/k8s/production-tls/production-issuer.yaml index 7ae9131a..f436090b 100644 --- a/k8s/production-tls/production-issuer.yaml +++ b/k8s/production-tls/production-issuer.yaml @@ -11,6 +11,6 @@ spec: # Secret resource used to store the account's private key. name: letsencrypt-production-acc-key solvers: - - http01: - ingress: - class: traefik + - http01: + ingress: + class: traefik diff --git a/k8s/sqlite/kustomization.yaml b/k8s/sqlite/kustomization.yaml index 5be451ca..ca799419 100644 --- a/k8s/sqlite/kustomization.yaml +++ b/k8s/sqlite/kustomization.yaml @@ -1,5 +1,5 @@ namespace: headscale bases: -- ../base + - ../base resources: -- statefulset.yaml + - statefulset.yaml diff --git a/k8s/sqlite/statefulset.yaml b/k8s/sqlite/statefulset.yaml index 9075e007..71077dad 100644 --- a/k8s/sqlite/statefulset.yaml +++ b/k8s/sqlite/statefulset.yaml @@ -14,66 +14,66 @@ spec: app: headscale spec: containers: - - name: headscale - image: "headscale:latest" - imagePullPolicy: IfNotPresent - command: ["/go/bin/headscale", "serve"] - env: - - name: SERVER_URL - value: $(PUBLIC_PROTO)://$(PUBLIC_HOSTNAME) - - name: LISTEN_ADDR - valueFrom: - configMapKeyRef: - name: headscale-config - key: listen_addr - - name: PRIVATE_KEY_PATH - value: /vol/secret/private-key - - name: DERP_MAP_PATH - value: /vol/config/derp.yaml - - name: EPHEMERAL_NODE_INACTIVITY_TIMEOUT - valueFrom: - configMapKeyRef: - name: headscale-config - key: ephemeral_node_inactivity_timeout - - name: DB_TYPE - value: sqlite3 - - name: DB_PATH - value: /vol/data/db.sqlite - ports: - - name: http - protocol: TCP - containerPort: 8080 - livenessProbe: - tcpSocket: - port: http - initialDelaySeconds: 30 - timeoutSeconds: 5 - periodSeconds: 15 - volumeMounts: - - name: config - mountPath: /vol/config - - name: data - mountPath: /vol/data - - name: secret - mountPath: /vol/secret - - name: etc - mountPath: /etc/headscale + - name: headscale + image: "headscale:latest" + imagePullPolicy: IfNotPresent + command: ["/go/bin/headscale", "serve"] + env: + - name: SERVER_URL + value: $(PUBLIC_PROTO)://$(PUBLIC_HOSTNAME) + - name: LISTEN_ADDR + valueFrom: + configMapKeyRef: + name: headscale-config + key: listen_addr + - name: PRIVATE_KEY_PATH + value: /vol/secret/private-key + - name: DERP_MAP_PATH + value: /vol/config/derp.yaml + - name: EPHEMERAL_NODE_INACTIVITY_TIMEOUT + valueFrom: + configMapKeyRef: + name: headscale-config + key: ephemeral_node_inactivity_timeout + - name: DB_TYPE + value: sqlite3 + - name: DB_PATH + value: /vol/data/db.sqlite + ports: + - name: http + protocol: TCP + containerPort: 8080 + livenessProbe: + tcpSocket: + port: http + initialDelaySeconds: 30 + timeoutSeconds: 5 + periodSeconds: 15 + volumeMounts: + - name: config + mountPath: /vol/config + - name: data + mountPath: /vol/data + - name: secret + mountPath: /vol/secret + - name: etc + mountPath: /etc/headscale volumes: - - name: config - configMap: - name: headscale-site - - name: etc - configMap: - name: headscale-etc - - name: secret - secret: - secretName: headscale + - name: config + configMap: + name: headscale-site + - name: etc + configMap: + name: headscale-etc + - name: secret + secret: + secretName: headscale volumeClaimTemplates: - - metadata: - name: data - spec: - storageClassName: local-path - accessModes: ["ReadWriteOnce"] - resources: - requests: - storage: 1Gi + - metadata: + name: data + spec: + storageClassName: local-path + accessModes: ["ReadWriteOnce"] + resources: + requests: + storage: 1Gi diff --git a/k8s/staging-tls/ingress-patch.yaml b/k8s/staging-tls/ingress-patch.yaml index f97974bd..5a1daf0c 100644 --- a/k8s/staging-tls/ingress-patch.yaml +++ b/k8s/staging-tls/ingress-patch.yaml @@ -6,6 +6,6 @@ metadata: traefik.ingress.kubernetes.io/router.tls: "true" spec: tls: - - hosts: - - $(PUBLIC_HOSTNAME) - secretName: staging-cert + - hosts: + - $(PUBLIC_HOSTNAME) + secretName: staging-cert diff --git a/k8s/staging-tls/kustomization.yaml b/k8s/staging-tls/kustomization.yaml index 931f27d5..0900c583 100644 --- a/k8s/staging-tls/kustomization.yaml +++ b/k8s/staging-tls/kustomization.yaml @@ -1,9 +1,9 @@ namespace: headscale bases: -- ../base + - ../base resources: -- staging-issuer.yaml + - staging-issuer.yaml patches: -- path: ingress-patch.yaml - target: - kind: Ingress + - path: ingress-patch.yaml + target: + kind: Ingress diff --git a/k8s/staging-tls/staging-issuer.yaml b/k8s/staging-tls/staging-issuer.yaml index 95325f6e..cf290415 100644 --- a/k8s/staging-tls/staging-issuer.yaml +++ b/k8s/staging-tls/staging-issuer.yaml @@ -11,6 +11,6 @@ spec: # Secret resource used to store the account's private key. name: letsencrypt-staging-acc-key solvers: - - http01: - ingress: - class: traefik + - http01: + ingress: + class: traefik From edfcdc466c554a4a578b52f11a1dc5ef7a2d38f0 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Sat, 13 Nov 2021 08:13:38 +0000 Subject: [PATCH 117/300] Update lint ci file with prettier and proto --- .github/workflows/lint.yml | 38 +++++++++++++++++++++++++++----------- 1 file changed, 27 insertions(+), 11 deletions(-) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 6b561d24..75de620e 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -1,20 +1,36 @@ +--- name: CI on: [push, pull_request] jobs: - # The "build" workflow - lint: - # The type of runner that the job will run on + golangci-lint: runs-on: ubuntu-latest - - # Steps represent a sequence of tasks that will be executed as part of the job steps: - # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - uses: actions/checkout@v2 - # Install and run golangci-lint as a separate step, it's much faster this - # way because this action has caching. It'll get run again in `make lint` - # below, but it's still much faster in the end than installing - # golangci-lint manually in the `Run lint` step. - - uses: golangci/golangci-lint-action@v2 + - name: golangci-lint + uses: golangci/golangci-lint-action@v2 + with: + version: latest + args: --timeout 30m + + prettier-lint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + + - name: Prettify code + uses: creyD/prettier_action@v4.0 + with: + prettier_options: >- + --check **/*.{ts,js,md,yaml,yml,sass,css,scss,html} + only_changed: false + dry: true + + proto-lint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: bufbuild/buf-setup-action@v0.5.0 + - uses: bufbuild/buf-lint-action@v1 From 03b7ec62cae3935705dc3b8811a122e6ad6b6a68 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Sat, 13 Nov 2021 08:36:45 +0000 Subject: [PATCH 118/300] Go format with shorter lines --- acls.go | 4 +- acls_test.go | 6 +- api.go | 55 ++++++++++---- app.go | 75 ++++++++++++++----- app_test.go | 6 +- apple_mobileconfig.go | 54 +++++++++++--- cli_test.go | 5 +- cmd/headscale/cli/debug.go | 27 +++++-- cmd/headscale/cli/namespaces.go | 39 ++++++++-- cmd/headscale/cli/nodes.go | 120 ++++++++++++++++++++++++++----- cmd/headscale/cli/preauthkeys.go | 34 +++++++-- cmd/headscale/cli/root.go | 3 +- cmd/headscale/cli/routes.go | 48 ++++++++++--- cmd/headscale/cli/utils.go | 34 ++++++--- cmd/headscale/headscale.go | 3 +- cmd/headscale/headscale_test.go | 16 ++++- db.go | 5 +- dns.go | 17 ++++- grpcv1.go | 15 +++- integration_cli_test.go | 81 ++++++++++++++++----- integration_common_test.go | 6 +- integration_test.go | 110 +++++++++++++++++++++++----- machine.go | 34 +++++++-- metrics.go | 2 +- namespaces.go | 19 +++-- oidc.go | 38 +++++++--- oidc_test.go | 12 +++- poll.go | 37 +++++++--- preauth_keys.go | 5 +- routes.go | 22 ++++-- routes_test.go | 5 +- sharing.go | 12 ++-- sharing_test.go | 11 ++- swagger.go | 6 +- utils.go | 20 +++++- 35 files changed, 794 insertions(+), 192 deletions(-) diff --git a/acls.go b/acls.go index cb02e044..0e01514e 100644 --- a/acls.go +++ b/acls.go @@ -108,7 +108,9 @@ func (h *Headscale) generateACLPolicySrcIP(u string) ([]string, error) { return h.expandAlias(u) } -func (h *Headscale) generateACLPolicyDestPorts(d string) ([]tailcfg.NetPortRange, error) { +func (h *Headscale) generateACLPolicyDestPorts( + d string, +) ([]tailcfg.NetPortRange, error) { tokens := strings.Split(d, ":") if len(tokens) < 2 || len(tokens) > 3 { return nil, errorInvalidPortFormat diff --git a/acls_test.go b/acls_test.go index da7f3ecc..c178805e 100644 --- a/acls_test.go +++ b/acls_test.go @@ -22,7 +22,11 @@ func (s *Suite) TestInvalidPolicyHuson(c *check.C) { func (s *Suite) TestParseHosts(c *check.C) { var hs Hosts - err := hs.UnmarshalJSON([]byte(`{"example-host-1": "100.100.100.100","example-host-2": "100.100.101.100/24"}`)) + err := hs.UnmarshalJSON( + []byte( + `{"example-host-1": "100.100.100.100","example-host-2": "100.100.101.100/24"}`, + ), + ) c.Assert(hs, check.NotNil) c.Assert(err, check.IsNil) } diff --git a/api.go b/api.go index 490ce258..25851d84 100644 --- a/api.go +++ b/api.go @@ -95,7 +95,8 @@ func (h *Headscale) RegistrationHandler(c *gin.Context) { Str("handler", "Registration"). Err(err). Msg("Could not create row") - machineRegistrations.WithLabelValues("unknown", "web", "error", m.Namespace.Name).Inc() + machineRegistrations.WithLabelValues("unknown", "web", "error", m.Namespace.Name). + Inc() return } m = &newMachine @@ -156,11 +157,13 @@ func (h *Headscale) RegistrationHandler(c *gin.Context) { Str("handler", "Registration"). Err(err). Msg("Cannot encode message") - machineRegistrations.WithLabelValues("update", "web", "error", m.Namespace.Name).Inc() + machineRegistrations.WithLabelValues("update", "web", "error", m.Namespace.Name). + Inc() c.String(http.StatusInternalServerError, "") return } - machineRegistrations.WithLabelValues("update", "web", "success", m.Namespace.Name).Inc() + machineRegistrations.WithLabelValues("update", "web", "success", m.Namespace.Name). + Inc() c.Data(200, "application/json; charset=utf-8", respBody) return } @@ -195,11 +198,13 @@ func (h *Headscale) RegistrationHandler(c *gin.Context) { Str("handler", "Registration"). Err(err). Msg("Cannot encode message") - machineRegistrations.WithLabelValues("new", "web", "error", m.Namespace.Name).Inc() + machineRegistrations.WithLabelValues("new", "web", "error", m.Namespace.Name). + Inc() c.String(http.StatusInternalServerError, "") return } - machineRegistrations.WithLabelValues("new", "web", "success", m.Namespace.Name).Inc() + machineRegistrations.WithLabelValues("new", "web", "success", m.Namespace.Name). + Inc() c.Data(200, "application/json; charset=utf-8", respBody) return } @@ -234,7 +239,11 @@ func (h *Headscale) RegistrationHandler(c *gin.Context) { Str("machine", m.Name). Msg("The node is sending us a new NodeKey, sending auth url") if h.cfg.OIDC.Issuer != "" { - resp.AuthURL = fmt.Sprintf("%s/oidc/register/%s", strings.TrimSuffix(h.cfg.ServerURL, "/"), mKey.HexString()) + resp.AuthURL = fmt.Sprintf( + "%s/oidc/register/%s", + strings.TrimSuffix(h.cfg.ServerURL, "/"), + mKey.HexString(), + ) } else { resp.AuthURL = fmt.Sprintf("%s/register?key=%s", strings.TrimSuffix(h.cfg.ServerURL, "/"), mKey.HexString()) @@ -257,7 +266,11 @@ func (h *Headscale) RegistrationHandler(c *gin.Context) { c.Data(200, "application/json; charset=utf-8", respBody) } -func (h *Headscale) getMapResponse(mKey wgkey.Key, req tailcfg.MapRequest, m *Machine) ([]byte, error) { +func (h *Headscale) getMapResponse( + mKey wgkey.Key, + req tailcfg.MapRequest, + m *Machine, +) ([]byte, error) { log.Trace(). Str("func", "getMapResponse"). Str("machine", req.Hostinfo.Hostname). @@ -291,7 +304,12 @@ func (h *Headscale) getMapResponse(mKey wgkey.Key, req tailcfg.MapRequest, m *Ma return nil, err } - dnsConfig, err := getMapResponseDNSConfig(h.cfg.DNSConfig, h.cfg.BaseDomain, *m, peers) + dnsConfig, err := getMapResponseDNSConfig( + h.cfg.DNSConfig, + h.cfg.BaseDomain, + *m, + peers, + ) if err != nil { log.Error(). Str("func", "getMapResponse"). @@ -340,7 +358,11 @@ func (h *Headscale) getMapResponse(mKey wgkey.Key, req tailcfg.MapRequest, m *Ma return data, nil } -func (h *Headscale) getMapKeepAliveResponse(mKey wgkey.Key, req tailcfg.MapRequest, m *Machine) ([]byte, error) { +func (h *Headscale) getMapKeepAliveResponse( + mKey wgkey.Key, + req tailcfg.MapRequest, + m *Machine, +) ([]byte, error) { resp := tailcfg.MapResponse{ KeepAlive: true, } @@ -394,7 +416,8 @@ func (h *Headscale) handleAuthKey( Err(err). Msg("Cannot encode message") c.String(http.StatusInternalServerError, "") - machineRegistrations.WithLabelValues("new", "authkey", "error", m.Namespace.Name).Inc() + machineRegistrations.WithLabelValues("new", "authkey", "error", m.Namespace.Name). + Inc() return } c.Data(401, "application/json; charset=utf-8", respBody) @@ -402,7 +425,8 @@ func (h *Headscale) handleAuthKey( Str("func", "handleAuthKey"). Str("machine", m.Name). Msg("Failed authentication via AuthKey") - machineRegistrations.WithLabelValues("new", "authkey", "error", m.Namespace.Name).Inc() + machineRegistrations.WithLabelValues("new", "authkey", "error", m.Namespace.Name). + Inc() return } @@ -416,7 +440,8 @@ func (h *Headscale) handleAuthKey( Str("func", "handleAuthKey"). Str("machine", m.Name). Msg("Failed to find an available IP") - machineRegistrations.WithLabelValues("new", "authkey", "error", m.Namespace.Name).Inc() + machineRegistrations.WithLabelValues("new", "authkey", "error", m.Namespace.Name). + Inc() return } log.Info(). @@ -445,11 +470,13 @@ func (h *Headscale) handleAuthKey( Str("machine", m.Name). Err(err). Msg("Cannot encode message") - machineRegistrations.WithLabelValues("new", "authkey", "error", m.Namespace.Name).Inc() + machineRegistrations.WithLabelValues("new", "authkey", "error", m.Namespace.Name). + Inc() c.String(http.StatusInternalServerError, "Extremely sad!") return } - machineRegistrations.WithLabelValues("new", "authkey", "success", m.Namespace.Name).Inc() + machineRegistrations.WithLabelValues("new", "authkey", "success", m.Namespace.Name). + Inc() c.Data(200, "application/json; charset=utf-8", respBody) log.Info(). Str("func", "handleAuthKey"). diff --git a/app.go b/app.go index c2260627..94181ac7 100644 --- a/app.go +++ b/app.go @@ -152,8 +152,14 @@ func NewHeadscale(cfg Config) (*Headscale, error) { var dbString string switch cfg.DBtype { case "postgres": - dbString = fmt.Sprintf("host=%s port=%d dbname=%s user=%s password=%s sslmode=disable", cfg.DBhost, - cfg.DBport, cfg.DBname, cfg.DBuser, cfg.DBpass) + dbString = fmt.Sprintf( + "host=%s port=%d dbname=%s user=%s password=%s sslmode=disable", + cfg.DBhost, + cfg.DBport, + cfg.DBname, + cfg.DBuser, + cfg.DBpass, + ) case "sqlite3": dbString = cfg.DBpath default: @@ -182,7 +188,10 @@ func NewHeadscale(cfg Config) (*Headscale, error) { } if h.cfg.DNSConfig != nil && h.cfg.DNSConfig.Proxied { // if MagicDNS - magicDNSDomains, err := generateMagicDNSRootDomains(h.cfg.IPPrefix, h.cfg.BaseDomain) + magicDNSDomains, err := generateMagicDNSRootDomains( + h.cfg.IPPrefix, + h.cfg.BaseDomain, + ) if err != nil { return nil, err } @@ -224,7 +233,10 @@ func (h *Headscale) expireEphemeralNodesWorker() { for _, ns := range namespaces { machines, err := h.ListMachinesInNamespace(ns.Name) if err != nil { - log.Error().Err(err).Str("namespace", ns.Name).Msg("Error listing machines in namespace") + log.Error(). + Err(err). + Str("namespace", ns.Name). + Msg("Error listing machines in namespace") return } @@ -232,7 +244,9 @@ func (h *Headscale) expireEphemeralNodesWorker() { for _, m := range machines { if m.AuthKey != nil && m.LastSeen != nil && m.AuthKey.Ephemeral && time.Now().After(m.LastSeen.Add(h.cfg.EphemeralNodeInactivityTimeout)) { - log.Info().Str("machine", m.Name).Msg("Ephemeral client removed from database") + log.Info(). + Str("machine", m.Name). + Msg("Ephemeral client removed from database") err = h.db.Unscoped().Delete(m).Error if err != nil { @@ -274,18 +288,33 @@ func (h *Headscale) grpcAuthenticationInterceptor(ctx context.Context, // the server p, _ := peer.FromContext(ctx) - log.Trace().Caller().Str("client_address", p.Addr.String()).Msg("Client is trying to authenticate") + log.Trace(). + Caller(). + Str("client_address", p.Addr.String()). + Msg("Client is trying to authenticate") md, ok := metadata.FromIncomingContext(ctx) if !ok { - log.Error().Caller().Str("client_address", p.Addr.String()).Msg("Retrieving metadata is failed") - return ctx, status.Errorf(codes.InvalidArgument, "Retrieving metadata is failed") + log.Error(). + Caller(). + Str("client_address", p.Addr.String()). + Msg("Retrieving metadata is failed") + return ctx, status.Errorf( + codes.InvalidArgument, + "Retrieving metadata is failed", + ) } authHeader, ok := md["authorization"] if !ok { - log.Error().Caller().Str("client_address", p.Addr.String()).Msg("Authorization token is not supplied") - return ctx, status.Errorf(codes.Unauthenticated, "Authorization token is not supplied") + log.Error(). + Caller(). + Str("client_address", p.Addr.String()). + Msg("Authorization token is not supplied") + return ctx, status.Errorf( + codes.Unauthenticated, + "Authorization token is not supplied", + ) } token := authHeader[0] @@ -295,7 +324,10 @@ func (h *Headscale) grpcAuthenticationInterceptor(ctx context.Context, Caller(). Str("client_address", p.Addr.String()). Msg(`missing "Bearer " prefix in "Authorization" header`) - return ctx, status.Error(codes.Unauthenticated, `missing "Bearer " prefix in "Authorization" header`) + return ctx, status.Error( + codes.Unauthenticated, + `missing "Bearer " prefix in "Authorization" header`, + ) } // TODO(kradalby): Implement API key backend: @@ -307,7 +339,10 @@ func (h *Headscale) grpcAuthenticationInterceptor(ctx context.Context, // Currently all other than localhost traffic is unauthorized, this is intentional to allow // us to make use of gRPC for our CLI, but not having to implement any of the remote capabilities // and API key auth - return ctx, status.Error(codes.Unauthenticated, "Authentication is not implemented yet") + return ctx, status.Error( + codes.Unauthenticated, + "Authentication is not implemented yet", + ) //if strings.TrimPrefix(token, AUTH_PREFIX) != a.Token { // log.Error().Caller().Str("client_address", p.Addr.String()).Msg("invalid token") @@ -405,7 +440,10 @@ func (h *Headscale) Serve() error { // Match gRPC requests here grpcListener := m.MatchWithWriters( cmux.HTTP2MatchHeaderFieldSendSettings("content-type", "application/grpc"), - cmux.HTTP2MatchHeaderFieldSendSettings("content-type", "application/grpc+proto"), + cmux.HTTP2MatchHeaderFieldSendSettings( + "content-type", + "application/grpc+proto", + ), ) // Otherwise match regular http requests. httpListener := m.Match(cmux.Any()) @@ -436,7 +474,10 @@ func (h *Headscale) Serve() error { p := ginprometheus.NewPrometheus("gin") p.Use(r) - r.GET("/health", func(c *gin.Context) { c.JSON(http.StatusOK, gin.H{"healthy": "ok"}) }) + r.GET( + "/health", + func(c *gin.Context) { c.JSON(http.StatusOK, gin.H{"healthy": "ok"}) }, + ) r.GET("/key", h.KeyHandler) r.GET("/register", h.RegisterWebAPI) r.POST("/machine/:id/map", h.PollNetMapHandler) @@ -537,7 +578,8 @@ func (h *Headscale) Serve() error { g.Go(func() error { return m.Serve() }) - log.Info().Msgf("listening and serving (multiplexed HTTP and gRPC) on: %s", h.cfg.Addr) + log.Info(). + Msgf("listening and serving (multiplexed HTTP and gRPC) on: %s", h.cfg.Addr) return g.Wait() } @@ -545,7 +587,8 @@ func (h *Headscale) Serve() error { func (h *Headscale) getTLSSettings() (*tls.Config, error) { if h.cfg.TLSLetsEncryptHostname != "" { if !strings.HasPrefix(h.cfg.ServerURL, "https://") { - log.Warn().Msg("Listening with TLS but ServerURL does not start with https://") + log.Warn(). + Msg("Listening with TLS but ServerURL does not start with https://") } m := autocert.Manager{ diff --git a/app_test.go b/app_test.go index 5e53f1cc..ec232827 100644 --- a/app_test.go +++ b/app_test.go @@ -17,8 +17,10 @@ var _ = check.Suite(&Suite{}) type Suite struct{} -var tmpDir string -var h Headscale +var ( + tmpDir string + h Headscale +) func (s *Suite) SetUpTest(c *check.C) { s.ResetDB(c) diff --git a/apple_mobileconfig.go b/apple_mobileconfig.go index f3956e3c..6ddd5be3 100644 --- a/apple_mobileconfig.go +++ b/apple_mobileconfig.go @@ -73,7 +73,11 @@ func (h *Headscale) AppleMobileConfig(c *gin.Context) { Str("handler", "AppleMobileConfig"). Err(err). Msg("Could not render Apple index template") - c.Data(http.StatusInternalServerError, "text/html; charset=utf-8", []byte("Could not render Apple index template")) + c.Data( + http.StatusInternalServerError, + "text/html; charset=utf-8", + []byte("Could not render Apple index template"), + ) return } @@ -89,7 +93,11 @@ func (h *Headscale) ApplePlatformConfig(c *gin.Context) { Str("handler", "ApplePlatformConfig"). Err(err). Msg("Failed not create UUID") - c.Data(http.StatusInternalServerError, "text/html; charset=utf-8", []byte("Failed to create UUID")) + c.Data( + http.StatusInternalServerError, + "text/html; charset=utf-8", + []byte("Failed to create UUID"), + ) return } @@ -99,7 +107,11 @@ func (h *Headscale) ApplePlatformConfig(c *gin.Context) { Str("handler", "ApplePlatformConfig"). Err(err). Msg("Failed not create UUID") - c.Data(http.StatusInternalServerError, "text/html; charset=utf-8", []byte("Failed to create UUID")) + c.Data( + http.StatusInternalServerError, + "text/html; charset=utf-8", + []byte("Failed to create UUID"), + ) return } @@ -117,7 +129,11 @@ func (h *Headscale) ApplePlatformConfig(c *gin.Context) { Str("handler", "ApplePlatformConfig"). Err(err). Msg("Could not render Apple macOS template") - c.Data(http.StatusInternalServerError, "text/html; charset=utf-8", []byte("Could not render Apple macOS template")) + c.Data( + http.StatusInternalServerError, + "text/html; charset=utf-8", + []byte("Could not render Apple macOS template"), + ) return } case "ios": @@ -126,11 +142,19 @@ func (h *Headscale) ApplePlatformConfig(c *gin.Context) { Str("handler", "ApplePlatformConfig"). Err(err). Msg("Could not render Apple iOS template") - c.Data(http.StatusInternalServerError, "text/html; charset=utf-8", []byte("Could not render Apple iOS template")) + c.Data( + http.StatusInternalServerError, + "text/html; charset=utf-8", + []byte("Could not render Apple iOS template"), + ) return } default: - c.Data(http.StatusOK, "text/html; charset=utf-8", []byte("Invalid platform, only ios and macos is supported")) + c.Data( + http.StatusOK, + "text/html; charset=utf-8", + []byte("Invalid platform, only ios and macos is supported"), + ) return } @@ -146,11 +170,19 @@ func (h *Headscale) ApplePlatformConfig(c *gin.Context) { Str("handler", "ApplePlatformConfig"). Err(err). Msg("Could not render Apple platform template") - c.Data(http.StatusInternalServerError, "text/html; charset=utf-8", []byte("Could not render Apple platform template")) + c.Data( + http.StatusInternalServerError, + "text/html; charset=utf-8", + []byte("Could not render Apple platform template"), + ) return } - c.Data(http.StatusOK, "application/x-apple-aspen-config; charset=utf-8", content.Bytes()) + c.Data( + http.StatusOK, + "application/x-apple-aspen-config; charset=utf-8", + content.Bytes(), + ) } type AppleMobileConfig struct { @@ -164,7 +196,8 @@ type AppleMobilePlatformConfig struct { Url string } -var commonTemplate = template.Must(template.New("mobileconfig").Parse(` +var commonTemplate = template.Must( + template.New("mobileconfig").Parse(` @@ -187,7 +220,8 @@ var commonTemplate = template.Must(template.New("mobileconfig").Parse(` -`)) +`), +) var iosTemplate = template.Must(template.New("iosTemplate").Parse(` diff --git a/cli_test.go b/cli_test.go index 291b5df1..6c0b2bbb 100644 --- a/cli_test.go +++ b/cli_test.go @@ -28,7 +28,10 @@ func (s *Suite) TestRegisterMachine(c *check.C) { _, err = h.GetMachine("test", "testmachine") c.Assert(err, check.IsNil) - m2, err := h.RegisterMachine("8ce002a935f8c394e55e78fbbb410576575ff8ec5cfa2e627e4b807f1be15b0e", n.Name) + m2, err := h.RegisterMachine( + "8ce002a935f8c394e55e78fbbb410576575ff8ec5cfa2e627e4b807f1be15b0e", + n.Name, + ) c.Assert(err, check.IsNil) c.Assert(m2.Registered, check.Equals, true) diff --git a/cmd/headscale/cli/debug.go b/cmd/headscale/cli/debug.go index e140156b..f106efa6 100644 --- a/cmd/headscale/cli/debug.go +++ b/cmd/headscale/cli/debug.go @@ -27,7 +27,8 @@ func init() { if err != nil { log.Fatal().Err(err).Msg("") } - createNodeCmd.Flags().StringSliceP("route", "r", []string{}, "List (or repeated flags) of routes to advertise") + createNodeCmd.Flags(). + StringSliceP("route", "r", []string{}, "List (or repeated flags) of routes to advertise") debugCmd.AddCommand(createNodeCmd) } @@ -56,19 +57,31 @@ var createNodeCmd = &cobra.Command{ name, err := cmd.Flags().GetString("name") if err != nil { - ErrorOutput(err, fmt.Sprintf("Error getting node from flag: %s", err), output) + ErrorOutput( + err, + fmt.Sprintf("Error getting node from flag: %s", err), + output, + ) return } machineKey, err := cmd.Flags().GetString("key") if err != nil { - ErrorOutput(err, fmt.Sprintf("Error getting key from flag: %s", err), output) + ErrorOutput( + err, + fmt.Sprintf("Error getting key from flag: %s", err), + output, + ) return } routes, err := cmd.Flags().GetStringSlice("route") if err != nil { - ErrorOutput(err, fmt.Sprintf("Error getting routes from flag: %s", err), output) + ErrorOutput( + err, + fmt.Sprintf("Error getting routes from flag: %s", err), + output, + ) return } @@ -81,7 +94,11 @@ var createNodeCmd = &cobra.Command{ response, err := client.DebugCreateMachine(ctx, request) if err != nil { - ErrorOutput(err, fmt.Sprintf("Cannot create machine: %s", status.Convert(err).Message()), output) + ErrorOutput( + err, + fmt.Sprintf("Cannot create machine: %s", status.Convert(err).Message()), + output, + ) return } diff --git a/cmd/headscale/cli/namespaces.go b/cmd/headscale/cli/namespaces.go index 752638a7..3a111782 100644 --- a/cmd/headscale/cli/namespaces.go +++ b/cmd/headscale/cli/namespaces.go @@ -48,7 +48,14 @@ var createNamespaceCmd = &cobra.Command{ log.Trace().Interface("request", request).Msg("Sending CreateNamespace request") response, err := client.CreateNamespace(ctx, request) if err != nil { - ErrorOutput(err, fmt.Sprintf("Cannot create namespace: %s", status.Convert(err).Message()), output) + ErrorOutput( + err, + fmt.Sprintf( + "Cannot create namespace: %s", + status.Convert(err).Message(), + ), + output, + ) return } @@ -78,7 +85,14 @@ var destroyNamespaceCmd = &cobra.Command{ response, err := client.DeleteNamespace(ctx, request) if err != nil { - ErrorOutput(err, fmt.Sprintf("Cannot destroy namespace: %s", status.Convert(err).Message()), output) + ErrorOutput( + err, + fmt.Sprintf( + "Cannot destroy namespace: %s", + status.Convert(err).Message(), + ), + output, + ) return } @@ -100,7 +114,11 @@ var listNamespacesCmd = &cobra.Command{ response, err := client.ListNamespaces(ctx, request) if err != nil { - ErrorOutput(err, fmt.Sprintf("Cannot get namespaces: %s", status.Convert(err).Message()), output) + ErrorOutput( + err, + fmt.Sprintf("Cannot get namespaces: %s", status.Convert(err).Message()), + output, + ) return } @@ -122,7 +140,11 @@ var listNamespacesCmd = &cobra.Command{ } err = pterm.DefaultTable.WithHasHeader().WithData(d).Render() if err != nil { - ErrorOutput(err, fmt.Sprintf("Failed to render pterm table: %s", err), output) + ErrorOutput( + err, + fmt.Sprintf("Failed to render pterm table: %s", err), + output, + ) return } }, @@ -151,7 +173,14 @@ var renameNamespaceCmd = &cobra.Command{ response, err := client.RenameNamespace(ctx, request) if err != nil { - ErrorOutput(err, fmt.Sprintf("Cannot rename namespace: %s", status.Convert(err).Message()), output) + ErrorOutput( + err, + fmt.Sprintf( + "Cannot rename namespace: %s", + status.Convert(err).Message(), + ), + output, + ) return } diff --git a/cmd/headscale/cli/nodes.go b/cmd/headscale/cli/nodes.go index 9b3f4243..934ac491 100644 --- a/cmd/headscale/cli/nodes.go +++ b/cmd/headscale/cli/nodes.go @@ -86,7 +86,11 @@ var registerNodeCmd = &cobra.Command{ machineKey, err := cmd.Flags().GetString("key") if err != nil { - ErrorOutput(err, fmt.Sprintf("Error getting machine key from flag: %s", err), output) + ErrorOutput( + err, + fmt.Sprintf("Error getting machine key from flag: %s", err), + output, + ) return } @@ -97,7 +101,14 @@ var registerNodeCmd = &cobra.Command{ response, err := client.RegisterMachine(ctx, request) if err != nil { - ErrorOutput(err, fmt.Sprintf("Cannot register machine: %s\n", status.Convert(err).Message()), output) + ErrorOutput( + err, + fmt.Sprintf( + "Cannot register machine: %s\n", + status.Convert(err).Message(), + ), + output, + ) return } @@ -126,7 +137,11 @@ var listNodesCmd = &cobra.Command{ response, err := client.ListMachines(ctx, request) if err != nil { - ErrorOutput(err, fmt.Sprintf("Cannot get nodes: %s", status.Convert(err).Message()), output) + ErrorOutput( + err, + fmt.Sprintf("Cannot get nodes: %s", status.Convert(err).Message()), + output, + ) return } @@ -143,7 +158,11 @@ var listNodesCmd = &cobra.Command{ err = pterm.DefaultTable.WithHasHeader().WithData(d).Render() if err != nil { - ErrorOutput(err, fmt.Sprintf("Failed to render pterm table: %s", err), output) + ErrorOutput( + err, + fmt.Sprintf("Failed to render pterm table: %s", err), + output, + ) return } }, @@ -157,7 +176,11 @@ var deleteNodeCmd = &cobra.Command{ id, err := cmd.Flags().GetInt("identifier") if err != nil { - ErrorOutput(err, fmt.Sprintf("Error converting ID to integer: %s", err), output) + ErrorOutput( + err, + fmt.Sprintf("Error converting ID to integer: %s", err), + output, + ) return } @@ -171,7 +194,14 @@ var deleteNodeCmd = &cobra.Command{ getResponse, err := client.GetMachine(ctx, getRequest) if err != nil { - ErrorOutput(err, fmt.Sprintf("Error getting node node: %s", status.Convert(err).Message()), output) + ErrorOutput( + err, + fmt.Sprintf( + "Error getting node node: %s", + status.Convert(err).Message(), + ), + output, + ) return } @@ -183,7 +213,10 @@ var deleteNodeCmd = &cobra.Command{ force, _ := cmd.Flags().GetBool("force") if !force { prompt := &survey.Confirm{ - Message: fmt.Sprintf("Do you want to remove the node %s?", getResponse.GetMachine().Name), + Message: fmt.Sprintf( + "Do you want to remove the node %s?", + getResponse.GetMachine().Name, + ), } err = survey.AskOne(prompt, &confirm) if err != nil { @@ -198,10 +231,21 @@ var deleteNodeCmd = &cobra.Command{ return } if err != nil { - ErrorOutput(err, fmt.Sprintf("Error deleting node: %s", status.Convert(err).Message()), output) + ErrorOutput( + err, + fmt.Sprintf( + "Error deleting node: %s", + status.Convert(err).Message(), + ), + output, + ) return } - SuccessOutput(map[string]string{"Result": "Node deleted"}, "Node deleted", output) + SuccessOutput( + map[string]string{"Result": "Node deleted"}, + "Node deleted", + output, + ) } else { SuccessOutput(map[string]string{"Result": "Node not deleted"}, "Node not deleted", output) } @@ -235,7 +279,11 @@ func sharingWorker( machineResponse, err := client.GetMachine(ctx, machineRequest) if err != nil { - ErrorOutput(err, fmt.Sprintf("Error getting node node: %s", status.Convert(err).Message()), output) + ErrorOutput( + err, + fmt.Sprintf("Error getting node node: %s", status.Convert(err).Message()), + output, + ) return "", nil, nil, err } @@ -245,7 +293,11 @@ func sharingWorker( namespaceResponse, err := client.GetNamespace(ctx, namespaceRequest) if err != nil { - ErrorOutput(err, fmt.Sprintf("Error getting node node: %s", status.Convert(err).Message()), output) + ErrorOutput( + err, + fmt.Sprintf("Error getting node node: %s", status.Convert(err).Message()), + output, + ) return "", nil, nil, err } @@ -258,7 +310,11 @@ var shareMachineCmd = &cobra.Command{ Run: func(cmd *cobra.Command, args []string) { output, machine, namespace, err := sharingWorker(cmd, args) if err != nil { - ErrorOutput(err, fmt.Sprintf("Failed to fetch namespace or machine: %s", err), output) + ErrorOutput( + err, + fmt.Sprintf("Failed to fetch namespace or machine: %s", err), + output, + ) return } @@ -273,7 +329,11 @@ var shareMachineCmd = &cobra.Command{ response, err := client.ShareMachine(ctx, request) if err != nil { - ErrorOutput(err, fmt.Sprintf("Error sharing node: %s", status.Convert(err).Message()), output) + ErrorOutput( + err, + fmt.Sprintf("Error sharing node: %s", status.Convert(err).Message()), + output, + ) return } @@ -287,7 +347,11 @@ var unshareMachineCmd = &cobra.Command{ Run: func(cmd *cobra.Command, args []string) { output, machine, namespace, err := sharingWorker(cmd, args) if err != nil { - ErrorOutput(err, fmt.Sprintf("Failed to fetch namespace or machine: %s", err), output) + ErrorOutput( + err, + fmt.Sprintf("Failed to fetch namespace or machine: %s", err), + output, + ) return } @@ -302,7 +366,11 @@ var unshareMachineCmd = &cobra.Command{ response, err := client.UnshareMachine(ctx, request) if err != nil { - ErrorOutput(err, fmt.Sprintf("Error unsharing node: %s", status.Convert(err).Message()), output) + ErrorOutput( + err, + fmt.Sprintf("Error unsharing node: %s", status.Convert(err).Message()), + output, + ) return } @@ -310,8 +378,22 @@ var unshareMachineCmd = &cobra.Command{ }, } -func nodesToPtables(currentNamespace string, machines []*v1.Machine) (pterm.TableData, error) { - d := pterm.TableData{{"ID", "Name", "NodeKey", "Namespace", "IP address", "Ephemeral", "Last seen", "Online"}} +func nodesToPtables( + currentNamespace string, + machines []*v1.Machine, +) (pterm.TableData, error) { + d := pterm.TableData{ + { + "ID", + "Name", + "NodeKey", + "Namespace", + "IP address", + "Ephemeral", + "Last seen", + "Online", + }, + } for _, machine := range machines { var ephemeral bool @@ -331,7 +413,9 @@ func nodesToPtables(currentNamespace string, machines []*v1.Machine) (pterm.Tabl nodeKey := tailcfg.NodeKey(nKey) var online string - if lastSeen.After(time.Now().Add(-5 * time.Minute)) { // TODO: Find a better way to reliably show if online + if lastSeen.After( + time.Now().Add(-5 * time.Minute), + ) { // TODO: Find a better way to reliably show if online online = pterm.LightGreen("true") } else { online = pterm.LightRed("false") diff --git a/cmd/headscale/cli/preauthkeys.go b/cmd/headscale/cli/preauthkeys.go index a07e9610..f5b3b87b 100644 --- a/cmd/headscale/cli/preauthkeys.go +++ b/cmd/headscale/cli/preauthkeys.go @@ -22,8 +22,10 @@ func init() { preauthkeysCmd.AddCommand(listPreAuthKeys) preauthkeysCmd.AddCommand(createPreAuthKeyCmd) preauthkeysCmd.AddCommand(expirePreAuthKeyCmd) - createPreAuthKeyCmd.PersistentFlags().Bool("reusable", false, "Make the preauthkey reusable") - createPreAuthKeyCmd.PersistentFlags().Bool("ephemeral", false, "Preauthkey for ephemeral nodes") + createPreAuthKeyCmd.PersistentFlags(). + Bool("reusable", false, "Make the preauthkey reusable") + createPreAuthKeyCmd.PersistentFlags(). + Bool("ephemeral", false, "Preauthkey for ephemeral nodes") createPreAuthKeyCmd.Flags(). DurationP("expiration", "e", 24*time.Hour, "Human-readable expiration of the key (30m, 24h, 365d...)") } @@ -55,7 +57,11 @@ var listPreAuthKeys = &cobra.Command{ response, err := client.ListPreAuthKeys(ctx, request) if err != nil { - ErrorOutput(err, fmt.Sprintf("Error getting the list of keys: %s", err), output) + ErrorOutput( + err, + fmt.Sprintf("Error getting the list of keys: %s", err), + output, + ) return } @@ -64,7 +70,9 @@ var listPreAuthKeys = &cobra.Command{ return } - d := pterm.TableData{{"ID", "Key", "Reusable", "Ephemeral", "Used", "Expiration", "Created"}} + d := pterm.TableData{ + {"ID", "Key", "Reusable", "Ephemeral", "Used", "Expiration", "Created"}, + } for _, k := range response.PreAuthKeys { expiration := "-" if k.GetExpiration() != nil { @@ -91,7 +99,11 @@ var listPreAuthKeys = &cobra.Command{ } err = pterm.DefaultTable.WithHasHeader().WithData(d).Render() if err != nil { - ErrorOutput(err, fmt.Sprintf("Failed to render pterm table: %s", err), output) + ErrorOutput( + err, + fmt.Sprintf("Failed to render pterm table: %s", err), + output, + ) return } }, @@ -139,7 +151,11 @@ var createPreAuthKeyCmd = &cobra.Command{ response, err := client.CreatePreAuthKey(ctx, request) if err != nil { - ErrorOutput(err, fmt.Sprintf("Cannot create Pre Auth Key: %s\n", err), output) + ErrorOutput( + err, + fmt.Sprintf("Cannot create Pre Auth Key: %s\n", err), + output, + ) return } @@ -175,7 +191,11 @@ var expirePreAuthKeyCmd = &cobra.Command{ response, err := client.ExpirePreAuthKey(ctx, request) if err != nil { - ErrorOutput(err, fmt.Sprintf("Cannot expire Pre Auth Key: %s\n", err), output) + ErrorOutput( + err, + fmt.Sprintf("Cannot expire Pre Auth Key: %s\n", err), + output, + ) return } diff --git a/cmd/headscale/cli/root.go b/cmd/headscale/cli/root.go index e5115f3d..99b15140 100644 --- a/cmd/headscale/cli/root.go +++ b/cmd/headscale/cli/root.go @@ -10,7 +10,8 @@ import ( func init() { rootCmd.PersistentFlags(). StringP("output", "o", "", "Output format. Empty for human-readable, 'json', 'json-line' or 'yaml'") - rootCmd.PersistentFlags().Bool("force", false, "Disable prompts and forces the execution") + rootCmd.PersistentFlags(). + Bool("force", false, "Disable prompts and forces the execution") } var rootCmd = &cobra.Command{ diff --git a/cmd/headscale/cli/routes.go b/cmd/headscale/cli/routes.go index 9f2e4e24..e6c80fb1 100644 --- a/cmd/headscale/cli/routes.go +++ b/cmd/headscale/cli/routes.go @@ -21,7 +21,8 @@ func init() { } routesCmd.AddCommand(listRoutesCmd) - enableRouteCmd.Flags().StringSliceP("route", "r", []string{}, "List (or repeated flags) of routes to enable") + enableRouteCmd.Flags(). + StringSliceP("route", "r", []string{}, "List (or repeated flags) of routes to enable") enableRouteCmd.Flags().Uint64P("identifier", "i", 0, "Node identifier (ID)") err = enableRouteCmd.MarkFlagRequired("identifier") if err != nil { @@ -46,7 +47,11 @@ var listRoutesCmd = &cobra.Command{ machineId, err := cmd.Flags().GetUint64("identifier") if err != nil { - ErrorOutput(err, fmt.Sprintf("Error getting machine id from flag: %s", err), output) + ErrorOutput( + err, + fmt.Sprintf("Error getting machine id from flag: %s", err), + output, + ) return } @@ -60,7 +65,11 @@ var listRoutesCmd = &cobra.Command{ response, err := client.GetMachineRoute(ctx, request) if err != nil { - ErrorOutput(err, fmt.Sprintf("Cannot get nodes: %s", status.Convert(err).Message()), output) + ErrorOutput( + err, + fmt.Sprintf("Cannot get nodes: %s", status.Convert(err).Message()), + output, + ) return } @@ -77,7 +86,11 @@ var listRoutesCmd = &cobra.Command{ err = pterm.DefaultTable.WithHasHeader().WithData(d).Render() if err != nil { - ErrorOutput(err, fmt.Sprintf("Failed to render pterm table: %s", err), output) + ErrorOutput( + err, + fmt.Sprintf("Failed to render pterm table: %s", err), + output, + ) return } }, @@ -95,13 +108,21 @@ omit the route you do not want to enable. output, _ := cmd.Flags().GetString("output") machineId, err := cmd.Flags().GetUint64("identifier") if err != nil { - ErrorOutput(err, fmt.Sprintf("Error getting machine id from flag: %s", err), output) + ErrorOutput( + err, + fmt.Sprintf("Error getting machine id from flag: %s", err), + output, + ) return } routes, err := cmd.Flags().GetStringSlice("route") if err != nil { - ErrorOutput(err, fmt.Sprintf("Error getting routes from flag: %s", err), output) + ErrorOutput( + err, + fmt.Sprintf("Error getting routes from flag: %s", err), + output, + ) return } @@ -116,7 +137,14 @@ omit the route you do not want to enable. response, err := client.EnableMachineRoutes(ctx, request) if err != nil { - ErrorOutput(err, fmt.Sprintf("Cannot register machine: %s\n", status.Convert(err).Message()), output) + ErrorOutput( + err, + fmt.Sprintf( + "Cannot register machine: %s\n", + status.Convert(err).Message(), + ), + output, + ) return } @@ -133,7 +161,11 @@ omit the route you do not want to enable. err = pterm.DefaultTable.WithHasHeader().WithData(d).Render() if err != nil { - ErrorOutput(err, fmt.Sprintf("Failed to render pterm table: %s", err), output) + ErrorOutput( + err, + fmt.Sprintf("Failed to render pterm table: %s", err), + output, + ) return } }, diff --git a/cmd/headscale/cli/utils.go b/cmd/headscale/cli/utils.go index 30f1a789..16b236a7 100644 --- a/cmd/headscale/cli/utils.go +++ b/cmd/headscale/cli/utils.go @@ -149,9 +149,14 @@ func GetDNSConfig() (*tailcfg.DNSConfig, string) { if viper.IsSet("dns_config.restricted_nameservers") { if len(dnsConfig.Nameservers) > 0 { dnsConfig.Routes = make(map[string][]dnstype.Resolver) - restrictedDNS := viper.GetStringMapStringSlice("dns_config.restricted_nameservers") + restrictedDNS := viper.GetStringMapStringSlice( + "dns_config.restricted_nameservers", + ) for domain, restrictedNameservers := range restrictedDNS { - restrictedResolvers := make([]dnstype.Resolver, len(restrictedNameservers)) + restrictedResolvers := make( + []dnstype.Resolver, + len(restrictedNameservers), + ) for index, nameserverStr := range restrictedNameservers { nameserver, err := netaddr.ParseIP(nameserverStr) if err != nil { @@ -219,7 +224,9 @@ func getHeadscaleConfig() headscale.Config { "10h", ) // use 10h here because it is the length of a standard business day plus a small amount of leeway if viper.GetDuration("max_machine_registration_duration") >= time.Second { - maxMachineRegistrationDuration = viper.GetDuration("max_machine_registration_duration") + maxMachineRegistrationDuration = viper.GetDuration( + "max_machine_registration_duration", + ) } // defaultMachineRegistrationDuration is the default time assigned to a machine registration if one is not @@ -229,7 +236,9 @@ func getHeadscaleConfig() headscale.Config { "8h", ) // use 8h here because it's the length of a standard business day if viper.GetDuration("default_machine_registration_duration") >= time.Second { - defaultMachineRegistrationDuration = viper.GetDuration("default_machine_registration_duration") + defaultMachineRegistrationDuration = viper.GetDuration( + "default_machine_registration_duration", + ) } dnsConfig, baseDomain := GetDNSConfig() @@ -244,7 +253,9 @@ func getHeadscaleConfig() headscale.Config { DERP: derpConfig, - EphemeralNodeInactivityTimeout: viper.GetDuration("ephemeral_node_inactivity_timeout"), + EphemeralNodeInactivityTimeout: viper.GetDuration( + "ephemeral_node_inactivity_timeout", + ), DBtype: viper.GetString("db_type"), DBpath: absPath(viper.GetString("db_path")), @@ -254,9 +265,11 @@ func getHeadscaleConfig() headscale.Config { DBuser: viper.GetString("db_user"), DBpass: viper.GetString("db_pass"), - TLSLetsEncryptHostname: viper.GetString("tls_letsencrypt_hostname"), - TLSLetsEncryptListen: viper.GetString("tls_letsencrypt_listen"), - TLSLetsEncryptCacheDir: absPath(viper.GetString("tls_letsencrypt_cache_dir")), + TLSLetsEncryptHostname: viper.GetString("tls_letsencrypt_hostname"), + TLSLetsEncryptListen: viper.GetString("tls_letsencrypt_listen"), + TLSLetsEncryptCacheDir: absPath( + viper.GetString("tls_letsencrypt_cache_dir"), + ), TLSLetsEncryptChallengeType: viper.GetString("tls_letsencrypt_challenge_type"), TLSCertPath: absPath(viper.GetString("tls_cert_path")), @@ -431,7 +444,10 @@ type tokenAuth struct { } // Return value is mapped to request headers. -func (t tokenAuth) GetRequestMetadata(ctx context.Context, in ...string) (map[string]string, error) { +func (t tokenAuth) GetRequestMetadata( + ctx context.Context, + in ...string, +) (map[string]string, error) { return map[string]string{ "authorization": "Bearer " + t.token, }, nil diff --git a/cmd/headscale/headscale.go b/cmd/headscale/headscale.go index ed4644f3..8f436b9e 100644 --- a/cmd/headscale/headscale.go +++ b/cmd/headscale/headscale.go @@ -63,7 +63,8 @@ func main() { } if !viper.GetBool("disable_check_updates") && !machineOutput { - if (runtime.GOOS == "linux" || runtime.GOOS == "darwin") && cli.Version != "dev" { + if (runtime.GOOS == "linux" || runtime.GOOS == "darwin") && + cli.Version != "dev" { githubTag := &latest.GithubTag{ Owner: "juanfont", Repository: "headscale", diff --git a/cmd/headscale/headscale_test.go b/cmd/headscale/headscale_test.go index e3a5713f..ceee3e44 100644 --- a/cmd/headscale/headscale_test.go +++ b/cmd/headscale/headscale_test.go @@ -40,7 +40,10 @@ func (*Suite) TestConfigLoading(c *check.C) { } // Symlink the example config file - err = os.Symlink(filepath.Clean(path+"/../../config-example.yaml"), filepath.Join(tmpDir, "config.yaml")) + err = os.Symlink( + filepath.Clean(path+"/../../config-example.yaml"), + filepath.Join(tmpDir, "config.yaml"), + ) if err != nil { c.Fatal(err) } @@ -74,7 +77,10 @@ func (*Suite) TestDNSConfigLoading(c *check.C) { } // Symlink the example config file - err = os.Symlink(filepath.Clean(path+"/../../config-example.yaml"), filepath.Join(tmpDir, "config.yaml")) + err = os.Symlink( + filepath.Clean(path+"/../../config-example.yaml"), + filepath.Join(tmpDir, "config.yaml"), + ) if err != nil { c.Fatal(err) } @@ -128,7 +134,11 @@ func (*Suite) TestTLSConfigValidation(c *check.C) { check.Matches, ".*Fatal config error: the only supported values for tls_letsencrypt_challenge_type are.*", ) - c.Assert(tmp, check.Matches, ".*Fatal config error: server_url must start with https:// or http://.*") + c.Assert( + tmp, + check.Matches, + ".*Fatal config error: server_url must start with https:// or http://.*", + ) fmt.Println(tmp) // Check configuration validation errors (2) diff --git a/db.go b/db.go index 42c5eee9..60e2f6f1 100644 --- a/db.go +++ b/db.go @@ -87,7 +87,10 @@ func (h *Headscale) openDB() (*gorm.DB, error) { // getValue returns the value for the given key in KV func (h *Headscale) getValue(key string) (string, error) { var row KV - if result := h.db.First(&row, "key = ?", key); errors.Is(result.Error, gorm.ErrRecordNotFound) { + if result := h.db.First(&row, "key = ?", key); errors.Is( + result.Error, + gorm.ErrRecordNotFound, + ) { return "", errors.New("not found") } return row.Value, nil diff --git a/dns.go b/dns.go index c7ca32ac..e0e1abee 100644 --- a/dns.go +++ b/dns.go @@ -30,7 +30,10 @@ import ( // From the netmask we can find out the wildcard bits (the bits that are not set in the netmask). // This allows us to then calculate the subnets included in the subsequent class block and generate the entries. -func generateMagicDNSRootDomains(ipPrefix netaddr.IPPrefix, baseDomain string) ([]dnsname.FQDN, error) { +func generateMagicDNSRootDomains( + ipPrefix netaddr.IPPrefix, + baseDomain string, +) ([]dnsname.FQDN, error) { // TODO(juanfont): we are not handing out IPv6 addresses yet // and in fact this is Tailscale.com's range (note the fd7a:115c:a1e0: range in the fc00::/7 network) ipv6base := dnsname.FQDN("0.e.1.a.c.5.1.1.a.7.d.f.ip6.arpa.") @@ -69,12 +72,20 @@ func generateMagicDNSRootDomains(ipPrefix netaddr.IPPrefix, baseDomain string) ( return fqdns, nil } -func getMapResponseDNSConfig(dnsConfigOrig *tailcfg.DNSConfig, baseDomain string, m Machine, peers Machines) (*tailcfg.DNSConfig, error) { +func getMapResponseDNSConfig( + dnsConfigOrig *tailcfg.DNSConfig, + baseDomain string, + m Machine, + peers Machines, +) (*tailcfg.DNSConfig, error) { var dnsConfig *tailcfg.DNSConfig if dnsConfigOrig != nil && dnsConfigOrig.Proxied { // if MagicDNS is enabled // Only inject the Search Domain of the current namespace - shared nodes should use their full FQDN dnsConfig = dnsConfigOrig.Clone() - dnsConfig.Domains = append(dnsConfig.Domains, fmt.Sprintf("%s.%s", m.Namespace.Name, baseDomain)) + dnsConfig.Domains = append( + dnsConfig.Domains, + fmt.Sprintf("%s.%s", m.Namespace.Name, baseDomain), + ) namespaceSet := set.New(set.ThreadSafe) namespaceSet.Add(m.Namespace) diff --git a/grpcv1.go b/grpcv1.go index 998f0c0e..4366446a 100644 --- a/grpcv1.go +++ b/grpcv1.go @@ -155,7 +155,10 @@ func (api headscaleV1APIServer) RegisterMachine( ctx context.Context, request *v1.RegisterMachineRequest, ) (*v1.RegisterMachineResponse, error) { - log.Trace().Str("namespace", request.GetNamespace()).Str("machine_key", request.GetKey()).Msg("Registering machine") + log.Trace(). + Str("namespace", request.GetNamespace()). + Str("machine_key", request.GetKey()). + Msg("Registering machine") machine, err := api.h.RegisterMachine( request.GetKey(), request.GetNamespace(), @@ -208,7 +211,9 @@ func (api headscaleV1APIServer) ListMachines( return nil, err } - sharedMachines, err := api.h.ListSharedMachinesInNamespace(request.GetNamespace()) + sharedMachines, err := api.h.ListSharedMachinesInNamespace( + request.GetNamespace(), + ) if err != nil { return nil, err } @@ -338,7 +343,11 @@ func (api headscaleV1APIServer) DebugCreateMachine( return nil, err } - log.Trace().Caller().Interface("route-prefix", routes).Interface("route-str", request.GetRoutes()).Msg("") + log.Trace(). + Caller(). + Interface("route-prefix", routes). + Interface("route-str", request.GetRoutes()). + Msg("") hostinfo := tailcfg.Hostinfo{ RoutableIPs: routes, diff --git a/integration_cli_test.go b/integration_cli_test.go index e1b16727..335768c9 100644 --- a/integration_cli_test.go +++ b/integration_cli_test.go @@ -109,7 +109,10 @@ func (s *IntegrationCLITestSuite) TearDownTest() { } } -func (s *IntegrationCLITestSuite) HandleStats(suiteName string, stats *suite.SuiteInformation) { +func (s *IntegrationCLITestSuite) HandleStats( + suiteName string, + stats *suite.SuiteInformation, +) { s.stats = stats } @@ -298,11 +301,26 @@ func (s *IntegrationCLITestSuite) TestPreAuthKeyCommand() { assert.True(s.T(), listedPreAuthKeys[3].Expiration.AsTime().After(time.Now())) assert.True(s.T(), listedPreAuthKeys[4].Expiration.AsTime().After(time.Now())) - assert.True(s.T(), listedPreAuthKeys[0].Expiration.AsTime().Before(time.Now().Add(time.Hour*26))) - assert.True(s.T(), listedPreAuthKeys[1].Expiration.AsTime().Before(time.Now().Add(time.Hour*26))) - assert.True(s.T(), listedPreAuthKeys[2].Expiration.AsTime().Before(time.Now().Add(time.Hour*26))) - assert.True(s.T(), listedPreAuthKeys[3].Expiration.AsTime().Before(time.Now().Add(time.Hour*26))) - assert.True(s.T(), listedPreAuthKeys[4].Expiration.AsTime().Before(time.Now().Add(time.Hour*26))) + assert.True( + s.T(), + listedPreAuthKeys[0].Expiration.AsTime().Before(time.Now().Add(time.Hour*26)), + ) + assert.True( + s.T(), + listedPreAuthKeys[1].Expiration.AsTime().Before(time.Now().Add(time.Hour*26)), + ) + assert.True( + s.T(), + listedPreAuthKeys[2].Expiration.AsTime().Before(time.Now().Add(time.Hour*26)), + ) + assert.True( + s.T(), + listedPreAuthKeys[3].Expiration.AsTime().Before(time.Now().Add(time.Hour*26)), + ) + assert.True( + s.T(), + listedPreAuthKeys[4].Expiration.AsTime().Before(time.Now().Add(time.Hour*26)), + ) // Expire three keys for i := 0; i < 3; i++ { @@ -341,11 +359,26 @@ func (s *IntegrationCLITestSuite) TestPreAuthKeyCommand() { err = json.Unmarshal([]byte(listAfterExpireResult), &listedAfterExpirePreAuthKeys) assert.Nil(s.T(), err) - assert.True(s.T(), listedAfterExpirePreAuthKeys[0].Expiration.AsTime().Before(time.Now())) - assert.True(s.T(), listedAfterExpirePreAuthKeys[1].Expiration.AsTime().Before(time.Now())) - assert.True(s.T(), listedAfterExpirePreAuthKeys[2].Expiration.AsTime().Before(time.Now())) - assert.True(s.T(), listedAfterExpirePreAuthKeys[3].Expiration.AsTime().After(time.Now())) - assert.True(s.T(), listedAfterExpirePreAuthKeys[4].Expiration.AsTime().After(time.Now())) + assert.True( + s.T(), + listedAfterExpirePreAuthKeys[0].Expiration.AsTime().Before(time.Now()), + ) + assert.True( + s.T(), + listedAfterExpirePreAuthKeys[1].Expiration.AsTime().Before(time.Now()), + ) + assert.True( + s.T(), + listedAfterExpirePreAuthKeys[2].Expiration.AsTime().Before(time.Now()), + ) + assert.True( + s.T(), + listedAfterExpirePreAuthKeys[3].Expiration.AsTime().After(time.Now()), + ) + assert.True( + s.T(), + listedAfterExpirePreAuthKeys[4].Expiration.AsTime().After(time.Now()), + ) } func (s *IntegrationCLITestSuite) TestPreAuthKeyCommandWithoutExpiry() { @@ -689,7 +722,10 @@ func (s *IntegrationCLITestSuite) TestNodeCommand() { assert.Nil(s.T(), err) var listOnlySharedMachineNamespace []v1.Machine - err = json.Unmarshal([]byte(listOnlySharedMachineNamespaceResult), &listOnlySharedMachineNamespace) + err = json.Unmarshal( + []byte(listOnlySharedMachineNamespaceResult), + &listOnlySharedMachineNamespace, + ) assert.Nil(s.T(), err) assert.Len(s.T(), listOnlySharedMachineNamespace, 2) @@ -738,7 +774,10 @@ func (s *IntegrationCLITestSuite) TestNodeCommand() { assert.Nil(s.T(), err) var listOnlyMachineNamespaceAfterDelete []v1.Machine - err = json.Unmarshal([]byte(listOnlyMachineNamespaceAfterDeleteResult), &listOnlyMachineNamespaceAfterDelete) + err = json.Unmarshal( + []byte(listOnlyMachineNamespaceAfterDeleteResult), + &listOnlyMachineNamespaceAfterDelete, + ) assert.Nil(s.T(), err) assert.Len(s.T(), listOnlyMachineNamespaceAfterDelete, 4) @@ -789,7 +828,10 @@ func (s *IntegrationCLITestSuite) TestNodeCommand() { assert.Nil(s.T(), err) var listOnlyMachineNamespaceAfterShare []v1.Machine - err = json.Unmarshal([]byte(listOnlyMachineNamespaceAfterShareResult), &listOnlyMachineNamespaceAfterShare) + err = json.Unmarshal( + []byte(listOnlyMachineNamespaceAfterShareResult), + &listOnlyMachineNamespaceAfterShare, + ) assert.Nil(s.T(), err) assert.Len(s.T(), listOnlyMachineNamespaceAfterShare, 5) @@ -846,7 +888,10 @@ func (s *IntegrationCLITestSuite) TestNodeCommand() { assert.Nil(s.T(), err) var listOnlyMachineNamespaceAfterUnshare []v1.Machine - err = json.Unmarshal([]byte(listOnlyMachineNamespaceAfterUnshareResult), &listOnlyMachineNamespaceAfterUnshare) + err = json.Unmarshal( + []byte(listOnlyMachineNamespaceAfterUnshareResult), + &listOnlyMachineNamespaceAfterUnshare, + ) assert.Nil(s.T(), err) assert.Len(s.T(), listOnlyMachineNamespaceAfterUnshare, 4) @@ -1010,5 +1055,9 @@ func (s *IntegrationCLITestSuite) TestRouteCommand() { ) assert.Nil(s.T(), err) - assert.Contains(s.T(), string(failEnableNonAdvertisedRoute), "route (route-machine) is not available on node") + assert.Contains( + s.T(), + string(failEnableNonAdvertisedRoute), + "route (route-machine) is not available on node", + ) } diff --git a/integration_common_test.go b/integration_common_test.go index 71d48669..6540012b 100644 --- a/integration_common_test.go +++ b/integration_common_test.go @@ -12,7 +12,11 @@ import ( "github.com/ory/dockertest/v3/docker" ) -func ExecuteCommand(resource *dockertest.Resource, cmd []string, env []string) (string, error) { +func ExecuteCommand( + resource *dockertest.Resource, + cmd []string, + env []string, +) (string, error) { var stdout bytes.Buffer var stderr bytes.Buffer diff --git a/integration_test.go b/integration_test.go index c4f6bb41..dc5a83c2 100644 --- a/integration_test.go +++ b/integration_test.go @@ -89,7 +89,10 @@ func TestIntegrationTestSuite(t *testing.T) { } } -func (s *IntegrationTestSuite) saveLog(resource *dockertest.Resource, basePath string) error { +func (s *IntegrationTestSuite) saveLog( + resource *dockertest.Resource, + basePath string, +) error { err := os.MkdirAll(basePath, os.ModePerm) if err != nil { return err @@ -118,12 +121,20 @@ func (s *IntegrationTestSuite) saveLog(resource *dockertest.Resource, basePath s fmt.Printf("Saving logs for %s to %s\n", resource.Container.Name, basePath) - err = ioutil.WriteFile(path.Join(basePath, resource.Container.Name+".stdout.log"), []byte(stdout.String()), 0o644) + err = ioutil.WriteFile( + path.Join(basePath, resource.Container.Name+".stdout.log"), + []byte(stdout.String()), + 0o644, + ) if err != nil { return err } - err = ioutil.WriteFile(path.Join(basePath, resource.Container.Name+".stderr.log"), []byte(stdout.String()), 0o644) + err = ioutil.WriteFile( + path.Join(basePath, resource.Container.Name+".stderr.log"), + []byte(stdout.String()), + 0o644, + ) if err != nil { return err } @@ -144,14 +155,27 @@ func (s *IntegrationTestSuite) tailscaleContainer( }, }, } - hostname := fmt.Sprintf("%s-tailscale-%s-%s", namespace, strings.Replace(version, ".", "-", -1), identifier) + hostname := fmt.Sprintf( + "%s-tailscale-%s-%s", + namespace, + strings.Replace(version, ".", "-", -1), + identifier, + ) tailscaleOptions := &dockertest.RunOptions{ Name: hostname, Networks: []*dockertest.Network{&s.network}, - Cmd: []string{"tailscaled", "--tun=userspace-networking", "--socks5-server=localhost:1055"}, + Cmd: []string{ + "tailscaled", + "--tun=userspace-networking", + "--socks5-server=localhost:1055", + }, } - pts, err := s.pool.BuildAndRunWithBuildOptions(tailscaleBuildOptions, tailscaleOptions, DockerRestartPolicy) + pts, err := s.pool.BuildAndRunWithBuildOptions( + tailscaleBuildOptions, + tailscaleOptions, + DockerRestartPolicy, + ) if err != nil { log.Fatalf("Could not start resource: %s", err) } @@ -210,7 +234,11 @@ func (s *IntegrationTestSuite) SetupSuite() { for i := 0; i < scales.count; i++ { version := tailscaleVersions[i%len(tailscaleVersions)] - hostname, container := s.tailscaleContainer(namespace, fmt.Sprint(i), version) + hostname, container := s.tailscaleContainer( + namespace, + fmt.Sprint(i), + version, + ) scales.tailscales[hostname] = *container } } @@ -273,7 +301,10 @@ func (s *IntegrationTestSuite) SetupSuite() { headscaleEndpoint := "http://headscale:8080" - fmt.Printf("Joining tailscale containers to headscale at %s\n", headscaleEndpoint) + fmt.Printf( + "Joining tailscale containers to headscale at %s\n", + headscaleEndpoint, + ) for hostname, tailscale := range scales.tailscales { command := []string{ "tailscale", @@ -307,7 +338,10 @@ func (s *IntegrationTestSuite) SetupSuite() { func (s *IntegrationTestSuite) TearDownSuite() { } -func (s *IntegrationTestSuite) HandleStats(suiteName string, stats *suite.SuiteInformation) { +func (s *IntegrationTestSuite) HandleStats( + suiteName string, + stats *suite.SuiteInformation, +) { s.stats = stats } @@ -427,7 +461,13 @@ func (s *IntegrationTestSuite) TestPingAllPeers() { ip.String(), } - fmt.Printf("Pinging from %s (%s) to %s (%s)\n", hostname, ips[hostname], peername, ip) + fmt.Printf( + "Pinging from %s (%s) to %s (%s)\n", + hostname, + ips[hostname], + peername, + ip, + ) result, err := ExecuteCommand( &tailscale, command, @@ -449,7 +489,15 @@ func (s *IntegrationTestSuite) TestSharedNodes() { result, err := ExecuteCommand( &s.headscale, - []string{"headscale", "nodes", "list", "--output", "json", "--namespace", "shared"}, + []string{ + "headscale", + "nodes", + "list", + "--output", + "json", + "--namespace", + "shared", + }, []string{}, ) assert.Nil(s.T(), err) @@ -520,7 +568,13 @@ func (s *IntegrationTestSuite) TestSharedNodes() { ip.String(), } - fmt.Printf("Pinging from %s (%s) to %s (%s)\n", hostname, mainIps[hostname], peername, ip) + fmt.Printf( + "Pinging from %s (%s) to %s (%s)\n", + hostname, + mainIps[hostname], + peername, + ip, + ) result, err := ExecuteCommand( &tailscale, command, @@ -578,9 +632,19 @@ func (s *IntegrationTestSuite) TestTailDrop() { "PUT", "--upload-file", fmt.Sprintf("/tmp/file_from_%s", hostname), - fmt.Sprintf("%s/v0/put/file_from_%s", peerAPI, hostname), + fmt.Sprintf( + "%s/v0/put/file_from_%s", + peerAPI, + hostname, + ), } - fmt.Printf("Sending file from %s (%s) to %s (%s)\n", hostname, ips[hostname], peername, ip) + fmt.Printf( + "Sending file from %s (%s) to %s (%s)\n", + hostname, + ips[hostname], + peername, + ip, + ) _, err = ExecuteCommand( &tailscale, command, @@ -621,7 +685,13 @@ func (s *IntegrationTestSuite) TestTailDrop() { "ls", fmt.Sprintf("/tmp/file_from_%s", peername), } - fmt.Printf("Checking file in %s (%s) from %s (%s)\n", hostname, ips[hostname], peername, ip) + fmt.Printf( + "Checking file in %s (%s) from %s (%s)\n", + hostname, + ips[hostname], + peername, + ip, + ) result, err := ExecuteCommand( &tailscale, command, @@ -629,7 +699,11 @@ func (s *IntegrationTestSuite) TestTailDrop() { ) assert.Nil(t, err) fmt.Printf("Result for %s: %s\n", peername, result) - assert.Equal(t, result, fmt.Sprintf("/tmp/file_from_%s\n", peername)) + assert.Equal( + t, + result, + fmt.Sprintf("/tmp/file_from_%s\n", peername), + ) } }) } @@ -699,7 +773,9 @@ func getIPs(tailscales map[string]dockertest.Resource) (map[string]netaddr.IP, e return ips, nil } -func getAPIURLs(tailscales map[string]dockertest.Resource) (map[netaddr.IP]string, error) { +func getAPIURLs( + tailscales map[string]dockertest.Resource, +) (map[netaddr.IP]string, error) { fts := make(map[netaddr.IP]string) for _, tailscale := range tailscales { command := []string{ diff --git a/machine.go b/machine.go index 557ab5b6..d0c07d02 100644 --- a/machine.go +++ b/machine.go @@ -73,8 +73,12 @@ func (m Machine) isExpired() bool { func (h *Headscale) updateMachineExpiry(m *Machine) { if m.isExpired() { now := time.Now().UTC() - maxExpiry := now.Add(h.cfg.MaxMachineRegistrationDuration) // calculate the maximum expiry - defaultExpiry := now.Add(h.cfg.DefaultMachineRegistrationDuration) // calculate the default expiry + maxExpiry := now.Add( + h.cfg.MaxMachineRegistrationDuration, + ) // calculate the maximum expiry + defaultExpiry := now.Add( + h.cfg.DefaultMachineRegistrationDuration, + ) // calculate the default expiry // clamp the expiry time of the machine registration to the maximum allowed, or use the default if none supplied if maxExpiry.Before(*m.RequestedExpiry) { @@ -157,7 +161,9 @@ func (h *Headscale) getSharedTo(m *Machine) (Machines, error) { peers := make(Machines, 0) for _, sharedMachine := range sharedMachines { - namespaceMachines, err := h.ListMachinesInNamespace(sharedMachine.Namespace.Name) + namespaceMachines, err := h.ListMachinesInNamespace( + sharedMachine.Namespace.Name, + ) if err != nil { return Machines{}, err } @@ -392,7 +398,11 @@ func (ms Machines) toNodes( // toNode converts a Machine into a Tailscale Node. includeRoutes is false for shared nodes // as per the expected behaviour in the official SaaS -func (m Machine) toNode(baseDomain string, dnsConfig *tailcfg.DNSConfig, includeRoutes bool) (*tailcfg.Node, error) { +func (m Machine) toNode( + baseDomain string, + dnsConfig *tailcfg.DNSConfig, + includeRoutes bool, +) (*tailcfg.Node, error) { nKey, err := wgkey.ParseHex(m.NodeKey) if err != nil { return nil, err @@ -425,7 +435,10 @@ func (m Machine) toNode(baseDomain string, dnsConfig *tailcfg.DNSConfig, include addrs = append(addrs, ip) // missing the ipv6 ? allowedIPs := []netaddr.IPPrefix{} - allowedIPs = append(allowedIPs, ip) // we append the node own IP, as it is required by the clients + allowedIPs = append( + allowedIPs, + ip, + ) // we append the node own IP, as it is required by the clients if includeRoutes { routesStr := []string{} @@ -571,7 +584,10 @@ func (h *Headscale) RegisterMachine(key string, namespace string) (*Machine, err } m := Machine{} - if result := h.db.First(&m, "machine_key = ?", mKey.HexString()); errors.Is(result.Error, gorm.ErrRecordNotFound) { + if result := h.db.First(&m, "machine_key = ?", mKey.HexString()); errors.Is( + result.Error, + gorm.ErrRecordNotFound, + ) { return nil, errors.New("Machine not found") } @@ -693,7 +709,11 @@ func (h *Headscale) EnableRoutes(m *Machine, routeStrs ...string) error { for _, newRoute := range newRoutes { if !containsIpPrefix(availableRoutes, newRoute) { - return fmt.Errorf("route (%s) is not available on node %s", m.Name, newRoute) + return fmt.Errorf( + "route (%s) is not available on node %s", + m.Name, + newRoute, + ) } } diff --git a/metrics.go b/metrics.go index 0d3dca34..f0ce16ec 100644 --- a/metrics.go +++ b/metrics.go @@ -32,7 +32,7 @@ var ( Name: "update_request_sent_to_node_total", Help: "The number of calls/messages issued on a specific nodes update channel", }, []string{"namespace", "machine", "status"}) - //TODO(kradalby): This is very debugging, we might want to remove it. + // TODO(kradalby): This is very debugging, we might want to remove it. updateRequestsReceivedOnChannel = promauto.NewCounterVec(prometheus.CounterOpts{ Namespace: prometheusNamespace, Name: "update_request_received_on_channel_total", diff --git a/namespaces.go b/namespaces.go index 66deb1a2..59a8e2ed 100644 --- a/namespaces.go +++ b/namespaces.go @@ -102,7 +102,10 @@ func (h *Headscale) RenameNamespace(oldName, newName string) error { // GetNamespace fetches a namespace by name func (h *Headscale) GetNamespace(name string) (*Namespace, error) { n := Namespace{} - if result := h.db.First(&n, "name = ?", name); errors.Is(result.Error, gorm.ErrRecordNotFound) { + if result := h.db.First(&n, "name = ?", name); errors.Is( + result.Error, + gorm.ErrRecordNotFound, + ) { return nil, errorNamespaceNotFound } return &n, nil @@ -144,7 +147,9 @@ func (h *Headscale) ListSharedMachinesInNamespace(name string) ([]Machine, error machines := []Machine{} for _, sharedMachine := range sharedMachines { - machine, err := h.GetMachineByID(sharedMachine.MachineID) // otherwise not everything comes filled + machine, err := h.GetMachineByID( + sharedMachine.MachineID, + ) // otherwise not everything comes filled if err != nil { return nil, err } @@ -173,7 +178,10 @@ func (h *Headscale) RequestMapUpdates(namespaceID uint) error { v, err := h.getValue("namespaces_pending_updates") if err != nil || v == "" { - err = h.setValue("namespaces_pending_updates", fmt.Sprintf(`["%s"]`, namespace.Name)) + err = h.setValue( + "namespaces_pending_updates", + fmt.Sprintf(`["%s"]`, namespace.Name), + ) if err != nil { return err } @@ -182,7 +190,10 @@ func (h *Headscale) RequestMapUpdates(namespaceID uint) error { names := []string{} err = json.Unmarshal([]byte(v), &names) if err != nil { - err = h.setValue("namespaces_pending_updates", fmt.Sprintf(`["%s"]`, namespace.Name)) + err = h.setValue( + "namespaces_pending_updates", + fmt.Sprintf(`["%s"]`, namespace.Name), + ) if err != nil { return err } diff --git a/oidc.go b/oidc.go index 51c443db..c3f7c2e2 100644 --- a/oidc.go +++ b/oidc.go @@ -39,8 +39,11 @@ func (h *Headscale) initOIDC() error { ClientID: h.cfg.OIDC.ClientID, ClientSecret: h.cfg.OIDC.ClientSecret, Endpoint: h.oidcProvider.Endpoint(), - RedirectURL: fmt.Sprintf("%s/oidc/callback", strings.TrimSuffix(h.cfg.ServerURL, "/")), - Scopes: []string{oidc.ScopeOpenID, "profile", "email"}, + RedirectURL: fmt.Sprintf( + "%s/oidc/callback", + strings.TrimSuffix(h.cfg.ServerURL, "/"), + ), + Scopes: []string{oidc.ScopeOpenID, "profile", "email"}, } } @@ -127,7 +130,10 @@ func (h *Headscale) OIDCCallback(c *gin.Context) { // Extract custom claims var claims IDTokenClaims if err = idToken.Claims(&claims); err != nil { - c.String(http.StatusBadRequest, fmt.Sprintf("Failed to decode id token claims: %s", err)) + c.String( + http.StatusBadRequest, + fmt.Sprintf("Failed to decode id token claims: %s", err), + ) return } @@ -135,7 +141,8 @@ func (h *Headscale) OIDCCallback(c *gin.Context) { mKeyIf, mKeyFound := h.oidcStateCache.Get(state) if !mKeyFound { - log.Error().Msg("requested machine state key expired before authorisation completed") + log.Error(). + Msg("requested machine state key expired before authorisation completed") c.String(http.StatusBadRequest, "state has expired") return } @@ -151,7 +158,10 @@ func (h *Headscale) OIDCCallback(c *gin.Context) { m, err := h.GetMachineByMachineKey(mKeyStr) if err != nil { log.Error().Msg("machine key not found in database") - c.String(http.StatusInternalServerError, "could not get machine info from database") + c.String( + http.StatusInternalServerError, + "could not get machine info from database", + ) return } @@ -168,15 +178,22 @@ func (h *Headscale) OIDCCallback(c *gin.Context) { ns, err = h.CreateNamespace(nsName) if err != nil { - log.Error().Msgf("could not create new namespace '%s'", claims.Email) - c.String(http.StatusInternalServerError, "could not create new namespace") + log.Error(). + Msgf("could not create new namespace '%s'", claims.Email) + c.String( + http.StatusInternalServerError, + "could not create new namespace", + ) return } } ip, err := h.getAvailableIP() if err != nil { - c.String(http.StatusInternalServerError, "could not get an IP from the pool") + c.String( + http.StatusInternalServerError, + "could not get an IP from the pool", + ) return } @@ -209,7 +226,10 @@ func (h *Headscale) OIDCCallback(c *gin.Context) { Str("username", claims.Username). Str("machine", m.Name). Msg("Email could not be mapped to a namespace") - c.String(http.StatusBadRequest, "email from claim could not be mapped to a namespace") + c.String( + http.StatusBadRequest, + "email from claim could not be mapped to a namespace", + ) } // getNamespaceFromEmail passes the users email through a list of "matchers" diff --git a/oidc_test.go b/oidc_test.go index c7a29ce9..6b019245 100644 --- a/oidc_test.go +++ b/oidc_test.go @@ -164,10 +164,18 @@ func TestHeadscale_getNamespaceFromEmail(t *testing.T) { } got, got1 := h.getNamespaceFromEmail(tt.args.email) if got != tt.want { - t.Errorf("Headscale.getNamespaceFromEmail() got = %v, want %v", got, tt.want) + t.Errorf( + "Headscale.getNamespaceFromEmail() got = %v, want %v", + got, + tt.want, + ) } if got1 != tt.want1 { - t.Errorf("Headscale.getNamespaceFromEmail() got1 = %v, want %v", got1, tt.want1) + t.Errorf( + "Headscale.getNamespaceFromEmail() got1 = %v, want %v", + got1, + tt.want1, + ) } }) } diff --git a/poll.go b/poll.go index 6a652805..038192f2 100644 --- a/poll.go +++ b/poll.go @@ -158,7 +158,8 @@ func (h *Headscale) PollNetMapHandler(c *gin.Context) { // It sounds like we should update the nodes when we have received a endpoint update // even tho the comments in the tailscale code dont explicitly say so. - updateRequestsFromNode.WithLabelValues(m.Name, m.Namespace.Name, "endpoint-update").Inc() + updateRequestsFromNode.WithLabelValues(m.Name, m.Namespace.Name, "endpoint-update"). + Inc() go func() { updateChan <- struct{}{} }() return } else if req.OmitPeers && req.Stream { @@ -184,10 +185,20 @@ func (h *Headscale) PollNetMapHandler(c *gin.Context) { Str("handler", "PollNetMap"). Str("machine", m.Name). Msg("Notifying peers") - updateRequestsFromNode.WithLabelValues(m.Name, m.Namespace.Name, "full-update").Inc() + updateRequestsFromNode.WithLabelValues(m.Name, m.Namespace.Name, "full-update"). + Inc() go func() { updateChan <- struct{}{} }() - h.PollNetMapStream(c, m, req, mKey, pollDataChan, keepAliveChan, updateChan, cancelKeepAlive) + h.PollNetMapStream( + c, + m, + req, + mKey, + pollDataChan, + keepAliveChan, + updateChan, + cancelKeepAlive, + ) log.Trace(). Str("handler", "PollNetMap"). Str("id", c.Param("id")). @@ -260,7 +271,8 @@ func (h *Headscale) PollNetMapStream( now := time.Now().UTC() m.LastSeen = &now - lastStateUpdate.WithLabelValues(m.Namespace.Name, m.Name).Set(float64(now.Unix())) + lastStateUpdate.WithLabelValues(m.Namespace.Name, m.Name). + Set(float64(now.Unix())) m.LastSuccessfulUpdate = &now h.db.Save(&m) @@ -324,7 +336,8 @@ func (h *Headscale) PollNetMapStream( Str("machine", m.Name). Str("channel", "update"). Msg("Received a request for update") - updateRequestsReceivedOnChannel.WithLabelValues(m.Name, m.Namespace.Name).Inc() + updateRequestsReceivedOnChannel.WithLabelValues(m.Name, m.Namespace.Name). + Inc() if h.isOutdated(m) { log.Debug(). Str("handler", "PollNetMapStream"). @@ -349,7 +362,8 @@ func (h *Headscale) PollNetMapStream( Str("channel", "update"). Err(err). Msg("Could not write the map response") - updateRequestsSentToNode.WithLabelValues(m.Name, m.Namespace.Name, "failed").Inc() + updateRequestsSentToNode.WithLabelValues(m.Name, m.Namespace.Name, "failed"). + Inc() return false } log.Trace(). @@ -357,7 +371,8 @@ func (h *Headscale) PollNetMapStream( Str("machine", m.Name). Str("channel", "update"). Msg("Updated Map has been sent") - updateRequestsSentToNode.WithLabelValues(m.Name, m.Namespace.Name, "success").Inc() + updateRequestsSentToNode.WithLabelValues(m.Name, m.Namespace.Name, "success"). + Inc() // Keep track of the last successful update, // we sometimes end in a state were the update @@ -377,7 +392,8 @@ func (h *Headscale) PollNetMapStream( } now := time.Now().UTC() - lastStateUpdate.WithLabelValues(m.Namespace.Name, m.Name).Set(float64(now.Unix())) + lastStateUpdate.WithLabelValues(m.Namespace.Name, m.Name). + Set(float64(now.Unix())) m.LastSuccessfulUpdate = &now h.db.Save(&m) @@ -424,7 +440,7 @@ func (h *Headscale) PollNetMapStream( Str("machine", m.Name). Str("channel", "Done"). Msg("Closing update channel") - //h.closeUpdateChannel(m) + // h.closeUpdateChannel(m) close(updateChan) log.Trace(). @@ -483,7 +499,8 @@ func (h *Headscale) scheduledPollWorker( Str("func", "scheduledPollWorker"). Str("machine", m.Name). Msg("Sending update request") - updateRequestsFromNode.WithLabelValues(m.Name, m.Namespace.Name, "scheduled-update").Inc() + updateRequestsFromNode.WithLabelValues(m.Name, m.Namespace.Name, "scheduled-update"). + Inc() updateChan <- struct{}{} } } diff --git a/preauth_keys.go b/preauth_keys.go index 1cb9c112..68664c17 100644 --- a/preauth_keys.go +++ b/preauth_keys.go @@ -105,7 +105,10 @@ func (h *Headscale) ExpirePreAuthKey(k *PreAuthKey) error { // If returns no error and a PreAuthKey, it can be used func (h *Headscale) checkKeyValidity(k string) (*PreAuthKey, error) { pak := PreAuthKey{} - if result := h.db.Preload("Namespace").First(&pak, "key = ?", k); errors.Is(result.Error, gorm.ErrRecordNotFound) { + if result := h.db.Preload("Namespace").First(&pak, "key = ?", k); errors.Is( + result.Error, + gorm.ErrRecordNotFound, + ) { return nil, errorAuthKeyNotFound } diff --git a/routes.go b/routes.go index f07b709a..84f8dfe4 100644 --- a/routes.go +++ b/routes.go @@ -11,7 +11,10 @@ import ( // Deprecated: use machine function instead // GetAdvertisedNodeRoutes returns the subnet routes advertised by a node (identified by // namespace and node name) -func (h *Headscale) GetAdvertisedNodeRoutes(namespace string, nodeName string) (*[]netaddr.IPPrefix, error) { +func (h *Headscale) GetAdvertisedNodeRoutes( + namespace string, + nodeName string, +) (*[]netaddr.IPPrefix, error) { m, err := h.GetMachine(namespace, nodeName) if err != nil { return nil, err @@ -27,7 +30,10 @@ func (h *Headscale) GetAdvertisedNodeRoutes(namespace string, nodeName string) ( // Deprecated: use machine function instead // GetEnabledNodeRoutes returns the subnet routes enabled by a node (identified by // namespace and node name) -func (h *Headscale) GetEnabledNodeRoutes(namespace string, nodeName string) ([]netaddr.IPPrefix, error) { +func (h *Headscale) GetEnabledNodeRoutes( + namespace string, + nodeName string, +) ([]netaddr.IPPrefix, error) { m, err := h.GetMachine(namespace, nodeName) if err != nil { return nil, err @@ -58,7 +64,11 @@ func (h *Headscale) GetEnabledNodeRoutes(namespace string, nodeName string) ([]n // Deprecated: use machine function instead // IsNodeRouteEnabled checks if a certain route has been enabled -func (h *Headscale) IsNodeRouteEnabled(namespace string, nodeName string, routeStr string) bool { +func (h *Headscale) IsNodeRouteEnabled( + namespace string, + nodeName string, + routeStr string, +) bool { route, err := netaddr.ParseIPPrefix(routeStr) if err != nil { return false @@ -80,7 +90,11 @@ func (h *Headscale) IsNodeRouteEnabled(namespace string, nodeName string, routeS // Deprecated: use EnableRoute in machine.go // EnableNodeRoute enables a subnet route advertised by a node (identified by // namespace and node name) -func (h *Headscale) EnableNodeRoute(namespace string, nodeName string, routeStr string) error { +func (h *Headscale) EnableNodeRoute( + namespace string, + nodeName string, + routeStr string, +) error { m, err := h.GetMachine(namespace, nodeName) if err != nil { return err diff --git a/routes_test.go b/routes_test.go index ad16d21c..a120eda6 100644 --- a/routes_test.go +++ b/routes_test.go @@ -93,7 +93,10 @@ func (s *Suite) TestGetEnableRoutes(c *check.C) { } h.db.Save(&m) - availableRoutes, err := h.GetAdvertisedNodeRoutes("test", "test_enable_route_machine") + availableRoutes, err := h.GetAdvertisedNodeRoutes( + "test", + "test_enable_route_machine", + ) c.Assert(err, check.IsNil) c.Assert(len(*availableRoutes), check.Equals, 2) diff --git a/sharing.go b/sharing.go index 5f6a8f45..581c2af4 100644 --- a/sharing.go +++ b/sharing.go @@ -2,9 +2,11 @@ package headscale import "gorm.io/gorm" -const errorSameNamespace = Error("Destination namespace same as origin") -const errorMachineAlreadyShared = Error("Node already shared to this namespace") -const errorMachineNotShared = Error("Machine not shared to this namespace") +const ( + errorSameNamespace = Error("Destination namespace same as origin") + errorMachineAlreadyShared = Error("Node already shared to this namespace") + errorMachineNotShared = Error("Machine not shared to this namespace") +) // SharedMachine is a join table to support sharing nodes between namespaces type SharedMachine struct { @@ -48,7 +50,9 @@ func (h *Headscale) RemoveSharedMachineFromNamespace(m *Machine, ns *Namespace) } sharedMachine := SharedMachine{} - result := h.db.Where("machine_id = ? AND namespace_id = ?", m.ID, ns.ID).Unscoped().Delete(&sharedMachine) + result := h.db.Where("machine_id = ? AND namespace_id = ?", m.ID, ns.ID). + Unscoped(). + Delete(&sharedMachine) if result.Error != nil { return result.Error } diff --git a/sharing_test.go b/sharing_test.go index 4d9e4092..7d63a745 100644 --- a/sharing_test.go +++ b/sharing_test.go @@ -4,7 +4,10 @@ import ( "gopkg.in/check.v1" ) -func CreateNodeNamespace(c *check.C, namespace, node, key, IP string) (*Namespace, *Machine) { +func CreateNodeNamespace( + c *check.C, + namespace, node, key, IP string, +) (*Namespace, *Machine) { n1, err := h.CreateNamespace(namespace) c.Assert(err, check.IsNil) @@ -229,7 +232,11 @@ func (s *Suite) TestComplexSharingAcrossNamespaces(c *check.C) { p1sAfter, err := h.getPeers(m1) c.Assert(err, check.IsNil) - c.Assert(len(p1sAfter), check.Equals, 2) // node1 can see node2 (shared) and node4 (same namespace) + c.Assert( + len(p1sAfter), + check.Equals, + 2, + ) // node1 can see node2 (shared) and node4 (same namespace) c.Assert(p1sAfter[0].Name, check.Equals, m2.Name) c.Assert(p1sAfter[1].Name, check.Equals, m4.Name) diff --git a/swagger.go b/swagger.go index 17f57697..d3ae1b2d 100644 --- a/swagger.go +++ b/swagger.go @@ -53,7 +53,11 @@ func SwaggerUI(c *gin.Context) { Caller(). Err(err). Msg("Could not render Swagger") - c.Data(http.StatusInternalServerError, "text/html; charset=utf-8", []byte("Could not render Swagger")) + c.Data( + http.StatusInternalServerError, + "text/html; charset=utf-8", + []byte("Could not render Swagger"), + ) return } diff --git a/utils.go b/utils.go index ad0a72d7..0b76b5e9 100644 --- a/utils.go +++ b/utils.go @@ -25,11 +25,21 @@ type Error string func (e Error) Error() string { return string(e) } -func decode(msg []byte, v interface{}, pubKey *wgkey.Key, privKey *wgkey.Private) error { +func decode( + msg []byte, + v interface{}, + pubKey *wgkey.Key, + privKey *wgkey.Private, +) error { return decodeMsg(msg, v, pubKey, privKey) } -func decodeMsg(msg []byte, v interface{}, pubKey *wgkey.Key, privKey *wgkey.Private) error { +func decodeMsg( + msg []byte, + v interface{}, + pubKey *wgkey.Key, + privKey *wgkey.Private, +) error { decrypted, err := decryptMsg(msg, pubKey, privKey) if err != nil { return err @@ -156,7 +166,11 @@ func tailNodesToString(nodes []*tailcfg.Node) string { } func tailMapResponseToString(resp tailcfg.MapResponse) string { - return fmt.Sprintf("{ Node: %s, Peers: %s }", resp.Node.Name, tailNodesToString(resp.Peers)) + return fmt.Sprintf( + "{ Node: %s, Peers: %s }", + resp.Node.Name, + tailNodesToString(resp.Peers), + ) } func GrpcSocketDialer(ctx context.Context, addr string) (net.Conn, error) { From dae34ca8c559d008f8e7078841a3a8ed2536a5aa Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Sat, 13 Nov 2021 08:36:56 +0000 Subject: [PATCH 119/300] Proto format --- proto/headscale/v1/headscale.proto | 110 ++++++++++++++--------------- 1 file changed, 55 insertions(+), 55 deletions(-) diff --git a/proto/headscale/v1/headscale.proto b/proto/headscale/v1/headscale.proto index 26fe2f96..e7a63fc5 100644 --- a/proto/headscale/v1/headscale.proto +++ b/proto/headscale/v1/headscale.proto @@ -12,115 +12,115 @@ import "headscale/v1/routes.proto"; service HeadscaleService { // --- Namespace start --- - rpc GetNamespace(GetNamespaceRequest) returns(GetNamespaceResponse) { - option(google.api.http) = { - get : "/api/v1/namespace/{name}" + rpc GetNamespace(GetNamespaceRequest) returns (GetNamespaceResponse) { + option (google.api.http) = { + get: "/api/v1/namespace/{name}" }; } - rpc CreateNamespace(CreateNamespaceRequest) returns(CreateNamespaceResponse) { - option(google.api.http) = { - post : "/api/v1/namespace" - body : "*" + rpc CreateNamespace(CreateNamespaceRequest) returns (CreateNamespaceResponse) { + option (google.api.http) = { + post: "/api/v1/namespace" + body: "*" }; } - rpc RenameNamespace(RenameNamespaceRequest) returns(RenameNamespaceResponse) { - option(google.api.http) = { - post : "/api/v1/namespace/{old_name}/rename/{new_name}" + rpc RenameNamespace(RenameNamespaceRequest) returns (RenameNamespaceResponse) { + option (google.api.http) = { + post: "/api/v1/namespace/{old_name}/rename/{new_name}" }; } - rpc DeleteNamespace(DeleteNamespaceRequest) returns(DeleteNamespaceResponse) { - option(google.api.http) = { - delete : "/api/v1/namespace/{name}" + rpc DeleteNamespace(DeleteNamespaceRequest) returns (DeleteNamespaceResponse) { + option (google.api.http) = { + delete: "/api/v1/namespace/{name}" }; } - rpc ListNamespaces(ListNamespacesRequest) returns(ListNamespacesResponse) { - option(google.api.http) = { - get : "/api/v1/namespace" + rpc ListNamespaces(ListNamespacesRequest) returns (ListNamespacesResponse) { + option (google.api.http) = { + get: "/api/v1/namespace" }; } // --- Namespace end --- // --- PreAuthKeys start --- - rpc CreatePreAuthKey(CreatePreAuthKeyRequest) returns(CreatePreAuthKeyResponse) { - option(google.api.http) = { - post : "/api/v1/preauthkey" - body : "*" + rpc CreatePreAuthKey(CreatePreAuthKeyRequest) returns (CreatePreAuthKeyResponse) { + option (google.api.http) = { + post: "/api/v1/preauthkey" + body: "*" }; } - rpc ExpirePreAuthKey(ExpirePreAuthKeyRequest) returns(ExpirePreAuthKeyResponse) { - option(google.api.http) = { - post : "/api/v1/preauthkey/expire" - body : "*" + rpc ExpirePreAuthKey(ExpirePreAuthKeyRequest) returns (ExpirePreAuthKeyResponse) { + option (google.api.http) = { + post: "/api/v1/preauthkey/expire" + body: "*" }; } - rpc ListPreAuthKeys(ListPreAuthKeysRequest) returns(ListPreAuthKeysResponse) { - option(google.api.http) = { - get : "/api/v1/preauthkey" + rpc ListPreAuthKeys(ListPreAuthKeysRequest) returns (ListPreAuthKeysResponse) { + option (google.api.http) = { + get: "/api/v1/preauthkey" }; } // --- PreAuthKeys end --- // --- Machine start --- - rpc DebugCreateMachine(DebugCreateMachineRequest) returns(DebugCreateMachineResponse) { - option(google.api.http) = { - post : "/api/v1/debug/machine" - body : "*" + rpc DebugCreateMachine(DebugCreateMachineRequest) returns (DebugCreateMachineResponse) { + option (google.api.http) = { + post: "/api/v1/debug/machine" + body: "*" }; } - rpc GetMachine(GetMachineRequest) returns(GetMachineResponse) { - option(google.api.http) = { - get : "/api/v1/machine/{machine_id}" + rpc GetMachine(GetMachineRequest) returns (GetMachineResponse) { + option (google.api.http) = { + get: "/api/v1/machine/{machine_id}" }; } - rpc RegisterMachine(RegisterMachineRequest) returns(RegisterMachineResponse) { - option(google.api.http) = { - post : "/api/v1/machine/register" + rpc RegisterMachine(RegisterMachineRequest) returns (RegisterMachineResponse) { + option (google.api.http) = { + post: "/api/v1/machine/register" }; } - rpc DeleteMachine(DeleteMachineRequest) returns(DeleteMachineResponse) { - option(google.api.http) = { - delete : "/api/v1/machine/{machine_id}" + rpc DeleteMachine(DeleteMachineRequest) returns (DeleteMachineResponse) { + option (google.api.http) = { + delete: "/api/v1/machine/{machine_id}" }; } - rpc ListMachines(ListMachinesRequest) returns(ListMachinesResponse) { - option(google.api.http) = { - get : "/api/v1/machine" + rpc ListMachines(ListMachinesRequest) returns (ListMachinesResponse) { + option (google.api.http) = { + get: "/api/v1/machine" }; } - rpc ShareMachine(ShareMachineRequest) returns(ShareMachineResponse) { - option(google.api.http) = { - post : "/api/v1/machine/{machine_id}/share/{namespace}" + rpc ShareMachine(ShareMachineRequest) returns (ShareMachineResponse) { + option (google.api.http) = { + post: "/api/v1/machine/{machine_id}/share/{namespace}" }; } - rpc UnshareMachine(UnshareMachineRequest) returns(UnshareMachineResponse) { - option(google.api.http) = { - post : "/api/v1/machine/{machine_id}/unshare/{namespace}" + rpc UnshareMachine(UnshareMachineRequest) returns (UnshareMachineResponse) { + option (google.api.http) = { + post: "/api/v1/machine/{machine_id}/unshare/{namespace}" }; } // --- Machine end --- // --- Route start --- - rpc GetMachineRoute(GetMachineRouteRequest) returns(GetMachineRouteResponse) { - option(google.api.http) = { - get : "/api/v1/machine/{machine_id}/routes" + rpc GetMachineRoute(GetMachineRouteRequest) returns (GetMachineRouteResponse) { + option (google.api.http) = { + get: "/api/v1/machine/{machine_id}/routes" }; } - rpc EnableMachineRoutes(EnableMachineRoutesRequest) returns(EnableMachineRoutesResponse) { - option(google.api.http) = { - post : "/api/v1/machine/{machine_id}/routes" + rpc EnableMachineRoutes(EnableMachineRoutesRequest) returns (EnableMachineRoutesResponse) { + option (google.api.http) = { + post: "/api/v1/machine/{machine_id}/routes" }; } // --- Route end --- From 2634215f125289f65cc101e37f859db1e66e6baa Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Sat, 13 Nov 2021 08:39:04 +0000 Subject: [PATCH 120/300] golangci-lint --fix --- acls.go | 3 +-- acls_types.go | 16 ++++++++-------- api.go | 10 ++++------ app.go | 10 ++++------ apple_mobileconfig.go | 5 ++--- cmd/headscale/cli/routes.go | 2 +- cmd/headscale/cli/utils.go | 1 - db.go | 4 ++-- derp.go | 4 +--- machine.go | 29 ++++++++++++++--------------- namespaces.go | 14 +++++++------- oidc.go | 6 ++---- preauth_keys.go | 15 +++++++-------- routes.go | 8 ++++---- sharing.go | 8 ++++---- swagger.go | 3 +-- utils.go | 1 - 17 files changed, 62 insertions(+), 77 deletions(-) diff --git a/acls.go b/acls.go index 0e01514e..9ce08a11 100644 --- a/acls.go +++ b/acls.go @@ -9,7 +9,6 @@ import ( "strings" "github.com/rs/zerolog/log" - "github.com/tailscale/hujson" "inet.af/netaddr" "tailscale.com/tailcfg" @@ -25,7 +24,7 @@ const ( errorInvalidPortFormat = Error("invalid port format") ) -// LoadACLPolicy loads the ACL policy from the specify path, and generates the ACL rules +// LoadACLPolicy loads the ACL policy from the specify path, and generates the ACL rules. func (h *Headscale) LoadACLPolicy(path string) error { policyFile, err := os.Open(path) if err != nil { diff --git a/acls_types.go b/acls_types.go index 67b74e73..91c9a44e 100644 --- a/acls_types.go +++ b/acls_types.go @@ -8,7 +8,7 @@ import ( "inet.af/netaddr" ) -// ACLPolicy represents a Tailscale ACL Policy +// ACLPolicy represents a Tailscale ACL Policy. type ACLPolicy struct { Groups Groups `json:"Groups"` Hosts Hosts `json:"Hosts"` @@ -17,30 +17,30 @@ type ACLPolicy struct { Tests []ACLTest `json:"Tests"` } -// ACL is a basic rule for the ACL Policy +// ACL is a basic rule for the ACL Policy. type ACL struct { Action string `json:"Action"` Users []string `json:"Users"` Ports []string `json:"Ports"` } -// Groups references a series of alias in the ACL rules +// Groups references a series of alias in the ACL rules. type Groups map[string][]string -// Hosts are alias for IP addresses or subnets +// Hosts are alias for IP addresses or subnets. type Hosts map[string]netaddr.IPPrefix -// TagOwners specify what users (namespaces?) are allow to use certain tags +// TagOwners specify what users (namespaces?) are allow to use certain tags. type TagOwners map[string][]string -// ACLTest is not implemented, but should be use to check if a certain rule is allowed +// ACLTest is not implemented, but should be use to check if a certain rule is allowed. type ACLTest struct { User string `json:"User"` Allow []string `json:"Allow"` Deny []string `json:"Deny,omitempty"` } -// UnmarshalJSON allows to parse the Hosts directly into netaddr objects +// UnmarshalJSON allows to parse the Hosts directly into netaddr objects. func (h *Hosts) UnmarshalJSON(data []byte) error { hosts := Hosts{} hs := make(map[string]string) @@ -68,7 +68,7 @@ func (h *Hosts) UnmarshalJSON(data []byte) error { return nil } -// IsZero is perhaps a bit naive here +// IsZero is perhaps a bit naive here. func (p ACLPolicy) IsZero() bool { if len(p.Groups) == 0 && len(p.Hosts) == 0 && len(p.ACLs) == 0 { return true diff --git a/api.go b/api.go index 25851d84..bd6b80c4 100644 --- a/api.go +++ b/api.go @@ -10,23 +10,22 @@ import ( "strings" "time" - "github.com/rs/zerolog/log" - "github.com/gin-gonic/gin" "github.com/klauspost/compress/zstd" + "github.com/rs/zerolog/log" "gorm.io/gorm" "tailscale.com/tailcfg" "tailscale.com/types/wgkey" ) // KeyHandler provides the Headscale pub key -// Listens in /key +// Listens in /key. func (h *Headscale) KeyHandler(c *gin.Context) { c.Data(200, "text/plain; charset=utf-8", []byte(h.publicKey.HexString())) } // RegisterWebAPI shows a simple message in the browser to point to the CLI -// Listens in /register +// Listens in /register. func (h *Headscale) RegisterWebAPI(c *gin.Context) { mKeyStr := c.Query("key") if mKeyStr == "" { @@ -55,7 +54,7 @@ func (h *Headscale) RegisterWebAPI(c *gin.Context) { } // RegistrationHandler handles the actual registration process of a machine -// Endpoint /machine/:id +// Endpoint /machine/:id. func (h *Headscale) RegistrationHandler(c *gin.Context) { body, _ := io.ReadAll(c.Request.Body) mKeyStr := c.Param("id") @@ -111,7 +110,6 @@ func (h *Headscale) RegistrationHandler(c *gin.Context) { // We have the updated key! if m.NodeKey == wgkey.Key(req.NodeKey).HexString() { - // The client sends an Expiry in the past if the client is requesting to expire the key (aka logout) // https://github.com/tailscale/tailscale/blob/main/tailcfg/tailcfg.go#L648 if !req.Expiry.IsZero() && req.Expiry.UTC().Before(now) { diff --git a/app.go b/app.go index 94181ac7..73fec927 100644 --- a/app.go +++ b/app.go @@ -18,20 +18,19 @@ import ( "time" "github.com/coreos/go-oidc/v3/oidc" - "github.com/patrickmn/go-cache" - "golang.org/x/oauth2" - "github.com/gin-gonic/gin" - "github.com/grpc-ecosystem/go-grpc-middleware" + grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware" "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" v1 "github.com/juanfont/headscale/gen/go/headscale/v1" - "github.com/philip-bui/grpc-zerolog" + "github.com/patrickmn/go-cache" + zerolog "github.com/philip-bui/grpc-zerolog" zl "github.com/rs/zerolog" "github.com/rs/zerolog/log" "github.com/soheilhy/cmux" ginprometheus "github.com/zsais/go-gin-prometheus" "golang.org/x/crypto/acme" "golang.org/x/crypto/acme/autocert" + "golang.org/x/oauth2" "golang.org/x/sync/errgroup" "google.golang.org/grpc" "google.golang.org/grpc/codes" @@ -280,7 +279,6 @@ func (h *Headscale) grpcAuthenticationInterceptor(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) { - // Check if the request is coming from the on-server client. // This is not secure, but it is to maintain maintainability // with the "legacy" database-based client diff --git a/apple_mobileconfig.go b/apple_mobileconfig.go index 6ddd5be3..3629daa4 100644 --- a/apple_mobileconfig.go +++ b/apple_mobileconfig.go @@ -5,14 +5,13 @@ import ( "net/http" "text/template" - "github.com/rs/zerolog/log" - "github.com/gin-gonic/gin" "github.com/gofrs/uuid" + "github.com/rs/zerolog/log" ) // AppleMobileConfig shows a simple message in the browser to point to the CLI -// Listens in /register +// Listens in /register. func (h *Headscale) AppleMobileConfig(c *gin.Context) { t := template.Must(template.New("apple").Parse(` diff --git a/cmd/headscale/cli/routes.go b/cmd/headscale/cli/routes.go index e6c80fb1..1a0ff2aa 100644 --- a/cmd/headscale/cli/routes.go +++ b/cmd/headscale/cli/routes.go @@ -171,7 +171,7 @@ omit the route you do not want to enable. }, } -// routesToPtables converts the list of routes to a nice table +// routesToPtables converts the list of routes to a nice table. func routesToPtables(routes *v1.Routes) pterm.TableData { d := pterm.TableData{{"Route", "Enabled"}} diff --git a/cmd/headscale/cli/utils.go b/cmd/headscale/cli/utils.go index 16b236a7..f4463231 100644 --- a/cmd/headscale/cli/utils.go +++ b/cmd/headscale/cli/utils.go @@ -355,7 +355,6 @@ func getHeadscaleCLIClient() (context.Context, v1.HeadscaleServiceClient, *grpc. // If the address is not set, we assume that we are on the server hosting headscale. if address == "" { - log.Debug(). Str("socket", cfg.UnixSocket). Msgf("HEADSCALE_CLI_ADDRESS environment is not set, connecting to unix socket.") diff --git a/db.go b/db.go index 60e2f6f1..d3ef6833 100644 --- a/db.go +++ b/db.go @@ -84,7 +84,7 @@ func (h *Headscale) openDB() (*gorm.DB, error) { return db, nil } -// getValue returns the value for the given key in KV +// getValue returns the value for the given key in KV. func (h *Headscale) getValue(key string) (string, error) { var row KV if result := h.db.First(&row, "key = ?", key); errors.Is( @@ -96,7 +96,7 @@ func (h *Headscale) getValue(key string) (string, error) { return row.Value, nil } -// setValue sets value for the given key in KV +// setValue sets value for the given key in KV. func (h *Headscale) setValue(key string, value string) error { kv := KV{ Key: key, diff --git a/derp.go b/derp.go index 7f65832c..422b1e62 100644 --- a/derp.go +++ b/derp.go @@ -10,9 +10,7 @@ import ( "time" "github.com/rs/zerolog/log" - "gopkg.in/yaml.v2" - "tailscale.com/tailcfg" ) @@ -55,7 +53,7 @@ func loadDERPMapFromURL(addr url.URL) (*tailcfg.DERPMap, error) { // DERPMap, it will _only_ look at the Regions, an integer. // If a region exists in two of the given DERPMaps, the region // form the _last_ DERPMap will be preserved. -// An empty DERPMap list will result in a DERPMap with no regions +// An empty DERPMap list will result in a DERPMap with no regions. func mergeDERPMaps(derpMaps []*tailcfg.DERPMap) *tailcfg.DERPMap { result := tailcfg.DERPMap{ OmitDefaultRegions: false, diff --git a/machine.go b/machine.go index d0c07d02..8ff0b359 100644 --- a/machine.go +++ b/machine.go @@ -10,10 +10,9 @@ import ( "time" "github.com/fatih/set" + v1 "github.com/juanfont/headscale/gen/go/headscale/v1" "github.com/rs/zerolog/log" "google.golang.org/protobuf/types/known/timestamppb" - - v1 "github.com/juanfont/headscale/gen/go/headscale/v1" "gorm.io/datatypes" "gorm.io/gorm" "inet.af/netaddr" @@ -21,7 +20,7 @@ import ( "tailscale.com/types/wgkey" ) -// Machine is a Headscale client +// Machine is a Headscale client. type Machine struct { ID uint64 `gorm:"primary_key"` MachineKey string `gorm:"type:varchar(64);unique_index"` @@ -56,12 +55,12 @@ type ( MachinesP []*Machine ) -// For the time being this method is rather naive +// For the time being this method is rather naive. func (m Machine) isAlreadyRegistered() bool { return m.Registered } -// isExpired returns whether the machine registration has expired +// isExpired returns whether the machine registration has expired. func (m Machine) isExpired() bool { return time.Now().UTC().After(*m.Expiry) } @@ -119,7 +118,7 @@ func (h *Headscale) getDirectPeers(m *Machine) (Machines, error) { return machines, nil } -// getShared fetches machines that are shared to the `Namespace` of the machine we are getting peers for +// getShared fetches machines that are shared to the `Namespace` of the machine we are getting peers for. func (h *Headscale) getShared(m *Machine) (Machines, error) { log.Trace(). Caller(). @@ -146,7 +145,7 @@ func (h *Headscale) getShared(m *Machine) (Machines, error) { return peers, nil } -// getSharedTo fetches the machines of the namespaces this machine is shared in +// getSharedTo fetches the machines of the namespaces this machine is shared in. func (h *Headscale) getSharedTo(m *Machine) (Machines, error) { log.Trace(). Caller(). @@ -228,7 +227,7 @@ func (h *Headscale) ListMachines() ([]Machine, error) { return machines, nil } -// GetMachine finds a Machine by name and namespace and returns the Machine struct +// GetMachine finds a Machine by name and namespace and returns the Machine struct. func (h *Headscale) GetMachine(namespace string, name string) (*Machine, error) { machines, err := h.ListMachinesInNamespace(namespace) if err != nil { @@ -243,7 +242,7 @@ func (h *Headscale) GetMachine(namespace string, name string) (*Machine, error) return nil, fmt.Errorf("machine not found") } -// GetMachineByID finds a Machine by ID and returns the Machine struct +// GetMachineByID finds a Machine by ID and returns the Machine struct. func (h *Headscale) GetMachineByID(id uint64) (*Machine, error) { m := Machine{} if result := h.db.Preload("Namespace").Find(&Machine{ID: id}).First(&m); result.Error != nil { @@ -252,7 +251,7 @@ func (h *Headscale) GetMachineByID(id uint64) (*Machine, error) { return &m, nil } -// GetMachineByMachineKey finds a Machine by ID and returns the Machine struct +// GetMachineByMachineKey finds a Machine by ID and returns the Machine struct. func (h *Headscale) GetMachineByMachineKey(mKey string) (*Machine, error) { m := Machine{} if result := h.db.Preload("Namespace").First(&m, "machine_key = ?", mKey); result.Error != nil { @@ -270,7 +269,7 @@ func (h *Headscale) UpdateMachine(m *Machine) error { return nil } -// DeleteMachine softs deletes a Machine from the database +// DeleteMachine softs deletes a Machine from the database. func (h *Headscale) DeleteMachine(m *Machine) error { err := h.RemoveSharedMachineFromAllNamespaces(m) if err != nil && err != errorMachineNotShared { @@ -287,7 +286,7 @@ func (h *Headscale) DeleteMachine(m *Machine) error { return h.RequestMapUpdates(namespaceID) } -// HardDeleteMachine hard deletes a Machine from the database +// HardDeleteMachine hard deletes a Machine from the database. func (h *Headscale) HardDeleteMachine(m *Machine) error { err := h.RemoveSharedMachineFromAllNamespaces(m) if err != nil && err != errorMachineNotShared { @@ -302,7 +301,7 @@ func (h *Headscale) HardDeleteMachine(m *Machine) error { return h.RequestMapUpdates(namespaceID) } -// GetHostInfo returns a Hostinfo struct for the machine +// GetHostInfo returns a Hostinfo struct for the machine. func (m *Machine) GetHostInfo() (*tailcfg.Hostinfo, error) { hostinfo := tailcfg.Hostinfo{} if len(m.HostInfo) != 0 { @@ -397,7 +396,7 @@ func (ms Machines) toNodes( } // toNode converts a Machine into a Tailscale Node. includeRoutes is false for shared nodes -// as per the expected behaviour in the official SaaS +// as per the expected behaviour in the official SaaS. func (m Machine) toNode( baseDomain string, dnsConfig *tailcfg.DNSConfig, @@ -572,7 +571,7 @@ func (m *Machine) toProto() *v1.Machine { return machine } -// RegisterMachine is executed from the CLI to register a new Machine using its MachineKey +// RegisterMachine is executed from the CLI to register a new Machine using its MachineKey. func (h *Headscale) RegisterMachine(key string, namespace string) (*Machine, error) { ns, err := h.GetNamespace(namespace) if err != nil { diff --git a/namespaces.go b/namespaces.go index 59a8e2ed..d54e117b 100644 --- a/namespaces.go +++ b/namespaces.go @@ -30,7 +30,7 @@ type Namespace struct { } // CreateNamespace creates a new Namespace. Returns error if could not be created -// or another namespace already exists +// or another namespace already exists. func (h *Headscale) CreateNamespace(name string) (*Namespace, error) { n := Namespace{} if err := h.db.Where("name = ?", name).First(&n).Error; err == nil { @@ -99,7 +99,7 @@ func (h *Headscale) RenameNamespace(oldName, newName string) error { return nil } -// GetNamespace fetches a namespace by name +// GetNamespace fetches a namespace by name. func (h *Headscale) GetNamespace(name string) (*Namespace, error) { n := Namespace{} if result := h.db.First(&n, "name = ?", name); errors.Is( @@ -111,7 +111,7 @@ func (h *Headscale) GetNamespace(name string) (*Namespace, error) { return &n, nil } -// ListNamespaces gets all the existing namespaces +// ListNamespaces gets all the existing namespaces. func (h *Headscale) ListNamespaces() ([]Namespace, error) { namespaces := []Namespace{} if err := h.db.Find(&namespaces).Error; err != nil { @@ -120,7 +120,7 @@ func (h *Headscale) ListNamespaces() ([]Namespace, error) { return namespaces, nil } -// ListMachinesInNamespace gets all the nodes in a given namespace +// ListMachinesInNamespace gets all the nodes in a given namespace. func (h *Headscale) ListMachinesInNamespace(name string) ([]Machine, error) { n, err := h.GetNamespace(name) if err != nil { @@ -134,7 +134,7 @@ func (h *Headscale) ListMachinesInNamespace(name string) ([]Machine, error) { return machines, nil } -// ListSharedMachinesInNamespace returns all the machines that are shared to the specified namespace +// ListSharedMachinesInNamespace returns all the machines that are shared to the specified namespace. func (h *Headscale) ListSharedMachinesInNamespace(name string) ([]Machine, error) { namespace, err := h.GetNamespace(name) if err != nil { @@ -158,7 +158,7 @@ func (h *Headscale) ListSharedMachinesInNamespace(name string) ([]Machine, error return machines, nil } -// SetMachineNamespace assigns a Machine to a namespace +// SetMachineNamespace assigns a Machine to a namespace. func (h *Headscale) SetMachineNamespace(m *Machine, namespaceName string) error { n, err := h.GetNamespace(namespaceName) if err != nil { @@ -169,7 +169,7 @@ func (h *Headscale) SetMachineNamespace(m *Machine, namespaceName string) error return nil } -// RequestMapUpdates signals the KV worker to update the maps for this namespace +// RequestMapUpdates signals the KV worker to update the maps for this namespace. func (h *Headscale) RequestMapUpdates(namespaceID uint) error { namespace := Namespace{} if err := h.db.First(&namespace, namespaceID).Error; err != nil { diff --git a/oidc.go b/oidc.go index c3f7c2e2..49ed1b3d 100644 --- a/oidc.go +++ b/oidc.go @@ -57,7 +57,7 @@ func (h *Headscale) initOIDC() error { // RegisterOIDC redirects to the OIDC provider for authentication // Puts machine key in cache so the callback can retrieve it using the oidc state param -// Listens in /oidc/register/:mKey +// Listens in /oidc/register/:mKey. func (h *Headscale) RegisterOIDC(c *gin.Context) { mKeyStr := c.Param("mkey") if mKeyStr == "" { @@ -88,7 +88,7 @@ func (h *Headscale) RegisterOIDC(c *gin.Context) { // Retrieves the mkey from the state cache and adds the machine to the users email namespace // TODO: A confirmation page for new machines should be added to avoid phishing vulnerabilities // TODO: Add groups information from OIDC tokens into machine HostInfo -// Listens in /oidc/callback +// Listens in /oidc/callback. func (h *Headscale) OIDCCallback(c *gin.Context) { code := c.Query("code") state := c.Query("state") @@ -170,7 +170,6 @@ func (h *Headscale) OIDCCallback(c *gin.Context) { if nsName, ok := h.getNamespaceFromEmail(claims.Email); ok { // register the machine if it's new if !m.Registered { - log.Debug().Msg("Registering new machine after successful callback") ns, err := h.GetNamespace(nsName) @@ -218,7 +217,6 @@ func (h *Headscale) OIDCCallback(c *gin.Context) { `, claims.Email))) - } log.Error(). diff --git a/preauth_keys.go b/preauth_keys.go index 68664c17..2641cbc8 100644 --- a/preauth_keys.go +++ b/preauth_keys.go @@ -7,10 +7,9 @@ import ( "strconv" "time" + v1 "github.com/juanfont/headscale/gen/go/headscale/v1" "google.golang.org/protobuf/types/known/timestamppb" "gorm.io/gorm" - - v1 "github.com/juanfont/headscale/gen/go/headscale/v1" ) const ( @@ -19,7 +18,7 @@ const ( errSingleUseAuthKeyHasBeenUsed = Error("AuthKey has already been used") ) -// PreAuthKey describes a pre-authorization key usable in a particular namespace +// PreAuthKey describes a pre-authorization key usable in a particular namespace. type PreAuthKey struct { ID uint64 `gorm:"primary_key"` Key string @@ -33,7 +32,7 @@ type PreAuthKey struct { Expiration *time.Time } -// CreatePreAuthKey creates a new PreAuthKey in a namespace, and returns it +// CreatePreAuthKey creates a new PreAuthKey in a namespace, and returns it. func (h *Headscale) CreatePreAuthKey( namespaceName string, reusable bool, @@ -65,7 +64,7 @@ func (h *Headscale) CreatePreAuthKey( return &k, nil } -// ListPreAuthKeys returns the list of PreAuthKeys for a namespace +// ListPreAuthKeys returns the list of PreAuthKeys for a namespace. func (h *Headscale) ListPreAuthKeys(namespaceName string) ([]PreAuthKey, error) { n, err := h.GetNamespace(namespaceName) if err != nil { @@ -79,7 +78,7 @@ func (h *Headscale) ListPreAuthKeys(namespaceName string) ([]PreAuthKey, error) return keys, nil } -// GetPreAuthKey returns a PreAuthKey for a given key +// GetPreAuthKey returns a PreAuthKey for a given key. func (h *Headscale) GetPreAuthKey(namespace string, key string) (*PreAuthKey, error) { pak, err := h.checkKeyValidity(key) if err != nil { @@ -93,7 +92,7 @@ func (h *Headscale) GetPreAuthKey(namespace string, key string) (*PreAuthKey, er return pak, nil } -// MarkExpirePreAuthKey marks a PreAuthKey as expired +// MarkExpirePreAuthKey marks a PreAuthKey as expired. func (h *Headscale) ExpirePreAuthKey(k *PreAuthKey) error { if err := h.db.Model(&k).Update("Expiration", time.Now()).Error; err != nil { return err @@ -102,7 +101,7 @@ func (h *Headscale) ExpirePreAuthKey(k *PreAuthKey) error { } // checkKeyValidity does the heavy lifting for validation of the PreAuthKey coming from a node -// If returns no error and a PreAuthKey, it can be used +// If returns no error and a PreAuthKey, it can be used. func (h *Headscale) checkKeyValidity(k string) (*PreAuthKey, error) { pak := PreAuthKey{} if result := h.db.Preload("Namespace").First(&pak, "key = ?", k); errors.Is( diff --git a/routes.go b/routes.go index 84f8dfe4..8b308125 100644 --- a/routes.go +++ b/routes.go @@ -10,7 +10,7 @@ import ( // Deprecated: use machine function instead // GetAdvertisedNodeRoutes returns the subnet routes advertised by a node (identified by -// namespace and node name) +// namespace and node name). func (h *Headscale) GetAdvertisedNodeRoutes( namespace string, nodeName string, @@ -29,7 +29,7 @@ func (h *Headscale) GetAdvertisedNodeRoutes( // Deprecated: use machine function instead // GetEnabledNodeRoutes returns the subnet routes enabled by a node (identified by -// namespace and node name) +// namespace and node name). func (h *Headscale) GetEnabledNodeRoutes( namespace string, nodeName string, @@ -63,7 +63,7 @@ func (h *Headscale) GetEnabledNodeRoutes( } // Deprecated: use machine function instead -// IsNodeRouteEnabled checks if a certain route has been enabled +// IsNodeRouteEnabled checks if a certain route has been enabled. func (h *Headscale) IsNodeRouteEnabled( namespace string, nodeName string, @@ -89,7 +89,7 @@ func (h *Headscale) IsNodeRouteEnabled( // Deprecated: use EnableRoute in machine.go // EnableNodeRoute enables a subnet route advertised by a node (identified by -// namespace and node name) +// namespace and node name). func (h *Headscale) EnableNodeRoute( namespace string, nodeName string, diff --git a/sharing.go b/sharing.go index 581c2af4..8f654143 100644 --- a/sharing.go +++ b/sharing.go @@ -8,7 +8,7 @@ const ( errorMachineNotShared = Error("Machine not shared to this namespace") ) -// SharedMachine is a join table to support sharing nodes between namespaces +// SharedMachine is a join table to support sharing nodes between namespaces. type SharedMachine struct { gorm.Model MachineID uint64 @@ -17,7 +17,7 @@ type SharedMachine struct { Namespace Namespace } -// AddSharedMachineToNamespace adds a machine as a shared node to a namespace +// AddSharedMachineToNamespace adds a machine as a shared node to a namespace. func (h *Headscale) AddSharedMachineToNamespace(m *Machine, ns *Namespace) error { if m.NamespaceID == ns.ID { return errorSameNamespace @@ -42,7 +42,7 @@ func (h *Headscale) AddSharedMachineToNamespace(m *Machine, ns *Namespace) error return nil } -// RemoveSharedMachineFromNamespace removes a shared machine from a namespace +// RemoveSharedMachineFromNamespace removes a shared machine from a namespace. func (h *Headscale) RemoveSharedMachineFromNamespace(m *Machine, ns *Namespace) error { if m.NamespaceID == ns.ID { // Can't unshare from primary namespace @@ -69,7 +69,7 @@ func (h *Headscale) RemoveSharedMachineFromNamespace(m *Machine, ns *Namespace) return nil } -// RemoveSharedMachineFromAllNamespaces removes a machine as a shared node from all namespaces +// RemoveSharedMachineFromAllNamespaces removes a machine as a shared node from all namespaces. func (h *Headscale) RemoveSharedMachineFromAllNamespaces(m *Machine) error { sharedMachine := SharedMachine{} if result := h.db.Where("machine_id = ?", m.ID).Unscoped().Delete(&sharedMachine); result.Error != nil { diff --git a/swagger.go b/swagger.go index d3ae1b2d..01c73e4b 100644 --- a/swagger.go +++ b/swagger.go @@ -6,9 +6,8 @@ import ( "net/http" "text/template" - "github.com/rs/zerolog/log" - "github.com/gin-gonic/gin" + "github.com/rs/zerolog/log" ) //go:embed gen/openapiv2/headscale/v1/headscale.swagger.json diff --git a/utils.go b/utils.go index 0b76b5e9..8dd6294a 100644 --- a/utils.go +++ b/utils.go @@ -113,7 +113,6 @@ func (h *Headscale) getAvailableIP() (*netaddr.IP, error) { if ip.IsZero() && ip.IsLoopback() { - ip = ip.Next() continue } From 3ddd9962ce3ac6c0a9a867943a3f0ae05bcd3e95 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Sat, 13 Nov 2021 08:39:20 +0000 Subject: [PATCH 121/300] Add format make entry --- Makefile | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 92beaefb..8e86b8a0 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,14 @@ # Calculate version version = $(shell ./scripts/version-at-commit.sh) +rwildcard=$(foreach d,$(wildcard $1*),$(call rwildcard,$d/,$2) $(filter $(subst *,%,$2),$d)) + +# GO_SOURCES = $(wildcard *.go) +# PROTO_SOURCES = $(wildcard **/*.proto) +GO_SOURCES = $(call rwildcard,,*.go) +PROTO_SOURCES = $(call rwildcard,,*.proto) + + build: go build -ldflags "-s -w -X github.com/juanfont/headscale/cmd/headscale/cli.Version=$(version)" cmd/headscale/headscale.go @@ -19,7 +27,12 @@ coverprofile_html: go tool cover -html=coverage.out lint: - golangci-lint run --fix + golangci-lint run --fix --timeout 10m + +fmt: + prettier --check '**/**.{ts,js,md,yaml,yml,sass,css,scss,html}' + golines --max-len=88 --base-formatter=gofumpt -w $(GO_SOURCES) + clang-format -style="{BasedOnStyle: Google, IndentWidth: 4, AlignConsecutiveDeclarations: true, AlignConsecutiveAssignments: true, ColumnLimit: 0}" -i $(PROTO_SOURCES) proto-lint: cd proto/ && buf lint From 148437f716cb8aec155eb2f255122f3732bbb445 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Sat, 13 Nov 2021 08:53:34 +0000 Subject: [PATCH 122/300] Setup more linters and goals for golangci --- .golangci.yaml | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/.golangci.yaml b/.golangci.yaml index a97c2bb5..5a4b9074 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -5,3 +5,49 @@ run: issues: skip-dirs: - gen +linters: + enable-all: true + disable: + - exhaustivestruct + - revive + - lll + - interfacer + - scopelint + - maligned + - golint + - gofmt + - gochecknoglobals + - gochecknoinits + - gocognit + - funlen + - exhaustivestruct + - tagliatelle + - godox + + # We should strive to enable these: + - testpackage + - stylecheck + - wrapcheck + - paralleltest + - noctx + - nlreturn + - ifshort + - gomnd + - goerr113 + - errorlint + - forcetypeassert + - errname + - wsl + - unparam + - makezero + - gosec + - gocritic + - forbidigo + - dupl + - goconst + - unconvert + - exhaustive + + # We might want to enable this, but it might be a lot of work + - cyclop + - nestif From 24e0c944b1ed896c21d672dee548518d909011ef Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Sat, 13 Nov 2021 09:11:03 +0000 Subject: [PATCH 123/300] Align with update golangci-lint --- .github/workflows/lint.yml | 1 - .golangci.yaml | 5 ++++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 75de620e..59747d3c 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -13,7 +13,6 @@ jobs: uses: golangci/golangci-lint-action@v2 with: version: latest - args: --timeout 30m prettier-lint: runs-on: ubuntu-latest diff --git a/.golangci.yaml b/.golangci.yaml index 5a4b9074..9139bba9 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -1,6 +1,6 @@ --- run: - timeout: 5m + timeout: 10m issues: skip-dirs: @@ -23,6 +23,7 @@ linters: - exhaustivestruct - tagliatelle - godox + - ireturn # We should strive to enable these: - testpackage @@ -47,6 +48,8 @@ linters: - goconst - unconvert - exhaustive + - varnamelen + - nilnil # We might want to enable this, but it might be a lot of work - cyclop From 95b9f03fb384be564f7bf3930411a5be7d2cee76 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Sat, 13 Nov 2021 09:13:17 +0000 Subject: [PATCH 124/300] update buf setup --- .github/workflows/lint.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 59747d3c..ee3f61b6 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -31,5 +31,5 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - uses: bufbuild/buf-setup-action@v0.5.0 + - uses: bufbuild/buf-setup-action@v0.7.0 - uses: bufbuild/buf-lint-action@v1 From fa0922d5bb640969d1bec4e4b6df1a4eb1ccf6e1 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Sat, 13 Nov 2021 09:18:00 +0000 Subject: [PATCH 125/300] define proto dir for buf --- .github/workflows/lint.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index ee3f61b6..169191d0 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -33,3 +33,5 @@ jobs: - uses: actions/checkout@v2 - uses: bufbuild/buf-setup-action@v0.7.0 - uses: bufbuild/buf-lint-action@v1 + with: + input: 'proto' From b653572272c87d1cb02e5a9187c81d2c911ba114 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Sat, 13 Nov 2021 09:20:51 +0000 Subject: [PATCH 126/300] Make format shuld format, not lint --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 8e86b8a0..060d3b9c 100644 --- a/Makefile +++ b/Makefile @@ -30,7 +30,7 @@ lint: golangci-lint run --fix --timeout 10m fmt: - prettier --check '**/**.{ts,js,md,yaml,yml,sass,css,scss,html}' + prettier --write '**/**.{ts,js,md,yaml,yml,sass,css,scss,html}' golines --max-len=88 --base-formatter=gofumpt -w $(GO_SOURCES) clang-format -style="{BasedOnStyle: Google, IndentWidth: 4, AlignConsecutiveDeclarations: true, AlignConsecutiveAssignments: true, ColumnLimit: 0}" -i $(PROTO_SOURCES) From 806f0d3e6c8b13c5af61ccdada900662218d5810 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Sat, 13 Nov 2021 09:20:59 +0000 Subject: [PATCH 127/300] Format lint --- .github/workflows/lint.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 169191d0..b3c64006 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -34,4 +34,4 @@ jobs: - uses: bufbuild/buf-setup-action@v0.7.0 - uses: bufbuild/buf-lint-action@v1 with: - input: 'proto' + input: "proto" From f94b0b54d843eb0a9f17be5979466c882c404f95 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Sat, 13 Nov 2021 09:39:20 +0000 Subject: [PATCH 128/300] Remove lint install, update go --- .github/workflows/build.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ca4d4cf2..963663a7 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -18,12 +18,11 @@ jobs: - name: Setup Go uses: actions/setup-go@v2 with: - go-version: "1.16.3" + go-version: "1.17.3" - name: Install dependencies run: | go version - go install golang.org/x/lint/golint@latest sudo apt update sudo apt install -y make From acf7e462adaea2c7e2c9ab1e0a0b5c3554a4dab6 Mon Sep 17 00:00:00 2001 From: Ward Vandewege Date: Sat, 13 Nov 2021 14:01:05 -0500 Subject: [PATCH 129/300] Improvements for namespace deletion: add a confirmation prompt, and make sure to also delete any associated preauthkeys. --- cmd/headscale/cli/namespaces.go | 36 ++++++++++++++++++++++++++++----- namespaces.go | 16 +++++++++++---- namespaces_test.go | 16 ++++++++++++++- preauth_keys.go | 10 +++++++++ 4 files changed, 68 insertions(+), 10 deletions(-) diff --git a/cmd/headscale/cli/namespaces.go b/cmd/headscale/cli/namespaces.go index 752638a7..0e5eeb4c 100644 --- a/cmd/headscale/cli/namespaces.go +++ b/cmd/headscale/cli/namespaces.go @@ -3,6 +3,7 @@ package cli import ( "fmt" + survey "github.com/AlecAivazis/survey/v2" v1 "github.com/juanfont/headscale/gen/go/headscale/v1" "github.com/pterm/pterm" "github.com/rs/zerolog/log" @@ -70,19 +71,44 @@ var destroyNamespaceCmd = &cobra.Command{ namespaceName := args[0] + request := &v1.GetNamespaceRequest{ + Name: namespaceName, + } + ctx, client, conn, cancel := getHeadscaleCLIClient() defer cancel() defer conn.Close() - request := &v1.DeleteNamespaceRequest{Name: namespaceName} - - response, err := client.DeleteNamespace(ctx, request) + _, err := client.GetNamespace(ctx, request) if err != nil { - ErrorOutput(err, fmt.Sprintf("Cannot destroy namespace: %s", status.Convert(err).Message()), output) + ErrorOutput(err, fmt.Sprintf("Error: %s", status.Convert(err).Message()), output) return } - SuccessOutput(response, "Namespace destroyed", output) + confirm := false + force, _ := cmd.Flags().GetBool("force") + if !force { + prompt := &survey.Confirm{ + Message: fmt.Sprintf("Do you want to remove the namespace '%s' and any associated preauthkeys?", namespaceName), + } + err := survey.AskOne(prompt, &confirm) + if err != nil { + return + } + } + + if confirm || force { + request := &v1.DeleteNamespaceRequest{Name: namespaceName} + + response, err := client.DeleteNamespace(ctx, request) + if err != nil { + ErrorOutput(err, fmt.Sprintf("Cannot destroy namespace: %s", status.Convert(err).Message()), output) + return + } + SuccessOutput(response, "Namespace destroyed", output) + } else { + SuccessOutput(map[string]string{"Result": "Namespace not destroyed"}, "Namespace not destroyed", output) + } }, } diff --git a/namespaces.go b/namespaces.go index 66deb1a2..dc034cb4 100644 --- a/namespaces.go +++ b/namespaces.go @@ -15,9 +15,9 @@ import ( ) const ( - errorNamespaceExists = Error("Namespace already exists") - errorNamespaceNotFound = Error("Namespace not found") - errorNamespaceNotEmpty = Error("Namespace not empty") + errorNamespaceExists = Error("Namespace already exists") + errorNamespaceNotFound = Error("Namespace not found") + errorNamespaceNotEmptyOfNodes = Error("Namespace not empty: node(s) found") ) // Namespace is the way Headscale implements the concept of users in Tailscale @@ -60,7 +60,15 @@ func (h *Headscale) DestroyNamespace(name string) error { return err } if len(m) > 0 { - return errorNamespaceNotEmpty + return errorNamespaceNotEmptyOfNodes + } + + keys, err := h.ListPreAuthKeys(name) + if err != nil { + return err + } + for _, p := range keys { + h.DestroyPreAuthKey(&p) } if result := h.db.Unscoped().Delete(&n); result.Error != nil { diff --git a/namespaces_test.go b/namespaces_test.go index 7ce4850e..72193ee2 100644 --- a/namespaces_test.go +++ b/namespaces_test.go @@ -3,6 +3,7 @@ package headscale import ( "github.com/rs/zerolog/log" "gopkg.in/check.v1" + "gorm.io/gorm" ) func (s *Suite) TestCreateAndDestroyNamespace(c *check.C) { @@ -31,6 +32,19 @@ func (s *Suite) TestDestroyNamespaceErrors(c *check.C) { pak, err := h.CreatePreAuthKey(n.Name, false, false, nil) c.Assert(err, check.IsNil) + err = h.DestroyNamespace("test") + c.Assert(err, check.IsNil) + + result := h.db.Preload("Namespace").First(&pak, "key = ?", pak.Key) + // destroying a namespace also deletes all associated preauthkeys + c.Assert(result.Error, check.Equals, gorm.ErrRecordNotFound) + + n, err = h.CreateNamespace("test") + c.Assert(err, check.IsNil) + + pak, err = h.CreatePreAuthKey(n.Name, false, false, nil) + c.Assert(err, check.IsNil) + m := Machine{ ID: 0, MachineKey: "foo", @@ -45,7 +59,7 @@ func (s *Suite) TestDestroyNamespaceErrors(c *check.C) { h.db.Save(&m) err = h.DestroyNamespace("test") - c.Assert(err, check.Equals, errorNamespaceNotEmpty) + c.Assert(err, check.Equals, errorNamespaceNotEmptyOfNodes) } func (s *Suite) TestRenameNamespace(c *check.C) { diff --git a/preauth_keys.go b/preauth_keys.go index 1cb9c112..41b10e39 100644 --- a/preauth_keys.go +++ b/preauth_keys.go @@ -93,6 +93,16 @@ func (h *Headscale) GetPreAuthKey(namespace string, key string) (*PreAuthKey, er return pak, nil } +// DestroyPreAuthKey destroys a preauthkey. Returns error if the PreAuthKey +// does not exist. +func (h *Headscale) DestroyPreAuthKey(pak *PreAuthKey) error { + if result := h.db.Unscoped().Delete(&pak); result.Error != nil { + return result.Error + } + + return nil +} + // MarkExpirePreAuthKey marks a PreAuthKey as expired func (h *Headscale) ExpirePreAuthKey(k *PreAuthKey) error { if err := h.db.Model(&k).Update("Expiration", time.Now()).Error; err != nil { From 34dba0ade864ee4bceb8cf7264c84c865ca828de Mon Sep 17 00:00:00 2001 From: Ward Vandewege Date: Sat, 13 Nov 2021 15:24:32 -0500 Subject: [PATCH 130/300] Fix missing error check. --- namespaces.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/namespaces.go b/namespaces.go index dc034cb4..e5d17839 100644 --- a/namespaces.go +++ b/namespaces.go @@ -68,7 +68,10 @@ func (h *Headscale) DestroyNamespace(name string) error { return err } for _, p := range keys { - h.DestroyPreAuthKey(&p) + err = h.DestroyPreAuthKey(&p) + if err != nil { + return err + } } if result := h.db.Unscoped().Delete(&n); result.Error != nil { From c0f16603c5d8656192b9854bf6c80aede3329059 Mon Sep 17 00:00:00 2001 From: "Alessandro (Ale) Segala" <43508+ItalyPaleAle@users.noreply.github.com> Date: Sat, 13 Nov 2021 22:10:58 +0000 Subject: [PATCH 131/300] Copy headscale binary in /bin in the container This way, we don't need to alter the PATH --- Dockerfile | 3 +-- Dockerfile.debug | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/Dockerfile b/Dockerfile index 58c3a38b..0d344268 100644 --- a/Dockerfile +++ b/Dockerfile @@ -14,9 +14,8 @@ RUN test -e /go/bin/headscale # Production image FROM gcr.io/distroless/base-debian11 -COPY --from=build /go/bin/headscale /headscale +COPY --from=build /go/bin/headscale /bin/headscale ENV TZ UTC -ENV PATH / EXPOSE 8080/tcp CMD ["headscale"] diff --git a/Dockerfile.debug b/Dockerfile.debug index 2d99faec..320b5c93 100644 --- a/Dockerfile.debug +++ b/Dockerfile.debug @@ -14,9 +14,8 @@ RUN test -e /go/bin/headscale # Debug image FROM gcr.io/distroless/base-debian11:debug -COPY --from=build /go/bin/headscale /headscale +COPY --from=build /go/bin/headscale /bin/headscale ENV TZ UTC -ENV PATH="/:$PATH" # Need to reset the entrypoint or everything will run as a busybox script ENTRYPOINT [] From 7d77acd88ea847e8412768fb8b218c7ced2a2b02 Mon Sep 17 00:00:00 2001 From: "Alessandro (Ale) Segala" <43508+ItalyPaleAle@users.noreply.github.com> Date: Sat, 13 Nov 2021 22:16:37 +0000 Subject: [PATCH 132/300] Docs for debug container --- docs/Running.md | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/docs/Running.md b/docs/Running.md index 014ef401..32fee2c8 100644 --- a/docs/Running.md +++ b/docs/Running.md @@ -158,3 +158,31 @@ If you used tailscale.com before in your nodes, make sure you clear the tailscal If you create an authkey with the `--ephemeral` flag, that key will create ephemeral nodes. This implies that `--reusable` is true. Please bear in mind that all headscale commands support adding `-o json` or `-o json-line` to get nicely JSON-formatted output. + +## Debugging headscale running in Docker + +The `headscale/headscale` Docker container is based on a "distroless" image that does not contain a shell or any other debug tools. If you need to debug your application running in the Docker container, you can use the `-debug` variant, for example `headscale/headscale:x.x.x-debug`. + +### Running the debug Docker container + +To run the debug Docker container, use the exact same commands as above, but replace `headscale/headscale:x.x.x` with `headscale/headscale:x.x.x-debug` (`x.x.x` is the version of headscale). The two containers are compatible with each other, so you can alternate between them. + +### Executing commands in the debug container + +The default command in the debug container is to run `headscale`, which is located at `/bin/headscale` inside the container. + +Additionally, the debug container includes a minimalist Busybox shell. + +To launch a shell in the container, use: + +``` +docker run -it headscale/headscale:x.x.x-debug sh +``` + +You can also execute commands directly, such as `ls /bin` in this example: + +``` +docker run headscale/headscale:x.x.x-debug ls /bin +``` + +Using `docker exec` allows you to run commands in an existing container. From b897a26f42e13ff9eed6a108f5eda1b6d9f8e78c Mon Sep 17 00:00:00 2001 From: Fernando De Lucchi <69133647+fdelucchijr@users.noreply.github.com> Date: Sat, 13 Nov 2021 21:08:59 -0500 Subject: [PATCH 133/300] arm64 docker image build in release process --- .github/workflows/release.yml | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index c0605f10..275c5b37 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -40,6 +40,20 @@ jobs: uses: actions/checkout@v2 with: fetch-depth: 0 + + - name: Set up QEMU for multiple platforms + uses: docker/setup-qemu-action@master + with: + platforms: arm64,amd64 + + - name: Cache Docker layers + uses: actions/cache@v2 + with: + path: /tmp/.buildx-cache + key: ${{ runner.os }}-buildx-${{ github.sha }} + restore-keys: | + ${{ runner.os }}-buildx- + - name: Docker meta id: meta uses: docker/metadata-action@v3 @@ -53,17 +67,20 @@ jobs: type=semver,pattern={{major}}.{{minor}} type=semver,pattern={{major}} type=sha + - name: Login to DockerHub uses: docker/login-action@v1 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} + - name: Login to GHCR uses: docker/login-action@v1 with: registry: ghcr.io username: ${{ github.repository_owner }} password: ${{ secrets.GITHUB_TOKEN }} + - name: Build and push id: docker_build uses: docker/build-push-action@v2 @@ -72,3 +89,11 @@ jobs: context: . tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} + platforms: linux/amd64,linux/arm64 + cache-from: type=local,src=/tmp/.buildx-cache + cache-to: type=local,dest=/tmp/.buildx-cache-new + + - name: Prepare cache for next build + run: | + rm -rf /tmp/.buildx-cache + mv /tmp/.buildx-cache-new /tmp/.buildx-cache From e8726b1e2272214cecc7583ea000bf59804f6da4 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Sun, 14 Nov 2021 08:08:03 +0000 Subject: [PATCH 134/300] Add readme note about codestyle --- README.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/README.md b/README.md index c99b54d7..987f7acf 100644 --- a/README.md +++ b/README.md @@ -63,6 +63,23 @@ Please have a look at the documentation under [`docs/`](docs/). To contribute to Headscale you would need the lastest version of [Go](https://golang.org) and [Buf](https://buf.build)(Protobuf generator). +### Code style + +To ensure we have some consistency with a growing number of contributes, this project has adopted linting and style/formatting rules: + +The **Go** code is linted with [`golangci-lint`](https://golangci-lint.run) and +formatted with [`golines`](https://github.com/segmentio/golines) (width 88) and +[`gofumpt`](https://github.com/mvdan/gofumpt). +Please configure your editor to run the tools while developing and make sure to +run `make lint` and `make fmt` before committing any code. + +The **Proto** code is linted with [`buf`](https://docs.buf.build/lint/overview) and +formatted with [`clang-format`](https://clang.llvm.org/docs/ClangFormat.html). + +The **rest** (markdown, yaml, etc) is formatted with [`prettier`](https://prettier.io). + +Check out the `.golangci.yaml` and `Makefile` to see the specific configuration. + ### Install development tools - Go From f3da299457f1073ffa276ad33f79743895747786 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Sun, 14 Nov 2021 08:09:33 +0000 Subject: [PATCH 135/300] Format readme --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 987f7acf..41f388ea 100644 --- a/README.md +++ b/README.md @@ -67,13 +67,13 @@ To contribute to Headscale you would need the lastest version of [Go](https://go To ensure we have some consistency with a growing number of contributes, this project has adopted linting and style/formatting rules: -The **Go** code is linted with [`golangci-lint`](https://golangci-lint.run) and -formatted with [`golines`](https://github.com/segmentio/golines) (width 88) and +The **Go** code is linted with [`golangci-lint`](https://golangci-lint.run) and +formatted with [`golines`](https://github.com/segmentio/golines) (width 88) and [`gofumpt`](https://github.com/mvdan/gofumpt). -Please configure your editor to run the tools while developing and make sure to +Please configure your editor to run the tools while developing and make sure to run `make lint` and `make fmt` before committing any code. -The **Proto** code is linted with [`buf`](https://docs.buf.build/lint/overview) and +The **Proto** code is linted with [`buf`](https://docs.buf.build/lint/overview) and formatted with [`clang-format`](https://clang.llvm.org/docs/ClangFormat.html). The **rest** (markdown, yaml, etc) is formatted with [`prettier`](https://prettier.io). From 1969802c6b26995d5c6c1cdd467f6a93b615a9b5 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Sun, 14 Nov 2021 08:32:58 +0000 Subject: [PATCH 136/300] Fix golanglint --- preauth_keys.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/preauth_keys.go b/preauth_keys.go index a1107481..4494dda1 100644 --- a/preauth_keys.go +++ b/preauth_keys.go @@ -102,7 +102,7 @@ func (h *Headscale) DestroyPreAuthKey(pak *PreAuthKey) error { return nil } -// MarkExpirePreAuthKey marks a PreAuthKey as expired +// MarkExpirePreAuthKey marks a PreAuthKey as expired. func (h *Headscale) ExpirePreAuthKey(k *PreAuthKey) error { if err := h.db.Model(&k).Update("Expiration", time.Now()).Error; err != nil { return err From d0ef8500358a744ce15d6b9fa476c05651c6f334 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Sun, 14 Nov 2021 16:37:43 +0100 Subject: [PATCH 137/300] Add and fix noctx linter --- .golangci.yaml | 1 - derp.go | 12 +++++++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/.golangci.yaml b/.golangci.yaml index 9139bba9..f74bc011 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -30,7 +30,6 @@ linters: - stylecheck - wrapcheck - paralleltest - - noctx - nlreturn - ifshort - gomnd diff --git a/derp.go b/derp.go index 422b1e62..fb06381b 100644 --- a/derp.go +++ b/derp.go @@ -1,6 +1,7 @@ package headscale import ( + "context" "encoding/json" "io" "io/ioutil" @@ -30,10 +31,19 @@ func loadDERPMapFromPath(path string) (*tailcfg.DERPMap, error) { } func loadDERPMapFromURL(addr url.URL) (*tailcfg.DERPMap, error) { + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + + req, err := http.NewRequestWithContext(ctx, "GET", addr.String(), nil) + if err != nil { + return nil, err + } + client := http.Client{ Timeout: 10 * time.Second, } - resp, err := client.Get(addr.String()) + + resp, err := client.Do(req) if err != nil { return nil, err } From 89eb13c6cbab94870819a2a9e77b96843bebee99 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Sun, 14 Nov 2021 16:46:09 +0100 Subject: [PATCH 138/300] Add and fix nlreturn (new line return) --- .golangci.yaml | 1 - acls.go | 9 +++++++++ acls_types.go | 2 ++ api.go | 24 ++++++++++++++++++++++++ app.go | 5 +++++ apple_mobileconfig.go | 7 +++++++ cmd/headscale/cli/debug.go | 5 +++++ cmd/headscale/cli/namespaces.go | 10 ++++++++++ cmd/headscale/cli/nodes.go | 21 +++++++++++++++++++++ cmd/headscale/cli/preauthkeys.go | 9 +++++++++ cmd/headscale/cli/routes.go | 12 ++++++++++++ cmd/headscale/cli/utils.go | 4 ++++ db.go | 4 ++++ derp.go | 4 ++++ dns.go | 2 ++ dns_test.go | 5 +++++ machine.go | 19 +++++++++++++++++++ namespaces.go | 15 +++++++++++++++ namespaces_test.go | 2 ++ oidc.go | 13 +++++++++++++ poll.go | 14 ++++++++++++++ preauth_keys.go | 3 +++ routes.go | 2 ++ swagger.go | 1 + utils.go | 6 ++++++ 25 files changed, 198 insertions(+), 1 deletion(-) diff --git a/.golangci.yaml b/.golangci.yaml index f74bc011..2856148e 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -30,7 +30,6 @@ linters: - stylecheck - wrapcheck - paralleltest - - nlreturn - ifshort - gomnd - goerr113 diff --git a/acls.go b/acls.go index 9ce08a11..a5e54400 100644 --- a/acls.go +++ b/acls.go @@ -58,6 +58,7 @@ func (h *Headscale) LoadACLPolicy(path string) error { return err } h.aclRules = rules + return nil } @@ -77,6 +78,7 @@ func (h *Headscale) generateACLRules() ([]tailcfg.FilterRule, error) { if err != nil { log.Error(). Msgf("Error parsing ACL %d, User %d", i, j) + return nil, err } srcIPs = append(srcIPs, srcs...) @@ -89,6 +91,7 @@ func (h *Headscale) generateACLRules() ([]tailcfg.FilterRule, error) { if err != nil { log.Error(). Msgf("Error parsing ACL %d, Port %d", i, j) + return nil, err } destPorts = append(destPorts, dests...) @@ -147,6 +150,7 @@ func (h *Headscale) generateACLPolicyDestPorts( dests = append(dests, pr) } } + return dests, nil } @@ -169,6 +173,7 @@ func (h *Headscale) expandAlias(s string) ([]string, error) { ips = append(ips, node.IPAddress) } } + return ips, nil } @@ -200,11 +205,13 @@ func (h *Headscale) expandAlias(s string) ([]string, error) { for _, t := range hostinfo.RequestTags { if s[4:] == t { ips = append(ips, m.IPAddress) + break } } } } + return ips, nil } @@ -218,6 +225,7 @@ func (h *Headscale) expandAlias(s string) ([]string, error) { for _, n := range nodes { ips = append(ips, n.IPAddress) } + return ips, nil } @@ -272,5 +280,6 @@ func (h *Headscale) expandPorts(s string) (*[]tailcfg.PortRange, error) { return nil, errorInvalidPortFormat } } + return &ports, nil } diff --git a/acls_types.go b/acls_types.go index 91c9a44e..63f79ba0 100644 --- a/acls_types.go +++ b/acls_types.go @@ -65,6 +65,7 @@ func (h *Hosts) UnmarshalJSON(data []byte) error { hosts[k] = prefix } *h = hosts + return nil } @@ -73,5 +74,6 @@ func (p ACLPolicy) IsZero() bool { if len(p.Groups) == 0 && len(p.Hosts) == 0 && len(p.ACLs) == 0 { return true } + return false } diff --git a/api.go b/api.go index bd6b80c4..c8a307cf 100644 --- a/api.go +++ b/api.go @@ -30,6 +30,7 @@ func (h *Headscale) RegisterWebAPI(c *gin.Context) { mKeyStr := c.Query("key") if mKeyStr == "" { c.String(http.StatusBadRequest, "Wrong params") + return } @@ -66,6 +67,7 @@ func (h *Headscale) RegistrationHandler(c *gin.Context) { Msg("Cannot parse machine key") machineRegistrations.WithLabelValues("unknown", "web", "error", "unknown").Inc() c.String(http.StatusInternalServerError, "Sad!") + return } req := tailcfg.RegisterRequest{} @@ -77,6 +79,7 @@ func (h *Headscale) RegistrationHandler(c *gin.Context) { Msg("Cannot decode message") machineRegistrations.WithLabelValues("unknown", "web", "error", "unknown").Inc() c.String(http.StatusInternalServerError, "Very sad!") + return } @@ -96,6 +99,7 @@ func (h *Headscale) RegistrationHandler(c *gin.Context) { Msg("Could not create row") machineRegistrations.WithLabelValues("unknown", "web", "error", m.Namespace.Name). Inc() + return } m = &newMachine @@ -103,6 +107,7 @@ func (h *Headscale) RegistrationHandler(c *gin.Context) { if !m.Registered && req.Auth.AuthKey != "" { h.handleAuthKey(c, h.db, mKey, req, *m) + return } @@ -131,9 +136,11 @@ func (h *Headscale) RegistrationHandler(c *gin.Context) { Err(err). Msg("Cannot encode message") c.String(http.StatusInternalServerError, "") + return } c.Data(200, "application/json; charset=utf-8", respBody) + return } @@ -158,11 +165,13 @@ func (h *Headscale) RegistrationHandler(c *gin.Context) { machineRegistrations.WithLabelValues("update", "web", "error", m.Namespace.Name). Inc() c.String(http.StatusInternalServerError, "") + return } machineRegistrations.WithLabelValues("update", "web", "success", m.Namespace.Name). Inc() c.Data(200, "application/json; charset=utf-8", respBody) + return } @@ -199,11 +208,13 @@ func (h *Headscale) RegistrationHandler(c *gin.Context) { machineRegistrations.WithLabelValues("new", "web", "error", m.Namespace.Name). Inc() c.String(http.StatusInternalServerError, "") + return } machineRegistrations.WithLabelValues("new", "web", "success", m.Namespace.Name). Inc() c.Data(200, "application/json; charset=utf-8", respBody) + return } @@ -225,9 +236,11 @@ func (h *Headscale) RegistrationHandler(c *gin.Context) { Err(err). Msg("Cannot encode message") c.String(http.StatusInternalServerError, "Extremely sad!") + return } c.Data(200, "application/json; charset=utf-8", respBody) + return } @@ -259,6 +272,7 @@ func (h *Headscale) RegistrationHandler(c *gin.Context) { Err(err). Msg("Cannot encode message") c.String(http.StatusInternalServerError, "") + return } c.Data(200, "application/json; charset=utf-8", respBody) @@ -279,6 +293,7 @@ func (h *Headscale) getMapResponse( Str("func", "getMapResponse"). Err(err). Msg("Cannot convert to node") + return nil, err } @@ -288,6 +303,7 @@ func (h *Headscale) getMapResponse( Str("func", "getMapResponse"). Err(err). Msg("Cannot fetch peers") + return nil, err } @@ -299,6 +315,7 @@ func (h *Headscale) getMapResponse( Str("func", "getMapResponse"). Err(err). Msg("Failed to convert peers to Tailscale nodes") + return nil, err } @@ -313,6 +330,7 @@ func (h *Headscale) getMapResponse( Str("func", "getMapResponse"). Err(err). Msg("Failed generate the DNSConfig") + return nil, err } @@ -353,6 +371,7 @@ func (h *Headscale) getMapResponse( data := make([]byte, 4) binary.LittleEndian.PutUint32(data, uint32(len(respBody))) data = append(data, respBody...) + return data, nil } @@ -383,6 +402,7 @@ func (h *Headscale) getMapKeepAliveResponse( data := make([]byte, 4) binary.LittleEndian.PutUint32(data, uint32(len(respBody))) data = append(data, respBody...) + return data, nil } @@ -416,6 +436,7 @@ func (h *Headscale) handleAuthKey( c.String(http.StatusInternalServerError, "") machineRegistrations.WithLabelValues("new", "authkey", "error", m.Namespace.Name). Inc() + return } c.Data(401, "application/json; charset=utf-8", respBody) @@ -425,6 +446,7 @@ func (h *Headscale) handleAuthKey( Msg("Failed authentication via AuthKey") machineRegistrations.WithLabelValues("new", "authkey", "error", m.Namespace.Name). Inc() + return } @@ -440,6 +462,7 @@ func (h *Headscale) handleAuthKey( Msg("Failed to find an available IP") machineRegistrations.WithLabelValues("new", "authkey", "error", m.Namespace.Name). Inc() + return } log.Info(). @@ -471,6 +494,7 @@ func (h *Headscale) handleAuthKey( machineRegistrations.WithLabelValues("new", "authkey", "error", m.Namespace.Name). Inc() c.String(http.StatusInternalServerError, "Extremely sad!") + return } machineRegistrations.WithLabelValues("new", "authkey", "success", m.Namespace.Name). diff --git a/app.go b/app.go index 73fec927..0da088f2 100644 --- a/app.go +++ b/app.go @@ -297,6 +297,7 @@ func (h *Headscale) grpcAuthenticationInterceptor(ctx context.Context, Caller(). Str("client_address", p.Addr.String()). Msg("Retrieving metadata is failed") + return ctx, status.Errorf( codes.InvalidArgument, "Retrieving metadata is failed", @@ -309,6 +310,7 @@ func (h *Headscale) grpcAuthenticationInterceptor(ctx context.Context, Caller(). Str("client_address", p.Addr.String()). Msg("Authorization token is not supplied") + return ctx, status.Errorf( codes.Unauthenticated, "Authorization token is not supplied", @@ -322,6 +324,7 @@ func (h *Headscale) grpcAuthenticationInterceptor(ctx context.Context, Caller(). Str("client_address", p.Addr.String()). Msg(`missing "Bearer " prefix in "Authorization" header`) + return ctx, status.Error( codes.Unauthenticated, `missing "Bearer " prefix in "Authorization" header`, @@ -392,6 +395,7 @@ func (h *Headscale) ensureUnixSocketIsAbsent() error { if _, err := os.Stat(h.cfg.UnixSocket); errors.Is(err, os.ErrNotExist) { return nil } + return os.Remove(h.cfg.UnixSocket) } @@ -568,6 +572,7 @@ func (h *Headscale) Serve() error { if tlsConfig != nil { g.Go(func() error { tlsl := tls.NewListener(httpListener, tlsConfig) + return httpServer.Serve(tlsl) }) } else { diff --git a/apple_mobileconfig.go b/apple_mobileconfig.go index 3629daa4..ff3ef3cf 100644 --- a/apple_mobileconfig.go +++ b/apple_mobileconfig.go @@ -77,6 +77,7 @@ func (h *Headscale) AppleMobileConfig(c *gin.Context) { "text/html; charset=utf-8", []byte("Could not render Apple index template"), ) + return } @@ -97,6 +98,7 @@ func (h *Headscale) ApplePlatformConfig(c *gin.Context) { "text/html; charset=utf-8", []byte("Failed to create UUID"), ) + return } @@ -111,6 +113,7 @@ func (h *Headscale) ApplePlatformConfig(c *gin.Context) { "text/html; charset=utf-8", []byte("Failed to create UUID"), ) + return } @@ -133,6 +136,7 @@ func (h *Headscale) ApplePlatformConfig(c *gin.Context) { "text/html; charset=utf-8", []byte("Could not render Apple macOS template"), ) + return } case "ios": @@ -146,6 +150,7 @@ func (h *Headscale) ApplePlatformConfig(c *gin.Context) { "text/html; charset=utf-8", []byte("Could not render Apple iOS template"), ) + return } default: @@ -154,6 +159,7 @@ func (h *Headscale) ApplePlatformConfig(c *gin.Context) { "text/html; charset=utf-8", []byte("Invalid platform, only ios and macos is supported"), ) + return } @@ -174,6 +180,7 @@ func (h *Headscale) ApplePlatformConfig(c *gin.Context) { "text/html; charset=utf-8", []byte("Could not render Apple platform template"), ) + return } diff --git a/cmd/headscale/cli/debug.go b/cmd/headscale/cli/debug.go index f106efa6..46bdb9e8 100644 --- a/cmd/headscale/cli/debug.go +++ b/cmd/headscale/cli/debug.go @@ -48,6 +48,7 @@ var createNodeCmd = &cobra.Command{ namespace, err := cmd.Flags().GetString("namespace") if err != nil { ErrorOutput(err, fmt.Sprintf("Error getting namespace: %s", err), output) + return } @@ -62,6 +63,7 @@ var createNodeCmd = &cobra.Command{ fmt.Sprintf("Error getting node from flag: %s", err), output, ) + return } @@ -72,6 +74,7 @@ var createNodeCmd = &cobra.Command{ fmt.Sprintf("Error getting key from flag: %s", err), output, ) + return } @@ -82,6 +85,7 @@ var createNodeCmd = &cobra.Command{ fmt.Sprintf("Error getting routes from flag: %s", err), output, ) + return } @@ -99,6 +103,7 @@ var createNodeCmd = &cobra.Command{ fmt.Sprintf("Cannot create machine: %s", status.Convert(err).Message()), output, ) + return } diff --git a/cmd/headscale/cli/namespaces.go b/cmd/headscale/cli/namespaces.go index ff57cc86..9e1be07f 100644 --- a/cmd/headscale/cli/namespaces.go +++ b/cmd/headscale/cli/namespaces.go @@ -31,6 +31,7 @@ var createNamespaceCmd = &cobra.Command{ if len(args) < 1 { return fmt.Errorf("Missing parameters") } + return nil }, Run: func(cmd *cobra.Command, args []string) { @@ -57,6 +58,7 @@ var createNamespaceCmd = &cobra.Command{ ), output, ) + return } @@ -71,6 +73,7 @@ var destroyNamespaceCmd = &cobra.Command{ if len(args) < 1 { return fmt.Errorf("Missing parameters") } + return nil }, Run: func(cmd *cobra.Command, args []string) { @@ -93,6 +96,7 @@ var destroyNamespaceCmd = &cobra.Command{ fmt.Sprintf("Error: %s", status.Convert(err).Message()), output, ) + return } @@ -124,6 +128,7 @@ var destroyNamespaceCmd = &cobra.Command{ ), output, ) + return } SuccessOutput(response, "Namespace destroyed", output) @@ -152,11 +157,13 @@ var listNamespacesCmd = &cobra.Command{ fmt.Sprintf("Cannot get namespaces: %s", status.Convert(err).Message()), output, ) + return } if output != "" { SuccessOutput(response.Namespaces, "", output) + return } @@ -178,6 +185,7 @@ var listNamespacesCmd = &cobra.Command{ fmt.Sprintf("Failed to render pterm table: %s", err), output, ) + return } }, @@ -190,6 +198,7 @@ var renameNamespaceCmd = &cobra.Command{ if len(args) < 2 { return fmt.Errorf("Missing parameters") } + return nil }, Run: func(cmd *cobra.Command, args []string) { @@ -214,6 +223,7 @@ var renameNamespaceCmd = &cobra.Command{ ), output, ) + return } diff --git a/cmd/headscale/cli/nodes.go b/cmd/headscale/cli/nodes.go index 934ac491..6b2cf4a2 100644 --- a/cmd/headscale/cli/nodes.go +++ b/cmd/headscale/cli/nodes.go @@ -77,6 +77,7 @@ var registerNodeCmd = &cobra.Command{ namespace, err := cmd.Flags().GetString("namespace") if err != nil { ErrorOutput(err, fmt.Sprintf("Error getting namespace: %s", err), output) + return } @@ -91,6 +92,7 @@ var registerNodeCmd = &cobra.Command{ fmt.Sprintf("Error getting machine key from flag: %s", err), output, ) + return } @@ -109,6 +111,7 @@ var registerNodeCmd = &cobra.Command{ ), output, ) + return } @@ -124,6 +127,7 @@ var listNodesCmd = &cobra.Command{ namespace, err := cmd.Flags().GetString("namespace") if err != nil { ErrorOutput(err, fmt.Sprintf("Error getting namespace: %s", err), output) + return } @@ -142,17 +146,20 @@ var listNodesCmd = &cobra.Command{ fmt.Sprintf("Cannot get nodes: %s", status.Convert(err).Message()), output, ) + return } if output != "" { SuccessOutput(response.Machines, "", output) + return } d, err := nodesToPtables(namespace, response.Machines) if err != nil { ErrorOutput(err, fmt.Sprintf("Error converting to table: %s", err), output) + return } @@ -163,6 +170,7 @@ var listNodesCmd = &cobra.Command{ fmt.Sprintf("Failed to render pterm table: %s", err), output, ) + return } }, @@ -181,6 +189,7 @@ var deleteNodeCmd = &cobra.Command{ fmt.Sprintf("Error converting ID to integer: %s", err), output, ) + return } @@ -202,6 +211,7 @@ var deleteNodeCmd = &cobra.Command{ ), output, ) + return } @@ -228,6 +238,7 @@ var deleteNodeCmd = &cobra.Command{ response, err := client.DeleteMachine(ctx, deleteRequest) if output != "" { SuccessOutput(response, "", output) + return } if err != nil { @@ -239,6 +250,7 @@ var deleteNodeCmd = &cobra.Command{ ), output, ) + return } SuccessOutput( @@ -260,6 +272,7 @@ func sharingWorker( namespaceStr, err := cmd.Flags().GetString("namespace") if err != nil { ErrorOutput(err, fmt.Sprintf("Error getting namespace: %s", err), output) + return "", nil, nil, err } @@ -270,6 +283,7 @@ func sharingWorker( id, err := cmd.Flags().GetInt("identifier") if err != nil { ErrorOutput(err, fmt.Sprintf("Error converting ID to integer: %s", err), output) + return "", nil, nil, err } @@ -284,6 +298,7 @@ func sharingWorker( fmt.Sprintf("Error getting node node: %s", status.Convert(err).Message()), output, ) + return "", nil, nil, err } @@ -298,6 +313,7 @@ func sharingWorker( fmt.Sprintf("Error getting node node: %s", status.Convert(err).Message()), output, ) + return "", nil, nil, err } @@ -315,6 +331,7 @@ var shareMachineCmd = &cobra.Command{ fmt.Sprintf("Failed to fetch namespace or machine: %s", err), output, ) + return } @@ -334,6 +351,7 @@ var shareMachineCmd = &cobra.Command{ fmt.Sprintf("Error sharing node: %s", status.Convert(err).Message()), output, ) + return } @@ -352,6 +370,7 @@ var unshareMachineCmd = &cobra.Command{ fmt.Sprintf("Failed to fetch namespace or machine: %s", err), output, ) + return } @@ -371,6 +390,7 @@ var unshareMachineCmd = &cobra.Command{ fmt.Sprintf("Error unsharing node: %s", status.Convert(err).Message()), output, ) + return } @@ -442,5 +462,6 @@ func nodesToPtables( }, ) } + return d, nil } diff --git a/cmd/headscale/cli/preauthkeys.go b/cmd/headscale/cli/preauthkeys.go index f5b3b87b..55df5aa2 100644 --- a/cmd/headscale/cli/preauthkeys.go +++ b/cmd/headscale/cli/preauthkeys.go @@ -44,6 +44,7 @@ var listPreAuthKeys = &cobra.Command{ n, err := cmd.Flags().GetString("namespace") if err != nil { ErrorOutput(err, fmt.Sprintf("Error getting namespace: %s", err), output) + return } @@ -62,11 +63,13 @@ var listPreAuthKeys = &cobra.Command{ fmt.Sprintf("Error getting the list of keys: %s", err), output, ) + return } if output != "" { SuccessOutput(response.PreAuthKeys, "", output) + return } @@ -104,6 +107,7 @@ var listPreAuthKeys = &cobra.Command{ fmt.Sprintf("Failed to render pterm table: %s", err), output, ) + return } }, @@ -118,6 +122,7 @@ var createPreAuthKeyCmd = &cobra.Command{ namespace, err := cmd.Flags().GetString("namespace") if err != nil { ErrorOutput(err, fmt.Sprintf("Error getting namespace: %s", err), output) + return } @@ -156,6 +161,7 @@ var createPreAuthKeyCmd = &cobra.Command{ fmt.Sprintf("Cannot create Pre Auth Key: %s\n", err), output, ) + return } @@ -170,6 +176,7 @@ var expirePreAuthKeyCmd = &cobra.Command{ if len(args) < 1 { return fmt.Errorf("missing parameters") } + return nil }, Run: func(cmd *cobra.Command, args []string) { @@ -177,6 +184,7 @@ var expirePreAuthKeyCmd = &cobra.Command{ namespace, err := cmd.Flags().GetString("namespace") if err != nil { ErrorOutput(err, fmt.Sprintf("Error getting namespace: %s", err), output) + return } @@ -196,6 +204,7 @@ var expirePreAuthKeyCmd = &cobra.Command{ fmt.Sprintf("Cannot expire Pre Auth Key: %s\n", err), output, ) + return } diff --git a/cmd/headscale/cli/routes.go b/cmd/headscale/cli/routes.go index 1a0ff2aa..2ad64bc3 100644 --- a/cmd/headscale/cli/routes.go +++ b/cmd/headscale/cli/routes.go @@ -52,6 +52,7 @@ var listRoutesCmd = &cobra.Command{ fmt.Sprintf("Error getting machine id from flag: %s", err), output, ) + return } @@ -70,17 +71,20 @@ var listRoutesCmd = &cobra.Command{ fmt.Sprintf("Cannot get nodes: %s", status.Convert(err).Message()), output, ) + return } if output != "" { SuccessOutput(response.Routes, "", output) + return } d := routesToPtables(response.Routes) if err != nil { ErrorOutput(err, fmt.Sprintf("Error converting to table: %s", err), output) + return } @@ -91,6 +95,7 @@ var listRoutesCmd = &cobra.Command{ fmt.Sprintf("Failed to render pterm table: %s", err), output, ) + return } }, @@ -113,6 +118,7 @@ omit the route you do not want to enable. fmt.Sprintf("Error getting machine id from flag: %s", err), output, ) + return } @@ -123,6 +129,7 @@ omit the route you do not want to enable. fmt.Sprintf("Error getting routes from flag: %s", err), output, ) + return } @@ -145,17 +152,20 @@ omit the route you do not want to enable. ), output, ) + return } if output != "" { SuccessOutput(response.Routes, "", output) + return } d := routesToPtables(response.Routes) if err != nil { ErrorOutput(err, fmt.Sprintf("Error converting to table: %s", err), output) + return } @@ -166,6 +176,7 @@ omit the route you do not want to enable. fmt.Sprintf("Failed to render pterm table: %s", err), output, ) + return } }, @@ -180,6 +191,7 @@ func routesToPtables(routes *v1.Routes) pterm.TableData { d = append(d, []string{route, strconv.FormatBool(enabled)}) } + return d } diff --git a/cmd/headscale/cli/utils.go b/cmd/headscale/cli/utils.go index f4463231..80bded8a 100644 --- a/cmd/headscale/cli/utils.go +++ b/cmd/headscale/cli/utils.go @@ -213,6 +213,7 @@ func absPath(path string) string { path = filepath.Join(dir, path) } } + return path } @@ -310,6 +311,7 @@ func getHeadscaleApp() (*headscale.Headscale, error) { viper.GetString("ephemeral_node_inactivity_timeout"), minInactivityTimeout, ) + return nil, err } @@ -415,6 +417,7 @@ func SuccessOutput(result interface{}, override string, outputFormat string) { } default: fmt.Println(override) + return } @@ -435,6 +438,7 @@ func HasMachineOutputFlag() bool { return true } } + return false } diff --git a/db.go b/db.go index d3ef6833..b3490ef9 100644 --- a/db.go +++ b/db.go @@ -50,6 +50,7 @@ func (h *Headscale) initDB() error { } err = h.setValue("db_version", dbVersion) + return err } @@ -93,6 +94,7 @@ func (h *Headscale) getValue(key string) (string, error) { ) { return "", errors.New("not found") } + return row.Value, nil } @@ -106,9 +108,11 @@ func (h *Headscale) setValue(key string, value string) error { _, err := h.getValue(key) if err == nil { h.db.Model(&kv).Where("key = ?", key).Update("value", value) + return nil } h.db.Create(kv) + return nil } diff --git a/derp.go b/derp.go index fb06381b..a2481acf 100644 --- a/derp.go +++ b/derp.go @@ -27,6 +27,7 @@ func loadDERPMapFromPath(path string) (*tailcfg.DERPMap, error) { return nil, err } err = yaml.Unmarshal(b, &derpMap) + return &derpMap, err } @@ -56,6 +57,7 @@ func loadDERPMapFromURL(addr url.URL) (*tailcfg.DERPMap, error) { var derpMap tailcfg.DERPMap err = json.Unmarshal(body, &derpMap) + return &derpMap, err } @@ -94,6 +96,7 @@ func GetDERPMap(cfg DERPConfig) *tailcfg.DERPMap { Str("path", path). Err(err). Msg("Could not load DERP map from path") + break } @@ -112,6 +115,7 @@ func GetDERPMap(cfg DERPConfig) *tailcfg.DERPMap { Str("url", addr.String()). Err(err). Msg("Could not load DERP map from path") + break } diff --git a/dns.go b/dns.go index e0e1abee..82d186e2 100644 --- a/dns.go +++ b/dns.go @@ -69,6 +69,7 @@ func generateMagicDNSRootDomains( } fqdns = append(fqdns, fqdn) } + return fqdns, nil } @@ -99,5 +100,6 @@ func getMapResponseDNSConfig( } else { dnsConfig = dnsConfigOrig } + return dnsConfig, nil } diff --git a/dns_test.go b/dns_test.go index eeaf8853..19cc803a 100644 --- a/dns_test.go +++ b/dns_test.go @@ -18,6 +18,7 @@ func (s *Suite) TestMagicDNSRootDomains100(c *check.C) { for _, domain := range domains { if domain == "64.100.in-addr.arpa." { found = true + break } } @@ -27,6 +28,7 @@ func (s *Suite) TestMagicDNSRootDomains100(c *check.C) { for _, domain := range domains { if domain == "100.100.in-addr.arpa." { found = true + break } } @@ -36,6 +38,7 @@ func (s *Suite) TestMagicDNSRootDomains100(c *check.C) { for _, domain := range domains { if domain == "127.100.in-addr.arpa." { found = true + break } } @@ -51,6 +54,7 @@ func (s *Suite) TestMagicDNSRootDomains172(c *check.C) { for _, domain := range domains { if domain == "0.16.172.in-addr.arpa." { found = true + break } } @@ -60,6 +64,7 @@ func (s *Suite) TestMagicDNSRootDomains172(c *check.C) { for _, domain := range domains { if domain == "255.16.172.in-addr.arpa." { found = true + break } } diff --git a/machine.go b/machine.go index 8ff0b359..e0fe2a3e 100644 --- a/machine.go +++ b/machine.go @@ -106,6 +106,7 @@ func (h *Headscale) getDirectPeers(m *Machine) (Machines, error) { if err := h.db.Preload("Namespace").Where("namespace_id = ? AND machine_key <> ? AND registered", m.NamespaceID, m.MachineKey).Find(&machines).Error; err != nil { log.Error().Err(err).Msg("Error accessing db") + return Machines{}, err } @@ -115,6 +116,7 @@ func (h *Headscale) getDirectPeers(m *Machine) (Machines, error) { Caller(). Str("machine", m.Name). Msgf("Found direct machines: %s", machines.String()) + return machines, nil } @@ -142,6 +144,7 @@ func (h *Headscale) getShared(m *Machine) (Machines, error) { Caller(). Str("machine", m.Name). Msgf("Found shared peers: %s", peers.String()) + return peers, nil } @@ -175,6 +178,7 @@ func (h *Headscale) getSharedTo(m *Machine) (Machines, error) { Caller(). Str("machine", m.Name). Msgf("Found peers we are shared with: %s", peers.String()) + return peers, nil } @@ -185,6 +189,7 @@ func (h *Headscale) getPeers(m *Machine) (Machines, error) { Caller(). Err(err). Msg("Cannot fetch peers") + return Machines{}, err } @@ -194,6 +199,7 @@ func (h *Headscale) getPeers(m *Machine) (Machines, error) { Caller(). Err(err). Msg("Cannot fetch peers") + return Machines{}, err } @@ -203,6 +209,7 @@ func (h *Headscale) getPeers(m *Machine) (Machines, error) { Caller(). Err(err). Msg("Cannot fetch peers") + return Machines{}, err } @@ -224,6 +231,7 @@ func (h *Headscale) ListMachines() ([]Machine, error) { if err := h.db.Preload("AuthKey").Preload("AuthKey.Namespace").Preload("Namespace").Find(&machines).Error; err != nil { return nil, err } + return machines, nil } @@ -239,6 +247,7 @@ func (h *Headscale) GetMachine(namespace string, name string) (*Machine, error) return &m, nil } } + return nil, fmt.Errorf("machine not found") } @@ -248,6 +257,7 @@ func (h *Headscale) GetMachineByID(id uint64) (*Machine, error) { if result := h.db.Preload("Namespace").Find(&Machine{ID: id}).First(&m); result.Error != nil { return nil, result.Error } + return &m, nil } @@ -257,6 +267,7 @@ func (h *Headscale) GetMachineByMachineKey(mKey string) (*Machine, error) { if result := h.db.Preload("Namespace").First(&m, "machine_key = ?", mKey); result.Error != nil { return nil, result.Error } + return &m, nil } @@ -266,6 +277,7 @@ func (h *Headscale) UpdateMachine(m *Machine) error { if result := h.db.Find(m).First(&m); result.Error != nil { return result.Error } + return nil } @@ -314,6 +326,7 @@ func (m *Machine) GetHostInfo() (*tailcfg.Hostinfo, error) { return nil, err } } + return &hostinfo, nil } @@ -348,6 +361,7 @@ func (h *Headscale) isOutdated(m *Machine) bool { Time("last_successful_update", *m.LastSuccessfulUpdate). Time("last_state_change", lastChange). Msgf("Checking if %s is missing updates", m.Name) + return m.LastSuccessfulUpdate.Before(lastChange) } @@ -429,6 +443,7 @@ func (m Machine) toNode( Caller(). Str("ip", m.IPAddress). Msgf("Failed to parse IP Prefix from IP: %s", m.IPAddress) + return nil, err } addrs = append(addrs, ip) // missing the ipv6 ? @@ -530,6 +545,7 @@ func (m Machine) toNode( MachineAuthorized: m.Registered, Capabilities: []string{tailcfg.CapabilityFileSharing}, } + return &n, nil } @@ -613,6 +629,7 @@ func (h *Headscale) RegisterMachine(key string, namespace string) (*Machine, err Err(err). Str("machine", m.Name). Msg("Could not find IP for the new machine") + return nil, err } @@ -642,6 +659,7 @@ func (m *Machine) GetAdvertisedRoutes() ([]netaddr.IPPrefix, error) { if err != nil { return nil, err } + return hostInfo.RoutableIPs, nil } @@ -685,6 +703,7 @@ func (m *Machine) IsRoutesEnabled(routeStr string) bool { return true } } + return false } diff --git a/namespaces.go b/namespaces.go index c421931e..d3ef8242 100644 --- a/namespaces.go +++ b/namespaces.go @@ -42,8 +42,10 @@ func (h *Headscale) CreateNamespace(name string) (*Namespace, error) { Str("func", "CreateNamespace"). Err(err). Msg("Could not create row") + return nil, err } + return &n, nil } @@ -119,6 +121,7 @@ func (h *Headscale) GetNamespace(name string) (*Namespace, error) { ) { return nil, errorNamespaceNotFound } + return &n, nil } @@ -128,6 +131,7 @@ func (h *Headscale) ListNamespaces() ([]Namespace, error) { if err := h.db.Find(&namespaces).Error; err != nil { return nil, err } + return namespaces, nil } @@ -142,6 +146,7 @@ func (h *Headscale) ListMachinesInNamespace(name string) ([]Machine, error) { if err := h.db.Preload("AuthKey").Preload("AuthKey.Namespace").Preload("Namespace").Where(&Machine{NamespaceID: n.ID}).Find(&machines).Error; err != nil { return nil, err } + return machines, nil } @@ -166,6 +171,7 @@ func (h *Headscale) ListSharedMachinesInNamespace(name string) ([]Machine, error } machines = append(machines, *machine) } + return machines, nil } @@ -177,6 +183,7 @@ func (h *Headscale) SetMachineNamespace(m *Machine, namespaceName string) error } m.NamespaceID = n.ID h.db.Save(&m) + return nil } @@ -196,6 +203,7 @@ func (h *Headscale) RequestMapUpdates(namespaceID uint) error { if err != nil { return err } + return nil } names := []string{} @@ -208,6 +216,7 @@ func (h *Headscale) RequestMapUpdates(namespaceID uint) error { if err != nil { return err } + return nil } @@ -218,8 +227,10 @@ func (h *Headscale) RequestMapUpdates(namespaceID uint) error { Str("func", "RequestMapUpdates"). Err(err). Msg("Could not marshal namespaces_pending_updates") + return err } + return h.setValue("namespaces_pending_updates", string(data)) } @@ -255,6 +266,7 @@ func (h *Headscale) checkForNamespacesPendingUpdates() { Str("func", "checkForNamespacesPendingUpdates"). Err(err). Msg("Could not save to KV") + return } } @@ -270,6 +282,7 @@ func (n *Namespace) toUser() *tailcfg.User { Logins: []tailcfg.LoginID{}, Created: time.Time{}, } + return &u } @@ -281,6 +294,7 @@ func (n *Namespace) toLogin() *tailcfg.Login { ProfilePicURL: "", Domain: "headscale.net", } + return &l } @@ -300,6 +314,7 @@ func getMapResponseUserProfiles(m Machine, peers Machines) []tailcfg.UserProfile DisplayName: namespace.Name, }) } + return profiles } diff --git a/namespaces_test.go b/namespaces_test.go index 72193ee2..502bc368 100644 --- a/namespaces_test.go +++ b/namespaces_test.go @@ -199,6 +199,7 @@ func (s *Suite) TestGetMapResponseUserProfiles(c *check.C) { for _, up := range userProfiles { if up.DisplayName == n1.Name { found = true + break } } @@ -208,6 +209,7 @@ func (s *Suite) TestGetMapResponseUserProfiles(c *check.C) { for _, up := range userProfiles { if up.DisplayName == n2.Name { found = true + break } } diff --git a/oidc.go b/oidc.go index 49ed1b3d..63a1abe0 100644 --- a/oidc.go +++ b/oidc.go @@ -32,6 +32,7 @@ func (h *Headscale) initOIDC() error { if err != nil { log.Error().Msgf("Could not retrieve OIDC Config: %s", err.Error()) + return err } @@ -62,6 +63,7 @@ func (h *Headscale) RegisterOIDC(c *gin.Context) { mKeyStr := c.Param("mkey") if mKeyStr == "" { c.String(http.StatusBadRequest, "Wrong params") + return } @@ -70,6 +72,7 @@ func (h *Headscale) RegisterOIDC(c *gin.Context) { if err != nil { log.Error().Msg("could not read 16 bytes from rand") c.String(http.StatusInternalServerError, "could not read 16 bytes from rand") + return } @@ -95,12 +98,14 @@ func (h *Headscale) OIDCCallback(c *gin.Context) { if code == "" || state == "" { c.String(http.StatusBadRequest, "Wrong params") + return } oauth2Token, err := h.oauth2Config.Exchange(context.Background(), code) if err != nil { c.String(http.StatusBadRequest, "Could not exchange code for token") + return } @@ -109,6 +114,7 @@ func (h *Headscale) OIDCCallback(c *gin.Context) { rawIDToken, rawIDTokenOK := oauth2Token.Extra("id_token").(string) if !rawIDTokenOK { c.String(http.StatusBadRequest, "Could not extract ID Token") + return } @@ -117,6 +123,7 @@ func (h *Headscale) OIDCCallback(c *gin.Context) { idToken, err := verifier.Verify(context.Background(), rawIDToken) if err != nil { c.String(http.StatusBadRequest, "Failed to verify id token: %s", err.Error()) + return } @@ -134,6 +141,7 @@ func (h *Headscale) OIDCCallback(c *gin.Context) { http.StatusBadRequest, fmt.Sprintf("Failed to decode id token claims: %s", err), ) + return } @@ -144,6 +152,7 @@ func (h *Headscale) OIDCCallback(c *gin.Context) { log.Error(). Msg("requested machine state key expired before authorisation completed") c.String(http.StatusBadRequest, "state has expired") + return } mKeyStr, mKeyOK := mKeyIf.(string) @@ -151,6 +160,7 @@ func (h *Headscale) OIDCCallback(c *gin.Context) { if !mKeyOK { log.Error().Msg("could not get machine key from cache") c.String(http.StatusInternalServerError, "could not get machine key from cache") + return } @@ -162,6 +172,7 @@ func (h *Headscale) OIDCCallback(c *gin.Context) { http.StatusInternalServerError, "could not get machine info from database", ) + return } @@ -183,6 +194,7 @@ func (h *Headscale) OIDCCallback(c *gin.Context) { http.StatusInternalServerError, "could not create new namespace", ) + return } } @@ -193,6 +205,7 @@ func (h *Headscale) OIDCCallback(c *gin.Context) { http.StatusInternalServerError, "could not get an IP from the pool", ) + return } diff --git a/poll.go b/poll.go index 038192f2..e3c5c663 100644 --- a/poll.go +++ b/poll.go @@ -38,6 +38,7 @@ func (h *Headscale) PollNetMapHandler(c *gin.Context) { Err(err). Msg("Cannot parse client key") c.String(http.StatusBadRequest, "") + return } req := tailcfg.MapRequest{} @@ -48,6 +49,7 @@ func (h *Headscale) PollNetMapHandler(c *gin.Context) { Err(err). Msg("Cannot decode message") c.String(http.StatusBadRequest, "") + return } @@ -58,6 +60,7 @@ func (h *Headscale) PollNetMapHandler(c *gin.Context) { Str("handler", "PollNetMap"). Msgf("Ignoring request, cannot find machine with key %s", mKey.HexString()) c.String(http.StatusUnauthorized, "") + return } log.Error(). @@ -101,6 +104,7 @@ func (h *Headscale) PollNetMapHandler(c *gin.Context) { Err(err). Msg("Failed to get Map response") c.String(http.StatusInternalServerError, ":(") + return } @@ -124,6 +128,7 @@ func (h *Headscale) PollNetMapHandler(c *gin.Context) { Str("machine", m.Name). Msg("Client is starting up. Probably interested in a DERP map") c.Data(200, "application/json; charset=utf-8", data) + return } @@ -161,6 +166,7 @@ func (h *Headscale) PollNetMapHandler(c *gin.Context) { updateRequestsFromNode.WithLabelValues(m.Name, m.Namespace.Name, "endpoint-update"). Inc() go func() { updateChan <- struct{}{} }() + return } else if req.OmitPeers && req.Stream { log.Warn(). @@ -168,6 +174,7 @@ func (h *Headscale) PollNetMapHandler(c *gin.Context) { Str("machine", m.Name). Msg("Ignoring request, don't know how to handle it") c.String(http.StatusBadRequest, "") + return } @@ -248,6 +255,7 @@ func (h *Headscale) PollNetMapStream( Str("channel", "pollData"). Err(err). Msg("Cannot write data") + return false } log.Trace(). @@ -282,6 +290,7 @@ func (h *Headscale) PollNetMapStream( Str("channel", "pollData"). Int("bytes", len(data)). Msg("Machine entry in database updated successfully after sending pollData") + return true case data := <-keepAliveChan: @@ -299,6 +308,7 @@ func (h *Headscale) PollNetMapStream( Str("channel", "keepAlive"). Err(err). Msg("Cannot write keep alive message") + return false } log.Trace(). @@ -328,6 +338,7 @@ func (h *Headscale) PollNetMapStream( Str("channel", "keepAlive"). Int("bytes", len(data)). Msg("Machine updated successfully after sending keep alive") + return true case <-updateChan: @@ -364,6 +375,7 @@ func (h *Headscale) PollNetMapStream( Msg("Could not write the map response") updateRequestsSentToNode.WithLabelValues(m.Name, m.Namespace.Name, "failed"). Inc() + return false } log.Trace(). @@ -405,6 +417,7 @@ func (h *Headscale) PollNetMapStream( Time("last_state_change", h.getLastStateChange(m.Namespace.Name)). Msgf("%s is up to date", m.Name) } + return true case <-c.Request.Context().Done(): @@ -485,6 +498,7 @@ func (h *Headscale) scheduledPollWorker( Str("func", "keepAlive"). Err(err). Msg("Error generating the keep alive msg") + return } diff --git a/preauth_keys.go b/preauth_keys.go index 4494dda1..a477d985 100644 --- a/preauth_keys.go +++ b/preauth_keys.go @@ -75,6 +75,7 @@ func (h *Headscale) ListPreAuthKeys(namespaceName string) ([]PreAuthKey, error) if err := h.db.Preload("Namespace").Where(&PreAuthKey{NamespaceID: n.ID}).Find(&keys).Error; err != nil { return nil, err } + return keys, nil } @@ -107,6 +108,7 @@ func (h *Headscale) ExpirePreAuthKey(k *PreAuthKey) error { if err := h.db.Model(&k).Update("Expiration", time.Now()).Error; err != nil { return err } + return nil } @@ -147,6 +149,7 @@ func (h *Headscale) generateKey() (string, error) { if _, err := rand.Read(bytes); err != nil { return "", err } + return hex.EncodeToString(bytes), nil } diff --git a/routes.go b/routes.go index 8b308125..d6acc3a5 100644 --- a/routes.go +++ b/routes.go @@ -24,6 +24,7 @@ func (h *Headscale) GetAdvertisedNodeRoutes( if err != nil { return nil, err } + return &hostInfo.RoutableIPs, nil } @@ -84,6 +85,7 @@ func (h *Headscale) IsNodeRouteEnabled( return true } } + return false } diff --git a/swagger.go b/swagger.go index 01c73e4b..01b2eb50 100644 --- a/swagger.go +++ b/swagger.go @@ -57,6 +57,7 @@ func SwaggerUI(c *gin.Context) { "text/html; charset=utf-8", []byte("Could not render Swagger"), ) + return } diff --git a/utils.go b/utils.go index 8dd6294a..85e3ba28 100644 --- a/utils.go +++ b/utils.go @@ -48,6 +48,7 @@ func decodeMsg( if err := json.Unmarshal(decrypted, v); err != nil { return fmt.Errorf("response: %v", err) } + return nil } @@ -64,6 +65,7 @@ func decryptMsg(msg []byte, pubKey *wgkey.Key, privKey *wgkey.Private) ([]byte, if !ok { return nil, fmt.Errorf("cannot decrypt response") } + return decrypted, nil } @@ -83,6 +85,7 @@ func encodeMsg(b []byte, pubKey *wgkey.Key, privKey *wgkey.Private) ([]byte, err } pub, pri := (*[32]byte)(pubKey), (*[32]byte)(privKey) msg := box.Seal(nonce[:], b, &nonce, pub, pri) + return msg, nil } @@ -108,12 +111,14 @@ func (h *Headscale) getAvailableIP() (*netaddr.IP, error) { ipRaw := ip.As4() if ipRaw[3] == 0 || ipRaw[3] == 255 { ip = ip.Next() + continue } if ip.IsZero() && ip.IsLoopback() { ip = ip.Next() + continue } @@ -174,6 +179,7 @@ func tailMapResponseToString(resp tailcfg.MapResponse) string { func GrpcSocketDialer(ctx context.Context, addr string) (net.Conn, error) { var d net.Dialer + return d.DialContext(ctx, "unix", addr) } From 4ace54c4e16d07e90a3448cfe80bc5d334ddc5bb Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Sun, 14 Nov 2021 16:49:54 +0100 Subject: [PATCH 139/300] Move wsl, might not be feasible --- .golangci.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.golangci.yaml b/.golangci.yaml index 2856148e..a796712d 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -36,7 +36,6 @@ linters: - errorlint - forcetypeassert - errname - - wsl - unparam - makezero - gosec @@ -52,3 +51,4 @@ linters: # We might want to enable this, but it might be a lot of work - cyclop - nestif + - wsl # might be incompatible with gofumpt From 668e958d3e986707f080bdf370d44ff66a53a8c3 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Sun, 14 Nov 2021 17:49:54 +0100 Subject: [PATCH 140/300] Add and fix unconvert --- .golangci.yaml | 1 - dns.go | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/.golangci.yaml b/.golangci.yaml index a796712d..058158ba 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -43,7 +43,6 @@ linters: - forbidigo - dupl - goconst - - unconvert - exhaustive - varnamelen - nilnil diff --git a/dns.go b/dns.go index 82d186e2..e917e953 100644 --- a/dns.go +++ b/dns.go @@ -52,7 +52,7 @@ func generateMagicDNSRootDomains( // min is the value in the lastOctet byte of the IP // max is basically 2^wildcardBits - i.e., the value when all the wildcardBits are set to 1 min := uint(netRange.IP[lastOctet]) - max := uint((min + 1< Date: Sun, 14 Nov 2021 17:51:34 +0100 Subject: [PATCH 141/300] Add and fix nilnil --- .golangci.yaml | 1 - app.go | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/.golangci.yaml b/.golangci.yaml index 058158ba..3006b0f4 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -45,7 +45,6 @@ linters: - goconst - exhaustive - varnamelen - - nilnil # We might want to enable this, but it might be a lot of work - cyclop diff --git a/app.go b/app.go index 0da088f2..034f86f9 100644 --- a/app.go +++ b/app.go @@ -588,6 +588,7 @@ func (h *Headscale) Serve() error { } func (h *Headscale) getTLSSettings() (*tls.Config, error) { + var err error if h.cfg.TLSLetsEncryptHostname != "" { if !strings.HasPrefix(h.cfg.ServerURL, "https://") { log.Warn(). @@ -628,12 +629,11 @@ func (h *Headscale) getTLSSettings() (*tls.Config, error) { log.Warn().Msg("Listening without TLS but ServerURL does not start with http://") } - return nil, nil + return nil, err } else { if !strings.HasPrefix(h.cfg.ServerURL, "https://") { log.Warn().Msg("Listening with TLS but ServerURL does not start with https://") } - var err error tlsConfig := &tls.Config{} tlsConfig.ClientAuth = tls.RequireAnyClientCert tlsConfig.NextProtos = []string{"http/1.1"} From 19cd7a4eac85317cc8155d544d7baa1eb663b593 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Sun, 14 Nov 2021 17:52:55 +0100 Subject: [PATCH 142/300] Add and fix exhaustive --- .golangci.yaml | 1 - cmd/headscale/headscale.go | 2 ++ 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.golangci.yaml b/.golangci.yaml index 3006b0f4..e2e33296 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -43,7 +43,6 @@ linters: - forbidigo - dupl - goconst - - exhaustive - varnamelen # We might want to enable this, but it might be a lot of work diff --git a/cmd/headscale/headscale.go b/cmd/headscale/headscale.go index 8f436b9e..c6ac0043 100644 --- a/cmd/headscale/headscale.go +++ b/cmd/headscale/headscale.go @@ -23,6 +23,8 @@ func main() { colors = true case termcolor.LevelBasic: colors = true + case termcolor.LevelNone: + colors = false default: // no color, return text as is. colors = false From c9c16c7fb81e48bf43c60b9d55a87414f8eaebe7 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Sun, 14 Nov 2021 18:03:21 +0100 Subject: [PATCH 143/300] Remove unused params or returns --- .golangci.yaml | 5 ++--- api.go | 11 +---------- app.go | 6 +----- cmd/headscale/cli/nodes.go | 5 ++--- dns.go | 9 ++++----- dns_test.go | 12 ++++-------- poll.go | 2 +- 7 files changed, 15 insertions(+), 35 deletions(-) diff --git a/.golangci.yaml b/.golangci.yaml index e2e33296..a68f5359 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -29,21 +29,20 @@ linters: - testpackage - stylecheck - wrapcheck - - paralleltest - ifshort - gomnd - goerr113 - errorlint - forcetypeassert - errname - - unparam - - makezero - gosec - gocritic - forbidigo - dupl - goconst - varnamelen + - makezero + - paralleltest # We might want to enable this, but it might be a lot of work - cyclop diff --git a/api.go b/api.go index c8a307cf..d8d4b512 100644 --- a/api.go +++ b/api.go @@ -319,20 +319,12 @@ func (h *Headscale) getMapResponse( return nil, err } - dnsConfig, err := getMapResponseDNSConfig( + dnsConfig := getMapResponseDNSConfig( h.cfg.DNSConfig, h.cfg.BaseDomain, *m, peers, ) - if err != nil { - log.Error(). - Str("func", "getMapResponse"). - Err(err). - Msg("Failed generate the DNSConfig") - - return nil, err - } resp := tailcfg.MapResponse{ KeepAlive: false, @@ -378,7 +370,6 @@ func (h *Headscale) getMapResponse( func (h *Headscale) getMapKeepAliveResponse( mKey wgkey.Key, req tailcfg.MapRequest, - m *Machine, ) ([]byte, error) { resp := tailcfg.MapResponse{ KeepAlive: true, diff --git a/app.go b/app.go index 034f86f9..da4e8aa6 100644 --- a/app.go +++ b/app.go @@ -187,13 +187,9 @@ func NewHeadscale(cfg Config) (*Headscale, error) { } if h.cfg.DNSConfig != nil && h.cfg.DNSConfig.Proxied { // if MagicDNS - magicDNSDomains, err := generateMagicDNSRootDomains( + magicDNSDomains := generateMagicDNSRootDomains( h.cfg.IPPrefix, - h.cfg.BaseDomain, ) - if err != nil { - return nil, err - } // we might have routes already from Split DNS if h.cfg.DNSConfig.Routes == nil { h.cfg.DNSConfig.Routes = make(map[string][]dnstype.Resolver) diff --git a/cmd/headscale/cli/nodes.go b/cmd/headscale/cli/nodes.go index 6b2cf4a2..8398bd8c 100644 --- a/cmd/headscale/cli/nodes.go +++ b/cmd/headscale/cli/nodes.go @@ -266,7 +266,6 @@ var deleteNodeCmd = &cobra.Command{ func sharingWorker( cmd *cobra.Command, - args []string, ) (string, *v1.Machine, *v1.Namespace, error) { output, _ := cmd.Flags().GetString("output") namespaceStr, err := cmd.Flags().GetString("namespace") @@ -324,7 +323,7 @@ var shareMachineCmd = &cobra.Command{ Use: "share", Short: "Shares a node from the current namespace to the specified one", Run: func(cmd *cobra.Command, args []string) { - output, machine, namespace, err := sharingWorker(cmd, args) + output, machine, namespace, err := sharingWorker(cmd) if err != nil { ErrorOutput( err, @@ -363,7 +362,7 @@ var unshareMachineCmd = &cobra.Command{ Use: "unshare", Short: "Unshares a node from the specified namespace", Run: func(cmd *cobra.Command, args []string) { - output, machine, namespace, err := sharingWorker(cmd, args) + output, machine, namespace, err := sharingWorker(cmd) if err != nil { ErrorOutput( err, diff --git a/dns.go b/dns.go index e917e953..d50fae63 100644 --- a/dns.go +++ b/dns.go @@ -32,8 +32,7 @@ import ( // This allows us to then calculate the subnets included in the subsequent class block and generate the entries. func generateMagicDNSRootDomains( ipPrefix netaddr.IPPrefix, - baseDomain string, -) ([]dnsname.FQDN, error) { +) []dnsname.FQDN { // TODO(juanfont): we are not handing out IPv6 addresses yet // and in fact this is Tailscale.com's range (note the fd7a:115c:a1e0: range in the fc00::/7 network) ipv6base := dnsname.FQDN("0.e.1.a.c.5.1.1.a.7.d.f.ip6.arpa.") @@ -70,7 +69,7 @@ func generateMagicDNSRootDomains( fqdns = append(fqdns, fqdn) } - return fqdns, nil + return fqdns } func getMapResponseDNSConfig( @@ -78,7 +77,7 @@ func getMapResponseDNSConfig( baseDomain string, m Machine, peers Machines, -) (*tailcfg.DNSConfig, error) { +) *tailcfg.DNSConfig { var dnsConfig *tailcfg.DNSConfig if dnsConfigOrig != nil && dnsConfigOrig.Proxied { // if MagicDNS is enabled // Only inject the Search Domain of the current namespace - shared nodes should use their full FQDN @@ -101,5 +100,5 @@ func getMapResponseDNSConfig( dnsConfig = dnsConfigOrig } - return dnsConfig, nil + return dnsConfig } diff --git a/dns_test.go b/dns_test.go index 19cc803a..dfde8631 100644 --- a/dns_test.go +++ b/dns_test.go @@ -11,8 +11,7 @@ import ( func (s *Suite) TestMagicDNSRootDomains100(c *check.C) { prefix := netaddr.MustParseIPPrefix("100.64.0.0/10") - domains, err := generateMagicDNSRootDomains(prefix, "foobar.headscale.net") - c.Assert(err, check.IsNil) + domains := generateMagicDNSRootDomains(prefix) found := false for _, domain := range domains { @@ -47,8 +46,7 @@ func (s *Suite) TestMagicDNSRootDomains100(c *check.C) { func (s *Suite) TestMagicDNSRootDomains172(c *check.C) { prefix := netaddr.MustParseIPPrefix("172.16.0.0/16") - domains, err := generateMagicDNSRootDomains(prefix, "headscale.net") - c.Assert(err, check.IsNil) + domains := generateMagicDNSRootDomains(prefix) found := false for _, domain := range domains { @@ -178,8 +176,7 @@ func (s *Suite) TestDNSConfigMapResponseWithMagicDNS(c *check.C) { m1peers, err := h.getPeers(m1) c.Assert(err, check.IsNil) - dnsConfig, err := getMapResponseDNSConfig(&dnsConfigOrig, baseDomain, *m1, m1peers) - c.Assert(err, check.IsNil) + dnsConfig := getMapResponseDNSConfig(&dnsConfigOrig, baseDomain, *m1, m1peers) c.Assert(dnsConfig, check.NotNil) c.Assert(len(dnsConfig.Routes), check.Equals, 2) @@ -303,8 +300,7 @@ func (s *Suite) TestDNSConfigMapResponseWithoutMagicDNS(c *check.C) { m1peers, err := h.getPeers(m1) c.Assert(err, check.IsNil) - dnsConfig, err := getMapResponseDNSConfig(&dnsConfigOrig, baseDomain, *m1, m1peers) - c.Assert(err, check.IsNil) + dnsConfig := getMapResponseDNSConfig(&dnsConfigOrig, baseDomain, *m1, m1peers) c.Assert(dnsConfig, check.NotNil) c.Assert(len(dnsConfig.Routes), check.Equals, 0) c.Assert(len(dnsConfig.Domains), check.Equals, 1) diff --git a/poll.go b/poll.go index e3c5c663..47717998 100644 --- a/poll.go +++ b/poll.go @@ -492,7 +492,7 @@ func (h *Headscale) scheduledPollWorker( return case <-keepAliveTicker.C: - data, err := h.getMapKeepAliveResponse(mKey, req, m) + data, err := h.getMapKeepAliveResponse(mKey, req) if err != nil { log.Error(). Str("func", "keepAlive"). From 9390348a65597119c7c958bdb66c8ad54177c3de Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Sun, 14 Nov 2021 18:06:25 +0100 Subject: [PATCH 144/300] Add and fix goconst --- .golangci.yaml | 1 - app.go | 6 ++++-- db.go | 6 +++--- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/.golangci.yaml b/.golangci.yaml index a68f5359..b97922b1 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -39,7 +39,6 @@ linters: - gocritic - forbidigo - dupl - - goconst - varnamelen - makezero - paralleltest diff --git a/app.go b/app.go index da4e8aa6..9c66ca21 100644 --- a/app.go +++ b/app.go @@ -48,6 +48,8 @@ import ( const ( AUTH_PREFIX = "Bearer " + POSTGRESQL = "postgresql" + SQLITE = "sqlite3" ) // Config contains the initial Headscale configuration. @@ -150,7 +152,7 @@ func NewHeadscale(cfg Config) (*Headscale, error) { var dbString string switch cfg.DBtype { - case "postgres": + case POSTGRESQL: dbString = fmt.Sprintf( "host=%s port=%d dbname=%s user=%s password=%s sslmode=disable", cfg.DBhost, @@ -159,7 +161,7 @@ func NewHeadscale(cfg Config) (*Headscale, error) { cfg.DBuser, cfg.DBpass, ) - case "sqlite3": + case SQLITE: dbString = cfg.DBpath default: return nil, errors.New("unsupported DB") diff --git a/db.go b/db.go index b3490ef9..da81e301 100644 --- a/db.go +++ b/db.go @@ -24,7 +24,7 @@ func (h *Headscale) initDB() error { } h.db = db - if h.dbType == "postgres" { + if h.dbType == POSTGRESQL { db.Exec("create extension if not exists \"uuid-ossp\";") } err = db.AutoMigrate(&Machine{}) @@ -66,12 +66,12 @@ func (h *Headscale) openDB() (*gorm.DB, error) { } switch h.dbType { - case "sqlite3": + case SQLITE: db, err = gorm.Open(sqlite.Open(h.dbString), &gorm.Config{ DisableForeignKeyConstraintWhenMigrating: true, Logger: log, }) - case "postgres": + case POSTGRESQL: db, err = gorm.Open(postgres.Open(h.dbString), &gorm.Config{ DisableForeignKeyConstraintWhenMigrating: true, Logger: log, From 796072a5a44d81c388a794b264078ef0b1486c48 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Sun, 14 Nov 2021 18:09:22 +0100 Subject: [PATCH 145/300] Add and fix ifshort --- .golangci.yaml | 1 - cmd/headscale/cli/utils.go | 3 +-- cmd/headscale/headscale.go | 3 +-- db.go | 3 +-- machine.go | 3 +-- oidc.go | 3 +-- 6 files changed, 5 insertions(+), 11 deletions(-) diff --git a/.golangci.yaml b/.golangci.yaml index b97922b1..8edc1b5a 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -29,7 +29,6 @@ linters: - testpackage - stylecheck - wrapcheck - - ifshort - gomnd - goerr113 - errorlint diff --git a/cmd/headscale/cli/utils.go b/cmd/headscale/cli/utils.go index 80bded8a..343ebe30 100644 --- a/cmd/headscale/cli/utils.go +++ b/cmd/headscale/cli/utils.go @@ -52,8 +52,7 @@ func LoadConfig(path string) error { viper.SetDefault("cli.insecure", false) viper.SetDefault("cli.timeout", "5s") - err := viper.ReadInConfig() - if err != nil { + if err := viper.ReadInConfig(); err != nil { return fmt.Errorf("Fatal error reading config file: %s \n", err) } diff --git a/cmd/headscale/headscale.go b/cmd/headscale/headscale.go index c6ac0043..f3352474 100644 --- a/cmd/headscale/headscale.go +++ b/cmd/headscale/headscale.go @@ -43,8 +43,7 @@ func main() { NoColor: !colors, }) - err := cli.LoadConfig("") - if err != nil { + if err := cli.LoadConfig(""); err != nil { log.Fatal().Err(err) } diff --git a/db.go b/db.go index da81e301..77d4ba03 100644 --- a/db.go +++ b/db.go @@ -105,8 +105,7 @@ func (h *Headscale) setValue(key string, value string) error { Value: value, } - _, err := h.getValue(key) - if err == nil { + if _, err := h.getValue(key); err == nil { h.db.Model(&kv).Where("key = ?", key).Update("value", value) return nil diff --git a/machine.go b/machine.go index e0fe2a3e..6443c828 100644 --- a/machine.go +++ b/machine.go @@ -331,8 +331,7 @@ func (m *Machine) GetHostInfo() (*tailcfg.Hostinfo, error) { } func (h *Headscale) isOutdated(m *Machine) bool { - err := h.UpdateMachine(m) - if err != nil { + if err := h.UpdateMachine(m); err != nil { // It does not seem meaningful to propagate this error as the end result // will have to be that the machine has to be considered outdated. return true diff --git a/oidc.go b/oidc.go index 63a1abe0..234a0bf3 100644 --- a/oidc.go +++ b/oidc.go @@ -68,8 +68,7 @@ func (h *Headscale) RegisterOIDC(c *gin.Context) { } b := make([]byte, 16) - _, err := rand.Read(b) - if err != nil { + if _, err := rand.Read(b); err != nil { log.Error().Msg("could not read 16 bytes from rand") c.String(http.StatusInternalServerError, "could not read 16 bytes from rand") From 85f28a3f4ad44f6404b44bd9643a135e662640fe Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Sun, 14 Nov 2021 18:31:51 +0100 Subject: [PATCH 146/300] Remove all instances of undefined numbers (gonmd) --- .golangci.yaml | 1 - acls.go | 24 +++++++++++++++++------- api.go | 22 ++++++++++++---------- app.go | 15 ++++++++------- cmd/headscale/cli/namespaces.go | 3 ++- cmd/headscale/cli/nodes.go | 3 ++- cmd/headscale/cli/preauthkeys.go | 6 +++++- derp.go | 4 ++-- dns.go | 8 ++++++-- machine.go | 2 +- namespaces.go | 2 +- oidc.go | 15 ++++++++++++--- poll.go | 13 +++++++++---- preauth_keys.go | 2 +- 14 files changed, 78 insertions(+), 42 deletions(-) diff --git a/.golangci.yaml b/.golangci.yaml index 8edc1b5a..9b1e2389 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -29,7 +29,6 @@ linters: - testpackage - stylecheck - wrapcheck - - gomnd - goerr113 - errorlint - forcetypeassert diff --git a/acls.go b/acls.go index a5e54400..994b8963 100644 --- a/acls.go +++ b/acls.go @@ -24,6 +24,14 @@ const ( errorInvalidPortFormat = Error("invalid port format") ) +const ( + PORT_RANGE_BEGIN = 0 + PORT_RANGE_END = 65535 + BASE_10 = 10 + BIT_SIZE_16 = 16 + EXPECTED_TOKEN_ITEMS = 2 +) + // LoadACLPolicy loads the ACL policy from the specify path, and generates the ACL rules. func (h *Headscale) LoadACLPolicy(path string) error { policyFile, err := os.Open(path) @@ -114,7 +122,7 @@ func (h *Headscale) generateACLPolicyDestPorts( d string, ) ([]tailcfg.NetPortRange, error) { tokens := strings.Split(d, ":") - if len(tokens) < 2 || len(tokens) > 3 { + if len(tokens) < EXPECTED_TOKEN_ITEMS || len(tokens) > 3 { return nil, errorInvalidPortFormat } @@ -125,7 +133,7 @@ func (h *Headscale) generateACLPolicyDestPorts( // tag:montreal-webserver:80,443 // tag:api-server:443 // example-host-1:* - if len(tokens) == 2 { + if len(tokens) == EXPECTED_TOKEN_ITEMS { alias = tokens[0] } else { alias = fmt.Sprintf("%s:%s", tokens[0], tokens[1]) @@ -248,14 +256,16 @@ func (h *Headscale) expandAlias(s string) ([]string, error) { func (h *Headscale) expandPorts(s string) (*[]tailcfg.PortRange, error) { if s == "*" { - return &[]tailcfg.PortRange{{First: 0, Last: 65535}}, nil + return &[]tailcfg.PortRange{ + {First: PORT_RANGE_BEGIN, Last: PORT_RANGE_END}, + }, nil } ports := []tailcfg.PortRange{} for _, p := range strings.Split(s, ",") { rang := strings.Split(p, "-") if len(rang) == 1 { - pi, err := strconv.ParseUint(rang[0], 10, 16) + pi, err := strconv.ParseUint(rang[0], BASE_10, BIT_SIZE_16) if err != nil { return nil, err } @@ -263,12 +273,12 @@ func (h *Headscale) expandPorts(s string) (*[]tailcfg.PortRange, error) { First: uint16(pi), Last: uint16(pi), }) - } else if len(rang) == 2 { - start, err := strconv.ParseUint(rang[0], 10, 16) + } else if len(rang) == EXPECTED_TOKEN_ITEMS { + start, err := strconv.ParseUint(rang[0], BASE_10, BIT_SIZE_16) if err != nil { return nil, err } - last, err := strconv.ParseUint(rang[1], 10, 16) + last, err := strconv.ParseUint(rang[1], BASE_10, BIT_SIZE_16) if err != nil { return nil, err } diff --git a/api.go b/api.go index d8d4b512..211b4868 100644 --- a/api.go +++ b/api.go @@ -18,10 +18,12 @@ import ( "tailscale.com/types/wgkey" ) +const RESERVED_RESPONSE_HEADER_SIZE = 4 + // KeyHandler provides the Headscale pub key // Listens in /key. func (h *Headscale) KeyHandler(c *gin.Context) { - c.Data(200, "text/plain; charset=utf-8", []byte(h.publicKey.HexString())) + c.Data(http.StatusOK, "text/plain; charset=utf-8", []byte(h.publicKey.HexString())) } // RegisterWebAPI shows a simple message in the browser to point to the CLI @@ -139,7 +141,7 @@ func (h *Headscale) RegistrationHandler(c *gin.Context) { return } - c.Data(200, "application/json; charset=utf-8", respBody) + c.Data(http.StatusOK, "application/json; charset=utf-8", respBody) return } @@ -170,7 +172,7 @@ func (h *Headscale) RegistrationHandler(c *gin.Context) { } machineRegistrations.WithLabelValues("update", "web", "success", m.Namespace.Name). Inc() - c.Data(200, "application/json; charset=utf-8", respBody) + c.Data(http.StatusOK, "application/json; charset=utf-8", respBody) return } @@ -213,7 +215,7 @@ func (h *Headscale) RegistrationHandler(c *gin.Context) { } machineRegistrations.WithLabelValues("new", "web", "success", m.Namespace.Name). Inc() - c.Data(200, "application/json; charset=utf-8", respBody) + c.Data(http.StatusOK, "application/json; charset=utf-8", respBody) return } @@ -239,7 +241,7 @@ func (h *Headscale) RegistrationHandler(c *gin.Context) { return } - c.Data(200, "application/json; charset=utf-8", respBody) + c.Data(http.StatusOK, "application/json; charset=utf-8", respBody) return } @@ -275,7 +277,7 @@ func (h *Headscale) RegistrationHandler(c *gin.Context) { return } - c.Data(200, "application/json; charset=utf-8", respBody) + c.Data(http.StatusOK, "application/json; charset=utf-8", respBody) } func (h *Headscale) getMapResponse( @@ -360,7 +362,7 @@ func (h *Headscale) getMapResponse( } } // declare the incoming size on the first 4 bytes - data := make([]byte, 4) + data := make([]byte, RESERVED_RESPONSE_HEADER_SIZE) binary.LittleEndian.PutUint32(data, uint32(len(respBody))) data = append(data, respBody...) @@ -390,7 +392,7 @@ func (h *Headscale) getMapKeepAliveResponse( return nil, err } } - data := make([]byte, 4) + data := make([]byte, RESERVED_RESPONSE_HEADER_SIZE) binary.LittleEndian.PutUint32(data, uint32(len(respBody))) data = append(data, respBody...) @@ -430,7 +432,7 @@ func (h *Headscale) handleAuthKey( return } - c.Data(401, "application/json; charset=utf-8", respBody) + c.Data(http.StatusUnauthorized, "application/json; charset=utf-8", respBody) log.Error(). Str("func", "handleAuthKey"). Str("machine", m.Name). @@ -490,7 +492,7 @@ func (h *Headscale) handleAuthKey( } machineRegistrations.WithLabelValues("new", "authkey", "success", m.Namespace.Name). Inc() - c.Data(200, "application/json; charset=utf-8", respBody) + c.Data(http.StatusOK, "application/json; charset=utf-8", respBody) log.Info(). Str("func", "handleAuthKey"). Str("machine", m.Name). diff --git a/app.go b/app.go index 9c66ca21..5b732d56 100644 --- a/app.go +++ b/app.go @@ -47,9 +47,11 @@ import ( ) const ( - AUTH_PREFIX = "Bearer " - POSTGRESQL = "postgresql" - SQLITE = "sqlite3" + AUTH_PREFIX = "Bearer " + POSTGRESQL = "postgresql" + SQLITE = "sqlite3" + UPDATE_RATE_MILLISECONDS = 5000 + HTTP_READ_TIMEOUT = 30 * time.Second ) // Config contains the initial Headscale configuration. @@ -507,14 +509,13 @@ func (h *Headscale) Serve() error { } // I HATE THIS - updateMillisecondsWait := int64(5000) - go h.watchForKVUpdates(updateMillisecondsWait) - go h.expireEphemeralNodes(updateMillisecondsWait) + go h.watchForKVUpdates(UPDATE_RATE_MILLISECONDS) + go h.expireEphemeralNodes(UPDATE_RATE_MILLISECONDS) httpServer := &http.Server{ Addr: h.cfg.Addr, Handler: r, - ReadTimeout: 30 * time.Second, + ReadTimeout: HTTP_READ_TIMEOUT, // Go does not handle timeouts in HTTP very well, and there is // no good way to handle streaming timeouts, therefore we need to // keep this at unlimited and be careful to clean up connections diff --git a/cmd/headscale/cli/namespaces.go b/cmd/headscale/cli/namespaces.go index 9e1be07f..8c69ac56 100644 --- a/cmd/headscale/cli/namespaces.go +++ b/cmd/headscale/cli/namespaces.go @@ -195,7 +195,8 @@ var renameNamespaceCmd = &cobra.Command{ Use: "rename OLD_NAME NEW_NAME", Short: "Renames a namespace", Args: func(cmd *cobra.Command, args []string) error { - if len(args) < 2 { + expectedArguments := 2 + if len(args) < expectedArguments { return fmt.Errorf("Missing parameters") } diff --git a/cmd/headscale/cli/nodes.go b/cmd/headscale/cli/nodes.go index 8398bd8c..83d6b1f5 100644 --- a/cmd/headscale/cli/nodes.go +++ b/cmd/headscale/cli/nodes.go @@ -7,6 +7,7 @@ import ( "time" survey "github.com/AlecAivazis/survey/v2" + "github.com/juanfont/headscale" v1 "github.com/juanfont/headscale/gen/go/headscale/v1" "github.com/pterm/pterm" "github.com/spf13/cobra" @@ -450,7 +451,7 @@ func nodesToPtables( d = append( d, []string{ - strconv.FormatUint(machine.Id, 10), + strconv.FormatUint(machine.Id, headscale.BASE_10), machine.Name, nodeKey.ShortString(), namespace, diff --git a/cmd/headscale/cli/preauthkeys.go b/cmd/headscale/cli/preauthkeys.go index 55df5aa2..13a30942 100644 --- a/cmd/headscale/cli/preauthkeys.go +++ b/cmd/headscale/cli/preauthkeys.go @@ -12,6 +12,10 @@ import ( "google.golang.org/protobuf/types/known/timestamppb" ) +const ( + DEFAULT_PRE_AUTH_KEY_EXPIRY = 24 * time.Hour +) + func init() { rootCmd.AddCommand(preauthkeysCmd) preauthkeysCmd.PersistentFlags().StringP("namespace", "n", "", "Namespace") @@ -27,7 +31,7 @@ func init() { createPreAuthKeyCmd.PersistentFlags(). Bool("ephemeral", false, "Preauthkey for ephemeral nodes") createPreAuthKeyCmd.Flags(). - DurationP("expiration", "e", 24*time.Hour, "Human-readable expiration of the key (30m, 24h, 365d...)") + DurationP("expiration", "e", DEFAULT_PRE_AUTH_KEY_EXPIRY, "Human-readable expiration of the key (30m, 24h, 365d...)") } var preauthkeysCmd = &cobra.Command{ diff --git a/derp.go b/derp.go index a2481acf..cf128a88 100644 --- a/derp.go +++ b/derp.go @@ -32,7 +32,7 @@ func loadDERPMapFromPath(path string) (*tailcfg.DERPMap, error) { } func loadDERPMapFromURL(addr url.URL) (*tailcfg.DERPMap, error) { - ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + ctx, cancel := context.WithTimeout(context.Background(), HTTP_READ_TIMEOUT) defer cancel() req, err := http.NewRequestWithContext(ctx, "GET", addr.String(), nil) @@ -41,7 +41,7 @@ func loadDERPMapFromURL(addr url.URL) (*tailcfg.DERPMap, error) { } client := http.Client{ - Timeout: 10 * time.Second, + Timeout: HTTP_READ_TIMEOUT, } resp, err := client.Do(req) diff --git a/dns.go b/dns.go index d50fae63..d7480b15 100644 --- a/dns.go +++ b/dns.go @@ -10,6 +10,10 @@ import ( "tailscale.com/util/dnsname" ) +const ( + BYTE_SIZE = 8 +) + // generateMagicDNSRootDomains generates a list of DNS entries to be included in `Routes` in `MapResponse`. // This list of reverse DNS entries instructs the OS on what subnets and domains the Tailscale embedded DNS // server (listening in 100.100.100.100 udp/53) should be used for. @@ -43,10 +47,10 @@ func generateMagicDNSRootDomains( maskBits, _ := netRange.Mask.Size() // lastOctet is the last IP byte covered by the mask - lastOctet := maskBits / 8 + lastOctet := maskBits / BYTE_SIZE // wildcardBits is the number of bits not under the mask in the lastOctet - wildcardBits := 8 - maskBits%8 + wildcardBits := BYTE_SIZE - maskBits%BYTE_SIZE // min is the value in the lastOctet byte of the IP // max is basically 2^wildcardBits - i.e., the value when all the wildcardBits are set to 1 diff --git a/machine.go b/machine.go index 6443c828..e8d2f72a 100644 --- a/machine.go +++ b/machine.go @@ -523,7 +523,7 @@ func (m Machine) toNode( n := tailcfg.Node{ ID: tailcfg.NodeID(m.ID), // this is the actual ID StableID: tailcfg.StableNodeID( - strconv.FormatUint(m.ID, 10), + strconv.FormatUint(m.ID, BASE_10), ), // in headscale, unlike tailcontrol server, IDs are permanent Name: hostname, User: tailcfg.UserID(m.NamespaceID), diff --git a/namespaces.go b/namespaces.go index d3ef8242..bea922de 100644 --- a/namespaces.go +++ b/namespaces.go @@ -320,7 +320,7 @@ func getMapResponseUserProfiles(m Machine, peers Machines) []tailcfg.UserProfile func (n *Namespace) toProto() *v1.Namespace { return &v1.Namespace{ - Id: strconv.FormatUint(uint64(n.ID), 10), + Id: strconv.FormatUint(uint64(n.ID), BASE_10), Name: n.Name, CreatedAt: timestamppb.New(n.CreatedAt), } diff --git a/oidc.go b/oidc.go index 234a0bf3..aea89e20 100644 --- a/oidc.go +++ b/oidc.go @@ -17,6 +17,12 @@ import ( "golang.org/x/oauth2" ) +const ( + OIDC_STATE_CACHE_EXPIRATION = time.Minute * 5 + OIDC_STATE_CACHE_CLEANUP_INTERVAL = time.Minute * 10 + RANDOM_BYTE_SIZE = 16 +) + type IDTokenClaims struct { Name string `json:"name,omitempty"` Groups []string `json:"groups,omitempty"` @@ -50,7 +56,10 @@ func (h *Headscale) initOIDC() error { // init the state cache if it hasn't been already if h.oidcStateCache == nil { - h.oidcStateCache = cache.New(time.Minute*5, time.Minute*10) + h.oidcStateCache = cache.New( + OIDC_STATE_CACHE_EXPIRATION, + OIDC_STATE_CACHE_CLEANUP_INTERVAL, + ) } return nil @@ -67,7 +76,7 @@ func (h *Headscale) RegisterOIDC(c *gin.Context) { return } - b := make([]byte, 16) + b := make([]byte, RANDOM_BYTE_SIZE) if _, err := rand.Read(b); err != nil { log.Error().Msg("could not read 16 bytes from rand") c.String(http.StatusInternalServerError, "could not read 16 bytes from rand") @@ -78,7 +87,7 @@ func (h *Headscale) RegisterOIDC(c *gin.Context) { stateStr := hex.EncodeToString(b)[:32] // place the machine key into the state cache, so it can be retrieved later - h.oidcStateCache.Set(stateStr, mKeyStr, time.Minute*5) + h.oidcStateCache.Set(stateStr, mKeyStr, OIDC_STATE_CACHE_EXPIRATION) authUrl := h.oauth2Config.AuthCodeURL(stateStr) log.Debug().Msgf("Redirecting to %s for authentication", authUrl) diff --git a/poll.go b/poll.go index 47717998..3f7b2939 100644 --- a/poll.go +++ b/poll.go @@ -15,6 +15,11 @@ import ( "tailscale.com/types/wgkey" ) +const ( + KEEP_ALIVE_INTERVAL = 60 * time.Second + UPDATE_CHECK_INTERVAL = 10 * time.Second +) + // PollNetMapHandler takes care of /machine/:id/map // // This is the busiest endpoint, as it keeps the HTTP long poll that updates @@ -127,7 +132,7 @@ func (h *Headscale) PollNetMapHandler(c *gin.Context) { Str("handler", "PollNetMap"). Str("machine", m.Name). Msg("Client is starting up. Probably interested in a DERP map") - c.Data(200, "application/json; charset=utf-8", data) + c.Data(http.StatusOK, "application/json; charset=utf-8", data) return } @@ -159,7 +164,7 @@ func (h *Headscale) PollNetMapHandler(c *gin.Context) { Str("handler", "PollNetMap"). Str("machine", m.Name). Msg("Client sent endpoint update and is ok with a response without peer list") - c.Data(200, "application/json; charset=utf-8", data) + c.Data(http.StatusOK, "application/json; charset=utf-8", data) // It sounds like we should update the nodes when we have received a endpoint update // even tho the comments in the tailscale code dont explicitly say so. @@ -483,8 +488,8 @@ func (h *Headscale) scheduledPollWorker( req tailcfg.MapRequest, m *Machine, ) { - keepAliveTicker := time.NewTicker(60 * time.Second) - updateCheckerTicker := time.NewTicker(10 * time.Second) + keepAliveTicker := time.NewTicker(KEEP_ALIVE_INTERVAL) + updateCheckerTicker := time.NewTicker(UPDATE_CHECK_INTERVAL) for { select { diff --git a/preauth_keys.go b/preauth_keys.go index a477d985..1a00077a 100644 --- a/preauth_keys.go +++ b/preauth_keys.go @@ -156,7 +156,7 @@ func (h *Headscale) generateKey() (string, error) { func (key *PreAuthKey) toProto() *v1.PreAuthKey { protoKey := v1.PreAuthKey{ Namespace: key.Namespace.Name, - Id: strconv.FormatUint(key.ID, 10), + Id: strconv.FormatUint(key.ID, BASE_10), Key: key.Key, Ephemeral: key.Ephemeral, Reusable: key.Reusable, From ba084b99874413341d348ecff1ecd171e685ab11 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Sun, 14 Nov 2021 18:35:49 +0100 Subject: [PATCH 147/300] Lint fix integration tests --- integration_cli_test.go | 2 +- integration_common_test.go | 6 +++++- integration_test.go | 11 +++++++---- 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/integration_cli_test.go b/integration_cli_test.go index 335768c9..898e2cd7 100644 --- a/integration_cli_test.go +++ b/integration_cli_test.go @@ -88,6 +88,7 @@ func (s *IntegrationCLITestSuite) SetupTest() { if resp.StatusCode != http.StatusOK { return fmt.Errorf("status code not OK") } + return nil }); err != nil { // TODO(kradalby): If we cannot access headscale, or any other fatal error during @@ -147,7 +148,6 @@ func (s *IntegrationCLITestSuite) TestNamespaceCommand() { namespaces := make([]*v1.Namespace, len(names)) for index, namespaceName := range names { - namespace, err := s.createNamespace(namespaceName) assert.Nil(s.T(), err) diff --git a/integration_common_test.go b/integration_common_test.go index 6540012b..31bae514 100644 --- a/integration_common_test.go +++ b/integration_common_test.go @@ -12,6 +12,8 @@ import ( "github.com/ory/dockertest/v3/docker" ) +const DOCKER_EXECUTE_TIMEOUT = 10 * time.Second + func ExecuteCommand( resource *dockertest.Resource, cmd []string, @@ -21,7 +23,7 @@ func ExecuteCommand( var stderr bytes.Buffer // TODO(kradalby): Make configurable - timeout := 10 * time.Second + timeout := DOCKER_EXECUTE_TIMEOUT type result struct { exitCode int @@ -55,11 +57,13 @@ func ExecuteCommand( fmt.Println("Command: ", cmd) fmt.Println("stdout: ", stdout.String()) fmt.Println("stderr: ", stderr.String()) + return "", fmt.Errorf("command failed with: %s", stderr.String()) } return stdout.String(), nil case <-time.After(timeout): + return "", fmt.Errorf("command timed out after %s", timeout) } } diff --git a/integration_test.go b/integration_test.go index dc5a83c2..ddbf19d5 100644 --- a/integration_test.go +++ b/integration_test.go @@ -23,10 +23,9 @@ import ( "github.com/ory/dockertest/v3/docker" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/suite" + "inet.af/netaddr" "tailscale.com/client/tailscale/apitype" "tailscale.com/ipn/ipnstate" - - "inet.af/netaddr" ) var tailscaleVersions = []string{"1.16.2", "1.14.3", "1.12.3"} @@ -180,6 +179,7 @@ func (s *IntegrationTestSuite) tailscaleContainer( log.Fatalf("Could not start resource: %s", err) } fmt.Printf("Created %s container\n", hostname) + return hostname, pts } @@ -248,13 +248,16 @@ func (s *IntegrationTestSuite) SetupSuite() { if err := s.pool.Retry(func() error { url := fmt.Sprintf("http://%s/health", hostEndpoint) + resp, err := http.Get(url) if err != nil { return err } + if resp.StatusCode != http.StatusOK { return fmt.Errorf("status code not OK") } + return nil }); err != nil { // TODO(kradalby): If we cannot access headscale, or any other fatal error during @@ -507,7 +510,6 @@ func (s *IntegrationTestSuite) TestSharedNodes() { assert.Nil(s.T(), err) for _, machine := range machineList { - result, err := ExecuteCommand( &s.headscale, []string{ @@ -607,7 +609,6 @@ func (s *IntegrationTestSuite) TestTailDrop() { for peername, ip := range ips { s.T().Run(fmt.Sprintf("%s-%s", hostname, peername), func(t *testing.T) { if peername != hostname { - // Under normal circumstances, we should be able to send a file // using `tailscale file cp` - but not in userspace networking mode // So curl! @@ -770,6 +771,7 @@ func getIPs(tailscales map[string]dockertest.Resource) (map[string]netaddr.IP, e ips[hostname] = ip } + return ips, nil } @@ -809,5 +811,6 @@ func getAPIURLs( } } } + return fts, nil } From 53ed749f4546da9fc5972da9d2e4d6f7ee1a259f Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Sun, 14 Nov 2021 18:44:37 +0100 Subject: [PATCH 148/300] Start work on making gocritic pass --- .golangci.yaml | 4 +++- acls.go | 9 ++++++--- acls_types.go | 2 +- app.go | 17 ++++++++++------- oidc.go | 10 +++++----- sharing_test.go | 4 ++-- 6 files changed, 27 insertions(+), 19 deletions(-) diff --git a/.golangci.yaml b/.golangci.yaml index 9b1e2389..b4ad0892 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -25,6 +25,9 @@ linters: - godox - ireturn + # In progress + - gocritic + # We should strive to enable these: - testpackage - stylecheck @@ -34,7 +37,6 @@ linters: - forcetypeassert - errname - gosec - - gocritic - forbidigo - dupl - varnamelen diff --git a/acls.go b/acls.go index 994b8963..fdcb0983 100644 --- a/acls.go +++ b/acls.go @@ -264,7 +264,8 @@ func (h *Headscale) expandPorts(s string) (*[]tailcfg.PortRange, error) { ports := []tailcfg.PortRange{} for _, p := range strings.Split(s, ",") { rang := strings.Split(p, "-") - if len(rang) == 1 { + switch len(rang) { + case 1: pi, err := strconv.ParseUint(rang[0], BASE_10, BIT_SIZE_16) if err != nil { return nil, err @@ -273,7 +274,8 @@ func (h *Headscale) expandPorts(s string) (*[]tailcfg.PortRange, error) { First: uint16(pi), Last: uint16(pi), }) - } else if len(rang) == EXPECTED_TOKEN_ITEMS { + + case EXPECTED_TOKEN_ITEMS: start, err := strconv.ParseUint(rang[0], BASE_10, BIT_SIZE_16) if err != nil { return nil, err @@ -286,7 +288,8 @@ func (h *Headscale) expandPorts(s string) (*[]tailcfg.PortRange, error) { First: uint16(start), Last: uint16(last), }) - } else { + + default: return nil, errorInvalidPortFormat } } diff --git a/acls_types.go b/acls_types.go index 63f79ba0..8611d905 100644 --- a/acls_types.go +++ b/acls_types.go @@ -56,7 +56,7 @@ func (h *Hosts) UnmarshalJSON(data []byte) error { } for k, v := range hs { if !strings.Contains(v, "/") { - v = v + "/32" + v += "/32" } prefix, err := netaddr.ParseIPPrefix(v) if err != nil { diff --git a/app.go b/app.go index 5b732d56..af51efd2 100644 --- a/app.go +++ b/app.go @@ -345,10 +345,10 @@ func (h *Headscale) grpcAuthenticationInterceptor(ctx context.Context, "Authentication is not implemented yet", ) - //if strings.TrimPrefix(token, AUTH_PREFIX) != a.Token { - // log.Error().Caller().Str("client_address", p.Addr.String()).Msg("invalid token") - // return ctx, status.Error(codes.Unauthenticated, "invalid token") - //} + // if strings.TrimPrefix(token, AUTH_PREFIX) != a.Token { + // log.Error().Caller().Str("client_address", p.Addr.String()).Msg("invalid token") + // return ctx, status.Error(codes.Unauthenticated, "invalid token") + // } // return handler(ctx, req) } @@ -604,12 +604,14 @@ func (h *Headscale) getTLSSettings() (*tls.Config, error) { Email: h.cfg.ACMEEmail, } - if h.cfg.TLSLetsEncryptChallengeType == "TLS-ALPN-01" { + switch h.cfg.TLSLetsEncryptChallengeType { + case "TLS-ALPN-01": // Configuration via autocert with TLS-ALPN-01 (https://tools.ietf.org/html/rfc8737) // The RFC requires that the validation is done on port 443; in other words, headscale // must be reachable on port 443. return m.TLSConfig(), nil - } else if h.cfg.TLSLetsEncryptChallengeType == "HTTP-01" { + + case "HTTP-01": // Configuration via autocert with HTTP-01. This requires listening on // port 80 for the certificate validation in addition to the headscale // service, which can be configured to run on any other port. @@ -620,7 +622,8 @@ func (h *Headscale) getTLSSettings() (*tls.Config, error) { }() return m.TLSConfig(), nil - } else { + + default: return nil, errors.New("unknown value for TLSLetsEncryptChallengeType") } } else if h.cfg.TLSCertPath == "" { diff --git a/oidc.go b/oidc.go index aea89e20..c77a249e 100644 --- a/oidc.go +++ b/oidc.go @@ -136,11 +136,11 @@ func (h *Headscale) OIDCCallback(c *gin.Context) { } // TODO: we can use userinfo at some point to grab additional information about the user (groups membership, etc) - //userInfo, err := oidcProvider.UserInfo(context.Background(), oauth2.StaticTokenSource(oauth2Token)) - //if err != nil { - // c.String(http.StatusBadRequest, fmt.Sprintf("Failed to retrieve userinfo: %s", err)) - // return - //} + // userInfo, err := oidcProvider.UserInfo(context.Background(), oauth2.StaticTokenSource(oauth2Token)) + // if err != nil { + // c.String(http.StatusBadRequest, fmt.Sprintf("Failed to retrieve userinfo: %s", err)) + // return + // } // Extract custom claims var claims IDTokenClaims diff --git a/sharing_test.go b/sharing_test.go index 7d63a745..395b8336 100644 --- a/sharing_test.go +++ b/sharing_test.go @@ -6,7 +6,7 @@ import ( func CreateNodeNamespace( c *check.C, - namespace, node, key, IP string, + namespace, node, key, ip string, ) (*Namespace, *Machine) { n1, err := h.CreateNamespace(namespace) c.Assert(err, check.IsNil) @@ -26,7 +26,7 @@ func CreateNodeNamespace( NamespaceID: n1.ID, Registered: true, RegisterMethod: "authKey", - IPAddress: IP, + IPAddress: ip, AuthKeyID: uint(pak1.ID), } h.db.Save(m1) From 471c0b49935d662bdee34378b5000836c0e8fa56 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Sun, 14 Nov 2021 20:32:03 +0100 Subject: [PATCH 149/300] Initial work eliminating one/two letter variables --- .golangci.yaml | 4 +- acls.go | 74 ++++---- acls_types.go | 24 +-- api.go | 229 +++++++++++------------ app.go | 140 ++++++++------- apple_mobileconfig.go | 28 +-- cmd/headscale/cli/namespaces.go | 8 +- cmd/headscale/cli/nodes.go | 22 +-- cmd/headscale/cli/preauthkeys.go | 30 ++-- cmd/headscale/cli/routes.go | 14 +- cmd/headscale/cli/utils.go | 6 +- dns.go | 6 +- machine.go | 299 ++++++++++++++++--------------- namespaces.go | 81 ++++----- oidc.go | 69 +++---- poll.go | 8 +- sharing.go | 32 ++-- swagger.go | 14 +- utils.go | 12 +- 19 files changed, 568 insertions(+), 532 deletions(-) diff --git a/.golangci.yaml b/.golangci.yaml index b4ad0892..f7fc0c67 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -28,6 +28,9 @@ linters: # In progress - gocritic + # TODO: approve: ok, db, id + - varnamelen + # We should strive to enable these: - testpackage - stylecheck @@ -39,7 +42,6 @@ linters: - gosec - forbidigo - dupl - - varnamelen - makezero - paralleltest diff --git a/acls.go b/acls.go index fdcb0983..01de114e 100644 --- a/acls.go +++ b/acls.go @@ -41,18 +41,18 @@ func (h *Headscale) LoadACLPolicy(path string) error { defer policyFile.Close() var policy ACLPolicy - b, err := io.ReadAll(policyFile) + policyBytes, err := io.ReadAll(policyFile) if err != nil { return err } - ast, err := hujson.Parse(b) + ast, err := hujson.Parse(policyBytes) if err != nil { return err } ast.Standardize() - b = ast.Pack() - err = json.Unmarshal(b, &policy) + policyBytes = ast.Pack() + err = json.Unmarshal(policyBytes, &policy) if err != nil { return err } @@ -73,32 +73,32 @@ func (h *Headscale) LoadACLPolicy(path string) error { func (h *Headscale) generateACLRules() ([]tailcfg.FilterRule, error) { rules := []tailcfg.FilterRule{} - for i, a := range h.aclPolicy.ACLs { - if a.Action != "accept" { + for index, acl := range h.aclPolicy.ACLs { + if acl.Action != "accept" { return nil, errorInvalidAction } - r := tailcfg.FilterRule{} + filterRule := tailcfg.FilterRule{} srcIPs := []string{} - for j, u := range a.Users { - srcs, err := h.generateACLPolicySrcIP(u) + for innerIndex, user := range acl.Users { + srcs, err := h.generateACLPolicySrcIP(user) if err != nil { log.Error(). - Msgf("Error parsing ACL %d, User %d", i, j) + Msgf("Error parsing ACL %d, User %d", index, innerIndex) return nil, err } srcIPs = append(srcIPs, srcs...) } - r.SrcIPs = srcIPs + filterRule.SrcIPs = srcIPs destPorts := []tailcfg.NetPortRange{} - for j, d := range a.Ports { - dests, err := h.generateACLPolicyDestPorts(d) + for innerIndex, ports := range acl.Ports { + dests, err := h.generateACLPolicyDestPorts(ports) if err != nil { log.Error(). - Msgf("Error parsing ACL %d, Port %d", i, j) + Msgf("Error parsing ACL %d, Port %d", index, innerIndex) return nil, err } @@ -162,17 +162,17 @@ func (h *Headscale) generateACLPolicyDestPorts( return dests, nil } -func (h *Headscale) expandAlias(s string) ([]string, error) { - if s == "*" { +func (h *Headscale) expandAlias(alias string) ([]string, error) { + if alias == "*" { return []string{"*"}, nil } - if strings.HasPrefix(s, "group:") { - if _, ok := h.aclPolicy.Groups[s]; !ok { + if strings.HasPrefix(alias, "group:") { + if _, ok := h.aclPolicy.Groups[alias]; !ok { return nil, errorInvalidGroup } ips := []string{} - for _, n := range h.aclPolicy.Groups[s] { + for _, n := range h.aclPolicy.Groups[alias] { nodes, err := h.ListMachinesInNamespace(n) if err != nil { return nil, errorInvalidNamespace @@ -185,8 +185,8 @@ func (h *Headscale) expandAlias(s string) ([]string, error) { return ips, nil } - if strings.HasPrefix(s, "tag:") { - if _, ok := h.aclPolicy.TagOwners[s]; !ok { + if strings.HasPrefix(alias, "tag:") { + if _, ok := h.aclPolicy.TagOwners[alias]; !ok { return nil, errorInvalidTag } @@ -197,10 +197,10 @@ func (h *Headscale) expandAlias(s string) ([]string, error) { return nil, err } ips := []string{} - for _, m := range machines { + for _, machine := range machines { hostinfo := tailcfg.Hostinfo{} - if len(m.HostInfo) != 0 { - hi, err := m.HostInfo.MarshalJSON() + if len(machine.HostInfo) != 0 { + hi, err := machine.HostInfo.MarshalJSON() if err != nil { return nil, err } @@ -211,8 +211,8 @@ func (h *Headscale) expandAlias(s string) ([]string, error) { // FIXME: Check TagOwners allows this for _, t := range hostinfo.RequestTags { - if s[4:] == t { - ips = append(ips, m.IPAddress) + if alias[4:] == t { + ips = append(ips, machine.IPAddress) break } @@ -223,7 +223,7 @@ func (h *Headscale) expandAlias(s string) ([]string, error) { return ips, nil } - n, err := h.GetNamespace(s) + n, err := h.GetNamespace(alias) if err == nil { nodes, err := h.ListMachinesInNamespace(n.Name) if err != nil { @@ -237,16 +237,16 @@ func (h *Headscale) expandAlias(s string) ([]string, error) { return ips, nil } - if h, ok := h.aclPolicy.Hosts[s]; ok { + if h, ok := h.aclPolicy.Hosts[alias]; ok { return []string{h.String()}, nil } - ip, err := netaddr.ParseIP(s) + ip, err := netaddr.ParseIP(alias) if err == nil { return []string{ip.String()}, nil } - cidr, err := netaddr.ParseIPPrefix(s) + cidr, err := netaddr.ParseIPPrefix(alias) if err == nil { return []string{cidr.String()}, nil } @@ -254,25 +254,25 @@ func (h *Headscale) expandAlias(s string) ([]string, error) { return nil, errorInvalidUserSection } -func (h *Headscale) expandPorts(s string) (*[]tailcfg.PortRange, error) { - if s == "*" { +func (h *Headscale) expandPorts(portsStr string) (*[]tailcfg.PortRange, error) { + if portsStr == "*" { return &[]tailcfg.PortRange{ {First: PORT_RANGE_BEGIN, Last: PORT_RANGE_END}, }, nil } ports := []tailcfg.PortRange{} - for _, p := range strings.Split(s, ",") { - rang := strings.Split(p, "-") + for _, portStr := range strings.Split(portsStr, ",") { + rang := strings.Split(portStr, "-") switch len(rang) { case 1: - pi, err := strconv.ParseUint(rang[0], BASE_10, BIT_SIZE_16) + port, err := strconv.ParseUint(rang[0], BASE_10, BIT_SIZE_16) if err != nil { return nil, err } ports = append(ports, tailcfg.PortRange{ - First: uint16(pi), - Last: uint16(pi), + First: uint16(port), + Last: uint16(port), }) case EXPECTED_TOKEN_ITEMS: diff --git a/acls_types.go b/acls_types.go index 8611d905..f6557bfb 100644 --- a/acls_types.go +++ b/acls_types.go @@ -41,37 +41,37 @@ type ACLTest struct { } // UnmarshalJSON allows to parse the Hosts directly into netaddr objects. -func (h *Hosts) UnmarshalJSON(data []byte) error { - hosts := Hosts{} - hs := make(map[string]string) +func (hosts *Hosts) UnmarshalJSON(data []byte) error { + newHosts := Hosts{} + hostIpPrefixMap := make(map[string]string) ast, err := hujson.Parse(data) if err != nil { return err } ast.Standardize() data = ast.Pack() - err = json.Unmarshal(data, &hs) + err = json.Unmarshal(data, &hostIpPrefixMap) if err != nil { return err } - for k, v := range hs { - if !strings.Contains(v, "/") { - v += "/32" + for host, prefixStr := range hostIpPrefixMap { + if !strings.Contains(prefixStr, "/") { + prefixStr += "/32" } - prefix, err := netaddr.ParseIPPrefix(v) + prefix, err := netaddr.ParseIPPrefix(prefixStr) if err != nil { return err } - hosts[k] = prefix + newHosts[host] = prefix } - *h = hosts + *hosts = newHosts return nil } // IsZero is perhaps a bit naive here. -func (p ACLPolicy) IsZero() bool { - if len(p.Groups) == 0 && len(p.Hosts) == 0 && len(p.ACLs) == 0 { +func (policy ACLPolicy) IsZero() bool { + if len(policy.Groups) == 0 && len(policy.Hosts) == 0 && len(policy.ACLs) == 0 { return true } diff --git a/api.go b/api.go index 211b4868..fb8c49c4 100644 --- a/api.go +++ b/api.go @@ -22,21 +22,25 @@ const RESERVED_RESPONSE_HEADER_SIZE = 4 // KeyHandler provides the Headscale pub key // Listens in /key. -func (h *Headscale) KeyHandler(c *gin.Context) { - c.Data(http.StatusOK, "text/plain; charset=utf-8", []byte(h.publicKey.HexString())) +func (h *Headscale) KeyHandler(ctx *gin.Context) { + ctx.Data( + http.StatusOK, + "text/plain; charset=utf-8", + []byte(h.publicKey.HexString()), + ) } // RegisterWebAPI shows a simple message in the browser to point to the CLI // Listens in /register. -func (h *Headscale) RegisterWebAPI(c *gin.Context) { - mKeyStr := c.Query("key") - if mKeyStr == "" { - c.String(http.StatusBadRequest, "Wrong params") +func (h *Headscale) RegisterWebAPI(ctx *gin.Context) { + machineKeyStr := ctx.Query("key") + if machineKeyStr == "" { + ctx.String(http.StatusBadRequest, "Wrong params") return } - c.Data(http.StatusOK, "text/html; charset=utf-8", []byte(fmt.Sprintf(` + ctx.Data(http.StatusOK, "text/html; charset=utf-8", []byte(fmt.Sprintf(`

headscale

@@ -53,45 +57,45 @@ func (h *Headscale) RegisterWebAPI(c *gin.Context) { - `, mKeyStr))) + `, machineKeyStr))) } // RegistrationHandler handles the actual registration process of a machine // Endpoint /machine/:id. -func (h *Headscale) RegistrationHandler(c *gin.Context) { - body, _ := io.ReadAll(c.Request.Body) - mKeyStr := c.Param("id") - mKey, err := wgkey.ParseHex(mKeyStr) +func (h *Headscale) RegistrationHandler(ctx *gin.Context) { + body, _ := io.ReadAll(ctx.Request.Body) + machineKeyStr := ctx.Param("id") + machineKey, err := wgkey.ParseHex(machineKeyStr) if err != nil { log.Error(). Str("handler", "Registration"). Err(err). Msg("Cannot parse machine key") machineRegistrations.WithLabelValues("unknown", "web", "error", "unknown").Inc() - c.String(http.StatusInternalServerError, "Sad!") + ctx.String(http.StatusInternalServerError, "Sad!") return } req := tailcfg.RegisterRequest{} - err = decode(body, &req, &mKey, h.privateKey) + err = decode(body, &req, &machineKey, h.privateKey) if err != nil { log.Error(). Str("handler", "Registration"). Err(err). Msg("Cannot decode message") machineRegistrations.WithLabelValues("unknown", "web", "error", "unknown").Inc() - c.String(http.StatusInternalServerError, "Very sad!") + ctx.String(http.StatusInternalServerError, "Very sad!") return } now := time.Now().UTC() - m, err := h.GetMachineByMachineKey(mKey.HexString()) + machine, err := h.GetMachineByMachineKey(machineKey.HexString()) if errors.Is(err, gorm.ErrRecordNotFound) { log.Info().Str("machine", req.Hostinfo.Hostname).Msg("New machine") newMachine := Machine{ Expiry: &time.Time{}, - MachineKey: mKey.HexString(), + MachineKey: machineKey.HexString(), Name: req.Hostinfo.Hostname, } if err := h.db.Create(&newMachine).Error; err != nil { @@ -99,16 +103,16 @@ func (h *Headscale) RegistrationHandler(c *gin.Context) { Str("handler", "Registration"). Err(err). Msg("Could not create row") - machineRegistrations.WithLabelValues("unknown", "web", "error", m.Namespace.Name). + machineRegistrations.WithLabelValues("unknown", "web", "error", machine.Namespace.Name). Inc() return } - m = &newMachine + machine = &newMachine } - if !m.Registered && req.Auth.AuthKey != "" { - h.handleAuthKey(c, h.db, mKey, req, *m) + if !machine.Registered && req.Auth.AuthKey != "" { + h.handleAuthKey(ctx, h.db, machineKey, req, *machine) return } @@ -116,63 +120,63 @@ func (h *Headscale) RegistrationHandler(c *gin.Context) { resp := tailcfg.RegisterResponse{} // We have the updated key! - if m.NodeKey == wgkey.Key(req.NodeKey).HexString() { + if machine.NodeKey == wgkey.Key(req.NodeKey).HexString() { // The client sends an Expiry in the past if the client is requesting to expire the key (aka logout) // https://github.com/tailscale/tailscale/blob/main/tailcfg/tailcfg.go#L648 if !req.Expiry.IsZero() && req.Expiry.UTC().Before(now) { log.Info(). Str("handler", "Registration"). - Str("machine", m.Name). + Str("machine", machine.Name). Msg("Client requested logout") - m.Expiry = &req.Expiry // save the expiry so that the machine is marked as expired - h.db.Save(&m) + machine.Expiry = &req.Expiry // save the expiry so that the machine is marked as expired + h.db.Save(&machine) resp.AuthURL = "" resp.MachineAuthorized = false - resp.User = *m.Namespace.toUser() - respBody, err := encode(resp, &mKey, h.privateKey) + resp.User = *machine.Namespace.toUser() + respBody, err := encode(resp, &machineKey, h.privateKey) if err != nil { log.Error(). Str("handler", "Registration"). Err(err). Msg("Cannot encode message") - c.String(http.StatusInternalServerError, "") + ctx.String(http.StatusInternalServerError, "") return } - c.Data(http.StatusOK, "application/json; charset=utf-8", respBody) + ctx.Data(http.StatusOK, "application/json; charset=utf-8", respBody) return } - if m.Registered && m.Expiry.UTC().After(now) { + if machine.Registered && machine.Expiry.UTC().After(now) { // The machine registration is valid, respond with redirect to /map log.Debug(). Str("handler", "Registration"). - Str("machine", m.Name). + Str("machine", machine.Name). Msg("Client is registered and we have the current NodeKey. All clear to /map") resp.AuthURL = "" resp.MachineAuthorized = true - resp.User = *m.Namespace.toUser() - resp.Login = *m.Namespace.toLogin() + resp.User = *machine.Namespace.toUser() + resp.Login = *machine.Namespace.toLogin() - respBody, err := encode(resp, &mKey, h.privateKey) + respBody, err := encode(resp, &machineKey, h.privateKey) if err != nil { log.Error(). Str("handler", "Registration"). Err(err). Msg("Cannot encode message") - machineRegistrations.WithLabelValues("update", "web", "error", m.Namespace.Name). + machineRegistrations.WithLabelValues("update", "web", "error", machine.Namespace.Name). Inc() - c.String(http.StatusInternalServerError, "") + ctx.String(http.StatusInternalServerError, "") return } - machineRegistrations.WithLabelValues("update", "web", "success", m.Namespace.Name). + machineRegistrations.WithLabelValues("update", "web", "success", machine.Namespace.Name). Inc() - c.Data(http.StatusOK, "application/json; charset=utf-8", respBody) + ctx.Data(http.StatusOK, "application/json; charset=utf-8", respBody) return } @@ -180,15 +184,15 @@ func (h *Headscale) RegistrationHandler(c *gin.Context) { // The client has registered before, but has expired log.Debug(). Str("handler", "Registration"). - Str("machine", m.Name). + Str("machine", machine.Name). Msg("Machine registration has expired. Sending a authurl to register") if h.cfg.OIDC.Issuer != "" { resp.AuthURL = fmt.Sprintf("%s/oidc/register/%s", - strings.TrimSuffix(h.cfg.ServerURL, "/"), mKey.HexString()) + strings.TrimSuffix(h.cfg.ServerURL, "/"), machineKey.HexString()) } else { resp.AuthURL = fmt.Sprintf("%s/register?key=%s", - strings.TrimSuffix(h.cfg.ServerURL, "/"), mKey.HexString()) + strings.TrimSuffix(h.cfg.ServerURL, "/"), machineKey.HexString()) } // When a client connects, it may request a specific expiry time in its @@ -197,51 +201,52 @@ func (h *Headscale) RegistrationHandler(c *gin.Context) { // into two steps (which cant pass arbitrary data between them easily) and needs to be // retrieved again after the user has authenticated. After the authentication flow // completes, RequestedExpiry is copied into Expiry. - m.RequestedExpiry = &req.Expiry + machine.RequestedExpiry = &req.Expiry - h.db.Save(&m) + h.db.Save(&machine) - respBody, err := encode(resp, &mKey, h.privateKey) + respBody, err := encode(resp, &machineKey, h.privateKey) if err != nil { log.Error(). Str("handler", "Registration"). Err(err). Msg("Cannot encode message") - machineRegistrations.WithLabelValues("new", "web", "error", m.Namespace.Name). + machineRegistrations.WithLabelValues("new", "web", "error", machine.Namespace.Name). Inc() - c.String(http.StatusInternalServerError, "") + ctx.String(http.StatusInternalServerError, "") return } - machineRegistrations.WithLabelValues("new", "web", "success", m.Namespace.Name). + machineRegistrations.WithLabelValues("new", "web", "success", machine.Namespace.Name). Inc() - c.Data(http.StatusOK, "application/json; charset=utf-8", respBody) + ctx.Data(http.StatusOK, "application/json; charset=utf-8", respBody) return } // The NodeKey we have matches OldNodeKey, which means this is a refresh after a key expiration - if m.NodeKey == wgkey.Key(req.OldNodeKey).HexString() && m.Expiry.UTC().After(now) { + if machine.NodeKey == wgkey.Key(req.OldNodeKey).HexString() && + machine.Expiry.UTC().After(now) { log.Debug(). Str("handler", "Registration"). - Str("machine", m.Name). + Str("machine", machine.Name). Msg("We have the OldNodeKey in the database. This is a key refresh") - m.NodeKey = wgkey.Key(req.NodeKey).HexString() - h.db.Save(&m) + machine.NodeKey = wgkey.Key(req.NodeKey).HexString() + h.db.Save(&machine) resp.AuthURL = "" - resp.User = *m.Namespace.toUser() - respBody, err := encode(resp, &mKey, h.privateKey) + resp.User = *machine.Namespace.toUser() + respBody, err := encode(resp, &machineKey, h.privateKey) if err != nil { log.Error(). Str("handler", "Registration"). Err(err). Msg("Cannot encode message") - c.String(http.StatusInternalServerError, "Extremely sad!") + ctx.String(http.StatusInternalServerError, "Extremely sad!") return } - c.Data(http.StatusOK, "application/json; charset=utf-8", respBody) + ctx.Data(http.StatusOK, "application/json; charset=utf-8", respBody) return } @@ -249,47 +254,47 @@ func (h *Headscale) RegistrationHandler(c *gin.Context) { // The machine registration is new, redirect the client to the registration URL log.Debug(). Str("handler", "Registration"). - Str("machine", m.Name). + Str("machine", machine.Name). Msg("The node is sending us a new NodeKey, sending auth url") if h.cfg.OIDC.Issuer != "" { resp.AuthURL = fmt.Sprintf( "%s/oidc/register/%s", strings.TrimSuffix(h.cfg.ServerURL, "/"), - mKey.HexString(), + machineKey.HexString(), ) } else { resp.AuthURL = fmt.Sprintf("%s/register?key=%s", - strings.TrimSuffix(h.cfg.ServerURL, "/"), mKey.HexString()) + strings.TrimSuffix(h.cfg.ServerURL, "/"), machineKey.HexString()) } // save the requested expiry time for retrieval later in the authentication flow - m.RequestedExpiry = &req.Expiry - m.NodeKey = wgkey.Key(req.NodeKey).HexString() // save the NodeKey - h.db.Save(&m) + machine.RequestedExpiry = &req.Expiry + machine.NodeKey = wgkey.Key(req.NodeKey).HexString() // save the NodeKey + h.db.Save(&machine) - respBody, err := encode(resp, &mKey, h.privateKey) + respBody, err := encode(resp, &machineKey, h.privateKey) if err != nil { log.Error(). Str("handler", "Registration"). Err(err). Msg("Cannot encode message") - c.String(http.StatusInternalServerError, "") + ctx.String(http.StatusInternalServerError, "") return } - c.Data(http.StatusOK, "application/json; charset=utf-8", respBody) + ctx.Data(http.StatusOK, "application/json; charset=utf-8", respBody) } func (h *Headscale) getMapResponse( - mKey wgkey.Key, + machineKey wgkey.Key, req tailcfg.MapRequest, - m *Machine, + machine *Machine, ) ([]byte, error) { log.Trace(). Str("func", "getMapResponse"). Str("machine", req.Hostinfo.Hostname). Msg("Creating Map response") - node, err := m.toNode(h.cfg.BaseDomain, h.cfg.DNSConfig, true) + node, err := machine.toNode(h.cfg.BaseDomain, h.cfg.DNSConfig, true) if err != nil { log.Error(). Str("func", "getMapResponse"). @@ -299,7 +304,7 @@ func (h *Headscale) getMapResponse( return nil, err } - peers, err := h.getPeers(m) + peers, err := h.getPeers(machine) if err != nil { log.Error(). Str("func", "getMapResponse"). @@ -309,7 +314,7 @@ func (h *Headscale) getMapResponse( return nil, err } - profiles := getMapResponseUserProfiles(*m, peers) + profiles := getMapResponseUserProfiles(*machine, peers) nodePeers, err := peers.toNodes(h.cfg.BaseDomain, h.cfg.DNSConfig, true) if err != nil { @@ -324,7 +329,7 @@ func (h *Headscale) getMapResponse( dnsConfig := getMapResponseDNSConfig( h.cfg.DNSConfig, h.cfg.BaseDomain, - *m, + *machine, peers, ) @@ -351,12 +356,12 @@ func (h *Headscale) getMapResponse( encoder, _ := zstd.NewWriter(nil) srcCompressed := encoder.EncodeAll(src, nil) - respBody, err = encodeMsg(srcCompressed, &mKey, h.privateKey) + respBody, err = encodeMsg(srcCompressed, &machineKey, h.privateKey) if err != nil { return nil, err } } else { - respBody, err = encode(resp, &mKey, h.privateKey) + respBody, err = encode(resp, &machineKey, h.privateKey) if err != nil { return nil, err } @@ -370,24 +375,24 @@ func (h *Headscale) getMapResponse( } func (h *Headscale) getMapKeepAliveResponse( - mKey wgkey.Key, - req tailcfg.MapRequest, + machineKey wgkey.Key, + mapRequest tailcfg.MapRequest, ) ([]byte, error) { - resp := tailcfg.MapResponse{ + mapResponse := tailcfg.MapResponse{ KeepAlive: true, } var respBody []byte var err error - if req.Compress == "zstd" { - src, _ := json.Marshal(resp) + if mapRequest.Compress == "zstd" { + src, _ := json.Marshal(mapResponse) encoder, _ := zstd.NewWriter(nil) srcCompressed := encoder.EncodeAll(src, nil) - respBody, err = encodeMsg(srcCompressed, &mKey, h.privateKey) + respBody, err = encodeMsg(srcCompressed, &machineKey, h.privateKey) if err != nil { return nil, err } } else { - respBody, err = encode(resp, &mKey, h.privateKey) + respBody, err = encode(mapResponse, &machineKey, h.privateKey) if err != nil { return nil, err } @@ -400,22 +405,22 @@ func (h *Headscale) getMapKeepAliveResponse( } func (h *Headscale) handleAuthKey( - c *gin.Context, + ctx *gin.Context, db *gorm.DB, idKey wgkey.Key, - req tailcfg.RegisterRequest, - m Machine, + reqisterRequest tailcfg.RegisterRequest, + machine Machine, ) { log.Debug(). Str("func", "handleAuthKey"). - Str("machine", req.Hostinfo.Hostname). - Msgf("Processing auth key for %s", req.Hostinfo.Hostname) + Str("machine", reqisterRequest.Hostinfo.Hostname). + Msgf("Processing auth key for %s", reqisterRequest.Hostinfo.Hostname) resp := tailcfg.RegisterResponse{} - pak, err := h.checkKeyValidity(req.Auth.AuthKey) + pak, err := h.checkKeyValidity(reqisterRequest.Auth.AuthKey) if err != nil { log.Error(). Str("func", "handleAuthKey"). - Str("machine", m.Name). + Str("machine", machine.Name). Err(err). Msg("Failed authentication via AuthKey") resp.MachineAuthorized = false @@ -423,21 +428,21 @@ func (h *Headscale) handleAuthKey( if err != nil { log.Error(). Str("func", "handleAuthKey"). - Str("machine", m.Name). + Str("machine", machine.Name). Err(err). Msg("Cannot encode message") - c.String(http.StatusInternalServerError, "") - machineRegistrations.WithLabelValues("new", "authkey", "error", m.Namespace.Name). + ctx.String(http.StatusInternalServerError, "") + machineRegistrations.WithLabelValues("new", "authkey", "error", machine.Namespace.Name). Inc() return } - c.Data(http.StatusUnauthorized, "application/json; charset=utf-8", respBody) + ctx.Data(http.StatusUnauthorized, "application/json; charset=utf-8", respBody) log.Error(). Str("func", "handleAuthKey"). - Str("machine", m.Name). + Str("machine", machine.Name). Msg("Failed authentication via AuthKey") - machineRegistrations.WithLabelValues("new", "authkey", "error", m.Namespace.Name). + machineRegistrations.WithLabelValues("new", "authkey", "error", machine.Namespace.Name). Inc() return @@ -445,32 +450,34 @@ func (h *Headscale) handleAuthKey( log.Debug(). Str("func", "handleAuthKey"). - Str("machine", m.Name). + Str("machine", machine.Name). Msg("Authentication key was valid, proceeding to acquire an IP address") ip, err := h.getAvailableIP() if err != nil { log.Error(). Str("func", "handleAuthKey"). - Str("machine", m.Name). + Str("machine", machine.Name). Msg("Failed to find an available IP") - machineRegistrations.WithLabelValues("new", "authkey", "error", m.Namespace.Name). + machineRegistrations.WithLabelValues("new", "authkey", "error", machine.Namespace.Name). Inc() return } log.Info(). Str("func", "handleAuthKey"). - Str("machine", m.Name). + Str("machine", machine.Name). Str("ip", ip.String()). - Msgf("Assigning %s to %s", ip, m.Name) + Msgf("Assigning %s to %s", ip, machine.Name) - m.AuthKeyID = uint(pak.ID) - m.IPAddress = ip.String() - m.NamespaceID = pak.NamespaceID - m.NodeKey = wgkey.Key(req.NodeKey).HexString() // we update it just in case - m.Registered = true - m.RegisterMethod = "authKey" - db.Save(&m) + machine.AuthKeyID = uint(pak.ID) + machine.IPAddress = ip.String() + machine.NamespaceID = pak.NamespaceID + machine.NodeKey = wgkey.Key(reqisterRequest.NodeKey). + HexString() + // we update it just in case + machine.Registered = true + machine.RegisterMethod = "authKey" + db.Save(&machine) pak.Used = true db.Save(&pak) @@ -481,21 +488,21 @@ func (h *Headscale) handleAuthKey( if err != nil { log.Error(). Str("func", "handleAuthKey"). - Str("machine", m.Name). + Str("machine", machine.Name). Err(err). Msg("Cannot encode message") - machineRegistrations.WithLabelValues("new", "authkey", "error", m.Namespace.Name). + machineRegistrations.WithLabelValues("new", "authkey", "error", machine.Namespace.Name). Inc() - c.String(http.StatusInternalServerError, "Extremely sad!") + ctx.String(http.StatusInternalServerError, "Extremely sad!") return } - machineRegistrations.WithLabelValues("new", "authkey", "success", m.Namespace.Name). + machineRegistrations.WithLabelValues("new", "authkey", "success", machine.Namespace.Name). Inc() - c.Data(http.StatusOK, "application/json; charset=utf-8", respBody) + ctx.Data(http.StatusOK, "application/json; charset=utf-8", respBody) log.Info(). Str("func", "handleAuthKey"). - Str("machine", m.Name). + Str("machine", machine.Name). Str("ip", ip.String()). Msg("Successfully authenticated via AuthKey") } diff --git a/app.go b/app.go index af51efd2..a0aa2385 100644 --- a/app.go +++ b/app.go @@ -169,7 +169,7 @@ func NewHeadscale(cfg Config) (*Headscale, error) { return nil, errors.New("unsupported DB") } - h := Headscale{ + app := Headscale{ cfg: cfg, dbType: cfg.DBtype, dbString: dbString, @@ -178,32 +178,32 @@ func NewHeadscale(cfg Config) (*Headscale, error) { aclRules: tailcfg.FilterAllowAll, // default allowall } - err = h.initDB() + err = app.initDB() if err != nil { return nil, err } if cfg.OIDC.Issuer != "" { - err = h.initOIDC() + err = app.initOIDC() if err != nil { return nil, err } } - if h.cfg.DNSConfig != nil && h.cfg.DNSConfig.Proxied { // if MagicDNS + if app.cfg.DNSConfig != nil && app.cfg.DNSConfig.Proxied { // if MagicDNS magicDNSDomains := generateMagicDNSRootDomains( - h.cfg.IPPrefix, + app.cfg.IPPrefix, ) // we might have routes already from Split DNS - if h.cfg.DNSConfig.Routes == nil { - h.cfg.DNSConfig.Routes = make(map[string][]dnstype.Resolver) + if app.cfg.DNSConfig.Routes == nil { + app.cfg.DNSConfig.Routes = make(map[string][]dnstype.Resolver) } for _, d := range magicDNSDomains { - h.cfg.DNSConfig.Routes[d.WithoutTrailingDot()] = nil + app.cfg.DNSConfig.Routes[d.WithoutTrailingDot()] = nil } } - return &h, nil + return &app, nil } // Redirect to our TLS url. @@ -229,35 +229,37 @@ func (h *Headscale) expireEphemeralNodesWorker() { return } - for _, ns := range namespaces { - machines, err := h.ListMachinesInNamespace(ns.Name) + for _, namespace := range namespaces { + machines, err := h.ListMachinesInNamespace(namespace.Name) if err != nil { log.Error(). Err(err). - Str("namespace", ns.Name). + Str("namespace", namespace.Name). Msg("Error listing machines in namespace") return } - for _, m := range machines { - if m.AuthKey != nil && m.LastSeen != nil && m.AuthKey.Ephemeral && - time.Now().After(m.LastSeen.Add(h.cfg.EphemeralNodeInactivityTimeout)) { + for _, machine := range machines { + if machine.AuthKey != nil && machine.LastSeen != nil && + machine.AuthKey.Ephemeral && + time.Now(). + After(machine.LastSeen.Add(h.cfg.EphemeralNodeInactivityTimeout)) { log.Info(). - Str("machine", m.Name). + Str("machine", machine.Name). Msg("Ephemeral client removed from database") - err = h.db.Unscoped().Delete(m).Error + err = h.db.Unscoped().Delete(machine).Error if err != nil { log.Error(). Err(err). - Str("machine", m.Name). + Str("machine", machine.Name). Msg("🤮 Cannot delete ephemeral machine from the database") } } } - h.setLastStateChangeToNow(ns.Name) + h.setLastStateChangeToNow(namespace.Name) } } @@ -284,18 +286,18 @@ func (h *Headscale) grpcAuthenticationInterceptor(ctx context.Context, // with the "legacy" database-based client // It is also neede for grpc-gateway to be able to connect to // the server - p, _ := peer.FromContext(ctx) + client, _ := peer.FromContext(ctx) log.Trace(). Caller(). - Str("client_address", p.Addr.String()). + Str("client_address", client.Addr.String()). Msg("Client is trying to authenticate") - md, ok := metadata.FromIncomingContext(ctx) + meta, ok := metadata.FromIncomingContext(ctx) if !ok { log.Error(). Caller(). - Str("client_address", p.Addr.String()). + Str("client_address", client.Addr.String()). Msg("Retrieving metadata is failed") return ctx, status.Errorf( @@ -304,11 +306,11 @@ func (h *Headscale) grpcAuthenticationInterceptor(ctx context.Context, ) } - authHeader, ok := md["authorization"] + authHeader, ok := meta["authorization"] if !ok { log.Error(). Caller(). - Str("client_address", p.Addr.String()). + Str("client_address", client.Addr.String()). Msg("Authorization token is not supplied") return ctx, status.Errorf( @@ -322,7 +324,7 @@ func (h *Headscale) grpcAuthenticationInterceptor(ctx context.Context, if !strings.HasPrefix(token, AUTH_PREFIX) { log.Error(). Caller(). - Str("client_address", p.Addr.String()). + Str("client_address", client.Addr.String()). Msg(`missing "Bearer " prefix in "Authorization" header`) return ctx, status.Error( @@ -353,25 +355,25 @@ func (h *Headscale) grpcAuthenticationInterceptor(ctx context.Context, // return handler(ctx, req) } -func (h *Headscale) httpAuthenticationMiddleware(c *gin.Context) { +func (h *Headscale) httpAuthenticationMiddleware(ctx *gin.Context) { log.Trace(). Caller(). - Str("client_address", c.ClientIP()). + Str("client_address", ctx.ClientIP()). Msg("HTTP authentication invoked") - authHeader := c.GetHeader("authorization") + authHeader := ctx.GetHeader("authorization") if !strings.HasPrefix(authHeader, AUTH_PREFIX) { log.Error(). Caller(). - Str("client_address", c.ClientIP()). + Str("client_address", ctx.ClientIP()). Msg(`missing "Bearer " prefix in "Authorization" header`) - c.AbortWithStatus(http.StatusUnauthorized) + ctx.AbortWithStatus(http.StatusUnauthorized) return } - c.AbortWithStatus(http.StatusUnauthorized) + ctx.AbortWithStatus(http.StatusUnauthorized) // TODO(kradalby): Implement API key backend // Currently all traffic is unauthorized, this is intentional to allow @@ -438,9 +440,9 @@ func (h *Headscale) Serve() error { // Create the cmux object that will multiplex 2 protocols on the same port. // The two following listeners will be served on the same port below gracefully. - m := cmux.New(networkListener) + networkMutex := cmux.New(networkListener) // Match gRPC requests here - grpcListener := m.MatchWithWriters( + grpcListener := networkMutex.MatchWithWriters( cmux.HTTP2MatchHeaderFieldSendSettings("content-type", "application/grpc"), cmux.HTTP2MatchHeaderFieldSendSettings( "content-type", @@ -448,7 +450,7 @@ func (h *Headscale) Serve() error { ), ) // Otherwise match regular http requests. - httpListener := m.Match(cmux.Any()) + httpListener := networkMutex.Match(cmux.Any()) grpcGatewayMux := runtime.NewServeMux() @@ -471,33 +473,33 @@ func (h *Headscale) Serve() error { return err } - r := gin.Default() + router := gin.Default() - p := ginprometheus.NewPrometheus("gin") - p.Use(r) + prometheus := ginprometheus.NewPrometheus("gin") + prometheus.Use(router) - r.GET( + router.GET( "/health", func(c *gin.Context) { c.JSON(http.StatusOK, gin.H{"healthy": "ok"}) }, ) - r.GET("/key", h.KeyHandler) - r.GET("/register", h.RegisterWebAPI) - r.POST("/machine/:id/map", h.PollNetMapHandler) - r.POST("/machine/:id", h.RegistrationHandler) - r.GET("/oidc/register/:mkey", h.RegisterOIDC) - r.GET("/oidc/callback", h.OIDCCallback) - r.GET("/apple", h.AppleMobileConfig) - r.GET("/apple/:platform", h.ApplePlatformConfig) - r.GET("/swagger", SwaggerUI) - r.GET("/swagger/v1/openapiv2.json", SwaggerAPIv1) + router.GET("/key", h.KeyHandler) + router.GET("/register", h.RegisterWebAPI) + router.POST("/machine/:id/map", h.PollNetMapHandler) + router.POST("/machine/:id", h.RegistrationHandler) + router.GET("/oidc/register/:mkey", h.RegisterOIDC) + router.GET("/oidc/callback", h.OIDCCallback) + router.GET("/apple", h.AppleMobileConfig) + router.GET("/apple/:platform", h.ApplePlatformConfig) + router.GET("/swagger", SwaggerUI) + router.GET("/swagger/v1/openapiv2.json", SwaggerAPIv1) - api := r.Group("/api") + api := router.Group("/api") api.Use(h.httpAuthenticationMiddleware) { api.Any("/v1/*any", gin.WrapF(grpcGatewayMux.ServeHTTP)) } - r.NoRoute(stdoutHandler) + router.NoRoute(stdoutHandler) // Fetch an initial DERP Map before we start serving h.DERPMap = GetDERPMap(h.cfg.DERP) @@ -514,7 +516,7 @@ func (h *Headscale) Serve() error { httpServer := &http.Server{ Addr: h.cfg.Addr, - Handler: r, + Handler: router, ReadTimeout: HTTP_READ_TIMEOUT, // Go does not handle timeouts in HTTP very well, and there is // no good way to handle streaming timeouts, therefore we need to @@ -561,29 +563,29 @@ func (h *Headscale) Serve() error { reflection.Register(grpcServer) reflection.Register(grpcSocket) - g := new(errgroup.Group) + errorGroup := new(errgroup.Group) - g.Go(func() error { return grpcSocket.Serve(socketListener) }) + errorGroup.Go(func() error { return grpcSocket.Serve(socketListener) }) // TODO(kradalby): Verify if we need the same TLS setup for gRPC as HTTP - g.Go(func() error { return grpcServer.Serve(grpcListener) }) + errorGroup.Go(func() error { return grpcServer.Serve(grpcListener) }) if tlsConfig != nil { - g.Go(func() error { + errorGroup.Go(func() error { tlsl := tls.NewListener(httpListener, tlsConfig) return httpServer.Serve(tlsl) }) } else { - g.Go(func() error { return httpServer.Serve(httpListener) }) + errorGroup.Go(func() error { return httpServer.Serve(httpListener) }) } - g.Go(func() error { return m.Serve() }) + errorGroup.Go(func() error { return networkMutex.Serve() }) log.Info(). Msgf("listening and serving (multiplexed HTTP and gRPC) on: %s", h.cfg.Addr) - return g.Wait() + return errorGroup.Wait() } func (h *Headscale) getTLSSettings() (*tls.Config, error) { @@ -594,7 +596,7 @@ func (h *Headscale) getTLSSettings() (*tls.Config, error) { Msg("Listening with TLS but ServerURL does not start with https://") } - m := autocert.Manager{ + certManager := autocert.Manager{ Prompt: autocert.AcceptTOS, HostPolicy: autocert.HostWhitelist(h.cfg.TLSLetsEncryptHostname), Cache: autocert.DirCache(h.cfg.TLSLetsEncryptCacheDir), @@ -609,7 +611,7 @@ func (h *Headscale) getTLSSettings() (*tls.Config, error) { // Configuration via autocert with TLS-ALPN-01 (https://tools.ietf.org/html/rfc8737) // The RFC requires that the validation is done on port 443; in other words, headscale // must be reachable on port 443. - return m.TLSConfig(), nil + return certManager.TLSConfig(), nil case "HTTP-01": // Configuration via autocert with HTTP-01. This requires listening on @@ -617,11 +619,11 @@ func (h *Headscale) getTLSSettings() (*tls.Config, error) { // service, which can be configured to run on any other port. go func() { log.Fatal(). - Err(http.ListenAndServe(h.cfg.TLSLetsEncryptListen, m.HTTPHandler(http.HandlerFunc(h.redirect)))). + Err(http.ListenAndServe(h.cfg.TLSLetsEncryptListen, certManager.HTTPHandler(http.HandlerFunc(h.redirect)))). Msg("failed to set up a HTTP server") }() - return m.TLSConfig(), nil + return certManager.TLSConfig(), nil default: return nil, errors.New("unknown value for TLSLetsEncryptChallengeType") @@ -676,13 +678,13 @@ func (h *Headscale) getLastStateChange(namespaces ...string) time.Time { } } -func stdoutHandler(c *gin.Context) { - b, _ := io.ReadAll(c.Request.Body) +func stdoutHandler(ctx *gin.Context) { + body, _ := io.ReadAll(ctx.Request.Body) log.Trace(). - Interface("header", c.Request.Header). - Interface("proto", c.Request.Proto). - Interface("url", c.Request.URL). - Bytes("body", b). + Interface("header", ctx.Request.Header). + Interface("proto", ctx.Request.Proto). + Interface("url", ctx.Request.URL). + Bytes("body", body). Msg("Request did not match") } diff --git a/apple_mobileconfig.go b/apple_mobileconfig.go index ff3ef3cf..8989c270 100644 --- a/apple_mobileconfig.go +++ b/apple_mobileconfig.go @@ -12,8 +12,8 @@ import ( // AppleMobileConfig shows a simple message in the browser to point to the CLI // Listens in /register. -func (h *Headscale) AppleMobileConfig(c *gin.Context) { - t := template.Must(template.New("apple").Parse(` +func (h *Headscale) AppleMobileConfig(ctx *gin.Context) { + appleTemplate := template.Must(template.New("apple").Parse(`

Apple configuration profiles

@@ -67,12 +67,12 @@ func (h *Headscale) AppleMobileConfig(c *gin.Context) { } var payload bytes.Buffer - if err := t.Execute(&payload, config); err != nil { + if err := appleTemplate.Execute(&payload, config); err != nil { log.Error(). Str("handler", "AppleMobileConfig"). Err(err). Msg("Could not render Apple index template") - c.Data( + ctx.Data( http.StatusInternalServerError, "text/html; charset=utf-8", []byte("Could not render Apple index template"), @@ -81,11 +81,11 @@ func (h *Headscale) AppleMobileConfig(c *gin.Context) { return } - c.Data(http.StatusOK, "text/html; charset=utf-8", payload.Bytes()) + ctx.Data(http.StatusOK, "text/html; charset=utf-8", payload.Bytes()) } -func (h *Headscale) ApplePlatformConfig(c *gin.Context) { - platform := c.Param("platform") +func (h *Headscale) ApplePlatformConfig(ctx *gin.Context) { + platform := ctx.Param("platform") id, err := uuid.NewV4() if err != nil { @@ -93,7 +93,7 @@ func (h *Headscale) ApplePlatformConfig(c *gin.Context) { Str("handler", "ApplePlatformConfig"). Err(err). Msg("Failed not create UUID") - c.Data( + ctx.Data( http.StatusInternalServerError, "text/html; charset=utf-8", []byte("Failed to create UUID"), @@ -108,7 +108,7 @@ func (h *Headscale) ApplePlatformConfig(c *gin.Context) { Str("handler", "ApplePlatformConfig"). Err(err). Msg("Failed not create UUID") - c.Data( + ctx.Data( http.StatusInternalServerError, "text/html; charset=utf-8", []byte("Failed to create UUID"), @@ -131,7 +131,7 @@ func (h *Headscale) ApplePlatformConfig(c *gin.Context) { Str("handler", "ApplePlatformConfig"). Err(err). Msg("Could not render Apple macOS template") - c.Data( + ctx.Data( http.StatusInternalServerError, "text/html; charset=utf-8", []byte("Could not render Apple macOS template"), @@ -145,7 +145,7 @@ func (h *Headscale) ApplePlatformConfig(c *gin.Context) { Str("handler", "ApplePlatformConfig"). Err(err). Msg("Could not render Apple iOS template") - c.Data( + ctx.Data( http.StatusInternalServerError, "text/html; charset=utf-8", []byte("Could not render Apple iOS template"), @@ -154,7 +154,7 @@ func (h *Headscale) ApplePlatformConfig(c *gin.Context) { return } default: - c.Data( + ctx.Data( http.StatusOK, "text/html; charset=utf-8", []byte("Invalid platform, only ios and macos is supported"), @@ -175,7 +175,7 @@ func (h *Headscale) ApplePlatformConfig(c *gin.Context) { Str("handler", "ApplePlatformConfig"). Err(err). Msg("Could not render Apple platform template") - c.Data( + ctx.Data( http.StatusInternalServerError, "text/html; charset=utf-8", []byte("Could not render Apple platform template"), @@ -184,7 +184,7 @@ func (h *Headscale) ApplePlatformConfig(c *gin.Context) { return } - c.Data( + ctx.Data( http.StatusOK, "application/x-apple-aspen-config; charset=utf-8", content.Bytes(), diff --git a/cmd/headscale/cli/namespaces.go b/cmd/headscale/cli/namespaces.go index 8c69ac56..8c6f10ad 100644 --- a/cmd/headscale/cli/namespaces.go +++ b/cmd/headscale/cli/namespaces.go @@ -167,10 +167,10 @@ var listNamespacesCmd = &cobra.Command{ return } - d := pterm.TableData{{"ID", "Name", "Created"}} + tableData := pterm.TableData{{"ID", "Name", "Created"}} for _, namespace := range response.GetNamespaces() { - d = append( - d, + tableData = append( + tableData, []string{ namespace.GetId(), namespace.GetName(), @@ -178,7 +178,7 @@ var listNamespacesCmd = &cobra.Command{ }, ) } - err = pterm.DefaultTable.WithHasHeader().WithData(d).Render() + err = pterm.DefaultTable.WithHasHeader().WithData(tableData).Render() if err != nil { ErrorOutput( err, diff --git a/cmd/headscale/cli/nodes.go b/cmd/headscale/cli/nodes.go index 83d6b1f5..c644ad9e 100644 --- a/cmd/headscale/cli/nodes.go +++ b/cmd/headscale/cli/nodes.go @@ -157,14 +157,14 @@ var listNodesCmd = &cobra.Command{ return } - d, err := nodesToPtables(namespace, response.Machines) + tableData, err := nodesToPtables(namespace, response.Machines) if err != nil { ErrorOutput(err, fmt.Sprintf("Error converting to table: %s", err), output) return } - err = pterm.DefaultTable.WithHasHeader().WithData(d).Render() + err = pterm.DefaultTable.WithHasHeader().WithData(tableData).Render() if err != nil { ErrorOutput( err, @@ -183,7 +183,7 @@ var deleteNodeCmd = &cobra.Command{ Run: func(cmd *cobra.Command, args []string) { output, _ := cmd.Flags().GetString("output") - id, err := cmd.Flags().GetInt("identifier") + identifier, err := cmd.Flags().GetInt("identifier") if err != nil { ErrorOutput( err, @@ -199,7 +199,7 @@ var deleteNodeCmd = &cobra.Command{ defer conn.Close() getRequest := &v1.GetMachineRequest{ - MachineId: uint64(id), + MachineId: uint64(identifier), } getResponse, err := client.GetMachine(ctx, getRequest) @@ -217,7 +217,7 @@ var deleteNodeCmd = &cobra.Command{ } deleteRequest := &v1.DeleteMachineRequest{ - MachineId: uint64(id), + MachineId: uint64(identifier), } confirm := false @@ -280,7 +280,7 @@ func sharingWorker( defer cancel() defer conn.Close() - id, err := cmd.Flags().GetInt("identifier") + identifier, err := cmd.Flags().GetInt("identifier") if err != nil { ErrorOutput(err, fmt.Sprintf("Error converting ID to integer: %s", err), output) @@ -288,7 +288,7 @@ func sharingWorker( } machineRequest := &v1.GetMachineRequest{ - MachineId: uint64(id), + MachineId: uint64(identifier), } machineResponse, err := client.GetMachine(ctx, machineRequest) @@ -402,7 +402,7 @@ func nodesToPtables( currentNamespace string, machines []*v1.Machine, ) (pterm.TableData, error) { - d := pterm.TableData{ + tableData := pterm.TableData{ { "ID", "Name", @@ -448,8 +448,8 @@ func nodesToPtables( // Shared into this namespace namespace = pterm.LightYellow(machine.Namespace.Name) } - d = append( - d, + tableData = append( + tableData, []string{ strconv.FormatUint(machine.Id, headscale.BASE_10), machine.Name, @@ -463,5 +463,5 @@ func nodesToPtables( ) } - return d, nil + return tableData, nil } diff --git a/cmd/headscale/cli/preauthkeys.go b/cmd/headscale/cli/preauthkeys.go index 13a30942..b28e6003 100644 --- a/cmd/headscale/cli/preauthkeys.go +++ b/cmd/headscale/cli/preauthkeys.go @@ -45,7 +45,7 @@ var listPreAuthKeys = &cobra.Command{ Run: func(cmd *cobra.Command, args []string) { output, _ := cmd.Flags().GetString("output") - n, err := cmd.Flags().GetString("namespace") + namespace, err := cmd.Flags().GetString("namespace") if err != nil { ErrorOutput(err, fmt.Sprintf("Error getting namespace: %s", err), output) @@ -57,7 +57,7 @@ var listPreAuthKeys = &cobra.Command{ defer conn.Close() request := &v1.ListPreAuthKeysRequest{ - Namespace: n, + Namespace: namespace, } response, err := client.ListPreAuthKeys(ctx, request) @@ -77,34 +77,34 @@ var listPreAuthKeys = &cobra.Command{ return } - d := pterm.TableData{ + tableData := pterm.TableData{ {"ID", "Key", "Reusable", "Ephemeral", "Used", "Expiration", "Created"}, } - for _, k := range response.PreAuthKeys { + for _, key := range response.PreAuthKeys { expiration := "-" - if k.GetExpiration() != nil { - expiration = k.Expiration.AsTime().Format("2006-01-02 15:04:05") + if key.GetExpiration() != nil { + expiration = key.Expiration.AsTime().Format("2006-01-02 15:04:05") } var reusable string - if k.GetEphemeral() { + if key.GetEphemeral() { reusable = "N/A" } else { - reusable = fmt.Sprintf("%v", k.GetReusable()) + reusable = fmt.Sprintf("%v", key.GetReusable()) } - d = append(d, []string{ - k.GetId(), - k.GetKey(), + tableData = append(tableData, []string{ + key.GetId(), + key.GetKey(), reusable, - strconv.FormatBool(k.GetEphemeral()), - strconv.FormatBool(k.GetUsed()), + strconv.FormatBool(key.GetEphemeral()), + strconv.FormatBool(key.GetUsed()), expiration, - k.GetCreatedAt().AsTime().Format("2006-01-02 15:04:05"), + key.GetCreatedAt().AsTime().Format("2006-01-02 15:04:05"), }) } - err = pterm.DefaultTable.WithHasHeader().WithData(d).Render() + err = pterm.DefaultTable.WithHasHeader().WithData(tableData).Render() if err != nil { ErrorOutput( err, diff --git a/cmd/headscale/cli/routes.go b/cmd/headscale/cli/routes.go index 2ad64bc3..7d0fcbf3 100644 --- a/cmd/headscale/cli/routes.go +++ b/cmd/headscale/cli/routes.go @@ -81,14 +81,14 @@ var listRoutesCmd = &cobra.Command{ return } - d := routesToPtables(response.Routes) + tableData := routesToPtables(response.Routes) if err != nil { ErrorOutput(err, fmt.Sprintf("Error converting to table: %s", err), output) return } - err = pterm.DefaultTable.WithHasHeader().WithData(d).Render() + err = pterm.DefaultTable.WithHasHeader().WithData(tableData).Render() if err != nil { ErrorOutput( err, @@ -162,14 +162,14 @@ omit the route you do not want to enable. return } - d := routesToPtables(response.Routes) + tableData := routesToPtables(response.Routes) if err != nil { ErrorOutput(err, fmt.Sprintf("Error converting to table: %s", err), output) return } - err = pterm.DefaultTable.WithHasHeader().WithData(d).Render() + err = pterm.DefaultTable.WithHasHeader().WithData(tableData).Render() if err != nil { ErrorOutput( err, @@ -184,15 +184,15 @@ omit the route you do not want to enable. // routesToPtables converts the list of routes to a nice table. func routesToPtables(routes *v1.Routes) pterm.TableData { - d := pterm.TableData{{"Route", "Enabled"}} + tableData := pterm.TableData{{"Route", "Enabled"}} for _, route := range routes.GetAdvertisedRoutes() { enabled := isStringInSlice(routes.EnabledRoutes, route) - d = append(d, []string{route, strconv.FormatBool(enabled)}) + tableData = append(tableData, []string{route, strconv.FormatBool(enabled)}) } - return d + return tableData } func isStringInSlice(strs []string, s string) bool { diff --git a/cmd/headscale/cli/utils.go b/cmd/headscale/cli/utils.go index 343ebe30..ad49c013 100644 --- a/cmd/headscale/cli/utils.go +++ b/cmd/headscale/cli/utils.go @@ -318,7 +318,7 @@ func getHeadscaleApp() (*headscale.Headscale, error) { cfg.OIDC.MatchMap = loadOIDCMatchMap() - h, err := headscale.NewHeadscale(cfg) + app, err := headscale.NewHeadscale(cfg) if err != nil { return nil, err } @@ -327,7 +327,7 @@ func getHeadscaleApp() (*headscale.Headscale, error) { if viper.GetString("acl_policy_path") != "" { aclPath := absPath(viper.GetString("acl_policy_path")) - err = h.LoadACLPolicy(aclPath) + err = app.LoadACLPolicy(aclPath) if err != nil { log.Error(). Str("path", aclPath). @@ -336,7 +336,7 @@ func getHeadscaleApp() (*headscale.Headscale, error) { } } - return h, nil + return app, nil } func getHeadscaleCLIClient() (context.Context, v1.HeadscaleServiceClient, *grpc.ClientConn, context.CancelFunc) { diff --git a/dns.go b/dns.go index d7480b15..cb986cf0 100644 --- a/dns.go +++ b/dns.go @@ -79,7 +79,7 @@ func generateMagicDNSRootDomains( func getMapResponseDNSConfig( dnsConfigOrig *tailcfg.DNSConfig, baseDomain string, - m Machine, + machine Machine, peers Machines, ) *tailcfg.DNSConfig { var dnsConfig *tailcfg.DNSConfig @@ -88,11 +88,11 @@ func getMapResponseDNSConfig( dnsConfig = dnsConfigOrig.Clone() dnsConfig.Domains = append( dnsConfig.Domains, - fmt.Sprintf("%s.%s", m.Namespace.Name, baseDomain), + fmt.Sprintf("%s.%s", machine.Namespace.Name, baseDomain), ) namespaceSet := set.New(set.ThreadSafe) - namespaceSet.Add(m.Namespace) + namespaceSet.Add(machine.Namespace) for _, p := range peers { namespaceSet.Add(p.Namespace) } diff --git a/machine.go b/machine.go index e8d2f72a..d1f27cc8 100644 --- a/machine.go +++ b/machine.go @@ -56,21 +56,21 @@ type ( ) // For the time being this method is rather naive. -func (m Machine) isAlreadyRegistered() bool { - return m.Registered +func (machine Machine) isAlreadyRegistered() bool { + return machine.Registered } // isExpired returns whether the machine registration has expired. -func (m Machine) isExpired() bool { - return time.Now().UTC().After(*m.Expiry) +func (machine Machine) isExpired() bool { + return time.Now().UTC().After(*machine.Expiry) } // If the Machine is expired, updateMachineExpiry updates the Machine Expiry time to the maximum allowed duration, // or the default duration if no Expiry time was requested by the client. The expiry time here does not (yet) cause // a client to be disconnected, however they will have to re-auth the machine if they attempt to reconnect after the // expiry time. -func (h *Headscale) updateMachineExpiry(m *Machine) { - if m.isExpired() { +func (h *Headscale) updateMachineExpiry(machine *Machine) { + if machine.isExpired() { now := time.Now().UTC() maxExpiry := now.Add( h.cfg.MaxMachineRegistrationDuration, @@ -80,31 +80,31 @@ func (h *Headscale) updateMachineExpiry(m *Machine) { ) // calculate the default expiry // clamp the expiry time of the machine registration to the maximum allowed, or use the default if none supplied - if maxExpiry.Before(*m.RequestedExpiry) { + if maxExpiry.Before(*machine.RequestedExpiry) { log.Debug(). Msgf("Clamping registration expiry time to maximum: %v (%v)", maxExpiry, h.cfg.MaxMachineRegistrationDuration) - m.Expiry = &maxExpiry - } else if m.RequestedExpiry.IsZero() { + machine.Expiry = &maxExpiry + } else if machine.RequestedExpiry.IsZero() { log.Debug().Msgf("Using default machine registration expiry time: %v (%v)", defaultExpiry, h.cfg.DefaultMachineRegistrationDuration) - m.Expiry = &defaultExpiry + machine.Expiry = &defaultExpiry } else { - log.Debug().Msgf("Using requested machine registration expiry time: %v", m.RequestedExpiry) - m.Expiry = m.RequestedExpiry + log.Debug().Msgf("Using requested machine registration expiry time: %v", machine.RequestedExpiry) + machine.Expiry = machine.RequestedExpiry } - h.db.Save(&m) + h.db.Save(&machine) } } -func (h *Headscale) getDirectPeers(m *Machine) (Machines, error) { +func (h *Headscale) getDirectPeers(machine *Machine) (Machines, error) { log.Trace(). Caller(). - Str("machine", m.Name). + Str("machine", machine.Name). Msg("Finding direct peers") machines := Machines{} if err := h.db.Preload("Namespace").Where("namespace_id = ? AND machine_key <> ? AND registered", - m.NamespaceID, m.MachineKey).Find(&machines).Error; err != nil { + machine.NamespaceID, machine.MachineKey).Find(&machines).Error; err != nil { log.Error().Err(err).Msg("Error accessing db") return Machines{}, err @@ -114,22 +114,22 @@ func (h *Headscale) getDirectPeers(m *Machine) (Machines, error) { log.Trace(). Caller(). - Str("machine", m.Name). + Str("machine", machine.Name). Msgf("Found direct machines: %s", machines.String()) return machines, nil } // getShared fetches machines that are shared to the `Namespace` of the machine we are getting peers for. -func (h *Headscale) getShared(m *Machine) (Machines, error) { +func (h *Headscale) getShared(machine *Machine) (Machines, error) { log.Trace(). Caller(). - Str("machine", m.Name). + Str("machine", machine.Name). Msg("Finding shared peers") sharedMachines := []SharedMachine{} if err := h.db.Preload("Namespace").Preload("Machine").Preload("Machine.Namespace").Where("namespace_id = ?", - m.NamespaceID).Find(&sharedMachines).Error; err != nil { + machine.NamespaceID).Find(&sharedMachines).Error; err != nil { return Machines{}, err } @@ -142,22 +142,22 @@ func (h *Headscale) getShared(m *Machine) (Machines, error) { log.Trace(). Caller(). - Str("machine", m.Name). + Str("machine", machine.Name). Msgf("Found shared peers: %s", peers.String()) return peers, nil } // getSharedTo fetches the machines of the namespaces this machine is shared in. -func (h *Headscale) getSharedTo(m *Machine) (Machines, error) { +func (h *Headscale) getSharedTo(machine *Machine) (Machines, error) { log.Trace(). Caller(). - Str("machine", m.Name). + Str("machine", machine.Name). Msg("Finding peers in namespaces this machine is shared with") sharedMachines := []SharedMachine{} if err := h.db.Preload("Namespace").Preload("Machine").Preload("Machine.Namespace").Where("machine_id = ?", - m.ID).Find(&sharedMachines).Error; err != nil { + machine.ID).Find(&sharedMachines).Error; err != nil { return Machines{}, err } @@ -176,14 +176,14 @@ func (h *Headscale) getSharedTo(m *Machine) (Machines, error) { log.Trace(). Caller(). - Str("machine", m.Name). + Str("machine", machine.Name). Msgf("Found peers we are shared with: %s", peers.String()) return peers, nil } -func (h *Headscale) getPeers(m *Machine) (Machines, error) { - direct, err := h.getDirectPeers(m) +func (h *Headscale) getPeers(machine *Machine) (Machines, error) { + direct, err := h.getDirectPeers(machine) if err != nil { log.Error(). Caller(). @@ -193,7 +193,7 @@ func (h *Headscale) getPeers(m *Machine) (Machines, error) { return Machines{}, err } - shared, err := h.getShared(m) + shared, err := h.getShared(machine) if err != nil { log.Error(). Caller(). @@ -203,7 +203,7 @@ func (h *Headscale) getPeers(m *Machine) (Machines, error) { return Machines{}, err } - sharedTo, err := h.getSharedTo(m) + sharedTo, err := h.getSharedTo(machine) if err != nil { log.Error(). Caller(). @@ -220,7 +220,7 @@ func (h *Headscale) getPeers(m *Machine) (Machines, error) { log.Trace(). Caller(). - Str("machine", m.Name). + Str("machine", machine.Name). Msgf("Found total peers: %s", peers.String()) return peers, nil @@ -262,9 +262,9 @@ func (h *Headscale) GetMachineByID(id uint64) (*Machine, error) { } // GetMachineByMachineKey finds a Machine by ID and returns the Machine struct. -func (h *Headscale) GetMachineByMachineKey(mKey string) (*Machine, error) { +func (h *Headscale) GetMachineByMachineKey(machineKey string) (*Machine, error) { m := Machine{} - if result := h.db.Preload("Namespace").First(&m, "machine_key = ?", mKey); result.Error != nil { + if result := h.db.Preload("Namespace").First(&m, "machine_key = ?", machineKey); result.Error != nil { return nil, result.Error } @@ -273,8 +273,8 @@ func (h *Headscale) GetMachineByMachineKey(mKey string) (*Machine, error) { // UpdateMachine takes a Machine struct pointer (typically already loaded from database // and updates it with the latest data from the database. -func (h *Headscale) UpdateMachine(m *Machine) error { - if result := h.db.Find(m).First(&m); result.Error != nil { +func (h *Headscale) UpdateMachine(machine *Machine) error { + if result := h.db.Find(machine).First(&machine); result.Error != nil { return result.Error } @@ -282,16 +282,16 @@ func (h *Headscale) UpdateMachine(m *Machine) error { } // DeleteMachine softs deletes a Machine from the database. -func (h *Headscale) DeleteMachine(m *Machine) error { - err := h.RemoveSharedMachineFromAllNamespaces(m) +func (h *Headscale) DeleteMachine(machine *Machine) error { + err := h.RemoveSharedMachineFromAllNamespaces(machine) if err != nil && err != errorMachineNotShared { return err } - m.Registered = false - namespaceID := m.NamespaceID - h.db.Save(&m) // we mark it as unregistered, just in case - if err := h.db.Delete(&m).Error; err != nil { + machine.Registered = false + namespaceID := machine.NamespaceID + h.db.Save(&machine) // we mark it as unregistered, just in case + if err := h.db.Delete(&machine).Error; err != nil { return err } @@ -299,14 +299,14 @@ func (h *Headscale) DeleteMachine(m *Machine) error { } // HardDeleteMachine hard deletes a Machine from the database. -func (h *Headscale) HardDeleteMachine(m *Machine) error { - err := h.RemoveSharedMachineFromAllNamespaces(m) +func (h *Headscale) HardDeleteMachine(machine *Machine) error { + err := h.RemoveSharedMachineFromAllNamespaces(machine) if err != nil && err != errorMachineNotShared { return err } - namespaceID := m.NamespaceID - if err := h.db.Unscoped().Delete(&m).Error; err != nil { + namespaceID := machine.NamespaceID + if err := h.db.Unscoped().Delete(&machine).Error; err != nil { return err } @@ -314,10 +314,10 @@ func (h *Headscale) HardDeleteMachine(m *Machine) error { } // GetHostInfo returns a Hostinfo struct for the machine. -func (m *Machine) GetHostInfo() (*tailcfg.Hostinfo, error) { +func (machine *Machine) GetHostInfo() (*tailcfg.Hostinfo, error) { hostinfo := tailcfg.Hostinfo{} - if len(m.HostInfo) != 0 { - hi, err := m.HostInfo.MarshalJSON() + if len(machine.HostInfo) != 0 { + hi, err := machine.HostInfo.MarshalJSON() if err != nil { return nil, err } @@ -330,17 +330,17 @@ func (m *Machine) GetHostInfo() (*tailcfg.Hostinfo, error) { return &hostinfo, nil } -func (h *Headscale) isOutdated(m *Machine) bool { - if err := h.UpdateMachine(m); err != nil { +func (h *Headscale) isOutdated(machine *Machine) bool { + if err := h.UpdateMachine(machine); err != nil { // It does not seem meaningful to propagate this error as the end result // will have to be that the machine has to be considered outdated. return true } - sharedMachines, _ := h.getShared(m) + sharedMachines, _ := h.getShared(machine) namespaceSet := set.New(set.ThreadSafe) - namespaceSet.Add(m.Namespace.Name) + namespaceSet.Add(machine.Namespace.Name) // Check if any of our shared namespaces has updates that we have // not propagated. @@ -356,22 +356,22 @@ func (h *Headscale) isOutdated(m *Machine) bool { lastChange := h.getLastStateChange(namespaces...) log.Trace(). Caller(). - Str("machine", m.Name). - Time("last_successful_update", *m.LastSuccessfulUpdate). + Str("machine", machine.Name). + Time("last_successful_update", *machine.LastSuccessfulUpdate). Time("last_state_change", lastChange). - Msgf("Checking if %s is missing updates", m.Name) + Msgf("Checking if %s is missing updates", machine.Name) - return m.LastSuccessfulUpdate.Before(lastChange) + return machine.LastSuccessfulUpdate.Before(lastChange) } -func (m Machine) String() string { - return m.Name +func (machine Machine) String() string { + return machine.Name } -func (ms Machines) String() string { - temp := make([]string, len(ms)) +func (machines Machines) String() string { + temp := make([]string, len(machines)) - for index, machine := range ms { + for index, machine := range machines { temp[index] = machine.Name } @@ -379,24 +379,24 @@ func (ms Machines) String() string { } // TODO(kradalby): Remove when we have generics... -func (ms MachinesP) String() string { - temp := make([]string, len(ms)) +func (machines MachinesP) String() string { + temp := make([]string, len(machines)) - for index, machine := range ms { + for index, machine := range machines { temp[index] = machine.Name } return fmt.Sprintf("[ %s ](%d)", strings.Join(temp, ", "), len(temp)) } -func (ms Machines) toNodes( +func (machines Machines) toNodes( baseDomain string, dnsConfig *tailcfg.DNSConfig, includeRoutes bool, ) ([]*tailcfg.Node, error) { - nodes := make([]*tailcfg.Node, len(ms)) + nodes := make([]*tailcfg.Node, len(machines)) - for index, machine := range ms { + for index, machine := range machines { node, err := machine.toNode(baseDomain, dnsConfig, includeRoutes) if err != nil { return nil, err @@ -410,23 +410,24 @@ func (ms Machines) toNodes( // toNode converts a Machine into a Tailscale Node. includeRoutes is false for shared nodes // as per the expected behaviour in the official SaaS. -func (m Machine) toNode( +func (machine Machine) toNode( baseDomain string, dnsConfig *tailcfg.DNSConfig, includeRoutes bool, ) (*tailcfg.Node, error) { - nKey, err := wgkey.ParseHex(m.NodeKey) + nodeKey, err := wgkey.ParseHex(machine.NodeKey) if err != nil { return nil, err } - mKey, err := wgkey.ParseHex(m.MachineKey) + + machineKey, err := wgkey.ParseHex(machine.MachineKey) if err != nil { return nil, err } var discoKey tailcfg.DiscoKey - if m.DiscoKey != "" { - dKey, err := wgkey.ParseHex(m.DiscoKey) + if machine.DiscoKey != "" { + dKey, err := wgkey.ParseHex(machine.DiscoKey) if err != nil { return nil, err } @@ -436,12 +437,12 @@ func (m Machine) toNode( } addrs := []netaddr.IPPrefix{} - ip, err := netaddr.ParseIPPrefix(fmt.Sprintf("%s/32", m.IPAddress)) + ip, err := netaddr.ParseIPPrefix(fmt.Sprintf("%s/32", machine.IPAddress)) if err != nil { log.Trace(). Caller(). - Str("ip", m.IPAddress). - Msgf("Failed to parse IP Prefix from IP: %s", m.IPAddress) + Str("ip", machine.IPAddress). + Msgf("Failed to parse IP Prefix from IP: %s", machine.IPAddress) return nil, err } @@ -455,8 +456,8 @@ func (m Machine) toNode( if includeRoutes { routesStr := []string{} - if len(m.EnabledRoutes) != 0 { - allwIps, err := m.EnabledRoutes.MarshalJSON() + if len(machine.EnabledRoutes) != 0 { + allwIps, err := machine.EnabledRoutes.MarshalJSON() if err != nil { return nil, err } @@ -476,8 +477,8 @@ func (m Machine) toNode( } endpoints := []string{} - if len(m.Endpoints) != 0 { - be, err := m.Endpoints.MarshalJSON() + if len(machine.Endpoints) != 0 { + be, err := machine.Endpoints.MarshalJSON() if err != nil { return nil, err } @@ -488,8 +489,8 @@ func (m Machine) toNode( } hostinfo := tailcfg.Hostinfo{} - if len(m.HostInfo) != 0 { - hi, err := m.HostInfo.MarshalJSON() + if len(machine.HostInfo) != 0 { + hi, err := machine.HostInfo.MarshalJSON() if err != nil { return nil, err } @@ -507,29 +508,34 @@ func (m Machine) toNode( } var keyExpiry time.Time - if m.Expiry != nil { - keyExpiry = *m.Expiry + if machine.Expiry != nil { + keyExpiry = *machine.Expiry } else { keyExpiry = time.Time{} } var hostname string if dnsConfig != nil && dnsConfig.Proxied { // MagicDNS - hostname = fmt.Sprintf("%s.%s.%s", m.Name, m.Namespace.Name, baseDomain) + hostname = fmt.Sprintf( + "%s.%s.%s", + machine.Name, + machine.Namespace.Name, + baseDomain, + ) } else { - hostname = m.Name + hostname = machine.Name } n := tailcfg.Node{ - ID: tailcfg.NodeID(m.ID), // this is the actual ID + ID: tailcfg.NodeID(machine.ID), // this is the actual ID StableID: tailcfg.StableNodeID( - strconv.FormatUint(m.ID, BASE_10), + strconv.FormatUint(machine.ID, BASE_10), ), // in headscale, unlike tailcontrol server, IDs are permanent Name: hostname, - User: tailcfg.UserID(m.NamespaceID), - Key: tailcfg.NodeKey(nKey), + User: tailcfg.UserID(machine.NamespaceID), + Key: tailcfg.NodeKey(nodeKey), KeyExpiry: keyExpiry, - Machine: tailcfg.MachineKey(mKey), + Machine: tailcfg.MachineKey(machineKey), DiscoKey: discoKey, Addresses: addrs, AllowedIPs: allowedIPs, @@ -537,68 +543,73 @@ func (m Machine) toNode( DERP: derp, Hostinfo: hostinfo, - Created: m.CreatedAt, - LastSeen: m.LastSeen, + Created: machine.CreatedAt, + LastSeen: machine.LastSeen, KeepAlive: true, - MachineAuthorized: m.Registered, + MachineAuthorized: machine.Registered, Capabilities: []string{tailcfg.CapabilityFileSharing}, } return &n, nil } -func (m *Machine) toProto() *v1.Machine { - machine := &v1.Machine{ - Id: m.ID, - MachineKey: m.MachineKey, +func (machine *Machine) toProto() *v1.Machine { + machineProto := &v1.Machine{ + Id: machine.ID, + MachineKey: machine.MachineKey, - NodeKey: m.NodeKey, - DiscoKey: m.DiscoKey, - IpAddress: m.IPAddress, - Name: m.Name, - Namespace: m.Namespace.toProto(), + NodeKey: machine.NodeKey, + DiscoKey: machine.DiscoKey, + IpAddress: machine.IPAddress, + Name: machine.Name, + Namespace: machine.Namespace.toProto(), - Registered: m.Registered, + Registered: machine.Registered, // TODO(kradalby): Implement register method enum converter // RegisterMethod: , - CreatedAt: timestamppb.New(m.CreatedAt), + CreatedAt: timestamppb.New(machine.CreatedAt), } - if m.AuthKey != nil { - machine.PreAuthKey = m.AuthKey.toProto() + if machine.AuthKey != nil { + machineProto.PreAuthKey = machine.AuthKey.toProto() } - if m.LastSeen != nil { - machine.LastSeen = timestamppb.New(*m.LastSeen) + if machine.LastSeen != nil { + machineProto.LastSeen = timestamppb.New(*machine.LastSeen) } - if m.LastSuccessfulUpdate != nil { - machine.LastSuccessfulUpdate = timestamppb.New(*m.LastSuccessfulUpdate) + if machine.LastSuccessfulUpdate != nil { + machineProto.LastSuccessfulUpdate = timestamppb.New( + *machine.LastSuccessfulUpdate, + ) } - if m.Expiry != nil { - machine.Expiry = timestamppb.New(*m.Expiry) + if machine.Expiry != nil { + machineProto.Expiry = timestamppb.New(*machine.Expiry) } - return machine + return machineProto } // RegisterMachine is executed from the CLI to register a new Machine using its MachineKey. -func (h *Headscale) RegisterMachine(key string, namespace string) (*Machine, error) { - ns, err := h.GetNamespace(namespace) +func (h *Headscale) RegisterMachine( + key string, + namespaceName string, +) (*Machine, error) { + namespace, err := h.GetNamespace(namespaceName) if err != nil { return nil, err } - mKey, err := wgkey.ParseHex(key) + machineKey, err := wgkey.ParseHex(key) if err != nil { return nil, err } - m := Machine{} - if result := h.db.First(&m, "machine_key = ?", mKey.HexString()); errors.Is( + machine := Machine{} + if result := h.db.First(&machine, "machine_key = ?", machineKey.HexString()); errors.Is( result.Error, gorm.ErrRecordNotFound, ) { @@ -607,15 +618,15 @@ func (h *Headscale) RegisterMachine(key string, namespace string) (*Machine, err log.Trace(). Caller(). - Str("machine", m.Name). + Str("machine", machine.Name). Msg("Attempting to register machine") - if m.isAlreadyRegistered() { + if machine.isAlreadyRegistered() { err := errors.New("Machine already registered") log.Error(). Caller(). Err(err). - Str("machine", m.Name). + Str("machine", machine.Name). Msg("Attempting to register machine") return nil, err @@ -626,7 +637,7 @@ func (h *Headscale) RegisterMachine(key string, namespace string) (*Machine, err log.Error(). Caller(). Err(err). - Str("machine", m.Name). + Str("machine", machine.Name). Msg("Could not find IP for the new machine") return nil, err @@ -634,27 +645,27 @@ func (h *Headscale) RegisterMachine(key string, namespace string) (*Machine, err log.Trace(). Caller(). - Str("machine", m.Name). + Str("machine", machine.Name). Str("ip", ip.String()). Msg("Found IP for host") - m.IPAddress = ip.String() - m.NamespaceID = ns.ID - m.Registered = true - m.RegisterMethod = "cli" - h.db.Save(&m) + machine.IPAddress = ip.String() + machine.NamespaceID = namespace.ID + machine.Registered = true + machine.RegisterMethod = "cli" + h.db.Save(&machine) log.Trace(). Caller(). - Str("machine", m.Name). + Str("machine", machine.Name). Str("ip", ip.String()). Msg("Machine registered with the database") - return &m, nil + return &machine, nil } -func (m *Machine) GetAdvertisedRoutes() ([]netaddr.IPPrefix, error) { - hostInfo, err := m.GetHostInfo() +func (machine *Machine) GetAdvertisedRoutes() ([]netaddr.IPPrefix, error) { + hostInfo, err := machine.GetHostInfo() if err != nil { return nil, err } @@ -662,8 +673,8 @@ func (m *Machine) GetAdvertisedRoutes() ([]netaddr.IPPrefix, error) { return hostInfo.RoutableIPs, nil } -func (m *Machine) GetEnabledRoutes() ([]netaddr.IPPrefix, error) { - data, err := m.EnabledRoutes.MarshalJSON() +func (machine *Machine) GetEnabledRoutes() ([]netaddr.IPPrefix, error) { + data, err := machine.EnabledRoutes.MarshalJSON() if err != nil { return nil, err } @@ -686,13 +697,13 @@ func (m *Machine) GetEnabledRoutes() ([]netaddr.IPPrefix, error) { return routes, nil } -func (m *Machine) IsRoutesEnabled(routeStr string) bool { +func (machine *Machine) IsRoutesEnabled(routeStr string) bool { route, err := netaddr.ParseIPPrefix(routeStr) if err != nil { return false } - enabledRoutes, err := m.GetEnabledRoutes() + enabledRoutes, err := machine.GetEnabledRoutes() if err != nil { return false } @@ -708,7 +719,7 @@ func (m *Machine) IsRoutesEnabled(routeStr string) bool { // EnableNodeRoute enables new routes based on a list of new routes. It will _replace_ the // previous list of routes. -func (h *Headscale) EnableRoutes(m *Machine, routeStrs ...string) error { +func (h *Headscale) EnableRoutes(machine *Machine, routeStrs ...string) error { newRoutes := make([]netaddr.IPPrefix, len(routeStrs)) for index, routeStr := range routeStrs { route, err := netaddr.ParseIPPrefix(routeStr) @@ -719,7 +730,7 @@ func (h *Headscale) EnableRoutes(m *Machine, routeStrs ...string) error { newRoutes[index] = route } - availableRoutes, err := m.GetAdvertisedRoutes() + availableRoutes, err := machine.GetAdvertisedRoutes() if err != nil { return err } @@ -728,7 +739,7 @@ func (h *Headscale) EnableRoutes(m *Machine, routeStrs ...string) error { if !containsIpPrefix(availableRoutes, newRoute) { return fmt.Errorf( "route (%s) is not available on node %s", - m.Name, + machine.Name, newRoute, ) } @@ -739,10 +750,10 @@ func (h *Headscale) EnableRoutes(m *Machine, routeStrs ...string) error { return err } - m.EnabledRoutes = datatypes.JSON(routes) - h.db.Save(&m) + machine.EnabledRoutes = datatypes.JSON(routes) + h.db.Save(&machine) - err = h.RequestMapUpdates(m.NamespaceID) + err = h.RequestMapUpdates(machine.NamespaceID) if err != nil { return err } @@ -750,13 +761,13 @@ func (h *Headscale) EnableRoutes(m *Machine, routeStrs ...string) error { return nil } -func (m *Machine) RoutesToProto() (*v1.Routes, error) { - availableRoutes, err := m.GetAdvertisedRoutes() +func (machine *Machine) RoutesToProto() (*v1.Routes, error) { + availableRoutes, err := machine.GetAdvertisedRoutes() if err != nil { return nil, err } - enabledRoutes, err := m.GetEnabledRoutes() + enabledRoutes, err := machine.GetEnabledRoutes() if err != nil { return nil, err } diff --git a/namespaces.go b/namespaces.go index bea922de..858a7aaa 100644 --- a/namespaces.go +++ b/namespaces.go @@ -32,12 +32,12 @@ type Namespace struct { // CreateNamespace creates a new Namespace. Returns error if could not be created // or another namespace already exists. func (h *Headscale) CreateNamespace(name string) (*Namespace, error) { - n := Namespace{} - if err := h.db.Where("name = ?", name).First(&n).Error; err == nil { + namespace := Namespace{} + if err := h.db.Where("name = ?", name).First(&namespace).Error; err == nil { return nil, errorNamespaceExists } - n.Name = name - if err := h.db.Create(&n).Error; err != nil { + namespace.Name = name + if err := h.db.Create(&namespace).Error; err != nil { log.Error(). Str("func", "CreateNamespace"). Err(err). @@ -46,22 +46,22 @@ func (h *Headscale) CreateNamespace(name string) (*Namespace, error) { return nil, err } - return &n, nil + return &namespace, nil } // DestroyNamespace destroys a Namespace. Returns error if the Namespace does // not exist or if there are machines associated with it. func (h *Headscale) DestroyNamespace(name string) error { - n, err := h.GetNamespace(name) + namespace, err := h.GetNamespace(name) if err != nil { return errorNamespaceNotFound } - m, err := h.ListMachinesInNamespace(name) + machines, err := h.ListMachinesInNamespace(name) if err != nil { return err } - if len(m) > 0 { + if len(machines) > 0 { return errorNamespaceNotEmptyOfNodes } @@ -69,14 +69,14 @@ func (h *Headscale) DestroyNamespace(name string) error { if err != nil { return err } - for _, p := range keys { - err = h.DestroyPreAuthKey(&p) + for _, key := range keys { + err = h.DestroyPreAuthKey(&key) if err != nil { return err } } - if result := h.db.Unscoped().Delete(&n); result.Error != nil { + if result := h.db.Unscoped().Delete(&namespace); result.Error != nil { return result.Error } @@ -86,7 +86,7 @@ func (h *Headscale) DestroyNamespace(name string) error { // RenameNamespace renames a Namespace. Returns error if the Namespace does // not exist or if another Namespace exists with the new name. func (h *Headscale) RenameNamespace(oldName, newName string) error { - n, err := h.GetNamespace(oldName) + oldNamespace, err := h.GetNamespace(oldName) if err != nil { return err } @@ -98,13 +98,13 @@ func (h *Headscale) RenameNamespace(oldName, newName string) error { return err } - n.Name = newName + oldNamespace.Name = newName - if result := h.db.Save(&n); result.Error != nil { + if result := h.db.Save(&oldNamespace); result.Error != nil { return result.Error } - err = h.RequestMapUpdates(n.ID) + err = h.RequestMapUpdates(oldNamespace.ID) if err != nil { return err } @@ -114,15 +114,15 @@ func (h *Headscale) RenameNamespace(oldName, newName string) error { // GetNamespace fetches a namespace by name. func (h *Headscale) GetNamespace(name string) (*Namespace, error) { - n := Namespace{} - if result := h.db.First(&n, "name = ?", name); errors.Is( + namespace := Namespace{} + if result := h.db.First(&namespace, "name = ?", name); errors.Is( result.Error, gorm.ErrRecordNotFound, ) { return nil, errorNamespaceNotFound } - return &n, nil + return &namespace, nil } // ListNamespaces gets all the existing namespaces. @@ -137,13 +137,13 @@ func (h *Headscale) ListNamespaces() ([]Namespace, error) { // ListMachinesInNamespace gets all the nodes in a given namespace. func (h *Headscale) ListMachinesInNamespace(name string) ([]Machine, error) { - n, err := h.GetNamespace(name) + namespace, err := h.GetNamespace(name) if err != nil { return nil, err } machines := []Machine{} - if err := h.db.Preload("AuthKey").Preload("AuthKey.Namespace").Preload("Namespace").Where(&Machine{NamespaceID: n.ID}).Find(&machines).Error; err != nil { + if err := h.db.Preload("AuthKey").Preload("AuthKey.Namespace").Preload("Namespace").Where(&Machine{NamespaceID: namespace.ID}).Find(&machines).Error; err != nil { return nil, err } @@ -176,17 +176,18 @@ func (h *Headscale) ListSharedMachinesInNamespace(name string) ([]Machine, error } // SetMachineNamespace assigns a Machine to a namespace. -func (h *Headscale) SetMachineNamespace(m *Machine, namespaceName string) error { - n, err := h.GetNamespace(namespaceName) +func (h *Headscale) SetMachineNamespace(machine *Machine, namespaceName string) error { + namespace, err := h.GetNamespace(namespaceName) if err != nil { return err } - m.NamespaceID = n.ID - h.db.Save(&m) + machine.NamespaceID = namespace.ID + h.db.Save(&machine) return nil } +// TODO(kradalby): Remove the need for this. // RequestMapUpdates signals the KV worker to update the maps for this namespace. func (h *Headscale) RequestMapUpdates(namespaceID uint) error { namespace := Namespace{} @@ -194,8 +195,8 @@ func (h *Headscale) RequestMapUpdates(namespaceID uint) error { return err } - v, err := h.getValue("namespaces_pending_updates") - if err != nil || v == "" { + namespacesPendingUpdates, err := h.getValue("namespaces_pending_updates") + if err != nil || namespacesPendingUpdates == "" { err = h.setValue( "namespaces_pending_updates", fmt.Sprintf(`["%s"]`, namespace.Name), @@ -207,7 +208,7 @@ func (h *Headscale) RequestMapUpdates(namespaceID uint) error { return nil } names := []string{} - err = json.Unmarshal([]byte(v), &names) + err = json.Unmarshal([]byte(namespacesPendingUpdates), &names) if err != nil { err = h.setValue( "namespaces_pending_updates", @@ -235,16 +236,16 @@ func (h *Headscale) RequestMapUpdates(namespaceID uint) error { } func (h *Headscale) checkForNamespacesPendingUpdates() { - v, err := h.getValue("namespaces_pending_updates") + namespacesPendingUpdates, err := h.getValue("namespaces_pending_updates") if err != nil { return } - if v == "" { + if namespacesPendingUpdates == "" { return } namespaces := []string{} - err = json.Unmarshal([]byte(v), &namespaces) + err = json.Unmarshal([]byte(namespacesPendingUpdates), &namespaces) if err != nil { return } @@ -255,11 +256,11 @@ func (h *Headscale) checkForNamespacesPendingUpdates() { Msg("Sending updates to nodes in namespacespace") h.setLastStateChangeToNow(namespace) } - newV, err := h.getValue("namespaces_pending_updates") + newPendingUpdateValue, err := h.getValue("namespaces_pending_updates") if err != nil { return } - if v == newV { // only clear when no changes, so we notified everybody + if namespacesPendingUpdates == newPendingUpdateValue { // only clear when no changes, so we notified everybody err = h.setValue("namespaces_pending_updates", "") if err != nil { log.Error(). @@ -273,7 +274,7 @@ func (h *Headscale) checkForNamespacesPendingUpdates() { } func (n *Namespace) toUser() *tailcfg.User { - u := tailcfg.User{ + user := tailcfg.User{ ID: tailcfg.UserID(n.ID), LoginName: n.Name, DisplayName: n.Name, @@ -283,11 +284,11 @@ func (n *Namespace) toUser() *tailcfg.User { Created: time.Time{}, } - return &u + return &user } func (n *Namespace) toLogin() *tailcfg.Login { - l := tailcfg.Login{ + login := tailcfg.Login{ ID: tailcfg.LoginID(n.ID), LoginName: n.Name, DisplayName: n.Name, @@ -295,14 +296,14 @@ func (n *Namespace) toLogin() *tailcfg.Login { Domain: "headscale.net", } - return &l + return &login } -func getMapResponseUserProfiles(m Machine, peers Machines) []tailcfg.UserProfile { +func getMapResponseUserProfiles(machine Machine, peers Machines) []tailcfg.UserProfile { namespaceMap := make(map[string]Namespace) - namespaceMap[m.Namespace.Name] = m.Namespace - for _, p := range peers { - namespaceMap[p.Namespace.Name] = p.Namespace // not worth checking if already is there + namespaceMap[machine.Namespace.Name] = machine.Namespace + for _, peer := range peers { + namespaceMap[peer.Namespace.Name] = peer.Namespace // not worth checking if already is there } profiles := []tailcfg.UserProfile{} diff --git a/oidc.go b/oidc.go index c77a249e..e68e1122 100644 --- a/oidc.go +++ b/oidc.go @@ -68,10 +68,10 @@ func (h *Headscale) initOIDC() error { // RegisterOIDC redirects to the OIDC provider for authentication // Puts machine key in cache so the callback can retrieve it using the oidc state param // Listens in /oidc/register/:mKey. -func (h *Headscale) RegisterOIDC(c *gin.Context) { - mKeyStr := c.Param("mkey") +func (h *Headscale) RegisterOIDC(ctx *gin.Context) { + mKeyStr := ctx.Param("mkey") if mKeyStr == "" { - c.String(http.StatusBadRequest, "Wrong params") + ctx.String(http.StatusBadRequest, "Wrong params") return } @@ -79,7 +79,7 @@ func (h *Headscale) RegisterOIDC(c *gin.Context) { b := make([]byte, RANDOM_BYTE_SIZE) if _, err := rand.Read(b); err != nil { log.Error().Msg("could not read 16 bytes from rand") - c.String(http.StatusInternalServerError, "could not read 16 bytes from rand") + ctx.String(http.StatusInternalServerError, "could not read 16 bytes from rand") return } @@ -92,7 +92,7 @@ func (h *Headscale) RegisterOIDC(c *gin.Context) { authUrl := h.oauth2Config.AuthCodeURL(stateStr) log.Debug().Msgf("Redirecting to %s for authentication", authUrl) - c.Redirect(http.StatusFound, authUrl) + ctx.Redirect(http.StatusFound, authUrl) } // OIDCCallback handles the callback from the OIDC endpoint @@ -100,19 +100,19 @@ func (h *Headscale) RegisterOIDC(c *gin.Context) { // TODO: A confirmation page for new machines should be added to avoid phishing vulnerabilities // TODO: Add groups information from OIDC tokens into machine HostInfo // Listens in /oidc/callback. -func (h *Headscale) OIDCCallback(c *gin.Context) { - code := c.Query("code") - state := c.Query("state") +func (h *Headscale) OIDCCallback(ctx *gin.Context) { + code := ctx.Query("code") + state := ctx.Query("state") if code == "" || state == "" { - c.String(http.StatusBadRequest, "Wrong params") + ctx.String(http.StatusBadRequest, "Wrong params") return } oauth2Token, err := h.oauth2Config.Exchange(context.Background(), code) if err != nil { - c.String(http.StatusBadRequest, "Could not exchange code for token") + ctx.String(http.StatusBadRequest, "Could not exchange code for token") return } @@ -121,7 +121,7 @@ func (h *Headscale) OIDCCallback(c *gin.Context) { rawIDToken, rawIDTokenOK := oauth2Token.Extra("id_token").(string) if !rawIDTokenOK { - c.String(http.StatusBadRequest, "Could not extract ID Token") + ctx.String(http.StatusBadRequest, "Could not extract ID Token") return } @@ -130,7 +130,7 @@ func (h *Headscale) OIDCCallback(c *gin.Context) { idToken, err := verifier.Verify(context.Background(), rawIDToken) if err != nil { - c.String(http.StatusBadRequest, "Failed to verify id token: %s", err.Error()) + ctx.String(http.StatusBadRequest, "Failed to verify id token: %s", err.Error()) return } @@ -145,7 +145,7 @@ func (h *Headscale) OIDCCallback(c *gin.Context) { // Extract custom claims var claims IDTokenClaims if err = idToken.Claims(&claims); err != nil { - c.String( + ctx.String( http.StatusBadRequest, fmt.Sprintf("Failed to decode id token claims: %s", err), ) @@ -159,7 +159,7 @@ func (h *Headscale) OIDCCallback(c *gin.Context) { if !mKeyFound { log.Error(). Msg("requested machine state key expired before authorisation completed") - c.String(http.StatusBadRequest, "state has expired") + ctx.String(http.StatusBadRequest, "state has expired") return } @@ -167,16 +167,19 @@ func (h *Headscale) OIDCCallback(c *gin.Context) { if !mKeyOK { log.Error().Msg("could not get machine key from cache") - c.String(http.StatusInternalServerError, "could not get machine key from cache") + ctx.String( + http.StatusInternalServerError, + "could not get machine key from cache", + ) return } // retrieve machine information - m, err := h.GetMachineByMachineKey(mKeyStr) + machine, err := h.GetMachineByMachineKey(mKeyStr) if err != nil { log.Error().Msg("machine key not found in database") - c.String( + ctx.String( http.StatusInternalServerError, "could not get machine info from database", ) @@ -186,19 +189,19 @@ func (h *Headscale) OIDCCallback(c *gin.Context) { now := time.Now().UTC() - if nsName, ok := h.getNamespaceFromEmail(claims.Email); ok { + if namespaceName, ok := h.getNamespaceFromEmail(claims.Email); ok { // register the machine if it's new - if !m.Registered { + if !machine.Registered { log.Debug().Msg("Registering new machine after successful callback") - ns, err := h.GetNamespace(nsName) + namespace, err := h.GetNamespace(namespaceName) if err != nil { - ns, err = h.CreateNamespace(nsName) + namespace, err = h.CreateNamespace(namespaceName) if err != nil { log.Error(). Msgf("could not create new namespace '%s'", claims.Email) - c.String( + ctx.String( http.StatusInternalServerError, "could not create new namespace", ) @@ -209,7 +212,7 @@ func (h *Headscale) OIDCCallback(c *gin.Context) { ip, err := h.getAvailableIP() if err != nil { - c.String( + ctx.String( http.StatusInternalServerError, "could not get an IP from the pool", ) @@ -217,17 +220,17 @@ func (h *Headscale) OIDCCallback(c *gin.Context) { return } - m.IPAddress = ip.String() - m.NamespaceID = ns.ID - m.Registered = true - m.RegisterMethod = "oidc" - m.LastSuccessfulUpdate = &now - h.db.Save(&m) + machine.IPAddress = ip.String() + machine.NamespaceID = namespace.ID + machine.Registered = true + machine.RegisterMethod = "oidc" + machine.LastSuccessfulUpdate = &now + h.db.Save(&machine) } - h.updateMachineExpiry(m) + h.updateMachineExpiry(machine) - c.Data(http.StatusOK, "text/html; charset=utf-8", []byte(fmt.Sprintf(` + ctx.Data(http.StatusOK, "text/html; charset=utf-8", []byte(fmt.Sprintf(`

headscale

@@ -243,9 +246,9 @@ func (h *Headscale) OIDCCallback(c *gin.Context) { log.Error(). Str("email", claims.Email). Str("username", claims.Username). - Str("machine", m.Name). + Str("machine", machine.Name). Msg("Email could not be mapped to a namespace") - c.String( + ctx.String( http.StatusBadRequest, "email from claim could not be mapped to a namespace", ) diff --git a/poll.go b/poll.go index 3f7b2939..19278538 100644 --- a/poll.go +++ b/poll.go @@ -233,7 +233,7 @@ func (h *Headscale) PollNetMapStream( ) { go h.scheduledPollWorker(cancelKeepAlive, updateChan, keepAliveChan, mKey, req, m) - c.Stream(func(w io.Writer) bool { + c.Stream(func(writer io.Writer) bool { log.Trace(). Str("handler", "PollNetMapStream"). Str("machine", m.Name). @@ -252,7 +252,7 @@ func (h *Headscale) PollNetMapStream( Str("channel", "pollData"). Int("bytes", len(data)). Msg("Sending data received via pollData channel") - _, err := w.Write(data) + _, err := writer.Write(data) if err != nil { log.Error(). Str("handler", "PollNetMapStream"). @@ -305,7 +305,7 @@ func (h *Headscale) PollNetMapStream( Str("channel", "keepAlive"). Int("bytes", len(data)). Msg("Sending keep alive message") - _, err := w.Write(data) + _, err := writer.Write(data) if err != nil { log.Error(). Str("handler", "PollNetMapStream"). @@ -370,7 +370,7 @@ func (h *Headscale) PollNetMapStream( Err(err). Msg("Could not get the map update") } - _, err = w.Write(data) + _, err = writer.Write(data) if err != nil { log.Error(). Str("handler", "PollNetMapStream"). diff --git a/sharing.go b/sharing.go index 8f654143..741deb61 100644 --- a/sharing.go +++ b/sharing.go @@ -18,13 +18,16 @@ type SharedMachine struct { } // AddSharedMachineToNamespace adds a machine as a shared node to a namespace. -func (h *Headscale) AddSharedMachineToNamespace(m *Machine, ns *Namespace) error { - if m.NamespaceID == ns.ID { +func (h *Headscale) AddSharedMachineToNamespace( + machine *Machine, + namespace *Namespace, +) error { + if machine.NamespaceID == namespace.ID { return errorSameNamespace } sharedMachines := []SharedMachine{} - if err := h.db.Where("machine_id = ? AND namespace_id = ?", m.ID, ns.ID).Find(&sharedMachines).Error; err != nil { + if err := h.db.Where("machine_id = ? AND namespace_id = ?", machine.ID, namespace.ID).Find(&sharedMachines).Error; err != nil { return err } if len(sharedMachines) > 0 { @@ -32,10 +35,10 @@ func (h *Headscale) AddSharedMachineToNamespace(m *Machine, ns *Namespace) error } sharedMachine := SharedMachine{ - MachineID: m.ID, - Machine: *m, - NamespaceID: ns.ID, - Namespace: *ns, + MachineID: machine.ID, + Machine: *machine, + NamespaceID: namespace.ID, + Namespace: *namespace, } h.db.Save(&sharedMachine) @@ -43,14 +46,17 @@ func (h *Headscale) AddSharedMachineToNamespace(m *Machine, ns *Namespace) error } // RemoveSharedMachineFromNamespace removes a shared machine from a namespace. -func (h *Headscale) RemoveSharedMachineFromNamespace(m *Machine, ns *Namespace) error { - if m.NamespaceID == ns.ID { +func (h *Headscale) RemoveSharedMachineFromNamespace( + machine *Machine, + namespace *Namespace, +) error { + if machine.NamespaceID == namespace.ID { // Can't unshare from primary namespace return errorMachineNotShared } sharedMachine := SharedMachine{} - result := h.db.Where("machine_id = ? AND namespace_id = ?", m.ID, ns.ID). + result := h.db.Where("machine_id = ? AND namespace_id = ?", machine.ID, namespace.ID). Unscoped(). Delete(&sharedMachine) if result.Error != nil { @@ -61,7 +67,7 @@ func (h *Headscale) RemoveSharedMachineFromNamespace(m *Machine, ns *Namespace) return errorMachineNotShared } - err := h.RequestMapUpdates(ns.ID) + err := h.RequestMapUpdates(namespace.ID) if err != nil { return err } @@ -70,9 +76,9 @@ func (h *Headscale) RemoveSharedMachineFromNamespace(m *Machine, ns *Namespace) } // RemoveSharedMachineFromAllNamespaces removes a machine as a shared node from all namespaces. -func (h *Headscale) RemoveSharedMachineFromAllNamespaces(m *Machine) error { +func (h *Headscale) RemoveSharedMachineFromAllNamespaces(machine *Machine) error { sharedMachine := SharedMachine{} - if result := h.db.Where("machine_id = ?", m.ID).Unscoped().Delete(&sharedMachine); result.Error != nil { + if result := h.db.Where("machine_id = ?", machine.ID).Unscoped().Delete(&sharedMachine); result.Error != nil { return result.Error } diff --git a/swagger.go b/swagger.go index 01b2eb50..9e62d393 100644 --- a/swagger.go +++ b/swagger.go @@ -13,8 +13,8 @@ import ( //go:embed gen/openapiv2/headscale/v1/headscale.swagger.json var apiV1JSON []byte -func SwaggerUI(c *gin.Context) { - t := template.Must(template.New("swagger").Parse(` +func SwaggerUI(ctx *gin.Context) { + swaggerTemplate := template.Must(template.New("swagger").Parse(` @@ -47,12 +47,12 @@ func SwaggerUI(c *gin.Context) { `)) var payload bytes.Buffer - if err := t.Execute(&payload, struct{}{}); err != nil { + if err := swaggerTemplate.Execute(&payload, struct{}{}); err != nil { log.Error(). Caller(). Err(err). Msg("Could not render Swagger") - c.Data( + ctx.Data( http.StatusInternalServerError, "text/html; charset=utf-8", []byte("Could not render Swagger"), @@ -61,9 +61,9 @@ func SwaggerUI(c *gin.Context) { return } - c.Data(http.StatusOK, "text/html; charset=utf-8", payload.Bytes()) + ctx.Data(http.StatusOK, "text/html; charset=utf-8", payload.Bytes()) } -func SwaggerAPIv1(c *gin.Context) { - c.Data(http.StatusOK, "application/json; charset=utf-8", apiV1JSON) +func SwaggerAPIv1(ctx *gin.Context) { + ctx.Data(http.StatusOK, "application/json; charset=utf-8", apiV1JSON) } diff --git a/utils.go b/utils.go index 85e3ba28..803cfc5d 100644 --- a/utils.go +++ b/utils.go @@ -36,7 +36,7 @@ func decode( func decodeMsg( msg []byte, - v interface{}, + output interface{}, pubKey *wgkey.Key, privKey *wgkey.Private, ) error { @@ -45,7 +45,7 @@ func decodeMsg( return err } // fmt.Println(string(decrypted)) - if err := json.Unmarshal(decrypted, v); err != nil { + if err := json.Unmarshal(decrypted, output); err != nil { return fmt.Errorf("response: %v", err) } @@ -78,13 +78,17 @@ func encode(v interface{}, pubKey *wgkey.Key, privKey *wgkey.Private) ([]byte, e return encodeMsg(b, pubKey, privKey) } -func encodeMsg(b []byte, pubKey *wgkey.Key, privKey *wgkey.Private) ([]byte, error) { +func encodeMsg( + payload []byte, + pubKey *wgkey.Key, + privKey *wgkey.Private, +) ([]byte, error) { var nonce [24]byte if _, err := io.ReadFull(rand.Reader, nonce[:]); err != nil { panic(err) } pub, pri := (*[32]byte)(pubKey), (*[32]byte)(privKey) - msg := box.Seal(nonce[:], b, &nonce, pub, pri) + msg := box.Seal(nonce[:], payload, &nonce, pub, pri) return msg, nil } From 8454c1b52c4b90b3dd82e257db1b95cc36d04d92 Mon Sep 17 00:00:00 2001 From: ohdearaugustin Date: Sun, 14 Nov 2021 21:15:33 +0100 Subject: [PATCH 150/300] workflows/release: add docker debug --- .github/workflows/release.yml | 40 +++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index c0605f10..05d01c92 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -72,3 +72,43 @@ jobs: context: . tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} + + docker-debug-release: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + with: + fetch-depth: 0 + - name: Docker meta + id: meta + uses: docker/metadata-action@v3 + with: + # list of Docker images to use as base name for tags + images: | + ${{ secrets.DOCKERHUB_USERNAME }}/headscale + ghcr.io/${{ github.repository_owner }}/headscale + tags: | + type=semver,pattern={{version}}-debug + type=semver,pattern={{major}}.{{minor}}-debug + type=semver,pattern={{major}}-debug + type=sha-debug + - name: Login to DockerHub + uses: docker/login-action@v1 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + - name: Login to GHCR + uses: docker/login-action@v1 + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + - name: Build and push + id: docker_build + uses: docker/build-push-action@v2 + with: + push: true + context: . + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} From c6bc9fffe96545a732ef6ac3f1870b5c2efb0958 Mon Sep 17 00:00:00 2001 From: ohdearaugustin Date: Sun, 14 Nov 2021 22:24:27 +0100 Subject: [PATCH 151/300] workflows/release: fix docker debug tags --- .github/workflows/release.yml | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 05d01c92..ace8014b 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -81,18 +81,21 @@ jobs: with: fetch-depth: 0 - name: Docker meta - id: meta + id: meta-debug uses: docker/metadata-action@v3 with: # list of Docker images to use as base name for tags images: | ${{ secrets.DOCKERHUB_USERNAME }}/headscale ghcr.io/${{ github.repository_owner }}/headscale + flavor: | + latest=false tags: | type=semver,pattern={{version}}-debug type=semver,pattern={{major}}.{{minor}}-debug type=semver,pattern={{major}}-debug - type=sha-debug + type=raw,value=latest-debug + type=sha,suffix=-debug - name: Login to DockerHub uses: docker/login-action@v1 with: @@ -110,5 +113,6 @@ jobs: with: push: true context: . - tags: ${{ steps.meta.outputs.tags }} - labels: ${{ steps.meta.outputs.labels }} + file: Dockerfile.debug + tags: ${{ steps.meta-debug.outputs.tags }} + labels: ${{ steps.meta-debug.outputs.labels }} From 333be80f9ca963b9642794811a91ac5c374e191f Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Mon, 15 Nov 2021 16:15:50 +0000 Subject: [PATCH 152/300] Fix rest of var name in main code --- db.go | 6 +- machine.go | 4 +- oidc.go | 6 +- poll.go | 219 +++++++++++++++++++++++++----------------------- preauth_keys.go | 16 ++-- routes.go | 16 ++-- 6 files changed, 137 insertions(+), 130 deletions(-) diff --git a/db.go b/db.go index 77d4ba03..fa200604 100644 --- a/db.go +++ b/db.go @@ -100,18 +100,18 @@ func (h *Headscale) getValue(key string) (string, error) { // setValue sets value for the given key in KV. func (h *Headscale) setValue(key string, value string) error { - kv := KV{ + keyValue := KV{ Key: key, Value: value, } if _, err := h.getValue(key); err == nil { - h.db.Model(&kv).Where("key = ?", key).Update("value", value) + h.db.Model(&keyValue).Where("key = ?", key).Update("value", value) return nil } - h.db.Create(kv) + h.db.Create(keyValue) return nil } diff --git a/machine.go b/machine.go index d1f27cc8..4dc9cd99 100644 --- a/machine.go +++ b/machine.go @@ -526,7 +526,7 @@ func (machine Machine) toNode( hostname = machine.Name } - n := tailcfg.Node{ + node := tailcfg.Node{ ID: tailcfg.NodeID(machine.ID), // this is the actual ID StableID: tailcfg.StableNodeID( strconv.FormatUint(machine.ID, BASE_10), @@ -551,7 +551,7 @@ func (machine Machine) toNode( Capabilities: []string{tailcfg.CapabilityFileSharing}, } - return &n, nil + return &node, nil } func (machine *Machine) toProto() *v1.Machine { diff --git a/oidc.go b/oidc.go index e68e1122..7e24ed3f 100644 --- a/oidc.go +++ b/oidc.go @@ -76,15 +76,15 @@ func (h *Headscale) RegisterOIDC(ctx *gin.Context) { return } - b := make([]byte, RANDOM_BYTE_SIZE) - if _, err := rand.Read(b); err != nil { + randomBlob := make([]byte, RANDOM_BYTE_SIZE) + if _, err := rand.Read(randomBlob); err != nil { log.Error().Msg("could not read 16 bytes from rand") ctx.String(http.StatusInternalServerError, "could not read 16 bytes from rand") return } - stateStr := hex.EncodeToString(b)[:32] + stateStr := hex.EncodeToString(randomBlob)[:32] // place the machine key into the state cache, so it can be retrieved later h.oidcStateCache.Set(stateStr, mKeyStr, OIDC_STATE_CACHE_EXPIRATION) diff --git a/poll.go b/poll.go index 19278538..aaf5bd0b 100644 --- a/poll.go +++ b/poll.go @@ -29,20 +29,20 @@ const ( // only after their first request (marked with the ReadOnly field). // // At this moment the updates are sent in a quite horrendous way, but they kinda work. -func (h *Headscale) PollNetMapHandler(c *gin.Context) { +func (h *Headscale) PollNetMapHandler(ctx *gin.Context) { log.Trace(). Str("handler", "PollNetMap"). - Str("id", c.Param("id")). + Str("id", ctx.Param("id")). Msg("PollNetMapHandler called") - body, _ := io.ReadAll(c.Request.Body) - mKeyStr := c.Param("id") + body, _ := io.ReadAll(ctx.Request.Body) + mKeyStr := ctx.Param("id") mKey, err := wgkey.ParseHex(mKeyStr) if err != nil { log.Error(). Str("handler", "PollNetMap"). Err(err). Msg("Cannot parse client key") - c.String(http.StatusBadRequest, "") + ctx.String(http.StatusBadRequest, "") return } @@ -53,36 +53,36 @@ func (h *Headscale) PollNetMapHandler(c *gin.Context) { Str("handler", "PollNetMap"). Err(err). Msg("Cannot decode message") - c.String(http.StatusBadRequest, "") + ctx.String(http.StatusBadRequest, "") return } - m, err := h.GetMachineByMachineKey(mKey.HexString()) + machine, err := h.GetMachineByMachineKey(mKey.HexString()) if err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { log.Warn(). Str("handler", "PollNetMap"). Msgf("Ignoring request, cannot find machine with key %s", mKey.HexString()) - c.String(http.StatusUnauthorized, "") + ctx.String(http.StatusUnauthorized, "") return } log.Error(). Str("handler", "PollNetMap"). Msgf("Failed to fetch machine from the database with Machine key: %s", mKey.HexString()) - c.String(http.StatusInternalServerError, "") + ctx.String(http.StatusInternalServerError, "") } log.Trace(). Str("handler", "PollNetMap"). - Str("id", c.Param("id")). - Str("machine", m.Name). + Str("id", ctx.Param("id")). + Str("machine", machine.Name). Msg("Found machine in database") hostinfo, _ := json.Marshal(req.Hostinfo) - m.Name = req.Hostinfo.Hostname - m.HostInfo = datatypes.JSON(hostinfo) - m.DiscoKey = wgkey.Key(req.DiscoKey).HexString() + machine.Name = req.Hostinfo.Hostname + machine.HostInfo = datatypes.JSON(hostinfo) + machine.DiscoKey = wgkey.Key(req.DiscoKey).HexString() now := time.Now().UTC() // From Tailscale client: @@ -95,20 +95,20 @@ func (h *Headscale) PollNetMapHandler(c *gin.Context) { // before their first real endpoint update. if !req.ReadOnly { endpoints, _ := json.Marshal(req.Endpoints) - m.Endpoints = datatypes.JSON(endpoints) - m.LastSeen = &now + machine.Endpoints = datatypes.JSON(endpoints) + machine.LastSeen = &now } - h.db.Save(&m) + h.db.Save(&machine) - data, err := h.getMapResponse(mKey, req, m) + data, err := h.getMapResponse(mKey, req, machine) if err != nil { log.Error(). Str("handler", "PollNetMap"). - Str("id", c.Param("id")). - Str("machine", m.Name). + Str("id", ctx.Param("id")). + Str("machine", machine.Name). Err(err). Msg("Failed to get Map response") - c.String(http.StatusInternalServerError, ":(") + ctx.String(http.StatusInternalServerError, ":(") return } @@ -120,8 +120,8 @@ func (h *Headscale) PollNetMapHandler(c *gin.Context) { // Details on the protocol can be found in https://github.com/tailscale/tailscale/blob/main/tailcfg/tailcfg.go#L696 log.Debug(). Str("handler", "PollNetMap"). - Str("id", c.Param("id")). - Str("machine", m.Name). + Str("id", ctx.Param("id")). + Str("machine", machine.Name). Bool("readOnly", req.ReadOnly). Bool("omitPeers", req.OmitPeers). Bool("stream", req.Stream). @@ -130,16 +130,16 @@ func (h *Headscale) PollNetMapHandler(c *gin.Context) { if req.ReadOnly { log.Info(). Str("handler", "PollNetMap"). - Str("machine", m.Name). + Str("machine", machine.Name). Msg("Client is starting up. Probably interested in a DERP map") - c.Data(http.StatusOK, "application/json; charset=utf-8", data) + ctx.Data(http.StatusOK, "application/json; charset=utf-8", data) return } // There has been an update to _any_ of the nodes that the other nodes would // need to know about - h.setLastStateChangeToNow(m.Namespace.Name) + h.setLastStateChangeToNow(machine.Namespace.Name) // The request is not ReadOnly, so we need to set up channels for updating // peers via longpoll @@ -147,8 +147,8 @@ func (h *Headscale) PollNetMapHandler(c *gin.Context) { // Only create update channel if it has not been created log.Trace(). Str("handler", "PollNetMap"). - Str("id", c.Param("id")). - Str("machine", m.Name). + Str("id", ctx.Param("id")). + Str("machine", machine.Name). Msg("Loading or creating update channel") updateChan := make(chan struct{}) @@ -162,13 +162,13 @@ func (h *Headscale) PollNetMapHandler(c *gin.Context) { if req.OmitPeers && !req.Stream { log.Info(). Str("handler", "PollNetMap"). - Str("machine", m.Name). + Str("machine", machine.Name). Msg("Client sent endpoint update and is ok with a response without peer list") - c.Data(http.StatusOK, "application/json; charset=utf-8", data) + ctx.Data(http.StatusOK, "application/json; charset=utf-8", data) // It sounds like we should update the nodes when we have received a endpoint update // even tho the comments in the tailscale code dont explicitly say so. - updateRequestsFromNode.WithLabelValues(m.Name, m.Namespace.Name, "endpoint-update"). + updateRequestsFromNode.WithLabelValues(machine.Name, machine.Namespace.Name, "endpoint-update"). Inc() go func() { updateChan <- struct{}{} }() @@ -176,34 +176,34 @@ func (h *Headscale) PollNetMapHandler(c *gin.Context) { } else if req.OmitPeers && req.Stream { log.Warn(). Str("handler", "PollNetMap"). - Str("machine", m.Name). + Str("machine", machine.Name). Msg("Ignoring request, don't know how to handle it") - c.String(http.StatusBadRequest, "") + ctx.String(http.StatusBadRequest, "") return } log.Info(). Str("handler", "PollNetMap"). - Str("machine", m.Name). + Str("machine", machine.Name). Msg("Client is ready to access the tailnet") log.Info(). Str("handler", "PollNetMap"). - Str("machine", m.Name). + Str("machine", machine.Name). Msg("Sending initial map") go func() { pollDataChan <- data }() log.Info(). Str("handler", "PollNetMap"). - Str("machine", m.Name). + Str("machine", machine.Name). Msg("Notifying peers") - updateRequestsFromNode.WithLabelValues(m.Name, m.Namespace.Name, "full-update"). + updateRequestsFromNode.WithLabelValues(machine.Name, machine.Namespace.Name, "full-update"). Inc() go func() { updateChan <- struct{}{} }() h.PollNetMapStream( - c, - m, + ctx, + machine, req, mKey, pollDataChan, @@ -213,8 +213,8 @@ func (h *Headscale) PollNetMapHandler(c *gin.Context) { ) log.Trace(). Str("handler", "PollNetMap"). - Str("id", c.Param("id")). - Str("machine", m.Name). + Str("id", ctx.Param("id")). + Str("machine", machine.Name). Msg("Finished stream, closing PollNetMap session") } @@ -222,33 +222,40 @@ func (h *Headscale) PollNetMapHandler(c *gin.Context) { // stream logic, ensuring we communicate updates and data // to the connected clients. func (h *Headscale) PollNetMapStream( - c *gin.Context, - m *Machine, - req tailcfg.MapRequest, - mKey wgkey.Key, + ctx *gin.Context, + machine *Machine, + mapRequest tailcfg.MapRequest, + machineKey wgkey.Key, pollDataChan chan []byte, keepAliveChan chan []byte, updateChan chan struct{}, cancelKeepAlive chan struct{}, ) { - go h.scheduledPollWorker(cancelKeepAlive, updateChan, keepAliveChan, mKey, req, m) + go h.scheduledPollWorker( + cancelKeepAlive, + updateChan, + keepAliveChan, + machineKey, + mapRequest, + machine, + ) - c.Stream(func(writer io.Writer) bool { + ctx.Stream(func(writer io.Writer) bool { log.Trace(). Str("handler", "PollNetMapStream"). - Str("machine", m.Name). + Str("machine", machine.Name). Msg("Waiting for data to stream...") log.Trace(). Str("handler", "PollNetMapStream"). - Str("machine", m.Name). + Str("machine", machine.Name). Msgf("pollData is %#v, keepAliveChan is %#v, updateChan is %#v", pollDataChan, keepAliveChan, updateChan) select { case data := <-pollDataChan: log.Trace(). Str("handler", "PollNetMapStream"). - Str("machine", m.Name). + Str("machine", machine.Name). Str("channel", "pollData"). Int("bytes", len(data)). Msg("Sending data received via pollData channel") @@ -256,7 +263,7 @@ func (h *Headscale) PollNetMapStream( if err != nil { log.Error(). Str("handler", "PollNetMapStream"). - Str("machine", m.Name). + Str("machine", machine.Name). Str("channel", "pollData"). Err(err). Msg("Cannot write data") @@ -265,33 +272,33 @@ func (h *Headscale) PollNetMapStream( } log.Trace(). Str("handler", "PollNetMapStream"). - Str("machine", m.Name). + Str("machine", machine.Name). Str("channel", "pollData"). Int("bytes", len(data)). Msg("Data from pollData channel written successfully") // TODO(kradalby): Abstract away all the database calls, this can cause race conditions // when an outdated machine object is kept alive, e.g. db is update from // command line, but then overwritten. - err = h.UpdateMachine(m) + err = h.UpdateMachine(machine) if err != nil { log.Error(). Str("handler", "PollNetMapStream"). - Str("machine", m.Name). + Str("machine", machine.Name). Str("channel", "pollData"). Err(err). Msg("Cannot update machine from database") } now := time.Now().UTC() - m.LastSeen = &now + machine.LastSeen = &now - lastStateUpdate.WithLabelValues(m.Namespace.Name, m.Name). + lastStateUpdate.WithLabelValues(machine.Namespace.Name, machine.Name). Set(float64(now.Unix())) - m.LastSuccessfulUpdate = &now + machine.LastSuccessfulUpdate = &now - h.db.Save(&m) + h.db.Save(&machine) log.Trace(). Str("handler", "PollNetMapStream"). - Str("machine", m.Name). + Str("machine", machine.Name). Str("channel", "pollData"). Int("bytes", len(data)). Msg("Machine entry in database updated successfully after sending pollData") @@ -301,7 +308,7 @@ func (h *Headscale) PollNetMapStream( case data := <-keepAliveChan: log.Trace(). Str("handler", "PollNetMapStream"). - Str("machine", m.Name). + Str("machine", machine.Name). Str("channel", "keepAlive"). Int("bytes", len(data)). Msg("Sending keep alive message") @@ -309,7 +316,7 @@ func (h *Headscale) PollNetMapStream( if err != nil { log.Error(). Str("handler", "PollNetMapStream"). - Str("machine", m.Name). + Str("machine", machine.Name). Str("channel", "keepAlive"). Err(err). Msg("Cannot write keep alive message") @@ -318,28 +325,28 @@ func (h *Headscale) PollNetMapStream( } log.Trace(). Str("handler", "PollNetMapStream"). - Str("machine", m.Name). + Str("machine", machine.Name). Str("channel", "keepAlive"). Int("bytes", len(data)). Msg("Keep alive sent successfully") // TODO(kradalby): Abstract away all the database calls, this can cause race conditions // when an outdated machine object is kept alive, e.g. db is update from // command line, but then overwritten. - err = h.UpdateMachine(m) + err = h.UpdateMachine(machine) if err != nil { log.Error(). Str("handler", "PollNetMapStream"). - Str("machine", m.Name). + Str("machine", machine.Name). Str("channel", "keepAlive"). Err(err). Msg("Cannot update machine from database") } now := time.Now().UTC() - m.LastSeen = &now - h.db.Save(&m) + machine.LastSeen = &now + h.db.Save(&machine) log.Trace(). Str("handler", "PollNetMapStream"). - Str("machine", m.Name). + Str("machine", machine.Name). Str("channel", "keepAlive"). Int("bytes", len(data)). Msg("Machine updated successfully after sending keep alive") @@ -349,23 +356,23 @@ func (h *Headscale) PollNetMapStream( case <-updateChan: log.Trace(). Str("handler", "PollNetMapStream"). - Str("machine", m.Name). + Str("machine", machine.Name). Str("channel", "update"). Msg("Received a request for update") - updateRequestsReceivedOnChannel.WithLabelValues(m.Name, m.Namespace.Name). + updateRequestsReceivedOnChannel.WithLabelValues(machine.Name, machine.Namespace.Name). Inc() - if h.isOutdated(m) { + if h.isOutdated(machine) { log.Debug(). Str("handler", "PollNetMapStream"). - Str("machine", m.Name). - Time("last_successful_update", *m.LastSuccessfulUpdate). - Time("last_state_change", h.getLastStateChange(m.Namespace.Name)). - Msgf("There has been updates since the last successful update to %s", m.Name) - data, err := h.getMapResponse(mKey, req, m) + Str("machine", machine.Name). + Time("last_successful_update", *machine.LastSuccessfulUpdate). + Time("last_state_change", h.getLastStateChange(machine.Namespace.Name)). + Msgf("There has been updates since the last successful update to %s", machine.Name) + data, err := h.getMapResponse(machineKey, mapRequest, machine) if err != nil { log.Error(). Str("handler", "PollNetMapStream"). - Str("machine", m.Name). + Str("machine", machine.Name). Str("channel", "update"). Err(err). Msg("Could not get the map update") @@ -374,21 +381,21 @@ func (h *Headscale) PollNetMapStream( if err != nil { log.Error(). Str("handler", "PollNetMapStream"). - Str("machine", m.Name). + Str("machine", machine.Name). Str("channel", "update"). Err(err). Msg("Could not write the map response") - updateRequestsSentToNode.WithLabelValues(m.Name, m.Namespace.Name, "failed"). + updateRequestsSentToNode.WithLabelValues(machine.Name, machine.Namespace.Name, "failed"). Inc() return false } log.Trace(). Str("handler", "PollNetMapStream"). - Str("machine", m.Name). + Str("machine", machine.Name). Str("channel", "update"). Msg("Updated Map has been sent") - updateRequestsSentToNode.WithLabelValues(m.Name, m.Namespace.Name, "success"). + updateRequestsSentToNode.WithLabelValues(machine.Name, machine.Namespace.Name, "success"). Inc() // Keep track of the last successful update, @@ -398,64 +405,64 @@ func (h *Headscale) PollNetMapStream( // TODO(kradalby): Abstract away all the database calls, this can cause race conditions // when an outdated machine object is kept alive, e.g. db is update from // command line, but then overwritten. - err = h.UpdateMachine(m) + err = h.UpdateMachine(machine) if err != nil { log.Error(). Str("handler", "PollNetMapStream"). - Str("machine", m.Name). + Str("machine", machine.Name). Str("channel", "update"). Err(err). Msg("Cannot update machine from database") } now := time.Now().UTC() - lastStateUpdate.WithLabelValues(m.Namespace.Name, m.Name). + lastStateUpdate.WithLabelValues(machine.Namespace.Name, machine.Name). Set(float64(now.Unix())) - m.LastSuccessfulUpdate = &now + machine.LastSuccessfulUpdate = &now - h.db.Save(&m) + h.db.Save(&machine) } else { log.Trace(). Str("handler", "PollNetMapStream"). - Str("machine", m.Name). - Time("last_successful_update", *m.LastSuccessfulUpdate). - Time("last_state_change", h.getLastStateChange(m.Namespace.Name)). - Msgf("%s is up to date", m.Name) + Str("machine", machine.Name). + Time("last_successful_update", *machine.LastSuccessfulUpdate). + Time("last_state_change", h.getLastStateChange(machine.Namespace.Name)). + Msgf("%s is up to date", machine.Name) } return true - case <-c.Request.Context().Done(): + case <-ctx.Request.Context().Done(): log.Info(). Str("handler", "PollNetMapStream"). - Str("machine", m.Name). + Str("machine", machine.Name). Msg("The client has closed the connection") // TODO: Abstract away all the database calls, this can cause race conditions // when an outdated machine object is kept alive, e.g. db is update from // command line, but then overwritten. - err := h.UpdateMachine(m) + err := h.UpdateMachine(machine) if err != nil { log.Error(). Str("handler", "PollNetMapStream"). - Str("machine", m.Name). + Str("machine", machine.Name). Str("channel", "Done"). Err(err). Msg("Cannot update machine from database") } now := time.Now().UTC() - m.LastSeen = &now - h.db.Save(&m) + machine.LastSeen = &now + h.db.Save(&machine) log.Trace(). Str("handler", "PollNetMapStream"). - Str("machine", m.Name). + Str("machine", machine.Name). Str("channel", "Done"). Msg("Cancelling keepAlive channel") cancelKeepAlive <- struct{}{} log.Trace(). Str("handler", "PollNetMapStream"). - Str("machine", m.Name). + Str("machine", machine.Name). Str("channel", "Done"). Msg("Closing update channel") // h.closeUpdateChannel(m) @@ -463,14 +470,14 @@ func (h *Headscale) PollNetMapStream( log.Trace(). Str("handler", "PollNetMapStream"). - Str("machine", m.Name). + Str("machine", machine.Name). Str("channel", "Done"). Msg("Closing pollData channel") close(pollDataChan) log.Trace(). Str("handler", "PollNetMapStream"). - Str("machine", m.Name). + Str("machine", machine.Name). Str("channel", "Done"). Msg("Closing keepAliveChan channel") close(keepAliveChan) @@ -484,9 +491,9 @@ func (h *Headscale) scheduledPollWorker( cancelChan <-chan struct{}, updateChan chan<- struct{}, keepAliveChan chan<- []byte, - mKey wgkey.Key, - req tailcfg.MapRequest, - m *Machine, + machineKey wgkey.Key, + mapRequest tailcfg.MapRequest, + machine *Machine, ) { keepAliveTicker := time.NewTicker(KEEP_ALIVE_INTERVAL) updateCheckerTicker := time.NewTicker(UPDATE_CHECK_INTERVAL) @@ -497,7 +504,7 @@ func (h *Headscale) scheduledPollWorker( return case <-keepAliveTicker.C: - data, err := h.getMapKeepAliveResponse(mKey, req) + data, err := h.getMapKeepAliveResponse(machineKey, mapRequest) if err != nil { log.Error(). Str("func", "keepAlive"). @@ -509,16 +516,16 @@ func (h *Headscale) scheduledPollWorker( log.Debug(). Str("func", "keepAlive"). - Str("machine", m.Name). + Str("machine", machine.Name). Msg("Sending keepalive") keepAliveChan <- data case <-updateCheckerTicker.C: log.Debug(). Str("func", "scheduledPollWorker"). - Str("machine", m.Name). + Str("machine", machine.Name). Msg("Sending update request") - updateRequestsFromNode.WithLabelValues(m.Name, m.Namespace.Name, "scheduled-update"). + updateRequestsFromNode.WithLabelValues(machine.Name, machine.Namespace.Name, "scheduled-update"). Inc() updateChan <- struct{}{} } diff --git a/preauth_keys.go b/preauth_keys.go index 1a00077a..742e06cf 100644 --- a/preauth_keys.go +++ b/preauth_keys.go @@ -39,7 +39,7 @@ func (h *Headscale) CreatePreAuthKey( ephemeral bool, expiration *time.Time, ) (*PreAuthKey, error) { - n, err := h.GetNamespace(namespaceName) + namespace, err := h.GetNamespace(namespaceName) if err != nil { return nil, err } @@ -50,29 +50,29 @@ func (h *Headscale) CreatePreAuthKey( return nil, err } - k := PreAuthKey{ + key := PreAuthKey{ Key: kstr, - NamespaceID: n.ID, - Namespace: *n, + NamespaceID: namespace.ID, + Namespace: *namespace, Reusable: reusable, Ephemeral: ephemeral, CreatedAt: &now, Expiration: expiration, } - h.db.Save(&k) + h.db.Save(&key) - return &k, nil + return &key, nil } // ListPreAuthKeys returns the list of PreAuthKeys for a namespace. func (h *Headscale) ListPreAuthKeys(namespaceName string) ([]PreAuthKey, error) { - n, err := h.GetNamespace(namespaceName) + namespace, err := h.GetNamespace(namespaceName) if err != nil { return nil, err } keys := []PreAuthKey{} - if err := h.db.Preload("Namespace").Where(&PreAuthKey{NamespaceID: n.ID}).Find(&keys).Error; err != nil { + if err := h.db.Preload("Namespace").Where(&PreAuthKey{NamespaceID: namespace.ID}).Find(&keys).Error; err != nil { return nil, err } diff --git a/routes.go b/routes.go index d6acc3a5..9845b76d 100644 --- a/routes.go +++ b/routes.go @@ -15,12 +15,12 @@ func (h *Headscale) GetAdvertisedNodeRoutes( namespace string, nodeName string, ) (*[]netaddr.IPPrefix, error) { - m, err := h.GetMachine(namespace, nodeName) + machine, err := h.GetMachine(namespace, nodeName) if err != nil { return nil, err } - hostInfo, err := m.GetHostInfo() + hostInfo, err := machine.GetHostInfo() if err != nil { return nil, err } @@ -35,12 +35,12 @@ func (h *Headscale) GetEnabledNodeRoutes( namespace string, nodeName string, ) ([]netaddr.IPPrefix, error) { - m, err := h.GetMachine(namespace, nodeName) + machine, err := h.GetMachine(namespace, nodeName) if err != nil { return nil, err } - data, err := m.EnabledRoutes.MarshalJSON() + data, err := machine.EnabledRoutes.MarshalJSON() if err != nil { return nil, err } @@ -97,7 +97,7 @@ func (h *Headscale) EnableNodeRoute( nodeName string, routeStr string, ) error { - m, err := h.GetMachine(namespace, nodeName) + machine, err := h.GetMachine(namespace, nodeName) if err != nil { return err } @@ -137,10 +137,10 @@ func (h *Headscale) EnableNodeRoute( return err } - m.EnabledRoutes = datatypes.JSON(routes) - h.db.Save(&m) + machine.EnabledRoutes = datatypes.JSON(routes) + h.db.Save(&machine) - err = h.RequestMapUpdates(m.NamespaceID) + err = h.RequestMapUpdates(machine.NamespaceID) if err != nil { return err } From 8ae682b412f2ba9cd3877b60e68c5afe0afdaa41 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Mon, 15 Nov 2021 16:16:04 +0000 Subject: [PATCH 153/300] Fix var name length in tests --- acls_test.go | 70 +++++++-------- app_test.go | 10 +-- cli_test.go | 18 ++-- dns_test.go | 198 +++++++++++++++++++++++++++---------------- integration_test.go | 2 +- machine_test.go | 113 ++++++++++++------------ namespaces_test.go | 155 ++++++++++++++++++--------------- oidc_test.go | 42 ++++----- preauth_keys_test.go | 110 ++++++++++++------------ routes_test.go | 72 ++++++++-------- sharing_test.go | 196 +++++++++++++++++++++--------------------- utils_test.go | 78 +++++++++-------- 12 files changed, 580 insertions(+), 484 deletions(-) diff --git a/acls_test.go b/acls_test.go index c178805e..cca39ce8 100644 --- a/acls_test.go +++ b/acls_test.go @@ -5,58 +5,58 @@ import ( ) func (s *Suite) TestWrongPath(c *check.C) { - err := h.LoadACLPolicy("asdfg") + err := app.LoadACLPolicy("asdfg") c.Assert(err, check.NotNil) } func (s *Suite) TestBrokenHuJson(c *check.C) { - err := h.LoadACLPolicy("./tests/acls/broken.hujson") + err := app.LoadACLPolicy("./tests/acls/broken.hujson") c.Assert(err, check.NotNil) } func (s *Suite) TestInvalidPolicyHuson(c *check.C) { - err := h.LoadACLPolicy("./tests/acls/invalid.hujson") + err := app.LoadACLPolicy("./tests/acls/invalid.hujson") c.Assert(err, check.NotNil) c.Assert(err, check.Equals, errorEmptyPolicy) } func (s *Suite) TestParseHosts(c *check.C) { - var hs Hosts - err := hs.UnmarshalJSON( + var hosts Hosts + err := hosts.UnmarshalJSON( []byte( `{"example-host-1": "100.100.100.100","example-host-2": "100.100.101.100/24"}`, ), ) - c.Assert(hs, check.NotNil) + c.Assert(hosts, check.NotNil) c.Assert(err, check.IsNil) } func (s *Suite) TestParseInvalidCIDR(c *check.C) { - var hs Hosts - err := hs.UnmarshalJSON([]byte(`{"example-host-1": "100.100.100.100/42"}`)) - c.Assert(hs, check.IsNil) + var hosts Hosts + err := hosts.UnmarshalJSON([]byte(`{"example-host-1": "100.100.100.100/42"}`)) + c.Assert(hosts, check.IsNil) c.Assert(err, check.NotNil) } func (s *Suite) TestRuleInvalidGeneration(c *check.C) { - err := h.LoadACLPolicy("./tests/acls/acl_policy_invalid.hujson") + err := app.LoadACLPolicy("./tests/acls/acl_policy_invalid.hujson") c.Assert(err, check.NotNil) } func (s *Suite) TestBasicRule(c *check.C) { - err := h.LoadACLPolicy("./tests/acls/acl_policy_basic_1.hujson") + err := app.LoadACLPolicy("./tests/acls/acl_policy_basic_1.hujson") c.Assert(err, check.IsNil) - rules, err := h.generateACLRules() + rules, err := app.generateACLRules() c.Assert(err, check.IsNil) c.Assert(rules, check.NotNil) } func (s *Suite) TestPortRange(c *check.C) { - err := h.LoadACLPolicy("./tests/acls/acl_policy_basic_range.hujson") + err := app.LoadACLPolicy("./tests/acls/acl_policy_basic_range.hujson") c.Assert(err, check.IsNil) - rules, err := h.generateACLRules() + rules, err := app.generateACLRules() c.Assert(err, check.IsNil) c.Assert(rules, check.NotNil) @@ -67,10 +67,10 @@ func (s *Suite) TestPortRange(c *check.C) { } func (s *Suite) TestPortWildcard(c *check.C) { - err := h.LoadACLPolicy("./tests/acls/acl_policy_basic_wildcards.hujson") + err := app.LoadACLPolicy("./tests/acls/acl_policy_basic_wildcards.hujson") c.Assert(err, check.IsNil) - rules, err := h.generateACLRules() + rules, err := app.generateACLRules() c.Assert(err, check.IsNil) c.Assert(rules, check.NotNil) @@ -83,33 +83,35 @@ func (s *Suite) TestPortWildcard(c *check.C) { } func (s *Suite) TestPortNamespace(c *check.C) { - n, err := h.CreateNamespace("testnamespace") + namespace, err := app.CreateNamespace("testnamespace") c.Assert(err, check.IsNil) - pak, err := h.CreatePreAuthKey(n.Name, false, false, nil) + pak, err := app.CreatePreAuthKey(namespace.Name, false, false, nil) c.Assert(err, check.IsNil) - _, err = h.GetMachine("testnamespace", "testmachine") + _, err = app.GetMachine("testnamespace", "testmachine") c.Assert(err, check.NotNil) - ip, _ := h.getAvailableIP() - m := Machine{ + ip, _ := app.getAvailableIP() + machine := Machine{ ID: 0, MachineKey: "foo", NodeKey: "bar", DiscoKey: "faa", Name: "testmachine", - NamespaceID: n.ID, + NamespaceID: namespace.ID, Registered: true, RegisterMethod: "authKey", IPAddress: ip.String(), AuthKeyID: uint(pak.ID), } - h.db.Save(&m) + app.db.Save(&machine) - err = h.LoadACLPolicy("./tests/acls/acl_policy_basic_namespace_as_user.hujson") + err = app.LoadACLPolicy( + "./tests/acls/acl_policy_basic_namespace_as_user.hujson", + ) c.Assert(err, check.IsNil) - rules, err := h.generateACLRules() + rules, err := app.generateACLRules() c.Assert(err, check.IsNil) c.Assert(rules, check.NotNil) @@ -123,33 +125,33 @@ func (s *Suite) TestPortNamespace(c *check.C) { } func (s *Suite) TestPortGroup(c *check.C) { - n, err := h.CreateNamespace("testnamespace") + namespace, err := app.CreateNamespace("testnamespace") c.Assert(err, check.IsNil) - pak, err := h.CreatePreAuthKey(n.Name, false, false, nil) + pak, err := app.CreatePreAuthKey(namespace.Name, false, false, nil) c.Assert(err, check.IsNil) - _, err = h.GetMachine("testnamespace", "testmachine") + _, err = app.GetMachine("testnamespace", "testmachine") c.Assert(err, check.NotNil) - ip, _ := h.getAvailableIP() - m := Machine{ + ip, _ := app.getAvailableIP() + machine := Machine{ ID: 0, MachineKey: "foo", NodeKey: "bar", DiscoKey: "faa", Name: "testmachine", - NamespaceID: n.ID, + NamespaceID: namespace.ID, Registered: true, RegisterMethod: "authKey", IPAddress: ip.String(), AuthKeyID: uint(pak.ID), } - h.db.Save(&m) + app.db.Save(&machine) - err = h.LoadACLPolicy("./tests/acls/acl_policy_basic_groups.hujson") + err = app.LoadACLPolicy("./tests/acls/acl_policy_basic_groups.hujson") c.Assert(err, check.IsNil) - rules, err := h.generateACLRules() + rules, err := app.generateACLRules() c.Assert(err, check.IsNil) c.Assert(rules, check.NotNil) diff --git a/app_test.go b/app_test.go index ec232827..947062bf 100644 --- a/app_test.go +++ b/app_test.go @@ -19,7 +19,7 @@ type Suite struct{} var ( tmpDir string - h Headscale + app Headscale ) func (s *Suite) SetUpTest(c *check.C) { @@ -43,18 +43,18 @@ func (s *Suite) ResetDB(c *check.C) { IPPrefix: netaddr.MustParseIPPrefix("10.27.0.0/23"), } - h = Headscale{ + app = Headscale{ cfg: cfg, dbType: "sqlite3", dbString: tmpDir + "/headscale_test.db", } - err = h.initDB() + err = app.initDB() if err != nil { c.Fatal(err) } - db, err := h.openDB() + db, err := app.openDB() if err != nil { c.Fatal(err) } - h.db = db + app.db = db } diff --git a/cli_test.go b/cli_test.go index 6c0b2bbb..44ef9f08 100644 --- a/cli_test.go +++ b/cli_test.go @@ -7,34 +7,34 @@ import ( ) func (s *Suite) TestRegisterMachine(c *check.C) { - n, err := h.CreateNamespace("test") + namespace, err := app.CreateNamespace("test") c.Assert(err, check.IsNil) now := time.Now().UTC() - m := Machine{ + machine := Machine{ ID: 0, MachineKey: "8ce002a935f8c394e55e78fbbb410576575ff8ec5cfa2e627e4b807f1be15b0e", NodeKey: "bar", DiscoKey: "faa", Name: "testmachine", - NamespaceID: n.ID, + NamespaceID: namespace.ID, IPAddress: "10.0.0.1", Expiry: &now, RequestedExpiry: &now, } - h.db.Save(&m) + app.db.Save(&machine) - _, err = h.GetMachine("test", "testmachine") + _, err = app.GetMachine("test", "testmachine") c.Assert(err, check.IsNil) - m2, err := h.RegisterMachine( + machineAfterRegistering, err := app.RegisterMachine( "8ce002a935f8c394e55e78fbbb410576575ff8ec5cfa2e627e4b807f1be15b0e", - n.Name, + namespace.Name, ) c.Assert(err, check.IsNil) - c.Assert(m2.Registered, check.Equals, true) + c.Assert(machineAfterRegistering.Registered, check.Equals, true) - _, err = m2.GetHostInfo() + _, err = machineAfterRegistering.GetHostInfo() c.Assert(err, check.IsNil) } diff --git a/dns_test.go b/dns_test.go index dfde8631..a2f7a652 100644 --- a/dns_test.go +++ b/dns_test.go @@ -70,100 +70,120 @@ func (s *Suite) TestMagicDNSRootDomains172(c *check.C) { } func (s *Suite) TestDNSConfigMapResponseWithMagicDNS(c *check.C) { - n1, err := h.CreateNamespace("shared1") + namespaceShared1, err := app.CreateNamespace("shared1") c.Assert(err, check.IsNil) - n2, err := h.CreateNamespace("shared2") + namespaceShared2, err := app.CreateNamespace("shared2") c.Assert(err, check.IsNil) - n3, err := h.CreateNamespace("shared3") + namespaceShared3, err := app.CreateNamespace("shared3") c.Assert(err, check.IsNil) - pak1n1, err := h.CreatePreAuthKey(n1.Name, false, false, nil) + preAuthKeyInShared1, err := app.CreatePreAuthKey( + namespaceShared1.Name, + false, + false, + nil, + ) c.Assert(err, check.IsNil) - pak2n2, err := h.CreatePreAuthKey(n2.Name, false, false, nil) + preAuthKeyInShared2, err := app.CreatePreAuthKey( + namespaceShared2.Name, + false, + false, + nil, + ) c.Assert(err, check.IsNil) - pak3n3, err := h.CreatePreAuthKey(n3.Name, false, false, nil) + preAuthKeyInShared3, err := app.CreatePreAuthKey( + namespaceShared3.Name, + false, + false, + nil, + ) c.Assert(err, check.IsNil) - pak4n1, err := h.CreatePreAuthKey(n1.Name, false, false, nil) + PreAuthKey2InShared1, err := app.CreatePreAuthKey( + namespaceShared1.Name, + false, + false, + nil, + ) c.Assert(err, check.IsNil) - _, err = h.GetMachine(n1.Name, "test_get_shared_nodes_1") + _, err = app.GetMachine(namespaceShared1.Name, "test_get_shared_nodes_1") c.Assert(err, check.NotNil) - m1 := &Machine{ + machineInShared1 := &Machine{ ID: 1, MachineKey: "686824e749f3b7f2a5927ee6c1e422aee5292592d9179a271ed7b3e659b44a66", NodeKey: "686824e749f3b7f2a5927ee6c1e422aee5292592d9179a271ed7b3e659b44a66", DiscoKey: "686824e749f3b7f2a5927ee6c1e422aee5292592d9179a271ed7b3e659b44a66", Name: "test_get_shared_nodes_1", - NamespaceID: n1.ID, - Namespace: *n1, + NamespaceID: namespaceShared1.ID, + Namespace: *namespaceShared1, Registered: true, RegisterMethod: "authKey", IPAddress: "100.64.0.1", - AuthKeyID: uint(pak1n1.ID), + AuthKeyID: uint(preAuthKeyInShared1.ID), } - h.db.Save(m1) + app.db.Save(machineInShared1) - _, err = h.GetMachine(n1.Name, m1.Name) + _, err = app.GetMachine(namespaceShared1.Name, machineInShared1.Name) c.Assert(err, check.IsNil) - m2 := &Machine{ + machineInShared2 := &Machine{ ID: 2, MachineKey: "dec46ef9dc45c7d2f03bfcd5a640d9e24e3cc68ce3d9da223867c9bc6d5e9863", NodeKey: "dec46ef9dc45c7d2f03bfcd5a640d9e24e3cc68ce3d9da223867c9bc6d5e9863", DiscoKey: "dec46ef9dc45c7d2f03bfcd5a640d9e24e3cc68ce3d9da223867c9bc6d5e9863", Name: "test_get_shared_nodes_2", - NamespaceID: n2.ID, - Namespace: *n2, + NamespaceID: namespaceShared2.ID, + Namespace: *namespaceShared2, Registered: true, RegisterMethod: "authKey", IPAddress: "100.64.0.2", - AuthKeyID: uint(pak2n2.ID), + AuthKeyID: uint(preAuthKeyInShared2.ID), } - h.db.Save(m2) + app.db.Save(machineInShared2) - _, err = h.GetMachine(n2.Name, m2.Name) + _, err = app.GetMachine(namespaceShared2.Name, machineInShared2.Name) c.Assert(err, check.IsNil) - m3 := &Machine{ + machineInShared3 := &Machine{ ID: 3, MachineKey: "dec46ef9dc45c7d2f03bfcd5a640d9e24e3cc68ce3d9da223867c9bc6d5e9863", NodeKey: "dec46ef9dc45c7d2f03bfcd5a640d9e24e3cc68ce3d9da223867c9bc6d5e9863", DiscoKey: "dec46ef9dc45c7d2f03bfcd5a640d9e24e3cc68ce3d9da223867c9bc6d5e9863", Name: "test_get_shared_nodes_3", - NamespaceID: n3.ID, - Namespace: *n3, + NamespaceID: namespaceShared3.ID, + Namespace: *namespaceShared3, Registered: true, RegisterMethod: "authKey", IPAddress: "100.64.0.3", - AuthKeyID: uint(pak3n3.ID), + AuthKeyID: uint(preAuthKeyInShared3.ID), } - h.db.Save(m3) + app.db.Save(machineInShared3) - _, err = h.GetMachine(n3.Name, m3.Name) + _, err = app.GetMachine(namespaceShared3.Name, machineInShared3.Name) c.Assert(err, check.IsNil) - m4 := &Machine{ + machine2InShared1 := &Machine{ ID: 4, MachineKey: "dec46ef9dc45c7d2f03bfcd5a640d9e24e3cc68ce3d9da223867c9bc6d5e9863", NodeKey: "dec46ef9dc45c7d2f03bfcd5a640d9e24e3cc68ce3d9da223867c9bc6d5e9863", DiscoKey: "dec46ef9dc45c7d2f03bfcd5a640d9e24e3cc68ce3d9da223867c9bc6d5e9863", Name: "test_get_shared_nodes_4", - NamespaceID: n1.ID, - Namespace: *n1, + NamespaceID: namespaceShared1.ID, + Namespace: *namespaceShared1, Registered: true, RegisterMethod: "authKey", IPAddress: "100.64.0.4", - AuthKeyID: uint(pak4n1.ID), + AuthKeyID: uint(PreAuthKey2InShared1.ID), } - h.db.Save(m4) + app.db.Save(machine2InShared1) - err = h.AddSharedMachineToNamespace(m2, n1) + err = app.AddSharedMachineToNamespace(machineInShared2, namespaceShared1) c.Assert(err, check.IsNil) baseDomain := "foobar.headscale.net" @@ -173,121 +193,146 @@ func (s *Suite) TestDNSConfigMapResponseWithMagicDNS(c *check.C) { Proxied: true, } - m1peers, err := h.getPeers(m1) + peersOfMachineInShared1, err := app.getPeers(machineInShared1) c.Assert(err, check.IsNil) - dnsConfig := getMapResponseDNSConfig(&dnsConfigOrig, baseDomain, *m1, m1peers) + dnsConfig := getMapResponseDNSConfig( + &dnsConfigOrig, + baseDomain, + *machineInShared1, + peersOfMachineInShared1, + ) c.Assert(dnsConfig, check.NotNil) c.Assert(len(dnsConfig.Routes), check.Equals, 2) - routeN1 := fmt.Sprintf("%s.%s", n1.Name, baseDomain) - _, ok := dnsConfig.Routes[routeN1] + domainRouteShared1 := fmt.Sprintf("%s.%s", namespaceShared1.Name, baseDomain) + _, ok := dnsConfig.Routes[domainRouteShared1] c.Assert(ok, check.Equals, true) - routeN2 := fmt.Sprintf("%s.%s", n2.Name, baseDomain) - _, ok = dnsConfig.Routes[routeN2] + domainRouteShared2 := fmt.Sprintf("%s.%s", namespaceShared2.Name, baseDomain) + _, ok = dnsConfig.Routes[domainRouteShared2] c.Assert(ok, check.Equals, true) - routeN3 := fmt.Sprintf("%s.%s", n3.Name, baseDomain) - _, ok = dnsConfig.Routes[routeN3] + domainRouteShared3 := fmt.Sprintf("%s.%s", namespaceShared3.Name, baseDomain) + _, ok = dnsConfig.Routes[domainRouteShared3] c.Assert(ok, check.Equals, false) } func (s *Suite) TestDNSConfigMapResponseWithoutMagicDNS(c *check.C) { - n1, err := h.CreateNamespace("shared1") + namespaceShared1, err := app.CreateNamespace("shared1") c.Assert(err, check.IsNil) - n2, err := h.CreateNamespace("shared2") + namespaceShared2, err := app.CreateNamespace("shared2") c.Assert(err, check.IsNil) - n3, err := h.CreateNamespace("shared3") + namespaceShared3, err := app.CreateNamespace("shared3") c.Assert(err, check.IsNil) - pak1n1, err := h.CreatePreAuthKey(n1.Name, false, false, nil) + preAuthKeyInShared1, err := app.CreatePreAuthKey( + namespaceShared1.Name, + false, + false, + nil, + ) c.Assert(err, check.IsNil) - pak2n2, err := h.CreatePreAuthKey(n2.Name, false, false, nil) + preAuthKeyInShared2, err := app.CreatePreAuthKey( + namespaceShared2.Name, + false, + false, + nil, + ) c.Assert(err, check.IsNil) - pak3n3, err := h.CreatePreAuthKey(n3.Name, false, false, nil) + preAuthKeyInShared3, err := app.CreatePreAuthKey( + namespaceShared3.Name, + false, + false, + nil, + ) c.Assert(err, check.IsNil) - pak4n1, err := h.CreatePreAuthKey(n1.Name, false, false, nil) + preAuthKey2InShared1, err := app.CreatePreAuthKey( + namespaceShared1.Name, + false, + false, + nil, + ) c.Assert(err, check.IsNil) - _, err = h.GetMachine(n1.Name, "test_get_shared_nodes_1") + _, err = app.GetMachine(namespaceShared1.Name, "test_get_shared_nodes_1") c.Assert(err, check.NotNil) - m1 := &Machine{ + machineInShared1 := &Machine{ ID: 1, MachineKey: "686824e749f3b7f2a5927ee6c1e422aee5292592d9179a271ed7b3e659b44a66", NodeKey: "686824e749f3b7f2a5927ee6c1e422aee5292592d9179a271ed7b3e659b44a66", DiscoKey: "686824e749f3b7f2a5927ee6c1e422aee5292592d9179a271ed7b3e659b44a66", Name: "test_get_shared_nodes_1", - NamespaceID: n1.ID, - Namespace: *n1, + NamespaceID: namespaceShared1.ID, + Namespace: *namespaceShared1, Registered: true, RegisterMethod: "authKey", IPAddress: "100.64.0.1", - AuthKeyID: uint(pak1n1.ID), + AuthKeyID: uint(preAuthKeyInShared1.ID), } - h.db.Save(m1) + app.db.Save(machineInShared1) - _, err = h.GetMachine(n1.Name, m1.Name) + _, err = app.GetMachine(namespaceShared1.Name, machineInShared1.Name) c.Assert(err, check.IsNil) - m2 := &Machine{ + machineInShared2 := &Machine{ ID: 2, MachineKey: "dec46ef9dc45c7d2f03bfcd5a640d9e24e3cc68ce3d9da223867c9bc6d5e9863", NodeKey: "dec46ef9dc45c7d2f03bfcd5a640d9e24e3cc68ce3d9da223867c9bc6d5e9863", DiscoKey: "dec46ef9dc45c7d2f03bfcd5a640d9e24e3cc68ce3d9da223867c9bc6d5e9863", Name: "test_get_shared_nodes_2", - NamespaceID: n2.ID, - Namespace: *n2, + NamespaceID: namespaceShared2.ID, + Namespace: *namespaceShared2, Registered: true, RegisterMethod: "authKey", IPAddress: "100.64.0.2", - AuthKeyID: uint(pak2n2.ID), + AuthKeyID: uint(preAuthKeyInShared2.ID), } - h.db.Save(m2) + app.db.Save(machineInShared2) - _, err = h.GetMachine(n2.Name, m2.Name) + _, err = app.GetMachine(namespaceShared2.Name, machineInShared2.Name) c.Assert(err, check.IsNil) - m3 := &Machine{ + machineInShared3 := &Machine{ ID: 3, MachineKey: "dec46ef9dc45c7d2f03bfcd5a640d9e24e3cc68ce3d9da223867c9bc6d5e9863", NodeKey: "dec46ef9dc45c7d2f03bfcd5a640d9e24e3cc68ce3d9da223867c9bc6d5e9863", DiscoKey: "dec46ef9dc45c7d2f03bfcd5a640d9e24e3cc68ce3d9da223867c9bc6d5e9863", Name: "test_get_shared_nodes_3", - NamespaceID: n3.ID, - Namespace: *n3, + NamespaceID: namespaceShared3.ID, + Namespace: *namespaceShared3, Registered: true, RegisterMethod: "authKey", IPAddress: "100.64.0.3", - AuthKeyID: uint(pak3n3.ID), + AuthKeyID: uint(preAuthKeyInShared3.ID), } - h.db.Save(m3) + app.db.Save(machineInShared3) - _, err = h.GetMachine(n3.Name, m3.Name) + _, err = app.GetMachine(namespaceShared3.Name, machineInShared3.Name) c.Assert(err, check.IsNil) - m4 := &Machine{ + machine2InShared1 := &Machine{ ID: 4, MachineKey: "dec46ef9dc45c7d2f03bfcd5a640d9e24e3cc68ce3d9da223867c9bc6d5e9863", NodeKey: "dec46ef9dc45c7d2f03bfcd5a640d9e24e3cc68ce3d9da223867c9bc6d5e9863", DiscoKey: "dec46ef9dc45c7d2f03bfcd5a640d9e24e3cc68ce3d9da223867c9bc6d5e9863", Name: "test_get_shared_nodes_4", - NamespaceID: n1.ID, - Namespace: *n1, + NamespaceID: namespaceShared1.ID, + Namespace: *namespaceShared1, Registered: true, RegisterMethod: "authKey", IPAddress: "100.64.0.4", - AuthKeyID: uint(pak4n1.ID), + AuthKeyID: uint(preAuthKey2InShared1.ID), } - h.db.Save(m4) + app.db.Save(machine2InShared1) - err = h.AddSharedMachineToNamespace(m2, n1) + err = app.AddSharedMachineToNamespace(machineInShared2, namespaceShared1) c.Assert(err, check.IsNil) baseDomain := "foobar.headscale.net" @@ -297,10 +342,15 @@ func (s *Suite) TestDNSConfigMapResponseWithoutMagicDNS(c *check.C) { Proxied: false, } - m1peers, err := h.getPeers(m1) + peersOfMachine1Shared1, err := app.getPeers(machineInShared1) c.Assert(err, check.IsNil) - dnsConfig := getMapResponseDNSConfig(&dnsConfigOrig, baseDomain, *m1, m1peers) + dnsConfig := getMapResponseDNSConfig( + &dnsConfigOrig, + baseDomain, + *machineInShared1, + peersOfMachine1Shared1, + ) c.Assert(dnsConfig, check.NotNil) c.Assert(len(dnsConfig.Routes), check.Equals, 0) c.Assert(len(dnsConfig.Domains), check.Equals, 1) diff --git a/integration_test.go b/integration_test.go index ddbf19d5..a9125a0a 100644 --- a/integration_test.go +++ b/integration_test.go @@ -185,7 +185,7 @@ func (s *IntegrationTestSuite) tailscaleContainer( func (s *IntegrationTestSuite) SetupSuite() { var err error - h = Headscale{ + app = Headscale{ dbType: "sqlite3", dbString: "integration_test_db.sqlite3", } diff --git a/machine_test.go b/machine_test.go index dfe84d33..cf367403 100644 --- a/machine_test.go +++ b/machine_test.go @@ -8,152 +8,159 @@ import ( ) func (s *Suite) TestGetMachine(c *check.C) { - n, err := h.CreateNamespace("test") + namespace, err := app.CreateNamespace("test") c.Assert(err, check.IsNil) - pak, err := h.CreatePreAuthKey(n.Name, false, false, nil) + pak, err := app.CreatePreAuthKey(namespace.Name, false, false, nil) c.Assert(err, check.IsNil) - _, err = h.GetMachine("test", "testmachine") + _, err = app.GetMachine("test", "testmachine") c.Assert(err, check.NotNil) - m := &Machine{ + machine := &Machine{ ID: 0, MachineKey: "foo", NodeKey: "bar", DiscoKey: "faa", Name: "testmachine", - NamespaceID: n.ID, + NamespaceID: namespace.ID, Registered: true, RegisterMethod: "authKey", AuthKeyID: uint(pak.ID), } - h.db.Save(m) + app.db.Save(machine) - m1, err := h.GetMachine("test", "testmachine") + machineFromDB, err := app.GetMachine("test", "testmachine") c.Assert(err, check.IsNil) - _, err = m1.GetHostInfo() + _, err = machineFromDB.GetHostInfo() c.Assert(err, check.IsNil) } func (s *Suite) TestGetMachineByID(c *check.C) { - n, err := h.CreateNamespace("test") + namespace, err := app.CreateNamespace("test") c.Assert(err, check.IsNil) - pak, err := h.CreatePreAuthKey(n.Name, false, false, nil) + pak, err := app.CreatePreAuthKey(namespace.Name, false, false, nil) c.Assert(err, check.IsNil) - _, err = h.GetMachineByID(0) + _, err = app.GetMachineByID(0) c.Assert(err, check.NotNil) - m := Machine{ + machine := Machine{ ID: 0, MachineKey: "foo", NodeKey: "bar", DiscoKey: "faa", Name: "testmachine", - NamespaceID: n.ID, + NamespaceID: namespace.ID, Registered: true, RegisterMethod: "authKey", AuthKeyID: uint(pak.ID), } - h.db.Save(&m) + app.db.Save(&machine) - m1, err := h.GetMachineByID(0) + machineByID, err := app.GetMachineByID(0) c.Assert(err, check.IsNil) - _, err = m1.GetHostInfo() + _, err = machineByID.GetHostInfo() c.Assert(err, check.IsNil) } func (s *Suite) TestDeleteMachine(c *check.C) { - n, err := h.CreateNamespace("test") + namespace, err := app.CreateNamespace("test") c.Assert(err, check.IsNil) - m := Machine{ + machine := Machine{ ID: 0, MachineKey: "foo", NodeKey: "bar", DiscoKey: "faa", Name: "testmachine", - NamespaceID: n.ID, + NamespaceID: namespace.ID, Registered: true, RegisterMethod: "authKey", AuthKeyID: uint(1), } - h.db.Save(&m) - err = h.DeleteMachine(&m) + app.db.Save(&machine) + + err = app.DeleteMachine(&machine) c.Assert(err, check.IsNil) - v, err := h.getValue("namespaces_pending_updates") + + namespacesPendingUpdates, err := app.getValue("namespaces_pending_updates") c.Assert(err, check.IsNil) + names := []string{} - err = json.Unmarshal([]byte(v), &names) + err = json.Unmarshal([]byte(namespacesPendingUpdates), &names) c.Assert(err, check.IsNil) - c.Assert(names, check.DeepEquals, []string{n.Name}) - h.checkForNamespacesPendingUpdates() - v, _ = h.getValue("namespaces_pending_updates") - c.Assert(v, check.Equals, "") - _, err = h.GetMachine(n.Name, "testmachine") + c.Assert(names, check.DeepEquals, []string{namespace.Name}) + + app.checkForNamespacesPendingUpdates() + + namespacesPendingUpdates, _ = app.getValue("namespaces_pending_updates") + c.Assert(namespacesPendingUpdates, check.Equals, "") + _, err = app.GetMachine(namespace.Name, "testmachine") c.Assert(err, check.NotNil) } func (s *Suite) TestHardDeleteMachine(c *check.C) { - n, err := h.CreateNamespace("test") + namespace, err := app.CreateNamespace("test") c.Assert(err, check.IsNil) - m := Machine{ + machine := Machine{ ID: 0, MachineKey: "foo", NodeKey: "bar", DiscoKey: "faa", Name: "testmachine3", - NamespaceID: n.ID, + NamespaceID: namespace.ID, Registered: true, RegisterMethod: "authKey", AuthKeyID: uint(1), } - h.db.Save(&m) - err = h.HardDeleteMachine(&m) + app.db.Save(&machine) + + err = app.HardDeleteMachine(&machine) c.Assert(err, check.IsNil) - _, err = h.GetMachine(n.Name, "testmachine3") + + _, err = app.GetMachine(namespace.Name, "testmachine3") c.Assert(err, check.NotNil) } func (s *Suite) TestGetDirectPeers(c *check.C) { - n, err := h.CreateNamespace("test") + namespace, err := app.CreateNamespace("test") c.Assert(err, check.IsNil) - pak, err := h.CreatePreAuthKey(n.Name, false, false, nil) + pak, err := app.CreatePreAuthKey(namespace.Name, false, false, nil) c.Assert(err, check.IsNil) - _, err = h.GetMachineByID(0) + _, err = app.GetMachineByID(0) c.Assert(err, check.NotNil) - for i := 0; i <= 10; i++ { - m := Machine{ - ID: uint64(i), - MachineKey: "foo" + strconv.Itoa(i), - NodeKey: "bar" + strconv.Itoa(i), - DiscoKey: "faa" + strconv.Itoa(i), - Name: "testmachine" + strconv.Itoa(i), - NamespaceID: n.ID, + for index := 0; index <= 10; index++ { + machine := Machine{ + ID: uint64(index), + MachineKey: "foo" + strconv.Itoa(index), + NodeKey: "bar" + strconv.Itoa(index), + DiscoKey: "faa" + strconv.Itoa(index), + Name: "testmachine" + strconv.Itoa(index), + NamespaceID: namespace.ID, Registered: true, RegisterMethod: "authKey", AuthKeyID: uint(pak.ID), } - h.db.Save(&m) + app.db.Save(&machine) } - m1, err := h.GetMachineByID(0) + machine0ByID, err := app.GetMachineByID(0) c.Assert(err, check.IsNil) - _, err = m1.GetHostInfo() + _, err = machine0ByID.GetHostInfo() c.Assert(err, check.IsNil) - peers, err := h.getDirectPeers(m1) + peersOfMachine0, err := app.getDirectPeers(machine0ByID) c.Assert(err, check.IsNil) - c.Assert(len(peers), check.Equals, 9) - c.Assert(peers[0].Name, check.Equals, "testmachine2") - c.Assert(peers[5].Name, check.Equals, "testmachine7") - c.Assert(peers[8].Name, check.Equals, "testmachine10") + c.Assert(len(peersOfMachine0), check.Equals, 9) + c.Assert(peersOfMachine0[0].Name, check.Equals, "testmachine2") + c.Assert(peersOfMachine0[5].Name, check.Equals, "testmachine7") + c.Assert(peersOfMachine0[8].Name, check.Equals, "testmachine10") } diff --git a/namespaces_test.go b/namespaces_test.go index 502bc368..7ac1f063 100644 --- a/namespaces_test.go +++ b/namespaces_test.go @@ -7,197 +7,220 @@ import ( ) func (s *Suite) TestCreateAndDestroyNamespace(c *check.C) { - n, err := h.CreateNamespace("test") + namespace, err := app.CreateNamespace("test") c.Assert(err, check.IsNil) - c.Assert(n.Name, check.Equals, "test") + c.Assert(namespace.Name, check.Equals, "test") - ns, err := h.ListNamespaces() + namespaces, err := app.ListNamespaces() c.Assert(err, check.IsNil) - c.Assert(len(ns), check.Equals, 1) + c.Assert(len(namespaces), check.Equals, 1) - err = h.DestroyNamespace("test") + err = app.DestroyNamespace("test") c.Assert(err, check.IsNil) - _, err = h.GetNamespace("test") + _, err = app.GetNamespace("test") c.Assert(err, check.NotNil) } func (s *Suite) TestDestroyNamespaceErrors(c *check.C) { - err := h.DestroyNamespace("test") + err := app.DestroyNamespace("test") c.Assert(err, check.Equals, errorNamespaceNotFound) - n, err := h.CreateNamespace("test") + namespace, err := app.CreateNamespace("test") c.Assert(err, check.IsNil) - pak, err := h.CreatePreAuthKey(n.Name, false, false, nil) + pak, err := app.CreatePreAuthKey(namespace.Name, false, false, nil) c.Assert(err, check.IsNil) - err = h.DestroyNamespace("test") + err = app.DestroyNamespace("test") c.Assert(err, check.IsNil) - result := h.db.Preload("Namespace").First(&pak, "key = ?", pak.Key) + result := app.db.Preload("Namespace").First(&pak, "key = ?", pak.Key) // destroying a namespace also deletes all associated preauthkeys c.Assert(result.Error, check.Equals, gorm.ErrRecordNotFound) - n, err = h.CreateNamespace("test") + namespace, err = app.CreateNamespace("test") c.Assert(err, check.IsNil) - pak, err = h.CreatePreAuthKey(n.Name, false, false, nil) + pak, err = app.CreatePreAuthKey(namespace.Name, false, false, nil) c.Assert(err, check.IsNil) - m := Machine{ + machine := Machine{ ID: 0, MachineKey: "foo", NodeKey: "bar", DiscoKey: "faa", Name: "testmachine", - NamespaceID: n.ID, + NamespaceID: namespace.ID, Registered: true, RegisterMethod: "authKey", AuthKeyID: uint(pak.ID), } - h.db.Save(&m) + app.db.Save(&machine) - err = h.DestroyNamespace("test") + err = app.DestroyNamespace("test") c.Assert(err, check.Equals, errorNamespaceNotEmptyOfNodes) } func (s *Suite) TestRenameNamespace(c *check.C) { - n, err := h.CreateNamespace("test") + namespaceTest, err := app.CreateNamespace("test") c.Assert(err, check.IsNil) - c.Assert(n.Name, check.Equals, "test") + c.Assert(namespaceTest.Name, check.Equals, "test") - ns, err := h.ListNamespaces() + namespaces, err := app.ListNamespaces() c.Assert(err, check.IsNil) - c.Assert(len(ns), check.Equals, 1) + c.Assert(len(namespaces), check.Equals, 1) - err = h.RenameNamespace("test", "test_renamed") + err = app.RenameNamespace("test", "test_renamed") c.Assert(err, check.IsNil) - _, err = h.GetNamespace("test") + _, err = app.GetNamespace("test") c.Assert(err, check.Equals, errorNamespaceNotFound) - _, err = h.GetNamespace("test_renamed") + _, err = app.GetNamespace("test_renamed") c.Assert(err, check.IsNil) - err = h.RenameNamespace("test_does_not_exit", "test") + err = app.RenameNamespace("test_does_not_exit", "test") c.Assert(err, check.Equals, errorNamespaceNotFound) - n2, err := h.CreateNamespace("test2") + namespaceTest2, err := app.CreateNamespace("test2") c.Assert(err, check.IsNil) - c.Assert(n2.Name, check.Equals, "test2") + c.Assert(namespaceTest2.Name, check.Equals, "test2") - err = h.RenameNamespace("test2", "test_renamed") + err = app.RenameNamespace("test2", "test_renamed") c.Assert(err, check.Equals, errorNamespaceExists) } func (s *Suite) TestGetMapResponseUserProfiles(c *check.C) { - n1, err := h.CreateNamespace("shared1") + namespaceShared1, err := app.CreateNamespace("shared1") c.Assert(err, check.IsNil) - n2, err := h.CreateNamespace("shared2") + namespaceShared2, err := app.CreateNamespace("shared2") c.Assert(err, check.IsNil) - n3, err := h.CreateNamespace("shared3") + namespaceShared3, err := app.CreateNamespace("shared3") c.Assert(err, check.IsNil) - pak1n1, err := h.CreatePreAuthKey(n1.Name, false, false, nil) + preAuthKeyShared1, err := app.CreatePreAuthKey( + namespaceShared1.Name, + false, + false, + nil, + ) c.Assert(err, check.IsNil) - pak2n2, err := h.CreatePreAuthKey(n2.Name, false, false, nil) + preAuthKeyShared2, err := app.CreatePreAuthKey( + namespaceShared2.Name, + false, + false, + nil, + ) c.Assert(err, check.IsNil) - pak3n3, err := h.CreatePreAuthKey(n3.Name, false, false, nil) + preAuthKeyShared3, err := app.CreatePreAuthKey( + namespaceShared3.Name, + false, + false, + nil, + ) c.Assert(err, check.IsNil) - pak4n1, err := h.CreatePreAuthKey(n1.Name, false, false, nil) + preAuthKey2Shared1, err := app.CreatePreAuthKey( + namespaceShared1.Name, + false, + false, + nil, + ) c.Assert(err, check.IsNil) - _, err = h.GetMachine(n1.Name, "test_get_shared_nodes_1") + _, err = app.GetMachine(namespaceShared1.Name, "test_get_shared_nodes_1") c.Assert(err, check.NotNil) - m1 := &Machine{ + machineInShared1 := &Machine{ ID: 1, MachineKey: "686824e749f3b7f2a5927ee6c1e422aee5292592d9179a271ed7b3e659b44a66", NodeKey: "686824e749f3b7f2a5927ee6c1e422aee5292592d9179a271ed7b3e659b44a66", DiscoKey: "686824e749f3b7f2a5927ee6c1e422aee5292592d9179a271ed7b3e659b44a66", Name: "test_get_shared_nodes_1", - NamespaceID: n1.ID, - Namespace: *n1, + NamespaceID: namespaceShared1.ID, + Namespace: *namespaceShared1, Registered: true, RegisterMethod: "authKey", IPAddress: "100.64.0.1", - AuthKeyID: uint(pak1n1.ID), + AuthKeyID: uint(preAuthKeyShared1.ID), } - h.db.Save(m1) + app.db.Save(machineInShared1) - _, err = h.GetMachine(n1.Name, m1.Name) + _, err = app.GetMachine(namespaceShared1.Name, machineInShared1.Name) c.Assert(err, check.IsNil) - m2 := &Machine{ + machineInShared2 := &Machine{ ID: 2, MachineKey: "dec46ef9dc45c7d2f03bfcd5a640d9e24e3cc68ce3d9da223867c9bc6d5e9863", NodeKey: "dec46ef9dc45c7d2f03bfcd5a640d9e24e3cc68ce3d9da223867c9bc6d5e9863", DiscoKey: "dec46ef9dc45c7d2f03bfcd5a640d9e24e3cc68ce3d9da223867c9bc6d5e9863", Name: "test_get_shared_nodes_2", - NamespaceID: n2.ID, - Namespace: *n2, + NamespaceID: namespaceShared2.ID, + Namespace: *namespaceShared2, Registered: true, RegisterMethod: "authKey", IPAddress: "100.64.0.2", - AuthKeyID: uint(pak2n2.ID), + AuthKeyID: uint(preAuthKeyShared2.ID), } - h.db.Save(m2) + app.db.Save(machineInShared2) - _, err = h.GetMachine(n2.Name, m2.Name) + _, err = app.GetMachine(namespaceShared2.Name, machineInShared2.Name) c.Assert(err, check.IsNil) - m3 := &Machine{ + machineInShared3 := &Machine{ ID: 3, MachineKey: "dec46ef9dc45c7d2f03bfcd5a640d9e24e3cc68ce3d9da223867c9bc6d5e9863", NodeKey: "dec46ef9dc45c7d2f03bfcd5a640d9e24e3cc68ce3d9da223867c9bc6d5e9863", DiscoKey: "dec46ef9dc45c7d2f03bfcd5a640d9e24e3cc68ce3d9da223867c9bc6d5e9863", Name: "test_get_shared_nodes_3", - NamespaceID: n3.ID, - Namespace: *n3, + NamespaceID: namespaceShared3.ID, + Namespace: *namespaceShared3, Registered: true, RegisterMethod: "authKey", IPAddress: "100.64.0.3", - AuthKeyID: uint(pak3n3.ID), + AuthKeyID: uint(preAuthKeyShared3.ID), } - h.db.Save(m3) + app.db.Save(machineInShared3) - _, err = h.GetMachine(n3.Name, m3.Name) + _, err = app.GetMachine(namespaceShared3.Name, machineInShared3.Name) c.Assert(err, check.IsNil) - m4 := &Machine{ + machine2InShared1 := &Machine{ ID: 4, MachineKey: "dec46ef9dc45c7d2f03bfcd5a640d9e24e3cc68ce3d9da223867c9bc6d5e9863", NodeKey: "dec46ef9dc45c7d2f03bfcd5a640d9e24e3cc68ce3d9da223867c9bc6d5e9863", DiscoKey: "dec46ef9dc45c7d2f03bfcd5a640d9e24e3cc68ce3d9da223867c9bc6d5e9863", Name: "test_get_shared_nodes_4", - NamespaceID: n1.ID, - Namespace: *n1, + NamespaceID: namespaceShared1.ID, + Namespace: *namespaceShared1, Registered: true, RegisterMethod: "authKey", IPAddress: "100.64.0.4", - AuthKeyID: uint(pak4n1.ID), + AuthKeyID: uint(preAuthKey2Shared1.ID), } - h.db.Save(m4) + app.db.Save(machine2InShared1) - err = h.AddSharedMachineToNamespace(m2, n1) + err = app.AddSharedMachineToNamespace(machineInShared2, namespaceShared1) c.Assert(err, check.IsNil) - m1peers, err := h.getPeers(m1) + peersOfMachine1InShared1, err := app.getPeers(machineInShared1) c.Assert(err, check.IsNil) - userProfiles := getMapResponseUserProfiles(*m1, m1peers) + userProfiles := getMapResponseUserProfiles( + *machineInShared1, + peersOfMachine1InShared1, + ) log.Trace().Msgf("userProfiles %#v", userProfiles) c.Assert(len(userProfiles), check.Equals, 2) found := false - for _, up := range userProfiles { - if up.DisplayName == n1.Name { + for _, userProfiles := range userProfiles { + if userProfiles.DisplayName == namespaceShared1.Name { found = true break @@ -206,8 +229,8 @@ func (s *Suite) TestGetMapResponseUserProfiles(c *check.C) { c.Assert(found, check.Equals, true) found = false - for _, up := range userProfiles { - if up.DisplayName == n2.Name { + for _, userProfile := range userProfiles { + if userProfile.DisplayName == namespaceShared2.Name { found = true break diff --git a/oidc_test.go b/oidc_test.go index 6b019245..21a4357d 100644 --- a/oidc_test.go +++ b/oidc_test.go @@ -145,36 +145,36 @@ func TestHeadscale_getNamespaceFromEmail(t *testing.T) { }, } //nolint - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - h := &Headscale{ - cfg: tt.fields.cfg, - db: tt.fields.db, - dbString: tt.fields.dbString, - dbType: tt.fields.dbType, - dbDebug: tt.fields.dbDebug, - publicKey: tt.fields.publicKey, - privateKey: tt.fields.privateKey, - aclPolicy: tt.fields.aclPolicy, - aclRules: tt.fields.aclRules, - lastStateChange: tt.fields.lastStateChange, - oidcProvider: tt.fields.oidcProvider, - oauth2Config: tt.fields.oauth2Config, - oidcStateCache: tt.fields.oidcStateCache, + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + app := &Headscale{ + cfg: test.fields.cfg, + db: test.fields.db, + dbString: test.fields.dbString, + dbType: test.fields.dbType, + dbDebug: test.fields.dbDebug, + publicKey: test.fields.publicKey, + privateKey: test.fields.privateKey, + aclPolicy: test.fields.aclPolicy, + aclRules: test.fields.aclRules, + lastStateChange: test.fields.lastStateChange, + oidcProvider: test.fields.oidcProvider, + oauth2Config: test.fields.oauth2Config, + oidcStateCache: test.fields.oidcStateCache, } - got, got1 := h.getNamespaceFromEmail(tt.args.email) - if got != tt.want { + got, got1 := app.getNamespaceFromEmail(test.args.email) + if got != test.want { t.Errorf( "Headscale.getNamespaceFromEmail() got = %v, want %v", got, - tt.want, + test.want, ) } - if got1 != tt.want1 { + if got1 != test.want1 { t.Errorf( "Headscale.getNamespaceFromEmail() got1 = %v, want %v", got1, - tt.want1, + test.want1, ) } }) diff --git a/preauth_keys_test.go b/preauth_keys_test.go index dceec00b..6a6a79b4 100644 --- a/preauth_keys_test.go +++ b/preauth_keys_test.go @@ -7,189 +7,189 @@ import ( ) func (*Suite) TestCreatePreAuthKey(c *check.C) { - _, err := h.CreatePreAuthKey("bogus", true, false, nil) + _, err := app.CreatePreAuthKey("bogus", true, false, nil) c.Assert(err, check.NotNil) - n, err := h.CreateNamespace("test") + namespace, err := app.CreateNamespace("test") c.Assert(err, check.IsNil) - k, err := h.CreatePreAuthKey(n.Name, true, false, nil) + key, err := app.CreatePreAuthKey(namespace.Name, true, false, nil) c.Assert(err, check.IsNil) // Did we get a valid key? - c.Assert(k.Key, check.NotNil) - c.Assert(len(k.Key), check.Equals, 48) + c.Assert(key.Key, check.NotNil) + c.Assert(len(key.Key), check.Equals, 48) // Make sure the Namespace association is populated - c.Assert(k.Namespace.Name, check.Equals, n.Name) + c.Assert(key.Namespace.Name, check.Equals, namespace.Name) - _, err = h.ListPreAuthKeys("bogus") + _, err = app.ListPreAuthKeys("bogus") c.Assert(err, check.NotNil) - keys, err := h.ListPreAuthKeys(n.Name) + keys, err := app.ListPreAuthKeys(namespace.Name) c.Assert(err, check.IsNil) c.Assert(len(keys), check.Equals, 1) // Make sure the Namespace association is populated - c.Assert((keys)[0].Namespace.Name, check.Equals, n.Name) + c.Assert((keys)[0].Namespace.Name, check.Equals, namespace.Name) } func (*Suite) TestExpiredPreAuthKey(c *check.C) { - n, err := h.CreateNamespace("test2") + namespace, err := app.CreateNamespace("test2") c.Assert(err, check.IsNil) now := time.Now() - pak, err := h.CreatePreAuthKey(n.Name, true, false, &now) + pak, err := app.CreatePreAuthKey(namespace.Name, true, false, &now) c.Assert(err, check.IsNil) - p, err := h.checkKeyValidity(pak.Key) + key, err := app.checkKeyValidity(pak.Key) c.Assert(err, check.Equals, errorAuthKeyExpired) - c.Assert(p, check.IsNil) + c.Assert(key, check.IsNil) } func (*Suite) TestPreAuthKeyDoesNotExist(c *check.C) { - p, err := h.checkKeyValidity("potatoKey") + key, err := app.checkKeyValidity("potatoKey") c.Assert(err, check.Equals, errorAuthKeyNotFound) - c.Assert(p, check.IsNil) + c.Assert(key, check.IsNil) } func (*Suite) TestValidateKeyOk(c *check.C) { - n, err := h.CreateNamespace("test3") + namespace, err := app.CreateNamespace("test3") c.Assert(err, check.IsNil) - pak, err := h.CreatePreAuthKey(n.Name, true, false, nil) + pak, err := app.CreatePreAuthKey(namespace.Name, true, false, nil) c.Assert(err, check.IsNil) - p, err := h.checkKeyValidity(pak.Key) + key, err := app.checkKeyValidity(pak.Key) c.Assert(err, check.IsNil) - c.Assert(p.ID, check.Equals, pak.ID) + c.Assert(key.ID, check.Equals, pak.ID) } func (*Suite) TestAlreadyUsedKey(c *check.C) { - n, err := h.CreateNamespace("test4") + namespace, err := app.CreateNamespace("test4") c.Assert(err, check.IsNil) - pak, err := h.CreatePreAuthKey(n.Name, false, false, nil) + pak, err := app.CreatePreAuthKey(namespace.Name, false, false, nil) c.Assert(err, check.IsNil) - m := Machine{ + machine := Machine{ ID: 0, MachineKey: "foo", NodeKey: "bar", DiscoKey: "faa", Name: "testest", - NamespaceID: n.ID, + NamespaceID: namespace.ID, Registered: true, RegisterMethod: "authKey", AuthKeyID: uint(pak.ID), } - h.db.Save(&m) + app.db.Save(&machine) - p, err := h.checkKeyValidity(pak.Key) + key, err := app.checkKeyValidity(pak.Key) c.Assert(err, check.Equals, errSingleUseAuthKeyHasBeenUsed) - c.Assert(p, check.IsNil) + c.Assert(key, check.IsNil) } func (*Suite) TestReusableBeingUsedKey(c *check.C) { - n, err := h.CreateNamespace("test5") + namespace, err := app.CreateNamespace("test5") c.Assert(err, check.IsNil) - pak, err := h.CreatePreAuthKey(n.Name, true, false, nil) + pak, err := app.CreatePreAuthKey(namespace.Name, true, false, nil) c.Assert(err, check.IsNil) - m := Machine{ + machine := Machine{ ID: 1, MachineKey: "foo", NodeKey: "bar", DiscoKey: "faa", Name: "testest", - NamespaceID: n.ID, + NamespaceID: namespace.ID, Registered: true, RegisterMethod: "authKey", AuthKeyID: uint(pak.ID), } - h.db.Save(&m) + app.db.Save(&machine) - p, err := h.checkKeyValidity(pak.Key) + key, err := app.checkKeyValidity(pak.Key) c.Assert(err, check.IsNil) - c.Assert(p.ID, check.Equals, pak.ID) + c.Assert(key.ID, check.Equals, pak.ID) } func (*Suite) TestNotReusableNotBeingUsedKey(c *check.C) { - n, err := h.CreateNamespace("test6") + namespace, err := app.CreateNamespace("test6") c.Assert(err, check.IsNil) - pak, err := h.CreatePreAuthKey(n.Name, false, false, nil) + pak, err := app.CreatePreAuthKey(namespace.Name, false, false, nil) c.Assert(err, check.IsNil) - p, err := h.checkKeyValidity(pak.Key) + key, err := app.checkKeyValidity(pak.Key) c.Assert(err, check.IsNil) - c.Assert(p.ID, check.Equals, pak.ID) + c.Assert(key.ID, check.Equals, pak.ID) } func (*Suite) TestEphemeralKey(c *check.C) { - n, err := h.CreateNamespace("test7") + namespace, err := app.CreateNamespace("test7") c.Assert(err, check.IsNil) - pak, err := h.CreatePreAuthKey(n.Name, false, true, nil) + pak, err := app.CreatePreAuthKey(namespace.Name, false, true, nil) c.Assert(err, check.IsNil) now := time.Now() - m := Machine{ + machine := Machine{ ID: 0, MachineKey: "foo", NodeKey: "bar", DiscoKey: "faa", Name: "testest", - NamespaceID: n.ID, + NamespaceID: namespace.ID, Registered: true, RegisterMethod: "authKey", LastSeen: &now, AuthKeyID: uint(pak.ID), } - h.db.Save(&m) + app.db.Save(&machine) - _, err = h.checkKeyValidity(pak.Key) + _, err = app.checkKeyValidity(pak.Key) // Ephemeral keys are by definition reusable c.Assert(err, check.IsNil) - _, err = h.GetMachine("test7", "testest") + _, err = app.GetMachine("test7", "testest") c.Assert(err, check.IsNil) - h.expireEphemeralNodesWorker() + app.expireEphemeralNodesWorker() // The machine record should have been deleted - _, err = h.GetMachine("test7", "testest") + _, err = app.GetMachine("test7", "testest") c.Assert(err, check.NotNil) } func (*Suite) TestExpirePreauthKey(c *check.C) { - n, err := h.CreateNamespace("test3") + namespace, err := app.CreateNamespace("test3") c.Assert(err, check.IsNil) - pak, err := h.CreatePreAuthKey(n.Name, true, false, nil) + pak, err := app.CreatePreAuthKey(namespace.Name, true, false, nil) c.Assert(err, check.IsNil) c.Assert(pak.Expiration, check.IsNil) - err = h.ExpirePreAuthKey(pak) + err = app.ExpirePreAuthKey(pak) c.Assert(err, check.IsNil) c.Assert(pak.Expiration, check.NotNil) - p, err := h.checkKeyValidity(pak.Key) + key, err := app.checkKeyValidity(pak.Key) c.Assert(err, check.Equals, errorAuthKeyExpired) - c.Assert(p, check.IsNil) + c.Assert(key, check.IsNil) } func (*Suite) TestNotReusableMarkedAsUsed(c *check.C) { - n, err := h.CreateNamespace("test6") + namespace, err := app.CreateNamespace("test6") c.Assert(err, check.IsNil) - pak, err := h.CreatePreAuthKey(n.Name, false, false, nil) + pak, err := app.CreatePreAuthKey(namespace.Name, false, false, nil) c.Assert(err, check.IsNil) pak.Used = true - h.db.Save(&pak) + app.db.Save(&pak) - _, err = h.checkKeyValidity(pak.Key) + _, err = app.checkKeyValidity(pak.Key) c.Assert(err, check.Equals, errSingleUseAuthKeyHasBeenUsed) } diff --git a/routes_test.go b/routes_test.go index a120eda6..07427548 100644 --- a/routes_test.go +++ b/routes_test.go @@ -10,57 +10,57 @@ import ( ) func (s *Suite) TestGetRoutes(c *check.C) { - n, err := h.CreateNamespace("test") + namespace, err := app.CreateNamespace("test") c.Assert(err, check.IsNil) - pak, err := h.CreatePreAuthKey(n.Name, false, false, nil) + pak, err := app.CreatePreAuthKey(namespace.Name, false, false, nil) c.Assert(err, check.IsNil) - _, err = h.GetMachine("test", "test_get_route_machine") + _, err = app.GetMachine("test", "test_get_route_machine") c.Assert(err, check.NotNil) route, err := netaddr.ParseIPPrefix("10.0.0.0/24") c.Assert(err, check.IsNil) - hi := tailcfg.Hostinfo{ + hostInfo := tailcfg.Hostinfo{ RoutableIPs: []netaddr.IPPrefix{route}, } - hostinfo, err := json.Marshal(hi) + hostinfo, err := json.Marshal(hostInfo) c.Assert(err, check.IsNil) - m := Machine{ + machine := Machine{ ID: 0, MachineKey: "foo", NodeKey: "bar", DiscoKey: "faa", Name: "test_get_route_machine", - NamespaceID: n.ID, + NamespaceID: namespace.ID, Registered: true, RegisterMethod: "authKey", AuthKeyID: uint(pak.ID), HostInfo: datatypes.JSON(hostinfo), } - h.db.Save(&m) + app.db.Save(&machine) - r, err := h.GetAdvertisedNodeRoutes("test", "test_get_route_machine") + advertisedRoutes, err := app.GetAdvertisedNodeRoutes("test", "test_get_route_machine") c.Assert(err, check.IsNil) - c.Assert(len(*r), check.Equals, 1) + c.Assert(len(*advertisedRoutes), check.Equals, 1) - err = h.EnableNodeRoute("test", "test_get_route_machine", "192.168.0.0/24") + err = app.EnableNodeRoute("test", "test_get_route_machine", "192.168.0.0/24") c.Assert(err, check.NotNil) - err = h.EnableNodeRoute("test", "test_get_route_machine", "10.0.0.0/24") + err = app.EnableNodeRoute("test", "test_get_route_machine", "10.0.0.0/24") c.Assert(err, check.IsNil) } func (s *Suite) TestGetEnableRoutes(c *check.C) { - n, err := h.CreateNamespace("test") + namespace, err := app.CreateNamespace("test") c.Assert(err, check.IsNil) - pak, err := h.CreatePreAuthKey(n.Name, false, false, nil) + pak, err := app.CreatePreAuthKey(namespace.Name, false, false, nil) c.Assert(err, check.IsNil) - _, err = h.GetMachine("test", "test_enable_route_machine") + _, err = app.GetMachine("test", "test_enable_route_machine") c.Assert(err, check.NotNil) route, err := netaddr.ParseIPPrefix( @@ -73,59 +73,65 @@ func (s *Suite) TestGetEnableRoutes(c *check.C) { ) c.Assert(err, check.IsNil) - hi := tailcfg.Hostinfo{ + hostInfo := tailcfg.Hostinfo{ RoutableIPs: []netaddr.IPPrefix{route, route2}, } - hostinfo, err := json.Marshal(hi) + hostinfo, err := json.Marshal(hostInfo) c.Assert(err, check.IsNil) - m := Machine{ + machine := Machine{ ID: 0, MachineKey: "foo", NodeKey: "bar", DiscoKey: "faa", Name: "test_enable_route_machine", - NamespaceID: n.ID, + NamespaceID: namespace.ID, Registered: true, RegisterMethod: "authKey", AuthKeyID: uint(pak.ID), HostInfo: datatypes.JSON(hostinfo), } - h.db.Save(&m) + app.db.Save(&machine) - availableRoutes, err := h.GetAdvertisedNodeRoutes( + availableRoutes, err := app.GetAdvertisedNodeRoutes( "test", "test_enable_route_machine", ) c.Assert(err, check.IsNil) c.Assert(len(*availableRoutes), check.Equals, 2) - enabledRoutes, err := h.GetEnabledNodeRoutes("test", "test_enable_route_machine") + noEnabledRoutes, err := app.GetEnabledNodeRoutes("test", "test_enable_route_machine") c.Assert(err, check.IsNil) - c.Assert(len(enabledRoutes), check.Equals, 0) + c.Assert(len(noEnabledRoutes), check.Equals, 0) - err = h.EnableNodeRoute("test", "test_enable_route_machine", "192.168.0.0/24") + err = app.EnableNodeRoute("test", "test_enable_route_machine", "192.168.0.0/24") c.Assert(err, check.NotNil) - err = h.EnableNodeRoute("test", "test_enable_route_machine", "10.0.0.0/24") + err = app.EnableNodeRoute("test", "test_enable_route_machine", "10.0.0.0/24") c.Assert(err, check.IsNil) - enabledRoutes1, err := h.GetEnabledNodeRoutes("test", "test_enable_route_machine") + enabledRoutes, err := app.GetEnabledNodeRoutes("test", "test_enable_route_machine") c.Assert(err, check.IsNil) - c.Assert(len(enabledRoutes1), check.Equals, 1) + c.Assert(len(enabledRoutes), check.Equals, 1) // Adding it twice will just let it pass through - err = h.EnableNodeRoute("test", "test_enable_route_machine", "10.0.0.0/24") + err = app.EnableNodeRoute("test", "test_enable_route_machine", "10.0.0.0/24") c.Assert(err, check.IsNil) - enabledRoutes2, err := h.GetEnabledNodeRoutes("test", "test_enable_route_machine") + enableRoutesAfterDoubleApply, err := app.GetEnabledNodeRoutes( + "test", + "test_enable_route_machine", + ) c.Assert(err, check.IsNil) - c.Assert(len(enabledRoutes2), check.Equals, 1) + c.Assert(len(enableRoutesAfterDoubleApply), check.Equals, 1) - err = h.EnableNodeRoute("test", "test_enable_route_machine", "150.0.10.0/25") + err = app.EnableNodeRoute("test", "test_enable_route_machine", "150.0.10.0/25") c.Assert(err, check.IsNil) - enabledRoutes3, err := h.GetEnabledNodeRoutes("test", "test_enable_route_machine") + enabledRoutesWithAdditionalRoute, err := app.GetEnabledNodeRoutes( + "test", + "test_enable_route_machine", + ) c.Assert(err, check.IsNil) - c.Assert(len(enabledRoutes3), check.Equals, 2) + c.Assert(len(enabledRoutesWithAdditionalRoute), check.Equals, 2) } diff --git a/sharing_test.go b/sharing_test.go index 395b8336..b1806213 100644 --- a/sharing_test.go +++ b/sharing_test.go @@ -6,46 +6,46 @@ import ( func CreateNodeNamespace( c *check.C, - namespace, node, key, ip string, + namespaceName, node, key, ip string, ) (*Namespace, *Machine) { - n1, err := h.CreateNamespace(namespace) + namespace, err := app.CreateNamespace(namespaceName) c.Assert(err, check.IsNil) - pak1, err := h.CreatePreAuthKey(n1.Name, false, false, nil) + pak1, err := app.CreatePreAuthKey(namespace.Name, false, false, nil) c.Assert(err, check.IsNil) - _, err = h.GetMachine(n1.Name, node) + _, err = app.GetMachine(namespace.Name, node) c.Assert(err, check.NotNil) - m1 := &Machine{ + machine := &Machine{ ID: 0, MachineKey: key, NodeKey: key, DiscoKey: key, Name: node, - NamespaceID: n1.ID, + NamespaceID: namespace.ID, Registered: true, RegisterMethod: "authKey", IPAddress: ip, AuthKeyID: uint(pak1.ID), } - h.db.Save(m1) + app.db.Save(machine) - _, err = h.GetMachine(n1.Name, m1.Name) + _, err = app.GetMachine(namespace.Name, machine.Name) c.Assert(err, check.IsNil) - return n1, m1 + return namespace, machine } func (s *Suite) TestBasicSharedNodesInNamespace(c *check.C) { - n1, m1 := CreateNodeNamespace( + namespace1, machine1 := CreateNodeNamespace( c, "shared1", "test_get_shared_nodes_1", "686824e749f3b7f2a5927ee6c1e422aee5292592d9179a271ed7b3e659b44a66", "100.64.0.1", ) - _, m2 := CreateNodeNamespace( + _, machine2 := CreateNodeNamespace( c, "shared2", "test_get_shared_nodes_2", @@ -53,21 +53,21 @@ func (s *Suite) TestBasicSharedNodesInNamespace(c *check.C) { "100.64.0.2", ) - p1s, err := h.getPeers(m1) + peersOfMachine1BeforeShared, err := app.getPeers(machine1) c.Assert(err, check.IsNil) - c.Assert(len(p1s), check.Equals, 0) + c.Assert(len(peersOfMachine1BeforeShared), check.Equals, 0) - err = h.AddSharedMachineToNamespace(m2, n1) + err = app.AddSharedMachineToNamespace(machine2, namespace1) c.Assert(err, check.IsNil) - p1sAfter, err := h.getPeers(m1) + peersOfMachine1AfterShared, err := app.getPeers(machine1) c.Assert(err, check.IsNil) - c.Assert(len(p1sAfter), check.Equals, 1) - c.Assert(p1sAfter[0].ID, check.Equals, m2.ID) + c.Assert(len(peersOfMachine1AfterShared), check.Equals, 1) + c.Assert(peersOfMachine1AfterShared[0].ID, check.Equals, machine2.ID) } func (s *Suite) TestSameNamespace(c *check.C) { - n1, m1 := CreateNodeNamespace( + namespace1, machine1 := CreateNodeNamespace( c, "shared1", "test_get_shared_nodes_1", @@ -75,23 +75,23 @@ func (s *Suite) TestSameNamespace(c *check.C) { "100.64.0.1", ) - p1s, err := h.getPeers(m1) + peersOfMachine1BeforeShare, err := app.getPeers(machine1) c.Assert(err, check.IsNil) - c.Assert(len(p1s), check.Equals, 0) + c.Assert(len(peersOfMachine1BeforeShare), check.Equals, 0) - err = h.AddSharedMachineToNamespace(m1, n1) + err = app.AddSharedMachineToNamespace(machine1, namespace1) c.Assert(err, check.Equals, errorSameNamespace) } func (s *Suite) TestUnshare(c *check.C) { - n1, m1 := CreateNodeNamespace( + namespace1, machine1 := CreateNodeNamespace( c, "shared1", "test_unshare_1", "686824e749f3b7f2a5927ee6c1e422aee5292592d9179a271ed7b3e659b44a66", "100.64.0.1", ) - _, m2 := CreateNodeNamespace( + _, machine2 := CreateNodeNamespace( c, "shared2", "test_unshare_2", @@ -99,40 +99,40 @@ func (s *Suite) TestUnshare(c *check.C) { "100.64.0.2", ) - p1s, err := h.getPeers(m1) + peersOfMachine1BeforeShare, err := app.getPeers(machine1) c.Assert(err, check.IsNil) - c.Assert(len(p1s), check.Equals, 0) + c.Assert(len(peersOfMachine1BeforeShare), check.Equals, 0) - err = h.AddSharedMachineToNamespace(m2, n1) + err = app.AddSharedMachineToNamespace(machine2, namespace1) c.Assert(err, check.IsNil) - p1s, err = h.getShared(m1) + peersOfMachine1BeforeShare, err = app.getShared(machine1) c.Assert(err, check.IsNil) - c.Assert(len(p1s), check.Equals, 1) + c.Assert(len(peersOfMachine1BeforeShare), check.Equals, 1) - err = h.RemoveSharedMachineFromNamespace(m2, n1) + err = app.RemoveSharedMachineFromNamespace(machine2, namespace1) c.Assert(err, check.IsNil) - p1s, err = h.getShared(m1) + peersOfMachine1BeforeShare, err = app.getShared(machine1) c.Assert(err, check.IsNil) - c.Assert(len(p1s), check.Equals, 0) + c.Assert(len(peersOfMachine1BeforeShare), check.Equals, 0) - err = h.RemoveSharedMachineFromNamespace(m2, n1) + err = app.RemoveSharedMachineFromNamespace(machine2, namespace1) c.Assert(err, check.Equals, errorMachineNotShared) - err = h.RemoveSharedMachineFromNamespace(m1, n1) + err = app.RemoveSharedMachineFromNamespace(machine1, namespace1) c.Assert(err, check.Equals, errorMachineNotShared) } func (s *Suite) TestAlreadyShared(c *check.C) { - n1, m1 := CreateNodeNamespace( + namespace1, machine1 := CreateNodeNamespace( c, "shared1", "test_get_shared_nodes_1", "686824e749f3b7f2a5927ee6c1e422aee5292592d9179a271ed7b3e659b44a66", "100.64.0.1", ) - _, m2 := CreateNodeNamespace( + _, machine2 := CreateNodeNamespace( c, "shared2", "test_get_shared_nodes_2", @@ -140,25 +140,25 @@ func (s *Suite) TestAlreadyShared(c *check.C) { "100.64.0.2", ) - p1s, err := h.getPeers(m1) + peersOfMachine1BeforeShare, err := app.getPeers(machine1) c.Assert(err, check.IsNil) - c.Assert(len(p1s), check.Equals, 0) + c.Assert(len(peersOfMachine1BeforeShare), check.Equals, 0) - err = h.AddSharedMachineToNamespace(m2, n1) + err = app.AddSharedMachineToNamespace(machine2, namespace1) c.Assert(err, check.IsNil) - err = h.AddSharedMachineToNamespace(m2, n1) + err = app.AddSharedMachineToNamespace(machine2, namespace1) c.Assert(err, check.Equals, errorMachineAlreadyShared) } func (s *Suite) TestDoNotIncludeRoutesOnShared(c *check.C) { - n1, m1 := CreateNodeNamespace( + namespace1, machine1 := CreateNodeNamespace( c, "shared1", "test_get_shared_nodes_1", "686824e749f3b7f2a5927ee6c1e422aee5292592d9179a271ed7b3e659b44a66", "100.64.0.1", ) - _, m2 := CreateNodeNamespace( + _, machine2 := CreateNodeNamespace( c, "shared2", "test_get_shared_nodes_2", @@ -166,35 +166,35 @@ func (s *Suite) TestDoNotIncludeRoutesOnShared(c *check.C) { "100.64.0.2", ) - p1s, err := h.getPeers(m1) + peersOfMachine1BeforeShare, err := app.getPeers(machine1) c.Assert(err, check.IsNil) - c.Assert(len(p1s), check.Equals, 0) + c.Assert(len(peersOfMachine1BeforeShare), check.Equals, 0) - err = h.AddSharedMachineToNamespace(m2, n1) + err = app.AddSharedMachineToNamespace(machine2, namespace1) c.Assert(err, check.IsNil) - p1sAfter, err := h.getPeers(m1) + peersOfMachine1AfterShare, err := app.getPeers(machine1) c.Assert(err, check.IsNil) - c.Assert(len(p1sAfter), check.Equals, 1) - c.Assert(p1sAfter[0].Name, check.Equals, "test_get_shared_nodes_2") + c.Assert(len(peersOfMachine1AfterShare), check.Equals, 1) + c.Assert(peersOfMachine1AfterShare[0].Name, check.Equals, "test_get_shared_nodes_2") } func (s *Suite) TestComplexSharingAcrossNamespaces(c *check.C) { - n1, m1 := CreateNodeNamespace( + namespace1, machine1 := CreateNodeNamespace( c, "shared1", "test_get_shared_nodes_1", "686824e749f3b7f2a5927ee6c1e422aee5292592d9179a271ed7b3e659b44a66", "100.64.0.1", ) - _, m2 := CreateNodeNamespace( + _, machine2 := CreateNodeNamespace( c, "shared2", "test_get_shared_nodes_2", "dec46ef9dc45c7d2f03bfcd5a640d9e24e3cc68ce3d9da223867c9bc6d5e9863", "100.64.0.2", ) - _, m3 := CreateNodeNamespace( + _, machine3 := CreateNodeNamespace( c, "shared3", "test_get_shared_nodes_3", @@ -202,80 +202,80 @@ func (s *Suite) TestComplexSharingAcrossNamespaces(c *check.C) { "100.64.0.3", ) - pak4, err := h.CreatePreAuthKey(n1.Name, false, false, nil) + pak4, err := app.CreatePreAuthKey(namespace1.Name, false, false, nil) c.Assert(err, check.IsNil) - m4 := &Machine{ + machine4 := &Machine{ ID: 4, MachineKey: "4c3e07c3ecd40e9c945bb6797557c451850691c0409740578325e17009dd298f", NodeKey: "4c3e07c3ecd40e9c945bb6797557c451850691c0409740578325e17009dd298f", DiscoKey: "4c3e07c3ecd40e9c945bb6797557c451850691c0409740578325e17009dd298f", Name: "test_get_shared_nodes_4", - NamespaceID: n1.ID, + NamespaceID: namespace1.ID, Registered: true, RegisterMethod: "authKey", IPAddress: "100.64.0.4", AuthKeyID: uint(pak4.ID), } - h.db.Save(m4) + app.db.Save(machine4) - _, err = h.GetMachine(n1.Name, m4.Name) + _, err = app.GetMachine(namespace1.Name, machine4.Name) c.Assert(err, check.IsNil) - p1s, err := h.getPeers(m1) + peersOfMachine1BeforeShare, err := app.getPeers(machine1) c.Assert(err, check.IsNil) - c.Assert(len(p1s), check.Equals, 1) // node1 can see node4 - c.Assert(p1s[0].Name, check.Equals, m4.Name) + c.Assert(len(peersOfMachine1BeforeShare), check.Equals, 1) // node1 can see node4 + c.Assert(peersOfMachine1BeforeShare[0].Name, check.Equals, machine4.Name) - err = h.AddSharedMachineToNamespace(m2, n1) + err = app.AddSharedMachineToNamespace(machine2, namespace1) c.Assert(err, check.IsNil) - p1sAfter, err := h.getPeers(m1) + peersOfMachine1AfterShare, err := app.getPeers(machine1) c.Assert(err, check.IsNil) c.Assert( - len(p1sAfter), + len(peersOfMachine1AfterShare), check.Equals, 2, ) // node1 can see node2 (shared) and node4 (same namespace) - c.Assert(p1sAfter[0].Name, check.Equals, m2.Name) - c.Assert(p1sAfter[1].Name, check.Equals, m4.Name) + c.Assert(peersOfMachine1AfterShare[0].Name, check.Equals, machine2.Name) + c.Assert(peersOfMachine1AfterShare[1].Name, check.Equals, machine4.Name) - node1shared, err := h.getShared(m1) + sharedOfMachine1, err := app.getShared(machine1) c.Assert(err, check.IsNil) - c.Assert(len(node1shared), check.Equals, 1) // node1 can see node2 as shared - c.Assert(node1shared[0].Name, check.Equals, m2.Name) + c.Assert(len(sharedOfMachine1), check.Equals, 1) // node1 can see node2 as shared + c.Assert(sharedOfMachine1[0].Name, check.Equals, machine2.Name) - pAlone, err := h.getPeers(m3) + peersOfMachine3, err := app.getPeers(machine3) c.Assert(err, check.IsNil) - c.Assert(len(pAlone), check.Equals, 0) // node3 is alone + c.Assert(len(peersOfMachine3), check.Equals, 0) // node3 is alone - pSharedTo, err := h.getPeers(m2) + peersOfMachine2, err := app.getPeers(machine2) c.Assert(err, check.IsNil) c.Assert( - len(pSharedTo), + len(peersOfMachine2), check.Equals, 2, ) // node2 should see node1 (sharedTo) and node4 (sharedTo), as is shared in namespace1 - c.Assert(pSharedTo[0].Name, check.Equals, m1.Name) - c.Assert(pSharedTo[1].Name, check.Equals, m4.Name) + c.Assert(peersOfMachine2[0].Name, check.Equals, machine1.Name) + c.Assert(peersOfMachine2[1].Name, check.Equals, machine4.Name) } func (s *Suite) TestDeleteSharedMachine(c *check.C) { - n1, m1 := CreateNodeNamespace( + namespace1, machine1 := CreateNodeNamespace( c, "shared1", "test_get_shared_nodes_1", "686824e749f3b7f2a5927ee6c1e422aee5292592d9179a271ed7b3e659b44a66", "100.64.0.1", ) - _, m2 := CreateNodeNamespace( + _, machine2 := CreateNodeNamespace( c, "shared2", "test_get_shared_nodes_2", "dec46ef9dc45c7d2f03bfcd5a640d9e24e3cc68ce3d9da223867c9bc6d5e9863", "100.64.0.2", ) - _, m3 := CreateNodeNamespace( + _, machine3 := CreateNodeNamespace( c, "shared3", "test_get_shared_nodes_3", @@ -283,56 +283,56 @@ func (s *Suite) TestDeleteSharedMachine(c *check.C) { "100.64.0.3", ) - pak4n1, err := h.CreatePreAuthKey(n1.Name, false, false, nil) + pak4n1, err := app.CreatePreAuthKey(namespace1.Name, false, false, nil) c.Assert(err, check.IsNil) - m4 := &Machine{ + machine4 := &Machine{ ID: 4, MachineKey: "4c3e07c3ecd40e9c945bb6797557c451850691c0409740578325e17009dd298f", NodeKey: "4c3e07c3ecd40e9c945bb6797557c451850691c0409740578325e17009dd298f", DiscoKey: "4c3e07c3ecd40e9c945bb6797557c451850691c0409740578325e17009dd298f", Name: "test_get_shared_nodes_4", - NamespaceID: n1.ID, + NamespaceID: namespace1.ID, Registered: true, RegisterMethod: "authKey", IPAddress: "100.64.0.4", AuthKeyID: uint(pak4n1.ID), } - h.db.Save(m4) + app.db.Save(machine4) - _, err = h.GetMachine(n1.Name, m4.Name) + _, err = app.GetMachine(namespace1.Name, machine4.Name) c.Assert(err, check.IsNil) - p1s, err := h.getPeers(m1) + peersOfMachine1BeforeShare, err := app.getPeers(machine1) c.Assert(err, check.IsNil) - c.Assert(len(p1s), check.Equals, 1) // nodes 1 and 4 - c.Assert(p1s[0].Name, check.Equals, m4.Name) + c.Assert(len(peersOfMachine1BeforeShare), check.Equals, 1) // nodes 1 and 4 + c.Assert(peersOfMachine1BeforeShare[0].Name, check.Equals, machine4.Name) - err = h.AddSharedMachineToNamespace(m2, n1) + err = app.AddSharedMachineToNamespace(machine2, namespace1) c.Assert(err, check.IsNil) - p1sAfter, err := h.getPeers(m1) + peersOfMachine1AfterShare, err := app.getPeers(machine1) c.Assert(err, check.IsNil) - c.Assert(len(p1sAfter), check.Equals, 2) // nodes 1, 2, 4 - c.Assert(p1sAfter[0].Name, check.Equals, m2.Name) - c.Assert(p1sAfter[1].Name, check.Equals, m4.Name) + c.Assert(len(peersOfMachine1AfterShare), check.Equals, 2) // nodes 1, 2, 4 + c.Assert(peersOfMachine1AfterShare[0].Name, check.Equals, machine2.Name) + c.Assert(peersOfMachine1AfterShare[1].Name, check.Equals, machine4.Name) - node1shared, err := h.getShared(m1) + sharedOfMachine1, err := app.getShared(machine1) c.Assert(err, check.IsNil) - c.Assert(len(node1shared), check.Equals, 1) // nodes 1, 2, 4 - c.Assert(node1shared[0].Name, check.Equals, m2.Name) + c.Assert(len(sharedOfMachine1), check.Equals, 1) // nodes 1, 2, 4 + c.Assert(sharedOfMachine1[0].Name, check.Equals, machine2.Name) - pAlone, err := h.getPeers(m3) + peersOfMachine3, err := app.getPeers(machine3) c.Assert(err, check.IsNil) - c.Assert(len(pAlone), check.Equals, 0) // node 3 is alone + c.Assert(len(peersOfMachine3), check.Equals, 0) // node 3 is alone - sharedMachines, err := h.ListSharedMachinesInNamespace(n1.Name) + sharedMachinesInNamespace1, err := app.ListSharedMachinesInNamespace(namespace1.Name) c.Assert(err, check.IsNil) - c.Assert(len(sharedMachines), check.Equals, 1) + c.Assert(len(sharedMachinesInNamespace1), check.Equals, 1) - err = h.DeleteMachine(m2) + err = app.DeleteMachine(machine2) c.Assert(err, check.IsNil) - sharedMachines, err = h.ListSharedMachinesInNamespace(n1.Name) + sharedMachinesInNamespace1, err = app.ListSharedMachinesInNamespace(namespace1.Name) c.Assert(err, check.IsNil) - c.Assert(len(sharedMachines), check.Equals, 0) + c.Assert(len(sharedMachinesInNamespace1), check.Equals, 0) } diff --git a/utils_test.go b/utils_test.go index f50cd117..dcda6130 100644 --- a/utils_test.go +++ b/utils_test.go @@ -6,7 +6,7 @@ import ( ) func (s *Suite) TestGetAvailableIp(c *check.C) { - ip, err := h.getAvailableIP() + ip, err := app.getAvailableIP() c.Assert(err, check.IsNil) @@ -16,33 +16,33 @@ func (s *Suite) TestGetAvailableIp(c *check.C) { } func (s *Suite) TestGetUsedIps(c *check.C) { - ip, err := h.getAvailableIP() + ip, err := app.getAvailableIP() c.Assert(err, check.IsNil) - n, err := h.CreateNamespace("test_ip") + namespace, err := app.CreateNamespace("test_ip") c.Assert(err, check.IsNil) - pak, err := h.CreatePreAuthKey(n.Name, false, false, nil) + pak, err := app.CreatePreAuthKey(namespace.Name, false, false, nil) c.Assert(err, check.IsNil) - _, err = h.GetMachine("test", "testmachine") + _, err = app.GetMachine("test", "testmachine") c.Assert(err, check.NotNil) - m := Machine{ + machine := Machine{ ID: 0, MachineKey: "foo", NodeKey: "bar", DiscoKey: "faa", Name: "testmachine", - NamespaceID: n.ID, + NamespaceID: namespace.ID, Registered: true, RegisterMethod: "authKey", AuthKeyID: uint(pak.ID), IPAddress: ip.String(), } - h.db.Save(&m) + app.db.Save(&machine) - ips, err := h.getUsedIPs() + ips, err := app.getUsedIPs() c.Assert(err, check.IsNil) @@ -50,42 +50,42 @@ func (s *Suite) TestGetUsedIps(c *check.C) { c.Assert(ips[0], check.Equals, expected) - m1, err := h.GetMachineByID(0) + machine1, err := app.GetMachineByID(0) c.Assert(err, check.IsNil) - c.Assert(m1.IPAddress, check.Equals, expected.String()) + c.Assert(machine1.IPAddress, check.Equals, expected.String()) } func (s *Suite) TestGetMultiIp(c *check.C) { - n, err := h.CreateNamespace("test-ip-multi") + namespace, err := app.CreateNamespace("test-ip-multi") c.Assert(err, check.IsNil) - for i := 1; i <= 350; i++ { - ip, err := h.getAvailableIP() + for index := 1; index <= 350; index++ { + ip, err := app.getAvailableIP() c.Assert(err, check.IsNil) - pak, err := h.CreatePreAuthKey(n.Name, false, false, nil) + pak, err := app.CreatePreAuthKey(namespace.Name, false, false, nil) c.Assert(err, check.IsNil) - _, err = h.GetMachine("test", "testmachine") + _, err = app.GetMachine("test", "testmachine") c.Assert(err, check.NotNil) - m := Machine{ - ID: uint64(i), + machine := Machine{ + ID: uint64(index), MachineKey: "foo", NodeKey: "bar", DiscoKey: "faa", Name: "testmachine", - NamespaceID: n.ID, + NamespaceID: namespace.ID, Registered: true, RegisterMethod: "authKey", AuthKeyID: uint(pak.ID), IPAddress: ip.String(), } - h.db.Save(&m) + app.db.Save(&machine) } - ips, err := h.getUsedIPs() + ips, err := app.getUsedIPs() c.Assert(err, check.IsNil) @@ -96,59 +96,67 @@ func (s *Suite) TestGetMultiIp(c *check.C) { c.Assert(ips[300], check.Equals, netaddr.MustParseIP("10.27.1.47")) // Check that we can read back the IPs - m1, err := h.GetMachineByID(1) + machine1, err := app.GetMachineByID(1) c.Assert(err, check.IsNil) - c.Assert(m1.IPAddress, check.Equals, netaddr.MustParseIP("10.27.0.1").String()) + c.Assert( + machine1.IPAddress, + check.Equals, + netaddr.MustParseIP("10.27.0.1").String(), + ) - m50, err := h.GetMachineByID(50) + machine50, err := app.GetMachineByID(50) c.Assert(err, check.IsNil) - c.Assert(m50.IPAddress, check.Equals, netaddr.MustParseIP("10.27.0.50").String()) + c.Assert( + machine50.IPAddress, + check.Equals, + netaddr.MustParseIP("10.27.0.50").String(), + ) expectedNextIP := netaddr.MustParseIP("10.27.1.97") - nextIP, err := h.getAvailableIP() + nextIP, err := app.getAvailableIP() c.Assert(err, check.IsNil) c.Assert(nextIP.String(), check.Equals, expectedNextIP.String()) // If we call get Available again, we should receive // the same IP, as it has not been reserved. - nextIP2, err := h.getAvailableIP() + nextIP2, err := app.getAvailableIP() c.Assert(err, check.IsNil) c.Assert(nextIP2.String(), check.Equals, expectedNextIP.String()) } func (s *Suite) TestGetAvailableIpMachineWithoutIP(c *check.C) { - ip, err := h.getAvailableIP() + ip, err := app.getAvailableIP() c.Assert(err, check.IsNil) expected := netaddr.MustParseIP("10.27.0.1") c.Assert(ip.String(), check.Equals, expected.String()) - n, err := h.CreateNamespace("test_ip") + namespace, err := app.CreateNamespace("test_ip") c.Assert(err, check.IsNil) - pak, err := h.CreatePreAuthKey(n.Name, false, false, nil) + pak, err := app.CreatePreAuthKey(namespace.Name, false, false, nil) c.Assert(err, check.IsNil) - _, err = h.GetMachine("test", "testmachine") + _, err = app.GetMachine("test", "testmachine") c.Assert(err, check.NotNil) - m := Machine{ + machine := Machine{ ID: 0, MachineKey: "foo", NodeKey: "bar", DiscoKey: "faa", Name: "testmachine", - NamespaceID: n.ID, + NamespaceID: namespace.ID, Registered: true, RegisterMethod: "authKey", AuthKeyID: uint(pak.ID), } - h.db.Save(&m) + app.db.Save(&machine) - ip2, err := h.getAvailableIP() + ip2, err := app.getAvailableIP() c.Assert(err, check.IsNil) c.Assert(ip2.String(), check.Equals, expected.String()) From 78cfba0a317cba98e516a2d7c1f79e8727c99987 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Mon, 15 Nov 2021 16:16:16 +0000 Subject: [PATCH 154/300] Add exceptions to var name length --- .golangci.yaml | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/.golangci.yaml b/.golangci.yaml index f7fc0c67..72bab980 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -28,9 +28,6 @@ linters: # In progress - gocritic - # TODO: approve: ok, db, id - - varnamelen - # We should strive to enable these: - testpackage - stylecheck @@ -49,3 +46,15 @@ linters: - cyclop - nestif - wsl # might be incompatible with gofumpt + +linters-settings: + varnamelen: + ignore-type-assert-ok: true + ignore-map-index-ok: true + ignore-names: + - err + - db + - id + - ip + - ok + - c From 2dde1242cf7d50ce3442456feda7f09e4c693711 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Mon, 15 Nov 2021 16:16:35 +0000 Subject: [PATCH 155/300] Fix formatting --- routes_test.go | 10 ++++++++-- sharing_test.go | 4 +++- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/routes_test.go b/routes_test.go index 07427548..18cb0ceb 100644 --- a/routes_test.go +++ b/routes_test.go @@ -42,7 +42,10 @@ func (s *Suite) TestGetRoutes(c *check.C) { } app.db.Save(&machine) - advertisedRoutes, err := app.GetAdvertisedNodeRoutes("test", "test_get_route_machine") + advertisedRoutes, err := app.GetAdvertisedNodeRoutes( + "test", + "test_get_route_machine", + ) c.Assert(err, check.IsNil) c.Assert(len(*advertisedRoutes), check.Equals, 1) @@ -100,7 +103,10 @@ func (s *Suite) TestGetEnableRoutes(c *check.C) { c.Assert(err, check.IsNil) c.Assert(len(*availableRoutes), check.Equals, 2) - noEnabledRoutes, err := app.GetEnabledNodeRoutes("test", "test_enable_route_machine") + noEnabledRoutes, err := app.GetEnabledNodeRoutes( + "test", + "test_enable_route_machine", + ) c.Assert(err, check.IsNil) c.Assert(len(noEnabledRoutes), check.Equals, 0) diff --git a/sharing_test.go b/sharing_test.go index b1806213..8d4ee2c9 100644 --- a/sharing_test.go +++ b/sharing_test.go @@ -325,7 +325,9 @@ func (s *Suite) TestDeleteSharedMachine(c *check.C) { c.Assert(err, check.IsNil) c.Assert(len(peersOfMachine3), check.Equals, 0) // node 3 is alone - sharedMachinesInNamespace1, err := app.ListSharedMachinesInNamespace(namespace1.Name) + sharedMachinesInNamespace1, err := app.ListSharedMachinesInNamespace( + namespace1.Name, + ) c.Assert(err, check.IsNil) c.Assert(len(sharedMachinesInNamespace1), check.Equals, 1) From 0c45f8d2525d895079ead681efa3612470888174 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Mon, 15 Nov 2021 16:26:41 +0000 Subject: [PATCH 156/300] Add and fix errorlint --- .golangci.yaml | 3 +-- cmd/headscale/cli/utils.go | 2 +- machine.go | 4 ++-- utils.go | 2 +- 4 files changed, 5 insertions(+), 6 deletions(-) diff --git a/.golangci.yaml b/.golangci.yaml index 72bab980..982c98bb 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -29,11 +29,9 @@ linters: - gocritic # We should strive to enable these: - - testpackage - stylecheck - wrapcheck - goerr113 - - errorlint - forcetypeassert - errname - gosec @@ -46,6 +44,7 @@ linters: - cyclop - nestif - wsl # might be incompatible with gofumpt + - testpackage linters-settings: varnamelen: diff --git a/cmd/headscale/cli/utils.go b/cmd/headscale/cli/utils.go index ad49c013..f60a72c5 100644 --- a/cmd/headscale/cli/utils.go +++ b/cmd/headscale/cli/utils.go @@ -53,7 +53,7 @@ func LoadConfig(path string) error { viper.SetDefault("cli.timeout", "5s") if err := viper.ReadInConfig(); err != nil { - return fmt.Errorf("Fatal error reading config file: %s \n", err) + return fmt.Errorf("Fatal error reading config file: %w", err) } // Collect any validation errors and return them all at once diff --git a/machine.go b/machine.go index 4dc9cd99..b0c003fd 100644 --- a/machine.go +++ b/machine.go @@ -284,7 +284,7 @@ func (h *Headscale) UpdateMachine(machine *Machine) error { // DeleteMachine softs deletes a Machine from the database. func (h *Headscale) DeleteMachine(machine *Machine) error { err := h.RemoveSharedMachineFromAllNamespaces(machine) - if err != nil && err != errorMachineNotShared { + if err != nil && errors.Is(err, errorMachineNotShared) { return err } @@ -301,7 +301,7 @@ func (h *Headscale) DeleteMachine(machine *Machine) error { // HardDeleteMachine hard deletes a Machine from the database. func (h *Headscale) HardDeleteMachine(machine *Machine) error { err := h.RemoveSharedMachineFromAllNamespaces(machine) - if err != nil && err != errorMachineNotShared { + if err != nil && errors.Is(err, errorMachineNotShared) { return err } diff --git a/utils.go b/utils.go index 803cfc5d..e291703a 100644 --- a/utils.go +++ b/utils.go @@ -46,7 +46,7 @@ func decodeMsg( } // fmt.Println(string(decrypted)) if err := json.Unmarshal(decrypted, output); err != nil { - return fmt.Errorf("response: %v", err) + return fmt.Errorf("response: %w", err) } return nil From 0c005a6b012816cbf91e717abfd04af2b5170b33 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Mon, 15 Nov 2021 16:33:16 +0000 Subject: [PATCH 157/300] Add and fix errname --- .golangci.yaml | 1 - acls.go | 30 +++++++++++++++--------------- acls_test.go | 2 +- machine.go | 4 ++-- namespaces.go | 18 +++++++++--------- namespaces_test.go | 10 +++++----- preauth_keys.go | 8 ++++---- preauth_keys_test.go | 6 +++--- sharing.go | 14 +++++++------- sharing_test.go | 8 ++++---- 10 files changed, 50 insertions(+), 51 deletions(-) diff --git a/.golangci.yaml b/.golangci.yaml index 982c98bb..08528b8f 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -33,7 +33,6 @@ linters: - wrapcheck - goerr113 - forcetypeassert - - errname - gosec - forbidigo - dupl diff --git a/acls.go b/acls.go index 01de114e..3f94663c 100644 --- a/acls.go +++ b/acls.go @@ -15,13 +15,13 @@ import ( ) const ( - errorEmptyPolicy = Error("empty policy") - errorInvalidAction = Error("invalid action") - errorInvalidUserSection = Error("invalid user section") - errorInvalidGroup = Error("invalid group") - errorInvalidTag = Error("invalid tag") - errorInvalidNamespace = Error("invalid namespace") - errorInvalidPortFormat = Error("invalid port format") + errEmptyPolicy = Error("empty policy") + errInvalidAction = Error("invalid action") + errInvalidUserSection = Error("invalid user section") + errInvalidGroup = Error("invalid group") + errInvalidTag = Error("invalid tag") + errInvalidNamespace = Error("invalid namespace") + errInvalidPortFormat = Error("invalid port format") ) const ( @@ -57,7 +57,7 @@ func (h *Headscale) LoadACLPolicy(path string) error { return err } if policy.IsZero() { - return errorEmptyPolicy + return errEmptyPolicy } h.aclPolicy = &policy @@ -75,7 +75,7 @@ func (h *Headscale) generateACLRules() ([]tailcfg.FilterRule, error) { for index, acl := range h.aclPolicy.ACLs { if acl.Action != "accept" { - return nil, errorInvalidAction + return nil, errInvalidAction } filterRule := tailcfg.FilterRule{} @@ -123,7 +123,7 @@ func (h *Headscale) generateACLPolicyDestPorts( ) ([]tailcfg.NetPortRange, error) { tokens := strings.Split(d, ":") if len(tokens) < EXPECTED_TOKEN_ITEMS || len(tokens) > 3 { - return nil, errorInvalidPortFormat + return nil, errInvalidPortFormat } var alias string @@ -169,13 +169,13 @@ func (h *Headscale) expandAlias(alias string) ([]string, error) { if strings.HasPrefix(alias, "group:") { if _, ok := h.aclPolicy.Groups[alias]; !ok { - return nil, errorInvalidGroup + return nil, errInvalidGroup } ips := []string{} for _, n := range h.aclPolicy.Groups[alias] { nodes, err := h.ListMachinesInNamespace(n) if err != nil { - return nil, errorInvalidNamespace + return nil, errInvalidNamespace } for _, node := range nodes { ips = append(ips, node.IPAddress) @@ -187,7 +187,7 @@ func (h *Headscale) expandAlias(alias string) ([]string, error) { if strings.HasPrefix(alias, "tag:") { if _, ok := h.aclPolicy.TagOwners[alias]; !ok { - return nil, errorInvalidTag + return nil, errInvalidTag } // This will have HORRIBLE performance. @@ -251,7 +251,7 @@ func (h *Headscale) expandAlias(alias string) ([]string, error) { return []string{cidr.String()}, nil } - return nil, errorInvalidUserSection + return nil, errInvalidUserSection } func (h *Headscale) expandPorts(portsStr string) (*[]tailcfg.PortRange, error) { @@ -290,7 +290,7 @@ func (h *Headscale) expandPorts(portsStr string) (*[]tailcfg.PortRange, error) { }) default: - return nil, errorInvalidPortFormat + return nil, errInvalidPortFormat } } diff --git a/acls_test.go b/acls_test.go index cca39ce8..3e051f5f 100644 --- a/acls_test.go +++ b/acls_test.go @@ -17,7 +17,7 @@ func (s *Suite) TestBrokenHuJson(c *check.C) { func (s *Suite) TestInvalidPolicyHuson(c *check.C) { err := app.LoadACLPolicy("./tests/acls/invalid.hujson") c.Assert(err, check.NotNil) - c.Assert(err, check.Equals, errorEmptyPolicy) + c.Assert(err, check.Equals, errEmptyPolicy) } func (s *Suite) TestParseHosts(c *check.C) { diff --git a/machine.go b/machine.go index b0c003fd..8aee68e3 100644 --- a/machine.go +++ b/machine.go @@ -284,7 +284,7 @@ func (h *Headscale) UpdateMachine(machine *Machine) error { // DeleteMachine softs deletes a Machine from the database. func (h *Headscale) DeleteMachine(machine *Machine) error { err := h.RemoveSharedMachineFromAllNamespaces(machine) - if err != nil && errors.Is(err, errorMachineNotShared) { + if err != nil && errors.Is(err, errMachineNotShared) { return err } @@ -301,7 +301,7 @@ func (h *Headscale) DeleteMachine(machine *Machine) error { // HardDeleteMachine hard deletes a Machine from the database. func (h *Headscale) HardDeleteMachine(machine *Machine) error { err := h.RemoveSharedMachineFromAllNamespaces(machine) - if err != nil && errors.Is(err, errorMachineNotShared) { + if err != nil && errors.Is(err, errMachineNotShared) { return err } diff --git a/namespaces.go b/namespaces.go index 858a7aaa..9ee7bf16 100644 --- a/namespaces.go +++ b/namespaces.go @@ -15,9 +15,9 @@ import ( ) const ( - errorNamespaceExists = Error("Namespace already exists") - errorNamespaceNotFound = Error("Namespace not found") - errorNamespaceNotEmptyOfNodes = Error("Namespace not empty: node(s) found") + errNamespaceExists = Error("Namespace already exists") + errNamespaceNotFound = Error("Namespace not found") + errNamespaceNotEmptyOfNodes = Error("Namespace not empty: node(s) found") ) // Namespace is the way Headscale implements the concept of users in Tailscale @@ -34,7 +34,7 @@ type Namespace struct { func (h *Headscale) CreateNamespace(name string) (*Namespace, error) { namespace := Namespace{} if err := h.db.Where("name = ?", name).First(&namespace).Error; err == nil { - return nil, errorNamespaceExists + return nil, errNamespaceExists } namespace.Name = name if err := h.db.Create(&namespace).Error; err != nil { @@ -54,7 +54,7 @@ func (h *Headscale) CreateNamespace(name string) (*Namespace, error) { func (h *Headscale) DestroyNamespace(name string) error { namespace, err := h.GetNamespace(name) if err != nil { - return errorNamespaceNotFound + return errNamespaceNotFound } machines, err := h.ListMachinesInNamespace(name) @@ -62,7 +62,7 @@ func (h *Headscale) DestroyNamespace(name string) error { return err } if len(machines) > 0 { - return errorNamespaceNotEmptyOfNodes + return errNamespaceNotEmptyOfNodes } keys, err := h.ListPreAuthKeys(name) @@ -92,9 +92,9 @@ func (h *Headscale) RenameNamespace(oldName, newName string) error { } _, err = h.GetNamespace(newName) if err == nil { - return errorNamespaceExists + return errNamespaceExists } - if !errors.Is(err, errorNamespaceNotFound) { + if !errors.Is(err, errNamespaceNotFound) { return err } @@ -119,7 +119,7 @@ func (h *Headscale) GetNamespace(name string) (*Namespace, error) { result.Error, gorm.ErrRecordNotFound, ) { - return nil, errorNamespaceNotFound + return nil, errNamespaceNotFound } return &namespace, nil diff --git a/namespaces_test.go b/namespaces_test.go index 7ac1f063..bbae98f9 100644 --- a/namespaces_test.go +++ b/namespaces_test.go @@ -24,7 +24,7 @@ func (s *Suite) TestCreateAndDestroyNamespace(c *check.C) { func (s *Suite) TestDestroyNamespaceErrors(c *check.C) { err := app.DestroyNamespace("test") - c.Assert(err, check.Equals, errorNamespaceNotFound) + c.Assert(err, check.Equals, errNamespaceNotFound) namespace, err := app.CreateNamespace("test") c.Assert(err, check.IsNil) @@ -59,7 +59,7 @@ func (s *Suite) TestDestroyNamespaceErrors(c *check.C) { app.db.Save(&machine) err = app.DestroyNamespace("test") - c.Assert(err, check.Equals, errorNamespaceNotEmptyOfNodes) + c.Assert(err, check.Equals, errNamespaceNotEmptyOfNodes) } func (s *Suite) TestRenameNamespace(c *check.C) { @@ -75,20 +75,20 @@ func (s *Suite) TestRenameNamespace(c *check.C) { c.Assert(err, check.IsNil) _, err = app.GetNamespace("test") - c.Assert(err, check.Equals, errorNamespaceNotFound) + c.Assert(err, check.Equals, errNamespaceNotFound) _, err = app.GetNamespace("test_renamed") c.Assert(err, check.IsNil) err = app.RenameNamespace("test_does_not_exit", "test") - c.Assert(err, check.Equals, errorNamespaceNotFound) + c.Assert(err, check.Equals, errNamespaceNotFound) namespaceTest2, err := app.CreateNamespace("test2") c.Assert(err, check.IsNil) c.Assert(namespaceTest2.Name, check.Equals, "test2") err = app.RenameNamespace("test2", "test_renamed") - c.Assert(err, check.Equals, errorNamespaceExists) + c.Assert(err, check.Equals, errNamespaceExists) } func (s *Suite) TestGetMapResponseUserProfiles(c *check.C) { diff --git a/preauth_keys.go b/preauth_keys.go index 742e06cf..5159a870 100644 --- a/preauth_keys.go +++ b/preauth_keys.go @@ -13,8 +13,8 @@ import ( ) const ( - errorAuthKeyNotFound = Error("AuthKey not found") - errorAuthKeyExpired = Error("AuthKey expired") + errPreAuthKeyNotFound = Error("AuthKey not found") + errPreAuthKeyExpired = Error("AuthKey expired") errSingleUseAuthKeyHasBeenUsed = Error("AuthKey has already been used") ) @@ -120,11 +120,11 @@ func (h *Headscale) checkKeyValidity(k string) (*PreAuthKey, error) { result.Error, gorm.ErrRecordNotFound, ) { - return nil, errorAuthKeyNotFound + return nil, errPreAuthKeyNotFound } if pak.Expiration != nil && pak.Expiration.Before(time.Now()) { - return nil, errorAuthKeyExpired + return nil, errPreAuthKeyExpired } if pak.Reusable || pak.Ephemeral { // we don't need to check if has been used before diff --git a/preauth_keys_test.go b/preauth_keys_test.go index 6a6a79b4..fd0feb03 100644 --- a/preauth_keys_test.go +++ b/preauth_keys_test.go @@ -44,13 +44,13 @@ func (*Suite) TestExpiredPreAuthKey(c *check.C) { c.Assert(err, check.IsNil) key, err := app.checkKeyValidity(pak.Key) - c.Assert(err, check.Equals, errorAuthKeyExpired) + c.Assert(err, check.Equals, errPreAuthKeyExpired) c.Assert(key, check.IsNil) } func (*Suite) TestPreAuthKeyDoesNotExist(c *check.C) { key, err := app.checkKeyValidity("potatoKey") - c.Assert(err, check.Equals, errorAuthKeyNotFound) + c.Assert(err, check.Equals, errPreAuthKeyNotFound) c.Assert(key, check.IsNil) } @@ -177,7 +177,7 @@ func (*Suite) TestExpirePreauthKey(c *check.C) { c.Assert(pak.Expiration, check.NotNil) key, err := app.checkKeyValidity(pak.Key) - c.Assert(err, check.Equals, errorAuthKeyExpired) + c.Assert(err, check.Equals, errPreAuthKeyExpired) c.Assert(key, check.IsNil) } diff --git a/sharing.go b/sharing.go index 741deb61..be1689d5 100644 --- a/sharing.go +++ b/sharing.go @@ -3,9 +3,9 @@ package headscale import "gorm.io/gorm" const ( - errorSameNamespace = Error("Destination namespace same as origin") - errorMachineAlreadyShared = Error("Node already shared to this namespace") - errorMachineNotShared = Error("Machine not shared to this namespace") + errSameNamespace = Error("Destination namespace same as origin") + errMachineAlreadyShared = Error("Node already shared to this namespace") + errMachineNotShared = Error("Machine not shared to this namespace") ) // SharedMachine is a join table to support sharing nodes between namespaces. @@ -23,7 +23,7 @@ func (h *Headscale) AddSharedMachineToNamespace( namespace *Namespace, ) error { if machine.NamespaceID == namespace.ID { - return errorSameNamespace + return errSameNamespace } sharedMachines := []SharedMachine{} @@ -31,7 +31,7 @@ func (h *Headscale) AddSharedMachineToNamespace( return err } if len(sharedMachines) > 0 { - return errorMachineAlreadyShared + return errMachineAlreadyShared } sharedMachine := SharedMachine{ @@ -52,7 +52,7 @@ func (h *Headscale) RemoveSharedMachineFromNamespace( ) error { if machine.NamespaceID == namespace.ID { // Can't unshare from primary namespace - return errorMachineNotShared + return errMachineNotShared } sharedMachine := SharedMachine{} @@ -64,7 +64,7 @@ func (h *Headscale) RemoveSharedMachineFromNamespace( } if result.RowsAffected == 0 { - return errorMachineNotShared + return errMachineNotShared } err := h.RequestMapUpdates(namespace.ID) diff --git a/sharing_test.go b/sharing_test.go index 8d4ee2c9..7ec1b0ee 100644 --- a/sharing_test.go +++ b/sharing_test.go @@ -80,7 +80,7 @@ func (s *Suite) TestSameNamespace(c *check.C) { c.Assert(len(peersOfMachine1BeforeShare), check.Equals, 0) err = app.AddSharedMachineToNamespace(machine1, namespace1) - c.Assert(err, check.Equals, errorSameNamespace) + c.Assert(err, check.Equals, errSameNamespace) } func (s *Suite) TestUnshare(c *check.C) { @@ -118,10 +118,10 @@ func (s *Suite) TestUnshare(c *check.C) { c.Assert(len(peersOfMachine1BeforeShare), check.Equals, 0) err = app.RemoveSharedMachineFromNamespace(machine2, namespace1) - c.Assert(err, check.Equals, errorMachineNotShared) + c.Assert(err, check.Equals, errMachineNotShared) err = app.RemoveSharedMachineFromNamespace(machine1, namespace1) - c.Assert(err, check.Equals, errorMachineNotShared) + c.Assert(err, check.Equals, errMachineNotShared) } func (s *Suite) TestAlreadyShared(c *check.C) { @@ -147,7 +147,7 @@ func (s *Suite) TestAlreadyShared(c *check.C) { err = app.AddSharedMachineToNamespace(machine2, namespace1) c.Assert(err, check.IsNil) err = app.AddSharedMachineToNamespace(machine2, namespace1) - c.Assert(err, check.Equals, errorMachineAlreadyShared) + c.Assert(err, check.Equals, errMachineAlreadyShared) } func (s *Suite) TestDoNotIncludeRoutesOnShared(c *check.C) { From 715542ac1c6134bac3bb234bf7fb28ebfc08ac5b Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Mon, 15 Nov 2021 17:24:24 +0000 Subject: [PATCH 158/300] Add and fix stylecheck (golint replacement) --- .golangci.yaml | 1 - acls.go | 24 ++++++++++++------------ acls_types.go | 6 +++--- api.go | 6 +++--- app.go | 24 ++++++++++++------------ apple_mobileconfig.go | 22 +++++++++++----------- cmd/headscale/cli/namespaces.go | 6 +++--- cmd/headscale/cli/nodes.go | 2 +- cmd/headscale/cli/preauthkeys.go | 4 ++-- cmd/headscale/cli/routes.go | 9 +++++---- cmd/headscale/cli/utils.go | 4 ++-- db.go | 6 +++--- derp.go | 4 ++-- dns.go | 6 +++--- grpcv1.go | 2 +- machine.go | 4 ++-- namespaces.go | 2 +- oidc.go | 20 ++++++++++---------- poll.go | 8 ++++---- preauth_keys.go | 2 +- utils.go | 4 ++-- 21 files changed, 83 insertions(+), 83 deletions(-) diff --git a/.golangci.yaml b/.golangci.yaml index 08528b8f..4902810c 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -29,7 +29,6 @@ linters: - gocritic # We should strive to enable these: - - stylecheck - wrapcheck - goerr113 - forcetypeassert diff --git a/acls.go b/acls.go index 3f94663c..1550c340 100644 --- a/acls.go +++ b/acls.go @@ -25,11 +25,11 @@ const ( ) const ( - PORT_RANGE_BEGIN = 0 - PORT_RANGE_END = 65535 - BASE_10 = 10 - BIT_SIZE_16 = 16 - EXPECTED_TOKEN_ITEMS = 2 + Base10 = 10 + BitSize16 = 16 + portRangeBegin = 0 + portRangeEnd = 65535 + expectedTokenItems = 2 ) // LoadACLPolicy loads the ACL policy from the specify path, and generates the ACL rules. @@ -122,7 +122,7 @@ func (h *Headscale) generateACLPolicyDestPorts( d string, ) ([]tailcfg.NetPortRange, error) { tokens := strings.Split(d, ":") - if len(tokens) < EXPECTED_TOKEN_ITEMS || len(tokens) > 3 { + if len(tokens) < expectedTokenItems || len(tokens) > 3 { return nil, errInvalidPortFormat } @@ -133,7 +133,7 @@ func (h *Headscale) generateACLPolicyDestPorts( // tag:montreal-webserver:80,443 // tag:api-server:443 // example-host-1:* - if len(tokens) == EXPECTED_TOKEN_ITEMS { + if len(tokens) == expectedTokenItems { alias = tokens[0] } else { alias = fmt.Sprintf("%s:%s", tokens[0], tokens[1]) @@ -257,7 +257,7 @@ func (h *Headscale) expandAlias(alias string) ([]string, error) { func (h *Headscale) expandPorts(portsStr string) (*[]tailcfg.PortRange, error) { if portsStr == "*" { return &[]tailcfg.PortRange{ - {First: PORT_RANGE_BEGIN, Last: PORT_RANGE_END}, + {First: portRangeBegin, Last: portRangeEnd}, }, nil } @@ -266,7 +266,7 @@ func (h *Headscale) expandPorts(portsStr string) (*[]tailcfg.PortRange, error) { rang := strings.Split(portStr, "-") switch len(rang) { case 1: - port, err := strconv.ParseUint(rang[0], BASE_10, BIT_SIZE_16) + port, err := strconv.ParseUint(rang[0], Base10, BitSize16) if err != nil { return nil, err } @@ -275,12 +275,12 @@ func (h *Headscale) expandPorts(portsStr string) (*[]tailcfg.PortRange, error) { Last: uint16(port), }) - case EXPECTED_TOKEN_ITEMS: - start, err := strconv.ParseUint(rang[0], BASE_10, BIT_SIZE_16) + case expectedTokenItems: + start, err := strconv.ParseUint(rang[0], Base10, BitSize16) if err != nil { return nil, err } - last, err := strconv.ParseUint(rang[1], BASE_10, BIT_SIZE_16) + last, err := strconv.ParseUint(rang[1], Base10, BitSize16) if err != nil { return nil, err } diff --git a/acls_types.go b/acls_types.go index f6557bfb..08e650ff 100644 --- a/acls_types.go +++ b/acls_types.go @@ -43,18 +43,18 @@ type ACLTest struct { // UnmarshalJSON allows to parse the Hosts directly into netaddr objects. func (hosts *Hosts) UnmarshalJSON(data []byte) error { newHosts := Hosts{} - hostIpPrefixMap := make(map[string]string) + hostIPPrefixMap := make(map[string]string) ast, err := hujson.Parse(data) if err != nil { return err } ast.Standardize() data = ast.Pack() - err = json.Unmarshal(data, &hostIpPrefixMap) + err = json.Unmarshal(data, &hostIPPrefixMap) if err != nil { return err } - for host, prefixStr := range hostIpPrefixMap { + for host, prefixStr := range hostIPPrefixMap { if !strings.Contains(prefixStr, "/") { prefixStr += "/32" } diff --git a/api.go b/api.go index fb8c49c4..85c28e3e 100644 --- a/api.go +++ b/api.go @@ -18,7 +18,7 @@ import ( "tailscale.com/types/wgkey" ) -const RESERVED_RESPONSE_HEADER_SIZE = 4 +const reservedResponseHeaderSize = 4 // KeyHandler provides the Headscale pub key // Listens in /key. @@ -367,7 +367,7 @@ func (h *Headscale) getMapResponse( } } // declare the incoming size on the first 4 bytes - data := make([]byte, RESERVED_RESPONSE_HEADER_SIZE) + data := make([]byte, reservedResponseHeaderSize) binary.LittleEndian.PutUint32(data, uint32(len(respBody))) data = append(data, respBody...) @@ -397,7 +397,7 @@ func (h *Headscale) getMapKeepAliveResponse( return nil, err } } - data := make([]byte, RESERVED_RESPONSE_HEADER_SIZE) + data := make([]byte, reservedResponseHeaderSize) binary.LittleEndian.PutUint32(data, uint32(len(respBody))) data = append(data, respBody...) diff --git a/app.go b/app.go index a0aa2385..17677d4c 100644 --- a/app.go +++ b/app.go @@ -47,11 +47,11 @@ import ( ) const ( - AUTH_PREFIX = "Bearer " - POSTGRESQL = "postgresql" - SQLITE = "sqlite3" - UPDATE_RATE_MILLISECONDS = 5000 - HTTP_READ_TIMEOUT = 30 * time.Second + AuthPrefix = "Bearer " + Postgres = "postgresql" + Sqlite = "sqlite3" + updateInterval = 5000 + HTTPReadTimeout = 30 * time.Second ) // Config contains the initial Headscale configuration. @@ -154,7 +154,7 @@ func NewHeadscale(cfg Config) (*Headscale, error) { var dbString string switch cfg.DBtype { - case POSTGRESQL: + case Postgres: dbString = fmt.Sprintf( "host=%s port=%d dbname=%s user=%s password=%s sslmode=disable", cfg.DBhost, @@ -163,7 +163,7 @@ func NewHeadscale(cfg Config) (*Headscale, error) { cfg.DBuser, cfg.DBpass, ) - case SQLITE: + case Sqlite: dbString = cfg.DBpath default: return nil, errors.New("unsupported DB") @@ -321,7 +321,7 @@ func (h *Headscale) grpcAuthenticationInterceptor(ctx context.Context, token := authHeader[0] - if !strings.HasPrefix(token, AUTH_PREFIX) { + if !strings.HasPrefix(token, AuthPrefix) { log.Error(). Caller(). Str("client_address", client.Addr.String()). @@ -363,7 +363,7 @@ func (h *Headscale) httpAuthenticationMiddleware(ctx *gin.Context) { authHeader := ctx.GetHeader("authorization") - if !strings.HasPrefix(authHeader, AUTH_PREFIX) { + if !strings.HasPrefix(authHeader, AuthPrefix) { log.Error(). Caller(). Str("client_address", ctx.ClientIP()). @@ -511,13 +511,13 @@ func (h *Headscale) Serve() error { } // I HATE THIS - go h.watchForKVUpdates(UPDATE_RATE_MILLISECONDS) - go h.expireEphemeralNodes(UPDATE_RATE_MILLISECONDS) + go h.watchForKVUpdates(updateInterval) + go h.expireEphemeralNodes(updateInterval) httpServer := &http.Server{ Addr: h.cfg.Addr, Handler: router, - ReadTimeout: HTTP_READ_TIMEOUT, + ReadTimeout: HTTPReadTimeout, // Go does not handle timeouts in HTTP very well, and there is // no good way to handle streaming timeouts, therefore we need to // keep this at unlimited and be careful to clean up connections diff --git a/apple_mobileconfig.go b/apple_mobileconfig.go index 8989c270..2e454df8 100644 --- a/apple_mobileconfig.go +++ b/apple_mobileconfig.go @@ -55,7 +55,7 @@ func (h *Headscale) AppleMobileConfig(ctx *gin.Context) {

Or

Use your terminal to configure the default setting for Tailscale by issuing:

- defaults write io.tailscale.ipn.macos ControlURL {{.Url}} + defaults write io.tailscale.ipn.macos ControlURL {{.URL}}

Restart Tailscale.app and log in.

@@ -63,7 +63,7 @@ func (h *Headscale) AppleMobileConfig(ctx *gin.Context) { `)) config := map[string]interface{}{ - "Url": h.cfg.ServerURL, + "URL": h.cfg.ServerURL, } var payload bytes.Buffer @@ -102,7 +102,7 @@ func (h *Headscale) ApplePlatformConfig(ctx *gin.Context) { return } - contentId, err := uuid.NewV4() + contentID, err := uuid.NewV4() if err != nil { log.Error(). Str("handler", "ApplePlatformConfig"). @@ -118,8 +118,8 @@ func (h *Headscale) ApplePlatformConfig(ctx *gin.Context) { } platformConfig := AppleMobilePlatformConfig{ - UUID: contentId, - Url: h.cfg.ServerURL, + UUID: contentID, + URL: h.cfg.ServerURL, } var payload bytes.Buffer @@ -165,7 +165,7 @@ func (h *Headscale) ApplePlatformConfig(ctx *gin.Context) { config := AppleMobileConfig{ UUID: id, - Url: h.cfg.ServerURL, + URL: h.cfg.ServerURL, Payload: payload.String(), } @@ -193,13 +193,13 @@ func (h *Headscale) ApplePlatformConfig(ctx *gin.Context) { type AppleMobileConfig struct { UUID uuid.UUID - Url string + URL string Payload string } type AppleMobilePlatformConfig struct { UUID uuid.UUID - Url string + URL string } var commonTemplate = template.Must( @@ -212,7 +212,7 @@ var commonTemplate = template.Must( PayloadDisplayName Headscale PayloadDescription - Configure Tailscale login server to: {{.Url}} + Configure Tailscale login server to: {{.URL}} PayloadIdentifier com.github.juanfont.headscale PayloadRemovalDisallowed @@ -243,7 +243,7 @@ var iosTemplate = template.Must(template.New("iosTemplate").Parse(` ControlURL - {{.Url}} + {{.URL}}
`)) @@ -261,6 +261,6 @@ var macosTemplate = template.Must(template.New("macosTemplate").Parse(` ControlURL - {{.Url}} + {{.URL}} `)) diff --git a/cmd/headscale/cli/namespaces.go b/cmd/headscale/cli/namespaces.go index 8c6f10ad..28958ecd 100644 --- a/cmd/headscale/cli/namespaces.go +++ b/cmd/headscale/cli/namespaces.go @@ -29,7 +29,7 @@ var createNamespaceCmd = &cobra.Command{ Short: "Creates a new namespace", Args: func(cmd *cobra.Command, args []string) error { if len(args) < 1 { - return fmt.Errorf("Missing parameters") + return fmt.Errorf("missing parameters") } return nil @@ -71,7 +71,7 @@ var destroyNamespaceCmd = &cobra.Command{ Short: "Destroys a namespace", Args: func(cmd *cobra.Command, args []string) error { if len(args) < 1 { - return fmt.Errorf("Missing parameters") + return fmt.Errorf("missing parameters") } return nil @@ -197,7 +197,7 @@ var renameNamespaceCmd = &cobra.Command{ Args: func(cmd *cobra.Command, args []string) error { expectedArguments := 2 if len(args) < expectedArguments { - return fmt.Errorf("Missing parameters") + return fmt.Errorf("missing parameters") } return nil diff --git a/cmd/headscale/cli/nodes.go b/cmd/headscale/cli/nodes.go index c644ad9e..218d25bd 100644 --- a/cmd/headscale/cli/nodes.go +++ b/cmd/headscale/cli/nodes.go @@ -451,7 +451,7 @@ func nodesToPtables( tableData = append( tableData, []string{ - strconv.FormatUint(machine.Id, headscale.BASE_10), + strconv.FormatUint(machine.Id, headscale.Base10), machine.Name, nodeKey.ShortString(), namespace, diff --git a/cmd/headscale/cli/preauthkeys.go b/cmd/headscale/cli/preauthkeys.go index b28e6003..d14193f6 100644 --- a/cmd/headscale/cli/preauthkeys.go +++ b/cmd/headscale/cli/preauthkeys.go @@ -13,7 +13,7 @@ import ( ) const ( - DEFAULT_PRE_AUTH_KEY_EXPIRY = 24 * time.Hour + DefaultPreAuthKeyExpiry = 24 * time.Hour ) func init() { @@ -31,7 +31,7 @@ func init() { createPreAuthKeyCmd.PersistentFlags(). Bool("ephemeral", false, "Preauthkey for ephemeral nodes") createPreAuthKeyCmd.Flags(). - DurationP("expiration", "e", DEFAULT_PRE_AUTH_KEY_EXPIRY, "Human-readable expiration of the key (30m, 24h, 365d...)") + DurationP("expiration", "e", DefaultPreAuthKeyExpiry, "Human-readable expiration of the key (30m, 24h, 365d...)") } var preauthkeysCmd = &cobra.Command{ diff --git a/cmd/headscale/cli/routes.go b/cmd/headscale/cli/routes.go index 7d0fcbf3..ced1a0bf 100644 --- a/cmd/headscale/cli/routes.go +++ b/cmd/headscale/cli/routes.go @@ -45,7 +45,7 @@ var listRoutesCmd = &cobra.Command{ Run: func(cmd *cobra.Command, args []string) { output, _ := cmd.Flags().GetString("output") - machineId, err := cmd.Flags().GetUint64("identifier") + machineID, err := cmd.Flags().GetUint64("identifier") if err != nil { ErrorOutput( err, @@ -61,7 +61,7 @@ var listRoutesCmd = &cobra.Command{ defer conn.Close() request := &v1.GetMachineRouteRequest{ - MachineId: machineId, + MachineId: machineID, } response, err := client.GetMachineRoute(ctx, request) @@ -111,7 +111,8 @@ omit the route you do not want to enable. `, Run: func(cmd *cobra.Command, args []string) { output, _ := cmd.Flags().GetString("output") - machineId, err := cmd.Flags().GetUint64("identifier") + + machineID, err := cmd.Flags().GetUint64("identifier") if err != nil { ErrorOutput( err, @@ -138,7 +139,7 @@ omit the route you do not want to enable. defer conn.Close() request := &v1.EnableMachineRoutesRequest{ - MachineId: machineId, + MachineId: machineID, Routes: routes, } diff --git a/cmd/headscale/cli/utils.go b/cmd/headscale/cli/utils.go index f60a72c5..a90a3c06 100644 --- a/cmd/headscale/cli/utils.go +++ b/cmd/headscale/cli/utils.go @@ -53,7 +53,7 @@ func LoadConfig(path string) error { viper.SetDefault("cli.timeout", "5s") if err := viper.ReadInConfig(); err != nil { - return fmt.Errorf("Fatal error reading config file: %w", err) + return fmt.Errorf("fatal error reading config file: %w", err) } // Collect any validation errors and return them all at once @@ -306,7 +306,7 @@ func getHeadscaleApp() (*headscale.Headscale, error) { minInactivityTimeout, _ := time.ParseDuration("65s") if viper.GetDuration("ephemeral_node_inactivity_timeout") <= minInactivityTimeout { err := fmt.Errorf( - "ephemeral_node_inactivity_timeout (%s) is set too low, must be more than %s\n", + "ephemeral_node_inactivity_timeout (%s) is set too low, must be more than %s", viper.GetString("ephemeral_node_inactivity_timeout"), minInactivityTimeout, ) diff --git a/db.go b/db.go index fa200604..503eedcf 100644 --- a/db.go +++ b/db.go @@ -24,7 +24,7 @@ func (h *Headscale) initDB() error { } h.db = db - if h.dbType == POSTGRESQL { + if h.dbType == Postgres { db.Exec("create extension if not exists \"uuid-ossp\";") } err = db.AutoMigrate(&Machine{}) @@ -66,12 +66,12 @@ func (h *Headscale) openDB() (*gorm.DB, error) { } switch h.dbType { - case SQLITE: + case Sqlite: db, err = gorm.Open(sqlite.Open(h.dbString), &gorm.Config{ DisableForeignKeyConstraintWhenMigrating: true, Logger: log, }) - case POSTGRESQL: + case Postgres: db, err = gorm.Open(postgres.Open(h.dbString), &gorm.Config{ DisableForeignKeyConstraintWhenMigrating: true, Logger: log, diff --git a/derp.go b/derp.go index cf128a88..63e448db 100644 --- a/derp.go +++ b/derp.go @@ -32,7 +32,7 @@ func loadDERPMapFromPath(path string) (*tailcfg.DERPMap, error) { } func loadDERPMapFromURL(addr url.URL) (*tailcfg.DERPMap, error) { - ctx, cancel := context.WithTimeout(context.Background(), HTTP_READ_TIMEOUT) + ctx, cancel := context.WithTimeout(context.Background(), HTTPReadTimeout) defer cancel() req, err := http.NewRequestWithContext(ctx, "GET", addr.String(), nil) @@ -41,7 +41,7 @@ func loadDERPMapFromURL(addr url.URL) (*tailcfg.DERPMap, error) { } client := http.Client{ - Timeout: HTTP_READ_TIMEOUT, + Timeout: HTTPReadTimeout, } resp, err := client.Do(req) diff --git a/dns.go b/dns.go index cb986cf0..af6f989d 100644 --- a/dns.go +++ b/dns.go @@ -11,7 +11,7 @@ import ( ) const ( - BYTE_SIZE = 8 + ByteSize = 8 ) // generateMagicDNSRootDomains generates a list of DNS entries to be included in `Routes` in `MapResponse`. @@ -47,10 +47,10 @@ func generateMagicDNSRootDomains( maskBits, _ := netRange.Mask.Size() // lastOctet is the last IP byte covered by the mask - lastOctet := maskBits / BYTE_SIZE + lastOctet := maskBits / ByteSize // wildcardBits is the number of bits not under the mask in the lastOctet - wildcardBits := BYTE_SIZE - maskBits%BYTE_SIZE + wildcardBits := ByteSize - maskBits%ByteSize // min is the value in the lastOctet byte of the IP // max is basically 2^wildcardBits - i.e., the value when all the wildcardBits are set to 1 diff --git a/grpcv1.go b/grpcv1.go index 4366446a..40419c3c 100644 --- a/grpcv1.go +++ b/grpcv1.go @@ -338,7 +338,7 @@ func (api headscaleV1APIServer) DebugCreateMachine( return nil, err } - routes, err := stringToIpPrefix(request.GetRoutes()) + routes, err := stringToIPPrefix(request.GetRoutes()) if err != nil { return nil, err } diff --git a/machine.go b/machine.go index 8aee68e3..be6d4467 100644 --- a/machine.go +++ b/machine.go @@ -529,7 +529,7 @@ func (machine Machine) toNode( node := tailcfg.Node{ ID: tailcfg.NodeID(machine.ID), // this is the actual ID StableID: tailcfg.StableNodeID( - strconv.FormatUint(machine.ID, BASE_10), + strconv.FormatUint(machine.ID, Base10), ), // in headscale, unlike tailcontrol server, IDs are permanent Name: hostname, User: tailcfg.UserID(machine.NamespaceID), @@ -736,7 +736,7 @@ func (h *Headscale) EnableRoutes(machine *Machine, routeStrs ...string) error { } for _, newRoute := range newRoutes { - if !containsIpPrefix(availableRoutes, newRoute) { + if !containsIPPrefix(availableRoutes, newRoute) { return fmt.Errorf( "route (%s) is not available on node %s", machine.Name, diff --git a/namespaces.go b/namespaces.go index 9ee7bf16..bb58c000 100644 --- a/namespaces.go +++ b/namespaces.go @@ -321,7 +321,7 @@ func getMapResponseUserProfiles(machine Machine, peers Machines) []tailcfg.UserP func (n *Namespace) toProto() *v1.Namespace { return &v1.Namespace{ - Id: strconv.FormatUint(uint64(n.ID), BASE_10), + Id: strconv.FormatUint(uint64(n.ID), Base10), Name: n.Name, CreatedAt: timestamppb.New(n.CreatedAt), } diff --git a/oidc.go b/oidc.go index 7e24ed3f..07561e8a 100644 --- a/oidc.go +++ b/oidc.go @@ -18,9 +18,9 @@ import ( ) const ( - OIDC_STATE_CACHE_EXPIRATION = time.Minute * 5 - OIDC_STATE_CACHE_CLEANUP_INTERVAL = time.Minute * 10 - RANDOM_BYTE_SIZE = 16 + oidcStateCacheExpiration = time.Minute * 5 + oidcStateCacheCleanupInterval = time.Minute * 10 + randomByteSize = 16 ) type IDTokenClaims struct { @@ -57,8 +57,8 @@ func (h *Headscale) initOIDC() error { // init the state cache if it hasn't been already if h.oidcStateCache == nil { h.oidcStateCache = cache.New( - OIDC_STATE_CACHE_EXPIRATION, - OIDC_STATE_CACHE_CLEANUP_INTERVAL, + oidcStateCacheExpiration, + oidcStateCacheCleanupInterval, ) } @@ -76,7 +76,7 @@ func (h *Headscale) RegisterOIDC(ctx *gin.Context) { return } - randomBlob := make([]byte, RANDOM_BYTE_SIZE) + randomBlob := make([]byte, randomByteSize) if _, err := rand.Read(randomBlob); err != nil { log.Error().Msg("could not read 16 bytes from rand") ctx.String(http.StatusInternalServerError, "could not read 16 bytes from rand") @@ -87,12 +87,12 @@ func (h *Headscale) RegisterOIDC(ctx *gin.Context) { stateStr := hex.EncodeToString(randomBlob)[:32] // place the machine key into the state cache, so it can be retrieved later - h.oidcStateCache.Set(stateStr, mKeyStr, OIDC_STATE_CACHE_EXPIRATION) + h.oidcStateCache.Set(stateStr, mKeyStr, oidcStateCacheExpiration) - authUrl := h.oauth2Config.AuthCodeURL(stateStr) - log.Debug().Msgf("Redirecting to %s for authentication", authUrl) + authURL := h.oauth2Config.AuthCodeURL(stateStr) + log.Debug().Msgf("Redirecting to %s for authentication", authURL) - ctx.Redirect(http.StatusFound, authUrl) + ctx.Redirect(http.StatusFound, authURL) } // OIDCCallback handles the callback from the OIDC endpoint diff --git a/poll.go b/poll.go index aaf5bd0b..9cf14e7a 100644 --- a/poll.go +++ b/poll.go @@ -16,8 +16,8 @@ import ( ) const ( - KEEP_ALIVE_INTERVAL = 60 * time.Second - UPDATE_CHECK_INTERVAL = 10 * time.Second + keepAliveInterval = 60 * time.Second + updateCheckInterval = 10 * time.Second ) // PollNetMapHandler takes care of /machine/:id/map @@ -495,8 +495,8 @@ func (h *Headscale) scheduledPollWorker( mapRequest tailcfg.MapRequest, machine *Machine, ) { - keepAliveTicker := time.NewTicker(KEEP_ALIVE_INTERVAL) - updateCheckerTicker := time.NewTicker(UPDATE_CHECK_INTERVAL) + keepAliveTicker := time.NewTicker(keepAliveInterval) + updateCheckerTicker := time.NewTicker(updateCheckInterval) for { select { diff --git a/preauth_keys.go b/preauth_keys.go index 5159a870..9ba70da3 100644 --- a/preauth_keys.go +++ b/preauth_keys.go @@ -156,7 +156,7 @@ func (h *Headscale) generateKey() (string, error) { func (key *PreAuthKey) toProto() *v1.PreAuthKey { protoKey := v1.PreAuthKey{ Namespace: key.Namespace.Name, - Id: strconv.FormatUint(key.ID, BASE_10), + Id: strconv.FormatUint(key.ID, Base10), Key: key.Key, Ephemeral: key.Ephemeral, Reusable: key.Reusable, diff --git a/utils.go b/utils.go index e291703a..6d62667d 100644 --- a/utils.go +++ b/utils.go @@ -197,7 +197,7 @@ func ipPrefixToString(prefixes []netaddr.IPPrefix) []string { return result } -func stringToIpPrefix(prefixes []string) ([]netaddr.IPPrefix, error) { +func stringToIPPrefix(prefixes []string) ([]netaddr.IPPrefix, error) { result := make([]netaddr.IPPrefix, len(prefixes)) for index, prefixStr := range prefixes { @@ -212,7 +212,7 @@ func stringToIpPrefix(prefixes []string) ([]netaddr.IPPrefix, error) { return result, nil } -func containsIpPrefix(prefixes []netaddr.IPPrefix, prefix netaddr.IPPrefix) bool { +func containsIPPrefix(prefixes []netaddr.IPPrefix, prefix netaddr.IPPrefix) bool { for _, p := range prefixes { if prefix == p { return true From c4d4c9c4e4a34f365bf25113cdb2634ba22d9230 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Mon, 15 Nov 2021 18:31:52 +0000 Subject: [PATCH 159/300] Add and fix gosec --- .golangci.yaml | 1 - app.go | 10 ++++++---- cmd/headscale/headscale_test.go | 2 +- namespaces.go | 2 +- preauth_keys.go | 4 ++-- 5 files changed, 10 insertions(+), 9 deletions(-) diff --git a/.golangci.yaml b/.golangci.yaml index 4902810c..476c1c24 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -32,7 +32,6 @@ linters: - wrapcheck - goerr113 - forcetypeassert - - gosec - forbidigo - dupl - makezero diff --git a/app.go b/app.go index 17677d4c..d4dc8e71 100644 --- a/app.go +++ b/app.go @@ -638,10 +638,12 @@ func (h *Headscale) getTLSSettings() (*tls.Config, error) { if !strings.HasPrefix(h.cfg.ServerURL, "https://") { log.Warn().Msg("Listening with TLS but ServerURL does not start with https://") } - tlsConfig := &tls.Config{} - tlsConfig.ClientAuth = tls.RequireAnyClientCert - tlsConfig.NextProtos = []string{"http/1.1"} - tlsConfig.Certificates = make([]tls.Certificate, 1) + tlsConfig := &tls.Config{ + ClientAuth: tls.RequireAnyClientCert, + NextProtos: []string{"http/1.1"}, + Certificates: make([]tls.Certificate, 1), + MinVersion: tls.VersionTLS12, + } tlsConfig.Certificates[0], err = tls.LoadX509KeyPair(h.cfg.TLSCertPath, h.cfg.TLSKeyPath) return tlsConfig, err diff --git a/cmd/headscale/headscale_test.go b/cmd/headscale/headscale_test.go index ceee3e44..0d1b9a13 100644 --- a/cmd/headscale/headscale_test.go +++ b/cmd/headscale/headscale_test.go @@ -100,7 +100,7 @@ func (*Suite) TestDNSConfigLoading(c *check.C) { func writeConfig(c *check.C, tmpDir string, configYaml []byte) { // Populate a custom config file configFile := filepath.Join(tmpDir, "config.yaml") - err := ioutil.WriteFile(configFile, configYaml, 0o644) + err := ioutil.WriteFile(configFile, configYaml, 0o600) if err != nil { c.Fatalf("Couldn't write file %s", configFile) } diff --git a/namespaces.go b/namespaces.go index bb58c000..e512068d 100644 --- a/namespaces.go +++ b/namespaces.go @@ -70,7 +70,7 @@ func (h *Headscale) DestroyNamespace(name string) error { return err } for _, key := range keys { - err = h.DestroyPreAuthKey(&key) + err = h.DestroyPreAuthKey(key) if err != nil { return err } diff --git a/preauth_keys.go b/preauth_keys.go index 9ba70da3..2d242c55 100644 --- a/preauth_keys.go +++ b/preauth_keys.go @@ -95,8 +95,8 @@ func (h *Headscale) GetPreAuthKey(namespace string, key string) (*PreAuthKey, er // DestroyPreAuthKey destroys a preauthkey. Returns error if the PreAuthKey // does not exist. -func (h *Headscale) DestroyPreAuthKey(pak *PreAuthKey) error { - if result := h.db.Unscoped().Delete(&pak); result.Error != nil { +func (h *Headscale) DestroyPreAuthKey(pak PreAuthKey) error { + if result := h.db.Unscoped().Delete(pak); result.Error != nil { return result.Error } From db8be91d8b0925459fbb3a8acfc5f97dfde7d727 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Mon, 15 Nov 2021 18:36:02 +0000 Subject: [PATCH 160/300] Add and fix forbidigo --- .golangci.yaml | 1 - cmd/headscale/cli/utils.go | 2 ++ cmd/headscale/headscale.go | 1 + cmd/headscale/headscale_test.go | 3 --- 4 files changed, 3 insertions(+), 4 deletions(-) diff --git a/.golangci.yaml b/.golangci.yaml index 476c1c24..0a1b9dc2 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -32,7 +32,6 @@ linters: - wrapcheck - goerr113 - forcetypeassert - - forbidigo - dupl - makezero - paralleltest diff --git a/cmd/headscale/cli/utils.go b/cmd/headscale/cli/utils.go index a90a3c06..ed4b823c 100644 --- a/cmd/headscale/cli/utils.go +++ b/cmd/headscale/cli/utils.go @@ -415,11 +415,13 @@ func SuccessOutput(result interface{}, override string, outputFormat string) { log.Fatal().Err(err) } default: + //nolint fmt.Println(override) return } + //nolint fmt.Println(string(j)) } diff --git a/cmd/headscale/headscale.go b/cmd/headscale/headscale.go index f3352474..d6bf2166 100644 --- a/cmd/headscale/headscale.go +++ b/cmd/headscale/headscale.go @@ -72,6 +72,7 @@ func main() { } res, err := latest.Check(githubTag, cli.Version) if err == nil && res.Outdated { + //nolint fmt.Printf( "An updated version of Headscale has been found (%s vs. your current %s). Check it out https://github.com/juanfont/headscale/releases\n", res.Current, diff --git a/cmd/headscale/headscale_test.go b/cmd/headscale/headscale_test.go index 0d1b9a13..1166d489 100644 --- a/cmd/headscale/headscale_test.go +++ b/cmd/headscale/headscale_test.go @@ -1,7 +1,6 @@ package main import ( - "fmt" "io/ioutil" "os" "path/filepath" @@ -112,7 +111,6 @@ func (*Suite) TestTLSConfigValidation(c *check.C) { c.Fatal(err) } // defer os.RemoveAll(tmpDir) - fmt.Println(tmpDir) configYaml := []byte( "---\ntls_letsencrypt_hostname: \"example.com\"\ntls_letsencrypt_challenge_type: \"\"\ntls_cert_path: \"abc.pem\"", @@ -139,7 +137,6 @@ func (*Suite) TestTLSConfigValidation(c *check.C) { check.Matches, ".*Fatal config error: server_url must start with https:// or http://.*", ) - fmt.Println(tmp) // Check configuration validation errors (2) configYaml = []byte( From 25b790d025f07926e51ed8c37ed86c6691b29bf9 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Mon, 15 Nov 2021 18:42:44 +0000 Subject: [PATCH 161/300] Add and fix forcetypeassert --- .golangci.yaml | 3 +-- machine.go | 4 +++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.golangci.yaml b/.golangci.yaml index 0a1b9dc2..5ab873d4 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -31,16 +31,15 @@ linters: # We should strive to enable these: - wrapcheck - goerr113 - - forcetypeassert - dupl - makezero - - paralleltest # We might want to enable this, but it might be a lot of work - cyclop - nestif - wsl # might be incompatible with gofumpt - testpackage + - paralleltest linters-settings: varnamelen: diff --git a/machine.go b/machine.go index be6d4467..a728e28c 100644 --- a/machine.go +++ b/machine.go @@ -350,7 +350,9 @@ func (h *Headscale) isOutdated(machine *Machine) bool { namespaces := make([]string, namespaceSet.Size()) for index, namespace := range namespaceSet.List() { - namespaces[index] = namespace.(string) + if name, ok := namespace.(string); ok { + namespaces[index] = name + } } lastChange := h.getLastStateChange(namespaces...) From d6739386a026ed94cf1468f076cd4dbf309cca6c Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Mon, 15 Nov 2021 19:18:14 +0000 Subject: [PATCH 162/300] Get rid of dynamic errors --- .golangci.yaml | 1 - app.go | 9 +++++++-- cmd/headscale/cli/namespaces.go | 11 ++++++++--- cmd/headscale/cli/preauthkeys.go | 2 +- cmd/headscale/cli/utils.go | 3 +++ db.go | 7 +++++-- machine.go | 16 +++++++++++----- preauth_keys.go | 3 ++- routes.go | 7 +++++-- utils.go | 16 +++++++++++----- 10 files changed, 53 insertions(+), 22 deletions(-) diff --git a/.golangci.yaml b/.golangci.yaml index 5ab873d4..2defdc88 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -30,7 +30,6 @@ linters: # We should strive to enable these: - wrapcheck - - goerr113 - dupl - makezero diff --git a/app.go b/app.go index d4dc8e71..08b67fe0 100644 --- a/app.go +++ b/app.go @@ -52,6 +52,11 @@ const ( Sqlite = "sqlite3" updateInterval = 5000 HTTPReadTimeout = 30 * time.Second + + errUnsupportedDatabase = Error("unsupported DB") + errUnsupportedLetsEncryptChallengeType = Error( + "unknown value for Lets Encrypt challenge type", + ) ) // Config contains the initial Headscale configuration. @@ -166,7 +171,7 @@ func NewHeadscale(cfg Config) (*Headscale, error) { case Sqlite: dbString = cfg.DBpath default: - return nil, errors.New("unsupported DB") + return nil, errUnsupportedDatabase } app := Headscale{ @@ -626,7 +631,7 @@ func (h *Headscale) getTLSSettings() (*tls.Config, error) { return certManager.TLSConfig(), nil default: - return nil, errors.New("unknown value for TLSLetsEncryptChallengeType") + return nil, errUnsupportedLetsEncryptChallengeType } } else if h.cfg.TLSCertPath == "" { if !strings.HasPrefix(h.cfg.ServerURL, "http://") { diff --git a/cmd/headscale/cli/namespaces.go b/cmd/headscale/cli/namespaces.go index 28958ecd..361e9be3 100644 --- a/cmd/headscale/cli/namespaces.go +++ b/cmd/headscale/cli/namespaces.go @@ -4,6 +4,7 @@ import ( "fmt" survey "github.com/AlecAivazis/survey/v2" + "github.com/juanfont/headscale" v1 "github.com/juanfont/headscale/gen/go/headscale/v1" "github.com/pterm/pterm" "github.com/rs/zerolog/log" @@ -19,6 +20,10 @@ func init() { namespaceCmd.AddCommand(renameNamespaceCmd) } +const ( + errMissingParameter = headscale.Error("missing parameters") +) + var namespaceCmd = &cobra.Command{ Use: "namespaces", Short: "Manage the namespaces of Headscale", @@ -29,7 +34,7 @@ var createNamespaceCmd = &cobra.Command{ Short: "Creates a new namespace", Args: func(cmd *cobra.Command, args []string) error { if len(args) < 1 { - return fmt.Errorf("missing parameters") + return errMissingParameter } return nil @@ -71,7 +76,7 @@ var destroyNamespaceCmd = &cobra.Command{ Short: "Destroys a namespace", Args: func(cmd *cobra.Command, args []string) error { if len(args) < 1 { - return fmt.Errorf("missing parameters") + return errMissingParameter } return nil @@ -197,7 +202,7 @@ var renameNamespaceCmd = &cobra.Command{ Args: func(cmd *cobra.Command, args []string) error { expectedArguments := 2 if len(args) < expectedArguments { - return fmt.Errorf("missing parameters") + return errMissingParameter } return nil diff --git a/cmd/headscale/cli/preauthkeys.go b/cmd/headscale/cli/preauthkeys.go index d14193f6..9d5c838f 100644 --- a/cmd/headscale/cli/preauthkeys.go +++ b/cmd/headscale/cli/preauthkeys.go @@ -178,7 +178,7 @@ var expirePreAuthKeyCmd = &cobra.Command{ Short: "Expire a preauthkey", Args: func(cmd *cobra.Command, args []string) error { if len(args) < 1 { - return fmt.Errorf("missing parameters") + return errMissingParameter } return nil diff --git a/cmd/headscale/cli/utils.go b/cmd/headscale/cli/utils.go index ed4b823c..958fb893 100644 --- a/cmd/headscale/cli/utils.go +++ b/cmd/headscale/cli/utils.go @@ -81,6 +81,7 @@ func LoadConfig(path string) error { errorText += "Fatal config error: server_url must start with https:// or http://\n" } if errorText != "" { + //nolint return errors.New(strings.TrimSuffix(errorText, "\n")) } else { return nil @@ -305,6 +306,8 @@ func getHeadscaleApp() (*headscale.Headscale, error) { // to avoid races minInactivityTimeout, _ := time.ParseDuration("65s") if viper.GetDuration("ephemeral_node_inactivity_timeout") <= minInactivityTimeout { + // TODO: Find a better way to return this text + //nolint err := fmt.Errorf( "ephemeral_node_inactivity_timeout (%s) is set too low, must be more than %s", viper.GetString("ephemeral_node_inactivity_timeout"), diff --git a/db.go b/db.go index 503eedcf..51363256 100644 --- a/db.go +++ b/db.go @@ -9,7 +9,10 @@ import ( "gorm.io/gorm/logger" ) -const dbVersion = "1" +const ( + dbVersion = "1" + errValueNotFound = Error("not found") +) // KV is a key-value store in a psql table. For future use... type KV struct { @@ -92,7 +95,7 @@ func (h *Headscale) getValue(key string) (string, error) { result.Error, gorm.ErrRecordNotFound, ) { - return "", errors.New("not found") + return "", errValueNotFound } return row.Value, nil diff --git a/machine.go b/machine.go index a728e28c..dcd79700 100644 --- a/machine.go +++ b/machine.go @@ -20,6 +20,12 @@ import ( "tailscale.com/types/wgkey" ) +const ( + errMachineNotFound = Error("machine not found") + errMachineAlreadyRegistered = Error("machine already registered") + errMachineRouteIsNotAvailable = Error("route is not available on machine") +) + // Machine is a Headscale client. type Machine struct { ID uint64 `gorm:"primary_key"` @@ -248,7 +254,7 @@ func (h *Headscale) GetMachine(namespace string, name string) (*Machine, error) } } - return nil, fmt.Errorf("machine not found") + return nil, errMachineNotFound } // GetMachineByID finds a Machine by ID and returns the Machine struct. @@ -615,7 +621,7 @@ func (h *Headscale) RegisterMachine( result.Error, gorm.ErrRecordNotFound, ) { - return nil, errors.New("Machine not found") + return nil, errMachineNotFound } log.Trace(). @@ -624,7 +630,7 @@ func (h *Headscale) RegisterMachine( Msg("Attempting to register machine") if machine.isAlreadyRegistered() { - err := errors.New("Machine already registered") + err := errMachineAlreadyRegistered log.Error(). Caller(). Err(err). @@ -740,9 +746,9 @@ func (h *Headscale) EnableRoutes(machine *Machine, routeStrs ...string) error { for _, newRoute := range newRoutes { if !containsIPPrefix(availableRoutes, newRoute) { return fmt.Errorf( - "route (%s) is not available on node %s", + "route (%s) is not available on node %s: %w", machine.Name, - newRoute, + newRoute, errMachineRouteIsNotAvailable, ) } } diff --git a/preauth_keys.go b/preauth_keys.go index 2d242c55..50bc4746 100644 --- a/preauth_keys.go +++ b/preauth_keys.go @@ -16,6 +16,7 @@ const ( errPreAuthKeyNotFound = Error("AuthKey not found") errPreAuthKeyExpired = Error("AuthKey expired") errSingleUseAuthKeyHasBeenUsed = Error("AuthKey has already been used") + errNamespaceMismatch = Error("namespace mismatch") ) // PreAuthKey describes a pre-authorization key usable in a particular namespace. @@ -87,7 +88,7 @@ func (h *Headscale) GetPreAuthKey(namespace string, key string) (*PreAuthKey, er } if pak.Namespace.Name != namespace { - return nil, errors.New("Namespace mismatch") + return nil, errNamespaceMismatch } return pak, nil diff --git a/routes.go b/routes.go index 9845b76d..448095a5 100644 --- a/routes.go +++ b/routes.go @@ -2,12 +2,15 @@ package headscale import ( "encoding/json" - "fmt" "gorm.io/datatypes" "inet.af/netaddr" ) +const ( + errRouteIsNotAvailable = Error("route is not available") +) + // Deprecated: use machine function instead // GetAdvertisedNodeRoutes returns the subnet routes advertised by a node (identified by // namespace and node name). @@ -129,7 +132,7 @@ func (h *Headscale) EnableNodeRoute( } if !available { - return fmt.Errorf("route (%s) is not available on node %s", nodeName, routeStr) + return errRouteIsNotAvailable } routes, err := json.Marshal(enabledRoutes) diff --git a/utils.go b/utils.go index 6d62667d..9f7849e2 100644 --- a/utils.go +++ b/utils.go @@ -20,6 +20,12 @@ import ( "tailscale.com/types/wgkey" ) +const ( + errCannotDecryptReponse = Error("cannot decrypt response") + errResponseMissingNonce = Error("response missing nonce") + errCouldNotAllocateIP = Error("could not find any suitable IP") +) + // Error is used to compare errors as per https://dave.cheney.net/2016/04/07/constant-errors type Error string @@ -46,7 +52,7 @@ func decodeMsg( } // fmt.Println(string(decrypted)) if err := json.Unmarshal(decrypted, output); err != nil { - return fmt.Errorf("response: %w", err) + return err } return nil @@ -55,7 +61,7 @@ func decodeMsg( func decryptMsg(msg []byte, pubKey *wgkey.Key, privKey *wgkey.Private) ([]byte, error) { var nonce [24]byte if len(msg) < len(nonce)+1 { - return nil, fmt.Errorf("response missing nonce, len=%d", len(msg)) + return nil, errResponseMissingNonce } copy(nonce[:], msg) msg = msg[len(nonce):] @@ -63,7 +69,7 @@ func decryptMsg(msg []byte, pubKey *wgkey.Key, privKey *wgkey.Private) ([]byte, pub, pri := (*[32]byte)(pubKey), (*[32]byte)(privKey) decrypted, ok := box.Open(nil, msg, &nonce, pub, pri) if !ok { - return nil, fmt.Errorf("cannot decrypt response") + return nil, errCannotDecryptReponse } return decrypted, nil @@ -106,7 +112,7 @@ func (h *Headscale) getAvailableIP() (*netaddr.IP, error) { for { if !ipPrefix.Contains(ip) { - return nil, fmt.Errorf("could not find any suitable IP in %s", ipPrefix) + return nil, errCouldNotAllocateIP } // Some OS (including Linux) does not like when IPs ends with 0 or 255, which @@ -143,7 +149,7 @@ func (h *Headscale) getUsedIPs() ([]netaddr.IP, error) { if addr != "" { ip, err := netaddr.ParseIP(addr) if err != nil { - return nil, fmt.Errorf("failed to parse ip from database, %w", err) + return nil, fmt.Errorf("failed to parse ip from database: %w", err) } ips[index] = ip From 7bc2f41b3363806f8d2fd8b547816587b0413457 Mon Sep 17 00:00:00 2001 From: ItalyPaleAle <43508+ItalyPaleAle@users.noreply.github.com> Date: Mon, 15 Nov 2021 15:37:40 -0800 Subject: [PATCH 163/300] =?UTF-8?q?Run=20prettier=20=F0=9F=92=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/Running.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/Running.md b/docs/Running.md index 05985e94..867c5ed2 100644 --- a/docs/Running.md +++ b/docs/Running.md @@ -34,7 +34,7 @@ ``` or b) Prepare a SQLite DB file: - + ```shell touch config/db.sqlite ``` @@ -115,7 +115,7 @@ systemctl start tailscaled ``` or Docker: - + ```shell docker run \ -v $(pwd)/config:/etc/headscale/ \ From f74b9f5fe27b2b22f05a5945b77e47300ee4a746 Mon Sep 17 00:00:00 2001 From: Fernando De Lucchi <69133647+fdelucchijr@users.noreply.github.com> Date: Wed, 17 Nov 2021 16:25:37 -0500 Subject: [PATCH 164/300] Styling and prettier --- .github/workflows/release.yml | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index be83a0e6..06bd3ccf 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -40,12 +40,10 @@ jobs: uses: actions/checkout@v2 with: fetch-depth: 0 - - name: Set up QEMU for multiple platforms uses: docker/setup-qemu-action@master with: platforms: arm64,amd64 - - name: Cache Docker layers uses: actions/cache@v2 with: @@ -53,7 +51,6 @@ jobs: key: ${{ runner.os }}-buildx-${{ github.sha }} restore-keys: | ${{ runner.os }}-buildx- - - name: Docker meta id: meta uses: docker/metadata-action@v3 @@ -67,20 +64,17 @@ jobs: type=semver,pattern={{major}}.{{minor}} type=semver,pattern={{major}} type=sha - - name: Login to DockerHub uses: docker/login-action@v1 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - - name: Login to GHCR uses: docker/login-action@v1 with: registry: ghcr.io username: ${{ github.repository_owner }} password: ${{ secrets.GITHUB_TOKEN }} - - name: Build and push id: docker_build uses: docker/build-push-action@v2 @@ -92,13 +86,11 @@ jobs: platforms: linux/amd64,linux/arm64 cache-from: type=local,src=/tmp/.buildx-cache cache-to: type=local,dest=/tmp/.buildx-cache-new - - name: Prepare cache for next build run: | rm -rf /tmp/.buildx-cache mv /tmp/.buildx-cache-new /tmp/.buildx-cache - docker-debug-release: runs-on: ubuntu-latest steps: @@ -110,7 +102,6 @@ jobs: uses: docker/setup-qemu-action@master with: platforms: arm64,amd64 - - name: Cache Docker layers uses: actions/cache@v2 with: @@ -118,7 +109,6 @@ jobs: key: ${{ runner.os }}-buildx-debug-${{ github.sha }} restore-keys: | ${{ runner.os }}-buildx-debug- - - name: Docker meta id: meta-debug uses: docker/metadata-action@v3 @@ -161,4 +151,4 @@ jobs: - name: Prepare cache for next build run: | rm -rf /tmp/.buildx-cache - mv /tmp/.buildx-cache-debug-new /tmp/.buildx-cache-debug \ No newline at end of file + mv /tmp/.buildx-cache-debug-new /tmp/.buildx-cache-debug From 35c3fe96083baaca8a1f25d1b8f42e3bfef4e5e9 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Wed, 17 Nov 2021 22:39:41 +0000 Subject: [PATCH 165/300] Move registration workflow into functions --- api.go | 352 +++++++++++++++++++++++++++++++++------------------------ 1 file changed, 206 insertions(+), 146 deletions(-) diff --git a/api.go b/api.go index 85c28e3e..367a0031 100644 --- a/api.go +++ b/api.go @@ -112,177 +112,41 @@ func (h *Headscale) RegistrationHandler(ctx *gin.Context) { } if !machine.Registered && req.Auth.AuthKey != "" { - h.handleAuthKey(ctx, h.db, machineKey, req, *machine) + h.handleAuthKey(ctx, machineKey, req, *machine) return } - resp := tailcfg.RegisterResponse{} - // We have the updated key! if machine.NodeKey == wgkey.Key(req.NodeKey).HexString() { // The client sends an Expiry in the past if the client is requesting to expire the key (aka logout) // https://github.com/tailscale/tailscale/blob/main/tailcfg/tailcfg.go#L648 if !req.Expiry.IsZero() && req.Expiry.UTC().Before(now) { - log.Info(). - Str("handler", "Registration"). - Str("machine", machine.Name). - Msg("Client requested logout") - - machine.Expiry = &req.Expiry // save the expiry so that the machine is marked as expired - h.db.Save(&machine) - - resp.AuthURL = "" - resp.MachineAuthorized = false - resp.User = *machine.Namespace.toUser() - respBody, err := encode(resp, &machineKey, h.privateKey) - if err != nil { - log.Error(). - Str("handler", "Registration"). - Err(err). - Msg("Cannot encode message") - ctx.String(http.StatusInternalServerError, "") - - return - } - ctx.Data(http.StatusOK, "application/json; charset=utf-8", respBody) + h.handleMachineLogOut(ctx, machineKey, req, *machine) return } if machine.Registered && machine.Expiry.UTC().After(now) { - // The machine registration is valid, respond with redirect to /map - log.Debug(). - Str("handler", "Registration"). - Str("machine", machine.Name). - Msg("Client is registered and we have the current NodeKey. All clear to /map") - - resp.AuthURL = "" - resp.MachineAuthorized = true - resp.User = *machine.Namespace.toUser() - resp.Login = *machine.Namespace.toLogin() - - respBody, err := encode(resp, &machineKey, h.privateKey) - if err != nil { - log.Error(). - Str("handler", "Registration"). - Err(err). - Msg("Cannot encode message") - machineRegistrations.WithLabelValues("update", "web", "error", machine.Namespace.Name). - Inc() - ctx.String(http.StatusInternalServerError, "") - - return - } - machineRegistrations.WithLabelValues("update", "web", "success", machine.Namespace.Name). - Inc() - ctx.Data(http.StatusOK, "application/json; charset=utf-8", respBody) + h.handleMachineValidRegistration(ctx, machineKey, req, *machine) return } - // The client has registered before, but has expired - log.Debug(). - Str("handler", "Registration"). - Str("machine", machine.Name). - Msg("Machine registration has expired. Sending a authurl to register") - - if h.cfg.OIDC.Issuer != "" { - resp.AuthURL = fmt.Sprintf("%s/oidc/register/%s", - strings.TrimSuffix(h.cfg.ServerURL, "/"), machineKey.HexString()) - } else { - resp.AuthURL = fmt.Sprintf("%s/register?key=%s", - strings.TrimSuffix(h.cfg.ServerURL, "/"), machineKey.HexString()) - } - - // When a client connects, it may request a specific expiry time in its - // RegisterRequest (https://github.com/tailscale/tailscale/blob/main/tailcfg/tailcfg.go#L634) - // RequestedExpiry is used to store the clients requested expiry time since the authentication flow is broken - // into two steps (which cant pass arbitrary data between them easily) and needs to be - // retrieved again after the user has authenticated. After the authentication flow - // completes, RequestedExpiry is copied into Expiry. - machine.RequestedExpiry = &req.Expiry - - h.db.Save(&machine) - - respBody, err := encode(resp, &machineKey, h.privateKey) - if err != nil { - log.Error(). - Str("handler", "Registration"). - Err(err). - Msg("Cannot encode message") - machineRegistrations.WithLabelValues("new", "web", "error", machine.Namespace.Name). - Inc() - ctx.String(http.StatusInternalServerError, "") - - return - } - machineRegistrations.WithLabelValues("new", "web", "success", machine.Namespace.Name). - Inc() - ctx.Data(http.StatusOK, "application/json; charset=utf-8", respBody) + h.handleMachineExpired(ctx, machineKey, req, *machine) return } // The NodeKey we have matches OldNodeKey, which means this is a refresh after a key expiration if machine.NodeKey == wgkey.Key(req.OldNodeKey).HexString() && - machine.Expiry.UTC().After(now) { - log.Debug(). - Str("handler", "Registration"). - Str("machine", machine.Name). - Msg("We have the OldNodeKey in the database. This is a key refresh") - machine.NodeKey = wgkey.Key(req.NodeKey).HexString() - h.db.Save(&machine) - - resp.AuthURL = "" - resp.User = *machine.Namespace.toUser() - respBody, err := encode(resp, &machineKey, h.privateKey) - if err != nil { - log.Error(). - Str("handler", "Registration"). - Err(err). - Msg("Cannot encode message") - ctx.String(http.StatusInternalServerError, "Extremely sad!") - - return - } - ctx.Data(http.StatusOK, "application/json; charset=utf-8", respBody) + !machine.isExpired() { + h.handleMachineRefreshKey(ctx, machineKey, req, *machine) return } - // The machine registration is new, redirect the client to the registration URL - log.Debug(). - Str("handler", "Registration"). - Str("machine", machine.Name). - Msg("The node is sending us a new NodeKey, sending auth url") - if h.cfg.OIDC.Issuer != "" { - resp.AuthURL = fmt.Sprintf( - "%s/oidc/register/%s", - strings.TrimSuffix(h.cfg.ServerURL, "/"), - machineKey.HexString(), - ) - } else { - resp.AuthURL = fmt.Sprintf("%s/register?key=%s", - strings.TrimSuffix(h.cfg.ServerURL, "/"), machineKey.HexString()) - } - - // save the requested expiry time for retrieval later in the authentication flow - machine.RequestedExpiry = &req.Expiry - machine.NodeKey = wgkey.Key(req.NodeKey).HexString() // save the NodeKey - h.db.Save(&machine) - - respBody, err := encode(resp, &machineKey, h.privateKey) - if err != nil { - log.Error(). - Str("handler", "Registration"). - Err(err). - Msg("Cannot encode message") - ctx.String(http.StatusInternalServerError, "") - - return - } - ctx.Data(http.StatusOK, "application/json; charset=utf-8", respBody) + h.handleMachineRegistrationNew(ctx, machineKey, req, *machine) } func (h *Headscale) getMapResponse( @@ -404,9 +268,205 @@ func (h *Headscale) getMapKeepAliveResponse( return data, nil } +func (h *Headscale) handleMachineLogOut( + ctx *gin.Context, + idKey wgkey.Key, + reqisterRequest tailcfg.RegisterRequest, + machine Machine, +) { + resp := tailcfg.RegisterResponse{} + + log.Info(). + Str("handler", "Registration"). + Str("machine", machine.Name). + Msg("Client requested logout") + + machine.Expiry = &reqisterRequest.Expiry // save the expiry so that the machine is marked as expired + h.db.Save(&machine) + + resp.AuthURL = "" + resp.MachineAuthorized = false + resp.User = *machine.Namespace.toUser() + respBody, err := encode(resp, &idKey, h.privateKey) + if err != nil { + log.Error(). + Str("handler", "Registration"). + Err(err). + Msg("Cannot encode message") + ctx.String(http.StatusInternalServerError, "") + + return + } + ctx.Data(http.StatusOK, "application/json; charset=utf-8", respBody) + + return +} + +func (h *Headscale) handleMachineValidRegistration( + ctx *gin.Context, + idKey wgkey.Key, + reqisterRequest tailcfg.RegisterRequest, + machine Machine, +) { + resp := tailcfg.RegisterResponse{} + + // The machine registration is valid, respond with redirect to /map + log.Debug(). + Str("handler", "Registration"). + Str("machine", machine.Name). + Msg("Client is registered and we have the current NodeKey. All clear to /map") + + resp.AuthURL = "" + resp.MachineAuthorized = true + resp.User = *machine.Namespace.toUser() + resp.Login = *machine.Namespace.toLogin() + + respBody, err := encode(resp, &idKey, h.privateKey) + if err != nil { + log.Error(). + Str("handler", "Registration"). + Err(err). + Msg("Cannot encode message") + machineRegistrations.WithLabelValues("update", "web", "error", machine.Namespace.Name). + Inc() + ctx.String(http.StatusInternalServerError, "") + + return + } + machineRegistrations.WithLabelValues("update", "web", "success", machine.Namespace.Name). + Inc() + ctx.Data(http.StatusOK, "application/json; charset=utf-8", respBody) + + return +} + +func (h *Headscale) handleMachineExpired( + ctx *gin.Context, + idKey wgkey.Key, + reqisterRequest tailcfg.RegisterRequest, + machine Machine, +) { + resp := tailcfg.RegisterResponse{} + + // The client has registered before, but has expired + log.Debug(). + Str("handler", "Registration"). + Str("machine", machine.Name). + Msg("Machine registration has expired. Sending a authurl to register") + + if h.cfg.OIDC.Issuer != "" { + resp.AuthURL = fmt.Sprintf("%s/oidc/register/%s", + strings.TrimSuffix(h.cfg.ServerURL, "/"), idKey.HexString()) + } else { + resp.AuthURL = fmt.Sprintf("%s/register?key=%s", + strings.TrimSuffix(h.cfg.ServerURL, "/"), idKey.HexString()) + } + + // When a client connects, it may request a specific expiry time in its + // RegisterRequest (https://github.com/tailscale/tailscale/blob/main/tailcfg/tailcfg.go#L634) + // RequestedExpiry is used to store the clients requested expiry time since the authentication flow is broken + // into two steps (which cant pass arbitrary data between them easily) and needs to be + // retrieved again after the user has authenticated. After the authentication flow + // completes, RequestedExpiry is copied into Expiry. + machine.RequestedExpiry = &reqisterRequest.Expiry + + h.db.Save(&machine) + + respBody, err := encode(resp, &idKey, h.privateKey) + if err != nil { + log.Error(). + Str("handler", "Registration"). + Err(err). + Msg("Cannot encode message") + machineRegistrations.WithLabelValues("new", "web", "error", machine.Namespace.Name). + Inc() + ctx.String(http.StatusInternalServerError, "") + + return + } + machineRegistrations.WithLabelValues("new", "web", "success", machine.Namespace.Name). + Inc() + ctx.Data(http.StatusOK, "application/json; charset=utf-8", respBody) + + return +} + +func (h *Headscale) handleMachineRefreshKey( + ctx *gin.Context, + idKey wgkey.Key, + reqisterRequest tailcfg.RegisterRequest, + machine Machine, +) { + resp := tailcfg.RegisterResponse{} + + log.Debug(). + Str("handler", "Registration"). + Str("machine", machine.Name). + Msg("We have the OldNodeKey in the database. This is a key refresh") + machine.NodeKey = wgkey.Key(reqisterRequest.NodeKey).HexString() + h.db.Save(&machine) + + resp.AuthURL = "" + resp.User = *machine.Namespace.toUser() + respBody, err := encode(resp, &idKey, h.privateKey) + if err != nil { + log.Error(). + Str("handler", "Registration"). + Err(err). + Msg("Cannot encode message") + ctx.String(http.StatusInternalServerError, "Extremely sad!") + + return + } + ctx.Data(http.StatusOK, "application/json; charset=utf-8", respBody) + + return +} + +func (h *Headscale) handleMachineRegistrationNew( + ctx *gin.Context, + idKey wgkey.Key, + reqisterRequest tailcfg.RegisterRequest, + machine Machine, +) { + resp := tailcfg.RegisterResponse{} + + // The machine registration is new, redirect the client to the registration URL + log.Debug(). + Str("handler", "Registration"). + Str("machine", machine.Name). + Msg("The node is sending us a new NodeKey, sending auth url") + if h.cfg.OIDC.Issuer != "" { + resp.AuthURL = fmt.Sprintf( + "%s/oidc/register/%s", + strings.TrimSuffix(h.cfg.ServerURL, "/"), + idKey.HexString(), + ) + } else { + resp.AuthURL = fmt.Sprintf("%s/register?key=%s", + strings.TrimSuffix(h.cfg.ServerURL, "/"), idKey.HexString()) + } + + // save the requested expiry time for retrieval later in the authentication flow + machine.RequestedExpiry = &reqisterRequest.Expiry + machine.NodeKey = wgkey.Key(reqisterRequest.NodeKey).HexString() // save the NodeKey + h.db.Save(&machine) + + respBody, err := encode(resp, &idKey, h.privateKey) + if err != nil { + log.Error(). + Str("handler", "Registration"). + Err(err). + Msg("Cannot encode message") + ctx.String(http.StatusInternalServerError, "") + + return + } + ctx.Data(http.StatusOK, "application/json; charset=utf-8", respBody) +} + func (h *Headscale) handleAuthKey( ctx *gin.Context, - db *gorm.DB, idKey wgkey.Key, reqisterRequest tailcfg.RegisterRequest, machine Machine, @@ -477,10 +537,10 @@ func (h *Headscale) handleAuthKey( // we update it just in case machine.Registered = true machine.RegisterMethod = "authKey" - db.Save(&machine) + h.db.Save(&machine) pak.Used = true - db.Save(&pak) + h.db.Save(&pak) resp.MachineAuthorized = true resp.User = *pak.Namespace.toUser() From a8a8f01429af9897b87d03235faa31197ee18c40 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Thu, 18 Nov 2021 08:49:55 +0000 Subject: [PATCH 166/300] Make "authKey" a constant --- acls_test.go | 4 ++-- api.go | 7 +++++-- dns_test.go | 16 ++++++++-------- machine_test.go | 10 +++++----- namespaces_test.go | 10 +++++----- preauth_keys_test.go | 6 +++--- routes_test.go | 4 ++-- sharing_test.go | 6 +++--- utils_test.go | 6 +++--- 9 files changed, 36 insertions(+), 33 deletions(-) diff --git a/acls_test.go b/acls_test.go index 3e051f5f..629ce1da 100644 --- a/acls_test.go +++ b/acls_test.go @@ -100,7 +100,7 @@ func (s *Suite) TestPortNamespace(c *check.C) { Name: "testmachine", NamespaceID: namespace.ID, Registered: true, - RegisterMethod: "authKey", + RegisterMethod: RegisterMethodAuthKey, IPAddress: ip.String(), AuthKeyID: uint(pak.ID), } @@ -142,7 +142,7 @@ func (s *Suite) TestPortGroup(c *check.C) { Name: "testmachine", NamespaceID: namespace.ID, Registered: true, - RegisterMethod: "authKey", + RegisterMethod: RegisterMethodAuthKey, IPAddress: ip.String(), AuthKeyID: uint(pak.ID), } diff --git a/api.go b/api.go index 367a0031..45b59d3c 100644 --- a/api.go +++ b/api.go @@ -18,7 +18,10 @@ import ( "tailscale.com/types/wgkey" ) -const reservedResponseHeaderSize = 4 +const ( + reservedResponseHeaderSize = 4 + RegisterMethodAuthKey = "authKey" +) // KeyHandler provides the Headscale pub key // Listens in /key. @@ -536,7 +539,7 @@ func (h *Headscale) handleAuthKey( HexString() // we update it just in case machine.Registered = true - machine.RegisterMethod = "authKey" + machine.RegisterMethod = RegisterMethodAuthKey h.db.Save(&machine) pak.Used = true diff --git a/dns_test.go b/dns_test.go index a2f7a652..92f7476f 100644 --- a/dns_test.go +++ b/dns_test.go @@ -123,7 +123,7 @@ func (s *Suite) TestDNSConfigMapResponseWithMagicDNS(c *check.C) { NamespaceID: namespaceShared1.ID, Namespace: *namespaceShared1, Registered: true, - RegisterMethod: "authKey", + RegisterMethod: RegisterMethodAuthKey, IPAddress: "100.64.0.1", AuthKeyID: uint(preAuthKeyInShared1.ID), } @@ -141,7 +141,7 @@ func (s *Suite) TestDNSConfigMapResponseWithMagicDNS(c *check.C) { NamespaceID: namespaceShared2.ID, Namespace: *namespaceShared2, Registered: true, - RegisterMethod: "authKey", + RegisterMethod: RegisterMethodAuthKey, IPAddress: "100.64.0.2", AuthKeyID: uint(preAuthKeyInShared2.ID), } @@ -159,7 +159,7 @@ func (s *Suite) TestDNSConfigMapResponseWithMagicDNS(c *check.C) { NamespaceID: namespaceShared3.ID, Namespace: *namespaceShared3, Registered: true, - RegisterMethod: "authKey", + RegisterMethod: RegisterMethodAuthKey, IPAddress: "100.64.0.3", AuthKeyID: uint(preAuthKeyInShared3.ID), } @@ -177,7 +177,7 @@ func (s *Suite) TestDNSConfigMapResponseWithMagicDNS(c *check.C) { NamespaceID: namespaceShared1.ID, Namespace: *namespaceShared1, Registered: true, - RegisterMethod: "authKey", + RegisterMethod: RegisterMethodAuthKey, IPAddress: "100.64.0.4", AuthKeyID: uint(PreAuthKey2InShared1.ID), } @@ -272,7 +272,7 @@ func (s *Suite) TestDNSConfigMapResponseWithoutMagicDNS(c *check.C) { NamespaceID: namespaceShared1.ID, Namespace: *namespaceShared1, Registered: true, - RegisterMethod: "authKey", + RegisterMethod: RegisterMethodAuthKey, IPAddress: "100.64.0.1", AuthKeyID: uint(preAuthKeyInShared1.ID), } @@ -290,7 +290,7 @@ func (s *Suite) TestDNSConfigMapResponseWithoutMagicDNS(c *check.C) { NamespaceID: namespaceShared2.ID, Namespace: *namespaceShared2, Registered: true, - RegisterMethod: "authKey", + RegisterMethod: RegisterMethodAuthKey, IPAddress: "100.64.0.2", AuthKeyID: uint(preAuthKeyInShared2.ID), } @@ -308,7 +308,7 @@ func (s *Suite) TestDNSConfigMapResponseWithoutMagicDNS(c *check.C) { NamespaceID: namespaceShared3.ID, Namespace: *namespaceShared3, Registered: true, - RegisterMethod: "authKey", + RegisterMethod: RegisterMethodAuthKey, IPAddress: "100.64.0.3", AuthKeyID: uint(preAuthKeyInShared3.ID), } @@ -326,7 +326,7 @@ func (s *Suite) TestDNSConfigMapResponseWithoutMagicDNS(c *check.C) { NamespaceID: namespaceShared1.ID, Namespace: *namespaceShared1, Registered: true, - RegisterMethod: "authKey", + RegisterMethod: RegisterMethodAuthKey, IPAddress: "100.64.0.4", AuthKeyID: uint(preAuthKey2InShared1.ID), } diff --git a/machine_test.go b/machine_test.go index cf367403..fdbc3cb5 100644 --- a/machine_test.go +++ b/machine_test.go @@ -25,7 +25,7 @@ func (s *Suite) TestGetMachine(c *check.C) { Name: "testmachine", NamespaceID: namespace.ID, Registered: true, - RegisterMethod: "authKey", + RegisterMethod: RegisterMethodAuthKey, AuthKeyID: uint(pak.ID), } app.db.Save(machine) @@ -55,7 +55,7 @@ func (s *Suite) TestGetMachineByID(c *check.C) { Name: "testmachine", NamespaceID: namespace.ID, Registered: true, - RegisterMethod: "authKey", + RegisterMethod: RegisterMethodAuthKey, AuthKeyID: uint(pak.ID), } app.db.Save(&machine) @@ -78,7 +78,7 @@ func (s *Suite) TestDeleteMachine(c *check.C) { Name: "testmachine", NamespaceID: namespace.ID, Registered: true, - RegisterMethod: "authKey", + RegisterMethod: RegisterMethodAuthKey, AuthKeyID: uint(1), } app.db.Save(&machine) @@ -113,7 +113,7 @@ func (s *Suite) TestHardDeleteMachine(c *check.C) { Name: "testmachine3", NamespaceID: namespace.ID, Registered: true, - RegisterMethod: "authKey", + RegisterMethod: RegisterMethodAuthKey, AuthKeyID: uint(1), } app.db.Save(&machine) @@ -144,7 +144,7 @@ func (s *Suite) TestGetDirectPeers(c *check.C) { Name: "testmachine" + strconv.Itoa(index), NamespaceID: namespace.ID, Registered: true, - RegisterMethod: "authKey", + RegisterMethod: RegisterMethodAuthKey, AuthKeyID: uint(pak.ID), } app.db.Save(&machine) diff --git a/namespaces_test.go b/namespaces_test.go index bbae98f9..9793e608 100644 --- a/namespaces_test.go +++ b/namespaces_test.go @@ -53,7 +53,7 @@ func (s *Suite) TestDestroyNamespaceErrors(c *check.C) { Name: "testmachine", NamespaceID: namespace.ID, Registered: true, - RegisterMethod: "authKey", + RegisterMethod: RegisterMethodAuthKey, AuthKeyID: uint(pak.ID), } app.db.Save(&machine) @@ -145,7 +145,7 @@ func (s *Suite) TestGetMapResponseUserProfiles(c *check.C) { NamespaceID: namespaceShared1.ID, Namespace: *namespaceShared1, Registered: true, - RegisterMethod: "authKey", + RegisterMethod: RegisterMethodAuthKey, IPAddress: "100.64.0.1", AuthKeyID: uint(preAuthKeyShared1.ID), } @@ -163,7 +163,7 @@ func (s *Suite) TestGetMapResponseUserProfiles(c *check.C) { NamespaceID: namespaceShared2.ID, Namespace: *namespaceShared2, Registered: true, - RegisterMethod: "authKey", + RegisterMethod: RegisterMethodAuthKey, IPAddress: "100.64.0.2", AuthKeyID: uint(preAuthKeyShared2.ID), } @@ -181,7 +181,7 @@ func (s *Suite) TestGetMapResponseUserProfiles(c *check.C) { NamespaceID: namespaceShared3.ID, Namespace: *namespaceShared3, Registered: true, - RegisterMethod: "authKey", + RegisterMethod: RegisterMethodAuthKey, IPAddress: "100.64.0.3", AuthKeyID: uint(preAuthKeyShared3.ID), } @@ -199,7 +199,7 @@ func (s *Suite) TestGetMapResponseUserProfiles(c *check.C) { NamespaceID: namespaceShared1.ID, Namespace: *namespaceShared1, Registered: true, - RegisterMethod: "authKey", + RegisterMethod: RegisterMethodAuthKey, IPAddress: "100.64.0.4", AuthKeyID: uint(preAuthKey2Shared1.ID), } diff --git a/preauth_keys_test.go b/preauth_keys_test.go index fd0feb03..f8cf276d 100644 --- a/preauth_keys_test.go +++ b/preauth_keys_test.go @@ -81,7 +81,7 @@ func (*Suite) TestAlreadyUsedKey(c *check.C) { Name: "testest", NamespaceID: namespace.ID, Registered: true, - RegisterMethod: "authKey", + RegisterMethod: RegisterMethodAuthKey, AuthKeyID: uint(pak.ID), } app.db.Save(&machine) @@ -106,7 +106,7 @@ func (*Suite) TestReusableBeingUsedKey(c *check.C) { Name: "testest", NamespaceID: namespace.ID, Registered: true, - RegisterMethod: "authKey", + RegisterMethod: RegisterMethodAuthKey, AuthKeyID: uint(pak.ID), } app.db.Save(&machine) @@ -144,7 +144,7 @@ func (*Suite) TestEphemeralKey(c *check.C) { Name: "testest", NamespaceID: namespace.ID, Registered: true, - RegisterMethod: "authKey", + RegisterMethod: RegisterMethodAuthKey, LastSeen: &now, AuthKeyID: uint(pak.ID), } diff --git a/routes_test.go b/routes_test.go index 18cb0ceb..94bda45b 100644 --- a/routes_test.go +++ b/routes_test.go @@ -36,7 +36,7 @@ func (s *Suite) TestGetRoutes(c *check.C) { Name: "test_get_route_machine", NamespaceID: namespace.ID, Registered: true, - RegisterMethod: "authKey", + RegisterMethod: RegisterMethodAuthKey, AuthKeyID: uint(pak.ID), HostInfo: datatypes.JSON(hostinfo), } @@ -90,7 +90,7 @@ func (s *Suite) TestGetEnableRoutes(c *check.C) { Name: "test_enable_route_machine", NamespaceID: namespace.ID, Registered: true, - RegisterMethod: "authKey", + RegisterMethod: RegisterMethodAuthKey, AuthKeyID: uint(pak.ID), HostInfo: datatypes.JSON(hostinfo), } diff --git a/sharing_test.go b/sharing_test.go index 7ec1b0ee..fd7634da 100644 --- a/sharing_test.go +++ b/sharing_test.go @@ -25,7 +25,7 @@ func CreateNodeNamespace( Name: node, NamespaceID: namespace.ID, Registered: true, - RegisterMethod: "authKey", + RegisterMethod: RegisterMethodAuthKey, IPAddress: ip, AuthKeyID: uint(pak1.ID), } @@ -213,7 +213,7 @@ func (s *Suite) TestComplexSharingAcrossNamespaces(c *check.C) { Name: "test_get_shared_nodes_4", NamespaceID: namespace1.ID, Registered: true, - RegisterMethod: "authKey", + RegisterMethod: RegisterMethodAuthKey, IPAddress: "100.64.0.4", AuthKeyID: uint(pak4.ID), } @@ -293,7 +293,7 @@ func (s *Suite) TestDeleteSharedMachine(c *check.C) { Name: "test_get_shared_nodes_4", NamespaceID: namespace1.ID, Registered: true, - RegisterMethod: "authKey", + RegisterMethod: RegisterMethodAuthKey, IPAddress: "100.64.0.4", AuthKeyID: uint(pak4n1.ID), } diff --git a/utils_test.go b/utils_test.go index dcda6130..95722a83 100644 --- a/utils_test.go +++ b/utils_test.go @@ -36,7 +36,7 @@ func (s *Suite) TestGetUsedIps(c *check.C) { Name: "testmachine", NamespaceID: namespace.ID, Registered: true, - RegisterMethod: "authKey", + RegisterMethod: RegisterMethodAuthKey, AuthKeyID: uint(pak.ID), IPAddress: ip.String(), } @@ -78,7 +78,7 @@ func (s *Suite) TestGetMultiIp(c *check.C) { Name: "testmachine", NamespaceID: namespace.ID, Registered: true, - RegisterMethod: "authKey", + RegisterMethod: RegisterMethodAuthKey, AuthKeyID: uint(pak.ID), IPAddress: ip.String(), } @@ -151,7 +151,7 @@ func (s *Suite) TestGetAvailableIpMachineWithoutIP(c *check.C) { Name: "testmachine", NamespaceID: namespace.ID, Registered: true, - RegisterMethod: "authKey", + RegisterMethod: RegisterMethodAuthKey, AuthKeyID: uint(pak.ID), } app.db.Save(&machine) From 50dcb8bb753210dd5bee08e9079f64fa2cfe3e5a Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Thu, 18 Nov 2021 08:50:53 +0000 Subject: [PATCH 167/300] Use valid handler for registered authkey machines --- api.go | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/api.go b/api.go index 45b59d3c..a92b5e6b 100644 --- a/api.go +++ b/api.go @@ -130,8 +130,15 @@ func (h *Headscale) RegistrationHandler(ctx *gin.Context) { return } - if machine.Registered && machine.Expiry.UTC().After(now) { - h.handleMachineValidRegistration(ctx, machineKey, req, *machine) + // We dont care about expiry time if the method is AuthKey, as we dont set that. + if machine.Registered && machine.RegisterMethod == RegisterMethodAuthKey { + h.handleMachineValidRegistration(ctx, machineKey, *machine) + + return + } + + if machine.Registered && !machine.isExpired() { + h.handleMachineValidRegistration(ctx, machineKey, *machine) return } From 981f712660746ac692255929ed62a29f5167321d Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Thu, 18 Nov 2021 08:51:21 +0000 Subject: [PATCH 168/300] Remove unused param --- api.go | 1 - 1 file changed, 1 deletion(-) diff --git a/api.go b/api.go index a92b5e6b..2c4f9897 100644 --- a/api.go +++ b/api.go @@ -315,7 +315,6 @@ func (h *Headscale) handleMachineLogOut( func (h *Headscale) handleMachineValidRegistration( ctx *gin.Context, idKey wgkey.Key, - reqisterRequest tailcfg.RegisterRequest, machine Machine, ) { resp := tailcfg.RegisterResponse{} From 58d12553577a98f4371ebfd0f9409a2f03ab9543 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Thu, 18 Nov 2021 08:51:33 +0000 Subject: [PATCH 169/300] Remove unneeded returns --- api.go | 6 ------ 1 file changed, 6 deletions(-) diff --git a/api.go b/api.go index 2c4f9897..d11971b6 100644 --- a/api.go +++ b/api.go @@ -308,8 +308,6 @@ func (h *Headscale) handleMachineLogOut( return } ctx.Data(http.StatusOK, "application/json; charset=utf-8", respBody) - - return } func (h *Headscale) handleMachineValidRegistration( @@ -345,8 +343,6 @@ func (h *Headscale) handleMachineValidRegistration( machineRegistrations.WithLabelValues("update", "web", "success", machine.Namespace.Name). Inc() ctx.Data(http.StatusOK, "application/json; charset=utf-8", respBody) - - return } func (h *Headscale) handleMachineExpired( @@ -396,8 +392,6 @@ func (h *Headscale) handleMachineExpired( machineRegistrations.WithLabelValues("new", "web", "success", machine.Namespace.Name). Inc() ctx.Data(http.StatusOK, "application/json; charset=utf-8", respBody) - - return } func (h *Headscale) handleMachineRefreshKey( From 106b1e7e8d35ef7deae2dc2c2cbe27e1c60d3e3e Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Thu, 18 Nov 2021 17:51:54 +0000 Subject: [PATCH 170/300] Create constants for other reg methods --- api.go | 4 ++-- machine.go | 2 +- oidc.go | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/api.go b/api.go index d11971b6..b8169111 100644 --- a/api.go +++ b/api.go @@ -21,6 +21,8 @@ import ( const ( reservedResponseHeaderSize = 4 RegisterMethodAuthKey = "authKey" + RegisterMethodOIDC = "oidc" + RegisterMethodCLI = "cli" ) // KeyHandler provides the Headscale pub key @@ -422,8 +424,6 @@ func (h *Headscale) handleMachineRefreshKey( return } ctx.Data(http.StatusOK, "application/json; charset=utf-8", respBody) - - return } func (h *Headscale) handleMachineRegistrationNew( diff --git a/machine.go b/machine.go index dcd79700..293b26fa 100644 --- a/machine.go +++ b/machine.go @@ -660,7 +660,7 @@ func (h *Headscale) RegisterMachine( machine.IPAddress = ip.String() machine.NamespaceID = namespace.ID machine.Registered = true - machine.RegisterMethod = "cli" + machine.RegisterMethod = RegisterMethodCLI h.db.Save(&machine) log.Trace(). diff --git a/oidc.go b/oidc.go index 07561e8a..f796c908 100644 --- a/oidc.go +++ b/oidc.go @@ -223,7 +223,7 @@ func (h *Headscale) OIDCCallback(ctx *gin.Context) { machine.IPAddress = ip.String() machine.NamespaceID = namespace.ID machine.Registered = true - machine.RegisterMethod = "oidc" + machine.RegisterMethod = RegisterMethodOIDC machine.LastSuccessfulUpdate = &now h.db.Save(&machine) } From 9aac1fb255f25473cc5a2890eebce128dbc97dc3 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Fri, 19 Nov 2021 09:02:29 +0000 Subject: [PATCH 171/300] Remove expiry logic, this needs to be redone --- api.go | 16 +++++++--------- app.go | 3 --- cli_test.go | 17 ++++++++--------- machine.go | 39 +++++++-------------------------------- oidc.go | 2 -- 5 files changed, 22 insertions(+), 55 deletions(-) diff --git a/api.go b/api.go index b8169111..ee10e88f 100644 --- a/api.go +++ b/api.go @@ -369,13 +369,9 @@ func (h *Headscale) handleMachineExpired( strings.TrimSuffix(h.cfg.ServerURL, "/"), idKey.HexString()) } - // When a client connects, it may request a specific expiry time in its - // RegisterRequest (https://github.com/tailscale/tailscale/blob/main/tailcfg/tailcfg.go#L634) - // RequestedExpiry is used to store the clients requested expiry time since the authentication flow is broken - // into two steps (which cant pass arbitrary data between them easily) and needs to be - // retrieved again after the user has authenticated. After the authentication flow - // completes, RequestedExpiry is copied into Expiry. - machine.RequestedExpiry = &reqisterRequest.Expiry + if !reqisterRequest.Expiry.IsZero() { + machine.Expiry = &reqisterRequest.Expiry + } h.db.Save(&machine) @@ -450,8 +446,10 @@ func (h *Headscale) handleMachineRegistrationNew( strings.TrimSuffix(h.cfg.ServerURL, "/"), idKey.HexString()) } - // save the requested expiry time for retrieval later in the authentication flow - machine.RequestedExpiry = &reqisterRequest.Expiry + if !reqisterRequest.Expiry.IsZero() { + machine.Expiry = &reqisterRequest.Expiry + } + machine.NodeKey = wgkey.Key(reqisterRequest.NodeKey).HexString() // save the NodeKey h.db.Save(&machine) diff --git a/app.go b/app.go index 08b67fe0..b2b545b4 100644 --- a/app.go +++ b/app.go @@ -96,9 +96,6 @@ type Config struct { OIDC OIDCConfig CLI CLIConfig - - MaxMachineRegistrationDuration time.Duration - DefaultMachineRegistrationDuration time.Duration } type OIDCConfig struct { diff --git a/cli_test.go b/cli_test.go index 44ef9f08..ef7e2993 100644 --- a/cli_test.go +++ b/cli_test.go @@ -13,15 +13,14 @@ func (s *Suite) TestRegisterMachine(c *check.C) { now := time.Now().UTC() machine := Machine{ - ID: 0, - MachineKey: "8ce002a935f8c394e55e78fbbb410576575ff8ec5cfa2e627e4b807f1be15b0e", - NodeKey: "bar", - DiscoKey: "faa", - Name: "testmachine", - NamespaceID: namespace.ID, - IPAddress: "10.0.0.1", - Expiry: &now, - RequestedExpiry: &now, + ID: 0, + MachineKey: "8ce002a935f8c394e55e78fbbb410576575ff8ec5cfa2e627e4b807f1be15b0e", + NodeKey: "bar", + DiscoKey: "faa", + Name: "testmachine", + NamespaceID: namespace.ID, + IPAddress: "10.0.0.1", + Expiry: &now, } app.db.Save(&machine) diff --git a/machine.go b/machine.go index 293b26fa..813da35c 100644 --- a/machine.go +++ b/machine.go @@ -45,7 +45,6 @@ type Machine struct { LastSeen *time.Time LastSuccessfulUpdate *time.Time Expiry *time.Time - RequestedExpiry *time.Time HostInfo datatypes.JSON Endpoints datatypes.JSON @@ -68,38 +67,14 @@ func (machine Machine) isAlreadyRegistered() bool { // isExpired returns whether the machine registration has expired. func (machine Machine) isExpired() bool { - return time.Now().UTC().After(*machine.Expiry) -} - -// If the Machine is expired, updateMachineExpiry updates the Machine Expiry time to the maximum allowed duration, -// or the default duration if no Expiry time was requested by the client. The expiry time here does not (yet) cause -// a client to be disconnected, however they will have to re-auth the machine if they attempt to reconnect after the -// expiry time. -func (h *Headscale) updateMachineExpiry(machine *Machine) { - if machine.isExpired() { - now := time.Now().UTC() - maxExpiry := now.Add( - h.cfg.MaxMachineRegistrationDuration, - ) // calculate the maximum expiry - defaultExpiry := now.Add( - h.cfg.DefaultMachineRegistrationDuration, - ) // calculate the default expiry - - // clamp the expiry time of the machine registration to the maximum allowed, or use the default if none supplied - if maxExpiry.Before(*machine.RequestedExpiry) { - log.Debug(). - Msgf("Clamping registration expiry time to maximum: %v (%v)", maxExpiry, h.cfg.MaxMachineRegistrationDuration) - machine.Expiry = &maxExpiry - } else if machine.RequestedExpiry.IsZero() { - log.Debug().Msgf("Using default machine registration expiry time: %v (%v)", defaultExpiry, h.cfg.DefaultMachineRegistrationDuration) - machine.Expiry = &defaultExpiry - } else { - log.Debug().Msgf("Using requested machine registration expiry time: %v", machine.RequestedExpiry) - machine.Expiry = machine.RequestedExpiry - } - - h.db.Save(&machine) + // If Expiry is not set, the client has not indicated that + // it wants an expiry time, it is therefor considered + // to mean "not expired" + if machine.Expiry.IsZero() { + return false } + + return time.Now().UTC().After(*machine.Expiry) } func (h *Headscale) getDirectPeers(machine *Machine) (Machines, error) { diff --git a/oidc.go b/oidc.go index f796c908..fb27354b 100644 --- a/oidc.go +++ b/oidc.go @@ -228,8 +228,6 @@ func (h *Headscale) OIDCCallback(ctx *gin.Context) { h.db.Save(&machine) } - h.updateMachineExpiry(machine) - ctx.Data(http.StatusOK, "text/html; charset=utf-8", []byte(fmt.Sprintf(` From 6a9dd2029e0985e5cbde1d11bdae16f3625b3ac1 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Fri, 19 Nov 2021 09:02:49 +0000 Subject: [PATCH 172/300] Remove expiry logic, this needs to be redone --- cmd/headscale/cli/utils.go | 27 --------------------------- 1 file changed, 27 deletions(-) diff --git a/cmd/headscale/cli/utils.go b/cmd/headscale/cli/utils.go index 958fb893..98b53619 100644 --- a/cmd/headscale/cli/utils.go +++ b/cmd/headscale/cli/utils.go @@ -218,30 +218,6 @@ func absPath(path string) string { } func getHeadscaleConfig() headscale.Config { - // maxMachineRegistrationDuration is the maximum time headscale will allow a client to (optionally) request for - // the machine key expiry time. RegisterRequests with Expiry times that are more than - // maxMachineRegistrationDuration in the future will be clamped to (now + maxMachineRegistrationDuration) - maxMachineRegistrationDuration, _ := time.ParseDuration( - "10h", - ) // use 10h here because it is the length of a standard business day plus a small amount of leeway - if viper.GetDuration("max_machine_registration_duration") >= time.Second { - maxMachineRegistrationDuration = viper.GetDuration( - "max_machine_registration_duration", - ) - } - - // defaultMachineRegistrationDuration is the default time assigned to a machine registration if one is not - // specified by the tailscale client. It is the default amount of time a machine registration is valid for - // (ie the amount of time before the user has to re-authenticate when requesting a connection) - defaultMachineRegistrationDuration, _ := time.ParseDuration( - "8h", - ) // use 8h here because it's the length of a standard business day - if viper.GetDuration("default_machine_registration_duration") >= time.Second { - defaultMachineRegistrationDuration = viper.GetDuration( - "default_machine_registration_duration", - ) - } - dnsConfig, baseDomain := GetDNSConfig() derpConfig := GetDERPConfig() @@ -295,9 +271,6 @@ func getHeadscaleConfig() headscale.Config { Insecure: viper.GetBool("cli.insecure"), Timeout: viper.GetDuration("cli.timeout"), }, - - MaxMachineRegistrationDuration: maxMachineRegistrationDuration, - DefaultMachineRegistrationDuration: defaultMachineRegistrationDuration, } } From 5a2cae508160b482510ba8999d6354a001b85fce Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Fri, 19 Nov 2021 09:16:11 +0000 Subject: [PATCH 173/300] Add new Tailscale version to integration tests --- integration_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integration_test.go b/integration_test.go index a9125a0a..c2679918 100644 --- a/integration_test.go +++ b/integration_test.go @@ -28,7 +28,7 @@ import ( "tailscale.com/ipn/ipnstate" ) -var tailscaleVersions = []string{"1.16.2", "1.14.3", "1.12.3"} +var tailscaleVersions = []string{"1.18.0", "1.16.2", "1.14.3", "1.12.3"} type TestNamespace struct { count int From e91f72fe4c9cf747605cbbd64f89b5016be35c00 Mon Sep 17 00:00:00 2001 From: lion24 Date: Sat, 20 Nov 2021 23:31:49 +0100 Subject: [PATCH 174/300] Running.md: fix missing backslash (\) * This would cause otherwise the command to abort after the first statement of the docker command ;) --- docs/Running.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Running.md b/docs/Running.md index 867c5ed2..ac9d2282 100644 --- a/docs/Running.md +++ b/docs/Running.md @@ -26,7 +26,7 @@ ```shell docker run --name headscale \ - -e POSTGRES_DB=headscale + -e POSTGRES_DB=headscale \ -e POSTGRES_USER=foo \ -e POSTGRES_PASSWORD=bar \ -p 5432:5432 \ From 1c7aff5dd912d89e4c571e93369517928a71db55 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Sun, 21 Nov 2021 09:44:38 +0000 Subject: [PATCH 175/300] Add expired column to machine list command --- cmd/headscale/cli/nodes.go | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/cmd/headscale/cli/nodes.go b/cmd/headscale/cli/nodes.go index 218d25bd..878fc7a4 100644 --- a/cmd/headscale/cli/nodes.go +++ b/cmd/headscale/cli/nodes.go @@ -412,6 +412,7 @@ func nodesToPtables( "Ephemeral", "Last seen", "Online", + "Expired", }, } @@ -420,12 +421,19 @@ func nodesToPtables( if machine.PreAuthKey != nil && machine.PreAuthKey.Ephemeral { ephemeral = true } + var lastSeen time.Time var lastSeenTime string if machine.LastSeen != nil { lastSeen = machine.LastSeen.AsTime() lastSeenTime = lastSeen.Format("2006-01-02 15:04:05") } + + var expiry time.Time + if machine.Expiry != nil { + expiry = machine.Expiry.AsTime() + } + nKey, err := wgkey.ParseHex(machine.NodeKey) if err != nil { return nil, err @@ -436,9 +444,21 @@ func nodesToPtables( if lastSeen.After( time.Now().Add(-5 * time.Minute), ) { // TODO: Find a better way to reliably show if online - online = pterm.LightGreen("true") + online = pterm.LightGreen("online") } else { - online = pterm.LightRed("false") + online = pterm.LightRed("offline") + } + + fmt.Printf( + "Machine %s, expiry: %s\n", + machine.Name, + expiry.Format("2006-01-02 15:04:05"), + ) + var expired string + if expiry.IsZero() || expiry.After(time.Now()) { + expired = pterm.LightGreen("no") + } else { + expired = pterm.LightRed("yes") } var namespace string @@ -459,6 +479,7 @@ func nodesToPtables( strconv.FormatBool(ephemeral), lastSeenTime, online, + expired, }, ) } From f85a77edb5110fca8f880793abbb98d1a6169c68 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Sun, 21 Nov 2021 09:48:59 +0000 Subject: [PATCH 176/300] Remove println statement --- cmd/headscale/cli/nodes.go | 5 ----- 1 file changed, 5 deletions(-) diff --git a/cmd/headscale/cli/nodes.go b/cmd/headscale/cli/nodes.go index 878fc7a4..7c2cd6c1 100644 --- a/cmd/headscale/cli/nodes.go +++ b/cmd/headscale/cli/nodes.go @@ -449,11 +449,6 @@ func nodesToPtables( online = pterm.LightRed("offline") } - fmt.Printf( - "Machine %s, expiry: %s\n", - machine.Name, - expiry.Format("2006-01-02 15:04:05"), - ) var expired string if expiry.IsZero() || expiry.After(time.Now()) { expired = pterm.LightGreen("no") From f1c05f80104e4468d46bf684d6bc9d9922821324 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Sun, 21 Nov 2021 13:40:04 +0000 Subject: [PATCH 177/300] Add ExpireMachine spec to rpc --- gen/go/headscale/v1/headscale.pb.go | 205 ++++++----- gen/go/headscale/v1/headscale.pb.gw.go | 99 +++++ gen/go/headscale/v1/headscale_grpc.pb.go | 36 ++ gen/go/headscale/v1/machine.pb.go | 345 ++++++++++++------ .../headscale/v1/headscale.swagger.json | 39 ++ proto/headscale/v1/headscale.proto | 6 + proto/headscale/v1/machine.proto | 8 + 7 files changed, 534 insertions(+), 204 deletions(-) diff --git a/gen/go/headscale/v1/headscale.pb.go b/gen/go/headscale/v1/headscale.pb.go index 56911b6b..dd27265d 100644 --- a/gen/go/headscale/v1/headscale.pb.go +++ b/gen/go/headscale/v1/headscale.pb.go @@ -34,8 +34,8 @@ var file_headscale_v1_headscale_proto_rawDesc = []byte{ 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1a, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x19, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2f, 0x76, - 0x31, 0x2f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x32, 0xec, - 0x11, 0x0a, 0x10, 0x48, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x53, 0x65, 0x72, 0x76, + 0x31, 0x2f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x32, 0xf4, + 0x12, 0x0a, 0x10, 0x48, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x77, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x21, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, @@ -133,54 +133,63 @@ var file_headscale_v1_headscale_proto_rawDesc = []byte{ 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x24, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1e, 0x2a, 0x1c, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, - 0x2f, 0x7b, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x12, 0x6e, 0x0a, - 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x73, 0x12, 0x21, 0x2e, - 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, - 0x74, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x22, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, - 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x17, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x11, 0x12, 0x0f, 0x2f, 0x61, - 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x12, 0x8d, 0x01, - 0x0a, 0x0c, 0x53, 0x68, 0x61, 0x72, 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x12, 0x21, - 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x68, - 0x61, 0x72, 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x22, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, - 0x2e, 0x53, 0x68, 0x61, 0x72, 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x36, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x30, 0x22, 0x2e, 0x2f, - 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x2f, 0x7b, - 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x73, 0x68, 0x61, 0x72, - 0x65, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x7d, 0x12, 0x95, 0x01, - 0x0a, 0x0e, 0x55, 0x6e, 0x73, 0x68, 0x61, 0x72, 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, - 0x12, 0x23, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, - 0x55, 0x6e, 0x73, 0x68, 0x61, 0x72, 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, - 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x6e, 0x73, 0x68, 0x61, 0x72, 0x65, 0x4d, 0x61, 0x63, 0x68, - 0x69, 0x6e, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x38, 0x82, 0xd3, 0xe4, - 0x93, 0x02, 0x32, 0x22, 0x30, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x6d, 0x61, 0x63, - 0x68, 0x69, 0x6e, 0x65, 0x2f, 0x7b, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x5f, 0x69, 0x64, - 0x7d, 0x2f, 0x75, 0x6e, 0x73, 0x68, 0x61, 0x72, 0x65, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x73, - 0x70, 0x61, 0x63, 0x65, 0x7d, 0x12, 0x8b, 0x01, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x4d, 0x61, 0x63, - 0x68, 0x69, 0x6e, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x12, 0x24, 0x2e, 0x68, 0x65, 0x61, 0x64, - 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x61, 0x63, 0x68, - 0x69, 0x6e, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x25, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, - 0x65, 0x74, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x25, 0x12, 0x23, - 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x2f, - 0x7b, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x72, 0x6f, 0x75, - 0x74, 0x65, 0x73, 0x12, 0x97, 0x01, 0x0a, 0x13, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x4d, 0x61, - 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x12, 0x28, 0x2e, 0x68, 0x65, - 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6e, 0x61, 0x62, 0x6c, - 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, - 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, - 0x6e, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x2b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x25, 0x22, 0x23, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, - 0x31, 0x2f, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x2f, 0x7b, 0x6d, 0x61, 0x63, 0x68, 0x69, - 0x6e, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x42, 0x29, 0x5a, - 0x27, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6a, 0x75, 0x61, 0x6e, - 0x66, 0x6f, 0x6e, 0x74, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2f, 0x67, - 0x65, 0x6e, 0x2f, 0x67, 0x6f, 0x2f, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x2f, 0x7b, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x12, 0x85, 0x01, + 0x0a, 0x0d, 0x45, 0x78, 0x70, 0x69, 0x72, 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x12, + 0x22, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, + 0x78, 0x70, 0x69, 0x72, 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, + 0x76, 0x31, 0x2e, 0x45, 0x78, 0x70, 0x69, 0x72, 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x25, + 0x22, 0x23, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, + 0x65, 0x2f, 0x7b, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x65, + 0x78, 0x70, 0x69, 0x72, 0x65, 0x12, 0x6e, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x61, 0x63, + 0x68, 0x69, 0x6e, 0x65, 0x73, 0x12, 0x21, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, + 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, + 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x61, 0x63, 0x68, + 0x69, 0x6e, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x17, 0x82, 0xd3, + 0xe4, 0x93, 0x02, 0x11, 0x12, 0x0f, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x6d, 0x61, + 0x63, 0x68, 0x69, 0x6e, 0x65, 0x12, 0x8d, 0x01, 0x0a, 0x0c, 0x53, 0x68, 0x61, 0x72, 0x65, 0x4d, + 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x12, 0x21, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, + 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, + 0x6e, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x68, 0x65, 0x61, 0x64, + 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x65, 0x4d, 0x61, + 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x36, 0x82, + 0xd3, 0xe4, 0x93, 0x02, 0x30, 0x22, 0x2e, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x6d, + 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x2f, 0x7b, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x5f, + 0x69, 0x64, 0x7d, 0x2f, 0x73, 0x68, 0x61, 0x72, 0x65, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x73, + 0x70, 0x61, 0x63, 0x65, 0x7d, 0x12, 0x95, 0x01, 0x0a, 0x0e, 0x55, 0x6e, 0x73, 0x68, 0x61, 0x72, + 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x12, 0x23, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, + 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x6e, 0x73, 0x68, 0x61, 0x72, 0x65, 0x4d, + 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, + 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x6e, 0x73, + 0x68, 0x61, 0x72, 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x38, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x32, 0x22, 0x30, 0x2f, 0x61, 0x70, + 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x2f, 0x7b, 0x6d, 0x61, + 0x63, 0x68, 0x69, 0x6e, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x75, 0x6e, 0x73, 0x68, 0x61, 0x72, + 0x65, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x7d, 0x12, 0x8b, 0x01, + 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x6f, 0x75, 0x74, + 0x65, 0x12, 0x24, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, + 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x65, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, + 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, + 0x65, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2b, + 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x25, 0x12, 0x23, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, + 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x2f, 0x7b, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, + 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x12, 0x97, 0x01, 0x0a, 0x13, + 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x6f, 0x75, + 0x74, 0x65, 0x73, 0x12, 0x28, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, + 0x76, 0x31, 0x2e, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, + 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, + 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6e, 0x61, + 0x62, 0x6c, 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x25, + 0x22, 0x23, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, + 0x65, 0x2f, 0x7b, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x72, + 0x6f, 0x75, 0x74, 0x65, 0x73, 0x42, 0x29, 0x5a, 0x27, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, + 0x63, 0x6f, 0x6d, 0x2f, 0x6a, 0x75, 0x61, 0x6e, 0x66, 0x6f, 0x6e, 0x74, 0x2f, 0x68, 0x65, 0x61, + 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x67, 0x6f, 0x2f, 0x76, 0x31, + 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var file_headscale_v1_headscale_proto_goTypes = []interface{}{ @@ -196,28 +205,30 @@ var file_headscale_v1_headscale_proto_goTypes = []interface{}{ (*GetMachineRequest)(nil), // 9: headscale.v1.GetMachineRequest (*RegisterMachineRequest)(nil), // 10: headscale.v1.RegisterMachineRequest (*DeleteMachineRequest)(nil), // 11: headscale.v1.DeleteMachineRequest - (*ListMachinesRequest)(nil), // 12: headscale.v1.ListMachinesRequest - (*ShareMachineRequest)(nil), // 13: headscale.v1.ShareMachineRequest - (*UnshareMachineRequest)(nil), // 14: headscale.v1.UnshareMachineRequest - (*GetMachineRouteRequest)(nil), // 15: headscale.v1.GetMachineRouteRequest - (*EnableMachineRoutesRequest)(nil), // 16: headscale.v1.EnableMachineRoutesRequest - (*GetNamespaceResponse)(nil), // 17: headscale.v1.GetNamespaceResponse - (*CreateNamespaceResponse)(nil), // 18: headscale.v1.CreateNamespaceResponse - (*RenameNamespaceResponse)(nil), // 19: headscale.v1.RenameNamespaceResponse - (*DeleteNamespaceResponse)(nil), // 20: headscale.v1.DeleteNamespaceResponse - (*ListNamespacesResponse)(nil), // 21: headscale.v1.ListNamespacesResponse - (*CreatePreAuthKeyResponse)(nil), // 22: headscale.v1.CreatePreAuthKeyResponse - (*ExpirePreAuthKeyResponse)(nil), // 23: headscale.v1.ExpirePreAuthKeyResponse - (*ListPreAuthKeysResponse)(nil), // 24: headscale.v1.ListPreAuthKeysResponse - (*DebugCreateMachineResponse)(nil), // 25: headscale.v1.DebugCreateMachineResponse - (*GetMachineResponse)(nil), // 26: headscale.v1.GetMachineResponse - (*RegisterMachineResponse)(nil), // 27: headscale.v1.RegisterMachineResponse - (*DeleteMachineResponse)(nil), // 28: headscale.v1.DeleteMachineResponse - (*ListMachinesResponse)(nil), // 29: headscale.v1.ListMachinesResponse - (*ShareMachineResponse)(nil), // 30: headscale.v1.ShareMachineResponse - (*UnshareMachineResponse)(nil), // 31: headscale.v1.UnshareMachineResponse - (*GetMachineRouteResponse)(nil), // 32: headscale.v1.GetMachineRouteResponse - (*EnableMachineRoutesResponse)(nil), // 33: headscale.v1.EnableMachineRoutesResponse + (*ExpireMachineRequest)(nil), // 12: headscale.v1.ExpireMachineRequest + (*ListMachinesRequest)(nil), // 13: headscale.v1.ListMachinesRequest + (*ShareMachineRequest)(nil), // 14: headscale.v1.ShareMachineRequest + (*UnshareMachineRequest)(nil), // 15: headscale.v1.UnshareMachineRequest + (*GetMachineRouteRequest)(nil), // 16: headscale.v1.GetMachineRouteRequest + (*EnableMachineRoutesRequest)(nil), // 17: headscale.v1.EnableMachineRoutesRequest + (*GetNamespaceResponse)(nil), // 18: headscale.v1.GetNamespaceResponse + (*CreateNamespaceResponse)(nil), // 19: headscale.v1.CreateNamespaceResponse + (*RenameNamespaceResponse)(nil), // 20: headscale.v1.RenameNamespaceResponse + (*DeleteNamespaceResponse)(nil), // 21: headscale.v1.DeleteNamespaceResponse + (*ListNamespacesResponse)(nil), // 22: headscale.v1.ListNamespacesResponse + (*CreatePreAuthKeyResponse)(nil), // 23: headscale.v1.CreatePreAuthKeyResponse + (*ExpirePreAuthKeyResponse)(nil), // 24: headscale.v1.ExpirePreAuthKeyResponse + (*ListPreAuthKeysResponse)(nil), // 25: headscale.v1.ListPreAuthKeysResponse + (*DebugCreateMachineResponse)(nil), // 26: headscale.v1.DebugCreateMachineResponse + (*GetMachineResponse)(nil), // 27: headscale.v1.GetMachineResponse + (*RegisterMachineResponse)(nil), // 28: headscale.v1.RegisterMachineResponse + (*DeleteMachineResponse)(nil), // 29: headscale.v1.DeleteMachineResponse + (*ExpireMachineResponse)(nil), // 30: headscale.v1.ExpireMachineResponse + (*ListMachinesResponse)(nil), // 31: headscale.v1.ListMachinesResponse + (*ShareMachineResponse)(nil), // 32: headscale.v1.ShareMachineResponse + (*UnshareMachineResponse)(nil), // 33: headscale.v1.UnshareMachineResponse + (*GetMachineRouteResponse)(nil), // 34: headscale.v1.GetMachineRouteResponse + (*EnableMachineRoutesResponse)(nil), // 35: headscale.v1.EnableMachineRoutesResponse } var file_headscale_v1_headscale_proto_depIdxs = []int32{ 0, // 0: headscale.v1.HeadscaleService.GetNamespace:input_type -> headscale.v1.GetNamespaceRequest @@ -232,30 +243,32 @@ var file_headscale_v1_headscale_proto_depIdxs = []int32{ 9, // 9: headscale.v1.HeadscaleService.GetMachine:input_type -> headscale.v1.GetMachineRequest 10, // 10: headscale.v1.HeadscaleService.RegisterMachine:input_type -> headscale.v1.RegisterMachineRequest 11, // 11: headscale.v1.HeadscaleService.DeleteMachine:input_type -> headscale.v1.DeleteMachineRequest - 12, // 12: headscale.v1.HeadscaleService.ListMachines:input_type -> headscale.v1.ListMachinesRequest - 13, // 13: headscale.v1.HeadscaleService.ShareMachine:input_type -> headscale.v1.ShareMachineRequest - 14, // 14: headscale.v1.HeadscaleService.UnshareMachine:input_type -> headscale.v1.UnshareMachineRequest - 15, // 15: headscale.v1.HeadscaleService.GetMachineRoute:input_type -> headscale.v1.GetMachineRouteRequest - 16, // 16: headscale.v1.HeadscaleService.EnableMachineRoutes:input_type -> headscale.v1.EnableMachineRoutesRequest - 17, // 17: headscale.v1.HeadscaleService.GetNamespace:output_type -> headscale.v1.GetNamespaceResponse - 18, // 18: headscale.v1.HeadscaleService.CreateNamespace:output_type -> headscale.v1.CreateNamespaceResponse - 19, // 19: headscale.v1.HeadscaleService.RenameNamespace:output_type -> headscale.v1.RenameNamespaceResponse - 20, // 20: headscale.v1.HeadscaleService.DeleteNamespace:output_type -> headscale.v1.DeleteNamespaceResponse - 21, // 21: headscale.v1.HeadscaleService.ListNamespaces:output_type -> headscale.v1.ListNamespacesResponse - 22, // 22: headscale.v1.HeadscaleService.CreatePreAuthKey:output_type -> headscale.v1.CreatePreAuthKeyResponse - 23, // 23: headscale.v1.HeadscaleService.ExpirePreAuthKey:output_type -> headscale.v1.ExpirePreAuthKeyResponse - 24, // 24: headscale.v1.HeadscaleService.ListPreAuthKeys:output_type -> headscale.v1.ListPreAuthKeysResponse - 25, // 25: headscale.v1.HeadscaleService.DebugCreateMachine:output_type -> headscale.v1.DebugCreateMachineResponse - 26, // 26: headscale.v1.HeadscaleService.GetMachine:output_type -> headscale.v1.GetMachineResponse - 27, // 27: headscale.v1.HeadscaleService.RegisterMachine:output_type -> headscale.v1.RegisterMachineResponse - 28, // 28: headscale.v1.HeadscaleService.DeleteMachine:output_type -> headscale.v1.DeleteMachineResponse - 29, // 29: headscale.v1.HeadscaleService.ListMachines:output_type -> headscale.v1.ListMachinesResponse - 30, // 30: headscale.v1.HeadscaleService.ShareMachine:output_type -> headscale.v1.ShareMachineResponse - 31, // 31: headscale.v1.HeadscaleService.UnshareMachine:output_type -> headscale.v1.UnshareMachineResponse - 32, // 32: headscale.v1.HeadscaleService.GetMachineRoute:output_type -> headscale.v1.GetMachineRouteResponse - 33, // 33: headscale.v1.HeadscaleService.EnableMachineRoutes:output_type -> headscale.v1.EnableMachineRoutesResponse - 17, // [17:34] is the sub-list for method output_type - 0, // [0:17] is the sub-list for method input_type + 12, // 12: headscale.v1.HeadscaleService.ExpireMachine:input_type -> headscale.v1.ExpireMachineRequest + 13, // 13: headscale.v1.HeadscaleService.ListMachines:input_type -> headscale.v1.ListMachinesRequest + 14, // 14: headscale.v1.HeadscaleService.ShareMachine:input_type -> headscale.v1.ShareMachineRequest + 15, // 15: headscale.v1.HeadscaleService.UnshareMachine:input_type -> headscale.v1.UnshareMachineRequest + 16, // 16: headscale.v1.HeadscaleService.GetMachineRoute:input_type -> headscale.v1.GetMachineRouteRequest + 17, // 17: headscale.v1.HeadscaleService.EnableMachineRoutes:input_type -> headscale.v1.EnableMachineRoutesRequest + 18, // 18: headscale.v1.HeadscaleService.GetNamespace:output_type -> headscale.v1.GetNamespaceResponse + 19, // 19: headscale.v1.HeadscaleService.CreateNamespace:output_type -> headscale.v1.CreateNamespaceResponse + 20, // 20: headscale.v1.HeadscaleService.RenameNamespace:output_type -> headscale.v1.RenameNamespaceResponse + 21, // 21: headscale.v1.HeadscaleService.DeleteNamespace:output_type -> headscale.v1.DeleteNamespaceResponse + 22, // 22: headscale.v1.HeadscaleService.ListNamespaces:output_type -> headscale.v1.ListNamespacesResponse + 23, // 23: headscale.v1.HeadscaleService.CreatePreAuthKey:output_type -> headscale.v1.CreatePreAuthKeyResponse + 24, // 24: headscale.v1.HeadscaleService.ExpirePreAuthKey:output_type -> headscale.v1.ExpirePreAuthKeyResponse + 25, // 25: headscale.v1.HeadscaleService.ListPreAuthKeys:output_type -> headscale.v1.ListPreAuthKeysResponse + 26, // 26: headscale.v1.HeadscaleService.DebugCreateMachine:output_type -> headscale.v1.DebugCreateMachineResponse + 27, // 27: headscale.v1.HeadscaleService.GetMachine:output_type -> headscale.v1.GetMachineResponse + 28, // 28: headscale.v1.HeadscaleService.RegisterMachine:output_type -> headscale.v1.RegisterMachineResponse + 29, // 29: headscale.v1.HeadscaleService.DeleteMachine:output_type -> headscale.v1.DeleteMachineResponse + 30, // 30: headscale.v1.HeadscaleService.ExpireMachine:output_type -> headscale.v1.ExpireMachineResponse + 31, // 31: headscale.v1.HeadscaleService.ListMachines:output_type -> headscale.v1.ListMachinesResponse + 32, // 32: headscale.v1.HeadscaleService.ShareMachine:output_type -> headscale.v1.ShareMachineResponse + 33, // 33: headscale.v1.HeadscaleService.UnshareMachine:output_type -> headscale.v1.UnshareMachineResponse + 34, // 34: headscale.v1.HeadscaleService.GetMachineRoute:output_type -> headscale.v1.GetMachineRouteResponse + 35, // 35: headscale.v1.HeadscaleService.EnableMachineRoutes:output_type -> headscale.v1.EnableMachineRoutesResponse + 18, // [18:36] is the sub-list for method output_type + 0, // [0:18] is the sub-list for method input_type 0, // [0:0] is the sub-list for extension type_name 0, // [0:0] is the sub-list for extension extendee 0, // [0:0] is the sub-list for field type_name diff --git a/gen/go/headscale/v1/headscale.pb.gw.go b/gen/go/headscale/v1/headscale.pb.gw.go index ba2d492f..41502c8f 100644 --- a/gen/go/headscale/v1/headscale.pb.gw.go +++ b/gen/go/headscale/v1/headscale.pb.gw.go @@ -537,6 +537,58 @@ func local_request_HeadscaleService_DeleteMachine_0(ctx context.Context, marshal } +func request_HeadscaleService_ExpireMachine_0(ctx context.Context, marshaler runtime.Marshaler, client HeadscaleServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq ExpireMachineRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["machine_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "machine_id") + } + + protoReq.MachineId, err = runtime.Uint64(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "machine_id", err) + } + + msg, err := client.ExpireMachine(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_HeadscaleService_ExpireMachine_0(ctx context.Context, marshaler runtime.Marshaler, server HeadscaleServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq ExpireMachineRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["machine_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "machine_id") + } + + protoReq.MachineId, err = runtime.Uint64(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "machine_id", err) + } + + msg, err := server.ExpireMachine(ctx, &protoReq) + return msg, metadata, err + +} + var ( filter_HeadscaleService_ListMachines_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)} ) @@ -1121,6 +1173,29 @@ func RegisterHeadscaleServiceHandlerServer(ctx context.Context, mux *runtime.Ser }) + mux.Handle("POST", pattern_HeadscaleService_ExpireMachine_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/headscale.v1.HeadscaleService/ExpireMachine", runtime.WithHTTPPathPattern("/api/v1/machine/{machine_id}/expire")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_HeadscaleService_ExpireMachine_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_HeadscaleService_ExpireMachine_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + mux.Handle("GET", pattern_HeadscaleService_ListMachines_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() @@ -1517,6 +1592,26 @@ func RegisterHeadscaleServiceHandlerClient(ctx context.Context, mux *runtime.Ser }) + mux.Handle("POST", pattern_HeadscaleService_ExpireMachine_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req, "/headscale.v1.HeadscaleService/ExpireMachine", runtime.WithHTTPPathPattern("/api/v1/machine/{machine_id}/expire")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_HeadscaleService_ExpireMachine_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_HeadscaleService_ExpireMachine_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + mux.Handle("GET", pattern_HeadscaleService_ListMachines_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() @@ -1645,6 +1740,8 @@ var ( pattern_HeadscaleService_DeleteMachine_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"api", "v1", "machine", "machine_id"}, "")) + pattern_HeadscaleService_ExpireMachine_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3, 2, 4}, []string{"api", "v1", "machine", "machine_id", "expire"}, "")) + pattern_HeadscaleService_ListMachines_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "v1", "machine"}, "")) pattern_HeadscaleService_ShareMachine_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3, 2, 4, 1, 0, 4, 1, 5, 5}, []string{"api", "v1", "machine", "machine_id", "share", "namespace"}, "")) @@ -1681,6 +1778,8 @@ var ( forward_HeadscaleService_DeleteMachine_0 = runtime.ForwardResponseMessage + forward_HeadscaleService_ExpireMachine_0 = runtime.ForwardResponseMessage + forward_HeadscaleService_ListMachines_0 = runtime.ForwardResponseMessage forward_HeadscaleService_ShareMachine_0 = runtime.ForwardResponseMessage diff --git a/gen/go/headscale/v1/headscale_grpc.pb.go b/gen/go/headscale/v1/headscale_grpc.pb.go index 06a98b49..ab6cb70c 100644 --- a/gen/go/headscale/v1/headscale_grpc.pb.go +++ b/gen/go/headscale/v1/headscale_grpc.pb.go @@ -33,6 +33,7 @@ type HeadscaleServiceClient interface { GetMachine(ctx context.Context, in *GetMachineRequest, opts ...grpc.CallOption) (*GetMachineResponse, error) RegisterMachine(ctx context.Context, in *RegisterMachineRequest, opts ...grpc.CallOption) (*RegisterMachineResponse, error) DeleteMachine(ctx context.Context, in *DeleteMachineRequest, opts ...grpc.CallOption) (*DeleteMachineResponse, error) + ExpireMachine(ctx context.Context, in *ExpireMachineRequest, opts ...grpc.CallOption) (*ExpireMachineResponse, error) ListMachines(ctx context.Context, in *ListMachinesRequest, opts ...grpc.CallOption) (*ListMachinesResponse, error) ShareMachine(ctx context.Context, in *ShareMachineRequest, opts ...grpc.CallOption) (*ShareMachineResponse, error) UnshareMachine(ctx context.Context, in *UnshareMachineRequest, opts ...grpc.CallOption) (*UnshareMachineResponse, error) @@ -157,6 +158,15 @@ func (c *headscaleServiceClient) DeleteMachine(ctx context.Context, in *DeleteMa return out, nil } +func (c *headscaleServiceClient) ExpireMachine(ctx context.Context, in *ExpireMachineRequest, opts ...grpc.CallOption) (*ExpireMachineResponse, error) { + out := new(ExpireMachineResponse) + err := c.cc.Invoke(ctx, "/headscale.v1.HeadscaleService/ExpireMachine", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *headscaleServiceClient) ListMachines(ctx context.Context, in *ListMachinesRequest, opts ...grpc.CallOption) (*ListMachinesResponse, error) { out := new(ListMachinesResponse) err := c.cc.Invoke(ctx, "/headscale.v1.HeadscaleService/ListMachines", in, out, opts...) @@ -221,6 +231,7 @@ type HeadscaleServiceServer interface { GetMachine(context.Context, *GetMachineRequest) (*GetMachineResponse, error) RegisterMachine(context.Context, *RegisterMachineRequest) (*RegisterMachineResponse, error) DeleteMachine(context.Context, *DeleteMachineRequest) (*DeleteMachineResponse, error) + ExpireMachine(context.Context, *ExpireMachineRequest) (*ExpireMachineResponse, error) ListMachines(context.Context, *ListMachinesRequest) (*ListMachinesResponse, error) ShareMachine(context.Context, *ShareMachineRequest) (*ShareMachineResponse, error) UnshareMachine(context.Context, *UnshareMachineRequest) (*UnshareMachineResponse, error) @@ -270,6 +281,9 @@ func (UnimplementedHeadscaleServiceServer) RegisterMachine(context.Context, *Reg func (UnimplementedHeadscaleServiceServer) DeleteMachine(context.Context, *DeleteMachineRequest) (*DeleteMachineResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method DeleteMachine not implemented") } +func (UnimplementedHeadscaleServiceServer) ExpireMachine(context.Context, *ExpireMachineRequest) (*ExpireMachineResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ExpireMachine not implemented") +} func (UnimplementedHeadscaleServiceServer) ListMachines(context.Context, *ListMachinesRequest) (*ListMachinesResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method ListMachines not implemented") } @@ -514,6 +528,24 @@ func _HeadscaleService_DeleteMachine_Handler(srv interface{}, ctx context.Contex return interceptor(ctx, in, info, handler) } +func _HeadscaleService_ExpireMachine_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ExpireMachineRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(HeadscaleServiceServer).ExpireMachine(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/headscale.v1.HeadscaleService/ExpireMachine", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(HeadscaleServiceServer).ExpireMachine(ctx, req.(*ExpireMachineRequest)) + } + return interceptor(ctx, in, info, handler) +} + func _HeadscaleService_ListMachines_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(ListMachinesRequest) if err := dec(in); err != nil { @@ -659,6 +691,10 @@ var HeadscaleService_ServiceDesc = grpc.ServiceDesc{ MethodName: "DeleteMachine", Handler: _HeadscaleService_DeleteMachine_Handler, }, + { + MethodName: "ExpireMachine", + Handler: _HeadscaleService_ExpireMachine_Handler, + }, { MethodName: "ListMachines", Handler: _HeadscaleService_ListMachines_Handler, diff --git a/gen/go/headscale/v1/machine.pb.go b/gen/go/headscale/v1/machine.pb.go index b5ec2cda..deafbe5c 100644 --- a/gen/go/headscale/v1/machine.pb.go +++ b/gen/go/headscale/v1/machine.pb.go @@ -505,6 +505,100 @@ func (*DeleteMachineResponse) Descriptor() ([]byte, []int) { return file_headscale_v1_machine_proto_rawDescGZIP(), []int{6} } +type ExpireMachineRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + MachineId uint64 `protobuf:"varint,1,opt,name=machine_id,json=machineId,proto3" json:"machine_id,omitempty"` +} + +func (x *ExpireMachineRequest) Reset() { + *x = ExpireMachineRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_headscale_v1_machine_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ExpireMachineRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ExpireMachineRequest) ProtoMessage() {} + +func (x *ExpireMachineRequest) ProtoReflect() protoreflect.Message { + mi := &file_headscale_v1_machine_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ExpireMachineRequest.ProtoReflect.Descriptor instead. +func (*ExpireMachineRequest) Descriptor() ([]byte, []int) { + return file_headscale_v1_machine_proto_rawDescGZIP(), []int{7} +} + +func (x *ExpireMachineRequest) GetMachineId() uint64 { + if x != nil { + return x.MachineId + } + return 0 +} + +type ExpireMachineResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Machine *Machine `protobuf:"bytes,1,opt,name=machine,proto3" json:"machine,omitempty"` +} + +func (x *ExpireMachineResponse) Reset() { + *x = ExpireMachineResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_headscale_v1_machine_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ExpireMachineResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ExpireMachineResponse) ProtoMessage() {} + +func (x *ExpireMachineResponse) ProtoReflect() protoreflect.Message { + mi := &file_headscale_v1_machine_proto_msgTypes[8] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ExpireMachineResponse.ProtoReflect.Descriptor instead. +func (*ExpireMachineResponse) Descriptor() ([]byte, []int) { + return file_headscale_v1_machine_proto_rawDescGZIP(), []int{8} +} + +func (x *ExpireMachineResponse) GetMachine() *Machine { + if x != nil { + return x.Machine + } + return nil +} + type ListMachinesRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -516,7 +610,7 @@ type ListMachinesRequest struct { func (x *ListMachinesRequest) Reset() { *x = ListMachinesRequest{} if protoimpl.UnsafeEnabled { - mi := &file_headscale_v1_machine_proto_msgTypes[7] + mi := &file_headscale_v1_machine_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -529,7 +623,7 @@ func (x *ListMachinesRequest) String() string { func (*ListMachinesRequest) ProtoMessage() {} func (x *ListMachinesRequest) ProtoReflect() protoreflect.Message { - mi := &file_headscale_v1_machine_proto_msgTypes[7] + mi := &file_headscale_v1_machine_proto_msgTypes[9] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -542,7 +636,7 @@ func (x *ListMachinesRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListMachinesRequest.ProtoReflect.Descriptor instead. func (*ListMachinesRequest) Descriptor() ([]byte, []int) { - return file_headscale_v1_machine_proto_rawDescGZIP(), []int{7} + return file_headscale_v1_machine_proto_rawDescGZIP(), []int{9} } func (x *ListMachinesRequest) GetNamespace() string { @@ -563,7 +657,7 @@ type ListMachinesResponse struct { func (x *ListMachinesResponse) Reset() { *x = ListMachinesResponse{} if protoimpl.UnsafeEnabled { - mi := &file_headscale_v1_machine_proto_msgTypes[8] + mi := &file_headscale_v1_machine_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -576,7 +670,7 @@ func (x *ListMachinesResponse) String() string { func (*ListMachinesResponse) ProtoMessage() {} func (x *ListMachinesResponse) ProtoReflect() protoreflect.Message { - mi := &file_headscale_v1_machine_proto_msgTypes[8] + mi := &file_headscale_v1_machine_proto_msgTypes[10] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -589,7 +683,7 @@ func (x *ListMachinesResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListMachinesResponse.ProtoReflect.Descriptor instead. func (*ListMachinesResponse) Descriptor() ([]byte, []int) { - return file_headscale_v1_machine_proto_rawDescGZIP(), []int{8} + return file_headscale_v1_machine_proto_rawDescGZIP(), []int{10} } func (x *ListMachinesResponse) GetMachines() []*Machine { @@ -611,7 +705,7 @@ type ShareMachineRequest struct { func (x *ShareMachineRequest) Reset() { *x = ShareMachineRequest{} if protoimpl.UnsafeEnabled { - mi := &file_headscale_v1_machine_proto_msgTypes[9] + mi := &file_headscale_v1_machine_proto_msgTypes[11] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -624,7 +718,7 @@ func (x *ShareMachineRequest) String() string { func (*ShareMachineRequest) ProtoMessage() {} func (x *ShareMachineRequest) ProtoReflect() protoreflect.Message { - mi := &file_headscale_v1_machine_proto_msgTypes[9] + mi := &file_headscale_v1_machine_proto_msgTypes[11] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -637,7 +731,7 @@ func (x *ShareMachineRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ShareMachineRequest.ProtoReflect.Descriptor instead. func (*ShareMachineRequest) Descriptor() ([]byte, []int) { - return file_headscale_v1_machine_proto_rawDescGZIP(), []int{9} + return file_headscale_v1_machine_proto_rawDescGZIP(), []int{11} } func (x *ShareMachineRequest) GetMachineId() uint64 { @@ -665,7 +759,7 @@ type ShareMachineResponse struct { func (x *ShareMachineResponse) Reset() { *x = ShareMachineResponse{} if protoimpl.UnsafeEnabled { - mi := &file_headscale_v1_machine_proto_msgTypes[10] + mi := &file_headscale_v1_machine_proto_msgTypes[12] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -678,7 +772,7 @@ func (x *ShareMachineResponse) String() string { func (*ShareMachineResponse) ProtoMessage() {} func (x *ShareMachineResponse) ProtoReflect() protoreflect.Message { - mi := &file_headscale_v1_machine_proto_msgTypes[10] + mi := &file_headscale_v1_machine_proto_msgTypes[12] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -691,7 +785,7 @@ func (x *ShareMachineResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ShareMachineResponse.ProtoReflect.Descriptor instead. func (*ShareMachineResponse) Descriptor() ([]byte, []int) { - return file_headscale_v1_machine_proto_rawDescGZIP(), []int{10} + return file_headscale_v1_machine_proto_rawDescGZIP(), []int{12} } func (x *ShareMachineResponse) GetMachine() *Machine { @@ -713,7 +807,7 @@ type UnshareMachineRequest struct { func (x *UnshareMachineRequest) Reset() { *x = UnshareMachineRequest{} if protoimpl.UnsafeEnabled { - mi := &file_headscale_v1_machine_proto_msgTypes[11] + mi := &file_headscale_v1_machine_proto_msgTypes[13] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -726,7 +820,7 @@ func (x *UnshareMachineRequest) String() string { func (*UnshareMachineRequest) ProtoMessage() {} func (x *UnshareMachineRequest) ProtoReflect() protoreflect.Message { - mi := &file_headscale_v1_machine_proto_msgTypes[11] + mi := &file_headscale_v1_machine_proto_msgTypes[13] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -739,7 +833,7 @@ func (x *UnshareMachineRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UnshareMachineRequest.ProtoReflect.Descriptor instead. func (*UnshareMachineRequest) Descriptor() ([]byte, []int) { - return file_headscale_v1_machine_proto_rawDescGZIP(), []int{11} + return file_headscale_v1_machine_proto_rawDescGZIP(), []int{13} } func (x *UnshareMachineRequest) GetMachineId() uint64 { @@ -767,7 +861,7 @@ type UnshareMachineResponse struct { func (x *UnshareMachineResponse) Reset() { *x = UnshareMachineResponse{} if protoimpl.UnsafeEnabled { - mi := &file_headscale_v1_machine_proto_msgTypes[12] + mi := &file_headscale_v1_machine_proto_msgTypes[14] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -780,7 +874,7 @@ func (x *UnshareMachineResponse) String() string { func (*UnshareMachineResponse) ProtoMessage() {} func (x *UnshareMachineResponse) ProtoReflect() protoreflect.Message { - mi := &file_headscale_v1_machine_proto_msgTypes[12] + mi := &file_headscale_v1_machine_proto_msgTypes[14] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -793,7 +887,7 @@ func (x *UnshareMachineResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use UnshareMachineResponse.ProtoReflect.Descriptor instead. func (*UnshareMachineResponse) Descriptor() ([]byte, []int) { - return file_headscale_v1_machine_proto_rawDescGZIP(), []int{12} + return file_headscale_v1_machine_proto_rawDescGZIP(), []int{14} } func (x *UnshareMachineResponse) GetMachine() *Machine { @@ -817,7 +911,7 @@ type DebugCreateMachineRequest struct { func (x *DebugCreateMachineRequest) Reset() { *x = DebugCreateMachineRequest{} if protoimpl.UnsafeEnabled { - mi := &file_headscale_v1_machine_proto_msgTypes[13] + mi := &file_headscale_v1_machine_proto_msgTypes[15] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -830,7 +924,7 @@ func (x *DebugCreateMachineRequest) String() string { func (*DebugCreateMachineRequest) ProtoMessage() {} func (x *DebugCreateMachineRequest) ProtoReflect() protoreflect.Message { - mi := &file_headscale_v1_machine_proto_msgTypes[13] + mi := &file_headscale_v1_machine_proto_msgTypes[15] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -843,7 +937,7 @@ func (x *DebugCreateMachineRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DebugCreateMachineRequest.ProtoReflect.Descriptor instead. func (*DebugCreateMachineRequest) Descriptor() ([]byte, []int) { - return file_headscale_v1_machine_proto_rawDescGZIP(), []int{13} + return file_headscale_v1_machine_proto_rawDescGZIP(), []int{15} } func (x *DebugCreateMachineRequest) GetNamespace() string { @@ -885,7 +979,7 @@ type DebugCreateMachineResponse struct { func (x *DebugCreateMachineResponse) Reset() { *x = DebugCreateMachineResponse{} if protoimpl.UnsafeEnabled { - mi := &file_headscale_v1_machine_proto_msgTypes[14] + mi := &file_headscale_v1_machine_proto_msgTypes[16] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -898,7 +992,7 @@ func (x *DebugCreateMachineResponse) String() string { func (*DebugCreateMachineResponse) ProtoMessage() {} func (x *DebugCreateMachineResponse) ProtoReflect() protoreflect.Message { - mi := &file_headscale_v1_machine_proto_msgTypes[14] + mi := &file_headscale_v1_machine_proto_msgTypes[16] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -911,7 +1005,7 @@ func (x *DebugCreateMachineResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use DebugCreateMachineResponse.ProtoReflect.Descriptor instead. func (*DebugCreateMachineResponse) Descriptor() ([]byte, []int) { - return file_headscale_v1_machine_proto_rawDescGZIP(), []int{14} + return file_headscale_v1_machine_proto_rawDescGZIP(), []int{16} } func (x *DebugCreateMachineResponse) GetMachine() *Machine { @@ -994,59 +1088,67 @@ var file_headscale_v1_machine_proto_rawDesc = []byte{ 0x0a, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x49, 0x64, 0x22, 0x17, 0x0a, 0x15, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x33, 0x0a, 0x13, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x61, 0x63, - 0x68, 0x69, 0x6e, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, - 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x22, 0x49, 0x0a, 0x14, 0x4c, 0x69, - 0x73, 0x74, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x31, 0x0a, 0x08, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x73, 0x18, 0x01, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, - 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x08, 0x6d, 0x61, 0x63, - 0x68, 0x69, 0x6e, 0x65, 0x73, 0x22, 0x52, 0x0a, 0x13, 0x53, 0x68, 0x61, 0x72, 0x65, 0x4d, 0x61, - 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, - 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, - 0x52, 0x09, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x6e, - 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, - 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x22, 0x47, 0x0a, 0x14, 0x53, 0x68, 0x61, - 0x72, 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x2f, 0x0a, 0x07, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, - 0x31, 0x2e, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x07, 0x6d, 0x61, 0x63, 0x68, 0x69, - 0x6e, 0x65, 0x22, 0x54, 0x0a, 0x15, 0x55, 0x6e, 0x73, 0x68, 0x61, 0x72, 0x65, 0x4d, 0x61, 0x63, - 0x68, 0x69, 0x6e, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x6d, - 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, - 0x09, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x61, - 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, - 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x22, 0x49, 0x0a, 0x16, 0x55, 0x6e, 0x73, 0x68, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x35, 0x0a, 0x14, 0x45, 0x78, 0x70, 0x69, 0x72, 0x65, 0x4d, + 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, + 0x0a, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x04, 0x52, 0x09, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x49, 0x64, 0x22, 0x48, 0x0a, 0x15, + 0x45, 0x78, 0x70, 0x69, 0x72, 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2f, 0x0a, 0x07, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, + 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x07, 0x6d, + 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x22, 0x33, 0x0a, 0x13, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x61, + 0x63, 0x68, 0x69, 0x6e, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, + 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x22, 0x49, 0x0a, 0x14, 0x4c, + 0x69, 0x73, 0x74, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x31, 0x0a, 0x08, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x73, 0x18, + 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, + 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x08, 0x6d, 0x61, + 0x63, 0x68, 0x69, 0x6e, 0x65, 0x73, 0x22, 0x52, 0x0a, 0x13, 0x53, 0x68, 0x61, 0x72, 0x65, 0x4d, + 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, + 0x0a, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x04, 0x52, 0x09, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, + 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x22, 0x47, 0x0a, 0x14, 0x53, 0x68, 0x61, 0x72, 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2f, 0x0a, 0x07, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x07, 0x6d, 0x61, 0x63, 0x68, - 0x69, 0x6e, 0x65, 0x22, 0x77, 0x0a, 0x19, 0x44, 0x65, 0x62, 0x75, 0x67, 0x43, 0x72, 0x65, 0x61, - 0x74, 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x10, - 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, - 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, - 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x18, 0x04, - 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x22, 0x4d, 0x0a, 0x1a, - 0x44, 0x65, 0x62, 0x75, 0x67, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, - 0x6e, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2f, 0x0a, 0x07, 0x6d, 0x61, - 0x63, 0x68, 0x69, 0x6e, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x68, 0x65, - 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x61, 0x63, 0x68, 0x69, - 0x6e, 0x65, 0x52, 0x07, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x2a, 0x82, 0x01, 0x0a, 0x0e, - 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, 0x1f, - 0x0a, 0x1b, 0x52, 0x45, 0x47, 0x49, 0x53, 0x54, 0x45, 0x52, 0x5f, 0x4d, 0x45, 0x54, 0x48, 0x4f, - 0x44, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, - 0x1c, 0x0a, 0x18, 0x52, 0x45, 0x47, 0x49, 0x53, 0x54, 0x45, 0x52, 0x5f, 0x4d, 0x45, 0x54, 0x48, - 0x4f, 0x44, 0x5f, 0x41, 0x55, 0x54, 0x48, 0x5f, 0x4b, 0x45, 0x59, 0x10, 0x01, 0x12, 0x17, 0x0a, - 0x13, 0x52, 0x45, 0x47, 0x49, 0x53, 0x54, 0x45, 0x52, 0x5f, 0x4d, 0x45, 0x54, 0x48, 0x4f, 0x44, - 0x5f, 0x43, 0x4c, 0x49, 0x10, 0x02, 0x12, 0x18, 0x0a, 0x14, 0x52, 0x45, 0x47, 0x49, 0x53, 0x54, - 0x45, 0x52, 0x5f, 0x4d, 0x45, 0x54, 0x48, 0x4f, 0x44, 0x5f, 0x4f, 0x49, 0x44, 0x43, 0x10, 0x03, - 0x42, 0x29, 0x5a, 0x27, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6a, - 0x75, 0x61, 0x6e, 0x66, 0x6f, 0x6e, 0x74, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, - 0x65, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x67, 0x6f, 0x2f, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x33, + 0x69, 0x6e, 0x65, 0x22, 0x54, 0x0a, 0x15, 0x55, 0x6e, 0x73, 0x68, 0x61, 0x72, 0x65, 0x4d, 0x61, + 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, + 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, + 0x52, 0x09, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x6e, + 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, + 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x22, 0x49, 0x0a, 0x16, 0x55, 0x6e, 0x73, + 0x68, 0x61, 0x72, 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x2f, 0x0a, 0x07, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, + 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x07, 0x6d, 0x61, 0x63, + 0x68, 0x69, 0x6e, 0x65, 0x22, 0x77, 0x0a, 0x19, 0x44, 0x65, 0x62, 0x75, 0x67, 0x43, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, + 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, + 0x79, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x18, + 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x22, 0x4d, 0x0a, + 0x1a, 0x44, 0x65, 0x62, 0x75, 0x67, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4d, 0x61, 0x63, 0x68, + 0x69, 0x6e, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2f, 0x0a, 0x07, 0x6d, + 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x68, + 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x61, 0x63, 0x68, + 0x69, 0x6e, 0x65, 0x52, 0x07, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x2a, 0x82, 0x01, 0x0a, + 0x0e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, + 0x1f, 0x0a, 0x1b, 0x52, 0x45, 0x47, 0x49, 0x53, 0x54, 0x45, 0x52, 0x5f, 0x4d, 0x45, 0x54, 0x48, + 0x4f, 0x44, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, + 0x12, 0x1c, 0x0a, 0x18, 0x52, 0x45, 0x47, 0x49, 0x53, 0x54, 0x45, 0x52, 0x5f, 0x4d, 0x45, 0x54, + 0x48, 0x4f, 0x44, 0x5f, 0x41, 0x55, 0x54, 0x48, 0x5f, 0x4b, 0x45, 0x59, 0x10, 0x01, 0x12, 0x17, + 0x0a, 0x13, 0x52, 0x45, 0x47, 0x49, 0x53, 0x54, 0x45, 0x52, 0x5f, 0x4d, 0x45, 0x54, 0x48, 0x4f, + 0x44, 0x5f, 0x43, 0x4c, 0x49, 0x10, 0x02, 0x12, 0x18, 0x0a, 0x14, 0x52, 0x45, 0x47, 0x49, 0x53, + 0x54, 0x45, 0x52, 0x5f, 0x4d, 0x45, 0x54, 0x48, 0x4f, 0x44, 0x5f, 0x4f, 0x49, 0x44, 0x43, 0x10, + 0x03, 0x42, 0x29, 0x5a, 0x27, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, + 0x6a, 0x75, 0x61, 0x6e, 0x66, 0x6f, 0x6e, 0x74, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x73, 0x63, 0x61, + 0x6c, 0x65, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x67, 0x6f, 0x2f, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -1062,7 +1164,7 @@ func file_headscale_v1_machine_proto_rawDescGZIP() []byte { } var file_headscale_v1_machine_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_headscale_v1_machine_proto_msgTypes = make([]protoimpl.MessageInfo, 15) +var file_headscale_v1_machine_proto_msgTypes = make([]protoimpl.MessageInfo, 17) var file_headscale_v1_machine_proto_goTypes = []interface{}{ (RegisterMethod)(0), // 0: headscale.v1.RegisterMethod (*Machine)(nil), // 1: headscale.v1.Machine @@ -1072,37 +1174,40 @@ var file_headscale_v1_machine_proto_goTypes = []interface{}{ (*GetMachineResponse)(nil), // 5: headscale.v1.GetMachineResponse (*DeleteMachineRequest)(nil), // 6: headscale.v1.DeleteMachineRequest (*DeleteMachineResponse)(nil), // 7: headscale.v1.DeleteMachineResponse - (*ListMachinesRequest)(nil), // 8: headscale.v1.ListMachinesRequest - (*ListMachinesResponse)(nil), // 9: headscale.v1.ListMachinesResponse - (*ShareMachineRequest)(nil), // 10: headscale.v1.ShareMachineRequest - (*ShareMachineResponse)(nil), // 11: headscale.v1.ShareMachineResponse - (*UnshareMachineRequest)(nil), // 12: headscale.v1.UnshareMachineRequest - (*UnshareMachineResponse)(nil), // 13: headscale.v1.UnshareMachineResponse - (*DebugCreateMachineRequest)(nil), // 14: headscale.v1.DebugCreateMachineRequest - (*DebugCreateMachineResponse)(nil), // 15: headscale.v1.DebugCreateMachineResponse - (*Namespace)(nil), // 16: headscale.v1.Namespace - (*timestamppb.Timestamp)(nil), // 17: google.protobuf.Timestamp - (*PreAuthKey)(nil), // 18: headscale.v1.PreAuthKey + (*ExpireMachineRequest)(nil), // 8: headscale.v1.ExpireMachineRequest + (*ExpireMachineResponse)(nil), // 9: headscale.v1.ExpireMachineResponse + (*ListMachinesRequest)(nil), // 10: headscale.v1.ListMachinesRequest + (*ListMachinesResponse)(nil), // 11: headscale.v1.ListMachinesResponse + (*ShareMachineRequest)(nil), // 12: headscale.v1.ShareMachineRequest + (*ShareMachineResponse)(nil), // 13: headscale.v1.ShareMachineResponse + (*UnshareMachineRequest)(nil), // 14: headscale.v1.UnshareMachineRequest + (*UnshareMachineResponse)(nil), // 15: headscale.v1.UnshareMachineResponse + (*DebugCreateMachineRequest)(nil), // 16: headscale.v1.DebugCreateMachineRequest + (*DebugCreateMachineResponse)(nil), // 17: headscale.v1.DebugCreateMachineResponse + (*Namespace)(nil), // 18: headscale.v1.Namespace + (*timestamppb.Timestamp)(nil), // 19: google.protobuf.Timestamp + (*PreAuthKey)(nil), // 20: headscale.v1.PreAuthKey } var file_headscale_v1_machine_proto_depIdxs = []int32{ - 16, // 0: headscale.v1.Machine.namespace:type_name -> headscale.v1.Namespace + 18, // 0: headscale.v1.Machine.namespace:type_name -> headscale.v1.Namespace 0, // 1: headscale.v1.Machine.register_method:type_name -> headscale.v1.RegisterMethod - 17, // 2: headscale.v1.Machine.last_seen:type_name -> google.protobuf.Timestamp - 17, // 3: headscale.v1.Machine.last_successful_update:type_name -> google.protobuf.Timestamp - 17, // 4: headscale.v1.Machine.expiry:type_name -> google.protobuf.Timestamp - 18, // 5: headscale.v1.Machine.pre_auth_key:type_name -> headscale.v1.PreAuthKey - 17, // 6: headscale.v1.Machine.created_at:type_name -> google.protobuf.Timestamp + 19, // 2: headscale.v1.Machine.last_seen:type_name -> google.protobuf.Timestamp + 19, // 3: headscale.v1.Machine.last_successful_update:type_name -> google.protobuf.Timestamp + 19, // 4: headscale.v1.Machine.expiry:type_name -> google.protobuf.Timestamp + 20, // 5: headscale.v1.Machine.pre_auth_key:type_name -> headscale.v1.PreAuthKey + 19, // 6: headscale.v1.Machine.created_at:type_name -> google.protobuf.Timestamp 1, // 7: headscale.v1.RegisterMachineResponse.machine:type_name -> headscale.v1.Machine 1, // 8: headscale.v1.GetMachineResponse.machine:type_name -> headscale.v1.Machine - 1, // 9: headscale.v1.ListMachinesResponse.machines:type_name -> headscale.v1.Machine - 1, // 10: headscale.v1.ShareMachineResponse.machine:type_name -> headscale.v1.Machine - 1, // 11: headscale.v1.UnshareMachineResponse.machine:type_name -> headscale.v1.Machine - 1, // 12: headscale.v1.DebugCreateMachineResponse.machine:type_name -> headscale.v1.Machine - 13, // [13:13] is the sub-list for method output_type - 13, // [13:13] is the sub-list for method input_type - 13, // [13:13] is the sub-list for extension type_name - 13, // [13:13] is the sub-list for extension extendee - 0, // [0:13] is the sub-list for field type_name + 1, // 9: headscale.v1.ExpireMachineResponse.machine:type_name -> headscale.v1.Machine + 1, // 10: headscale.v1.ListMachinesResponse.machines:type_name -> headscale.v1.Machine + 1, // 11: headscale.v1.ShareMachineResponse.machine:type_name -> headscale.v1.Machine + 1, // 12: headscale.v1.UnshareMachineResponse.machine:type_name -> headscale.v1.Machine + 1, // 13: headscale.v1.DebugCreateMachineResponse.machine:type_name -> headscale.v1.Machine + 14, // [14:14] is the sub-list for method output_type + 14, // [14:14] is the sub-list for method input_type + 14, // [14:14] is the sub-list for extension type_name + 14, // [14:14] is the sub-list for extension extendee + 0, // [0:14] is the sub-list for field type_name } func init() { file_headscale_v1_machine_proto_init() } @@ -1198,7 +1303,7 @@ func file_headscale_v1_machine_proto_init() { } } file_headscale_v1_machine_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ListMachinesRequest); i { + switch v := v.(*ExpireMachineRequest); i { case 0: return &v.state case 1: @@ -1210,7 +1315,7 @@ func file_headscale_v1_machine_proto_init() { } } file_headscale_v1_machine_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ListMachinesResponse); i { + switch v := v.(*ExpireMachineResponse); i { case 0: return &v.state case 1: @@ -1222,7 +1327,7 @@ func file_headscale_v1_machine_proto_init() { } } file_headscale_v1_machine_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ShareMachineRequest); i { + switch v := v.(*ListMachinesRequest); i { case 0: return &v.state case 1: @@ -1234,7 +1339,7 @@ func file_headscale_v1_machine_proto_init() { } } file_headscale_v1_machine_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ShareMachineResponse); i { + switch v := v.(*ListMachinesResponse); i { case 0: return &v.state case 1: @@ -1246,7 +1351,7 @@ func file_headscale_v1_machine_proto_init() { } } file_headscale_v1_machine_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UnshareMachineRequest); i { + switch v := v.(*ShareMachineRequest); i { case 0: return &v.state case 1: @@ -1258,7 +1363,7 @@ func file_headscale_v1_machine_proto_init() { } } file_headscale_v1_machine_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UnshareMachineResponse); i { + switch v := v.(*ShareMachineResponse); i { case 0: return &v.state case 1: @@ -1270,7 +1375,7 @@ func file_headscale_v1_machine_proto_init() { } } file_headscale_v1_machine_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DebugCreateMachineRequest); i { + switch v := v.(*UnshareMachineRequest); i { case 0: return &v.state case 1: @@ -1282,6 +1387,30 @@ func file_headscale_v1_machine_proto_init() { } } file_headscale_v1_machine_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UnshareMachineResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_headscale_v1_machine_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DebugCreateMachineRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_headscale_v1_machine_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*DebugCreateMachineResponse); i { case 0: return &v.state @@ -1300,7 +1429,7 @@ func file_headscale_v1_machine_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_headscale_v1_machine_proto_rawDesc, NumEnums: 1, - NumMessages: 15, + NumMessages: 17, NumExtensions: 0, NumServices: 0, }, diff --git a/gen/openapiv2/headscale/v1/headscale.swagger.json b/gen/openapiv2/headscale/v1/headscale.swagger.json index f1e95cad..2274e22c 100644 --- a/gen/openapiv2/headscale/v1/headscale.swagger.json +++ b/gen/openapiv2/headscale/v1/headscale.swagger.json @@ -161,6 +161,37 @@ ] } }, + "/api/v1/machine/{machineId}/expire": { + "post": { + "operationId": "HeadscaleService_ExpireMachine", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ExpireMachineResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "machineId", + "in": "path", + "required": true, + "type": "string", + "format": "uint64" + } + ], + "tags": [ + "HeadscaleService" + ] + } + }, "/api/v1/machine/{machineId}/routes": { "get": { "summary": "--- Route start ---", @@ -649,6 +680,14 @@ } } }, + "v1ExpireMachineResponse": { + "type": "object", + "properties": { + "machine": { + "$ref": "#/definitions/v1Machine" + } + } + }, "v1ExpirePreAuthKeyRequest": { "type": "object", "properties": { diff --git a/proto/headscale/v1/headscale.proto b/proto/headscale/v1/headscale.proto index e7a63fc5..f7332a88 100644 --- a/proto/headscale/v1/headscale.proto +++ b/proto/headscale/v1/headscale.proto @@ -92,6 +92,12 @@ service HeadscaleService { }; } + rpc ExpireMachine(ExpireMachineRequest) returns (ExpireMachineResponse) { + option (google.api.http) = { + post: "/api/v1/machine/{machine_id}/expire" + }; + } + rpc ListMachines(ListMachinesRequest) returns (ListMachinesResponse) { option (google.api.http) = { get: "/api/v1/machine" diff --git a/proto/headscale/v1/machine.proto b/proto/headscale/v1/machine.proto index 4e53c4ad..ed99f002 100644 --- a/proto/headscale/v1/machine.proto +++ b/proto/headscale/v1/machine.proto @@ -64,6 +64,14 @@ message DeleteMachineRequest { message DeleteMachineResponse { } +message ExpireMachineRequest { + uint64 machine_id = 1; +} + +message ExpireMachineResponse { + Machine machine = 1; +} + message ListMachinesRequest { string namespace = 1; } From bd1d1b1a3b859f155012710cc2681f23d37707d5 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Sun, 21 Nov 2021 13:40:19 +0000 Subject: [PATCH 178/300] Implement ExpireMachine rpc --- grpcv1.go | 21 +++++++++++++++++++++ machine.go | 8 ++++++++ machine_test.go | 35 +++++++++++++++++++++++++++++++++++ 3 files changed, 64 insertions(+) diff --git a/grpcv1.go b/grpcv1.go index 40419c3c..1850ce7a 100644 --- a/grpcv1.go +++ b/grpcv1.go @@ -201,6 +201,27 @@ func (api headscaleV1APIServer) DeleteMachine( return &v1.DeleteMachineResponse{}, nil } +func (api headscaleV1APIServer) ExpireMachine( + ctx context.Context, + request *v1.ExpireMachineRequest, +) (*v1.ExpireMachineResponse, error) { + machine, err := api.h.GetMachineByID(request.GetMachineId()) + if err != nil { + return nil, err + } + + api.h.ExpireMachine( + machine, + ) + + log.Trace(). + Str("machine", machine.Name). + Time("expiry", *machine.Expiry). + Msg("machine expired") + + return &v1.ExpireMachineResponse{Machine: machine.toProto()}, nil +} + func (api headscaleV1APIServer) ListMachines( ctx context.Context, request *v1.ListMachinesRequest, diff --git a/machine.go b/machine.go index 813da35c..e34bff87 100644 --- a/machine.go +++ b/machine.go @@ -262,6 +262,14 @@ func (h *Headscale) UpdateMachine(machine *Machine) error { return nil } +// ExpireMachine takes a Machine struct and sets the expire field to now. +func (h *Headscale) ExpireMachine(machine *Machine) { + now := time.Now() + machine.Expiry = &now + + h.db.Save(machine) +} + // DeleteMachine softs deletes a Machine from the database. func (h *Headscale) DeleteMachine(machine *Machine) error { err := h.RemoveSharedMachineFromAllNamespaces(machine) diff --git a/machine_test.go b/machine_test.go index fdbc3cb5..eb090072 100644 --- a/machine_test.go +++ b/machine_test.go @@ -3,6 +3,7 @@ package headscale import ( "encoding/json" "strconv" + "time" "gopkg.in/check.v1" ) @@ -164,3 +165,37 @@ func (s *Suite) TestGetDirectPeers(c *check.C) { c.Assert(peersOfMachine0[5].Name, check.Equals, "testmachine7") c.Assert(peersOfMachine0[8].Name, check.Equals, "testmachine10") } + +func (s *Suite) TestExpireMachine(c *check.C) { + namespace, err := app.CreateNamespace("test") + c.Assert(err, check.IsNil) + + pak, err := app.CreatePreAuthKey(namespace.Name, false, false, nil) + c.Assert(err, check.IsNil) + + _, err = app.GetMachine("test", "testmachine") + c.Assert(err, check.NotNil) + + machine := &Machine{ + ID: 0, + MachineKey: "foo", + NodeKey: "bar", + DiscoKey: "faa", + Name: "testmachine", + NamespaceID: namespace.ID, + Registered: true, + RegisterMethod: RegisterMethodAuthKey, + AuthKeyID: uint(pak.ID), + Expiry: &time.Time{}, + } + app.db.Save(machine) + + machineFromDB, err := app.GetMachine("test", "testmachine") + c.Assert(err, check.IsNil) + + c.Assert(machineFromDB.isExpired(), check.Equals, false) + + app.ExpireMachine(machineFromDB) + + c.Assert(machineFromDB.isExpired(), check.Equals, true) +} From a2b9f3bedea8a3216b8885fc5b7196d0aace957d Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Sun, 21 Nov 2021 13:40:44 +0000 Subject: [PATCH 179/300] Add expire (logout) machine command --- cmd/headscale/cli/nodes.go | 51 +++++++++++++++ integration_cli_test.go | 127 +++++++++++++++++++++++++++++++++++++ 2 files changed, 178 insertions(+) diff --git a/cmd/headscale/cli/nodes.go b/cmd/headscale/cli/nodes.go index 7c2cd6c1..29679f0d 100644 --- a/cmd/headscale/cli/nodes.go +++ b/cmd/headscale/cli/nodes.go @@ -33,6 +33,13 @@ func init() { } nodeCmd.AddCommand(registerNodeCmd) + expireNodeCmd.Flags().IntP("identifier", "i", 0, "Node identifier (ID)") + err = expireNodeCmd.MarkFlagRequired("identifier") + if err != nil { + log.Fatalf(err.Error()) + } + nodeCmd.AddCommand(expireNodeCmd) + deleteNodeCmd.Flags().IntP("identifier", "i", 0, "Node identifier (ID)") err = deleteNodeCmd.MarkFlagRequired("identifier") if err != nil { @@ -177,6 +184,50 @@ var listNodesCmd = &cobra.Command{ }, } +var expireNodeCmd = &cobra.Command{ + Use: "expire", + Short: "Expire (log out) a machine in your network", + Aliases: []string{"logout"}, + Run: func(cmd *cobra.Command, args []string) { + output, _ := cmd.Flags().GetString("output") + + identifier, err := cmd.Flags().GetInt("identifier") + if err != nil { + ErrorOutput( + err, + fmt.Sprintf("Error converting ID to integer: %s", err), + output, + ) + + return + } + + ctx, client, conn, cancel := getHeadscaleCLIClient() + defer cancel() + defer conn.Close() + + request := &v1.ExpireMachineRequest{ + MachineId: uint64(identifier), + } + + response, err := client.ExpireMachine(ctx, request) + if err != nil { + ErrorOutput( + err, + fmt.Sprintf( + "Cannot expire machine: %s\n", + status.Convert(err).Message(), + ), + output, + ) + + return + } + + SuccessOutput(response.Machine, "Machine expired", output) + }, +} + var deleteNodeCmd = &cobra.Command{ Use: "delete", Short: "Delete a node", diff --git a/integration_cli_test.go b/integration_cli_test.go index 898e2cd7..ee940542 100644 --- a/integration_cli_test.go +++ b/integration_cli_test.go @@ -897,6 +897,133 @@ func (s *IntegrationCLITestSuite) TestNodeCommand() { assert.Len(s.T(), listOnlyMachineNamespaceAfterUnshare, 4) } +func (s *IntegrationCLITestSuite) TestNodeExpireCommand() { + namespace, err := s.createNamespace("machine-expire-namespace") + assert.Nil(s.T(), err) + + // Randomly generated machine keys + machineKeys := []string{ + "9b2ffa7e08cc421a3d2cca9012280f6a236fd0de0b4ce005b30a98ad930306fe", + "6abd00bb5fdda622db51387088c68e97e71ce58e7056aa54f592b6a8219d524c", + "f08305b4ee4250b95a70f3b7504d048d75d899993c624a26d422c67af0422507", + "8bc13285cee598acf76b1824a6f4490f7f2e3751b201e28aeb3b07fe81d5b4a1", + "cf7b0fd05da556fdc3bab365787b506fd82d64a70745db70e00e86c1b1c03084", + } + machines := make([]*v1.Machine, len(machineKeys)) + assert.Nil(s.T(), err) + + for index, machineKey := range machineKeys { + _, err := ExecuteCommand( + &s.headscale, + []string{ + "headscale", + "debug", + "create-node", + "--name", + fmt.Sprintf("machine-%d", index+1), + "--namespace", + namespace.Name, + "--key", + machineKey, + "--output", + "json", + }, + []string{}, + ) + assert.Nil(s.T(), err) + + machineResult, err := ExecuteCommand( + &s.headscale, + []string{ + "headscale", + "nodes", + "--namespace", + namespace.Name, + "register", + "--key", + machineKey, + "--output", + "json", + }, + []string{}, + ) + assert.Nil(s.T(), err) + + var machine v1.Machine + err = json.Unmarshal([]byte(machineResult), &machine) + assert.Nil(s.T(), err) + + machines[index] = &machine + } + + assert.Len(s.T(), machines, len(machineKeys)) + + listAllResult, err := ExecuteCommand( + &s.headscale, + []string{ + "headscale", + "nodes", + "list", + "--output", + "json", + }, + []string{}, + ) + assert.Nil(s.T(), err) + + var listAll []v1.Machine + err = json.Unmarshal([]byte(listAllResult), &listAll) + assert.Nil(s.T(), err) + + assert.Len(s.T(), listAll, 5) + + assert.True(s.T(), listAll[0].Expiry.AsTime().IsZero()) + assert.True(s.T(), listAll[1].Expiry.AsTime().IsZero()) + assert.True(s.T(), listAll[2].Expiry.AsTime().IsZero()) + assert.True(s.T(), listAll[3].Expiry.AsTime().IsZero()) + assert.True(s.T(), listAll[4].Expiry.AsTime().IsZero()) + + for i := 0; i < 3; i++ { + _, err := ExecuteCommand( + &s.headscale, + []string{ + "headscale", + "nodes", + "expire", + "--identifier", + fmt.Sprintf("%d", listAll[i].Id), + }, + []string{}, + ) + assert.Nil(s.T(), err) + } + + listAllAfterExpiryResult, err := ExecuteCommand( + &s.headscale, + []string{ + "headscale", + "nodes", + "list", + "--output", + "json", + }, + []string{}, + ) + assert.Nil(s.T(), err) + + var listAllAfterExpiry []v1.Machine + err = json.Unmarshal([]byte(listAllAfterExpiryResult), &listAllAfterExpiry) + assert.Nil(s.T(), err) + + assert.Len(s.T(), listAllAfterExpiry, 5) + + assert.True(s.T(), listAllAfterExpiry[0].Expiry.AsTime().Before(time.Now())) + assert.True(s.T(), listAllAfterExpiry[1].Expiry.AsTime().Before(time.Now())) + assert.True(s.T(), listAllAfterExpiry[2].Expiry.AsTime().Before(time.Now())) + assert.True(s.T(), listAllAfterExpiry[3].Expiry.AsTime().IsZero()) + assert.True(s.T(), listAllAfterExpiry[4].Expiry.AsTime().IsZero()) +} + func (s *IntegrationCLITestSuite) TestRouteCommand() { namespace, err := s.createNamespace("routes-namespace") assert.Nil(s.T(), err) From 8ccc51ae5750ffa099509c13b6dacbd523f2c55b Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Sun, 21 Nov 2021 13:45:19 +0000 Subject: [PATCH 180/300] Remove special case for authkey We no longer have weird expire behaviour, so we dont need this case --- api.go | 7 ------- 1 file changed, 7 deletions(-) diff --git a/api.go b/api.go index ee10e88f..61146c6a 100644 --- a/api.go +++ b/api.go @@ -132,13 +132,6 @@ func (h *Headscale) RegistrationHandler(ctx *gin.Context) { return } - // We dont care about expiry time if the method is AuthKey, as we dont set that. - if machine.Registered && machine.RegisterMethod == RegisterMethodAuthKey { - h.handleMachineValidRegistration(ctx, machineKey, *machine) - - return - } - if machine.Registered && !machine.isExpired() { h.handleMachineValidRegistration(ctx, machineKey, *machine) From c4ecc4db91acc64261bab971ab4191eab43eef06 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Sun, 21 Nov 2021 13:59:24 +0000 Subject: [PATCH 181/300] Simplify control flow in RegistrationHandler This commits tries to dismantle the complicated "if and or" in the RegistrationHandler by factoring out the "is Registrated" into a root if. This, together with some new comments, should hopefully make it a bit easier to follow what is happening in all the different cases that needs to be handled when a Node contacts the registration endpoint. --- api.go | 73 +++++++++++++++++++++++++++++++++------------------------- 1 file changed, 41 insertions(+), 32 deletions(-) diff --git a/api.go b/api.go index 61146c6a..8e8e6d67 100644 --- a/api.go +++ b/api.go @@ -116,41 +116,51 @@ func (h *Headscale) RegistrationHandler(ctx *gin.Context) { machine = &newMachine } - if !machine.Registered && req.Auth.AuthKey != "" { + if machine.Registered { + // If the NodeKey stored in headscale is the same as the key presented in a registration + // request, then we have a node that is either: + // - Trying to log out (sending a expiry in the past) + // - A valid, registered machine, looking for the node map + // - Expired machine wanting to reauthenticate + if machine.NodeKey == wgkey.Key(req.NodeKey).HexString() { + // The client sends an Expiry in the past if the client is requesting to expire the key (aka logout) + // https://github.com/tailscale/tailscale/blob/main/tailcfg/tailcfg.go#L648 + if !req.Expiry.IsZero() && req.Expiry.UTC().Before(now) { + h.handleMachineLogOut(ctx, machineKey, req, *machine) + + return + } + + // If machine is not expired, and is register, we have a already accepted this machine, + // let it proceed with a valid registration + if !machine.isExpired() { + h.handleMachineValidRegistration(ctx, machineKey, *machine) + + return + } + + // The machine has expired + h.handleMachineExpired(ctx, machineKey, req, *machine) + + return + } + + // The NodeKey we have matches OldNodeKey, which means this is a refresh after a key expiration + if machine.NodeKey == wgkey.Key(req.OldNodeKey).HexString() && + !machine.isExpired() { + h.handleMachineRefreshKey(ctx, machineKey, req, *machine) + + return + } + } + + // If the machine has AuthKey set, handle registration via PreAuthKeys + if req.Auth.AuthKey != "" { h.handleAuthKey(ctx, machineKey, req, *machine) return } - // We have the updated key! - if machine.NodeKey == wgkey.Key(req.NodeKey).HexString() { - // The client sends an Expiry in the past if the client is requesting to expire the key (aka logout) - // https://github.com/tailscale/tailscale/blob/main/tailcfg/tailcfg.go#L648 - if !req.Expiry.IsZero() && req.Expiry.UTC().Before(now) { - h.handleMachineLogOut(ctx, machineKey, req, *machine) - - return - } - - if machine.Registered && !machine.isExpired() { - h.handleMachineValidRegistration(ctx, machineKey, *machine) - - return - } - - h.handleMachineExpired(ctx, machineKey, req, *machine) - - return - } - - // The NodeKey we have matches OldNodeKey, which means this is a refresh after a key expiration - if machine.NodeKey == wgkey.Key(req.OldNodeKey).HexString() && - !machine.isExpired() { - h.handleMachineRefreshKey(ctx, machineKey, req, *machine) - - return - } - h.handleMachineRegistrationNew(ctx, machineKey, req, *machine) } @@ -286,8 +296,7 @@ func (h *Headscale) handleMachineLogOut( Str("machine", machine.Name). Msg("Client requested logout") - machine.Expiry = &reqisterRequest.Expiry // save the expiry so that the machine is marked as expired - h.db.Save(&machine) + h.ExpireMachine(&machine) resp.AuthURL = "" resp.MachineAuthorized = false From bda2d9c3b0566c270ba4e7f93185a440c50c1d1d Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Sun, 21 Nov 2021 14:00:48 +0000 Subject: [PATCH 182/300] Remove unused param --- api.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/api.go b/api.go index 8e8e6d67..bc1dccbb 100644 --- a/api.go +++ b/api.go @@ -126,7 +126,7 @@ func (h *Headscale) RegistrationHandler(ctx *gin.Context) { // The client sends an Expiry in the past if the client is requesting to expire the key (aka logout) // https://github.com/tailscale/tailscale/blob/main/tailcfg/tailcfg.go#L648 if !req.Expiry.IsZero() && req.Expiry.UTC().Before(now) { - h.handleMachineLogOut(ctx, machineKey, req, *machine) + h.handleMachineLogOut(ctx, machineKey, *machine) return } @@ -286,7 +286,6 @@ func (h *Headscale) getMapKeepAliveResponse( func (h *Headscale) handleMachineLogOut( ctx *gin.Context, idKey wgkey.Key, - reqisterRequest tailcfg.RegisterRequest, machine Machine, ) { resp := tailcfg.RegisterResponse{} From fd5f42c2e6241adbac3080a851d85b9883e32bfe Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Sun, 21 Nov 2021 21:14:13 +0000 Subject: [PATCH 183/300] Move handle expired machine to the end of registration --- api.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/api.go b/api.go index bc1dccbb..6901896f 100644 --- a/api.go +++ b/api.go @@ -138,11 +138,6 @@ func (h *Headscale) RegistrationHandler(ctx *gin.Context) { return } - - // The machine has expired - h.handleMachineExpired(ctx, machineKey, req, *machine) - - return } // The NodeKey we have matches OldNodeKey, which means this is a refresh after a key expiration @@ -152,6 +147,11 @@ func (h *Headscale) RegistrationHandler(ctx *gin.Context) { return } + + // The machine has expired + h.handleMachineExpired(ctx, machineKey, req, *machine) + + return } // If the machine has AuthKey set, handle registration via PreAuthKeys From c2393685f1747512f9bf45ac846a4a9716969cd5 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Sun, 21 Nov 2021 21:14:40 +0000 Subject: [PATCH 184/300] Remove expiry update in expiry, we dont want to extend it just because they _try_ to connect --- api.go | 6 ------ 1 file changed, 6 deletions(-) diff --git a/api.go b/api.go index 6901896f..565db969 100644 --- a/api.go +++ b/api.go @@ -370,12 +370,6 @@ func (h *Headscale) handleMachineExpired( strings.TrimSuffix(h.cfg.ServerURL, "/"), idKey.HexString()) } - if !reqisterRequest.Expiry.IsZero() { - machine.Expiry = &reqisterRequest.Expiry - } - - h.db.Save(&machine) - respBody, err := encode(resp, &idKey, h.privateKey) if err != nil { log.Error(). From 1687e3b03f92d7e063c780882af3884776015f5a Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Sun, 21 Nov 2021 21:29:27 +0000 Subject: [PATCH 185/300] Removed unused parameter --- api.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/api.go b/api.go index 565db969..c5002bb1 100644 --- a/api.go +++ b/api.go @@ -149,7 +149,7 @@ func (h *Headscale) RegistrationHandler(ctx *gin.Context) { } // The machine has expired - h.handleMachineExpired(ctx, machineKey, req, *machine) + h.handleMachineExpired(ctx, machineKey, *machine) return } @@ -351,7 +351,6 @@ func (h *Headscale) handleMachineValidRegistration( func (h *Headscale) handleMachineExpired( ctx *gin.Context, idKey wgkey.Key, - reqisterRequest tailcfg.RegisterRequest, machine Machine, ) { resp := tailcfg.RegisterResponse{} From b152e53b13f9c93900a1290af473a7eb1fcdc07e Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Sun, 21 Nov 2021 21:34:03 +0000 Subject: [PATCH 186/300] Use correct type for nodes command --- cmd/headscale/cli/nodes.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/cmd/headscale/cli/nodes.go b/cmd/headscale/cli/nodes.go index 29679f0d..4bc0e316 100644 --- a/cmd/headscale/cli/nodes.go +++ b/cmd/headscale/cli/nodes.go @@ -191,7 +191,7 @@ var expireNodeCmd = &cobra.Command{ Run: func(cmd *cobra.Command, args []string) { output, _ := cmd.Flags().GetString("output") - identifier, err := cmd.Flags().GetInt("identifier") + identifier, err := cmd.Flags().GetUint64("identifier") if err != nil { ErrorOutput( err, @@ -207,7 +207,7 @@ var expireNodeCmd = &cobra.Command{ defer conn.Close() request := &v1.ExpireMachineRequest{ - MachineId: uint64(identifier), + MachineId: identifier, } response, err := client.ExpireMachine(ctx, request) @@ -234,7 +234,7 @@ var deleteNodeCmd = &cobra.Command{ Run: func(cmd *cobra.Command, args []string) { output, _ := cmd.Flags().GetString("output") - identifier, err := cmd.Flags().GetInt("identifier") + identifier, err := cmd.Flags().GetUint64("identifier") if err != nil { ErrorOutput( err, @@ -250,7 +250,7 @@ var deleteNodeCmd = &cobra.Command{ defer conn.Close() getRequest := &v1.GetMachineRequest{ - MachineId: uint64(identifier), + MachineId: identifier, } getResponse, err := client.GetMachine(ctx, getRequest) @@ -331,7 +331,7 @@ func sharingWorker( defer cancel() defer conn.Close() - identifier, err := cmd.Flags().GetInt("identifier") + identifier, err := cmd.Flags().GetUint64("identifier") if err != nil { ErrorOutput(err, fmt.Sprintf("Error converting ID to integer: %s", err), output) @@ -339,7 +339,7 @@ func sharingWorker( } machineRequest := &v1.GetMachineRequest{ - MachineId: uint64(identifier), + MachineId: identifier, } machineResponse, err := client.GetMachine(ctx, machineRequest) From fac33e46e11475ed7061d286d6e97d67ce1bf53c Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Sun, 21 Nov 2021 21:35:36 +0000 Subject: [PATCH 187/300] Add long description for expire --- cmd/headscale/cli/nodes.go | 1 + 1 file changed, 1 insertion(+) diff --git a/cmd/headscale/cli/nodes.go b/cmd/headscale/cli/nodes.go index 4bc0e316..01d37a7d 100644 --- a/cmd/headscale/cli/nodes.go +++ b/cmd/headscale/cli/nodes.go @@ -187,6 +187,7 @@ var listNodesCmd = &cobra.Command{ var expireNodeCmd = &cobra.Command{ Use: "expire", Short: "Expire (log out) a machine in your network", + Long: "Expiring a node will keep the node in the database and force it to reauthenticate.", Aliases: []string{"logout"}, Run: func(cmd *cobra.Command, args []string) { output, _ := cmd.Flags().GetString("output") From fcd4d94927fb261ae24762b42efdd941087a97f6 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Sun, 21 Nov 2021 21:51:39 +0000 Subject: [PATCH 188/300] Clean up logging and error handling in oidc We should never expose errors via web, it gives attackers a lot of info (Insert OWASP guide). Also handle error that didnt separate not found gorm issue and other errors. --- oidc.go | 62 ++++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 48 insertions(+), 14 deletions(-) diff --git a/oidc.go b/oidc.go index fb27354b..e569fe10 100644 --- a/oidc.go +++ b/oidc.go @@ -4,6 +4,7 @@ import ( "context" "crypto/rand" "encoding/hex" + "errors" "fmt" "net/http" "regexp" @@ -15,6 +16,7 @@ import ( "github.com/patrickmn/go-cache" "github.com/rs/zerolog/log" "golang.org/x/oauth2" + "gorm.io/gorm" ) const ( @@ -37,7 +39,10 @@ func (h *Headscale) initOIDC() error { h.oidcProvider, err = oidc.NewProvider(context.Background(), h.cfg.OIDC.Issuer) if err != nil { - log.Error().Msgf("Could not retrieve OIDC Config: %s", err.Error()) + log.Error(). + Err(err). + Caller(). + Msgf("Could not retrieve OIDC Config: %s", err.Error()) return err } @@ -69,8 +74,8 @@ func (h *Headscale) initOIDC() error { // Puts machine key in cache so the callback can retrieve it using the oidc state param // Listens in /oidc/register/:mKey. func (h *Headscale) RegisterOIDC(ctx *gin.Context) { - mKeyStr := ctx.Param("mkey") - if mKeyStr == "" { + machineKeyStr := ctx.Param("mkey") + if machineKeyStr == "" { ctx.String(http.StatusBadRequest, "Wrong params") return @@ -78,7 +83,9 @@ func (h *Headscale) RegisterOIDC(ctx *gin.Context) { randomBlob := make([]byte, randomByteSize) if _, err := rand.Read(randomBlob); err != nil { - log.Error().Msg("could not read 16 bytes from rand") + log.Error(). + Caller(). + Msg("could not read 16 bytes from rand") ctx.String(http.StatusInternalServerError, "could not read 16 bytes from rand") return @@ -87,7 +94,7 @@ func (h *Headscale) RegisterOIDC(ctx *gin.Context) { stateStr := hex.EncodeToString(randomBlob)[:32] // place the machine key into the state cache, so it can be retrieved later - h.oidcStateCache.Set(stateStr, mKeyStr, oidcStateCacheExpiration) + h.oidcStateCache.Set(stateStr, machineKeyStr, oidcStateCacheExpiration) authURL := h.oauth2Config.AuthCodeURL(stateStr) log.Debug().Msgf("Redirecting to %s for authentication", authURL) @@ -130,7 +137,11 @@ func (h *Headscale) OIDCCallback(ctx *gin.Context) { idToken, err := verifier.Verify(context.Background(), rawIDToken) if err != nil { - ctx.String(http.StatusBadRequest, "Failed to verify id token: %s", err.Error()) + log.Error(). + Err(err). + Caller(). + Msg("failed to verify id token") + ctx.String(http.StatusBadRequest, "Failed to verify id token") return } @@ -145,27 +156,31 @@ func (h *Headscale) OIDCCallback(ctx *gin.Context) { // Extract custom claims var claims IDTokenClaims if err = idToken.Claims(&claims); err != nil { + log.Error(). + Err(err). + Caller(). + Msg("Failed to decode id token claims") ctx.String( http.StatusBadRequest, - fmt.Sprintf("Failed to decode id token claims: %s", err), + fmt.Sprintf("Failed to decode id token claims"), ) return } // retrieve machinekey from state cache - mKeyIf, mKeyFound := h.oidcStateCache.Get(state) + machineKeyIf, machineKeyFound := h.oidcStateCache.Get(state) - if !mKeyFound { + if !machineKeyFound { log.Error(). Msg("requested machine state key expired before authorisation completed") ctx.String(http.StatusBadRequest, "state has expired") return } - mKeyStr, mKeyOK := mKeyIf.(string) + machineKey, machineKeyOK := machineKeyIf.(string) - if !mKeyOK { + if !machineKeyOK { log.Error().Msg("could not get machine key from cache") ctx.String( http.StatusInternalServerError, @@ -176,7 +191,7 @@ func (h *Headscale) OIDCCallback(ctx *gin.Context) { } // retrieve machine information - machine, err := h.GetMachineByMachineKey(mKeyStr) + machine, err := h.GetMachineByMachineKey(machineKey) if err != nil { log.Error().Msg("machine key not found in database") ctx.String( @@ -195,12 +210,14 @@ func (h *Headscale) OIDCCallback(ctx *gin.Context) { log.Debug().Msg("Registering new machine after successful callback") namespace, err := h.GetNamespace(namespaceName) - if err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { namespace, err = h.CreateNamespace(namespaceName) if err != nil { log.Error(). - Msgf("could not create new namespace '%s'", claims.Email) + Err(err). + Caller(). + Msgf("could not create new namespace '%s'", namespaceName) ctx.String( http.StatusInternalServerError, "could not create new namespace", @@ -208,10 +225,26 @@ func (h *Headscale) OIDCCallback(ctx *gin.Context) { return } + } else if err != nil { + log.Error(). + Caller(). + Err(err). + Str("namespace", namespaceName). + Msg("could not find or create namespace") + ctx.String( + http.StatusInternalServerError, + "could not find or create namespace", + ) + + return } ip, err := h.getAvailableIP() if err != nil { + log.Error(). + Caller(). + Err(err). + Msg("could not get an IP from the pool") ctx.String( http.StatusInternalServerError, "could not get an IP from the pool", @@ -242,6 +275,7 @@ func (h *Headscale) OIDCCallback(ctx *gin.Context) { } log.Error(). + Caller(). Str("email", claims.Email). Str("username", claims.Username). Str("machine", machine.Name). From 74044f62f4bd67070ab72e743f2f6486e0203d22 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Sun, 21 Nov 2021 21:54:19 +0000 Subject: [PATCH 189/300] Remove anouther potential error leak --- oidc.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/oidc.go b/oidc.go index e569fe10..8fafc89a 100644 --- a/oidc.go +++ b/oidc.go @@ -149,7 +149,7 @@ func (h *Headscale) OIDCCallback(ctx *gin.Context) { // TODO: we can use userinfo at some point to grab additional information about the user (groups membership, etc) // userInfo, err := oidcProvider.UserInfo(context.Background(), oauth2.StaticTokenSource(oauth2Token)) // if err != nil { - // c.String(http.StatusBadRequest, fmt.Sprintf("Failed to retrieve userinfo: %s", err)) + // c.String(http.StatusBadRequest, fmt.Sprintf("Failed to retrieve userinfo")) // return // } From 5cbd4513a436592f6971a2a4c78b6fe332e067b5 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Mon, 22 Nov 2021 17:21:56 +0000 Subject: [PATCH 190/300] Simplify register function if --- machine.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/machine.go b/machine.go index e34bff87..d6903bd7 100644 --- a/machine.go +++ b/machine.go @@ -61,7 +61,7 @@ type ( ) // For the time being this method is rather naive. -func (machine Machine) isAlreadyRegistered() bool { +func (machine Machine) isRegistered() bool { return machine.Registered } @@ -612,7 +612,7 @@ func (h *Headscale) RegisterMachine( Str("machine", machine.Name). Msg("Attempting to register machine") - if machine.isAlreadyRegistered() { + if machine.isRegistered() { err := errMachineAlreadyRegistered log.Error(). Caller(). From e8faff4fe2bbdd36a383032dc4954fdc204768f7 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Mon, 22 Nov 2021 17:22:22 +0000 Subject: [PATCH 191/300] Use uint64 straight instead of converting --- cmd/headscale/cli/nodes.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/cmd/headscale/cli/nodes.go b/cmd/headscale/cli/nodes.go index 01d37a7d..f5117d95 100644 --- a/cmd/headscale/cli/nodes.go +++ b/cmd/headscale/cli/nodes.go @@ -33,14 +33,14 @@ func init() { } nodeCmd.AddCommand(registerNodeCmd) - expireNodeCmd.Flags().IntP("identifier", "i", 0, "Node identifier (ID)") + expireNodeCmd.Flags().Uint64P("identifier", "i", 0, "Node identifier (ID)") err = expireNodeCmd.MarkFlagRequired("identifier") if err != nil { log.Fatalf(err.Error()) } nodeCmd.AddCommand(expireNodeCmd) - deleteNodeCmd.Flags().IntP("identifier", "i", 0, "Node identifier (ID)") + deleteNodeCmd.Flags().Uint64P("identifier", "i", 0, "Node identifier (ID)") err = deleteNodeCmd.MarkFlagRequired("identifier") if err != nil { log.Fatalf(err.Error()) @@ -52,7 +52,7 @@ func init() { if err != nil { log.Fatalf(err.Error()) } - shareMachineCmd.Flags().IntP("identifier", "i", 0, "Node identifier (ID)") + shareMachineCmd.Flags().Uint64P("identifier", "i", 0, "Node identifier (ID)") err = shareMachineCmd.MarkFlagRequired("identifier") if err != nil { log.Fatalf(err.Error()) @@ -64,7 +64,7 @@ func init() { if err != nil { log.Fatalf(err.Error()) } - unshareMachineCmd.Flags().IntP("identifier", "i", 0, "Node identifier (ID)") + unshareMachineCmd.Flags().Uint64P("identifier", "i", 0, "Node identifier (ID)") err = unshareMachineCmd.MarkFlagRequired("identifier") if err != nil { log.Fatalf(err.Error()) @@ -269,7 +269,7 @@ var deleteNodeCmd = &cobra.Command{ } deleteRequest := &v1.DeleteMachineRequest{ - MachineId: uint64(identifier), + MachineId: identifier, } confirm := false From 200c10e48c19866379f096b4b322d1270d32a81d Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Mon, 22 Nov 2021 17:22:47 +0000 Subject: [PATCH 192/300] Add missing return in oidc.go --- oidc.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/oidc.go b/oidc.go index 8fafc89a..cdd4fc21 100644 --- a/oidc.go +++ b/oidc.go @@ -162,7 +162,7 @@ func (h *Headscale) OIDCCallback(ctx *gin.Context) { Msg("Failed to decode id token claims") ctx.String( http.StatusBadRequest, - fmt.Sprintf("Failed to decode id token claims"), + "Failed to decode id token claims", ) return @@ -272,6 +272,8 @@ func (h *Headscale) OIDCCallback(ctx *gin.Context) { `, claims.Email))) + + return } log.Error(). From e600ead3e9d8d8689013a2cd27c19977087fc74b Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Mon, 22 Nov 2021 19:32:11 +0000 Subject: [PATCH 193/300] Make sure nodes can reauthenticate This commit fixes an issue where nodes were not able to reauthenticate. --- api.go | 68 +++++++++++++++++++++++++++++++----------------------- machine.go | 10 ++++++++ oidc.go | 35 +++++++++++++++++++++++++++- 3 files changed, 83 insertions(+), 30 deletions(-) diff --git a/api.go b/api.go index c5002bb1..50af5522 100644 --- a/api.go +++ b/api.go @@ -375,13 +375,13 @@ func (h *Headscale) handleMachineExpired( Str("handler", "Registration"). Err(err). Msg("Cannot encode message") - machineRegistrations.WithLabelValues("new", "web", "error", machine.Namespace.Name). + machineRegistrations.WithLabelValues("reauth", "web", "error", machine.Namespace.Name). Inc() ctx.String(http.StatusInternalServerError, "") return } - machineRegistrations.WithLabelValues("new", "web", "success", machine.Namespace.Name). + machineRegistrations.WithLabelValues("reauth", "web", "success", machine.Namespace.Name). Inc() ctx.Data(http.StatusOK, "application/json; charset=utf-8", respBody) } @@ -503,36 +503,46 @@ func (h *Headscale) handleAuthKey( return } - log.Debug(). - Str("func", "handleAuthKey"). - Str("machine", machine.Name). - Msg("Authentication key was valid, proceeding to acquire an IP address") - ip, err := h.getAvailableIP() - if err != nil { - log.Error(). + if machine.isRegistered() { + log.Trace(). + Caller(). + Str("machine", machine.Name). + Msg("machine already registered, reauthenticating") + + h.RefreshMachine(&machine, reqisterRequest.Expiry) + } else { + log.Debug(). Str("func", "handleAuthKey"). Str("machine", machine.Name). - Msg("Failed to find an available IP") - machineRegistrations.WithLabelValues("new", "authkey", "error", machine.Namespace.Name). - Inc() + Msg("Authentication key was valid, proceeding to acquire an IP address") + ip, err := h.getAvailableIP() + if err != nil { + log.Error(). + Str("func", "handleAuthKey"). + Str("machine", machine.Name). + Msg("Failed to find an available IP") + machineRegistrations.WithLabelValues("new", "authkey", "error", machine.Namespace.Name). + Inc() - return + return + } + log.Info(). + Str("func", "handleAuthKey"). + Str("machine", machine.Name). + Str("ip", ip.String()). + Msgf("Assigning %s to %s", ip, machine.Name) + + machine.Expiry = &reqisterRequest.Expiry + machine.AuthKeyID = uint(pak.ID) + machine.IPAddress = ip.String() + machine.NamespaceID = pak.NamespaceID + machine.NodeKey = wgkey.Key(reqisterRequest.NodeKey). + HexString() + // we update it just in case + machine.Registered = true + machine.RegisterMethod = RegisterMethodAuthKey + h.db.Save(&machine) } - log.Info(). - Str("func", "handleAuthKey"). - Str("machine", machine.Name). - Str("ip", ip.String()). - Msgf("Assigning %s to %s", ip, machine.Name) - - machine.AuthKeyID = uint(pak.ID) - machine.IPAddress = ip.String() - machine.NamespaceID = pak.NamespaceID - machine.NodeKey = wgkey.Key(reqisterRequest.NodeKey). - HexString() - // we update it just in case - machine.Registered = true - machine.RegisterMethod = RegisterMethodAuthKey - h.db.Save(&machine) pak.Used = true h.db.Save(&pak) @@ -558,6 +568,6 @@ func (h *Headscale) handleAuthKey( log.Info(). Str("func", "handleAuthKey"). Str("machine", machine.Name). - Str("ip", ip.String()). + Str("ip", machine.IPAddress). Msg("Successfully authenticated via AuthKey") } diff --git a/machine.go b/machine.go index d6903bd7..dd7124ec 100644 --- a/machine.go +++ b/machine.go @@ -270,6 +270,15 @@ func (h *Headscale) ExpireMachine(machine *Machine) { h.db.Save(machine) } +// RefreshMachine takes a Machine struct and sets the expire field to now. +func (h *Headscale) RefreshMachine(machine *Machine, expiry time.Time) { + now := time.Now() + + machine.LastSuccessfulUpdate = &now + machine.Expiry = &expiry + h.db.Save(machine) +} + // DeleteMachine softs deletes a Machine from the database. func (h *Headscale) DeleteMachine(machine *Machine) error { err := h.RemoveSharedMachineFromAllNamespaces(machine) @@ -644,6 +653,7 @@ func (h *Headscale) RegisterMachine( machine.NamespaceID = namespace.ID machine.Registered = true machine.RegisterMethod = RegisterMethodCLI + machine.Expiry = &requestedTime h.db.Save(&machine) log.Trace(). diff --git a/oidc.go b/oidc.go index cdd4fc21..2f7d6d61 100644 --- a/oidc.go +++ b/oidc.go @@ -81,6 +81,11 @@ func (h *Headscale) RegisterOIDC(ctx *gin.Context) { return } + log.Trace(). + Caller(). + Str("machine_key", machineKeyStr). + Msg("Received oidc register call") + randomBlob := make([]byte, randomByteSize) if _, err := rand.Read(randomBlob); err != nil { log.Error(). @@ -124,7 +129,11 @@ func (h *Headscale) OIDCCallback(ctx *gin.Context) { return } - log.Debug().Msgf("AccessToken: %v", oauth2Token.AccessToken) + log.Trace(). + Caller(). + Str("code", code). + Str("state", state). + Msg("Got oidc callback") rawIDToken, rawIDTokenOK := oauth2Token.Extra("id_token").(string) if !rawIDTokenOK { @@ -202,6 +211,29 @@ func (h *Headscale) OIDCCallback(ctx *gin.Context) { return } + if machine.isRegistered() { + log.Trace(). + Caller(). + Str("machine", machine.Name). + Msg("machine already registered, reauthenticating") + + h.RefreshMachine(machine, requestedTime) + + ctx.Data(http.StatusOK, "text/html; charset=utf-8", []byte(fmt.Sprintf(` + + +

headscale

+

+ Reuthenticated as %s, you can now close this window. +

+ + + +`, claims.Email))) + + return + } + now := time.Now().UTC() if namespaceName, ok := h.getNamespaceFromEmail(claims.Email); ok { @@ -258,6 +290,7 @@ func (h *Headscale) OIDCCallback(ctx *gin.Context) { machine.Registered = true machine.RegisterMethod = RegisterMethodOIDC machine.LastSuccessfulUpdate = &now + machine.Expiry = &requestedTime h.db.Save(&machine) } From 021c464148c65f836f83b8a0196995587270b917 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Mon, 22 Nov 2021 19:32:52 +0000 Subject: [PATCH 194/300] Add cache for requested expiry times This commit adds a sentral cache to keep track of clients whom has requested an expiry time, but were we need to keep hold of it until the second request comes in. --- api.go | 22 +++++++++++++++++----- app.go | 23 +++++++++++++++++------ machine.go | 25 +++++++++++++++++++++++++ oidc.go | 8 ++++++++ 4 files changed, 67 insertions(+), 11 deletions(-) diff --git a/api.go b/api.go index 50af5522..92186ee8 100644 --- a/api.go +++ b/api.go @@ -19,10 +19,13 @@ import ( ) const ( - reservedResponseHeaderSize = 4 - RegisterMethodAuthKey = "authKey" - RegisterMethodOIDC = "oidc" - RegisterMethodCLI = "cli" + reservedResponseHeaderSize = 4 + RegisterMethodAuthKey = "authKey" + RegisterMethodOIDC = "oidc" + RegisterMethodCLI = "cli" + ErrRegisterMethodCLIDoesNotSupportExpire = Error( + "machines registered with CLI does not support expire", + ) ) // KeyHandler provides the Headscale pub key @@ -441,7 +444,16 @@ func (h *Headscale) handleMachineRegistrationNew( } if !reqisterRequest.Expiry.IsZero() { - machine.Expiry = &reqisterRequest.Expiry + log.Trace(). + Caller(). + Str("machine", machine.Name). + Time("expiry", reqisterRequest.Expiry). + Msg("Non-zero expiry time requested, adding to cache") + h.requestedExpiryCache.Set( + idKey.HexString(), + reqisterRequest.Expiry, + requestedExpiryCacheExpiration, + ) } machine.NodeKey = wgkey.Key(reqisterRequest.NodeKey).HexString() // save the NodeKey diff --git a/app.go b/app.go index b2b545b4..0d3332dd 100644 --- a/app.go +++ b/app.go @@ -53,6 +53,9 @@ const ( updateInterval = 5000 HTTPReadTimeout = 30 * time.Second + requestedExpiryCacheExpiration = time.Minute * 5 + requestedExpiryCacheCleanupInterval = time.Minute * 10 + errUnsupportedDatabase = Error("unsupported DB") errUnsupportedLetsEncryptChallengeType = Error( "unknown value for Lets Encrypt challenge type", @@ -139,6 +142,8 @@ type Headscale struct { oidcProvider *oidc.Provider oauth2Config *oauth2.Config oidcStateCache *cache.Cache + + requestedExpiryCache *cache.Cache } // NewHeadscale returns the Headscale app. @@ -171,13 +176,19 @@ func NewHeadscale(cfg Config) (*Headscale, error) { return nil, errUnsupportedDatabase } + requestedExpiryCache := cache.New( + requestedExpiryCacheExpiration, + requestedExpiryCacheCleanupInterval, + ) + app := Headscale{ - cfg: cfg, - dbType: cfg.DBtype, - dbString: dbString, - privateKey: privKey, - publicKey: &pubKey, - aclRules: tailcfg.FilterAllowAll, // default allowall + cfg: cfg, + dbType: cfg.DBtype, + dbString: dbString, + privateKey: privKey, + publicKey: &pubKey, + aclRules: tailcfg.FilterAllowAll, // default allowall + requestedExpiryCache: requestedExpiryCache, } err = app.initDB() diff --git a/machine.go b/machine.go index dd7124ec..06fec743 100644 --- a/machine.go +++ b/machine.go @@ -616,6 +616,31 @@ func (h *Headscale) RegisterMachine( return nil, errMachineNotFound } + // TODO(kradalby): Currently, if it fails to find a requested expiry, non will be set + // This means that if a user is to slow with register a machine, it will possibly not + // have the correct expiry. + requestedTime := time.Time{} + if requestedTimeIf, found := h.requestedExpiryCache.Get(machineKey.HexString()); found { + log.Trace(). + Caller(). + Str("machine", machine.Name). + Msg("Expiry time found in cache, assigning to node") + if reqTime, ok := requestedTimeIf.(time.Time); ok { + requestedTime = reqTime + } + } + + if machine.isRegistered() { + log.Trace(). + Caller(). + Str("machine", machine.Name). + Msg("machine already registered, reauthenticating") + + h.RefreshMachine(&machine, requestedTime) + + return &machine, nil + } + log.Trace(). Caller(). Str("machine", machine.Name). diff --git a/oidc.go b/oidc.go index 2f7d6d61..9b0a3087 100644 --- a/oidc.go +++ b/oidc.go @@ -199,6 +199,14 @@ func (h *Headscale) OIDCCallback(ctx *gin.Context) { return } + // TODO(kradalby): Currently, if it fails to find a requested expiry, non will be set + requestedTime := time.Time{} + if requestedTimeIf, found := h.requestedExpiryCache.Get(machineKey); found { + if reqTime, ok := requestedTimeIf.(time.Time); ok { + requestedTime = reqTime + } + } + // retrieve machine information machine, err := h.GetMachineByMachineKey(machineKey) if err != nil { From caf1b1cabce45fa30bee6fee71d9ede3816e1605 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Mon, 22 Nov 2021 19:35:24 +0000 Subject: [PATCH 195/300] Fix typo --- api.go | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/api.go b/api.go index 92186ee8..5a0b9d37 100644 --- a/api.go +++ b/api.go @@ -392,7 +392,7 @@ func (h *Headscale) handleMachineExpired( func (h *Headscale) handleMachineRefreshKey( ctx *gin.Context, idKey wgkey.Key, - reqisterRequest tailcfg.RegisterRequest, + registerRequest tailcfg.RegisterRequest, machine Machine, ) { resp := tailcfg.RegisterResponse{} @@ -401,7 +401,7 @@ func (h *Headscale) handleMachineRefreshKey( Str("handler", "Registration"). Str("machine", machine.Name). Msg("We have the OldNodeKey in the database. This is a key refresh") - machine.NodeKey = wgkey.Key(reqisterRequest.NodeKey).HexString() + machine.NodeKey = wgkey.Key(registerRequest.NodeKey).HexString() h.db.Save(&machine) resp.AuthURL = "" @@ -422,7 +422,7 @@ func (h *Headscale) handleMachineRefreshKey( func (h *Headscale) handleMachineRegistrationNew( ctx *gin.Context, idKey wgkey.Key, - reqisterRequest tailcfg.RegisterRequest, + registerRequest tailcfg.RegisterRequest, machine Machine, ) { resp := tailcfg.RegisterResponse{} @@ -443,20 +443,20 @@ func (h *Headscale) handleMachineRegistrationNew( strings.TrimSuffix(h.cfg.ServerURL, "/"), idKey.HexString()) } - if !reqisterRequest.Expiry.IsZero() { + if !registerRequest.Expiry.IsZero() { log.Trace(). Caller(). Str("machine", machine.Name). - Time("expiry", reqisterRequest.Expiry). + Time("expiry", registerRequest.Expiry). Msg("Non-zero expiry time requested, adding to cache") h.requestedExpiryCache.Set( idKey.HexString(), - reqisterRequest.Expiry, + registerRequest.Expiry, requestedExpiryCacheExpiration, ) } - machine.NodeKey = wgkey.Key(reqisterRequest.NodeKey).HexString() // save the NodeKey + machine.NodeKey = wgkey.Key(registerRequest.NodeKey).HexString() // save the NodeKey h.db.Save(&machine) respBody, err := encode(resp, &idKey, h.privateKey) @@ -475,15 +475,15 @@ func (h *Headscale) handleMachineRegistrationNew( func (h *Headscale) handleAuthKey( ctx *gin.Context, idKey wgkey.Key, - reqisterRequest tailcfg.RegisterRequest, + registerRequest tailcfg.RegisterRequest, machine Machine, ) { log.Debug(). Str("func", "handleAuthKey"). - Str("machine", reqisterRequest.Hostinfo.Hostname). - Msgf("Processing auth key for %s", reqisterRequest.Hostinfo.Hostname) + Str("machine", registerRequest.Hostinfo.Hostname). + Msgf("Processing auth key for %s", registerRequest.Hostinfo.Hostname) resp := tailcfg.RegisterResponse{} - pak, err := h.checkKeyValidity(reqisterRequest.Auth.AuthKey) + pak, err := h.checkKeyValidity(registerRequest.Auth.AuthKey) if err != nil { log.Error(). Str("func", "handleAuthKey"). @@ -521,7 +521,7 @@ func (h *Headscale) handleAuthKey( Str("machine", machine.Name). Msg("machine already registered, reauthenticating") - h.RefreshMachine(&machine, reqisterRequest.Expiry) + h.RefreshMachine(&machine, registerRequest.Expiry) } else { log.Debug(). Str("func", "handleAuthKey"). @@ -544,11 +544,11 @@ func (h *Headscale) handleAuthKey( Str("ip", ip.String()). Msgf("Assigning %s to %s", ip, machine.Name) - machine.Expiry = &reqisterRequest.Expiry + machine.Expiry = ®isterRequest.Expiry machine.AuthKeyID = uint(pak.ID) machine.IPAddress = ip.String() machine.NamespaceID = pak.NamespaceID - machine.NodeKey = wgkey.Key(reqisterRequest.NodeKey). + machine.NodeKey = wgkey.Key(registerRequest.NodeKey). HexString() // we update it just in case machine.Registered = true From 68dc2a70dbe789a7b7de78439dd52d0a6f0a0cab Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Mon, 22 Nov 2021 19:51:16 +0000 Subject: [PATCH 196/300] Update neighbours if node is expired or refreshed In addition, only pass the map of registered and not expired nodes to clients. --- api.go | 2 +- machine.go | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/api.go b/api.go index 5a0b9d37..6b75ad45 100644 --- a/api.go +++ b/api.go @@ -186,7 +186,7 @@ func (h *Headscale) getMapResponse( return nil, err } - peers, err := h.getPeers(machine) + peers, err := h.getValidPeers(machine) if err != nil { log.Error(). Str("func", "getMapResponse"). diff --git a/machine.go b/machine.go index 06fec743..306b3a47 100644 --- a/machine.go +++ b/machine.go @@ -207,6 +207,23 @@ func (h *Headscale) getPeers(machine *Machine) (Machines, error) { return peers, nil } +func (h *Headscale) getValidPeers(machine *Machine) (Machines, error) { + validPeers := make(Machines, 0) + + peers, err := h.getPeers(machine) + if err != nil { + return Machines{}, err + } + + for _, peer := range peers { + if peer.isRegistered() && !peer.isExpired() { + validPeers = append(validPeers, peer) + } + } + + return validPeers, nil +} + func (h *Headscale) ListMachines() ([]Machine, error) { machines := []Machine{} if err := h.db.Preload("AuthKey").Preload("AuthKey.Namespace").Preload("Namespace").Find(&machines).Error; err != nil { @@ -267,6 +284,8 @@ func (h *Headscale) ExpireMachine(machine *Machine) { now := time.Now() machine.Expiry = &now + h.setLastStateChangeToNow(machine.Namespace.Name) + h.db.Save(machine) } @@ -276,6 +295,9 @@ func (h *Headscale) RefreshMachine(machine *Machine, expiry time.Time) { machine.LastSuccessfulUpdate = &now machine.Expiry = &expiry + + h.setLastStateChangeToNow(machine.Namespace.Name) + h.db.Save(machine) } From 1f1c45a2c0834be24d85ebdc8bad7bfe6049b200 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Mon, 22 Nov 2021 19:59:44 +0000 Subject: [PATCH 197/300] Fix cli_test --- app_test.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app_test.go b/app_test.go index 947062bf..bff13933 100644 --- a/app_test.go +++ b/app_test.go @@ -5,6 +5,7 @@ import ( "os" "testing" + "github.com/patrickmn/go-cache" "gopkg.in/check.v1" "inet.af/netaddr" ) @@ -47,6 +48,10 @@ func (s *Suite) ResetDB(c *check.C) { cfg: cfg, dbType: "sqlite3", dbString: tmpDir + "/headscale_test.db", + requestedExpiryCache: cache.New( + requestedExpiryCacheExpiration, + requestedExpiryCacheCleanupInterval, + ), } err = app.initDB() if err != nil { From 349264830b6689edd7d2f008cdc03c32ed4a55e0 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Tue, 23 Nov 2021 11:27:44 +0000 Subject: [PATCH 198/300] Use .1 --- integration_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integration_test.go b/integration_test.go index c2679918..d6aedf19 100644 --- a/integration_test.go +++ b/integration_test.go @@ -28,7 +28,7 @@ import ( "tailscale.com/ipn/ipnstate" ) -var tailscaleVersions = []string{"1.18.0", "1.16.2", "1.14.3", "1.12.3"} +var tailscaleVersions = []string{"1.18.1", "1.16.2", "1.14.3", "1.12.3"} type TestNamespace struct { count int From 2eca344f0e8ff0467afa2318029132b3c77fafc5 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Wed, 24 Nov 2021 10:13:41 +0000 Subject: [PATCH 199/300] Fix gocritic --- .golangci.yaml | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/.golangci.yaml b/.golangci.yaml index 2defdc88..09b50d78 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -25,9 +25,6 @@ linters: - godox - ireturn - # In progress - - gocritic - # We should strive to enable these: - wrapcheck - dupl @@ -51,3 +48,10 @@ linters-settings: - ip - ok - c + + gocritic: + disabled-checks: + - appendAssign + # TODO(kradalby): Remove this + - ifElseChain + From 9968992be078073c913e19805bac500a2f019a0b Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Wed, 24 Nov 2021 10:47:20 +0000 Subject: [PATCH 200/300] Fix prettier --- .golangci.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/.golangci.yaml b/.golangci.yaml index 09b50d78..965f5496 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -54,4 +54,3 @@ linters-settings: - appendAssign # TODO(kradalby): Remove this - ifElseChain - From fdd64d98c81c186743b5eec60928292d743d656e Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Wed, 24 Nov 2021 12:15:32 +0000 Subject: [PATCH 201/300] Add missing iff to handle expired preauthkey machines --- api.go | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/api.go b/api.go index 6b75ad45..43a9f235 100644 --- a/api.go +++ b/api.go @@ -364,15 +364,21 @@ func (h *Headscale) handleMachineExpired( Str("machine", machine.Name). Msg("Machine registration has expired. Sending a authurl to register") - if h.cfg.OIDC.Issuer != "" { - resp.AuthURL = fmt.Sprintf("%s/oidc/register/%s", - strings.TrimSuffix(h.cfg.ServerURL, "/"), idKey.HexString()) - } else { - resp.AuthURL = fmt.Sprintf("%s/register?key=%s", - strings.TrimSuffix(h.cfg.ServerURL, "/"), idKey.HexString()) + if registerRequest.Auth.AuthKey != "" { + h.handleAuthKey(ctx, machineKey, registerRequest, machine) + + return } - respBody, err := encode(resp, &idKey, h.privateKey) + if h.cfg.OIDC.Issuer != "" { + resp.AuthURL = fmt.Sprintf("%s/oidc/register/%s", + strings.TrimSuffix(h.cfg.ServerURL, "/"), machineKey.HexString()) + } else { + resp.AuthURL = fmt.Sprintf("%s/register?key=%s", + strings.TrimSuffix(h.cfg.ServerURL, "/"), machineKey.HexString()) + } + + respBody, err := encode(resp, &machineKey, h.privateKey) if err != nil { log.Error(). Str("handler", "Registration"). From dcbf289470a72adef36ca39e5b5e8e3081459e9c Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Wed, 24 Nov 2021 12:15:55 +0000 Subject: [PATCH 202/300] Rename idKey to machineKey to keep consistency --- api.go | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/api.go b/api.go index 43a9f235..96a1d5cb 100644 --- a/api.go +++ b/api.go @@ -288,7 +288,7 @@ func (h *Headscale) getMapKeepAliveResponse( func (h *Headscale) handleMachineLogOut( ctx *gin.Context, - idKey wgkey.Key, + machineKey wgkey.Key, machine Machine, ) { resp := tailcfg.RegisterResponse{} @@ -303,7 +303,7 @@ func (h *Headscale) handleMachineLogOut( resp.AuthURL = "" resp.MachineAuthorized = false resp.User = *machine.Namespace.toUser() - respBody, err := encode(resp, &idKey, h.privateKey) + respBody, err := encode(resp, &machineKey, h.privateKey) if err != nil { log.Error(). Str("handler", "Registration"). @@ -318,7 +318,7 @@ func (h *Headscale) handleMachineLogOut( func (h *Headscale) handleMachineValidRegistration( ctx *gin.Context, - idKey wgkey.Key, + machineKey wgkey.Key, machine Machine, ) { resp := tailcfg.RegisterResponse{} @@ -334,7 +334,7 @@ func (h *Headscale) handleMachineValidRegistration( resp.User = *machine.Namespace.toUser() resp.Login = *machine.Namespace.toLogin() - respBody, err := encode(resp, &idKey, h.privateKey) + respBody, err := encode(resp, &machineKey, h.privateKey) if err != nil { log.Error(). Str("handler", "Registration"). @@ -353,7 +353,8 @@ func (h *Headscale) handleMachineValidRegistration( func (h *Headscale) handleMachineExpired( ctx *gin.Context, - idKey wgkey.Key, + machineKey wgkey.Key, + registerRequest tailcfg.RegisterRequest, machine Machine, ) { resp := tailcfg.RegisterResponse{} @@ -397,7 +398,7 @@ func (h *Headscale) handleMachineExpired( func (h *Headscale) handleMachineRefreshKey( ctx *gin.Context, - idKey wgkey.Key, + machineKey wgkey.Key, registerRequest tailcfg.RegisterRequest, machine Machine, ) { @@ -412,7 +413,7 @@ func (h *Headscale) handleMachineRefreshKey( resp.AuthURL = "" resp.User = *machine.Namespace.toUser() - respBody, err := encode(resp, &idKey, h.privateKey) + respBody, err := encode(resp, &machineKey, h.privateKey) if err != nil { log.Error(). Str("handler", "Registration"). @@ -427,7 +428,7 @@ func (h *Headscale) handleMachineRefreshKey( func (h *Headscale) handleMachineRegistrationNew( ctx *gin.Context, - idKey wgkey.Key, + machineKey wgkey.Key, registerRequest tailcfg.RegisterRequest, machine Machine, ) { @@ -442,11 +443,11 @@ func (h *Headscale) handleMachineRegistrationNew( resp.AuthURL = fmt.Sprintf( "%s/oidc/register/%s", strings.TrimSuffix(h.cfg.ServerURL, "/"), - idKey.HexString(), + machineKey.HexString(), ) } else { resp.AuthURL = fmt.Sprintf("%s/register?key=%s", - strings.TrimSuffix(h.cfg.ServerURL, "/"), idKey.HexString()) + strings.TrimSuffix(h.cfg.ServerURL, "/"), machineKey.HexString()) } if !registerRequest.Expiry.IsZero() { @@ -456,7 +457,7 @@ func (h *Headscale) handleMachineRegistrationNew( Time("expiry", registerRequest.Expiry). Msg("Non-zero expiry time requested, adding to cache") h.requestedExpiryCache.Set( - idKey.HexString(), + machineKey.HexString(), registerRequest.Expiry, requestedExpiryCacheExpiration, ) @@ -465,7 +466,7 @@ func (h *Headscale) handleMachineRegistrationNew( machine.NodeKey = wgkey.Key(registerRequest.NodeKey).HexString() // save the NodeKey h.db.Save(&machine) - respBody, err := encode(resp, &idKey, h.privateKey) + respBody, err := encode(resp, &machineKey, h.privateKey) if err != nil { log.Error(). Str("handler", "Registration"). @@ -480,7 +481,7 @@ func (h *Headscale) handleMachineRegistrationNew( func (h *Headscale) handleAuthKey( ctx *gin.Context, - idKey wgkey.Key, + machineKey wgkey.Key, registerRequest tailcfg.RegisterRequest, machine Machine, ) { @@ -497,7 +498,7 @@ func (h *Headscale) handleAuthKey( Err(err). Msg("Failed authentication via AuthKey") resp.MachineAuthorized = false - respBody, err := encode(resp, &idKey, h.privateKey) + respBody, err := encode(resp, &machineKey, h.privateKey) if err != nil { log.Error(). Str("func", "handleAuthKey"). @@ -567,7 +568,7 @@ func (h *Headscale) handleAuthKey( resp.MachineAuthorized = true resp.User = *pak.Namespace.toUser() - respBody, err := encode(resp, &idKey, h.privateKey) + respBody, err := encode(resp, &machineKey, h.privateKey) if err != nil { log.Error(). Str("func", "handleAuthKey"). From cec1e86b588b28d7c62eb371dc91ca5af7a22e87 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Wed, 24 Nov 2021 12:16:56 +0000 Subject: [PATCH 203/300] Add missing request arguemnt --- api.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api.go b/api.go index 96a1d5cb..1a51fdfe 100644 --- a/api.go +++ b/api.go @@ -152,7 +152,7 @@ func (h *Headscale) RegistrationHandler(ctx *gin.Context) { } // The machine has expired - h.handleMachineExpired(ctx, machineKey, *machine) + h.handleMachineExpired(ctx, machineKey, req, *machine) return } From f2e273b8a2d182adfb427f872245d16e1751aee1 Mon Sep 17 00:00:00 2001 From: Adrien Raffin-Caboisse Date: Wed, 24 Nov 2021 15:51:24 +0100 Subject: [PATCH 204/300] fix(derp-example): change regionid in nodes Using a wrong regionid value lead to non working DERP custom server. No checks are performed for this kind of errors making it difficult to find. --- derp-example.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/derp-example.yaml b/derp-example.yaml index a9901bef..0ebe32ed 100644 --- a/derp-example.yaml +++ b/derp-example.yaml @@ -5,8 +5,8 @@ regions: regioncode: custom regionname: My Region nodes: - - name: 1a - regionid: 1 + - name: 900a + regionid: 900 hostname: myderp.mydomain.no ipv4: 123.123.123.123 ipv6: "2604:a880:400:d1::828:b001" From 58fd6c4ba5d23684113493db43b542719bc15c3d Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Fri, 26 Nov 2021 07:13:00 +0000 Subject: [PATCH 205/300] Revert postgres constant value changes "postgresql" to "postgres" --- app.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app.go b/app.go index 0d3332dd..0a12d965 100644 --- a/app.go +++ b/app.go @@ -48,7 +48,7 @@ import ( const ( AuthPrefix = "Bearer " - Postgres = "postgresql" + Postgres = "postgres" Sqlite = "sqlite3" updateInterval = 5000 HTTPReadTimeout = 30 * time.Second From c7f3e0632bf7adfe7d5e6bd98deb19ad89510b63 Mon Sep 17 00:00:00 2001 From: Ward Vandewege Date: Thu, 25 Nov 2021 19:23:10 -0500 Subject: [PATCH 206/300] When creating a preauthkey, the default expiration was passed through as a nil value, instead of the default value (1h). This resulted in the preauthkey being created with expiration key '0001-01-01 00:00:00', which meant the key would not work, because it was already expired. This commit applies the default expiration time (1h) when a preauthkey is created without a specific expiration. It also updates an integration test to make sure this bug does not reoccur. --- cmd/headscale/cli/preauthkeys.go | 12 +++++------- integration_cli_test.go | 7 ++++++- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/cmd/headscale/cli/preauthkeys.go b/cmd/headscale/cli/preauthkeys.go index 9d5c838f..5342085c 100644 --- a/cmd/headscale/cli/preauthkeys.go +++ b/cmd/headscale/cli/preauthkeys.go @@ -13,7 +13,7 @@ import ( ) const ( - DefaultPreAuthKeyExpiry = 24 * time.Hour + DefaultPreAuthKeyExpiry = 1 * time.Hour ) func init() { @@ -145,14 +145,12 @@ var createPreAuthKeyCmd = &cobra.Command{ Ephemeral: ephemeral, } - if cmd.Flags().Changed("expiration") { - duration, _ := cmd.Flags().GetDuration("expiration") - expiration := time.Now().UTC().Add(duration) + duration, _ := cmd.Flags().GetDuration("expiration") + expiration := time.Now().UTC().Add(duration) - log.Trace().Dur("expiration", duration).Msg("expiration has been set") + log.Trace().Dur("expiration", duration).Msg("expiration has been set") - request.Expiration = timestamppb.New(expiration) - } + request.Expiration = timestamppb.New(expiration) ctx, client, conn, cancel := getHeadscaleCLIClient() defer cancel() diff --git a/integration_cli_test.go b/integration_cli_test.go index ee940542..92d497a9 100644 --- a/integration_cli_test.go +++ b/integration_cli_test.go @@ -426,7 +426,12 @@ func (s *IntegrationCLITestSuite) TestPreAuthKeyCommandWithoutExpiry() { assert.Nil(s.T(), err) assert.Len(s.T(), listedPreAuthKeys, 1) - assert.True(s.T(), time.Time{}.Equal(listedPreAuthKeys[0].Expiration.AsTime())) + + assert.True(s.T(), listedPreAuthKeys[0].Expiration.AsTime().After(time.Now())) + assert.True( + s.T(), + listedPreAuthKeys[0].Expiration.AsTime().Before(time.Now().Add(time.Minute*70)), + ) } func (s *IntegrationCLITestSuite) TestPreAuthKeyCommandReusableEphemeral() { From b6ae60cc44bd8218443c21da0473d9b193c8ca7d Mon Sep 17 00:00:00 2001 From: Ward Vandewege Date: Fri, 26 Nov 2021 14:49:51 -0500 Subject: [PATCH 207/300] The `create-node` subcommand under `debug` needs a 64 character key. --- cmd/headscale/cli/debug.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/cmd/headscale/cli/debug.go b/cmd/headscale/cli/debug.go index 46bdb9e8..226ae5e7 100644 --- a/cmd/headscale/cli/debug.go +++ b/cmd/headscale/cli/debug.go @@ -77,6 +77,16 @@ var createNodeCmd = &cobra.Command{ return } + if len(machineKey) != 64 { + err = fmt.Errorf("key '%s' too short, must be 64 hexadecimal characters", machineKey) + ErrorOutput( + err, + fmt.Sprintf("Error: %s", err), + output, + ) + + return + } routes, err := cmd.Flags().GetStringSlice("route") if err != nil { From 50b47adaa3fa0db6878be66154dd82fa1aee6c9d Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Fri, 26 Nov 2021 23:27:09 +0000 Subject: [PATCH 208/300] Upgrade tailscale to 1.18 --- go.mod | 9 +++---- go.sum | 85 ++++++++++++++++++++++++++++++++++++++++------------------ 2 files changed, 63 insertions(+), 31 deletions(-) diff --git a/go.mod b/go.mod index 65a8582e..e036effc 100644 --- a/go.mod +++ b/go.mod @@ -44,12 +44,11 @@ require ( github.com/ugorji/go v1.2.6 // indirect github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect github.com/zsais/go-gin-prometheus v0.1.0 - go4.org/mem v0.0.0-20210711025021-927187094b94 // indirect - golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 - golang.org/x/net v0.0.0-20211104170005-ce137452f963 // indirect + go4.org/mem v0.0.0-20210711025021-927187094b94 + golang.org/x/crypto v0.0.0-20211117183948-ae814b36b871 golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 golang.org/x/sync v0.0.0-20210220032951-036812b2e83c - golang.org/x/sys v0.0.0-20211103235746-7861aae1554b // indirect + golang.org/x/sys v0.0.0-20211124211545-fe61309f8881 // indirect google.golang.org/genproto v0.0.0-20211104193956-4c6863e31247 google.golang.org/grpc v1.42.0 google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0 @@ -62,5 +61,5 @@ require ( gorm.io/driver/sqlite v1.1.5 gorm.io/gorm v1.21.15 inet.af/netaddr v0.0.0-20211027220019-c74959edd3b6 - tailscale.com v1.14.6 + tailscale.com v1.18.1 ) diff --git a/go.sum b/go.sum index a34ef217..8d4b4587 100644 --- a/go.sum +++ b/go.sum @@ -79,6 +79,7 @@ github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMx github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= +github.com/akutz/memconn v0.1.0/go.mod h1:Jo8rI7m0NieZyLI5e2CDlRdRqRRB4S7Xp77ukDjH+Fw= github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs= github.com/alecthomas/kingpin v2.2.6+incompatible/go.mod h1:59OFYbFVLKQKq+mqrL6Rw5bR0c3ACQaawgXx0QYndlE= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= @@ -106,6 +107,16 @@ github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQ github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.38.52/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= +github.com/aws/aws-sdk-go-v2 v1.9.2/go.mod h1:cK/D0BBs0b/oWPIcX/Z/obahJK1TT7IPVjy53i/mX/4= +github.com/aws/aws-sdk-go-v2/config v1.8.3/go.mod h1:4AEiLtAb8kLs7vgw2ZV3p2VZ1+hBavOc84hqxVNpCyw= +github.com/aws/aws-sdk-go-v2/credentials v1.4.3/go.mod h1:FNNC6nQZQUuyhq5aE5c7ata8o9e4ECGmS4lAXC7o1mQ= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.6.0/go.mod h1:gqlclDEZp4aqJOancXK6TN24aKhT0W0Ae9MHk3wzTMM= +github.com/aws/aws-sdk-go-v2/internal/ini v1.2.4/go.mod h1:ZcBrrI3zBKlhGFNYWvju0I3TR93I7YIgAfy82Fh4lcQ= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.3.2/go.mod h1:72HRZDLMtmVQiLG2tLfQcaWLCssELvGl+Zf2WVxMmR8= +github.com/aws/aws-sdk-go-v2/service/ssm v1.12.0/go.mod h1:m3cb1hedrft0oYmueH0CkBgRdiwczuKRXPr0tilSpz4= +github.com/aws/aws-sdk-go-v2/service/sso v1.4.2/go.mod h1:NBvT9R1MEF+Ud6ApJKM0G+IkPchKS7p7c2YPKwHmBOk= +github.com/aws/aws-sdk-go-v2/service/sts v1.7.2/go.mod h1:8EzeIqfWt2wWT4rJVu3f21TfrhJ8AEMzVybRNSb/b4g= +github.com/aws/smithy-go v1.8.0/go.mod h1:SObp3lf9smib00L/v3U2eAKG8FyQ7iLrJnQiAmR5n+E= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= @@ -173,8 +184,9 @@ github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:ma github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/creack/pty v1.1.11 h1:07n33Z8lZxZ2qwegKbObQohDhXDQxiMMz1NOUGYlesw= github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/creack/pty v1.1.17 h1:QeVUsEDNrLBW4tMgZHvxy18sKtr6VI492kBhUfhDJNI= +github.com/creack/pty v1.1.17/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= github.com/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4= github.com/daixiang0/gci v0.2.4/go.mod h1:+AV8KmHTGxxwp/pY84TLQfFKp2vuKXXJVzF3kD/hfR4= github.com/daixiang0/gci v0.2.7/go.mod h1:+4dZ7TISfSmqfAGv59ePaHfNzgGtIkHAhhdKggP1JAc= @@ -232,7 +244,7 @@ github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= -github.com/frankban/quicktest v1.13.0/go.mod h1:qLE0fzW0VuyUAJgPU19zByoIr0HtCHN/r/VLSOOIySU= +github.com/frankban/quicktest v1.14.0/go.mod h1:NeW+ay9A/U67EYXNFA1nPE8e/tnQv/09mUdL/ijj8og= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= @@ -240,11 +252,12 @@ github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= +github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M= github.com/gin-gonic/gin v1.7.4 h1:QmUZXrvJ9qZ3GfWvQ+2wnW/1ePrTEJqPKMYEU3lD/DM= github.com/gin-gonic/gin v1.7.4/go.mod h1:jD2toBW3GZUr5UMcdrwQA10I7RuaFOl/SGeDjXkfUtY= github.com/github/fakeca v0.1.0/go.mod h1:+bormgoGMMuamOscx7N91aOuUST7wdaJ2rNjeohylyo= github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= -github.com/gliderlabs/ssh v0.3.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= +github.com/gliderlabs/ssh v0.3.3/go.mod h1:ZSS+CUoKHDrqVakTfTWUlKSr9MtMFkC4UvtQKD7O914= github.com/go-critic/go-critic v0.5.2/go.mod h1:cc0+HvdE3lFpqLecgqMaJcvWWH77sLdBp+wLGPM1Yyo= github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E= github.com/go-git/go-billy/v5 v5.0.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0= @@ -260,9 +273,8 @@ github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vb github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= -github.com/go-multierror/multierror v1.0.2/go.mod h1:U7SZR/D9jHgt2nkSj8XcbCWdmVM2igraCHQ3HC1HiKY= github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8= -github.com/go-ole/go-ole v1.2.5/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= +github.com/go-ole/go-ole v1.2.6-0.20210915003542-8b1f7f90f6b1/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A= github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= @@ -271,6 +283,7 @@ github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= github.com/go-playground/universal-translator v0.18.0 h1:82dyy6p4OuJq4/CByFNOn/jYrnRPArHwAcmLoJZxyho= github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA= +github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4= github.com/go-playground/validator/v10 v10.9.0 h1:NgTtmN58D0m8+UuxtYmGztBJB7VnPgjj221I1QHci2A= github.com/go-playground/validator/v10 v10.9.0/go.mod h1:74x4gJWsvQexRdW8Pn3dXSGrTK4nAUsbPlLADvpJkos= @@ -291,7 +304,11 @@ github.com/go-toolsmith/typep v1.0.0/go.mod h1:JSQCQMUPdRlMZFswiq3TGpNp1GMktqkR2 github.com/go-toolsmith/typep v1.0.2/go.mod h1:JSQCQMUPdRlMZFswiq3TGpNp1GMktqkR2Ns5AIQkATU= github.com/go-xmlfmt/xmlfmt v0.0.0-20191208150333-d5b6f63a941b/go.mod h1:aUCEOzzezBEjDBbFBoSiya/gduyIiWYRP6CnSFIV8AM= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= +github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= +github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= +github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/godbus/dbus/v5 v5.0.5/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gofrs/flock v0.8.0/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= @@ -340,7 +357,6 @@ github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2/go.mod h1:k9Qvh+8juN+UKMCS/3jFtGICgW8O96FVaZsaxdzDkR4= github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a/go.mod h1:ryS0uhF+x9jgbj/N71xsEqODy9BN81/GonCZiOzirOk= github.com/golangci/errcheck v0.0.0-20181223084120-ef45e06d44b6/go.mod h1:DbHgvLiFKX1Sh2T1w8Q/h4NAI8MHIpzCdnBUDTXU3I0= @@ -377,7 +393,6 @@ github.com/google/go-github v17.0.0+incompatible h1:N0LgJ1j65A7kfXrZnUDaYCs/Sf4r github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= -github.com/google/goexpect v0.0.0-20210430020637-ab937bf7fd6f/go.mod h1:n1ej5+FqyEytMt/mugVDZLIiqTMO+vsrgY+kM6ohzN0= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/goterm v0.0.0-20190703233501-fc88cf888a3f/go.mod h1:nOFQdrUlIlx6M6ODdSpBj1NVA+VgLC6kmw60mkw34H4= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= @@ -401,6 +416,7 @@ github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3 github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/gookit/color v1.3.1/go.mod h1:R3ogXq2B9rTbXoSHJ1HyUVAZ3poOJHpd9nQmyGZsfvQ= @@ -417,6 +433,7 @@ github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2z github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gostaticanalysis/analysisutil v0.0.0-20190318220348-4088753ea4d3/go.mod h1:eEOZF4jCKGi+aprrirO9e7WKB3beBRtWgqGunKl6pKE= github.com/gostaticanalysis/analysisutil v0.0.3/go.mod h1:eEOZF4jCKGi+aprrirO9e7WKB3beBRtWgqGunKl6pKE= @@ -600,10 +617,10 @@ github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351/go.mod h1:CT github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.10.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.11.0/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.11.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= -github.com/klauspost/compress v1.12.2/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= github.com/klauspost/compress v1.13.6 h1:P76CopJELS0TiO2mebmnzgWaajssP/EszplttgQxcgc= github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= github.com/klauspost/pgzip v1.2.5/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= @@ -704,7 +721,7 @@ github.com/mdlayher/socket v0.0.0-20210307095302-262dc9984e00/go.mod h1:GAFlyu4/ github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b h1:j7+1HpAFS1zy5+Q4qx1fWh90gTKwiN4QCGoY9TWyyO4= github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= -github.com/miekg/dns v1.1.42/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4= +github.com/miekg/dns v1.1.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= @@ -795,8 +812,8 @@ github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrap github.com/pelletier/go-toml v1.9.3 h1:zeC5b1GviRUyKYd6OJPvBU/mcVDVoL1OhT17FCt5dSQ= github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= -github.com/peterbourgon/ff/v2 v2.0.0/go.mod h1:xjwr+t+SjWm4L46fcj/D+Ap+6ME7+HqFzaP22pP5Ggk= github.com/peterbourgon/ff/v3 v3.0.0/go.mod h1:UILIFjRH5a/ar8TjXYLTkIvSvekZqPm5Eb/qbGk6CT0= +github.com/peterbourgon/ff/v3 v3.1.0/go.mod h1:XNJLY8EIl6MjMVjBS4F0+G0LYoAqs0DTa4rmHHukKDE= github.com/phayes/checkstyle v0.0.0-20170904204023-bfd46e6a821d/go.mod h1:3OzsM7FXDQlpCiw2j81fOmAwQLnZnLGXVKUzeKQXIAw= github.com/philip-bui/grpc-zerolog v1.0.1 h1:EMacvLRUd2O1K0eWod27ZP5CY1iTNkhBDLSN+Q4JEvA= github.com/philip-bui/grpc-zerolog v1.0.1/go.mod h1:qXbiq/2X4ZUMMshsqlWyTHOcw7ns+GZmlqZZN05ZHcQ= @@ -811,7 +828,7 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= github.com/pkg/profile v1.5.0/go.mod h1:qBsxPvzyUincmltOk6iyRVxHYg4adc0OFOv72ZdLa18= github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= -github.com/pkg/sftp v1.13.0/go.mod h1:41g+FIPlQUTDCveupEmEA65IoiQFrtgCeDopC4ajGIM= +github.com/pkg/sftp v1.13.4/go.mod h1:LzqnAvaD5TWeNBsZpfKxSYn1MbjWwOsCIAFFJbpIsK8= 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/polyfloyd/go-errorlint v0.0.0-20201006195004-351e25ade6e3/go.mod h1:wi9BfjxjF/bwiZ701TzmfKu6UKC357IOAtNr0Td0Lvw= @@ -907,6 +924,7 @@ github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic github.com/sirupsen/logrus v1.8.0/go.mod h1:4GuYW9TZmE769R5STWrRakJc4UqQ3+QQ95fyz7ENv1A= github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e/go.mod h1:XV66xRDqSt+GTGFMVlhk3ULuV0y9ZmzeVGR4mloJI3M= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= @@ -966,10 +984,12 @@ github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69 github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= github.com/tailscale/certstore v0.0.0-20210528134328-066c94b793d3/go.mod h1:2P+hpOwd53e7JMX/L4f3VXkv1G+33ES6IWZSrkIeWNs= github.com/tailscale/depaware v0.0.0-20201214215404-77d1e9757027/go.mod h1:p9lPsd+cx33L3H9nNoecRRxPssFKUwwI50I3pZ0yT+8= +github.com/tailscale/goexpect v0.0.0-20210902213824-6e8c725cea41/go.mod h1:/roCdA6gg6lQyw/Oz6gIIGu3ggJKYhF+WC/AQReE5XQ= github.com/tailscale/goupnp v1.0.1-0.20210804011211-c64d0f06ea05/go.mod h1:PdCqy9JzfWMJf1H5UJW2ip33/d4YkoKN0r67yKH1mG8= github.com/tailscale/hujson v0.0.0-20200924210142-dde312d0d6a2/go.mod h1:STqf+YV0ADdzk4ejtXFsGqDpATP9JoL0OB+hiFQbkdE= github.com/tailscale/hujson v0.0.0-20210923003652-c3758b31534b h1:bvys7zUACfrQZBUAinXREfu9jUgq6KcNQcQnUkzl3yc= github.com/tailscale/hujson v0.0.0-20210923003652-c3758b31534b/go.mod h1:iTDXJsA6A2wNNjurgic2rk+is6uzU4U2NLm4T+edr6M= +github.com/tailscale/netlink v1.1.1-0.20211101221916-cabfb018fe85/go.mod h1:NzVQi3Mleb+qzq8VmcWpSkcSYxXIg0DkI6XDzpVkhJ0= github.com/tcnksm/go-httpstat v0.2.0/go.mod h1:s3JVJFtQxtBEBC9dwcdTTXS9xFnM3SXAZwPG41aurT8= github.com/tcnksm/go-latest v0.0.0-20170313132115-e3007ae9052e h1:IWllFTiDjjLIf2oeKxpIUmtiDV5sn71VgeQgg6vcE7k= github.com/tcnksm/go-latest v0.0.0-20170313132115-e3007ae9052e/go.mod h1:d7u6HkTYKSv5m6MCKkOQlHwaShTMl3HjqSGW3XtVhXM= @@ -995,6 +1015,7 @@ github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLY github.com/ugorji/go/codec v1.2.6 h1:7kbGefxLoDBuYXOms4yD7223OpNMMPNPZxXk5TvFcyQ= github.com/ugorji/go/codec v1.2.6/go.mod h1:V6TCNZ4PHqoHGFZuSG1W8nrCzzdgA2DozYxWFFpvxTw= github.com/ulikunitz/xz v0.5.7/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= +github.com/ulikunitz/xz v0.5.10/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= github.com/ultraware/funlen v0.0.3/go.mod h1:Dp4UiAus7Wdb9KUZsYWZEWiRzGuM2kXM1lPbfaF6xhA= github.com/ultraware/whitespace v0.0.4/go.mod h1:aVMh/gQve5Maj9hQ/hg+F75lr/X5A89uZnzAmWSineA= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= @@ -1005,7 +1026,9 @@ github.com/valyala/fasthttp v1.16.0/go.mod h1:YOKImeEosDdBPnxc0gy7INqi3m1zK6A+xl github.com/valyala/quicktemplate v1.6.3/go.mod h1:fwPzK2fHuYEODzJ9pkw0ipCPNHZ2tD5KW4lOuSdPKzY= github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE= +github.com/vishvananda/netlink v1.1.1-0.20211101163509-b10eb8fe5cf6/go.mod h1:twkDnbuQxJYemMlGd4JFIcuhgX83tXhKS2B/PRMpOho= github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU= +github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0= github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4= github.com/xanzy/ssh-agent v0.3.0/go.mod h1:3s9xbODqPuuhK9JV1R321M/FlMZSBvE5aY6eAcqrDh0= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= @@ -1093,14 +1116,16 @@ golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20201208171446-5f87f3452ae9/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= -golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= +golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 h1:7I4JAnoQBe7ZtJcBaYHi5UtiO8tQHbUSXxL+pnGRANg= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20211117183948-ae814b36b871 h1:/pEO3GD/ABYAjuakUS6xSEmmlyVS4kxBNkeA9tLJiTI= +golang.org/x/crypto v0.0.0-20211117183948-ae814b36b871/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1194,10 +1219,12 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211104170005-ce137452f963 h1:8gJUadZl+kWvZBqG/LautX0X6qe5qTC2VI/3V3NBRAY= -golang.org/x/net v0.0.0-20211104170005-ce137452f963/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210903162142-ad29c8ab022f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211101193420-4a448f8816b3/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211111083644-e5c967477495/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 h1:CIJ76btIcR3eFI5EgSo6k1qKw9KJexJuRLI9G7Hp5wE= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1271,6 +1298,7 @@ golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1284,6 +1312,7 @@ golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200728102440-3e129f6d46b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1313,6 +1342,7 @@ golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210525143221-35b2ab0089ea/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1322,9 +1352,11 @@ golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210817190340-bfb29a6856f2/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211103235746-7861aae1554b h1:1VkfZQv42XQlA/jchYumAnv1UPo6RgF9rJFkTgZIxO4= +golang.org/x/sys v0.0.0-20210906170528-6f6e22806c34/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211110154304-99a53858aa08/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211124211545-fe61309f8881 h1:TyHqChC80pFkXWraUUf6RuB5IqFdQieMLwwCJokV2pc= +golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -1339,7 +1371,6 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7-0.20210524175448-3115f89c4b99/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1448,8 +1479,10 @@ golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.zx2c4.com/wireguard v0.0.0-20210624150102-15b24b6179e0/go.mod h1:laHzsbfMhGSobUmruXWAyMKKHSqvIcrqZJMyHD+/3O8= -golang.zx2c4.com/wireguard/windows v0.3.16/go.mod h1:f80rkFY2CKQklps1GHE15k/M4Tq78aofbr1iQM5MTVY= +golang.zx2c4.com/wintun v0.0.0-20211104114900-415007cec224/go.mod h1:deeaetjYA+DHMHg+sMSMI58GrEteJUUzzw7en6TJQcI= +golang.zx2c4.com/wireguard v0.0.0-20210905140043-2ef39d47540c/go.mod h1:laHzsbfMhGSobUmruXWAyMKKHSqvIcrqZJMyHD+/3O8= +golang.zx2c4.com/wireguard v0.0.0-20211116201604-de7c702ace45/go.mod h1:evxZIqfCetExY5piKXGAxJYwvXWkps9zTCkWpkoGFxw= +golang.zx2c4.com/wireguard/windows v0.4.10/go.mod h1:v7w/8FC48tTBm1IzScDVPEEb0/GjLta+T0ybpP9UWRg= google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= @@ -1649,13 +1682,12 @@ honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.6/go.mod h1:pyyisuGw24ruLjrr1ddx39WE0y9OooInRzEYLhQB2YY= -honnef.co/go/tools v0.1.4/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las= +honnef.co/go/tools v0.2.1/go.mod h1:lPVVZ2BS5TfnjLyizF7o7hv7j9/L+8cZY2hLyjP9cGY= howett.net/plist v0.0.0-20181124034731-591f970eefbb/go.mod h1:vMygbs4qMhSZSc4lCUl2OEE+rDiIIJAIdR4m7MiMcm0= inet.af/netaddr v0.0.0-20210515010201-ad03edc7c841/go.mod h1:z0nx+Dh+7N7CC8V5ayHtHGpZpxLQZZxkIaaz6HN65Ls= -inet.af/netaddr v0.0.0-20210721214506-ce7a8ad02cc1/go.mod h1:z0nx+Dh+7N7CC8V5ayHtHGpZpxLQZZxkIaaz6HN65Ls= inet.af/netaddr v0.0.0-20211027220019-c74959edd3b6 h1:acCzuUSQ79tGsM/O50VRFySfMm19IoMKL+sZztZkCxw= inet.af/netaddr v0.0.0-20211027220019-c74959edd3b6/go.mod h1:y3MGhcFMlh0KZPMuXXow8mpjxxAk3yoDNsp4cQz54i8= -inet.af/netstack v0.0.0-20210622165351-29b14ebc044e/go.mod h1:fG3G1dekmK8oDX3iVzt8c0zICLMLSN8SjdxbXVt0WjU= +inet.af/netstack v0.0.0-20211101182044-1c1bcf452982/go.mod h1:fG3G1dekmK8oDX3iVzt8c0zICLMLSN8SjdxbXVt0WjU= inet.af/peercred v0.0.0-20210318190834-4259e17bb763/go.mod h1:FjawnflS/udxX+SvpsMgZfdqx2aykOlkISeAsADi5IU= inet.af/wf v0.0.0-20210516214145-a5343001b756/go.mod h1:ViGMZRA6+RA318D7GCncrjv5gHUrPYrNDejjU12tikA= mvdan.cc/gofumpt v0.0.0-20200802201014-ab5a8192947d/go.mod h1:bzrjFmaD6+xqohD3KYP0H2FEuxknnBmyyOxdhLdaIws= @@ -1663,11 +1695,12 @@ mvdan.cc/gofumpt v0.0.0-20201129102820-5c11c50e9475/go.mod h1:E4LOcu9JQEtnYXtB1Y mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed/go.mod h1:Xkxe497xwlCKkIaQYRfC7CSLworTXY9RMqwhhCm+8Nc= mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b/go.mod h1:2odslEg/xrtNQqCYg2/jCoyKnw3vv5biOc3JnIcYfL4= mvdan.cc/unparam v0.0.0-20200501210554-b37ab49443f7/go.mod h1:HGC5lll35J70Y5v7vCGb9oLhHoScFwkHDJm/05RdSTc= +nhooyr.io/websocket v1.8.7/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= software.sslmate.com/src/go-pkcs12 v0.0.0-20180114231543-2291e8f0f237/go.mod h1:/xvNRWUqm0+/ZMiF4EX00vrSCMsE4/NHb+Pt3freEeQ= sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= -tailscale.com v1.14.6 h1:xhpDI3hks1lz80Tq7gxybdM0vt8NSuWEFpQeBqBZJhw= -tailscale.com v1.14.6/go.mod h1:3F94TfP5nSn9M40v7jEQB+QI3m/4trasLDF3Dcljs8o= +tailscale.com v1.18.1 h1:3hkMsdpREdz2w0O3YcmOgJkl95ChTT4Dje7wq8prD/E= +tailscale.com v1.18.1/go.mod h1:XzG4o2vtYFkVvmJWPaTGSaOzqlKSRx2WU+aJbrxaVE0= From c63c259d319fe3b03535cf4989e9c9039ec87134 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Fri, 26 Nov 2021 23:28:06 +0000 Subject: [PATCH 209/300] Switch wgkey for types/key We dont seem to need the wireguard key anymore, we generate a key on startup based on the new library and the users fetch it from /key. Clean up app.go and update docs --- app.go | 21 ++++++--------------- config-example.yaml | 3 --- docs/Configuration.md | 6 ------ docs/DNS.md | 1 - k8s/postgres/deployment.yaml | 2 -- k8s/sqlite/statefulset.yaml | 2 -- 6 files changed, 6 insertions(+), 29 deletions(-) diff --git a/app.go b/app.go index 0d3332dd..874bedf2 100644 --- a/app.go +++ b/app.go @@ -43,7 +43,7 @@ import ( "inet.af/netaddr" "tailscale.com/tailcfg" "tailscale.com/types/dnstype" - "tailscale.com/types/wgkey" + "tailscale.com/types/key" ) const ( @@ -66,7 +66,6 @@ const ( type Config struct { ServerURL string Addr string - PrivateKeyPath string EphemeralNodeInactivityTimeout time.Duration IPPrefix netaddr.IPPrefix BaseDomain string @@ -129,8 +128,8 @@ type Headscale struct { dbString string dbType string dbDebug bool - publicKey *wgkey.Key - privateKey *wgkey.Private + publicKey *key.MachinePublic + privateKey *key.MachinePrivate DERPMap *tailcfg.DERPMap @@ -148,15 +147,7 @@ type Headscale struct { // NewHeadscale returns the Headscale app. func NewHeadscale(cfg Config) (*Headscale, error) { - content, err := os.ReadFile(cfg.PrivateKeyPath) - if err != nil { - return nil, err - } - - privKey, err := wgkey.ParsePrivate(string(content)) - if err != nil { - return nil, err - } + privKey := key.NewMachine() pubKey := privKey.Public() var dbString string @@ -185,13 +176,13 @@ func NewHeadscale(cfg Config) (*Headscale, error) { cfg: cfg, dbType: cfg.DBtype, dbString: dbString, - privateKey: privKey, + privateKey: &privKey, publicKey: &pubKey, aclRules: tailcfg.FilterAllowAll, // default allowall requestedExpiryCache: requestedExpiryCache, } - err = app.initDB() + err := app.initDB() if err != nil { return nil, err } diff --git a/config-example.yaml b/config-example.yaml index 60369306..dc4bd579 100644 --- a/config-example.yaml +++ b/config-example.yaml @@ -6,9 +6,6 @@ server_url: http://127.0.0.1:8080 # Address to listen to / bind to on the server listen_addr: 0.0.0.0:8080 -# Path to WireGuard private key file -private_key_path: private.key - derp: # List of externally available DERP maps encoded in JSON urls: diff --git a/docs/Configuration.md b/docs/Configuration.md index fa766428..f5e8c3f4 100644 --- a/docs/Configuration.md +++ b/docs/Configuration.md @@ -21,12 +21,6 @@ log_level: debug `log_level` can be used to set the Log level for Headscale, it defaults to `debug`, and the available levels are: `trace`, `debug`, `info`, `warn` and `error`. -```yaml -private_key_path: private.key -``` - -`private_key_path` is the path to the Wireguard private key. If the path is relative, it will be interpreted as relative to the directory the configuration file was read from. - ```yaml derp_map_path: derp.yaml ``` diff --git a/docs/DNS.md b/docs/DNS.md index e51feaf6..53106526 100644 --- a/docs/DNS.md +++ b/docs/DNS.md @@ -15,7 +15,6 @@ The setup is done via the `config.yaml` file, under the `dns_config` key. ```yaml server_url: http://127.0.0.1:8001 listen_addr: 0.0.0.0:8001 -private_key_path: private.key dns_config: nameservers: - 1.1.1.1 diff --git a/k8s/postgres/deployment.yaml b/k8s/postgres/deployment.yaml index 661d87ed..75e64446 100644 --- a/k8s/postgres/deployment.yaml +++ b/k8s/postgres/deployment.yaml @@ -25,8 +25,6 @@ spec: configMapKeyRef: name: headscale-config key: listen_addr - - name: PRIVATE_KEY_PATH - value: /vol/secret/private-key - name: DERP_MAP_PATH value: /vol/config/derp.yaml - name: EPHEMERAL_NODE_INACTIVITY_TIMEOUT diff --git a/k8s/sqlite/statefulset.yaml b/k8s/sqlite/statefulset.yaml index 71077dad..050bf766 100644 --- a/k8s/sqlite/statefulset.yaml +++ b/k8s/sqlite/statefulset.yaml @@ -26,8 +26,6 @@ spec: configMapKeyRef: name: headscale-config key: listen_addr - - name: PRIVATE_KEY_PATH - value: /vol/secret/private-key - name: DERP_MAP_PATH value: /vol/config/derp.yaml - name: EPHEMERAL_NODE_INACTIVITY_TIMEOUT From 07418140a2b5bebafc20a87f5a87c9f2b619b427 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Fri, 26 Nov 2021 23:29:41 +0000 Subject: [PATCH 210/300] Remove config loading of private key path --- cmd/headscale/cli/utils.go | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/cmd/headscale/cli/utils.go b/cmd/headscale/cli/utils.go index 98b53619..d47a5ca9 100644 --- a/cmd/headscale/cli/utils.go +++ b/cmd/headscale/cli/utils.go @@ -222,11 +222,10 @@ func getHeadscaleConfig() headscale.Config { derpConfig := GetDERPConfig() return headscale.Config{ - ServerURL: viper.GetString("server_url"), - Addr: viper.GetString("listen_addr"), - PrivateKeyPath: absPath(viper.GetString("private_key_path")), - IPPrefix: netaddr.MustParseIPPrefix(viper.GetString("ip_prefix")), - BaseDomain: baseDomain, + ServerURL: viper.GetString("server_url"), + Addr: viper.GetString("listen_addr"), + IPPrefix: netaddr.MustParseIPPrefix(viper.GetString("ip_prefix")), + BaseDomain: baseDomain, DERP: derpConfig, From cfd53bc4aafaeed912330db7c2698ada135afa4e Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Fri, 26 Nov 2021 23:30:42 +0000 Subject: [PATCH 211/300] Factor wgkey to types/key This commit converts all the uses of wgkey to the new key interfaces. It now has specific machine, node and discovery keys and we now should use them correctly. Please note the new logic which strips a key prefix (in utils.go) that is now standard inside tailscale. In theory we could put it in the database, but to preserve backwards compatibility and not spend a lot of resources on accounting for both, we just strip them. --- api.go | 92 +++++++++++++-------------- cmd/headscale/cli/nodes.go | 7 +-- machine.go | 66 ++++++++++++-------- oidc.go | 16 ++++- oidc_test.go | 6 +- poll.go | 17 ++--- utils.go | 123 +++++++++++++++++++++---------------- 7 files changed, 184 insertions(+), 143 deletions(-) diff --git a/api.go b/api.go index 1a51fdfe..84b79a58 100644 --- a/api.go +++ b/api.go @@ -13,9 +13,10 @@ import ( "github.com/gin-gonic/gin" "github.com/klauspost/compress/zstd" "github.com/rs/zerolog/log" + "go4.org/mem" "gorm.io/gorm" "tailscale.com/tailcfg" - "tailscale.com/types/wgkey" + "tailscale.com/types/key" ) const ( @@ -34,7 +35,7 @@ func (h *Headscale) KeyHandler(ctx *gin.Context) { ctx.Data( http.StatusOK, "text/plain; charset=utf-8", - []byte(h.publicKey.HexString()), + []byte(MachinePublicKeyStripPrefix(*h.publicKey)), ) } @@ -73,10 +74,10 @@ func (h *Headscale) RegisterWebAPI(ctx *gin.Context) { func (h *Headscale) RegistrationHandler(ctx *gin.Context) { body, _ := io.ReadAll(ctx.Request.Body) machineKeyStr := ctx.Param("id") - machineKey, err := wgkey.ParseHex(machineKeyStr) + machineKey, err := key.ParseMachinePublicUntyped(mem.S(machineKeyStr)) if err != nil { log.Error(). - Str("handler", "Registration"). + Caller(). Err(err). Msg("Cannot parse machine key") machineRegistrations.WithLabelValues("unknown", "web", "error", "unknown").Inc() @@ -88,7 +89,7 @@ func (h *Headscale) RegistrationHandler(ctx *gin.Context) { err = decode(body, &req, &machineKey, h.privateKey) if err != nil { log.Error(). - Str("handler", "Registration"). + Caller(). Err(err). Msg("Cannot decode message") machineRegistrations.WithLabelValues("unknown", "web", "error", "unknown").Inc() @@ -98,17 +99,17 @@ func (h *Headscale) RegistrationHandler(ctx *gin.Context) { } now := time.Now().UTC() - machine, err := h.GetMachineByMachineKey(machineKey.HexString()) + machine, err := h.GetMachineByMachineKey(machineKey) if errors.Is(err, gorm.ErrRecordNotFound) { log.Info().Str("machine", req.Hostinfo.Hostname).Msg("New machine") newMachine := Machine{ Expiry: &time.Time{}, - MachineKey: machineKey.HexString(), + MachineKey: MachinePublicKeyStripPrefix(machineKey), Name: req.Hostinfo.Hostname, } if err := h.db.Create(&newMachine).Error; err != nil { log.Error(). - Str("handler", "Registration"). + Caller(). Err(err). Msg("Could not create row") machineRegistrations.WithLabelValues("unknown", "web", "error", machine.Namespace.Name). @@ -125,7 +126,7 @@ func (h *Headscale) RegistrationHandler(ctx *gin.Context) { // - Trying to log out (sending a expiry in the past) // - A valid, registered machine, looking for the node map // - Expired machine wanting to reauthenticate - if machine.NodeKey == wgkey.Key(req.NodeKey).HexString() { + if machine.NodeKey == req.NodeKey.String() { // The client sends an Expiry in the past if the client is requesting to expire the key (aka logout) // https://github.com/tailscale/tailscale/blob/main/tailcfg/tailcfg.go#L648 if !req.Expiry.IsZero() && req.Expiry.UTC().Before(now) { @@ -144,7 +145,7 @@ func (h *Headscale) RegistrationHandler(ctx *gin.Context) { } // The NodeKey we have matches OldNodeKey, which means this is a refresh after a key expiration - if machine.NodeKey == wgkey.Key(req.OldNodeKey).HexString() && + if machine.NodeKey == req.OldNodeKey.String() && !machine.isExpired() { h.handleMachineRefreshKey(ctx, machineKey, req, *machine) @@ -168,7 +169,7 @@ func (h *Headscale) RegistrationHandler(ctx *gin.Context) { } func (h *Headscale) getMapResponse( - machineKey wgkey.Key, + machineKey key.MachinePublic, req tailcfg.MapRequest, machine *Machine, ) ([]byte, error) { @@ -179,6 +180,7 @@ func (h *Headscale) getMapResponse( node, err := machine.toNode(h.cfg.BaseDomain, h.cfg.DNSConfig, true) if err != nil { log.Error(). + Caller(). Str("func", "getMapResponse"). Err(err). Msg("Cannot convert to node") @@ -189,6 +191,7 @@ func (h *Headscale) getMapResponse( peers, err := h.getValidPeers(machine) if err != nil { log.Error(). + Caller(). Str("func", "getMapResponse"). Err(err). Msg("Cannot fetch peers") @@ -201,6 +204,7 @@ func (h *Headscale) getMapResponse( nodePeers, err := peers.toNodes(h.cfg.BaseDomain, h.cfg.DNSConfig, true) if err != nil { log.Error(). + Caller(). Str("func", "getMapResponse"). Err(err). Msg("Failed to convert peers to Tailscale nodes") @@ -238,10 +242,7 @@ func (h *Headscale) getMapResponse( encoder, _ := zstd.NewWriter(nil) srcCompressed := encoder.EncodeAll(src, nil) - respBody, err = encodeMsg(srcCompressed, &machineKey, h.privateKey) - if err != nil { - return nil, err - } + respBody = h.privateKey.SealTo(machineKey, srcCompressed) } else { respBody, err = encode(resp, &machineKey, h.privateKey) if err != nil { @@ -257,7 +258,7 @@ func (h *Headscale) getMapResponse( } func (h *Headscale) getMapKeepAliveResponse( - machineKey wgkey.Key, + machineKey key.MachinePublic, mapRequest tailcfg.MapRequest, ) ([]byte, error) { mapResponse := tailcfg.MapResponse{ @@ -269,10 +270,7 @@ func (h *Headscale) getMapKeepAliveResponse( src, _ := json.Marshal(mapResponse) encoder, _ := zstd.NewWriter(nil) srcCompressed := encoder.EncodeAll(src, nil) - respBody, err = encodeMsg(srcCompressed, &machineKey, h.privateKey) - if err != nil { - return nil, err - } + respBody = h.privateKey.SealTo(machineKey, srcCompressed) } else { respBody, err = encode(mapResponse, &machineKey, h.privateKey) if err != nil { @@ -288,13 +286,12 @@ func (h *Headscale) getMapKeepAliveResponse( func (h *Headscale) handleMachineLogOut( ctx *gin.Context, - machineKey wgkey.Key, + machineKey key.MachinePublic, machine Machine, ) { resp := tailcfg.RegisterResponse{} log.Info(). - Str("handler", "Registration"). Str("machine", machine.Name). Msg("Client requested logout") @@ -306,7 +303,7 @@ func (h *Headscale) handleMachineLogOut( respBody, err := encode(resp, &machineKey, h.privateKey) if err != nil { log.Error(). - Str("handler", "Registration"). + Caller(). Err(err). Msg("Cannot encode message") ctx.String(http.StatusInternalServerError, "") @@ -318,14 +315,13 @@ func (h *Headscale) handleMachineLogOut( func (h *Headscale) handleMachineValidRegistration( ctx *gin.Context, - machineKey wgkey.Key, + machineKey key.MachinePublic, machine Machine, ) { resp := tailcfg.RegisterResponse{} // The machine registration is valid, respond with redirect to /map log.Debug(). - Str("handler", "Registration"). Str("machine", machine.Name). Msg("Client is registered and we have the current NodeKey. All clear to /map") @@ -337,7 +333,7 @@ func (h *Headscale) handleMachineValidRegistration( respBody, err := encode(resp, &machineKey, h.privateKey) if err != nil { log.Error(). - Str("handler", "Registration"). + Caller(). Err(err). Msg("Cannot encode message") machineRegistrations.WithLabelValues("update", "web", "error", machine.Namespace.Name). @@ -353,7 +349,7 @@ func (h *Headscale) handleMachineValidRegistration( func (h *Headscale) handleMachineExpired( ctx *gin.Context, - machineKey wgkey.Key, + machineKey key.MachinePublic, registerRequest tailcfg.RegisterRequest, machine Machine, ) { @@ -361,7 +357,6 @@ func (h *Headscale) handleMachineExpired( // The client has registered before, but has expired log.Debug(). - Str("handler", "Registration"). Str("machine", machine.Name). Msg("Machine registration has expired. Sending a authurl to register") @@ -373,16 +368,16 @@ func (h *Headscale) handleMachineExpired( if h.cfg.OIDC.Issuer != "" { resp.AuthURL = fmt.Sprintf("%s/oidc/register/%s", - strings.TrimSuffix(h.cfg.ServerURL, "/"), machineKey.HexString()) + strings.TrimSuffix(h.cfg.ServerURL, "/"), machineKey.String()) } else { resp.AuthURL = fmt.Sprintf("%s/register?key=%s", - strings.TrimSuffix(h.cfg.ServerURL, "/"), machineKey.HexString()) + strings.TrimSuffix(h.cfg.ServerURL, "/"), machineKey.String()) } respBody, err := encode(resp, &machineKey, h.privateKey) if err != nil { log.Error(). - Str("handler", "Registration"). + Caller(). Err(err). Msg("Cannot encode message") machineRegistrations.WithLabelValues("reauth", "web", "error", machine.Namespace.Name). @@ -398,17 +393,16 @@ func (h *Headscale) handleMachineExpired( func (h *Headscale) handleMachineRefreshKey( ctx *gin.Context, - machineKey wgkey.Key, + machineKey key.MachinePublic, registerRequest tailcfg.RegisterRequest, machine Machine, ) { resp := tailcfg.RegisterResponse{} log.Debug(). - Str("handler", "Registration"). Str("machine", machine.Name). Msg("We have the OldNodeKey in the database. This is a key refresh") - machine.NodeKey = wgkey.Key(registerRequest.NodeKey).HexString() + machine.NodeKey = NodePublicKeyStripPrefix(registerRequest.NodeKey) h.db.Save(&machine) resp.AuthURL = "" @@ -416,7 +410,7 @@ func (h *Headscale) handleMachineRefreshKey( respBody, err := encode(resp, &machineKey, h.privateKey) if err != nil { log.Error(). - Str("handler", "Registration"). + Caller(). Err(err). Msg("Cannot encode message") ctx.String(http.StatusInternalServerError, "Extremely sad!") @@ -428,7 +422,7 @@ func (h *Headscale) handleMachineRefreshKey( func (h *Headscale) handleMachineRegistrationNew( ctx *gin.Context, - machineKey wgkey.Key, + machineKey key.MachinePublic, registerRequest tailcfg.RegisterRequest, machine Machine, ) { @@ -436,18 +430,17 @@ func (h *Headscale) handleMachineRegistrationNew( // The machine registration is new, redirect the client to the registration URL log.Debug(). - Str("handler", "Registration"). Str("machine", machine.Name). Msg("The node is sending us a new NodeKey, sending auth url") if h.cfg.OIDC.Issuer != "" { resp.AuthURL = fmt.Sprintf( "%s/oidc/register/%s", strings.TrimSuffix(h.cfg.ServerURL, "/"), - machineKey.HexString(), + machineKey.String(), ) } else { resp.AuthURL = fmt.Sprintf("%s/register?key=%s", - strings.TrimSuffix(h.cfg.ServerURL, "/"), machineKey.HexString()) + strings.TrimSuffix(h.cfg.ServerURL, "/"), MachinePublicKeyStripPrefix(machineKey)) } if !registerRequest.Expiry.IsZero() { @@ -457,19 +450,21 @@ func (h *Headscale) handleMachineRegistrationNew( Time("expiry", registerRequest.Expiry). Msg("Non-zero expiry time requested, adding to cache") h.requestedExpiryCache.Set( - machineKey.HexString(), + machineKey.String(), registerRequest.Expiry, requestedExpiryCacheExpiration, ) } - machine.NodeKey = wgkey.Key(registerRequest.NodeKey).HexString() // save the NodeKey + machine.NodeKey = NodePublicKeyStripPrefix(registerRequest.NodeKey) + + // save the NodeKey h.db.Save(&machine) respBody, err := encode(resp, &machineKey, h.privateKey) if err != nil { log.Error(). - Str("handler", "Registration"). + Caller(). Err(err). Msg("Cannot encode message") ctx.String(http.StatusInternalServerError, "") @@ -481,7 +476,7 @@ func (h *Headscale) handleMachineRegistrationNew( func (h *Headscale) handleAuthKey( ctx *gin.Context, - machineKey wgkey.Key, + machineKey key.MachinePublic, registerRequest tailcfg.RegisterRequest, machine Machine, ) { @@ -493,6 +488,7 @@ func (h *Headscale) handleAuthKey( pak, err := h.checkKeyValidity(registerRequest.Auth.AuthKey) if err != nil { log.Error(). + Caller(). Str("func", "handleAuthKey"). Str("machine", machine.Name). Err(err). @@ -501,6 +497,7 @@ func (h *Headscale) handleAuthKey( respBody, err := encode(resp, &machineKey, h.privateKey) if err != nil { log.Error(). + Caller(). Str("func", "handleAuthKey"). Str("machine", machine.Name). Err(err). @@ -513,6 +510,7 @@ func (h *Headscale) handleAuthKey( } ctx.Data(http.StatusUnauthorized, "application/json; charset=utf-8", respBody) log.Error(). + Caller(). Str("func", "handleAuthKey"). Str("machine", machine.Name). Msg("Failed authentication via AuthKey") @@ -537,6 +535,7 @@ func (h *Headscale) handleAuthKey( ip, err := h.getAvailableIP() if err != nil { log.Error(). + Caller(). Str("func", "handleAuthKey"). Str("machine", machine.Name). Msg("Failed to find an available IP") @@ -555,9 +554,9 @@ func (h *Headscale) handleAuthKey( machine.AuthKeyID = uint(pak.ID) machine.IPAddress = ip.String() machine.NamespaceID = pak.NamespaceID - machine.NodeKey = wgkey.Key(registerRequest.NodeKey). - HexString() - // we update it just in case + + machine.NodeKey = NodePublicKeyStripPrefix(registerRequest.NodeKey) + // we update it just in case machine.Registered = true machine.RegisterMethod = RegisterMethodAuthKey h.db.Save(&machine) @@ -571,6 +570,7 @@ func (h *Headscale) handleAuthKey( respBody, err := encode(resp, &machineKey, h.privateKey) if err != nil { log.Error(). + Caller(). Str("func", "handleAuthKey"). Str("machine", machine.Name). Err(err). diff --git a/cmd/headscale/cli/nodes.go b/cmd/headscale/cli/nodes.go index f5117d95..2c7fa9b5 100644 --- a/cmd/headscale/cli/nodes.go +++ b/cmd/headscale/cli/nodes.go @@ -11,9 +11,9 @@ import ( v1 "github.com/juanfont/headscale/gen/go/headscale/v1" "github.com/pterm/pterm" "github.com/spf13/cobra" + "go4.org/mem" "google.golang.org/grpc/status" - "tailscale.com/tailcfg" - "tailscale.com/types/wgkey" + "tailscale.com/types/key" ) func init() { @@ -486,11 +486,10 @@ func nodesToPtables( expiry = machine.Expiry.AsTime() } - nKey, err := wgkey.ParseHex(machine.NodeKey) + nodeKey, err := key.ParseNodePublicUntyped(mem.S(machine.NodeKey)) if err != nil { return nil, err } - nodeKey := tailcfg.NodeKey(nKey) var online string if lastSeen.After( diff --git a/machine.go b/machine.go index 306b3a47..26c59c65 100644 --- a/machine.go +++ b/machine.go @@ -12,12 +12,12 @@ import ( "github.com/fatih/set" v1 "github.com/juanfont/headscale/gen/go/headscale/v1" "github.com/rs/zerolog/log" + "go4.org/mem" "google.golang.org/protobuf/types/known/timestamppb" "gorm.io/datatypes" - "gorm.io/gorm" "inet.af/netaddr" "tailscale.com/tailcfg" - "tailscale.com/types/wgkey" + "tailscale.com/types/key" ) const ( @@ -260,9 +260,11 @@ func (h *Headscale) GetMachineByID(id uint64) (*Machine, error) { } // GetMachineByMachineKey finds a Machine by ID and returns the Machine struct. -func (h *Headscale) GetMachineByMachineKey(machineKey string) (*Machine, error) { +func (h *Headscale) GetMachineByMachineKey( + machineKey key.MachinePublic, +) (*Machine, error) { m := Machine{} - if result := h.db.Preload("Namespace").First(&m, "machine_key = ?", machineKey); result.Error != nil { + if result := h.db.Preload("Namespace").First(&m, "machine_key = ?", MachinePublicKeyStripPrefix(machineKey)); result.Error != nil { return nil, result.Error } @@ -437,25 +439,31 @@ func (machine Machine) toNode( dnsConfig *tailcfg.DNSConfig, includeRoutes bool, ) (*tailcfg.Node, error) { - nodeKey, err := wgkey.ParseHex(machine.NodeKey) + nodeKey, err := key.ParseNodePublicUntyped(mem.S(machine.NodeKey)) if err != nil { - return nil, err + log.Trace(). + Caller(). + Str("node_key", machine.NodeKey). + Msgf("Failed to parse node public key from hex") + + return nil, fmt.Errorf("failed to parse node public key: %w", err) } - machineKey, err := wgkey.ParseHex(machine.MachineKey) + machineKey, err := key.ParseMachinePublicUntyped(mem.S(machine.MachineKey)) if err != nil { - return nil, err + return nil, fmt.Errorf("failed to parse machine public key: %w", err) } - var discoKey tailcfg.DiscoKey + var discoKey key.DiscoPublic if machine.DiscoKey != "" { - dKey, err := wgkey.ParseHex(machine.DiscoKey) + dKey := key.DiscoPublic{} + err := dKey.UnmarshalText([]byte(discoPublicHexPrefix + machine.DiscoKey)) if err != nil { - return nil, err + return nil, fmt.Errorf("failed to parse disco public key: %w", err) } - discoKey = tailcfg.DiscoKey(dKey) + discoKey = key.DiscoPublic(dKey) } else { - discoKey = tailcfg.DiscoKey{} + discoKey = key.DiscoPublic{} } addrs := []netaddr.IPPrefix{} @@ -555,9 +563,9 @@ func (machine Machine) toNode( ), // in headscale, unlike tailcontrol server, IDs are permanent Name: hostname, User: tailcfg.UserID(machine.NamespaceID), - Key: tailcfg.NodeKey(nodeKey), + Key: nodeKey, KeyExpiry: keyExpiry, - Machine: tailcfg.MachineKey(machineKey), + Machine: machineKey, DiscoKey: discoKey, Addresses: addrs, AllowedIPs: allowedIPs, @@ -618,31 +626,35 @@ func (machine *Machine) toProto() *v1.Machine { // RegisterMachine is executed from the CLI to register a new Machine using its MachineKey. func (h *Headscale) RegisterMachine( - key string, + machineKeyStr string, namespaceName string, ) (*Machine, error) { namespace, err := h.GetNamespace(namespaceName) if err != nil { return nil, err } - machineKey, err := wgkey.ParseHex(key) + + machineKey, err := key.ParseMachinePublicUntyped(mem.S(machineKeyStr)) if err != nil { return nil, err } - machine := Machine{} - if result := h.db.First(&machine, "machine_key = ?", machineKey.HexString()); errors.Is( - result.Error, - gorm.ErrRecordNotFound, - ) { - return nil, errMachineNotFound + log.Trace(). + Caller(). + Str("machine_key_str", machineKeyStr). + Str("machine_key", machineKey.String()). + Msg("Registering machine") + + machine, err := h.GetMachineByMachineKey(machineKey) + if err != nil { + return nil, err } // TODO(kradalby): Currently, if it fails to find a requested expiry, non will be set // This means that if a user is to slow with register a machine, it will possibly not // have the correct expiry. requestedTime := time.Time{} - if requestedTimeIf, found := h.requestedExpiryCache.Get(machineKey.HexString()); found { + if requestedTimeIf, found := h.requestedExpiryCache.Get(machineKey.String()); found { log.Trace(). Caller(). Str("machine", machine.Name). @@ -658,9 +670,9 @@ func (h *Headscale) RegisterMachine( Str("machine", machine.Name). Msg("machine already registered, reauthenticating") - h.RefreshMachine(&machine, requestedTime) + h.RefreshMachine(machine, requestedTime) - return &machine, nil + return machine, nil } log.Trace(). @@ -709,7 +721,7 @@ func (h *Headscale) RegisterMachine( Str("ip", ip.String()). Msg("Machine registered with the database") - return &machine, nil + return machine, nil } func (machine *Machine) GetAdvertisedRoutes() ([]netaddr.IPPrefix, error) { diff --git a/oidc.go b/oidc.go index 9b0a3087..02666d89 100644 --- a/oidc.go +++ b/oidc.go @@ -15,8 +15,10 @@ import ( "github.com/gin-gonic/gin" "github.com/patrickmn/go-cache" "github.com/rs/zerolog/log" + "go4.org/mem" "golang.org/x/oauth2" "gorm.io/gorm" + "tailscale.com/types/key" ) const ( @@ -187,7 +189,17 @@ func (h *Headscale) OIDCCallback(ctx *gin.Context) { return } - machineKey, machineKeyOK := machineKeyIf.(string) + + machineKeyStr, machineKeyOK := machineKeyIf.(string) + + machineKey, err := key.ParseMachinePublicUntyped(mem.S(machineKeyStr)) + if err != nil { + log.Error(). + Msg("could not parse machine public key") + ctx.String(http.StatusBadRequest, "could not parse public key") + + return + } if !machineKeyOK { log.Error().Msg("could not get machine key from cache") @@ -201,7 +213,7 @@ func (h *Headscale) OIDCCallback(ctx *gin.Context) { // TODO(kradalby): Currently, if it fails to find a requested expiry, non will be set requestedTime := time.Time{} - if requestedTimeIf, found := h.requestedExpiryCache.Get(machineKey); found { + if requestedTimeIf, found := h.requestedExpiryCache.Get(machineKey.String()); found { if reqTime, ok := requestedTimeIf.(time.Time); ok { requestedTime = reqTime } diff --git a/oidc_test.go b/oidc_test.go index 21a4357d..db581b99 100644 --- a/oidc_test.go +++ b/oidc_test.go @@ -9,7 +9,7 @@ import ( "golang.org/x/oauth2" "gorm.io/gorm" "tailscale.com/tailcfg" - "tailscale.com/types/wgkey" + "tailscale.com/types/key" ) func TestHeadscale_getNamespaceFromEmail(t *testing.T) { @@ -19,8 +19,8 @@ func TestHeadscale_getNamespaceFromEmail(t *testing.T) { dbString string dbType string dbDebug bool - publicKey *wgkey.Key - privateKey *wgkey.Private + publicKey *key.MachinePublic + privateKey *key.MachinePrivate aclPolicy *ACLPolicy aclRules []tailcfg.FilterRule lastStateChange sync.Map diff --git a/poll.go b/poll.go index 9cf14e7a..b993fa7b 100644 --- a/poll.go +++ b/poll.go @@ -9,10 +9,11 @@ import ( "github.com/gin-gonic/gin" "github.com/rs/zerolog/log" + "go4.org/mem" "gorm.io/datatypes" "gorm.io/gorm" "tailscale.com/tailcfg" - "tailscale.com/types/wgkey" + "tailscale.com/types/key" ) const ( @@ -36,7 +37,7 @@ func (h *Headscale) PollNetMapHandler(ctx *gin.Context) { Msg("PollNetMapHandler called") body, _ := io.ReadAll(ctx.Request.Body) mKeyStr := ctx.Param("id") - mKey, err := wgkey.ParseHex(mKeyStr) + mKey, err := key.ParseMachinePublicUntyped(mem.S(mKeyStr)) if err != nil { log.Error(). Str("handler", "PollNetMap"). @@ -58,19 +59,19 @@ func (h *Headscale) PollNetMapHandler(ctx *gin.Context) { return } - machine, err := h.GetMachineByMachineKey(mKey.HexString()) + machine, err := h.GetMachineByMachineKey(mKey) if err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { log.Warn(). Str("handler", "PollNetMap"). - Msgf("Ignoring request, cannot find machine with key %s", mKey.HexString()) + Msgf("Ignoring request, cannot find machine with key %s", mKey.String()) ctx.String(http.StatusUnauthorized, "") return } log.Error(). Str("handler", "PollNetMap"). - Msgf("Failed to fetch machine from the database with Machine key: %s", mKey.HexString()) + Msgf("Failed to fetch machine from the database with Machine key: %s", mKey.String()) ctx.String(http.StatusInternalServerError, "") } log.Trace(). @@ -82,7 +83,7 @@ func (h *Headscale) PollNetMapHandler(ctx *gin.Context) { hostinfo, _ := json.Marshal(req.Hostinfo) machine.Name = req.Hostinfo.Hostname machine.HostInfo = datatypes.JSON(hostinfo) - machine.DiscoKey = wgkey.Key(req.DiscoKey).HexString() + machine.DiscoKey = DiscoPublicKeyStripPrefix(req.DiscoKey) now := time.Now().UTC() // From Tailscale client: @@ -225,7 +226,7 @@ func (h *Headscale) PollNetMapStream( ctx *gin.Context, machine *Machine, mapRequest tailcfg.MapRequest, - machineKey wgkey.Key, + machineKey key.MachinePublic, pollDataChan chan []byte, keepAliveChan chan []byte, updateChan chan struct{}, @@ -491,7 +492,7 @@ func (h *Headscale) scheduledPollWorker( cancelChan <-chan struct{}, updateChan chan<- struct{}, keepAliveChan chan<- []byte, - machineKey wgkey.Key, + machineKey key.MachinePublic, mapRequest tailcfg.MapRequest, machine *Machine, ) { diff --git a/utils.go b/utils.go index 9f7849e2..d0fa1b5e 100644 --- a/utils.go +++ b/utils.go @@ -7,50 +7,95 @@ package headscale import ( "context" - "crypto/rand" "encoding/json" "fmt" - "io" "net" "strings" - "golang.org/x/crypto/nacl/box" + "github.com/rs/zerolog/log" "inet.af/netaddr" "tailscale.com/tailcfg" - "tailscale.com/types/wgkey" + "tailscale.com/types/key" ) const ( errCannotDecryptReponse = Error("cannot decrypt response") errResponseMissingNonce = Error("response missing nonce") errCouldNotAllocateIP = Error("could not find any suitable IP") + + // These constants are copied from the upstream tailscale.com/types/key + // library, because they are not exported. + // https://github.com/tailscale/tailscale/tree/main/types/key + + // nodePrivateHexPrefix is the prefix used to identify a + // hex-encoded node private key. + // + // This prefix name is a little unfortunate, in that it comes from + // WireGuard's own key types, and we've used it for both key types + // we persist to disk (machine and node keys). But we're stuck + // with it for now, barring another round of tricky migration. + nodePrivateHexPrefix = "privkey:" + + // nodePublicHexPrefix is the prefix used to identify a + // hex-encoded node public key. + // + // This prefix is used in the control protocol, so cannot be + // changed. + nodePublicHexPrefix = "nodekey:" + + // machinePrivateHexPrefix is the prefix used to identify a + // hex-encoded machine private key. + // + // This prefix name is a little unfortunate, in that it comes from + // WireGuard's own key types. Unfortunately we're stuck with it for + // machine keys, because we serialize them to disk with this prefix. + machinePrivateHexPrefix = "privkey:" + + // machinePublicHexPrefix is the prefix used to identify a + // hex-encoded machine public key. + // + // This prefix is used in the control protocol, so cannot be + // changed. + machinePublicHexPrefix = "mkey:" + + // discoPublicHexPrefix is the prefix used to identify a + // hex-encoded disco public key. + // + // This prefix is used in the control protocol, so cannot be + // changed. + discoPublicHexPrefix = "discokey:" ) +func MachinePublicKeyStripPrefix(machineKey key.MachinePublic) string { + return strings.TrimPrefix(machineKey.String(), machinePublicHexPrefix) +} + +func NodePublicKeyStripPrefix(nodeKey key.NodePublic) string { + return strings.TrimPrefix(nodeKey.String(), nodePublicHexPrefix) +} + +func DiscoPublicKeyStripPrefix(discoKey key.DiscoPublic) string { + return strings.TrimPrefix(discoKey.String(), discoPublicHexPrefix) +} + // Error is used to compare errors as per https://dave.cheney.net/2016/04/07/constant-errors type Error string func (e Error) Error() string { return string(e) } func decode( - msg []byte, - v interface{}, - pubKey *wgkey.Key, - privKey *wgkey.Private, -) error { - return decodeMsg(msg, v, pubKey, privKey) -} - -func decodeMsg( msg []byte, output interface{}, - pubKey *wgkey.Key, - privKey *wgkey.Private, + pubKey *key.MachinePublic, + privKey *key.MachinePrivate, ) error { - decrypted, err := decryptMsg(msg, pubKey, privKey) - if err != nil { - return err + log.Trace().Int("length", len(msg)).Msg("Trying to decrypt") + + decrypted, ok := privKey.OpenFrom(*pubKey, msg) + if !ok { + return errCannotDecryptReponse } - // fmt.Println(string(decrypted)) + if err := json.Unmarshal(decrypted, output); err != nil { return err } @@ -58,45 +103,17 @@ func decodeMsg( return nil } -func decryptMsg(msg []byte, pubKey *wgkey.Key, privKey *wgkey.Private) ([]byte, error) { - var nonce [24]byte - if len(msg) < len(nonce)+1 { - return nil, errResponseMissingNonce - } - copy(nonce[:], msg) - msg = msg[len(nonce):] - - pub, pri := (*[32]byte)(pubKey), (*[32]byte)(privKey) - decrypted, ok := box.Open(nil, msg, &nonce, pub, pri) - if !ok { - return nil, errCannotDecryptReponse - } - - return decrypted, nil -} - -func encode(v interface{}, pubKey *wgkey.Key, privKey *wgkey.Private) ([]byte, error) { +func encode( + v interface{}, + pubKey *key.MachinePublic, + privKey *key.MachinePrivate, +) ([]byte, error) { b, err := json.Marshal(v) if err != nil { return nil, err } - return encodeMsg(b, pubKey, privKey) -} - -func encodeMsg( - payload []byte, - pubKey *wgkey.Key, - privKey *wgkey.Private, -) ([]byte, error) { - var nonce [24]byte - if _, err := io.ReadFull(rand.Reader, nonce[:]); err != nil { - panic(err) - } - pub, pri := (*[32]byte)(pubKey), (*[32]byte)(privKey) - msg := box.Seal(nonce[:], payload, &nonce, pub, pri) - - return msg, nil + return privKey.SealTo(*pubKey, b), nil } func (h *Headscale) getAvailableIP() (*netaddr.IP, error) { From 0012c7617067e6b02b6d55ad9a264f7c786f7c69 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Fri, 26 Nov 2021 23:34:11 +0000 Subject: [PATCH 212/300] Make it easier to run cli integration tests --- Makefile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Makefile b/Makefile index 060d3b9c..6b4c02ff 100644 --- a/Makefile +++ b/Makefile @@ -20,6 +20,9 @@ test: test_integration: go test -tags integration -timeout 30m ./... +test_integration_cli: + go test -tags integration -v integration_cli_test.go integration_common_test.go + coverprofile_func: go tool cover -func=coverage.out From c38f00fab85d3e77d99f3796683d4c5913ef2931 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Fri, 26 Nov 2021 23:50:42 +0000 Subject: [PATCH 213/300] Unmarshal keys in the non-deprecated way --- api.go | 5 +++-- cmd/headscale/cli/nodes.go | 4 ++-- integration_cli_test.go | 3 +++ machine.go | 14 +++++++------- oidc.go | 4 ++-- poll.go | 19 ++++++++++--------- utils.go | 18 ------------------ 7 files changed, 27 insertions(+), 40 deletions(-) diff --git a/api.go b/api.go index 84b79a58..ff738712 100644 --- a/api.go +++ b/api.go @@ -13,7 +13,6 @@ import ( "github.com/gin-gonic/gin" "github.com/klauspost/compress/zstd" "github.com/rs/zerolog/log" - "go4.org/mem" "gorm.io/gorm" "tailscale.com/tailcfg" "tailscale.com/types/key" @@ -74,7 +73,9 @@ func (h *Headscale) RegisterWebAPI(ctx *gin.Context) { func (h *Headscale) RegistrationHandler(ctx *gin.Context) { body, _ := io.ReadAll(ctx.Request.Body) machineKeyStr := ctx.Param("id") - machineKey, err := key.ParseMachinePublicUntyped(mem.S(machineKeyStr)) + + var machineKey key.MachinePublic + err := machineKey.UnmarshalText([]byte(machineKeyStr)) if err != nil { log.Error(). Caller(). diff --git a/cmd/headscale/cli/nodes.go b/cmd/headscale/cli/nodes.go index 2c7fa9b5..5adc7f59 100644 --- a/cmd/headscale/cli/nodes.go +++ b/cmd/headscale/cli/nodes.go @@ -11,7 +11,6 @@ import ( v1 "github.com/juanfont/headscale/gen/go/headscale/v1" "github.com/pterm/pterm" "github.com/spf13/cobra" - "go4.org/mem" "google.golang.org/grpc/status" "tailscale.com/types/key" ) @@ -486,7 +485,8 @@ func nodesToPtables( expiry = machine.Expiry.AsTime() } - nodeKey, err := key.ParseNodePublicUntyped(mem.S(machine.NodeKey)) + var nodeKey key.NodePublic + err := nodeKey.UnmarshalText([]byte(machine.NodeKey)) if err != nil { return nil, err } diff --git a/integration_cli_test.go b/integration_cli_test.go index ee940542..eb553220 100644 --- a/integration_cli_test.go +++ b/integration_cli_test.go @@ -720,6 +720,7 @@ func (s *IntegrationCLITestSuite) TestNodeCommand() { []string{}, ) assert.Nil(s.T(), err) + fmt.Println("Error: ", err) var listOnlySharedMachineNamespace []v1.Machine err = json.Unmarshal( @@ -728,6 +729,8 @@ func (s *IntegrationCLITestSuite) TestNodeCommand() { ) assert.Nil(s.T(), err) + fmt.Println("List: ", listOnlySharedMachineNamespaceResult) + fmt.Println("List2: ", listOnlySharedMachineNamespace) assert.Len(s.T(), listOnlySharedMachineNamespace, 2) assert.Equal(s.T(), uint64(6), listOnlySharedMachineNamespace[0].Id) diff --git a/machine.go b/machine.go index 26c59c65..03caa5a2 100644 --- a/machine.go +++ b/machine.go @@ -12,7 +12,6 @@ import ( "github.com/fatih/set" v1 "github.com/juanfont/headscale/gen/go/headscale/v1" "github.com/rs/zerolog/log" - "go4.org/mem" "google.golang.org/protobuf/types/known/timestamppb" "gorm.io/datatypes" "inet.af/netaddr" @@ -439,7 +438,8 @@ func (machine Machine) toNode( dnsConfig *tailcfg.DNSConfig, includeRoutes bool, ) (*tailcfg.Node, error) { - nodeKey, err := key.ParseNodePublicUntyped(mem.S(machine.NodeKey)) + var nodeKey key.NodePublic + err := nodeKey.UnmarshalText([]byte(machine.NodeKey)) if err != nil { log.Trace(). Caller(). @@ -449,19 +449,18 @@ func (machine Machine) toNode( return nil, fmt.Errorf("failed to parse node public key: %w", err) } - machineKey, err := key.ParseMachinePublicUntyped(mem.S(machine.MachineKey)) + var machineKey key.MachinePublic + err = machineKey.UnmarshalText([]byte(machine.MachineKey)) if err != nil { return nil, fmt.Errorf("failed to parse machine public key: %w", err) } var discoKey key.DiscoPublic if machine.DiscoKey != "" { - dKey := key.DiscoPublic{} - err := dKey.UnmarshalText([]byte(discoPublicHexPrefix + machine.DiscoKey)) + err := discoKey.UnmarshalText([]byte(discoPublicHexPrefix + machine.DiscoKey)) if err != nil { return nil, fmt.Errorf("failed to parse disco public key: %w", err) } - discoKey = key.DiscoPublic(dKey) } else { discoKey = key.DiscoPublic{} } @@ -634,7 +633,8 @@ func (h *Headscale) RegisterMachine( return nil, err } - machineKey, err := key.ParseMachinePublicUntyped(mem.S(machineKeyStr)) + var machineKey key.MachinePublic + err = machineKey.UnmarshalText([]byte(machineKeyStr)) if err != nil { return nil, err } diff --git a/oidc.go b/oidc.go index 02666d89..48ad7187 100644 --- a/oidc.go +++ b/oidc.go @@ -15,7 +15,6 @@ import ( "github.com/gin-gonic/gin" "github.com/patrickmn/go-cache" "github.com/rs/zerolog/log" - "go4.org/mem" "golang.org/x/oauth2" "gorm.io/gorm" "tailscale.com/types/key" @@ -192,7 +191,8 @@ func (h *Headscale) OIDCCallback(ctx *gin.Context) { machineKeyStr, machineKeyOK := machineKeyIf.(string) - machineKey, err := key.ParseMachinePublicUntyped(mem.S(machineKeyStr)) + var machineKey key.MachinePublic + err = machineKey.UnmarshalText([]byte(machineKeyStr)) if err != nil { log.Error(). Msg("could not parse machine public key") diff --git a/poll.go b/poll.go index b993fa7b..70bacc6f 100644 --- a/poll.go +++ b/poll.go @@ -9,7 +9,6 @@ import ( "github.com/gin-gonic/gin" "github.com/rs/zerolog/log" - "go4.org/mem" "gorm.io/datatypes" "gorm.io/gorm" "tailscale.com/tailcfg" @@ -36,8 +35,10 @@ func (h *Headscale) PollNetMapHandler(ctx *gin.Context) { Str("id", ctx.Param("id")). Msg("PollNetMapHandler called") body, _ := io.ReadAll(ctx.Request.Body) - mKeyStr := ctx.Param("id") - mKey, err := key.ParseMachinePublicUntyped(mem.S(mKeyStr)) + machineKeyStr := ctx.Param("id") + + var machineKey key.MachinePublic + err := machineKey.UnmarshalText([]byte(machineKeyStr)) if err != nil { log.Error(). Str("handler", "PollNetMap"). @@ -48,7 +49,7 @@ func (h *Headscale) PollNetMapHandler(ctx *gin.Context) { return } req := tailcfg.MapRequest{} - err = decode(body, &req, &mKey, h.privateKey) + err = decode(body, &req, &machineKey, h.privateKey) if err != nil { log.Error(). Str("handler", "PollNetMap"). @@ -59,19 +60,19 @@ func (h *Headscale) PollNetMapHandler(ctx *gin.Context) { return } - machine, err := h.GetMachineByMachineKey(mKey) + machine, err := h.GetMachineByMachineKey(machineKey) if err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { log.Warn(). Str("handler", "PollNetMap"). - Msgf("Ignoring request, cannot find machine with key %s", mKey.String()) + Msgf("Ignoring request, cannot find machine with key %s", machineKey.String()) ctx.String(http.StatusUnauthorized, "") return } log.Error(). Str("handler", "PollNetMap"). - Msgf("Failed to fetch machine from the database with Machine key: %s", mKey.String()) + Msgf("Failed to fetch machine from the database with Machine key: %s", machineKey.String()) ctx.String(http.StatusInternalServerError, "") } log.Trace(). @@ -101,7 +102,7 @@ func (h *Headscale) PollNetMapHandler(ctx *gin.Context) { } h.db.Save(&machine) - data, err := h.getMapResponse(mKey, req, machine) + data, err := h.getMapResponse(machineKey, req, machine) if err != nil { log.Error(). Str("handler", "PollNetMap"). @@ -206,7 +207,7 @@ func (h *Headscale) PollNetMapHandler(ctx *gin.Context) { ctx, machine, req, - mKey, + machineKey, pollDataChan, keepAliveChan, updateChan, diff --git a/utils.go b/utils.go index d0fa1b5e..fa9f028d 100644 --- a/utils.go +++ b/utils.go @@ -20,22 +20,12 @@ import ( const ( errCannotDecryptReponse = Error("cannot decrypt response") - errResponseMissingNonce = Error("response missing nonce") errCouldNotAllocateIP = Error("could not find any suitable IP") // These constants are copied from the upstream tailscale.com/types/key // library, because they are not exported. // https://github.com/tailscale/tailscale/tree/main/types/key - // nodePrivateHexPrefix is the prefix used to identify a - // hex-encoded node private key. - // - // This prefix name is a little unfortunate, in that it comes from - // WireGuard's own key types, and we've used it for both key types - // we persist to disk (machine and node keys). But we're stuck - // with it for now, barring another round of tricky migration. - nodePrivateHexPrefix = "privkey:" - // nodePublicHexPrefix is the prefix used to identify a // hex-encoded node public key. // @@ -43,14 +33,6 @@ const ( // changed. nodePublicHexPrefix = "nodekey:" - // machinePrivateHexPrefix is the prefix used to identify a - // hex-encoded machine private key. - // - // This prefix name is a little unfortunate, in that it comes from - // WireGuard's own key types. Unfortunately we're stuck with it for - // machine keys, because we serialize them to disk with this prefix. - machinePrivateHexPrefix = "privkey:" - // machinePublicHexPrefix is the prefix used to identify a // hex-encoded machine public key. // From cb2ea300ad19e3ef76d3d7b4802ce28708e48225 Mon Sep 17 00:00:00 2001 From: Ward Vandewege Date: Sat, 27 Nov 2021 13:59:39 -0500 Subject: [PATCH 214/300] Fix linter errors. --- cmd/headscale/cli/debug.go | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/cmd/headscale/cli/debug.go b/cmd/headscale/cli/debug.go index 226ae5e7..8010a9be 100644 --- a/cmd/headscale/cli/debug.go +++ b/cmd/headscale/cli/debug.go @@ -9,6 +9,16 @@ import ( "google.golang.org/grpc/status" ) +const ( + keyLength = 64 + errPreAuthKeyTooShort = Error("key too short, must be 64 hexadecimal characters") +) + +// Error is used to compare errors as per https://dave.cheney.net/2016/04/07/constant-errors +type Error string + +func (e Error) Error() string { return string(e) } + func init() { rootCmd.AddCommand(debugCmd) @@ -77,8 +87,8 @@ var createNodeCmd = &cobra.Command{ return } - if len(machineKey) != 64 { - err = fmt.Errorf("key '%s' too short, must be 64 hexadecimal characters", machineKey) + if len(machineKey) != keyLength { + err = errPreAuthKeyTooShort ErrorOutput( err, fmt.Sprintf("Error: %s", err), From 59aeaa8476aa6043f830dc2e2bd8bbff3693a799 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Sat, 27 Nov 2021 20:25:12 +0000 Subject: [PATCH 215/300] Ensure we always have the key prefix when needed --- api.go | 2 +- cmd/headscale/cli/nodes.go | 4 +++- machine.go | 12 ++++++++---- oidc.go | 2 +- poll.go | 2 +- utils.go | 24 ++++++++++++++++++++++++ 6 files changed, 38 insertions(+), 8 deletions(-) diff --git a/api.go b/api.go index ff738712..aadc604e 100644 --- a/api.go +++ b/api.go @@ -75,7 +75,7 @@ func (h *Headscale) RegistrationHandler(ctx *gin.Context) { machineKeyStr := ctx.Param("id") var machineKey key.MachinePublic - err := machineKey.UnmarshalText([]byte(machineKeyStr)) + err := machineKey.UnmarshalText([]byte(MachinePublicKeyEnsurePrefix(machineKeyStr))) if err != nil { log.Error(). Caller(). diff --git a/cmd/headscale/cli/nodes.go b/cmd/headscale/cli/nodes.go index 5adc7f59..26ead6dc 100644 --- a/cmd/headscale/cli/nodes.go +++ b/cmd/headscale/cli/nodes.go @@ -486,7 +486,9 @@ func nodesToPtables( } var nodeKey key.NodePublic - err := nodeKey.UnmarshalText([]byte(machine.NodeKey)) + err := nodeKey.UnmarshalText( + []byte(headscale.NodePublicKeyEnsurePrefix(machine.NodeKey)), + ) if err != nil { return nil, err } diff --git a/machine.go b/machine.go index 03caa5a2..d58c9c5c 100644 --- a/machine.go +++ b/machine.go @@ -439,7 +439,7 @@ func (machine Machine) toNode( includeRoutes bool, ) (*tailcfg.Node, error) { var nodeKey key.NodePublic - err := nodeKey.UnmarshalText([]byte(machine.NodeKey)) + err := nodeKey.UnmarshalText([]byte(NodePublicKeyEnsurePrefix(machine.NodeKey))) if err != nil { log.Trace(). Caller(). @@ -450,14 +450,18 @@ func (machine Machine) toNode( } var machineKey key.MachinePublic - err = machineKey.UnmarshalText([]byte(machine.MachineKey)) + err = machineKey.UnmarshalText( + []byte(MachinePublicKeyEnsurePrefix(machine.MachineKey)), + ) if err != nil { return nil, fmt.Errorf("failed to parse machine public key: %w", err) } var discoKey key.DiscoPublic if machine.DiscoKey != "" { - err := discoKey.UnmarshalText([]byte(discoPublicHexPrefix + machine.DiscoKey)) + err := discoKey.UnmarshalText( + []byte(DiscoPublicKeyEnsurePrefix(machine.DiscoKey)), + ) if err != nil { return nil, fmt.Errorf("failed to parse disco public key: %w", err) } @@ -634,7 +638,7 @@ func (h *Headscale) RegisterMachine( } var machineKey key.MachinePublic - err = machineKey.UnmarshalText([]byte(machineKeyStr)) + err = machineKey.UnmarshalText([]byte(MachinePublicKeyEnsurePrefix(machineKeyStr))) if err != nil { return nil, err } diff --git a/oidc.go b/oidc.go index 48ad7187..d481e028 100644 --- a/oidc.go +++ b/oidc.go @@ -192,7 +192,7 @@ func (h *Headscale) OIDCCallback(ctx *gin.Context) { machineKeyStr, machineKeyOK := machineKeyIf.(string) var machineKey key.MachinePublic - err = machineKey.UnmarshalText([]byte(machineKeyStr)) + err = machineKey.UnmarshalText([]byte(MachinePublicKeyEnsurePrefix(machineKeyStr))) if err != nil { log.Error(). Msg("could not parse machine public key") diff --git a/poll.go b/poll.go index 70bacc6f..1d2db944 100644 --- a/poll.go +++ b/poll.go @@ -38,7 +38,7 @@ func (h *Headscale) PollNetMapHandler(ctx *gin.Context) { machineKeyStr := ctx.Param("id") var machineKey key.MachinePublic - err := machineKey.UnmarshalText([]byte(machineKeyStr)) + err := machineKey.UnmarshalText([]byte(MachinePublicKeyEnsurePrefix(machineKeyStr))) if err != nil { log.Error(). Str("handler", "PollNetMap"). diff --git a/utils.go b/utils.go index fa9f028d..c9971390 100644 --- a/utils.go +++ b/utils.go @@ -60,6 +60,30 @@ func DiscoPublicKeyStripPrefix(discoKey key.DiscoPublic) string { return strings.TrimPrefix(discoKey.String(), discoPublicHexPrefix) } +func MachinePublicKeyEnsurePrefix(machineKey string) string { + if !strings.HasPrefix(machineKey, machinePublicHexPrefix) { + return machinePublicHexPrefix + machineKey + } + + return machineKey +} + +func NodePublicKeyEnsurePrefix(nodeKey string) string { + if !strings.HasPrefix(nodeKey, nodePublicHexPrefix) { + return nodePublicHexPrefix + nodeKey + } + + return nodeKey +} + +func DiscoPublicKeyEnsurePrefix(discoKey string) string { + if !strings.HasPrefix(discoKey, discoPublicHexPrefix) { + return discoPublicHexPrefix + discoKey + } + + return discoKey +} + // Error is used to compare errors as per https://dave.cheney.net/2016/04/07/constant-errors type Error string From d96b681c8380f13c5b1a9ace86daf02ab536bf36 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Sat, 27 Nov 2021 20:25:37 +0000 Subject: [PATCH 216/300] Fix node cli integration test --- integration_cli_test.go | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/integration_cli_test.go b/integration_cli_test.go index eb553220..81a19334 100644 --- a/integration_cli_test.go +++ b/integration_cli_test.go @@ -639,7 +639,7 @@ func (s *IntegrationCLITestSuite) TestNodeCommand() { "--name", fmt.Sprintf("shared-machine-%d", index+1), "--namespace", - namespace.Name, + sharedNamespace.Name, "--key", machineKey, "--output", @@ -720,7 +720,6 @@ func (s *IntegrationCLITestSuite) TestNodeCommand() { []string{}, ) assert.Nil(s.T(), err) - fmt.Println("Error: ", err) var listOnlySharedMachineNamespace []v1.Machine err = json.Unmarshal( @@ -729,8 +728,6 @@ func (s *IntegrationCLITestSuite) TestNodeCommand() { ) assert.Nil(s.T(), err) - fmt.Println("List: ", listOnlySharedMachineNamespaceResult) - fmt.Println("List2: ", listOnlySharedMachineNamespace) assert.Len(s.T(), listOnlySharedMachineNamespace, 2) assert.Equal(s.T(), uint64(6), listOnlySharedMachineNamespace[0].Id) From 2ae882d8019329fce724409242dd5ea99d0c1e5f Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Sat, 27 Nov 2021 20:31:33 +0000 Subject: [PATCH 217/300] Update go version --- go.mod | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go.mod b/go.mod index e036effc..982c2989 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/juanfont/headscale -go 1.16 +go 1.17 require ( github.com/AlecAivazis/survey/v2 v2.3.2 From 6295b0bd843ac8676e3bf6cf2e9f8860f34f17c0 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Sat, 27 Nov 2021 20:34:46 +0000 Subject: [PATCH 218/300] Go mod tidy --- go.mod | 115 ++++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 94 insertions(+), 21 deletions(-) diff --git a/go.mod b/go.mod index 982c2989..2d9e8c61 100644 --- a/go.mod +++ b/go.mod @@ -4,35 +4,19 @@ go 1.17 require ( github.com/AlecAivazis/survey/v2 v2.3.2 - github.com/Microsoft/go-winio v0.5.0 // indirect - github.com/cenkalti/backoff/v4 v4.1.1 // indirect - github.com/cespare/xxhash/v2 v2.1.2 // indirect - github.com/containerd/continuity v0.1.0 // indirect github.com/coreos/go-oidc/v3 v3.1.0 - github.com/docker/cli v20.10.8+incompatible // indirect - github.com/docker/docker v20.10.8+incompatible // indirect github.com/efekarakus/termcolor v1.0.1 github.com/fatih/set v0.2.1 github.com/gin-gonic/gin v1.7.4 - github.com/go-playground/validator/v10 v10.9.0 // indirect github.com/gofrs/uuid v4.1.0+incompatible - github.com/google/go-github v17.0.0+incompatible // indirect - github.com/google/go-querystring v1.1.0 // indirect github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 github.com/grpc-ecosystem/grpc-gateway/v2 v2.6.0 github.com/infobloxopen/protoc-gen-gorm v1.0.1 - github.com/json-iterator/go v1.1.12 // indirect github.com/klauspost/compress v1.13.6 - github.com/lib/pq v1.10.3 // indirect - github.com/mattn/go-isatty v0.0.14 // indirect - github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6 // indirect - github.com/opencontainers/runc v1.0.2 // indirect github.com/ory/dockertest/v3 v3.7.0 github.com/patrickmn/go-cache v2.1.0+incompatible github.com/philip-bui/grpc-zerolog v1.0.1 github.com/prometheus/client_golang v1.11.0 - github.com/prometheus/common v0.32.1 // indirect - github.com/prometheus/procfs v0.7.3 // indirect github.com/pterm/pterm v0.12.30 github.com/rs/zerolog v1.26.0 github.com/soheilhy/cmux v0.1.5 @@ -41,20 +25,15 @@ require ( github.com/stretchr/testify v1.7.0 github.com/tailscale/hujson v0.0.0-20210923003652-c3758b31534b github.com/tcnksm/go-latest v0.0.0-20170313132115-e3007ae9052e - github.com/ugorji/go v1.2.6 // indirect - github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect github.com/zsais/go-gin-prometheus v0.1.0 - go4.org/mem v0.0.0-20210711025021-927187094b94 golang.org/x/crypto v0.0.0-20211117183948-ae814b36b871 golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 golang.org/x/sync v0.0.0-20210220032951-036812b2e83c - golang.org/x/sys v0.0.0-20211124211545-fe61309f8881 // indirect google.golang.org/genproto v0.0.0-20211104193956-4c6863e31247 google.golang.org/grpc v1.42.0 google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0 google.golang.org/protobuf v1.27.1 gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c - gopkg.in/square/go-jose.v2 v2.6.0 // indirect gopkg.in/yaml.v2 v2.4.0 gorm.io/datatypes v1.0.2 gorm.io/driver/postgres v1.1.1 @@ -63,3 +42,97 @@ require ( inet.af/netaddr v0.0.0-20211027220019-c74959edd3b6 tailscale.com v1.18.1 ) + +require ( + github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect + github.com/Microsoft/go-winio v0.5.0 // indirect + github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 // indirect + github.com/atomicgo/cursor v0.0.1 // indirect + github.com/beorn7/perks v1.0.1 // indirect + github.com/cenkalti/backoff/v4 v4.1.1 // indirect + github.com/cespare/xxhash/v2 v2.1.2 // indirect + github.com/containerd/continuity v0.1.0 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/docker/cli v20.10.8+incompatible // indirect + github.com/docker/docker v20.10.8+incompatible // indirect + github.com/docker/go-connections v0.4.0 // indirect + github.com/docker/go-units v0.4.0 // indirect + github.com/fsnotify/fsnotify v1.4.9 // indirect + github.com/ghodss/yaml v1.0.0 // indirect + github.com/gin-contrib/sse v0.1.0 // indirect + github.com/go-playground/locales v0.14.0 // indirect + github.com/go-playground/universal-translator v0.18.0 // indirect + github.com/go-playground/validator/v10 v10.9.0 // indirect + github.com/gogo/protobuf v1.3.2 // indirect + github.com/golang/glog v1.0.0 // indirect + github.com/golang/protobuf v1.5.2 // indirect + github.com/google/go-github v17.0.0+incompatible // indirect + github.com/google/go-querystring v1.1.0 // indirect + github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect + github.com/gookit/color v1.4.2 // indirect + github.com/hashicorp/go-version v1.2.0 // indirect + github.com/hashicorp/hcl v1.0.0 // indirect + github.com/imdario/mergo v0.3.12 // indirect + github.com/inconshreveable/mousetrap v1.0.0 // indirect + github.com/jackc/chunkreader/v2 v2.0.1 // indirect + github.com/jackc/pgconn v1.10.0 // indirect + github.com/jackc/pgio v1.0.0 // indirect + github.com/jackc/pgpassfile v1.0.0 // indirect + github.com/jackc/pgproto3/v2 v2.1.1 // indirect + github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b // indirect + github.com/jackc/pgtype v1.8.1 // indirect + github.com/jackc/pgx/v4 v4.13.0 // indirect + github.com/jinzhu/gorm v1.9.16 // indirect + github.com/jinzhu/inflection v1.0.0 // indirect + github.com/jinzhu/now v1.1.2 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect + github.com/kr/pretty v0.3.0 // indirect + github.com/kr/text v0.2.0 // indirect + github.com/leodido/go-urn v1.2.1 // indirect + github.com/lib/pq v1.10.3 // indirect + github.com/magiconair/properties v1.8.5 // indirect + github.com/mattn/go-colorable v0.1.8 // indirect + github.com/mattn/go-isatty v0.0.14 // indirect + github.com/mattn/go-runewidth v0.0.13 // indirect + github.com/mattn/go-sqlite3 v1.14.8 // indirect + github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect + github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b // indirect + github.com/mitchellh/mapstructure v1.4.1 // indirect + github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/opencontainers/go-digest v1.0.0 // indirect + github.com/opencontainers/image-spec v1.0.1 // indirect + github.com/opencontainers/runc v1.0.2 // indirect + github.com/pelletier/go-toml v1.9.3 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/prometheus/client_model v0.2.0 // indirect + github.com/prometheus/common v0.32.1 // indirect + github.com/prometheus/procfs v0.7.3 // indirect + github.com/rivo/uniseg v0.2.0 // indirect + github.com/rogpeppe/go-internal v1.8.0 // indirect + github.com/sirupsen/logrus v1.8.1 // indirect + github.com/spf13/afero v1.6.0 // indirect + github.com/spf13/cast v1.3.1 // indirect + github.com/spf13/jwalterweatherman v1.1.0 // indirect + github.com/spf13/pflag v1.0.5 // indirect + github.com/subosito/gotenv v1.2.0 // indirect + github.com/ugorji/go/codec v1.2.6 // indirect + github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect + github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect + github.com/xeipuuv/gojsonschema v1.2.0 // indirect + github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 // indirect + go4.org/intern v0.0.0-20211027215823-ae77deb06f29 // indirect + go4.org/mem v0.0.0-20210711025021-927187094b94 // indirect + go4.org/unsafe/assume-no-moving-gc v0.0.0-20211027215541-db492cf91b37 // indirect + golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 // indirect + golang.org/x/sys v0.0.0-20211124211545-fe61309f8881 // indirect + golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b // indirect + golang.org/x/text v0.3.7 // indirect + google.golang.org/appengine v1.6.7 // indirect + gopkg.in/ini.v1 v1.62.0 // indirect + gopkg.in/square/go-jose.v2 v2.6.0 // indirect + gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect +) From e9d5214d1cc608ee52f2e68f8028ce6a08edd3f1 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Sat, 27 Nov 2021 21:04:19 +0000 Subject: [PATCH 219/300] Disable tests which is broken due to split version --- integration_test.go | 84 ++++++++++++++++++++++++--------------------- 1 file changed, 44 insertions(+), 40 deletions(-) diff --git a/integration_test.go b/integration_test.go index d6aedf19..7840adc3 100644 --- a/integration_test.go +++ b/integration_test.go @@ -393,46 +393,50 @@ func (s *IntegrationTestSuite) TestGetIpAddresses() { } } -func (s *IntegrationTestSuite) TestStatus() { - for _, scales := range s.namespaces { - ips, err := getIPs(scales.tailscales) - assert.Nil(s.T(), err) - - for hostname, tailscale := range scales.tailscales { - s.T().Run(hostname, func(t *testing.T) { - command := []string{"tailscale", "status", "--json"} - - fmt.Printf("Getting status for %s\n", hostname) - result, err := ExecuteCommand( - &tailscale, - command, - []string{}, - ) - assert.Nil(t, err) - - var status ipnstate.Status - err = json.Unmarshal([]byte(result), &status) - assert.Nil(s.T(), err) - - // TODO(kradalby): Replace this check with peer length of SAME namespace - // Check if we have as many nodes in status - // as we have IPs/tailscales - // lines := strings.Split(result, "\n") - // assert.Equal(t, len(ips), len(lines)-1) - // assert.Equal(t, len(scales.tailscales), len(lines)-1) - - peerIps := getIPsfromIPNstate(status) - - // Check that all hosts is present in all hosts status - for ipHostname, ip := range ips { - if hostname != ipHostname { - assert.Contains(t, peerIps, ip) - } - } - }) - } - } -} +// TODO(kradalby): fix this test +// We need some way to impot ipnstate.Status from multiple go packages. +// Currently it will only work with 1.18.x since that is the last +// version we have in go.mod +// func (s *IntegrationTestSuite) TestStatus() { +// for _, scales := range s.namespaces { +// ips, err := getIPs(scales.tailscales) +// assert.Nil(s.T(), err) +// +// for hostname, tailscale := range scales.tailscales { +// s.T().Run(hostname, func(t *testing.T) { +// command := []string{"tailscale", "status", "--json"} +// +// fmt.Printf("Getting status for %s\n", hostname) +// result, err := ExecuteCommand( +// &tailscale, +// command, +// []string{}, +// ) +// assert.Nil(t, err) +// +// var status ipnstate.Status +// err = json.Unmarshal([]byte(result), &status) +// assert.Nil(s.T(), err) +// +// // TODO(kradalby): Replace this check with peer length of SAME namespace +// // Check if we have as many nodes in status +// // as we have IPs/tailscales +// // lines := strings.Split(result, "\n") +// // assert.Equal(t, len(ips), len(lines)-1) +// // assert.Equal(t, len(scales.tailscales), len(lines)-1) +// +// peerIps := getIPsfromIPNstate(status) +// +// // Check that all hosts is present in all hosts status +// for ipHostname, ip := range ips { +// if hostname != ipHostname { +// assert.Contains(t, peerIps, ip) +// } +// } +// }) +// } +// } +// } func getIPsfromIPNstate(status ipnstate.Status) []netaddr.IP { ips := make([]netaddr.IP, 0) From ff8c961dbbd8fe01cdacbd9da60d039b9fb4b83f Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Sun, 28 Nov 2021 08:23:45 +0000 Subject: [PATCH 220/300] Make sure comparison of nodekey is on the same format --- api.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api.go b/api.go index aadc604e..076594dc 100644 --- a/api.go +++ b/api.go @@ -127,7 +127,7 @@ func (h *Headscale) RegistrationHandler(ctx *gin.Context) { // - Trying to log out (sending a expiry in the past) // - A valid, registered machine, looking for the node map // - Expired machine wanting to reauthenticate - if machine.NodeKey == req.NodeKey.String() { + if machine.NodeKey == NodePublicKeyStripPrefix(req.NodeKey) { // The client sends an Expiry in the past if the client is requesting to expire the key (aka logout) // https://github.com/tailscale/tailscale/blob/main/tailcfg/tailcfg.go#L648 if !req.Expiry.IsZero() && req.Expiry.UTC().Before(now) { @@ -146,7 +146,7 @@ func (h *Headscale) RegistrationHandler(ctx *gin.Context) { } // The NodeKey we have matches OldNodeKey, which means this is a refresh after a key expiration - if machine.NodeKey == req.OldNodeKey.String() && + if machine.NodeKey == NodePublicKeyStripPrefix(req.OldNodeKey) && !machine.isExpired() { h.handleMachineRefreshKey(ctx, machineKey, req, *machine) From 32006f3a20c791d677c55528d9a3adf2d892c237 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Sun, 28 Nov 2021 08:26:36 +0000 Subject: [PATCH 221/300] Use go 1.17 --- .github/workflows/test-integration.yml | 2 +- .github/workflows/test.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test-integration.yml b/.github/workflows/test-integration.yml index e939df22..abf46d32 100644 --- a/.github/workflows/test-integration.yml +++ b/.github/workflows/test-integration.yml @@ -17,7 +17,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v2 with: - go-version: "1.16.3" + go-version: "1.17.3" - name: Run Integration tests run: go test -tags integration -timeout 30m diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 3d254fa6..4540482c 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -17,7 +17,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v2 with: - go-version: "1.16.3" # The Go version to download (if necessary) and use. + go-version: "1.17.3" # The Go version to download (if necessary) and use. # Install all the dependencies - name: Install dependencies From 34f4109fbd6b5c5da322eb31ac1dbe1b5d9d74e7 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Sun, 28 Nov 2021 09:17:18 +0000 Subject: [PATCH 222/300] Add back privatekey, but automatically generate it if it does not exist --- api.go | 2 +- app.go | 67 +++++++++++++++++++++++++++++++------- cmd/headscale/cli/utils.go | 9 ++--- utils.go | 11 +++++++ 4 files changed, 73 insertions(+), 16 deletions(-) diff --git a/api.go b/api.go index 076594dc..96e22bd5 100644 --- a/api.go +++ b/api.go @@ -34,7 +34,7 @@ func (h *Headscale) KeyHandler(ctx *gin.Context) { ctx.Data( http.StatusOK, "text/plain; charset=utf-8", - []byte(MachinePublicKeyStripPrefix(*h.publicKey)), + []byte(MachinePublicKeyStripPrefix(h.privateKey.Public())), ) } diff --git a/app.go b/app.go index 640803b6..db788908 100644 --- a/app.go +++ b/app.go @@ -47,11 +47,12 @@ import ( ) const ( - AuthPrefix = "Bearer " - Postgres = "postgres" - Sqlite = "sqlite3" - updateInterval = 5000 - HTTPReadTimeout = 30 * time.Second + AuthPrefix = "Bearer " + Postgres = "postgres" + Sqlite = "sqlite3" + updateInterval = 5000 + HTTPReadTimeout = 30 * time.Second + privateKeyFileMode = 0o600 requestedExpiryCacheExpiration = time.Minute * 5 requestedExpiryCacheCleanupInterval = time.Minute * 10 @@ -68,6 +69,7 @@ type Config struct { Addr string EphemeralNodeInactivityTimeout time.Duration IPPrefix netaddr.IPPrefix + PrivateKeyPath string BaseDomain string DERP DERPConfig @@ -128,7 +130,6 @@ type Headscale struct { dbString string dbType string dbDebug bool - publicKey *key.MachinePublic privateKey *key.MachinePrivate DERPMap *tailcfg.DERPMap @@ -147,8 +148,10 @@ type Headscale struct { // NewHeadscale returns the Headscale app. func NewHeadscale(cfg Config) (*Headscale, error) { - privKey := key.NewMachine() - pubKey := privKey.Public() + privKey, err := readOrCreatePrivateKey(cfg.PrivateKeyPath) + if err != nil { + return nil, fmt.Errorf("failed to read or create private key: %w", err) + } var dbString string switch cfg.DBtype { @@ -176,13 +179,12 @@ func NewHeadscale(cfg Config) (*Headscale, error) { cfg: cfg, dbType: cfg.DBtype, dbString: dbString, - privateKey: &privKey, - publicKey: &pubKey, + privateKey: privKey, aclRules: tailcfg.FilterAllowAll, // default allowall requestedExpiryCache: requestedExpiryCache, } - err := app.initDB() + err = app.initDB() if err != nil { return nil, err } @@ -694,3 +696,46 @@ func stdoutHandler(ctx *gin.Context) { Bytes("body", body). Msg("Request did not match") } + +func readOrCreatePrivateKey(path string) (*key.MachinePrivate, error) { + privateKey, err := os.ReadFile(path) + if errors.Is(err, os.ErrNotExist) { + log.Info().Str("path", path).Msg("No private key file at path, creating...") + + machineKey := key.NewMachine() + + machineKeyStr, err := machineKey.MarshalText() + if err != nil { + return nil, fmt.Errorf( + "failed to convert private key to string for saving: %w", + err, + ) + } + err = os.WriteFile(path, machineKeyStr, privateKeyFileMode) + if err != nil { + return nil, fmt.Errorf( + "failed to save private key to disk: %w", + err, + ) + } + + return &machineKey, nil + } else if err != nil { + return nil, fmt.Errorf("failed to read private key file: %w", err) + } + + privateKeyEnsurePrefix := PrivateKeyEnsurePrefix(string(privateKey)) + + var machineKey key.MachinePrivate + if err = machineKey.UnmarshalText([]byte(privateKeyEnsurePrefix)); err != nil { + log.Info(). + Str("path", path). + Msg("This might be due to a legacy (headscale pre-0.12) private key. " + + "If the key is in WireGuard format, delete the key and restart headscale. " + + "A new key will automatically be generated. All Tailscale clients will have to be restarted") + + return nil, fmt.Errorf("failed to parse private key: %w", err) + } + + return &machineKey, nil +} diff --git a/cmd/headscale/cli/utils.go b/cmd/headscale/cli/utils.go index d47a5ca9..a4856642 100644 --- a/cmd/headscale/cli/utils.go +++ b/cmd/headscale/cli/utils.go @@ -222,10 +222,11 @@ func getHeadscaleConfig() headscale.Config { derpConfig := GetDERPConfig() return headscale.Config{ - ServerURL: viper.GetString("server_url"), - Addr: viper.GetString("listen_addr"), - IPPrefix: netaddr.MustParseIPPrefix(viper.GetString("ip_prefix")), - BaseDomain: baseDomain, + ServerURL: viper.GetString("server_url"), + Addr: viper.GetString("listen_addr"), + IPPrefix: netaddr.MustParseIPPrefix(viper.GetString("ip_prefix")), + PrivateKeyPath: absPath(viper.GetString("private_key_path")), + BaseDomain: baseDomain, DERP: derpConfig, diff --git a/utils.go b/utils.go index c9971390..7011e63d 100644 --- a/utils.go +++ b/utils.go @@ -46,6 +46,9 @@ const ( // This prefix is used in the control protocol, so cannot be // changed. discoPublicHexPrefix = "discokey:" + + // privateKey prefix. + privateHexPrefix = "privkey:" ) func MachinePublicKeyStripPrefix(machineKey key.MachinePublic) string { @@ -84,6 +87,14 @@ func DiscoPublicKeyEnsurePrefix(discoKey string) string { return discoKey } +func PrivateKeyEnsurePrefix(privateKey string) string { + if !strings.HasPrefix(privateKey, privateHexPrefix) { + return privateHexPrefix + privateKey + } + + return privateKey +} + // Error is used to compare errors as per https://dave.cheney.net/2016/04/07/constant-errors type Error string From e167be6d64ee90400b33cddb669c6e2dbb878155 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Sun, 28 Nov 2021 09:18:24 +0000 Subject: [PATCH 223/300] Remove generate private key step from docs --- docs/Running.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/docs/Running.md b/docs/Running.md index ac9d2282..8aa5850e 100644 --- a/docs/Running.md +++ b/docs/Running.md @@ -39,11 +39,9 @@ touch config/db.sqlite ``` -4. Create a WireGuard private key, headscale configuration, and a DERP map file. Refer to [tailscale sample](https://raw.githubusercontent.com/tailscale/tailscale/main/net/dnsfallback/dns-fallback-servers.json) for more guidance. +4. Create a headscale configuration, and a DERP map file. Refer to [tailscale sample](https://raw.githubusercontent.com/tailscale/tailscale/main/net/dnsfallback/dns-fallback-servers.json) for more guidance. ```shell - wg genkey > config/private.key - cp config.yaml.[sqlite|postgres].example config/config.yaml cp derp-example.yaml config/derp.yaml From 5b8587037d1207e048b1e4150efbf013499b1732 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Sun, 28 Nov 2021 09:25:27 +0000 Subject: [PATCH 224/300] Remove non-existing field from oidc test --- oidc_test.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/oidc_test.go b/oidc_test.go index db581b99..d50027a9 100644 --- a/oidc_test.go +++ b/oidc_test.go @@ -19,7 +19,6 @@ func TestHeadscale_getNamespaceFromEmail(t *testing.T) { dbString string dbType string dbDebug bool - publicKey *key.MachinePublic privateKey *key.MachinePrivate aclPolicy *ACLPolicy aclRules []tailcfg.FilterRule @@ -153,7 +152,6 @@ func TestHeadscale_getNamespaceFromEmail(t *testing.T) { dbString: test.fields.dbString, dbType: test.fields.dbType, dbDebug: test.fields.dbDebug, - publicKey: test.fields.publicKey, privateKey: test.fields.privateKey, aclPolicy: test.fields.aclPolicy, aclRules: test.fields.aclRules, From 8e9a94613c0094e308bdcc086e96b15f12a4fda6 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Sun, 28 Nov 2021 11:00:22 +0000 Subject: [PATCH 225/300] Remove outdate integration test private key --- integration_test/etc/private.key | 1 - 1 file changed, 1 deletion(-) delete mode 100644 integration_test/etc/private.key diff --git a/integration_test/etc/private.key b/integration_test/etc/private.key deleted file mode 100644 index b3a3ae6d..00000000 --- a/integration_test/etc/private.key +++ /dev/null @@ -1 +0,0 @@ -SEmQwCu+tGywQWEUsf93TpTRUvlB7WhnCdHgWrSXjEA= From 3e941ef95995f565b72c7dea2fbedbdbc3580b87 Mon Sep 17 00:00:00 2001 From: Juan Font Date: Sun, 28 Nov 2021 22:00:22 +0000 Subject: [PATCH 226/300] Enable marking releases as prerelease --- .goreleaser.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.goreleaser.yml b/.goreleaser.yml index d20aed6b..5073b57c 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -3,6 +3,10 @@ before: hooks: - go mod tidy + +release: + prerelease: auto + builds: - id: darwin-amd64 main: ./cmd/headscale/headscale.go From 48fc93bbdcc4a23a6b12aab044291e1e2f5ab42b Mon Sep 17 00:00:00 2001 From: "Michael Ko. Gajda" Date: Mon, 29 Nov 2021 14:36:47 +0100 Subject: [PATCH 227/300] Add simple overview README for docs --- docs/README.md | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 docs/README.md diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 00000000..b86d99fb --- /dev/null +++ b/docs/README.md @@ -0,0 +1,7 @@ +# Official headscale documentation + +* [Configuration](Configuration.md) +* [Running](Running.md) +* [DNS](DNS.md) +* [TLS](TLS.md) +* [Glossary](Glossary.md) From 6fc6355d66ab23d56609df799a0abf08492beb0c Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Mon, 29 Nov 2021 17:31:19 +0000 Subject: [PATCH 228/300] Add initial CHANGELOG --- CHANGELOG.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 00000000..f296981b --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,18 @@ +# CHANGELOG + +**Unreleased: 0.12.0:** + +**BREAKING**: +- Upgrade to Tailscale 1.18 [#229](https://github.com/juanfont/headscale/pull/229) + - This change requires a new format for private key, private keys are now generated automatically: + 1. Delete your current key + 2. Restart `headscale`, a new key will be generated. + 3. Restart all Tailscale clients to fetch the new key + + + +**Changes**: +- Unifi configuration example [#197](https://github.com/juanfont/headscale/pull/197) +- Add gRPC and API (API is currently unavailable) [#204](https://github.com/juanfont/headscale/pull/204) +- Use gRPC between the CLI and the server [#206](https://github.com/juanfont/headscale/pull/206) [#212](https://github.com/juanfont/headscale/pull/212) +- Add stricter linting and formatting [#223](https://github.com/juanfont/headscale/pull/223) From 2e2fb687158c3c299a975523bc7c1cc8a19a5665 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Mon, 29 Nov 2021 17:32:05 +0000 Subject: [PATCH 229/300] Remove unreleased --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f296981b..7ed77b65 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # CHANGELOG -**Unreleased: 0.12.0:** +**0.12.0:** **BREAKING**: - Upgrade to Tailscale 1.18 [#229](https://github.com/juanfont/headscale/pull/229) From 42eb6b9e01fdbd8eaa509894087d7f3b7000905c Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Mon, 29 Nov 2021 17:34:41 +0000 Subject: [PATCH 230/300] format --- CHANGELOG.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7ed77b65..bfb29df9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,15 +3,15 @@ **0.12.0:** **BREAKING**: + - Upgrade to Tailscale 1.18 [#229](https://github.com/juanfont/headscale/pull/229) - - This change requires a new format for private key, private keys are now generated automatically: - 1. Delete your current key - 2. Restart `headscale`, a new key will be generated. - 3. Restart all Tailscale clients to fetch the new key - - + - This change requires a new format for private key, private keys are now generated automatically: + 1. Delete your current key + 2. Restart `headscale`, a new key will be generated. + 3. Restart all Tailscale clients to fetch the new key **Changes**: + - Unifi configuration example [#197](https://github.com/juanfont/headscale/pull/197) - Add gRPC and API (API is currently unavailable) [#204](https://github.com/juanfont/headscale/pull/204) - Use gRPC between the CLI and the server [#206](https://github.com/juanfont/headscale/pull/206) [#212](https://github.com/juanfont/headscale/pull/212) From 6350d528a7ec51b783a632f5498e6b162e07cf01 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Mon, 29 Nov 2021 19:45:31 +0000 Subject: [PATCH 231/300] Change changelog format --- CHANGELOG.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bfb29df9..a150b16b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # CHANGELOG -**0.12.0:** +**TBD (TBD):** **BREAKING**: @@ -16,3 +16,9 @@ - Add gRPC and API (API is currently unavailable) [#204](https://github.com/juanfont/headscale/pull/204) - Use gRPC between the CLI and the server [#206](https://github.com/juanfont/headscale/pull/206) [#212](https://github.com/juanfont/headscale/pull/212) - Add stricter linting and formatting [#223](https://github.com/juanfont/headscale/pull/223) + +**0.11.0 (2021-10-25):** + +**BREAKING**: + +- Make headscale fetch DERP map from URL and file [#196](https://github.com/juanfont/headscale/pull/196) From 78eba97bf9849c6acc5973382c2e758b60be1f09 Mon Sep 17 00:00:00 2001 From: "Michael Ko. Gajda" Date: Mon, 29 Nov 2021 14:37:00 +0100 Subject: [PATCH 232/300] Add GitHub templates --- .github/ISSUE_TEMPLATE/bug_report.md | 25 +++++++++++++++++++++++ .github/ISSUE_TEMPLATE/config.yml | 11 ++++++++++ .github/ISSUE_TEMPLATE/feature_request.md | 14 +++++++++++++ .github/ISSUE_TEMPLATE/other_issue.md | 25 +++++++++++++++++++++++ .github/pull_request_template.md | 10 +++++++++ 5 files changed, 85 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/bug_report.md create mode 100644 .github/ISSUE_TEMPLATE/config.yml create mode 100644 .github/ISSUE_TEMPLATE/feature_request.md create mode 100644 .github/ISSUE_TEMPLATE/other_issue.md create mode 100644 .github/pull_request_template.md diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 00000000..2ca3ecfa --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,25 @@ +--- +name: 'Bug report' +about: 'Create a bug report to help us improve' +title: '' +labels: [ 'bug' ] +assignees: '' +--- + +**Bug description** + + +**To Reproduce** + + +**Context info** + diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 00000000..d1937779 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,11 @@ +# Issues must have some content +blank_issues_enabled: false + +# Contact links +contact_links: + - name: "headsacle usage documentation" + url: "https://github.com/juanfont/headscale/blob/main/docs" + about: "Find documentation about how to configure and run headscale." + - name: "headscale Discord community" + url: "https://discord.com/invite/XcQxk2VHjx" + about: "Please ask and answer questions about usage of headscale here." diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 00000000..141ac042 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,14 @@ +--- +name: 'Feature request' +about: 'Suggest an idea for headscale' +title: '' +labels: [ 'enhancement' ] +assignees: '' +--- + +**Feature request** + + + diff --git a/.github/ISSUE_TEMPLATE/other_issue.md b/.github/ISSUE_TEMPLATE/other_issue.md new file mode 100644 index 00000000..7d9c11c3 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/other_issue.md @@ -0,0 +1,25 @@ +--- +name: 'Other issue' +about: 'Report a different issue' +title: '' +labels: [ 'bug' ] +assignees: '' +--- + + + +**Issue description** + + +**To Reproduce** + + +**Context info** + diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 00000000..c7015806 --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,10 @@ + + +- [] read the [CONTRIBUTING guidelines](README.md#user-content-contributing) +- [] raised a GitHub issue or discussed it on the projects chat beforehand +- [] added unit tests +- [] added integration tests +- [] updated documentation if needed +- [] updated CHANGELOG.md + + From acaab7a3dee0fbd4d92610c07074e0cdc542f2b1 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Tue, 30 Nov 2021 09:16:09 +0000 Subject: [PATCH 233/300] Add Open ID connect to changelog --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a150b16b..ddd94e40 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,10 @@ - Use gRPC between the CLI and the server [#206](https://github.com/juanfont/headscale/pull/206) [#212](https://github.com/juanfont/headscale/pull/212) - Add stricter linting and formatting [#223](https://github.com/juanfont/headscale/pull/223) +**Features**: + +- Beta OpenID Connect support [#126](https://github.com/juanfont/headscale/pull/126) [#227](https://github.com/juanfont/headscale/pull/227) + **0.11.0 (2021-10-25):** **BREAKING**: From 3435d95c80f2c425f068f95772d2b889f10d4713 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Tue, 30 Nov 2021 09:17:21 +0000 Subject: [PATCH 234/300] Clarify and formatting --- CHANGELOG.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ddd94e40..cdc9f55b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,14 +12,14 @@ **Changes**: -- Unifi configuration example [#197](https://github.com/juanfont/headscale/pull/197) -- Add gRPC and API (API is currently unavailable) [#204](https://github.com/juanfont/headscale/pull/204) -- Use gRPC between the CLI and the server [#206](https://github.com/juanfont/headscale/pull/206) [#212](https://github.com/juanfont/headscale/pull/212) +- Unify configuration example [#197](https://github.com/juanfont/headscale/pull/197) - Add stricter linting and formatting [#223](https://github.com/juanfont/headscale/pull/223) **Features**: -- Beta OpenID Connect support [#126](https://github.com/juanfont/headscale/pull/126) [#227](https://github.com/juanfont/headscale/pull/227) +- Add gRPC and HTTP API (HTTP API is currently disabled) [#204](https://github.com/juanfont/headscale/pull/204) +- Use gRPC between the CLI and the server [#206](https://github.com/juanfont/headscale/pull/206), [#212](https://github.com/juanfont/headscale/pull/212) +- Beta OpenID Connect support [#126](https://github.com/juanfont/headscale/pull/126), [#227](https://github.com/juanfont/headscale/pull/227) **0.11.0 (2021-10-25):** From c046ffbceb15dd73694f768accf62001c3610e47 Mon Sep 17 00:00:00 2001 From: ZiYuan Date: Wed, 1 Dec 2021 14:50:08 +0800 Subject: [PATCH 235/300] fix typo Remove redundant quotation: `ephemeral_node_inactivity_timeout": "30m"` => `ephemeral_node_inactivity_timeout: "30m"` --- docs/Configuration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Configuration.md b/docs/Configuration.md index f5e8c3f4..55ab56e5 100644 --- a/docs/Configuration.md +++ b/docs/Configuration.md @@ -28,7 +28,7 @@ derp_map_path: derp.yaml `derp_map_path` is the path to the [DERP](https://pkg.go.dev/tailscale.com/derp) map file. If the path is relative, it will be interpreted as relative to the directory the configuration file was read from. ```yaml -ephemeral_node_inactivity_timeout": "30m" +ephemeral_node_inactivity_timeout: "30m" ``` `ephemeral_node_inactivity_timeout` is the timeout after which inactive ephemeral node records will be deleted from the database. The default is 30 minutes. This value must be higher than 65 seconds (the keepalive timeout for the HTTP long poll is 60 seconds, plus a few seconds to avoid race conditions). From 07a437c7073d7e41ef30eabe1e9504634ddcaf53 Mon Sep 17 00:00:00 2001 From: Eugen Date: Wed, 1 Dec 2021 14:34:08 +0100 Subject: [PATCH 236/300] Add private_key_path to example config --- config-example.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/config-example.yaml b/config-example.yaml index dc4bd579..692c605a 100644 --- a/config-example.yaml +++ b/config-example.yaml @@ -6,6 +6,10 @@ server_url: http://127.0.0.1:8080 # Address to listen to / bind to on the server listen_addr: 0.0.0.0:8080 +# Private key file which will be +# autogenerated if it's missing +private_key_path: private.key + derp: # List of externally available DERP maps encoded in JSON urls: From 7e95b3501dcf8239e59c9cf6607ff67968d08b65 Mon Sep 17 00:00:00 2001 From: Eugen Date: Wed, 1 Dec 2021 19:32:47 +0100 Subject: [PATCH 237/300] Ignoe derp.yaml, don't panic in Serve() --- .gitignore | 1 + app.go | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 610550b9..ddec49c0 100644 --- a/.gitignore +++ b/.gitignore @@ -17,6 +17,7 @@ /headscale config.json config.yaml +derp.yaml *.key /db.sqlite *.sqlite3 diff --git a/app.go b/app.go index db788908..0fe65761 100644 --- a/app.go +++ b/app.go @@ -418,12 +418,12 @@ func (h *Headscale) Serve() error { err = h.ensureUnixSocketIsAbsent() if err != nil { - panic(err) + return err } socketListener, err := net.Listen("unix", h.cfg.UnixSocket) if err != nil { - panic(err) + return err } // Handle common process-killing signals so we can gracefully shut down: @@ -441,7 +441,7 @@ func (h *Headscale) Serve() error { networkListener, err := net.Listen("tcp", h.cfg.Addr) if err != nil { - panic(err) + return err } // Create the cmux object that will multiplex 2 protocols on the same port. From a6e99525aca8e32e1807f84017627e112b2e67ef Mon Sep 17 00:00:00 2001 From: Eugen Date: Wed, 1 Dec 2021 20:02:00 +0100 Subject: [PATCH 238/300] Add log_level to config, more ACL debug log --- .gitignore | 1 + acls.go | 7 +++++++ config-example.yaml | 2 ++ 3 files changed, 10 insertions(+) diff --git a/.gitignore b/.gitignore index ddec49c0..d047cbfd 100644 --- a/.gitignore +++ b/.gitignore @@ -18,6 +18,7 @@ config.json config.yaml derp.yaml +*.hujson *.key /db.sqlite *.sqlite3 diff --git a/acls.go b/acls.go index 1550c340..4017e28e 100644 --- a/acls.go +++ b/acls.go @@ -34,6 +34,11 @@ const ( // LoadACLPolicy loads the ACL policy from the specify path, and generates the ACL rules. func (h *Headscale) LoadACLPolicy(path string) error { + log.Debug(). + Str("func", "LoadACLPolicy"). + Str("path", path). + Msg("Loading ACL policy from path") + policyFile, err := os.Open(path) if err != nil { return err @@ -67,6 +72,8 @@ func (h *Headscale) LoadACLPolicy(path string) error { } h.aclRules = rules + log.Trace().Interface("ACL", rules).Msg("ACL rules generated") + return nil } diff --git a/config-example.yaml b/config-example.yaml index 692c605a..29b2f3ff 100644 --- a/config-example.yaml +++ b/config-example.yaml @@ -54,6 +54,8 @@ tls_letsencrypt_challenge_type: HTTP-01 tls_cert_path: "" tls_key_path: "" +log_level: info + # Path to a file containg ACL policies. acl_policy_path: "" From 0c13d9da156b03b4400c48a586a907c54d598ff9 Mon Sep 17 00:00:00 2001 From: "Michael Ko. Gajda" Date: Sat, 4 Dec 2021 18:51:09 +0100 Subject: [PATCH 239/300] Fix format with prettier --- .github/ISSUE_TEMPLATE/bug_report.md | 13 ++++++++----- .github/ISSUE_TEMPLATE/feature_request.md | 11 ++++++----- .github/ISSUE_TEMPLATE/other_issue.md | 13 ++++++++----- docs/README.md | 10 +++++----- 4 files changed, 27 insertions(+), 20 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 2ca3ecfa..f0902132 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -1,20 +1,23 @@ --- -name: 'Bug report' -about: 'Create a bug report to help us improve' -title: '' -labels: [ 'bug' ] -assignees: '' +name: "Bug report" +about: "Create a bug report to help us improve" +title: "" +labels: ["bug"] +assignees: "" --- **Bug description** + **To Reproduce** + **Context info** + **Issue description** + **To Reproduce** + **Context info** + - -2. When running headscale in a docker container, prepare a directory to hold all configuration - - ```shell - mkdir config - ``` - -3. Get yourself a DB - - a) Get a Postgres DB running in Docker: - - ```shell - docker run --name headscale \ - -e POSTGRES_DB=headscale \ - -e POSTGRES_USER=foo \ - -e POSTGRES_PASSWORD=bar \ - -p 5432:5432 \ - -d postgres - ``` - - or b) Prepare a SQLite DB file: - - ```shell - touch config/db.sqlite - ``` - -4. Create a headscale configuration, and a DERP map file. Refer to [tailscale sample](https://raw.githubusercontent.com/tailscale/tailscale/main/net/dnsfallback/dns-fallback-servers.json) for more guidance. - - ```shell - cp config.yaml.[sqlite|postgres].example config/config.yaml - - cp derp-example.yaml config/derp.yaml - ``` - -5. Create a namespace - - ```shell - headscale namespaces create myfirstnamespace - ``` - - or Docker: - - ```shell - docker run \ - -v $(pwd)/config:/etc/headscale/ \ - -p 127.0.0.1:8080:8080 \ - headscale/headscale:x.x.x \ - headscale namespaces create myfirstnamespace - ``` - - or if your server is already running in Docker: - - ```shell - docker exec \ - headscale namespaces create myfirstnamespace - ``` - -6. Run the server - - ```shell - headscale serve - ``` - - or Docker: - - ```shell - docker run \ - -v $(pwd)/config:/etc/headscale/ \ - -p 127.0.0.1:8080:8080 \ - headscale/headscale:x.x.x \ - headscale serve - ``` - -## Nodes configuration - -If you used tailscale.com before in your nodes, make sure you clear the tailscaled data folder - -```shell -systemctl stop tailscaled -rm -fr /var/lib/tailscale -systemctl start tailscaled -``` - -### Adding node based on MACHINEKEY - -1. Add your first machine - - ```shell - tailscale up --login-server YOUR_HEADSCALE_URL - ``` - -2. Navigate to the URL returned by `tailscale up`, where you'll find your machine key. - -3. In the server, register your machine to a namespace with the CLI - - ```shell - headscale -n myfirstnamespace nodes register -k YOURMACHINEKEY - ``` - - or Docker: - - ```shell - docker run \ - -v $(pwd)/config:/etc/headscale/ \ - headscale/headscale:x.x.x \ - headscale -n myfirstnamespace nodes register -k YOURMACHINEKEY - ``` - - or if your server is already running in Docker: - - ```shell - docker exec \ - headscale -n myfirstnamespace nodes register -k YOURMACHINEKEY - ``` - -### Alternative: adding node with AUTHKEY - -1. Create an authkey - - ```shell - headscale -n myfirstnamespace preauthkeys create --reusable --expiration 24h - ``` - - or Docker: - - ```shell - docker run \ - -v $(pwd)/config:/etc/headscale/ \ - headscale/headscale:x.x.x \ - headscale -n myfirstnamespace preauthkeys create --reusable --expiration 24h - ``` - - or if your server is already running in Docker: - - ```shell - docker exec \ - headscale -n myfirstnamespace preauthkeys create --reusable --expiration 24h - ``` - -2. Use the authkey on your node to register it: - - ```shell - tailscale up --login-server YOUR_HEADSCALE_URL --authkey YOURAUTHKEY - ``` - -If you create an authkey with the `--ephemeral` flag, that key will create ephemeral nodes. This implies that `--reusable` is true. - -Please bear in mind that all headscale commands support adding `-o json` or `-o json-line` to get nicely JSON-formatted output. - -## Debugging headscale running in Docker - -The `headscale/headscale` Docker container is based on a "distroless" image that does not contain a shell or any other debug tools. If you need to debug your application running in the Docker container, you can use the `-debug` variant, for example `headscale/headscale:x.x.x-debug`. - -### Running the debug Docker container - -To run the debug Docker container, use the exact same commands as above, but replace `headscale/headscale:x.x.x` with `headscale/headscale:x.x.x-debug` (`x.x.x` is the version of headscale). The two containers are compatible with each other, so you can alternate between them. - -### Executing commands in the debug container - -The default command in the debug container is to run `headscale`, which is located at `/bin/headscale` inside the container. - -Additionally, the debug container includes a minimalist Busybox shell. - -To launch a shell in the container, use: - -``` -docker run -it headscale/headscale:x.x.x-debug sh -``` - -You can also execute commands directly, such as `ls /bin` in this example: - -``` -docker run headscale/headscale:x.x.x-debug ls /bin -``` - -Using `docker exec` allows you to run commands in an existing container. diff --git a/docs/running-headscale-container.md b/docs/running-headscale-container.md new file mode 100644 index 00000000..996070ae --- /dev/null +++ b/docs/running-headscale-container.md @@ -0,0 +1,133 @@ +# Running headscale in a container + +**Note:** the container documentation is maintained by the \*_community_ and there is no guarentee +it is up to date, or working. + +## Goal + +This documentation has the goal of showing a user how-to set up and run `headscale` in a container. +[Docker]() is used as the reference container implementation, but there is no reason that it should +not work with alternatives like [Podman](). + +## Configure and run `headscale` + +1. Prepare a direction to hold `headscale` configuration and the [SQlite]() database: + +```shell +mkdir config +``` + +1. Create an empty SQlite datebase: + +```shell +touch config/db.sqlite +``` + +1. Create a `headscale` configuration: + +```shell +touch config/config.yaml +``` + +It is strongly recommended to copy the [example configuration](../config.yaml) from the [headscale repository](../) + +1. Start the headscale server: + +```shell +docker run \ + --name headscale \ + --detach \ + --rm \ + --volume $(pwd)/config:/etc/headscale/ \ + --publish 127.0.0.1:8080:8080 \ + headscale/headscale: \ + headscale serve + +``` + +This command will mount `config/` under `/etc/headscale`, forward port 8080 out of the container so the +`headscale` instance becomes available and then detach so headscale runs in the background. + +1. Verify `headscale` is running: + +Follow the container logs: + +```shell +docker logs --follow headscale +``` + +Verify running containers: + +```shell +docker ps +``` + +Verify `headscale` is available: + +```shell +curl http://127.0.0.1:8080/metrics +``` + +1. Create a namespace ([tailnet]()): + +```shell +docker exec headscale -- headscale namespaces create myfirstnamespace +``` + +### Register a machine (normal login) + +On a client machine, execute the `tailscale` login command: + +```shell +tailscale up --login-server YOUR_HEADSCALE_URL +``` + +To register a machine when running `headscale` in a container, take the headscale command and pass it to the container: + +```shell +docker exec headscale -- \ + headscale --namespace myfirstnamespace nodes register --key +``` + +### Register machine using a pre authenticated key + +Generate a key using the command line: + +```shell +docker exec headscale -- \ + headscale --namespace myfirstnamespace preauthkeys create --reusable --expiration 24h +``` + +This will return a pre-authenticated key that can be used to connect a node to `headscale` during the `tailscale` command: + +```shell +tailscale up --login-server --authkey +``` + +## Debugging headscale running in Docker + +The `headscale/headscale` Docker container is based on a "distroless" image that does not contain a shell or any other debug tools. If you need to debug your application running in the Docker container, you can use the `-debug` variant, for example `headscale/headscale:x.x.x-debug`. + +### Running the debug Docker container + +To run the debug Docker container, use the exact same commands as above, but replace `headscale/headscale:x.x.x` with `headscale/headscale:x.x.x-debug` (`x.x.x` is the version of headscale). The two containers are compatible with each other, so you can alternate between them. + +### Executing commands in the debug container + +The default command in the debug container is to run `headscale`, which is located at `/bin/headscale` inside the container. + +Additionally, the debug container includes a minimalist Busybox shell. + +To launch a shell in the container, use: + +``` +docker run -it headscale/headscale:x.x.x-debug sh +``` + +You can also execute commands directly, such as `ls /bin` in this example: + +``` +docker run headscale/headscale:x.x.x-debug ls /bin +``` + +Using `docker exec` allows you to run commands in an existing container. diff --git a/docs/running-headscale-linux.md b/docs/running-headscale-linux.md new file mode 100644 index 00000000..0f0d570a --- /dev/null +++ b/docs/running-headscale-linux.md @@ -0,0 +1,170 @@ +# Running headscale on Linux + +## Goal + +This documentation has the goal of showing a user how-to set up and run `headscale` on Linux. +In additional to the "get up and running section", there is an optional [SystemD section]() +describing how to make `headscale` run properly in a server environment. + +## Configure and run `headscale` + +1. Download the latest [`headscale` binary from GitHub's release page](): + +```shell +wget --output-document=/usr/local/bin/headscale \ + https://github.com/juanfont/headscale/releases/download/v/headscale__linux_ +``` + +1. Make `headscale` executable: + +```shell +chmod +x /usr/local/bin/headscale +``` + +1. Prepare a direction to hold `headscale` configuration and the [SQlite]() database: + +```shell +# Directory for configuration + +mkdir -p /etc/headscale + +# Directory for Database, and other variable data (like certificates) +mkdir -p /var/lib/headscale +``` + +1. Create an empty SQlite datebase: + +```shell +touch /var/lib/headscale/db.sqlite +``` + +1. Create a `headscale` configuration: + +```shell +touch /etc/headscale/config.yaml +``` + +It is strongly recommended to copy and modifiy the [example configuration](../config.yaml) +from the [headscale repository](../) + +1. Start the headscale server: + +```shell + headscale serve +``` + +This command will start `headscale` in the current terminal session. + +To continue the tutorial, open a new terminal and let it run in the background. +Alternatively use terminal emulators like [tmux]() or [screen](). + +To run `headscale` in the background, please follow the steps in the [SystemD section]() before continuing. + +1. Verify `headscale` is running: + +Verify `headscale` is available: + +```shell +curl http://127.0.0.1:8080/metrics +``` + +1. Create a namespace ([tailnet]()): + +```shell +headscale namespaces create myfirstnamespace +``` + +### Register a machine (normal login) + +On a client machine, execute the `tailscale` login command: + +```shell +tailscale up --login-server YOUR_HEADSCALE_URL +``` + +Register the machine: + +```shell +headscale --namespace myfirstnamespace nodes register --key +``` + +### Register machine using a pre authenticated key + +Generate a key using the command line: + +```shell +headscale --namespace myfirstnamespace preauthkeys create --reusable --expiration 24h +``` + +This will return a pre-authenticated key that can be used to connect a node to `headscale` during the `tailscale` command: + +```shell +tailscale up --login-server --authkey +``` + +## Running `headscale` in the background with SystemD + +In this section it will be demonstrated how to run `headscale` as a service in the background with [SystemD](). +This should work on most modern Linux distributions. + +1. Create a SystemD service configuration at `/etc/systemd/system/headscale.service` containing: + +```systemd +[Unit] +Description=headscale controller +After=syslog.target +After=network.target + +[Service] +Type=simple +User=headscale +Group=headscale +ExecStart=/usr/local/bin/headscale serve +Restart=always +RestartSec=5 + +# Optional security enhancements +NoNewPrivileges=yes +PrivateTmp=yes +ProtectSystem=strict +ProtectHome=yes +ReadWritePaths=/var/lib/headscale /var/run/headscale +AmbientCapabilities=CAP_NET_BIND_SERVICE +RuntimeDirectory=headscale + +[Install] +WantedBy=multi-user.target +``` + +1. In `/etc/headscale/config.yaml`, override the default `headscale` unix socket with a SystemD friendly path: + +```yaml +unix_socket: /var/run/headscale/headscale.sock +``` + +1. Reload SystemD to load the new configuration file: + +```shell +systemctl daemon-reload +``` + +1. Enable and start the new `headscale` service: + +```shell +systemctl enable headscale +systemctl start headscale +``` + +1. Verify the headscale service: + +```shell +systemctl status headscale +``` + +Verify `headscale` is available: + +```shell +curl http://127.0.0.1:8080/metrics +``` + +`headscale` will now run in the background and start at boot. From 74fd5de43da839ce6d8103982dadeba3a17f7e9d Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Sun, 2 Jan 2022 20:04:35 +0100 Subject: [PATCH 252/300] Move kubernetes example under docs --- {k8s => docs/examples/kubernetes}/.gitignore | 0 {k8s => docs/examples/kubernetes}/README.md | 0 {k8s => docs/examples/kubernetes}/base/configmap.yaml | 0 {k8s => docs/examples/kubernetes}/base/ingress.yaml | 0 {k8s => docs/examples/kubernetes}/base/kustomization.yaml | 0 {k8s => docs/examples/kubernetes}/base/service.yaml | 0 {k8s => docs/examples/kubernetes}/headscale.bash | 0 {k8s => docs/examples/kubernetes}/init.bash | 0 {k8s => docs/examples/kubernetes}/install-cert-manager.bash | 0 {k8s => docs/examples/kubernetes}/postgres/deployment.yaml | 0 {k8s => docs/examples/kubernetes}/postgres/kustomization.yaml | 0 {k8s => docs/examples/kubernetes}/postgres/postgres-service.yaml | 0 .../examples/kubernetes}/postgres/postgres-statefulset.yaml | 0 .../examples/kubernetes}/production-tls/ingress-patch.yaml | 0 .../examples/kubernetes}/production-tls/kustomization.yaml | 0 .../examples/kubernetes}/production-tls/production-issuer.yaml | 0 {k8s => docs/examples/kubernetes}/sqlite/kustomization.yaml | 0 {k8s => docs/examples/kubernetes}/sqlite/statefulset.yaml | 0 {k8s => docs/examples/kubernetes}/staging-tls/ingress-patch.yaml | 0 {k8s => docs/examples/kubernetes}/staging-tls/kustomization.yaml | 0 {k8s => docs/examples/kubernetes}/staging-tls/staging-issuer.yaml | 0 21 files changed, 0 insertions(+), 0 deletions(-) rename {k8s => docs/examples/kubernetes}/.gitignore (100%) rename {k8s => docs/examples/kubernetes}/README.md (100%) rename {k8s => docs/examples/kubernetes}/base/configmap.yaml (100%) rename {k8s => docs/examples/kubernetes}/base/ingress.yaml (100%) rename {k8s => docs/examples/kubernetes}/base/kustomization.yaml (100%) rename {k8s => docs/examples/kubernetes}/base/service.yaml (100%) rename {k8s => docs/examples/kubernetes}/headscale.bash (100%) rename {k8s => docs/examples/kubernetes}/init.bash (100%) rename {k8s => docs/examples/kubernetes}/install-cert-manager.bash (100%) rename {k8s => docs/examples/kubernetes}/postgres/deployment.yaml (100%) rename {k8s => docs/examples/kubernetes}/postgres/kustomization.yaml (100%) rename {k8s => docs/examples/kubernetes}/postgres/postgres-service.yaml (100%) rename {k8s => docs/examples/kubernetes}/postgres/postgres-statefulset.yaml (100%) rename {k8s => docs/examples/kubernetes}/production-tls/ingress-patch.yaml (100%) rename {k8s => docs/examples/kubernetes}/production-tls/kustomization.yaml (100%) rename {k8s => docs/examples/kubernetes}/production-tls/production-issuer.yaml (100%) rename {k8s => docs/examples/kubernetes}/sqlite/kustomization.yaml (100%) rename {k8s => docs/examples/kubernetes}/sqlite/statefulset.yaml (100%) rename {k8s => docs/examples/kubernetes}/staging-tls/ingress-patch.yaml (100%) rename {k8s => docs/examples/kubernetes}/staging-tls/kustomization.yaml (100%) rename {k8s => docs/examples/kubernetes}/staging-tls/staging-issuer.yaml (100%) diff --git a/k8s/.gitignore b/docs/examples/kubernetes/.gitignore similarity index 100% rename from k8s/.gitignore rename to docs/examples/kubernetes/.gitignore diff --git a/k8s/README.md b/docs/examples/kubernetes/README.md similarity index 100% rename from k8s/README.md rename to docs/examples/kubernetes/README.md diff --git a/k8s/base/configmap.yaml b/docs/examples/kubernetes/base/configmap.yaml similarity index 100% rename from k8s/base/configmap.yaml rename to docs/examples/kubernetes/base/configmap.yaml diff --git a/k8s/base/ingress.yaml b/docs/examples/kubernetes/base/ingress.yaml similarity index 100% rename from k8s/base/ingress.yaml rename to docs/examples/kubernetes/base/ingress.yaml diff --git a/k8s/base/kustomization.yaml b/docs/examples/kubernetes/base/kustomization.yaml similarity index 100% rename from k8s/base/kustomization.yaml rename to docs/examples/kubernetes/base/kustomization.yaml diff --git a/k8s/base/service.yaml b/docs/examples/kubernetes/base/service.yaml similarity index 100% rename from k8s/base/service.yaml rename to docs/examples/kubernetes/base/service.yaml diff --git a/k8s/headscale.bash b/docs/examples/kubernetes/headscale.bash similarity index 100% rename from k8s/headscale.bash rename to docs/examples/kubernetes/headscale.bash diff --git a/k8s/init.bash b/docs/examples/kubernetes/init.bash similarity index 100% rename from k8s/init.bash rename to docs/examples/kubernetes/init.bash diff --git a/k8s/install-cert-manager.bash b/docs/examples/kubernetes/install-cert-manager.bash similarity index 100% rename from k8s/install-cert-manager.bash rename to docs/examples/kubernetes/install-cert-manager.bash diff --git a/k8s/postgres/deployment.yaml b/docs/examples/kubernetes/postgres/deployment.yaml similarity index 100% rename from k8s/postgres/deployment.yaml rename to docs/examples/kubernetes/postgres/deployment.yaml diff --git a/k8s/postgres/kustomization.yaml b/docs/examples/kubernetes/postgres/kustomization.yaml similarity index 100% rename from k8s/postgres/kustomization.yaml rename to docs/examples/kubernetes/postgres/kustomization.yaml diff --git a/k8s/postgres/postgres-service.yaml b/docs/examples/kubernetes/postgres/postgres-service.yaml similarity index 100% rename from k8s/postgres/postgres-service.yaml rename to docs/examples/kubernetes/postgres/postgres-service.yaml diff --git a/k8s/postgres/postgres-statefulset.yaml b/docs/examples/kubernetes/postgres/postgres-statefulset.yaml similarity index 100% rename from k8s/postgres/postgres-statefulset.yaml rename to docs/examples/kubernetes/postgres/postgres-statefulset.yaml diff --git a/k8s/production-tls/ingress-patch.yaml b/docs/examples/kubernetes/production-tls/ingress-patch.yaml similarity index 100% rename from k8s/production-tls/ingress-patch.yaml rename to docs/examples/kubernetes/production-tls/ingress-patch.yaml diff --git a/k8s/production-tls/kustomization.yaml b/docs/examples/kubernetes/production-tls/kustomization.yaml similarity index 100% rename from k8s/production-tls/kustomization.yaml rename to docs/examples/kubernetes/production-tls/kustomization.yaml diff --git a/k8s/production-tls/production-issuer.yaml b/docs/examples/kubernetes/production-tls/production-issuer.yaml similarity index 100% rename from k8s/production-tls/production-issuer.yaml rename to docs/examples/kubernetes/production-tls/production-issuer.yaml diff --git a/k8s/sqlite/kustomization.yaml b/docs/examples/kubernetes/sqlite/kustomization.yaml similarity index 100% rename from k8s/sqlite/kustomization.yaml rename to docs/examples/kubernetes/sqlite/kustomization.yaml diff --git a/k8s/sqlite/statefulset.yaml b/docs/examples/kubernetes/sqlite/statefulset.yaml similarity index 100% rename from k8s/sqlite/statefulset.yaml rename to docs/examples/kubernetes/sqlite/statefulset.yaml diff --git a/k8s/staging-tls/ingress-patch.yaml b/docs/examples/kubernetes/staging-tls/ingress-patch.yaml similarity index 100% rename from k8s/staging-tls/ingress-patch.yaml rename to docs/examples/kubernetes/staging-tls/ingress-patch.yaml diff --git a/k8s/staging-tls/kustomization.yaml b/docs/examples/kubernetes/staging-tls/kustomization.yaml similarity index 100% rename from k8s/staging-tls/kustomization.yaml rename to docs/examples/kubernetes/staging-tls/kustomization.yaml diff --git a/k8s/staging-tls/staging-issuer.yaml b/docs/examples/kubernetes/staging-tls/staging-issuer.yaml similarity index 100% rename from k8s/staging-tls/staging-issuer.yaml rename to docs/examples/kubernetes/staging-tls/staging-issuer.yaml From 8a07a63b1c71af340a0efccf2f1d7792138da868 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Sun, 2 Jan 2022 20:06:21 +0100 Subject: [PATCH 253/300] Write disclaimer in kubernetes example --- docs/examples/kubernetes/README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/examples/kubernetes/README.md b/docs/examples/kubernetes/README.md index 78e9ef2c..cc57f147 100644 --- a/docs/examples/kubernetes/README.md +++ b/docs/examples/kubernetes/README.md @@ -1,5 +1,7 @@ # Deploying headscale on Kubernetes +**Note:** This is contributed by the community and not verified by the headscale authors. + This directory contains [Kustomize](https://kustomize.io) templates that deploy headscale in various configurations. @@ -66,7 +68,7 @@ tasks like creating namespaces, authkeys, etc. headscale is an open source implementation of the Tailscale control server -https://gitlab.com/juanfont/headscale +https://github.com/juanfont/headscale Usage: headscale [command] From 8d504c35bf4aefc6931e357f6814d1718139bf89 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Sun, 2 Jan 2022 20:06:32 +0100 Subject: [PATCH 254/300] Move kubernetes to kustomize, since thats what it is --- docs/examples/{kubernetes => kustomize}/.gitignore | 0 docs/examples/{kubernetes => kustomize}/README.md | 0 docs/examples/{kubernetes => kustomize}/base/configmap.yaml | 0 docs/examples/{kubernetes => kustomize}/base/ingress.yaml | 0 docs/examples/{kubernetes => kustomize}/base/kustomization.yaml | 0 docs/examples/{kubernetes => kustomize}/base/service.yaml | 0 docs/examples/{kubernetes => kustomize}/headscale.bash | 0 docs/examples/{kubernetes => kustomize}/init.bash | 0 docs/examples/{kubernetes => kustomize}/install-cert-manager.bash | 0 docs/examples/{kubernetes => kustomize}/postgres/deployment.yaml | 0 .../{kubernetes => kustomize}/postgres/kustomization.yaml | 0 .../{kubernetes => kustomize}/postgres/postgres-service.yaml | 0 .../{kubernetes => kustomize}/postgres/postgres-statefulset.yaml | 0 .../{kubernetes => kustomize}/production-tls/ingress-patch.yaml | 0 .../{kubernetes => kustomize}/production-tls/kustomization.yaml | 0 .../production-tls/production-issuer.yaml | 0 docs/examples/{kubernetes => kustomize}/sqlite/kustomization.yaml | 0 docs/examples/{kubernetes => kustomize}/sqlite/statefulset.yaml | 0 .../{kubernetes => kustomize}/staging-tls/ingress-patch.yaml | 0 .../{kubernetes => kustomize}/staging-tls/kustomization.yaml | 0 .../{kubernetes => kustomize}/staging-tls/staging-issuer.yaml | 0 21 files changed, 0 insertions(+), 0 deletions(-) rename docs/examples/{kubernetes => kustomize}/.gitignore (100%) rename docs/examples/{kubernetes => kustomize}/README.md (100%) rename docs/examples/{kubernetes => kustomize}/base/configmap.yaml (100%) rename docs/examples/{kubernetes => kustomize}/base/ingress.yaml (100%) rename docs/examples/{kubernetes => kustomize}/base/kustomization.yaml (100%) rename docs/examples/{kubernetes => kustomize}/base/service.yaml (100%) rename docs/examples/{kubernetes => kustomize}/headscale.bash (100%) rename docs/examples/{kubernetes => kustomize}/init.bash (100%) rename docs/examples/{kubernetes => kustomize}/install-cert-manager.bash (100%) rename docs/examples/{kubernetes => kustomize}/postgres/deployment.yaml (100%) rename docs/examples/{kubernetes => kustomize}/postgres/kustomization.yaml (100%) rename docs/examples/{kubernetes => kustomize}/postgres/postgres-service.yaml (100%) rename docs/examples/{kubernetes => kustomize}/postgres/postgres-statefulset.yaml (100%) rename docs/examples/{kubernetes => kustomize}/production-tls/ingress-patch.yaml (100%) rename docs/examples/{kubernetes => kustomize}/production-tls/kustomization.yaml (100%) rename docs/examples/{kubernetes => kustomize}/production-tls/production-issuer.yaml (100%) rename docs/examples/{kubernetes => kustomize}/sqlite/kustomization.yaml (100%) rename docs/examples/{kubernetes => kustomize}/sqlite/statefulset.yaml (100%) rename docs/examples/{kubernetes => kustomize}/staging-tls/ingress-patch.yaml (100%) rename docs/examples/{kubernetes => kustomize}/staging-tls/kustomization.yaml (100%) rename docs/examples/{kubernetes => kustomize}/staging-tls/staging-issuer.yaml (100%) diff --git a/docs/examples/kubernetes/.gitignore b/docs/examples/kustomize/.gitignore similarity index 100% rename from docs/examples/kubernetes/.gitignore rename to docs/examples/kustomize/.gitignore diff --git a/docs/examples/kubernetes/README.md b/docs/examples/kustomize/README.md similarity index 100% rename from docs/examples/kubernetes/README.md rename to docs/examples/kustomize/README.md diff --git a/docs/examples/kubernetes/base/configmap.yaml b/docs/examples/kustomize/base/configmap.yaml similarity index 100% rename from docs/examples/kubernetes/base/configmap.yaml rename to docs/examples/kustomize/base/configmap.yaml diff --git a/docs/examples/kubernetes/base/ingress.yaml b/docs/examples/kustomize/base/ingress.yaml similarity index 100% rename from docs/examples/kubernetes/base/ingress.yaml rename to docs/examples/kustomize/base/ingress.yaml diff --git a/docs/examples/kubernetes/base/kustomization.yaml b/docs/examples/kustomize/base/kustomization.yaml similarity index 100% rename from docs/examples/kubernetes/base/kustomization.yaml rename to docs/examples/kustomize/base/kustomization.yaml diff --git a/docs/examples/kubernetes/base/service.yaml b/docs/examples/kustomize/base/service.yaml similarity index 100% rename from docs/examples/kubernetes/base/service.yaml rename to docs/examples/kustomize/base/service.yaml diff --git a/docs/examples/kubernetes/headscale.bash b/docs/examples/kustomize/headscale.bash similarity index 100% rename from docs/examples/kubernetes/headscale.bash rename to docs/examples/kustomize/headscale.bash diff --git a/docs/examples/kubernetes/init.bash b/docs/examples/kustomize/init.bash similarity index 100% rename from docs/examples/kubernetes/init.bash rename to docs/examples/kustomize/init.bash diff --git a/docs/examples/kubernetes/install-cert-manager.bash b/docs/examples/kustomize/install-cert-manager.bash similarity index 100% rename from docs/examples/kubernetes/install-cert-manager.bash rename to docs/examples/kustomize/install-cert-manager.bash diff --git a/docs/examples/kubernetes/postgres/deployment.yaml b/docs/examples/kustomize/postgres/deployment.yaml similarity index 100% rename from docs/examples/kubernetes/postgres/deployment.yaml rename to docs/examples/kustomize/postgres/deployment.yaml diff --git a/docs/examples/kubernetes/postgres/kustomization.yaml b/docs/examples/kustomize/postgres/kustomization.yaml similarity index 100% rename from docs/examples/kubernetes/postgres/kustomization.yaml rename to docs/examples/kustomize/postgres/kustomization.yaml diff --git a/docs/examples/kubernetes/postgres/postgres-service.yaml b/docs/examples/kustomize/postgres/postgres-service.yaml similarity index 100% rename from docs/examples/kubernetes/postgres/postgres-service.yaml rename to docs/examples/kustomize/postgres/postgres-service.yaml diff --git a/docs/examples/kubernetes/postgres/postgres-statefulset.yaml b/docs/examples/kustomize/postgres/postgres-statefulset.yaml similarity index 100% rename from docs/examples/kubernetes/postgres/postgres-statefulset.yaml rename to docs/examples/kustomize/postgres/postgres-statefulset.yaml diff --git a/docs/examples/kubernetes/production-tls/ingress-patch.yaml b/docs/examples/kustomize/production-tls/ingress-patch.yaml similarity index 100% rename from docs/examples/kubernetes/production-tls/ingress-patch.yaml rename to docs/examples/kustomize/production-tls/ingress-patch.yaml diff --git a/docs/examples/kubernetes/production-tls/kustomization.yaml b/docs/examples/kustomize/production-tls/kustomization.yaml similarity index 100% rename from docs/examples/kubernetes/production-tls/kustomization.yaml rename to docs/examples/kustomize/production-tls/kustomization.yaml diff --git a/docs/examples/kubernetes/production-tls/production-issuer.yaml b/docs/examples/kustomize/production-tls/production-issuer.yaml similarity index 100% rename from docs/examples/kubernetes/production-tls/production-issuer.yaml rename to docs/examples/kustomize/production-tls/production-issuer.yaml diff --git a/docs/examples/kubernetes/sqlite/kustomization.yaml b/docs/examples/kustomize/sqlite/kustomization.yaml similarity index 100% rename from docs/examples/kubernetes/sqlite/kustomization.yaml rename to docs/examples/kustomize/sqlite/kustomization.yaml diff --git a/docs/examples/kubernetes/sqlite/statefulset.yaml b/docs/examples/kustomize/sqlite/statefulset.yaml similarity index 100% rename from docs/examples/kubernetes/sqlite/statefulset.yaml rename to docs/examples/kustomize/sqlite/statefulset.yaml diff --git a/docs/examples/kubernetes/staging-tls/ingress-patch.yaml b/docs/examples/kustomize/staging-tls/ingress-patch.yaml similarity index 100% rename from docs/examples/kubernetes/staging-tls/ingress-patch.yaml rename to docs/examples/kustomize/staging-tls/ingress-patch.yaml diff --git a/docs/examples/kubernetes/staging-tls/kustomization.yaml b/docs/examples/kustomize/staging-tls/kustomization.yaml similarity index 100% rename from docs/examples/kubernetes/staging-tls/kustomization.yaml rename to docs/examples/kustomize/staging-tls/kustomization.yaml diff --git a/docs/examples/kubernetes/staging-tls/staging-issuer.yaml b/docs/examples/kustomize/staging-tls/staging-issuer.yaml similarity index 100% rename from docs/examples/kubernetes/staging-tls/staging-issuer.yaml rename to docs/examples/kustomize/staging-tls/staging-issuer.yaml From a75c5a4cff93a3ec654f80e78eace9b65d18c3ea Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Sun, 2 Jan 2022 20:08:04 +0100 Subject: [PATCH 255/300] Add eradme to examples --- docs/examples/README.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 docs/examples/README.md diff --git a/docs/examples/README.md b/docs/examples/README.md new file mode 100644 index 00000000..f9e85ff3 --- /dev/null +++ b/docs/examples/README.md @@ -0,0 +1,5 @@ +# Examples + +This directory contains examples on how to run `headscale` on different platforms. + +All examples are provided by the community and they are not verified by the `headscale` authors. From a11c6fd8b99d9457247fd8fe69e5c736e9f61b7c Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Sun, 2 Jan 2022 20:08:18 +0100 Subject: [PATCH 256/300] Fix formatting error in container doc --- docs/running-headscale-container.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/running-headscale-container.md b/docs/running-headscale-container.md index 996070ae..c1f4099d 100644 --- a/docs/running-headscale-container.md +++ b/docs/running-headscale-container.md @@ -1,6 +1,6 @@ # Running headscale in a container -**Note:** the container documentation is maintained by the \*_community_ and there is no guarentee +**Note:** the container documentation is maintained by the _community_ and there is no guarentee it is up to date, or working. ## Goal From 3ce3ccb559b28cde87cb496be03510a13b927c04 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Sun, 2 Jan 2022 19:36:50 +0000 Subject: [PATCH 257/300] Reorder tls docs --- docs/TLS.md | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/docs/TLS.md b/docs/TLS.md index 47de1cd7..557cdf01 100644 --- a/docs/TLS.md +++ b/docs/TLS.md @@ -1,5 +1,9 @@ # Running the service via TLS (optional) +## Let's Encrypt / ACME + +To get a certificate automatically via [Let's Encrypt](https://letsencrypt.org/), set `tls_letsencrypt_hostname` to the desired certificate hostname. This name must resolve to the IP address(es) headscale is reachable on (i.e., it must correspond to the `server_url` configuration parameter). The certificate and Let's Encrypt account credentials will be stored in the directory configured in `tls_letsencrypt_cache_dir`. If the path is relative, it will be interpreted as relative to the directory the configuration file was read from. The certificate will automatically be renewed as needed. + ```yaml tls_letsencrypt_hostname: "" tls_letsencrypt_listen: ":http" @@ -7,21 +11,21 @@ tls_letsencrypt_cache_dir: ".cache" tls_letsencrypt_challenge_type: HTTP-01 ``` -To get a certificate automatically via [Let's Encrypt](https://letsencrypt.org/), set `tls_letsencrypt_hostname` to the desired certificate hostname. This name must resolve to the IP address(es) headscale is reachable on (i.e., it must correspond to the `server_url` configuration parameter). The certificate and Let's Encrypt account credentials will be stored in the directory configured in `tls_letsencrypt_cache_dir`. If the path is relative, it will be interpreted as relative to the directory the configuration file was read from. The certificate will automatically be renewed as needed. - -```yaml -tls_cert_path: "" -tls_key_path: "" -``` - -headscale can also be configured to expose its web service via TLS. To configure the certificate and key file manually, set the `tls_cert_path` and `tls_cert_path` configuration parameters. If the path is relative, it will be interpreted as relative to the directory the configuration file was read from. - -## Challenge type HTTP-01 +### Challenge type HTTP-01 The default challenge type `HTTP-01` requires that headscale is reachable on port 80 for the Let's Encrypt automated validation, in addition to whatever port is configured in `listen_addr`. By default, headscale listens on port 80 on all local IPs for Let's Encrypt automated validation. If you need to change the ip and/or port used by headscale for the Let's Encrypt validation process, set `tls_letsencrypt_listen` to the appropriate value. This can be handy if you are running headscale as a non-root user (or can't run `setcap`). Keep in mind, however, that Let's Encrypt will _only_ connect to port 80 for the validation callback, so if you change `tls_letsencrypt_listen` you will also need to configure something else (e.g. a firewall rule) to forward the traffic from port 80 to the ip:port combination specified in `tls_letsencrypt_listen`. -## Challenge type TLS-ALPN-01 +### Challenge type TLS-ALPN-01 Alternatively, `tls_letsencrypt_challenge_type` can be set to `TLS-ALPN-01`. In this configuration, headscale listens on the ip:port combination defined in `listen_addr`. Let's Encrypt will _only_ connect to port 443 for the validation callback, so if `listen_addr` is not set to port 443, something else (e.g. a firewall rule) will be required to forward the traffic from port 443 to the ip:port combination specified in `listen_addr`. + +## Bring your own certificate + +headscale can also be configured to expose its web service via TLS. To configure the certificate and key file manually, set the `tls_cert_path` and `tls_cert_path` configuration parameters. If the path is relative, it will be interpreted as relative to the directory the configuration file was read from. + +```yaml +tls_cert_path: "" +tls_key_path: "" +``` From 80d196cbfd30dc9b81d9a7033fa1bd409aafdbf8 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Sun, 2 Jan 2022 19:37:48 +0000 Subject: [PATCH 258/300] Remove DNS file, it will be merged into example configuration --- docs/DNS.md | 37 ------------------------------------- 1 file changed, 37 deletions(-) delete mode 100644 docs/DNS.md diff --git a/docs/DNS.md b/docs/DNS.md deleted file mode 100644 index 53106526..00000000 --- a/docs/DNS.md +++ /dev/null @@ -1,37 +0,0 @@ -# DNS in headscale - -headscale supports Tailscale's DNS configuration and MagicDNS. Please have a look to their KB to better understand what this means: - -- https://tailscale.com/kb/1054/dns/ -- https://tailscale.com/kb/1081/magicdns/ -- https://tailscale.com/blog/2021-09-private-dns-with-magicdns/ - -Long story short, you can define the DNS servers you want to use in your tailnets, activate MagicDNS (so you don't have to remember the IP addresses of your nodes), define search domains, as well as predefined hosts. headscale will inject that settings into your nodes. - -## Configuration reference - -The setup is done via the `config.yaml` file, under the `dns_config` key. - -```yaml -server_url: http://127.0.0.1:8001 -listen_addr: 0.0.0.0:8001 -dns_config: - nameservers: - - 1.1.1.1 - - 8.8.8.8 - restricted_nameservers: - foo.bar.com: - - 1.1.1.1 - darp.headscale.net: - - 1.1.1.1 - - 8.8.8.8 - domains: [] - magic_dns: true - base_domain: example.com -``` - -- `nameservers`: The list of DNS servers to use. -- `domains`: Search domains to inject. -- `magic_dns`: Whether to use [MagicDNS](https://tailscale.com/kb/1081/magicdns/). Only works if there is at least a nameserver defined. -- `base_domain`: Defines the base domain to create the hostnames for MagicDNS. `base_domain` must be a FQDNs, without the trailing dot. The FQDN of the hosts will be `hostname.namespace.base_domain` (e.g., _myhost.mynamespace.example.com_). -- `restricted_nameservers`: Split DNS (see https://tailscale.com/kb/1054/dns/), list of search domains and the DNS to query for each one. From 271cb71754961cfe9a1cc3e82917255e9cd8fa4e Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Sun, 2 Jan 2022 19:38:04 +0000 Subject: [PATCH 259/300] Add more explaination and less redunancy with docs --- config-example.yaml | 87 ++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 79 insertions(+), 8 deletions(-) diff --git a/config-example.yaml b/config-example.yaml index aceb8ada..e26f06e8 100644 --- a/config-example.yaml +++ b/config-example.yaml @@ -1,21 +1,38 @@ --- # The url clients will connect to. -# Typically this will be a domain. +# Typically this will be a domain like: +# +# https://myheadscale.example.com:443 +# server_url: http://127.0.0.1:8080 # Address to listen to / bind to on the server +# listen_addr: 0.0.0.0:8080 -# Private key file which will be +# Private key used encrypt the traffic between headscale +# and Tailscale clients. +# The private key file which will be # autogenerated if it's missing private_key_path: /var/lib/headscale/private.key +# DERP is a relay system that Tailscale uses when a direct +# connection cannot be established. +# https://tailscale.com/blog/how-tailscale-works/#encrypted-tcp-relays-derp +# +# headscale needs a list of DERP servers that can be presented +# to the clients. derp: # List of externally available DERP maps encoded in JSON urls: - https://controlplane.tailscale.com/derpmap/default # Locally available DERP map files encoded in YAML + # + # This option is mostly interesting for people hosting + # their own DERP servers: + # https://tailscale.com/kb/1118/custom-derp-servers/ + # # paths: # - /etc/headscale/derp-example.yaml @@ -24,11 +41,13 @@ derp: # will be set up. auto_update_enabled: true - # How often should we check for updates? + # How often should we check for DERP updates? update_frequency: 24h -# Disables the automatic check for updates on startup +# Disables the automatic check for headscale updates on startup disable_check_updates: false + +# Time before an inactive ephemeral node is deleted? ephemeral_node_inactivity_timeout: 30m # SQLite config @@ -43,35 +62,87 @@ db_path: /var/lib/headscale/db.sqlite # db_user: foo # db_pass: bar +### TLS configuration +# +## Let's encrypt / ACME +# +# headscale supports automatically requesting and setting up +# TLS for a domain with Let's Encrypt. +# +# URL to ACME directory acme_url: https://acme-v02.api.letsencrypt.org/directory + +# Email to register with ACME provider acme_email: "" +# Domain name to request a TLS certificate for: tls_letsencrypt_hostname: "" -tls_letsencrypt_listen: ":http" -tls_letsencrypt_cache_dir: /var/lib/headscale/cache -tls_letsencrypt_challenge_type: HTTP-01 +# Path to store certificates and metadata needed by +# letsencrypt +tls_letsencrypt_cache_dir: /var/lib/headscale/cache + +# Type of ACME challenge to use, currently supported types: +# HTTP-01 or TLS_ALPN-01 +# See [docs/tls.md](docs/tls.md) for more information +tls_letsencrypt_challenge_type: HTTP-01 +# When HTTP-01 challenge is chosen, letsencrypt must set up a +# verification endpoint, and it will be listning on: +# :http = port 80 +tls_letsencrypt_listen: ":http" + +## Use already defined certificates: tls_cert_path: "" tls_key_path: "" log_level: info # Path to a file containg ACL policies. +# Recommended path: /etc/headscale/acl.hujson acl_policy_path: "" +## DNS +# +# headscale supports Tailscale's DNS configuration and MagicDNS. +# Please have a look to their KB to better understand the concepts: +# +# - https://tailscale.com/kb/1054/dns/ +# - https://tailscale.com/kb/1081/magicdns/ +# - https://tailscale.com/blog/2021-09-private-dns-with-magicdns/ +# dns_config: - # Upstream DNS servers + # List of DNS servers to expose to clients. nameservers: - 1.1.1.1 + + # Split DNS (see https://tailscale.com/kb/1054/dns/), + # list of search domains and the DNS to query for each one. + # + # restricted_nameservers: + # foo.bar.com: + # - 1.1.1.1 + # darp.headscale.net: + # - 1.1.1.1 + # - 8.8.8.8 + + # Search domains to inject. domains: [] + # Whether to use [MagicDNS](https://tailscale.com/kb/1081/magicdns/). + # Only works if there is at least a nameserver defined. magic_dns: true + + # Defines the base domain to create the hostnames for MagicDNS. + # `base_domain` must be a FQDNs, without the trailing dot. + # The FQDN of the hosts will be + # `hostname.namespace.base_domain` (e.g., _myhost.mynamespace.example.com_). base_domain: example.com # Unix socket used for the CLI to connect without authentication # Note: for local development, you probably want to change this to: # unix_socket: ./headscale.sock unix_socket: /var/run/headscale.sock +# # headscale supports experimental OpenID connect support, # it is still being tested and might have some bugs, please # help us test it. From 86f36f9a43ba13ac75a55243c397f687aa939060 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Sun, 2 Jan 2022 19:39:03 +0000 Subject: [PATCH 260/300] Lowercase markdown docs --- docs/{Configuration.md => configuration.md} | 0 docs/{Glossary.md => glossary.md} | 0 docs/{TLS.md => tls.md} | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename docs/{Configuration.md => configuration.md} (100%) rename docs/{Glossary.md => glossary.md} (100%) rename docs/{TLS.md => tls.md} (100%) diff --git a/docs/Configuration.md b/docs/configuration.md similarity index 100% rename from docs/Configuration.md rename to docs/configuration.md diff --git a/docs/Glossary.md b/docs/glossary.md similarity index 100% rename from docs/Glossary.md rename to docs/glossary.md diff --git a/docs/TLS.md b/docs/tls.md similarity index 100% rename from docs/TLS.md rename to docs/tls.md From 11c86acbe3057c346c1847646d9d3345f6ba1439 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Sun, 2 Jan 2022 19:39:51 +0000 Subject: [PATCH 261/300] update case in readme --- docs/README.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/docs/README.md b/docs/README.md index 66bde260..f8a1e836 100644 --- a/docs/README.md +++ b/docs/README.md @@ -10,13 +10,12 @@ please ask on [Discord](https://discord.gg/XcQxk2VHjx) instead of opening an Iss ### How-to - [Running headscale on Linux](running-headscale-linux.md) -- [DNS](DNS.md) -- [TLS](TLS.md) ### References -- [Configuration](Configuration.md) -- [Glossary](Glossary.md) +- [Configuration](configuration.md) +- [TLS](tls.md) +- [Glossary](glossary.md) ## Community documentation From 5df100539c54fe85ad93413d019083d421f1f681 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Sun, 2 Jan 2022 19:42:35 +0000 Subject: [PATCH 262/300] Remove outdated configuration page in favour of config-example --- config-example.yaml | 6 ++++ docs/README.md | 16 +++++++++- docs/configuration.md | 74 ------------------------------------------- 3 files changed, 21 insertions(+), 75 deletions(-) delete mode 100644 docs/configuration.md diff --git a/config-example.yaml b/config-example.yaml index e26f06e8..80af11a6 100644 --- a/config-example.yaml +++ b/config-example.yaml @@ -1,4 +1,10 @@ --- +# headscale will look for a configuration file named `config.yaml` (or `config.json`) in the following order: +# +# - `/etc/headscale` +# - `~/.headscale` +# - current working directory + # The url clients will connect to. # Typically this will be a domain like: # diff --git a/docs/README.md b/docs/README.md index f8a1e836..aff549b5 100644 --- a/docs/README.md +++ b/docs/README.md @@ -13,7 +13,6 @@ please ask on [Discord](https://discord.gg/XcQxk2VHjx) instead of opening an Iss ### References -- [Configuration](configuration.md) - [TLS](tls.md) - [Glossary](glossary.md) @@ -25,3 +24,18 @@ written by community members. It is _not_ verified by `headscale` developers. **It might be outdated and it might miss necessary steps**. - [Running headscale in container](running-headscale-container.md) + +## Misc + +### Policy ACLs + +Headscale implements the same policy ACLs as Tailscale.com, adapted to the self-hosted environment. + +For instance, instead of referring to users when defining groups you must +use namespaces (which are the equivalent to user/logins in Tailscale.com). + +Please check https://tailscale.com/kb/1018/acls/, and `./tests/acls/` in this repo for working examples. + +### Apple devices + +An endpoint with information on how to connect your Apple devices (currently macOS only) is available at `/apple` on your running instance. diff --git a/docs/configuration.md b/docs/configuration.md deleted file mode 100644 index 55ab56e5..00000000 --- a/docs/configuration.md +++ /dev/null @@ -1,74 +0,0 @@ -# Configuration reference - -Headscale will look for a configuration file named `config.yaml` (or `config.json`) in the following order: - -- `/etc/headscale` -- `~/.headscale` -- current working directory - -```yaml -server_url: http://headscale.mydomain.net -listen_addr: 0.0.0.0:8080 -ip_prefix: 100.64.0.0/10 -disable_check_updates: false -``` - -`server_url` is the external URL via which Headscale is reachable. `listen_addr` is the IP address and port the Headscale program should listen on. `ip_prefix` is the IP prefix (range) in which IP addresses for nodes will be allocated (default 100.64.0.0/10, e.g., 192.168.4.0/24, 10.0.0.0/8). `disable_check_updates` disables the automatic check for updates. - -```yaml -log_level: debug -``` - -`log_level` can be used to set the Log level for Headscale, it defaults to `debug`, and the available levels are: `trace`, `debug`, `info`, `warn` and `error`. - -```yaml -derp_map_path: derp.yaml -``` - -`derp_map_path` is the path to the [DERP](https://pkg.go.dev/tailscale.com/derp) map file. If the path is relative, it will be interpreted as relative to the directory the configuration file was read from. - -```yaml -ephemeral_node_inactivity_timeout: "30m" -``` - -`ephemeral_node_inactivity_timeout` is the timeout after which inactive ephemeral node records will be deleted from the database. The default is 30 minutes. This value must be higher than 65 seconds (the keepalive timeout for the HTTP long poll is 60 seconds, plus a few seconds to avoid race conditions). - -PostgresSQL - -```yaml -db_host: localhost -db_port: 5432 -db_name: headscale -db_user: foo -db_pass: bar -``` - -SQLite - -```yaml -db_type: sqlite3 -db_path: db.sqlite -``` - -The fields starting with `db_` are used for the DB connection information. - -### TLS configuration - -Please check [`TLS.md`](TLS.md). - -### DNS configuration - -Please refer to [`DNS.md`](DNS.md). - -### Policy ACLs - -Headscale implements the same policy ACLs as Tailscale.com, adapted to the self-hosted environment. - -For instance, instead of referring to users when defining groups you must -use namespaces (which are the equivalent to user/logins in Tailscale.com). - -Please check https://tailscale.com/kb/1018/acls/, and `./tests/acls/` in this repo for working examples. - -### Apple devices - -An endpoint with information on how to connect your Apple devices (currently macOS only) is available at `/apple` on your running instance. From 1d01103b67bbf3d67f42fad9d7b5015443479510 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Sun, 2 Jan 2022 19:43:06 +0000 Subject: [PATCH 263/300] Link to example config from docs --- docs/README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/README.md b/docs/README.md index aff549b5..e2ae456c 100644 --- a/docs/README.md +++ b/docs/README.md @@ -13,8 +13,9 @@ please ask on [Discord](https://discord.gg/XcQxk2VHjx) instead of opening an Iss ### References -- [TLS](tls.md) +- [Configuration](../config-example.yaml) - [Glossary](glossary.md) +- [TLS](tls.md) ## Community documentation From 8da029bd14fb8f5cc4d5277ead8da988f2aef6ff Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Sun, 2 Jan 2022 19:48:57 +0000 Subject: [PATCH 264/300] Add missing links --- docs/running-headscale-container.md | 8 ++++---- docs/running-headscale-linux.md | 14 +++++++------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/docs/running-headscale-container.md b/docs/running-headscale-container.md index c1f4099d..8b15c06d 100644 --- a/docs/running-headscale-container.md +++ b/docs/running-headscale-container.md @@ -6,12 +6,12 @@ it is up to date, or working. ## Goal This documentation has the goal of showing a user how-to set up and run `headscale` in a container. -[Docker]() is used as the reference container implementation, but there is no reason that it should -not work with alternatives like [Podman](). +[Docker](https://www.docker.com) is used as the reference container implementation, but there is no reason that it should +not work with alternatives like [Podman](https://podman.io). ## Configure and run `headscale` -1. Prepare a direction to hold `headscale` configuration and the [SQlite]() database: +1. Prepare a direction to hold `headscale` configuration and the [SQLite](https://www.sqlite.org/) database: ```shell mkdir config @@ -68,7 +68,7 @@ Verify `headscale` is available: curl http://127.0.0.1:8080/metrics ``` -1. Create a namespace ([tailnet]()): +1. Create a namespace ([tailnet](https://tailscale.com/kb/1136/tailnet/)): ```shell docker exec headscale -- headscale namespaces create myfirstnamespace diff --git a/docs/running-headscale-linux.md b/docs/running-headscale-linux.md index 0f0d570a..5eb2dbdb 100644 --- a/docs/running-headscale-linux.md +++ b/docs/running-headscale-linux.md @@ -3,12 +3,12 @@ ## Goal This documentation has the goal of showing a user how-to set up and run `headscale` on Linux. -In additional to the "get up and running section", there is an optional [SystemD section]() +In additional to the "get up and running section", there is an optional [SystemD section](#running-headscale-in-the-background-with-systemd) describing how to make `headscale` run properly in a server environment. ## Configure and run `headscale` -1. Download the latest [`headscale` binary from GitHub's release page](): +1. Download the latest [`headscale` binary from GitHub's release page](https://github.com/juanfont/headscale/releases): ```shell wget --output-document=/usr/local/bin/headscale \ @@ -21,7 +21,7 @@ wget --output-document=/usr/local/bin/headscale \ chmod +x /usr/local/bin/headscale ``` -1. Prepare a direction to hold `headscale` configuration and the [SQlite]() database: +1. Prepare a direction to hold `headscale` configuration and the [SQLite](https://www.sqlite.org/) database: ```shell # Directory for configuration @@ -56,9 +56,9 @@ from the [headscale repository](../) This command will start `headscale` in the current terminal session. To continue the tutorial, open a new terminal and let it run in the background. -Alternatively use terminal emulators like [tmux]() or [screen](). +Alternatively use terminal emulators like [tmux](https://github.com/tmux/tmux) or [screen](https://www.gnu.org/software/screen/). -To run `headscale` in the background, please follow the steps in the [SystemD section]() before continuing. +To run `headscale` in the background, please follow the steps in the [SystemD section](#running-headscale-in-the-background-with-systemd) before continuing. 1. Verify `headscale` is running: @@ -68,7 +68,7 @@ Verify `headscale` is available: curl http://127.0.0.1:8080/metrics ``` -1. Create a namespace ([tailnet]()): +1. Create a namespace ([tailnet](https://tailscale.com/kb/1136/tailnet/)): ```shell headscale namespaces create myfirstnamespace @@ -104,7 +104,7 @@ tailscale up --login-server --authkey ## Running `headscale` in the background with SystemD -In this section it will be demonstrated how to run `headscale` as a service in the background with [SystemD](). +In this section it will be demonstrated how to run `headscale` as a service in the background with [SystemD](https://www.freedesktop.org/wiki/Software/systemd/). This should work on most modern Linux distributions. 1. Create a SystemD service configuration at `/etc/systemd/system/headscale.service` containing: From 6b7c74133d383ef56180649ca9ba4e312e804871 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Sun, 2 Jan 2022 19:53:49 +0000 Subject: [PATCH 265/300] Use markdown numbering so github gets it --- docs/running-headscale-container.md | 10 +++++----- docs/running-headscale-linux.md | 22 +++++++++++----------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/docs/running-headscale-container.md b/docs/running-headscale-container.md index 8b15c06d..fe7298a4 100644 --- a/docs/running-headscale-container.md +++ b/docs/running-headscale-container.md @@ -17,13 +17,13 @@ not work with alternatives like [Podman](https://podman.io). mkdir config ``` -1. Create an empty SQlite datebase: +2. Create an empty SQlite datebase: ```shell touch config/db.sqlite ``` -1. Create a `headscale` configuration: +3. Create a `headscale` configuration: ```shell touch config/config.yaml @@ -31,7 +31,7 @@ touch config/config.yaml It is strongly recommended to copy the [example configuration](../config.yaml) from the [headscale repository](../) -1. Start the headscale server: +4. Start the headscale server: ```shell docker run \ @@ -48,7 +48,7 @@ docker run \ This command will mount `config/` under `/etc/headscale`, forward port 8080 out of the container so the `headscale` instance becomes available and then detach so headscale runs in the background. -1. Verify `headscale` is running: +5. Verify `headscale` is running: Follow the container logs: @@ -68,7 +68,7 @@ Verify `headscale` is available: curl http://127.0.0.1:8080/metrics ``` -1. Create a namespace ([tailnet](https://tailscale.com/kb/1136/tailnet/)): +6. Create a namespace ([tailnet](https://tailscale.com/kb/1136/tailnet/)): ```shell docker exec headscale -- headscale namespaces create myfirstnamespace diff --git a/docs/running-headscale-linux.md b/docs/running-headscale-linux.md index 5eb2dbdb..59264653 100644 --- a/docs/running-headscale-linux.md +++ b/docs/running-headscale-linux.md @@ -15,13 +15,13 @@ wget --output-document=/usr/local/bin/headscale \ https://github.com/juanfont/headscale/releases/download/v/headscale__linux_ ``` -1. Make `headscale` executable: +2. Make `headscale` executable: ```shell chmod +x /usr/local/bin/headscale ``` -1. Prepare a direction to hold `headscale` configuration and the [SQLite](https://www.sqlite.org/) database: +3. Prepare a direction to hold `headscale` configuration and the [SQLite](https://www.sqlite.org/) database: ```shell # Directory for configuration @@ -32,13 +32,13 @@ mkdir -p /etc/headscale mkdir -p /var/lib/headscale ``` -1. Create an empty SQlite datebase: +4. Create an empty SQlite datebase: ```shell touch /var/lib/headscale/db.sqlite ``` -1. Create a `headscale` configuration: +5. Create a `headscale` configuration: ```shell touch /etc/headscale/config.yaml @@ -47,7 +47,7 @@ touch /etc/headscale/config.yaml It is strongly recommended to copy and modifiy the [example configuration](../config.yaml) from the [headscale repository](../) -1. Start the headscale server: +6. Start the headscale server: ```shell headscale serve @@ -60,7 +60,7 @@ Alternatively use terminal emulators like [tmux](https://github.com/tmux/tmux) o To run `headscale` in the background, please follow the steps in the [SystemD section](#running-headscale-in-the-background-with-systemd) before continuing. -1. Verify `headscale` is running: +7. Verify `headscale` is running: Verify `headscale` is available: @@ -68,7 +68,7 @@ Verify `headscale` is available: curl http://127.0.0.1:8080/metrics ``` -1. Create a namespace ([tailnet](https://tailscale.com/kb/1136/tailnet/)): +8. Create a namespace ([tailnet](https://tailscale.com/kb/1136/tailnet/)): ```shell headscale namespaces create myfirstnamespace @@ -136,26 +136,26 @@ RuntimeDirectory=headscale WantedBy=multi-user.target ``` -1. In `/etc/headscale/config.yaml`, override the default `headscale` unix socket with a SystemD friendly path: +2. In `/etc/headscale/config.yaml`, override the default `headscale` unix socket with a SystemD friendly path: ```yaml unix_socket: /var/run/headscale/headscale.sock ``` -1. Reload SystemD to load the new configuration file: +3. Reload SystemD to load the new configuration file: ```shell systemctl daemon-reload ``` -1. Enable and start the new `headscale` service: +4. Enable and start the new `headscale` service: ```shell systemctl enable headscale systemctl start headscale ``` -1. Verify the headscale service: +5. Verify the headscale service: ```shell systemctl status headscale From 4edc96d14dc29c415d8a5c1fde4d078ad7db4bd2 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Sun, 2 Jan 2022 19:54:37 +0000 Subject: [PATCH 266/300] Make strongly strong --- docs/running-headscale-container.md | 2 +- docs/running-headscale-linux.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/running-headscale-container.md b/docs/running-headscale-container.md index fe7298a4..9c658bf7 100644 --- a/docs/running-headscale-container.md +++ b/docs/running-headscale-container.md @@ -29,7 +29,7 @@ touch config/db.sqlite touch config/config.yaml ``` -It is strongly recommended to copy the [example configuration](../config.yaml) from the [headscale repository](../) +It is **strongly recommended** to copy the [example configuration](../config.yaml) from the [headscale repository](../) 4. Start the headscale server: diff --git a/docs/running-headscale-linux.md b/docs/running-headscale-linux.md index 59264653..82bd36df 100644 --- a/docs/running-headscale-linux.md +++ b/docs/running-headscale-linux.md @@ -44,7 +44,7 @@ touch /var/lib/headscale/db.sqlite touch /etc/headscale/config.yaml ``` -It is strongly recommended to copy and modifiy the [example configuration](../config.yaml) +It is **strongly recommended** to copy and modifiy the [example configuration](../config.yaml) from the [headscale repository](../) 6. Start the headscale server: From 81c60939c93e775da4197b704bca692db10cd46d Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Sun, 2 Jan 2022 19:55:38 +0000 Subject: [PATCH 267/300] Add vertical line for breathing --- docs/running-headscale-linux.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/running-headscale-linux.md b/docs/running-headscale-linux.md index 82bd36df..6b3d0ecb 100644 --- a/docs/running-headscale-linux.md +++ b/docs/running-headscale-linux.md @@ -55,6 +55,8 @@ from the [headscale repository](../) This command will start `headscale` in the current terminal session. +--- + To continue the tutorial, open a new terminal and let it run in the background. Alternatively use terminal emulators like [tmux](https://github.com/tmux/tmux) or [screen](https://www.gnu.org/software/screen/). From 25b5eb8d7fd94ec1a7342b8e022af29a1f7a1e0c Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Sun, 2 Jan 2022 23:17:42 +0000 Subject: [PATCH 268/300] Update tests to aline with new config example --- cmd/headscale/headscale_test.go | 3 +-- config-example.yaml | 1 + 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd/headscale/headscale_test.go b/cmd/headscale/headscale_test.go index 1166d489..0b56a073 100644 --- a/cmd/headscale/headscale_test.go +++ b/cmd/headscale/headscale_test.go @@ -54,9 +54,8 @@ func (*Suite) TestConfigLoading(c *check.C) { // Test that config file was interpreted correctly c.Assert(viper.GetString("server_url"), check.Equals, "http://127.0.0.1:8080") c.Assert(viper.GetString("listen_addr"), check.Equals, "0.0.0.0:8080") - c.Assert(viper.GetStringSlice("derp.paths")[0], check.Equals, "derp-example.yaml") c.Assert(viper.GetString("db_type"), check.Equals, "sqlite3") - c.Assert(viper.GetString("db_path"), check.Equals, "db.sqlite") + c.Assert(viper.GetString("db_path"), check.Equals, "/var/lib/headscale/db.sqlite") c.Assert(viper.GetString("tls_letsencrypt_hostname"), check.Equals, "") c.Assert(viper.GetString("tls_letsencrypt_listen"), check.Equals, ":http") c.Assert(viper.GetString("tls_letsencrypt_challenge_type"), check.Equals, "HTTP-01") diff --git a/config-example.yaml b/config-example.yaml index 80af11a6..3301669d 100644 --- a/config-example.yaml +++ b/config-example.yaml @@ -41,6 +41,7 @@ derp: # # paths: # - /etc/headscale/derp-example.yaml + paths: [] # If enabled, a worker will be set up to periodically # refresh the given sources and update the derpmap From d9f52efe70400c325f1c60c65640661e81200990 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Sun, 2 Jan 2022 23:17:48 +0000 Subject: [PATCH 269/300] Fix typo --- docs/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/README.md b/docs/README.md index e2ae456c..f42d67de 100644 --- a/docs/README.md +++ b/docs/README.md @@ -24,7 +24,7 @@ written by community members. It is _not_ verified by `headscale` developers. **It might be outdated and it might miss necessary steps**. -- [Running headscale in container](running-headscale-container.md) +- [Running headscale in a container](running-headscale-container.md) ## Misc From d971cf1295c3a000e7525afe5c3c98cd6875a261 Mon Sep 17 00:00:00 2001 From: JJGadgets <5709019+JJGadgets@users.noreply.github.com> Date: Thu, 6 Jan 2022 14:10:28 +0800 Subject: [PATCH 270/300] Improve Docker docs - Fix URLs referring to files in this repository - Better explain that we are creating the headscale directory and running the commands on the host Docker node - Place instructions to download example config file to use as config file, as recommended steps. --- docs/running-headscale-container.md | 31 ++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/docs/running-headscale-container.md b/docs/running-headscale-container.md index 9c658bf7..fc6fb38b 100644 --- a/docs/running-headscale-container.md +++ b/docs/running-headscale-container.md @@ -7,31 +7,44 @@ it is up to date, or working. This documentation has the goal of showing a user how-to set up and run `headscale` in a container. [Docker](https://www.docker.com) is used as the reference container implementation, but there is no reason that it should -not work with alternatives like [Podman](https://podman.io). +not work with alternatives like [Podman](https://podman.io). The Docker image can be found on Docker Hub [here](https://hub.docker.com/r/headscale/headscale). ## Configure and run `headscale` -1. Prepare a direction to hold `headscale` configuration and the [SQLite](https://www.sqlite.org/) database: +1. Prepare a directory on the host Docker node in your directory of choice, used to hold `headscale` configuration and the [SQLite](https://www.sqlite.org/) database: ```shell -mkdir config +mkdir ./headscale && cd ./headscale +mkdir ./config ``` -2. Create an empty SQlite datebase: +2. Create an empty SQlite datebase in the headscale directory: ```shell -touch config/db.sqlite +touch ./config/db.sqlite ``` -3. Create a `headscale` configuration: +3. **(Strongly Recommended)** Download a copy of the [example configuration](../config-example.yaml) from the [headscale repository](https://github.com/juanfont/headscale/). + +Using wget: +```shell +wget -O ./config/config.yaml https://raw.githubusercontent.com/juanfont/headscale/main/config-example.yaml +``` + +Using curl: +```shell +curl https://raw.githubusercontent.com/juanfont/headscale/main/config-example.yaml -o ./config/config.yaml +``` + +**(Advanced)** If you would like to hand craft a config file **instead** of downloading the example config file, create a blank `headscale` configuration in the headscale directory to edit: ```shell -touch config/config.yaml +touch ./config/config.yaml ``` -It is **strongly recommended** to copy the [example configuration](../config.yaml) from the [headscale repository](../) +Modify the config file to your preferences before launching Docker container. -4. Start the headscale server: +4. Start the headscale server while working in the host headscale directory: ```shell docker run \ From 897fa558b07a5a12249e3f3eb02d8b01adff5b7d Mon Sep 17 00:00:00 2001 From: JJGadgets Date: Thu, 6 Jan 2022 17:25:07 +0800 Subject: [PATCH 271/300] prettier: Docker docs --- docs/running-headscale-container.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/running-headscale-container.md b/docs/running-headscale-container.md index fc6fb38b..d39f4d49 100644 --- a/docs/running-headscale-container.md +++ b/docs/running-headscale-container.md @@ -27,11 +27,13 @@ touch ./config/db.sqlite 3. **(Strongly Recommended)** Download a copy of the [example configuration](../config-example.yaml) from the [headscale repository](https://github.com/juanfont/headscale/). Using wget: + ```shell wget -O ./config/config.yaml https://raw.githubusercontent.com/juanfont/headscale/main/config-example.yaml ``` Using curl: + ```shell curl https://raw.githubusercontent.com/juanfont/headscale/main/config-example.yaml -o ./config/config.yaml ``` From cec236ce243a5910c0091cd33ee26647a90338a1 Mon Sep 17 00:00:00 2001 From: Pierre Carru Date: Mon, 10 Jan 2022 14:44:11 +0100 Subject: [PATCH 272/300] Fix example config link Everything is in the title :p --- docs/running-headscale-linux.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/running-headscale-linux.md b/docs/running-headscale-linux.md index 6b3d0ecb..d53b72f8 100644 --- a/docs/running-headscale-linux.md +++ b/docs/running-headscale-linux.md @@ -44,7 +44,7 @@ touch /var/lib/headscale/db.sqlite touch /etc/headscale/config.yaml ``` -It is **strongly recommended** to copy and modifiy the [example configuration](../config.yaml) +It is **strongly recommended** to copy and modifiy the [example configuration](../config-example.yaml) from the [headscale repository](../) 6. Start the headscale server: From e9cc60e49c218dc4b2878075bba571bd86d9e5c5 Mon Sep 17 00:00:00 2001 From: Juan Font Alonso Date: Tue, 11 Jan 2022 15:45:13 +0100 Subject: [PATCH 273/300] Updated changelog for 0.12.2 --- CHANGELOG.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4ae02d67..48d55deb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,16 @@ **TBD (TBD):** +**0.12.2 (2022-01-11):** + +Happy New Year! + +**Changes**: + +- Fix Docker release [#258](https://github.com/juanfont/headscale/pull/258) +- Rewrite main docs [#262](https://github.com/juanfont/headscale/pull/262) +- Improve Docker docs [#263](https://github.com/juanfont/headscale/pull/263) + **0.12.1 (2021-12-24):** (We are skipping 0.12.0 to correct a mishap done weeks ago with the version tagging) From 1b6bad0b631c781d5ee67800bb58909fc2ce06f9 Mon Sep 17 00:00:00 2001 From: Artem Klevtsov Date: Wed, 12 Jan 2022 19:29:59 +0700 Subject: [PATCH 274/300] Add docker alpine image --- .github/workflows/release.yml | 64 +++++++++++++++++++++++++++++++++++ Dockerfile.alpine | 22 ++++++++++++ 2 files changed, 86 insertions(+) create mode 100644 Dockerfile.alpine diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 71dab053..c9a40bc0 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -157,3 +157,67 @@ jobs: run: | rm -rf /tmp/.buildx-cache-debug mv /tmp/.buildx-cache-debug-new /tmp/.buildx-cache-debug + + docker-alpine-release: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + with: + fetch-depth: 0 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v1 + - name: Set up QEMU for multiple platforms + uses: docker/setup-qemu-action@master + with: + platforms: arm64,amd64 + - name: Cache Docker layers + uses: actions/cache@v2 + with: + path: /tmp/.buildx-cache-alpine + key: ${{ runner.os }}-buildx-alpine-${{ github.sha }} + restore-keys: | + ${{ runner.os }}-buildx-alpine- + - name: Docker meta + id: meta-alpine + uses: docker/metadata-action@v3 + with: + # list of Docker images to use as base name for tags + images: | + ${{ secrets.DOCKERHUB_USERNAME }}/headscale + ghcr.io/${{ github.repository_owner }}/headscale + flavor: | + latest=false + tags: | + type=semver,pattern={{version}}-alpine + type=semver,pattern={{major}}.{{minor}}-alpine + type=semver,pattern={{major}}-alpine + type=raw,value=latest-alpine + type=sha,suffix=-alpine + - name: Login to DockerHub + uses: docker/login-action@v1 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + - name: Login to GHCR + uses: docker/login-action@v1 + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + - name: Build and push + id: docker_build + uses: docker/build-push-action@v2 + with: + push: true + context: . + file: Dockerfile.alpine + tags: ${{ steps.meta-alpine.outputs.tags }} + labels: ${{ steps.meta-alpine.outputs.labels }} + platforms: linux/amd64,linux/arm64 + cache-from: type=local,src=/tmp/.buildx-cache-alpine + cache-to: type=local,dest=/tmp/.buildx-cache-alpine-new + - name: Prepare cache for next build + run: | + rm -rf /tmp/.buildx-cache-alpine + mv /tmp/.buildx-cache-alpine-new /tmp/.buildx-cache-alpine diff --git a/Dockerfile.alpine b/Dockerfile.alpine new file mode 100644 index 00000000..7d90e1ec --- /dev/null +++ b/Dockerfile.alpine @@ -0,0 +1,22 @@ +# Builder image +FROM golang:1.17.1-alpine AS build +ENV GOPATH /go +WORKDIR /go/src/headscale + +COPY go.mod go.sum /go/src/headscale/ +RUN apk add gcc musl-dev +RUN go mod download + +COPY . . + +RUN go install -a -ldflags="-extldflags=-static" -tags netgo,sqlite_omit_load_extension ./cmd/headscale +RUN test -e /go/bin/headscale + +# Production image +FROM alpine:latest + +COPY --from=build /go/bin/headscale /bin/headscale +ENV TZ UTC + +EXPOSE 8080/tcp +CMD ["headscale"] From 4660b265d963dfee5942bf53fe86aca09d8deea1 Mon Sep 17 00:00:00 2001 From: Juan Font Alonso Date: Wed, 12 Jan 2022 15:17:55 +0100 Subject: [PATCH 275/300] Minor security updates in go.mod --- go.mod | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/go.mod b/go.mod index 2d9e8c61..67b23608 100644 --- a/go.mod +++ b/go.mod @@ -103,8 +103,8 @@ require ( github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect - github.com/opencontainers/image-spec v1.0.1 // indirect - github.com/opencontainers/runc v1.0.2 // indirect + github.com/opencontainers/image-spec v1.0.2 // indirect + github.com/opencontainers/runc v1.0.3 // indirect github.com/pelletier/go-toml v1.9.3 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect From 163ecb2a6b578bc540fac9f11e97fee891fe93a4 Mon Sep 17 00:00:00 2001 From: Juan Font Alonso Date: Wed, 12 Jan 2022 15:22:16 +0100 Subject: [PATCH 276/300] go.sum updated --- go.sum | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/go.sum b/go.sum index 8d4b4587..6dcc0a85 100644 --- a/go.sum +++ b/go.sum @@ -783,11 +783,12 @@ github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWEr github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= -github.com/opencontainers/image-spec v1.0.1 h1:JMemWkRwHx4Zj+fVxWoMCFm/8sYGGrUVojFA6h/TRcI= github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= +github.com/opencontainers/image-spec v1.0.2 h1:9yCKha/T5XdGtO0q9Q9a6T5NUCsTn/DrBg0D7ufOcFM= +github.com/opencontainers/image-spec v1.0.2/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= github.com/opencontainers/runc v1.0.0-rc9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= -github.com/opencontainers/runc v1.0.2 h1:opHZMaswlyxz1OuGpBE53Dwe4/xF7EZTY0A2L/FpCOg= -github.com/opencontainers/runc v1.0.2/go.mod h1:aTaHFFwQXuA71CiyxOdFFIorAoemI04suvGRQFzWTD0= +github.com/opencontainers/runc v1.0.3 h1:1hbqejyQWCJBvtKAfdO0b1FmaEf2z/bxnjqbARass5k= +github.com/opencontainers/runc v1.0.3/go.mod h1:aTaHFFwQXuA71CiyxOdFFIorAoemI04suvGRQFzWTD0= github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/selinux v1.8.2/go.mod h1:MUIHuUEvKB1wtJjQdOyYRgOnLD2xAPP8dBsCoU0KuF8= github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis= From 19effe7034d9279e46c5fc708dcd120335a66a34 Mon Sep 17 00:00:00 2001 From: Juan Font Alonso Date: Thu, 13 Jan 2022 12:42:56 +0100 Subject: [PATCH 277/300] Updated changelog for 0.12.3 --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 48d55deb..38904b0a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,13 @@ **TBD (TBD):** +**0.12.3 (2022-01-13):** + +**Changes**: + +- Added Alpine container [#270](https://github.com/juanfont/headscale/pull/270) +- Minor updates in dependencies [#271](https://github.com/juanfont/headscale/pull/271) + **0.12.2 (2022-01-11):** Happy New Year! From 2c057c2d89cefbccbe023a67bf2e7193860e4bdc Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Thu, 13 Jan 2022 19:16:12 +0000 Subject: [PATCH 278/300] Update integration_test.go --- integration_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integration_test.go b/integration_test.go index 7840adc3..fc71ed15 100644 --- a/integration_test.go +++ b/integration_test.go @@ -28,7 +28,7 @@ import ( "tailscale.com/ipn/ipnstate" ) -var tailscaleVersions = []string{"1.18.1", "1.16.2", "1.14.3", "1.12.3"} +var tailscaleVersions = []string{"1.20.0", "1.18.2", "1.16.2", "1.14.3", "1.12.3"} type TestNamespace struct { count int From 1d68509463124138f04ea736dd3aa75c1e47f574 Mon Sep 17 00:00:00 2001 From: Stefan Majer Date: Fri, 14 Jan 2022 09:19:16 +0100 Subject: [PATCH 279/300] Strip binary, update to go-1.17.6 --- Dockerfile | 3 ++- Dockerfile.alpine | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 0d344268..d5fe3421 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ # Builder image -FROM golang:1.17.1-bullseye AS build +FROM golang:1.17.6-bullseye AS build ENV GOPATH /go WORKDIR /go/src/headscale @@ -9,6 +9,7 @@ RUN go mod download COPY . . RUN go install -a -ldflags="-extldflags=-static" -tags netgo,sqlite_omit_load_extension ./cmd/headscale +RUN strip /go/bin/headscale RUN test -e /go/bin/headscale # Production image diff --git a/Dockerfile.alpine b/Dockerfile.alpine index 7d90e1ec..8185dbe4 100644 --- a/Dockerfile.alpine +++ b/Dockerfile.alpine @@ -1,5 +1,5 @@ # Builder image -FROM golang:1.17.1-alpine AS build +FROM golang:1.17.6-alpine AS build ENV GOPATH /go WORKDIR /go/src/headscale @@ -10,6 +10,7 @@ RUN go mod download COPY . . RUN go install -a -ldflags="-extldflags=-static" -tags netgo,sqlite_omit_load_extension ./cmd/headscale +RUN strip /go/bin/headscale RUN test -e /go/bin/headscale # Production image From febbb6006f040b26bfe30db31ed4dee7ea362540 Mon Sep 17 00:00:00 2001 From: Stefan Majer Date: Fri, 14 Jan 2022 12:59:53 +0100 Subject: [PATCH 280/300] use most recent go 1.17 for tests --- .github/workflows/build.yml | 2 +- .github/workflows/test-integration.yml | 2 +- .github/workflows/test.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 963663a7..589d8c58 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -18,7 +18,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v2 with: - go-version: "1.17.3" + go-version: "1.17" - name: Install dependencies run: | diff --git a/.github/workflows/test-integration.yml b/.github/workflows/test-integration.yml index abf46d32..d4179ea2 100644 --- a/.github/workflows/test-integration.yml +++ b/.github/workflows/test-integration.yml @@ -17,7 +17,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v2 with: - go-version: "1.17.3" + go-version: "1.17" - name: Run Integration tests run: go test -tags integration -timeout 30m diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 4540482c..651063fc 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -17,7 +17,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v2 with: - go-version: "1.17.3" # The Go version to download (if necessary) and use. + go-version: "1.17" # The Go version to download (if necessary) and use. # Install all the dependencies - name: Install dependencies From 86f3f26a18f2aaf4de6b73047be1f2cb51b81c4d Mon Sep 17 00:00:00 2001 From: Jim Tittsler Date: Sat, 15 Jan 2022 16:32:52 +0900 Subject: [PATCH 281/300] Fix typos --- README.md | 6 +++--- docs/running-headscale-linux.md | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 07da4aab..9a599d3d 100644 --- a/README.md +++ b/README.md @@ -65,7 +65,7 @@ To contribute to Headscale you would need the lastest version of [Go](https://go ### Code style -To ensure we have some consistency with a growing number of contributes, this project has adopted linting and style/formatting rules: +To ensure we have some consistency with a growing number of contributions, this project has adopted linting and style/formatting rules: The **Go** code is linted with [`golangci-lint`](https://golangci-lint.run) and formatted with [`golines`](https://github.com/segmentio/golines) (width 88) and @@ -76,7 +76,7 @@ run `make lint` and `make fmt` before committing any code. The **Proto** code is linted with [`buf`](https://docs.buf.build/lint/overview) and formatted with [`clang-format`](https://clang.llvm.org/docs/ClangFormat.html). -The **rest** (markdown, yaml, etc) is formatted with [`prettier`](https://prettier.io). +The **rest** (Markdown, YAML, etc) is formatted with [`prettier`](https://prettier.io). Check out the `.golangci.yaml` and `Makefile` to see the specific configuration. @@ -92,7 +92,7 @@ make install-protobuf-plugins ### Testing and building -Some parts of the project requires the generation of Go code from Protobuf (if changes is made in `proto/`) and it must be (re-)generated with: +Some parts of the project require the generation of Go code from Protobuf (if changes are made in `proto/`) and it must be (re-)generated with: ```shell make generate diff --git a/docs/running-headscale-linux.md b/docs/running-headscale-linux.md index d53b72f8..7a62fcc6 100644 --- a/docs/running-headscale-linux.md +++ b/docs/running-headscale-linux.md @@ -21,7 +21,7 @@ wget --output-document=/usr/local/bin/headscale \ chmod +x /usr/local/bin/headscale ``` -3. Prepare a direction to hold `headscale` configuration and the [SQLite](https://www.sqlite.org/) database: +3. Prepare a directory to hold `headscale` configuration and the [SQLite](https://www.sqlite.org/) database: ```shell # Directory for configuration @@ -32,7 +32,7 @@ mkdir -p /etc/headscale mkdir -p /var/lib/headscale ``` -4. Create an empty SQlite datebase: +4. Create an empty SQLite database: ```shell touch /var/lib/headscale/db.sqlite @@ -106,7 +106,7 @@ tailscale up --login-server --authkey ## Running `headscale` in the background with SystemD -In this section it will be demonstrated how to run `headscale` as a service in the background with [SystemD](https://www.freedesktop.org/wiki/Software/systemd/). +This section demonstrates how to run `headscale` as a service in the background with [SystemD](https://www.freedesktop.org/wiki/Software/systemd/). This should work on most modern Linux distributions. 1. Create a SystemD service configuration at `/etc/systemd/system/headscale.service` containing: From 67d1dd984f575c3b4b73d96ff7ce5b1899b730d3 Mon Sep 17 00:00:00 2001 From: Ryan Fowler Date: Fri, 21 Jan 2022 21:48:58 -0800 Subject: [PATCH 282/300] Fix missing return in PollNetMapHandler --- poll.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/poll.go b/poll.go index 1d2db944..10389038 100644 --- a/poll.go +++ b/poll.go @@ -74,6 +74,8 @@ func (h *Headscale) PollNetMapHandler(ctx *gin.Context) { Str("handler", "PollNetMap"). Msgf("Failed to fetch machine from the database with Machine key: %s", machineKey.String()) ctx.String(http.StatusInternalServerError, "") + + return } log.Trace(). Str("handler", "PollNetMap"). From f59071ff1c2da7f03cd58b626f2267ab14905352 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Fri, 28 Jan 2022 17:23:01 +0000 Subject: [PATCH 283/300] Trim whitespace from privateKey before parsing --- app.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app.go b/app.go index b9d570c5..3ba384b9 100644 --- a/app.go +++ b/app.go @@ -724,7 +724,8 @@ func readOrCreatePrivateKey(path string) (*key.MachinePrivate, error) { return nil, fmt.Errorf("failed to read private key file: %w", err) } - privateKeyEnsurePrefix := PrivateKeyEnsurePrefix(string(privateKey)) + trimmedPrivateKey := strings.TrimSpace(string(privateKey)) + privateKeyEnsurePrefix := PrivateKeyEnsurePrefix(trimmedPrivateKey) var machineKey key.MachinePrivate if err = machineKey.UnmarshalText([]byte(privateKeyEnsurePrefix)); err != nil { From ab45cd37f8cf9203fcc6c14865d0e33271036ac9 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Fri, 28 Jan 2022 17:40:39 +0000 Subject: [PATCH 284/300] Only golint new problems --- .github/workflows/lint.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index b3c64006..6fb985f7 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -14,6 +14,12 @@ jobs: with: version: latest + # Only block PRs on new problems. + # If this is not enabled, we will end up having PRs + # blocked because new linters has appared and other + # parts of the code is affected. + only-new-issues: true + prettier-lint: runs-on: ubuntu-latest steps: From 126e694f26f763f38090eecc228ee16125618e14 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Fri, 28 Jan 2022 18:08:52 +0000 Subject: [PATCH 285/300] Add generate private-key command This commit adds a command to generate a private key for headscale. Mostly useful for systems were you drive the deployment from another machine and use a secret management system. --- cmd/headscale/cli/generate.go | 41 +++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 cmd/headscale/cli/generate.go diff --git a/cmd/headscale/cli/generate.go b/cmd/headscale/cli/generate.go new file mode 100644 index 00000000..24844146 --- /dev/null +++ b/cmd/headscale/cli/generate.go @@ -0,0 +1,41 @@ +package cli + +import ( + "fmt" + + "github.com/spf13/cobra" + "tailscale.com/types/key" +) + +func init() { + rootCmd.AddCommand(generateCmd) + generateCmd.AddCommand(generatePrivateKeyCmd) +} + +var generateCmd = &cobra.Command{ + Use: "generate", + Short: "Generate commands", +} + +var generatePrivateKeyCmd = &cobra.Command{ + Use: "private-key", + Short: "Generate a private key for the headscale server", + Run: func(cmd *cobra.Command, args []string) { + output, _ := cmd.Flags().GetString("output") + machineKey := key.NewMachine() + + machineKeyStr, err := machineKey.MarshalText() + if err != nil { + ErrorOutput( + err, + fmt.Sprintf("Error getting machine key from flag: %s", err), + output, + ) + } + + SuccessOutput(map[string]string{ + "private_key": string(machineKeyStr), + }, + string(machineKeyStr), output) + }, +} From 726ccc8c1f25cc82fdabce2200ff444b139f0709 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Fri, 28 Jan 2022 18:15:41 +0000 Subject: [PATCH 286/300] Upgrade to latest tailscale --- go.mod | 30 +-- go.sum | 484 +++++++++----------------------------------- integration_test.go | 2 +- 3 files changed, 111 insertions(+), 405 deletions(-) diff --git a/go.mod b/go.mod index 67b23608..8683c324 100644 --- a/go.mod +++ b/go.mod @@ -21,12 +21,12 @@ require ( github.com/rs/zerolog v1.26.0 github.com/soheilhy/cmux v0.1.5 github.com/spf13/cobra v1.2.1 - github.com/spf13/viper v1.8.1 + github.com/spf13/viper v1.9.0 github.com/stretchr/testify v1.7.0 - github.com/tailscale/hujson v0.0.0-20210923003652-c3758b31534b + github.com/tailscale/hujson v0.0.0-20211105212140-3a0adc019d83 github.com/tcnksm/go-latest v0.0.0-20170313132115-e3007ae9052e github.com/zsais/go-gin-prometheus v0.1.0 - golang.org/x/crypto v0.0.0-20211117183948-ae814b36b871 + golang.org/x/crypto v0.0.0-20211202192323-5770296d904e golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 golang.org/x/sync v0.0.0-20210220032951-036812b2e83c google.golang.org/genproto v0.0.0-20211104193956-4c6863e31247 @@ -40,12 +40,12 @@ require ( gorm.io/driver/sqlite v1.1.5 gorm.io/gorm v1.21.15 inet.af/netaddr v0.0.0-20211027220019-c74959edd3b6 - tailscale.com v1.18.1 + tailscale.com v1.20.3 ) require ( github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect - github.com/Microsoft/go-winio v0.5.0 // indirect + github.com/Microsoft/go-winio v0.5.1 // indirect github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 // indirect github.com/atomicgo/cursor v0.0.1 // indirect github.com/beorn7/perks v1.0.1 // indirect @@ -57,7 +57,7 @@ require ( github.com/docker/docker v20.10.8+incompatible // indirect github.com/docker/go-connections v0.4.0 // indirect github.com/docker/go-units v0.4.0 // indirect - github.com/fsnotify/fsnotify v1.4.9 // indirect + github.com/fsnotify/fsnotify v1.5.1 // indirect github.com/ghodss/yaml v1.0.0 // indirect github.com/gin-contrib/sse v0.1.0 // indirect github.com/go-playground/locales v0.14.0 // indirect @@ -92,30 +92,30 @@ require ( github.com/leodido/go-urn v1.2.1 // indirect github.com/lib/pq v1.10.3 // indirect github.com/magiconair/properties v1.8.5 // indirect - github.com/mattn/go-colorable v0.1.8 // indirect + github.com/mattn/go-colorable v0.1.12 // indirect github.com/mattn/go-isatty v0.0.14 // indirect github.com/mattn/go-runewidth v0.0.13 // indirect github.com/mattn/go-sqlite3 v1.14.8 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b // indirect - github.com/mitchellh/mapstructure v1.4.1 // indirect + github.com/mitchellh/mapstructure v1.4.3 // indirect github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/image-spec v1.0.2 // indirect github.com/opencontainers/runc v1.0.3 // indirect - github.com/pelletier/go-toml v1.9.3 // indirect + github.com/pelletier/go-toml v1.9.4 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/prometheus/client_model v0.2.0 // indirect github.com/prometheus/common v0.32.1 // indirect github.com/prometheus/procfs v0.7.3 // indirect github.com/rivo/uniseg v0.2.0 // indirect - github.com/rogpeppe/go-internal v1.8.0 // indirect + github.com/rogpeppe/go-internal v1.8.1-0.20211023094830-115ce09fd6b4 // indirect github.com/sirupsen/logrus v1.8.1 // indirect github.com/spf13/afero v1.6.0 // indirect - github.com/spf13/cast v1.3.1 // indirect + github.com/spf13/cast v1.4.1 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/subosito/gotenv v1.2.0 // indirect @@ -127,12 +127,12 @@ require ( go4.org/intern v0.0.0-20211027215823-ae77deb06f29 // indirect go4.org/mem v0.0.0-20210711025021-927187094b94 // indirect go4.org/unsafe/assume-no-moving-gc v0.0.0-20211027215541-db492cf91b37 // indirect - golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 // indirect - golang.org/x/sys v0.0.0-20211124211545-fe61309f8881 // indirect - golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b // indirect + golang.org/x/net v0.0.0-20211205041911-012df41ee64c // indirect + golang.org/x/sys v0.0.0-20211205182925-97ca703d548d // indirect + golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect golang.org/x/text v0.3.7 // indirect google.golang.org/appengine v1.6.7 // indirect - gopkg.in/ini.v1 v1.62.0 // indirect + gopkg.in/ini.v1 v1.66.2 // indirect gopkg.in/square/go-jose.v2 v2.6.0 // indirect gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect ) diff --git a/go.sum b/go.sum index 6dcc0a85..86642b87 100644 --- a/go.sum +++ b/go.sum @@ -1,4 +1,3 @@ -4d63.com/gochecknoglobals v0.0.0-20201008074935-acfc0b28355a/go.mod h1:wfdC5ZjKSPr7CybKEcgJhUOgeAQW1+7WcyK8OvUilfo= bazil.org/fuse v0.0.0-20160811212531-371fbbdaa898/go.mod h1:Xbm+BRKSBEpa4q4hTSxohYNQpsxXPbPry4JJWOB3LB8= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= @@ -20,6 +19,11 @@ cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmW cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg= cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8= cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= +cloud.google.com/go v0.83.0/go.mod h1:Z7MJUsANfY0pYPdw0lbnivPx4/vhy/e2FEkSkF7vAVY= +cloud.google.com/go v0.84.0/go.mod h1:RazrYuxIK6Kb7YrzzhPoLmCVzl7Sup4NrbKPg8KHSUM= +cloud.google.com/go v0.87.0/go.mod h1:TpDYlFy7vuLzZMMZ+B6iRiELaY7z/gJPaqbMx6mlWcY= +cloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ= +cloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= @@ -29,6 +33,7 @@ cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM7 cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= +cloud.google.com/go/firestore v1.6.0/go.mod h1:afJwI0vaXwAG54kI7A//lP/lSPDkQORQuMkv56TxEPU= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= @@ -40,7 +45,6 @@ cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RX cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= contrib.go.opencensus.io/exporter/ocagent v0.7.0/go.mod h1:IshRmMJBhDfFj5Y67nVhMYTTIze91RUeT73ipWKs/GY= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -filippo.io/mkcert v1.4.3/go.mod h1:64ke566uBwAQcdK3vRDABgsgVHqrfORPTw6YytZCTxk= github.com/AlecAivazis/survey/v2 v2.3.2 h1:TqTB+aDDCLYhf9/bD2TwSO8u8jDSmMUd2SUVO4gCnU8= github.com/AlecAivazis/survey/v2 v2.3.2/go.mod h1:TH2kPCDU3Kqq7pLbnCWwZXDBjnhZtmsCle5EiYDJ2fg= github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= @@ -49,49 +53,32 @@ github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg6 github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= -github.com/Djarvur/go-err113 v0.0.0-20200511133814-5174e21577d5/go.mod h1:4UJr5HIiMZrwgkSPdsjy2uOQExX/WEILpIrO9UPGuXs= -github.com/Djarvur/go-err113 v0.1.0/go.mod h1:4UJr5HIiMZrwgkSPdsjy2uOQExX/WEILpIrO9UPGuXs= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= github.com/MarvinJWendt/testza v0.1.0/go.mod h1:7AxNvlfeHP7Z/hDQ5JtE3OKYT3XFUeLCDE2DQninSqs= github.com/MarvinJWendt/testza v0.2.1 h1:eitywm1lzygA2KCyn55jFVdOaXj5I9LeOsLNeifd2Kw= github.com/MarvinJWendt/testza v0.2.1/go.mod h1:God7bhG8n6uQxwdScay+gjm9/LnO4D3kkcZX4hv9Rp8= -github.com/Masterminds/goutils v1.1.0/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww= -github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= -github.com/Masterminds/semver/v3 v3.1.0/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= github.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc= github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= -github.com/Masterminds/sprig v2.22.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o= github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= -github.com/Microsoft/go-winio v0.4.15/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw= -github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0= -github.com/Microsoft/go-winio v0.5.0 h1:Elr9Wn+sGKPlkaBvwu4mTrxtmOp3F3yV9qhaHbXGjwU= -github.com/Microsoft/go-winio v0.5.0/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= +github.com/Microsoft/go-winio v0.5.1 h1:aPJp2QD7OOrhO5tQXqQoGSJc+DjDtWTGLOmNyAm6FgY= +github.com/Microsoft/go-winio v0.5.1/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= github.com/Netflix/go-expect v0.0.0-20180615182759-c93bf25de8e8 h1:xzYJEypr/85nBpB11F9br+3HUrpgb+fcm5iADzXXYEw= github.com/Netflix/go-expect v0.0.0-20180615182759-c93bf25de8e8/go.mod h1:oX5x61PbNXchhh0oikYAH+4Pcfw5LKv21+Jnpr6r6Pc= github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 h1:TngWCqHvy9oXAN6lEVMRuU21PR1EtLVZJmdB18Gu3Rw= github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= -github.com/OpenPeeDeeP/depguard v1.0.1/go.mod h1:xsIw86fROiiwelg+jB2uM9PiKihMMmUx/1V+TNhjQvM= github.com/PuerkitoBio/goquery v1.5.1/go.mod h1:GsLWisAFVj4WgDibEWF4pvYnkVQBpKBKeU+7zCJoLcc= github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= -github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= -github.com/akutz/memconn v0.1.0/go.mod h1:Jo8rI7m0NieZyLI5e2CDlRdRqRRB4S7Xp77ukDjH+Fw= -github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs= -github.com/alecthomas/kingpin v2.2.6+incompatible/go.mod h1:59OFYbFVLKQKq+mqrL6Rw5bR0c3ACQaawgXx0QYndlE= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= -github.com/alexbrainman/sspi v0.0.0-20210105120005-909beea2cc74/go.mod h1:cEWa1LVoE5KvSD9ONXsZrj0z6KqySlCCNKHlLzbqAt4= -github.com/andybalholm/brotli v1.0.0/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y= github.com/andybalholm/cascadia v1.1.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y= -github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= -github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= @@ -99,24 +86,13 @@ github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hC github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= -github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= +github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= github.com/atomicgo/cursor v0.0.1 h1:xdogsqa6YYlLfM+GyClC/Lchf7aiMerFiZQn7soTOoU= github.com/atomicgo/cursor v0.0.1/go.mod h1:cBON2QmmrysudxNBFthvMtN32r3jxVRIvzkUiF/RuIk= github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= -github.com/aws/aws-sdk-go v1.38.52/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= -github.com/aws/aws-sdk-go-v2 v1.9.2/go.mod h1:cK/D0BBs0b/oWPIcX/Z/obahJK1TT7IPVjy53i/mX/4= -github.com/aws/aws-sdk-go-v2/config v1.8.3/go.mod h1:4AEiLtAb8kLs7vgw2ZV3p2VZ1+hBavOc84hqxVNpCyw= -github.com/aws/aws-sdk-go-v2/credentials v1.4.3/go.mod h1:FNNC6nQZQUuyhq5aE5c7ata8o9e4ECGmS4lAXC7o1mQ= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.6.0/go.mod h1:gqlclDEZp4aqJOancXK6TN24aKhT0W0Ae9MHk3wzTMM= -github.com/aws/aws-sdk-go-v2/internal/ini v1.2.4/go.mod h1:ZcBrrI3zBKlhGFNYWvju0I3TR93I7YIgAfy82Fh4lcQ= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.3.2/go.mod h1:72HRZDLMtmVQiLG2tLfQcaWLCssELvGl+Zf2WVxMmR8= -github.com/aws/aws-sdk-go-v2/service/ssm v1.12.0/go.mod h1:m3cb1hedrft0oYmueH0CkBgRdiwczuKRXPr0tilSpz4= -github.com/aws/aws-sdk-go-v2/service/sso v1.4.2/go.mod h1:NBvT9R1MEF+Ud6ApJKM0G+IkPchKS7p7c2YPKwHmBOk= -github.com/aws/aws-sdk-go-v2/service/sts v1.7.2/go.mod h1:8EzeIqfWt2wWT4rJVu3f21TfrhJ8AEMzVybRNSb/b4g= -github.com/aws/smithy-go v1.8.0/go.mod h1:SObp3lf9smib00L/v3U2eAKG8FyQ7iLrJnQiAmR5n+E= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= @@ -126,18 +102,13 @@ github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kB github.com/bits-and-blooms/bitset v1.2.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= github.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqOes/6LfM= -github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb/go.mod h1:PkYb9DJNAwrSvRx5DYA+gUcOIgTGVMNkfSCbZM8cWpI= -github.com/bombsimon/wsl/v3 v3.1.0/go.mod h1:st10JtZYLE4D5sC7b8xV4zTKZwAQjCH/Hy2Pm1FNZIc= github.com/bufbuild/buf v0.37.0/go.mod h1:lQ1m2HkIaGOFba6w/aC3KYBHhKEOESP3gaAEpS3dAFM= github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= -github.com/cavaliercoder/go-cpio v0.0.0-20180626203310-925f9528c45e/go.mod h1:oDpT4efm8tSYHXV5tHSdRvBet/b/QzxZ+XyyPehvm3A= -github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4= github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= github.com/cenkalti/backoff/v4 v4.1.0/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= github.com/cenkalti/backoff/v4 v4.1.1 h1:G2HAfAmvm/GcKan2oOQpBXOd2tT2G57ZnZGWa1PxPBQ= github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= @@ -146,7 +117,6 @@ github.com/checkpoint-restore/go-criu/v5 v5.0.0/go.mod h1:cfwC0EG7HMUenopBsUf9d8 github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/cilium/ebpf v0.5.0/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs= github.com/cilium/ebpf v0.6.2/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs= github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= @@ -169,7 +139,6 @@ github.com/containerd/continuity v0.1.0/go.mod h1:ICJu0PwR54nI0yPEnJ6jcS+J7CZAUX github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= -github.com/coreos/go-iptables v0.6.0/go.mod h1:Qe8Bv2Xik5FyTXwgIbLAnv2sWSBmvWdFETJConOQ//Q= github.com/coreos/go-oidc/v3 v3.1.0 h1:6avEvcdvTa1qYsOZ6I5PRkSYHzpTNWgKYmaJfaYbrRw= github.com/coreos/go-oidc/v3 v3.1.0/go.mod h1:rEJ/idjfUyfkBit1eI1fvyr+64/g9dcKpAm8MJMesvo= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= @@ -186,15 +155,10 @@ github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7Do github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/creack/pty v1.1.17 h1:QeVUsEDNrLBW4tMgZHvxy18sKtr6VI492kBhUfhDJNI= -github.com/creack/pty v1.1.17/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= github.com/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4= -github.com/daixiang0/gci v0.2.4/go.mod h1:+AV8KmHTGxxwp/pY84TLQfFKp2vuKXXJVzF3kD/hfR4= -github.com/daixiang0/gci v0.2.7/go.mod h1:+4dZ7TISfSmqfAGv59ePaHfNzgGtIkHAhhdKggP1JAc= -github.com/dave/jennifer v1.4.1/go.mod h1:7jEdnm+qBcxl8PC0zyp7vxcpSRnzXSt9r39tpTVGlwA= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 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/denis-tingajkin/go-header v0.3.1/go.mod h1:sq/2IxMhaZX+RRcgHfCRx/m0M5na0fBt4/CRe7Lrji0= github.com/denisenkom/go-mssqldb v0.0.0-20191124224453-732737034ffd/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU= github.com/denisenkom/go-mssqldb v0.9.0/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU= github.com/denisenkom/go-mssqldb v0.10.0 h1:QykgLZBorFE95+gO3u9esLd0BmbvpWp0/waNNZfHBM8= @@ -221,7 +185,6 @@ github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFP github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= github.com/efekarakus/termcolor v1.0.1 h1:YAKFO3bnLrqZGTWyNLcYoSIAQFKVOmbqmDnwsU/znzg= github.com/efekarakus/termcolor v1.0.1/go.mod h1:AitrZNrE4nPO538fRsqf+p0WgLdAsGN5pUNrHEPsEMM= -github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o= github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= @@ -234,35 +197,23 @@ github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go. github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5 h1:Yzb9+7DPaBjB8zlTR87/ElzFsnQfuHnVUVqpZZIcV5Y= github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5/go.mod h1:a2zkGnVExMxdzMo3M0Hi/3sEU+cWnZpSni0O6/Yb/P0= -github.com/fanliao/go-promise v0.0.0-20141029170127-1890db352a72/go.mod h1:PjfxuH4FZdUyfMdtBio2lsRr1AKEaVPwelzuHuh8Lqc= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= -github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= github.com/fatih/set v0.2.1 h1:nn2CaJyknWE/6txyUDGwysr3G5QC6xWB/PtVjPBbeaA= github.com/fatih/set v0.2.1/go.mod h1:+RKtMCH+favT2+3YecHGxcc0b4KyVWA1QWWJUs4E0CI= -github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= -github.com/frankban/quicktest v1.14.0/go.mod h1:NeW+ay9A/U67EYXNFA1nPE8e/tnQv/09mUdL/ijj8og= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/fsnotify/fsnotify v1.5.1 h1:mZcQUHVQUQWoPXXtuf9yuEXKudkV2sx1E06UadKWpgI= +github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU= github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= -github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M= github.com/gin-gonic/gin v1.7.4 h1:QmUZXrvJ9qZ3GfWvQ+2wnW/1ePrTEJqPKMYEU3lD/DM= github.com/gin-gonic/gin v1.7.4/go.mod h1:jD2toBW3GZUr5UMcdrwQA10I7RuaFOl/SGeDjXkfUtY= -github.com/github/fakeca v0.1.0/go.mod h1:+bormgoGMMuamOscx7N91aOuUST7wdaJ2rNjeohylyo= -github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= -github.com/gliderlabs/ssh v0.3.3/go.mod h1:ZSS+CUoKHDrqVakTfTWUlKSr9MtMFkC4UvtQKD7O914= -github.com/go-critic/go-critic v0.5.2/go.mod h1:cc0+HvdE3lFpqLecgqMaJcvWWH77sLdBp+wLGPM1Yyo= -github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E= -github.com/go-git/go-billy/v5 v5.0.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0= -github.com/go-git/go-git-fixtures/v4 v4.0.2-0.20200613231340-f56387b50c12/go.mod h1:m+ICp2rF3jDhFgEZ/8yziagdT1C+ZpZcrJjappBCDSw= -github.com/go-git/go-git/v5 v5.2.0/go.mod h1:kh02eMX+wdqqxgNMEyq8YgwlIOsDOa9homkUq1PoTMs= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= @@ -273,8 +224,6 @@ github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vb github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= -github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8= -github.com/go-ole/go-ole v1.2.6-0.20210915003542-8b1f7f90f6b1/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A= github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= @@ -283,7 +232,6 @@ github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= github.com/go-playground/universal-translator v0.18.0 h1:82dyy6p4OuJq4/CByFNOn/jYrnRPArHwAcmLoJZxyho= github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA= -github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4= github.com/go-playground/validator/v10 v10.9.0 h1:NgTtmN58D0m8+UuxtYmGztBJB7VnPgjj221I1QHci2A= github.com/go-playground/validator/v10 v10.9.0/go.mod h1:74x4gJWsvQexRdW8Pn3dXSGrTK4nAUsbPlLADvpJkos= @@ -292,23 +240,7 @@ github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LB github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE= github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/go-toolsmith/astcast v1.0.0/go.mod h1:mt2OdQTeAQcY4DQgPSArJjHCcOwlX+Wl/kwN+LbLGQ4= -github.com/go-toolsmith/astcopy v1.0.0/go.mod h1:vrgyG+5Bxrnz4MZWPF+pI4R8h3qKRjjyvV/DSez4WVQ= -github.com/go-toolsmith/astequal v1.0.0/go.mod h1:H+xSiq0+LtiDC11+h1G32h7Of5O3CYFJ99GVbS5lDKY= -github.com/go-toolsmith/astfmt v1.0.0/go.mod h1:cnWmsOAuq4jJY6Ct5YWlVLmcmLMn1JUPuQIHCY7CJDw= -github.com/go-toolsmith/astinfo v0.0.0-20180906194353-9809ff7efb21/go.mod h1:dDStQCHtmZpYOmjRP/8gHHnCCch3Zz3oEgCdZVdtweU= -github.com/go-toolsmith/astp v1.0.0/go.mod h1:RSyrtpVlfTFGDYRbrjyWP1pYu//tSFcvdYrA8meBmLI= -github.com/go-toolsmith/pkgload v1.0.0/go.mod h1:5eFArkbO80v7Z0kdngIxsRXRMTaX4Ilcwuh3clNrQJc= -github.com/go-toolsmith/strparse v1.0.0/go.mod h1:YI2nUKP9YGZnL/L1/DLFBfixrcjslWct4wyljWhSRy8= -github.com/go-toolsmith/typep v1.0.0/go.mod h1:JSQCQMUPdRlMZFswiq3TGpNp1GMktqkR2Ns5AIQkATU= -github.com/go-toolsmith/typep v1.0.2/go.mod h1:JSQCQMUPdRlMZFswiq3TGpNp1GMktqkR2Ns5AIQkATU= -github.com/go-xmlfmt/xmlfmt v0.0.0-20191208150333-d5b6f63a941b/go.mod h1:aUCEOzzezBEjDBbFBoSiya/gduyIiWYRP6CnSFIV8AM= -github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= -github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= -github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= -github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= -github.com/godbus/dbus/v5 v5.0.5/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gofrs/flock v0.8.0/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= @@ -338,6 +270,7 @@ github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= +github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -357,25 +290,9 @@ github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2/go.mod h1:k9Qvh+8juN+UKMCS/3jFtGICgW8O96FVaZsaxdzDkR4= -github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a/go.mod h1:ryS0uhF+x9jgbj/N71xsEqODy9BN81/GonCZiOzirOk= -github.com/golangci/errcheck v0.0.0-20181223084120-ef45e06d44b6/go.mod h1:DbHgvLiFKX1Sh2T1w8Q/h4NAI8MHIpzCdnBUDTXU3I0= -github.com/golangci/go-misc v0.0.0-20180628070357-927a3d87b613/go.mod h1:SyvUF2NxV+sN8upjjeVYr5W7tyxaT1JVtvhKhOn2ii8= -github.com/golangci/gocyclo v0.0.0-20180528144436-0a533e8fa43d/go.mod h1:ozx7R9SIwqmqf5pRP90DhR2Oay2UIjGuKheCBCNwAYU= -github.com/golangci/gofmt v0.0.0-20190930125516-244bba706f1a/go.mod h1:9qCChq59u/eW8im404Q2WWTrnBUQKjpNYKMbU4M7EFU= -github.com/golangci/golangci-lint v1.33.0/go.mod h1:zMnMLSCaDlrXExYsuq2LOweE9CHVqYk5jexk23UsjYM= -github.com/golangci/ineffassign v0.0.0-20190609212857-42439a7714cc/go.mod h1:e5tpTHCfVze+7EpLEozzMB3eafxo2KT5veNg1k6byQU= -github.com/golangci/lint-1 v0.0.0-20191013205115-297bf364a8e0/go.mod h1:66R6K6P6VWk9I95jvqGxkqJxVWGFy9XlDwLwVz1RCFg= -github.com/golangci/maligned v0.0.0-20180506175553-b1d89398deca/go.mod h1:tvlJhZqDe4LMs4ZHD0oMUlt9G2LWuDGoisJTBzLMV9o= -github.com/golangci/misspell v0.0.0-20180809174111-950f5d19e770/go.mod h1:dEbvlSfYbMQDtrpRMQU675gSDLDNa8sCPPChZ7PhiVA= -github.com/golangci/misspell v0.3.5/go.mod h1:dEbvlSfYbMQDtrpRMQU675gSDLDNa8sCPPChZ7PhiVA= -github.com/golangci/prealloc v0.0.0-20180630174525-215b22d4de21/go.mod h1:tf5+bzsHdTM0bsB7+8mt0GUMvjCgwLpTapNZHU8AajI= -github.com/golangci/revgrep v0.0.0-20180526074752-d9c87f5ffaf0/go.mod h1:qOQCunEYvmd/TLamH+7LlVccLvUH5kZNhbCgTHoBbp4= -github.com/golangci/revgrep v0.0.0-20180812185044-276a5c0a1039/go.mod h1:qOQCunEYvmd/TLamH+7LlVccLvUH5kZNhbCgTHoBbp4= -github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4/go.mod h1:Izgrg8RkN3rCIMLGE9CyYmU9pY2Jer6DgANEnZ/L/cQ= +github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -394,10 +311,10 @@ github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+u github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/goterm v0.0.0-20190703233501-fc88cf888a3f/go.mod h1:nOFQdrUlIlx6M6ODdSpBj1NVA+VgLC6kmw60mkw34H4= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= @@ -409,38 +326,28 @@ github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLe github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/google/rpmpack v0.0.0-20201206194719-59e495f2b7e1/go.mod h1:+y9lKiqDhR4zkLl+V9h4q0rdyrYVsWWm6LLCQP33DIk= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/gookit/color v1.3.1/go.mod h1:R3ogXq2B9rTbXoSHJ1HyUVAZ3poOJHpd9nQmyGZsfvQ= +github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= github.com/gookit/color v1.4.2 h1:tXy44JFSFkKnELV6WaMo/lLfu/meqITX3iAV52do7lk= github.com/gookit/color v1.4.2/go.mod h1:fqRyamkC1W8uxl+lxCQxOT09l/vYfZ+QeiX3rKQHCoQ= -github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gordonklaus/ineffassign v0.0.0-20200309095847-7953dde2c7bf/go.mod h1:cuNKsD1zp2v6XfE/orVX2QE1LC+i254ceGcVeDT3pTU= -github.com/goreleaser/chglog v0.1.2/go.mod h1:tTZsFuSZK4epDXfjMkxzcGbrIOXprf0JFp47BjIr3B8= -github.com/goreleaser/fileglob v0.3.1/go.mod h1:kNcPrPzjCp+Ox3jmXLU5QEsjhqrtLBm6OnXAif8KRl8= -github.com/goreleaser/nfpm v1.10.3/go.mod h1:EEC7YD5wi+ol0MiAshpgPANBOkjXDl7wqTLVk68OBsk= github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= -github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/gostaticanalysis/analysisutil v0.0.0-20190318220348-4088753ea4d3/go.mod h1:eEOZF4jCKGi+aprrirO9e7WKB3beBRtWgqGunKl6pKE= -github.com/gostaticanalysis/analysisutil v0.0.3/go.mod h1:eEOZF4jCKGi+aprrirO9e7WKB3beBRtWgqGunKl6pKE= -github.com/gostaticanalysis/analysisutil v0.1.0/go.mod h1:dMhHRU9KTiDcuLGdy87/2gTR8WruwYZrKdRq9m1O6uw= -github.com/gostaticanalysis/analysisutil v0.6.1/go.mod h1:18U/DLpRgIUd459wGxVHE0fRgmo1UgHDcbw7F5idXu0= -github.com/gostaticanalysis/comment v1.3.0/go.mod h1:xMicKDx7XRXYdVwY9f9wQpDJVnqWxw9wCauCMKp+IBI= -github.com/gostaticanalysis/comment v1.4.1/go.mod h1:ih6ZxzTHLdadaiSnF5WY3dxUoXfXAlTaRzuaNDlSado= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-middleware v1.2.2/go.mod h1:EaizFBKfUKtMIF5iaDEhniwNedqGo9FuLFzppDr3uwI= @@ -450,7 +357,6 @@ github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgf github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.14.6/go.mod h1:zdiPV4Yse/1gnckTHtghG4GkDEdKCRJduHpTxT3/jcw= -github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/grpc-ecosystem/grpc-gateway/v2 v2.3.0/go.mod h1:d2gYTOTUQklu06xp0AJYYmRdTVU1VKrqhkYfYag2L08= github.com/grpc-ecosystem/grpc-gateway/v2 v2.4.0/go.mod h1:IOyTYjcIO0rkmnGBfJTL0NJ11exy/Tc2QEuv7hCXp24= @@ -458,14 +364,19 @@ github.com/grpc-ecosystem/grpc-gateway/v2 v2.6.0 h1:rgxjzoDmDXw5q8HONgyHhBas4to0 github.com/grpc-ecosystem/grpc-gateway/v2 v2.6.0/go.mod h1:qrJPVzv9YlhsrxJc3P/Q85nr0w1lIRikTl4JlhdDH5w= github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE= +github.com/hashicorp/consul/api v1.10.1/go.mod h1:XjsvQN+RJGWI2TWy1/kqaE16HrR2J/FWgkYjdZQsX9M= github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= +github.com/hashicorp/consul/sdk v0.8.0/go.mod h1:GBvyrGALthsZObzUGsfgHZQDXjg4lOjagTIwIR1vPms= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-hclog v0.12.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= +github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA= github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= +github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= @@ -479,19 +390,17 @@ github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= +github.com/hashicorp/mdns v1.0.1/go.mod h1:4gW7WsVCke5TE7EPeYliwHlRUyBtfCwuFwuMg2DmyNY= github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= +github.com/hashicorp/memberlist v0.2.2/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE= github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= +github.com/hashicorp/serf v0.9.5/go.mod h1:UWDWwZeL5cuWDJdl0C6wrvrUwEqtQ4ZKBKKENpqIUyk= github.com/hinshun/vt10x v0.0.0-20180616224451-1954e6464174 h1:WlZsjVhE8Af9IcZDGgJGQpNflI3+MJSBhsgT5PCtzBQ= github.com/hinshun/vt10x v0.0.0-20180616224451-1954e6464174/go.mod h1:DqJ97dSdRW1W22yXSB90986pcOyQ7r45iio1KN2ez1A= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/huandu/xstrings v1.3.2/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= -github.com/hugelgupf/socketpair v0.0.0-20190730060125-05d35a94e714/go.mod h1:2Goc3h8EklBH5mspfHFxBnEoURQCGzQQH1ga9Myjvis= -github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/imdario/mergo v0.3.9/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= -github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU= github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= @@ -500,8 +409,6 @@ github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod github.com/infobloxopen/atlas-app-toolkit v0.24.1-0.20210416193901-4c7518b07e08/go.mod h1:9BTHnpff654rY1J8KxSUOLJ+ZUDn2Vi3mmk26gQDo1M= github.com/infobloxopen/protoc-gen-gorm v1.0.1 h1:IjvQ02gZSll+CjpWjxkLqrpxnvKAGfs5dXRJEpfZx2s= github.com/infobloxopen/protoc-gen-gorm v1.0.1/go.mod h1:gTu86stnDQXwcNqLG9WNJfl3IPUIhxmGNqJ8z4826uo= -github.com/insomniacslk/dhcp v0.0.0-20210621130208-1cac67f12b1e/go.mod h1:h+MxyHxRg9NH3terB1nfRIUaQEcI0XOVkdR9LNBlp8E= -github.com/jackc/chunkreader v1.0.0 h1:4s39bBR8ByfqH+DKm8rQA3E1LHZWB9XWcrz8fqaZbe0= github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo= github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk= github.com/jackc/chunkreader/v2 v2.0.1 h1:i+RDz65UE+mmpjTfyz0MoVTnzeYxroil2G82ki7MGG8= @@ -526,7 +433,6 @@ github.com/jackc/pgmock v0.0.0-20210724152146-4ad1a8207f65 h1:DadwsjnMwFjfWc9y5W github.com/jackc/pgmock v0.0.0-20210724152146-4ad1a8207f65/go.mod h1:5R2h2EEX+qri8jOWMbJCtaPWkrrNc7OHwsp2TCqp7ak= github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= -github.com/jackc/pgproto3 v1.1.0 h1:FYYE4yRw+AgI8wXIinMlNjBbp/UitDJwfj5LqqewP1A= github.com/jackc/pgproto3 v1.1.0/go.mod h1:eR5FA3leWg7p9aeAqi37XOTgTIbkABlvcPB3E5rlc78= github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190420180111-c116219b62db/go.mod h1:bhq50y+xrl9n5mRYyCBFKkpRVTLYJVWeCc+mEAI3yXA= github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190609003834-432c2951c711/go.mod h1:uH0AWtUmuShn0bcesswc4aBTWGvw0cAxIJp+6OB//Wg= @@ -564,11 +470,7 @@ github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0f github.com/jackc/puddle v1.1.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v1.1.1/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= -github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= -github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= -github.com/jgautheron/goconst v0.0.0-20201117150253-ccae5bf973f3/go.mod h1:aAosetZ5zaeC/2EfMeRswtxUFBpe2Hr7HzkgX4fanO4= github.com/jhump/protoreflect v1.8.1/go.mod h1:7GcYQDdMU/O/BBrl/cX6PNHpXh6cenjd8pneu5yW7Tg= -github.com/jingyugao/rowserrcheck v0.0.0-20191204022205-72ab7603b68a/go.mod h1:xRskid8CManxVta/ALEhJha/pweKBaVG6fWgc0yH25s= github.com/jinzhu/gorm v1.9.16 h1:+IyIjPEABKRpsu/F8OvDPy9fyQlgsg2luMV2ZIH5i5o= github.com/jinzhu/gorm v1.9.16/go.mod h1:G3LB3wezTOWM2ITLzPxEXgSkOXAntiLHS7UdBefADcs= github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= @@ -577,25 +479,9 @@ github.com/jinzhu/now v1.0.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/ github.com/jinzhu/now v1.1.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= github.com/jinzhu/now v1.1.2 h1:eVKgfIdy9b6zbWBMgFpfDPoAMifwSZagU9HmEU6zgiI= github.com/jinzhu/now v1.1.2/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= -github.com/jirfag/go-printf-func-name v0.0.0-20191110105641-45db9963cdd3/go.mod h1:HEWGJkRDzjJY2sqdDwxccsGicWEf9BQOZsq2tV+xzM0= -github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af/go.mod h1:HEWGJkRDzjJY2sqdDwxccsGicWEf9BQOZsq2tV+xzM0= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= -github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= -github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= -github.com/jmoiron/sqlx v1.2.0/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks= -github.com/jmoiron/sqlx v1.2.1-0.20190826204134-d7d95172beb5/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= -github.com/josharian/native v0.0.0-20200817173448-b6b71def0850/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= -github.com/jsimonetti/rtnetlink v0.0.0-20190606172950-9527aa82566a/go.mod h1:Oz+70psSo5OFh8DBl0Zv2ACw7Esh6pPUphlvZG9x7uw= -github.com/jsimonetti/rtnetlink v0.0.0-20200117123717-f846d4f6c1f4/go.mod h1:WGuG/smIU4J/54PblvSbh+xvCZmpJnFgr3ds6Z55XMQ= -github.com/jsimonetti/rtnetlink v0.0.0-20201009170750-9c6f07d100c1/go.mod h1:hqoO/u39cqLeBLebZ8fWdE96O7FxrAsRYhnVOdgHxok= -github.com/jsimonetti/rtnetlink v0.0.0-20201110080708-d2c240429e6c/go.mod h1:huN4d1phzjhlOsNIjFsw2SVRbwIHj3fJDMEU2SDPTmg= -github.com/jsimonetti/rtnetlink v0.0.0-20201216134343-bde56ed16391/go.mod h1:cR77jAZG3Y3bsb8hF6fHJbFoyFukLFOkQ98S0pQz3xw= -github.com/jsimonetti/rtnetlink v0.0.0-20201220180245-69540ac93943/go.mod h1:z4c53zj6Eex712ROyh8WI0ihysb5j2ROyV42iNogmAs= -github.com/jsimonetti/rtnetlink v0.0.0-20210122163228-8d122574c736/go.mod h1:ZXpIyOK59ZnN7J0BV99cZUPmsqDRZ3eq5X+st7u/oSA= -github.com/jsimonetti/rtnetlink v0.0.0-20210212075122-66c871082f2b/go.mod h1:8w9Rh8m+aHZIG69YPGGem1i5VzoyRC8nw2kA8B+ik5U= -github.com/jsimonetti/rtnetlink v0.0.0-20210525051524-4cc836578190/go.mod h1:NmKSdU4VGSiv1bMsdqNALI4RSvvjtz65tTMCnD05qLo= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= @@ -606,20 +492,14 @@ github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnr github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= -github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs= github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= -github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= -github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= -github.com/klauspost/compress v1.10.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= -github.com/klauspost/compress v1.11.0/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.11.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.13.6 h1:P76CopJELS0TiO2mebmnzgWaajssP/EszplttgQxcgc= github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= @@ -630,6 +510,7 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxv github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= @@ -640,8 +521,6 @@ github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/kunwardeep/paralleltest v1.0.2/go.mod h1:ZPqNm1fVHPllh5LPVujzbVz1JN2GhLxSfY+oqUsvG30= -github.com/kyoh86/exportloopref v0.1.8/go.mod h1:1tUcJeiioIs7VWe5gcOObrux3lb66+sBqGZrRkMwPgg= github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w= github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY= @@ -657,26 +536,19 @@ github.com/lib/pq v1.10.3 h1:v9QZf2Sn6AmjXtQeFpdoq/eaNtYP6IN+7lcrygsIAtg= github.com/lib/pq v1.10.3/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= -github.com/logrusorgru/aurora v0.0.0-20181002194514-a7b3b318ed4e/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4= -github.com/lxn/walk v0.0.0-20210112085537-c389da54e794/go.mod h1:E23UucZGqpuUANJooIbHWCufXvOcT6E7Stq81gU+CSQ= -github.com/lxn/win v0.0.0-20210218163916-a377121e959e/go.mod h1:KxxjdtRkfNoYDCUP5ryK7XJJNTnpC8atvtmTheChOtk= github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= github.com/magefile/mage v1.10.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/magiconair/properties v1.8.4/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= github.com/magiconair/properties v1.8.5 h1:b6kJs+EmPFMYGkow9GiUyCyOvIwYetYJ3fSaWak/Gls= github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= -github.com/maratori/testpackage v1.0.1/go.mod h1:ddKdw+XG0Phzhx8BFDTKgpWP4i7MpApTE5fXSKAqwDU= -github.com/matoous/godox v0.0.0-20190911065817-5d6d842e92eb/go.mod h1:1BELzlh859Sh1c6+90blK8lbYy0kwQf1bYlBhBysy1s= -github.com/matoous/godox v0.0.0-20200801072554-4fb83dc2941e/go.mod h1:1BELzlh859Sh1c6+90blK8lbYy0kwQf1bYlBhBysy1s= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8= -github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40= +github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= @@ -691,53 +563,30 @@ github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27k github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= -github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/mattn/go-sqlite3 v1.14.0/go.mod h1:JIl7NbARA7phWnGvh0LKTyg7S9BA+6gx71ShQilpsus= github.com/mattn/go-sqlite3 v1.14.5/go.mod h1:WVKg1VTActs4Qso6iwGbiFih2UIHo0ENGwNd0Lj+XmI= github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/mattn/go-sqlite3 v1.14.8 h1:gDp86IdQsN/xWjIEmr9MF6o9mpksUgh0fu+9ByFxzIU= github.com/mattn/go-sqlite3 v1.14.8/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= -github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/mbilski/exhaustivestruct v1.1.0/go.mod h1:OeTBVxQWoEmB2J2JCHmXWPJ0aksxSUOUy+nvtVEfzXc= -github.com/mdlayher/ethernet v0.0.0-20190606142754-0394541c37b7/go.mod h1:U6ZQobyTjI/tJyq2HG+i/dfSoFUt8/aZCM+GKtmFk/Y= -github.com/mdlayher/ethtool v0.0.0-20210210192532-2b88debcdd43/go.mod h1:+t7E0lkKfbBsebllff1xdTmyJt8lH37niI6kwFk9OTo= -github.com/mdlayher/genetlink v1.0.0/go.mod h1:0rJ0h4itni50A86M2kHcgS85ttZazNt7a8H2a2cw0Gc= -github.com/mdlayher/netlink v0.0.0-20190409211403-11939a169225/go.mod h1:eQB3mZE4aiYnlUsyGGCOpPETfdQq4Jhsgf1fk3cwQaA= -github.com/mdlayher/netlink v1.0.0/go.mod h1:KxeJAFOFLG6AjpyDkQ/iIhxygIUKD+vcwqcnu43w/+M= -github.com/mdlayher/netlink v1.1.0/go.mod h1:H4WCitaheIsdF9yOYu8CFmCgQthAPIWZmcKp9uZHgmY= -github.com/mdlayher/netlink v1.1.1/go.mod h1:WTYpFb/WTvlRJAyKhZL5/uy69TDDpHHu2VZmb2XgV7o= -github.com/mdlayher/netlink v1.2.0/go.mod h1:kwVW1io0AZy9A1E2YYgaD4Cj+C+GPkU6klXCMzIJ9p8= -github.com/mdlayher/netlink v1.2.1/go.mod h1:bacnNlfhqHqqLo4WsYeXSqfyXkInQ9JneWI68v1KwSU= -github.com/mdlayher/netlink v1.2.2-0.20210123213345-5cc92139ae3e/go.mod h1:bacnNlfhqHqqLo4WsYeXSqfyXkInQ9JneWI68v1KwSU= -github.com/mdlayher/netlink v1.3.0/go.mod h1:xK/BssKuwcRXHrtN04UBkwQ6dY9VviGGuriDdoPSWys= -github.com/mdlayher/netlink v1.4.0/go.mod h1:dRJi5IABcZpBD2A3D0Mv/AiX8I9uDEu5oGkAVrekmf8= -github.com/mdlayher/netlink v1.4.1/go.mod h1:e4/KuJ+s8UhfUpO9z00/fDZZmhSrs+oxyqAS9cNgn6Q= -github.com/mdlayher/raw v0.0.0-20190606142536-fef19f00fc18/go.mod h1:7EpbotpCmVZcu+KCX4g9WaRNuu11uyhiW7+Le1dKawg= -github.com/mdlayher/raw v0.0.0-20191009151244-50f2db8cc065/go.mod h1:7EpbotpCmVZcu+KCX4g9WaRNuu11uyhiW7+Le1dKawg= -github.com/mdlayher/sdnotify v0.0.0-20210228150836-ea3ec207d697/go.mod h1:HtjVsQfsrBm1GDcDTUFn4ZXhftxTwO/hxrvEiRc61U4= -github.com/mdlayher/socket v0.0.0-20210307095302-262dc9984e00/go.mod h1:GAFlyu4/XV68LkQKYzKhIo/WW7j3Zi0YRAz/BOoanUc= github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b h1:j7+1HpAFS1zy5+Q4qx1fWh90gTKwiN4QCGoY9TWyyO4= github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= -github.com/miekg/dns v1.1.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4= +github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= -github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= +github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI= github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/go-ps v1.0.0/go.mod h1:J4lOc8z8yJs6vUwklHw2XEIiT4z4C40KtWVN3nvg8Pg= github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/mapstructure v1.3.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/mitchellh/mapstructure v1.4.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag= github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= -github.com/mitchellh/reflectwalk v1.0.1/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= +github.com/mitchellh/mapstructure v1.4.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/mapstructure v1.4.3 h1:OVowDSCllw/YjdLkam3/sm7wEtOy59d8ndGgCcyj8cs= +github.com/mitchellh/mapstructure v1.4.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/moby/sys/mountinfo v0.4.1/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A= github.com/moby/term v0.0.0-20201216013528-df9cb8a40635/go.mod h1:FBS0z0QWA44HXygs7VXDUOGoN/1TV3RuWkLO04am3wc= github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6 h1:dcztxKSvZ4Id8iPpHERQBbIJfabdt4wUm5qy3wOL2Zc= @@ -749,12 +598,9 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lN github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -github.com/moricho/tparallel v0.2.1/go.mod h1:fXEIZxG2vdfl0ZF8b42f5a78EhjjD5mX8qUplsoSU4k= -github.com/mozilla/tls-observatory v0.0.0-20200317151703-4fa42e1c2dee/go.mod h1:SrKMQvPiws7F7iqYp8/TX+IhxCYhzr6N/1yb8cwHsGk= github.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/nakabonne/nestif v0.3.0/go.mod h1:dI314BppzXjJ4HsCnbo7XzrJHPszZsjnk5wEBSYHI2c= github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU= github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k= @@ -762,23 +608,14 @@ github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzE github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= -github.com/nbutton23/zxcvbn-go v0.0.0-20180912185939-ae427f1e4c1d/go.mod h1:o96djdrsSGy3AWPyBgZMAGfxZNfgntdJG+11KU4QvbU= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= -github.com/nishanths/exhaustive v0.1.0/go.mod h1:S1j9110vxV1ECdCudXRkeMnFQ/DQk9ajLT0Uf2MYZQQ= github.com/nishanths/predeclared v0.0.0-20200524104333-86fad755b4d3/go.mod h1:nt3d53pc1VYcphSCIaYAJtnPYnr3Zyn8fMq2wvPGPso= -github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= -github.com/onsi/ginkgo v1.14.1/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= -github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.10.2/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= @@ -805,22 +642,16 @@ github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIw github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc= github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ= -github.com/pborman/getopt v1.1.0/go.mod h1:FxXoW1Re00sQG/+KIkuSqRL/LwQgSkv7uyac+STFsbk= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= -github.com/pelletier/go-toml v1.6.0/go.mod h1:5N711Q9dKgbdkxHL+MEfF31hpT7l0S0s/t2kKREewys= -github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc= -github.com/pelletier/go-toml v1.9.3 h1:zeC5b1GviRUyKYd6OJPvBU/mcVDVoL1OhT17FCt5dSQ= github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= +github.com/pelletier/go-toml v1.9.4 h1:tjENF6MfZAg8e4ZmZTeWaWiT2vXtsoO6+iuOjFhECwM= +github.com/pelletier/go-toml v1.9.4/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= -github.com/peterbourgon/ff/v3 v3.0.0/go.mod h1:UILIFjRH5a/ar8TjXYLTkIvSvekZqPm5Eb/qbGk6CT0= -github.com/peterbourgon/ff/v3 v3.1.0/go.mod h1:XNJLY8EIl6MjMVjBS4F0+G0LYoAqs0DTa4rmHHukKDE= -github.com/phayes/checkstyle v0.0.0-20170904204023-bfd46e6a821d/go.mod h1:3OzsM7FXDQlpCiw2j81fOmAwQLnZnLGXVKUzeKQXIAw= github.com/philip-bui/grpc-zerolog v1.0.1 h1:EMacvLRUd2O1K0eWod27ZP5CY1iTNkhBDLSN+Q4JEvA= github.com/philip-bui/grpc-zerolog v1.0.1/go.mod h1:qXbiq/2X4ZUMMshsqlWyTHOcw7ns+GZmlqZZN05ZHcQ= github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= -github.com/pkg/diff v0.0.0-20200914180035-5b29258ca4f7/go.mod h1:zO8QMzTeZd5cpnIkz/Gn6iK0jDfGicM1nynOkkPIl28= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -829,12 +660,10 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= github.com/pkg/profile v1.5.0/go.mod h1:qBsxPvzyUincmltOk6iyRVxHYg4adc0OFOv72ZdLa18= github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= -github.com/pkg/sftp v1.13.4/go.mod h1:LzqnAvaD5TWeNBsZpfKxSYn1MbjWwOsCIAFFJbpIsK8= 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/polyfloyd/go-errorlint v0.0.0-20201006195004-351e25ade6e3/go.mod h1:wi9BfjxjF/bwiZ701TzmfKu6UKC357IOAtNr0Td0Lvw= -github.com/polyfloyd/go-errorlint v0.0.0-20201127212506-19bd8db6546f/go.mod h1:wi9BfjxjF/bwiZ701TzmfKu6UKC357IOAtNr0Td0Lvw= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= +github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= @@ -873,22 +702,16 @@ github.com/pterm/pterm v0.12.27/go.mod h1:PhQ89w4i95rhgE+xedAoqous6K9X+r6aSOI2eF github.com/pterm/pterm v0.12.29/go.mod h1:WI3qxgvoQFFGKGjGnJR849gU0TsEOvKn5Q8LlY1U7lg= github.com/pterm/pterm v0.12.30 h1:ZfXzqtOJVKZ2Uhd+L5o6jmbO44PH3Mee4mxq303nh1Y= github.com/pterm/pterm v0.12.30/go.mod h1:MOqLIyMOgmTDz9yorcYbcw+HsgoZo3BQfg2wtl3HEFE= -github.com/quasilyte/go-consistent v0.0.0-20190521200055-c6f3937de18c/go.mod h1:5STLWrekHfjyYwxBRVRXNOSewLJ3PWfDJd1VyTS21fI= -github.com/quasilyte/go-ruleguard v0.2.0/go.mod h1:2RT/tf0Ce0UDj5y243iWKosQogJd8+1G3Rs2fxmlYnw= -github.com/quasilyte/go-ruleguard v0.2.1/go.mod h1:hN2rVc/uS4bQhQKTio2XaSJSafJwqBUWWwtssT3cQmc= -github.com/quasilyte/regex/syntax v0.0.0-20200407221936-30656e2c4a95/go.mod h1:rlzQ04UMyJXu/aOvhd8qT+hvDrFpiwqp8MRXDY9szc0= -github.com/quasilyte/regex/syntax v0.0.0-20200805063351-8f842688393c/go.mod h1:rlzQ04UMyJXu/aOvhd8qT+hvDrFpiwqp8MRXDY9szc0= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.5.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= -github.com/rogpeppe/go-internal v1.6.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= -github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8= github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= +github.com/rogpeppe/go-internal v1.8.1-0.20211023094830-115ce09fd6b4 h1:Ha8xCaq6ln1a+R91Km45Oq6lPXj2Mla6CRJYcuV2h1w= +github.com/rogpeppe/go-internal v1.8.1-0.20211023094830-115ce09fd6b4/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o= github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= github.com/rs/xid v1.3.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU= @@ -896,26 +719,16 @@ github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThC github.com/rs/zerolog v1.26.0 h1:ORM4ibhEZeTeQlCojCK2kPz1ogAY4bGs4tD+SaAdGaE= github.com/rs/zerolog v1.26.0/go.mod h1:yBiM87lvSqX8h0Ww4sdzNSkVYZ8dL2xjZJG1lAuGZEo= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/ryancurrah/gomodguard v1.1.0/go.mod h1:4O8tr7hBODaGE6VIhfJDHcwzh5GUccKSJBU0UMXJFVM= -github.com/ryanrolds/sqlclosecheck v0.3.0/go.mod h1:1gREqxyTGR3lVtpngyFo3hZAgk0KCtEdgEkHwDbigdA= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/sagikazarmark/crypt v0.1.0/go.mod h1:B/mN0msZuINBtQ1zZLEQcegFJJf9vnYIR88KRMEuODE= github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= -github.com/sassoftware/go-rpmutils v0.0.0-20190420191620-a8f1baeba37b/go.mod h1:am+Fp8Bt506lA3Rk3QCmSqmYmLMnPDhdDUcosQCAx+I= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/seccomp/libseccomp-golang v0.9.1/go.mod h1:GbW5+tmTXfcxTToHLXlScSlAvWlF4P2Ca7zGrPiEpWo= -github.com/securego/gosec/v2 v2.5.0/go.mod h1:L/CDXVntIff5ypVHIkqPXbtRpJiNCh6c6Amn68jXDjo= -github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= -github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= -github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c/go.mod h1:/PevMnwAxekIXwN8qQyfc5gl2NlkB3CQlkizAbOkeBs= -github.com/shirou/gopsutil v0.0.0-20190901111213-e4ec7b275ada/go.mod h1:WWnYX4lzhCH5h/3YBfyVA3VbLYjlMZZAQcW9ojMexNc= -github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4/go.mod h1:qsXQc7+bwAM3Q1u/4XEfrquwF8Lw7D7y5cD8CuHnfIc= github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= github.com/shopspring/decimal v0.0.0-20200227202807-02e2044944cc/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= github.com/shopspring/decimal v1.2.0 h1:abSATXmQEYyShuxI4/vyW3tV1MrKAJzCZ/0zLUXYbsQ= github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= -github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk= -github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= @@ -925,30 +738,23 @@ github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic github.com/sirupsen/logrus v1.8.0/go.mod h1:4GuYW9TZmE769R5STWrRakJc4UqQ3+QQ95fyz7ENv1A= github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e/go.mod h1:XV66xRDqSt+GTGFMVlhk3ULuV0y9ZmzeVGR4mloJI3M= -github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= -github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= github.com/soheilhy/cmux v0.1.5 h1:jjzc5WVemNEDTLwv9tlmemhC73tI08BNOIGwBOo10Js= github.com/soheilhy/cmux v0.1.5/go.mod h1:T7TcVDs9LWfQgPlPsdngu6I6QIoyIFZDDC6sNE1GqG0= -github.com/sonatard/noctx v0.0.1/go.mod h1:9D2D/EoULe8Yy2joDHJj7bv3sZoq9AaSb8B4lqBjiZI= github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= -github.com/sourcegraph/go-diff v0.6.1/go.mod h1:iBszgVvyxdc8SFZ7gm69go2KDdt3ag071iBaWPF6cjs= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= -github.com/spf13/afero v1.4.1/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= -github.com/spf13/afero v1.5.1/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= github.com/spf13/afero v1.6.0 h1:xoax2sJ2DT8S8xA2paPFjDCScCNeWsg75VG0DLRreiY= github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= -github.com/spf13/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng= github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cast v1.4.1 h1:s0hze+J0196ZfEMTs80N7UlFt0BDuQ7Q+JDnHiMWKdA= +github.com/spf13/cast v1.4.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= github.com/spf13/cobra v1.0.1-0.20201006035406-b97b5ead31f7/go.mod h1:yk5b0mALVusDL5fMM6Rd1wgnoO5jUPhwsQ6LQAJTidQ= -github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJQMI= github.com/spf13/cobra v1.2.1 h1:+KmjbUw1hriSNMF55oPrkZcb27aECyrj8V2ytv7kWDw= github.com/spf13/cobra v1.2.1/go.mod h1:ExllRjgxM/piMAM+3tAZvg8fsklGAf3tPfi+i8t68Nk= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= @@ -960,10 +766,9 @@ 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/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= -github.com/spf13/viper v1.7.1/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= -github.com/spf13/viper v1.8.1 h1:Kq1fyeebqsBfbjZj4EL7gj2IO0mMaiyjYUWcUsl2O44= github.com/spf13/viper v1.8.1/go.mod h1:o0Pch8wJ9BVSWGQMbra6iw0oQ5oktSIBaujf1rJH9Ns= -github.com/ssgreg/nlreturn/v2 v2.1.0/go.mod h1:E/iiPB78hV7Szg2YfRgyIrk1AD6JVMTRkkxBiELzh2I= +github.com/spf13/viper v1.9.0 h1:yR6EXjTp0y0cLN8OZg1CRZmOBdI88UcGkhgyJhu6nZk= +github.com/spf13/viper v1.9.0/go.mod h1:+i6ajR7OX2XaiBkrcZJFK21htRk7eDeLg7+O6bhUPP4= github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= @@ -971,7 +776,6 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/objx v0.3.0 h1:NGXK3lHquSN08v5vWalVI/L8XU9hdzE/G6xsrze47As= -github.com/stretchr/objx v0.3.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/testify v1.2.1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= @@ -983,55 +787,23 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= -github.com/tailscale/certstore v0.0.0-20210528134328-066c94b793d3/go.mod h1:2P+hpOwd53e7JMX/L4f3VXkv1G+33ES6IWZSrkIeWNs= -github.com/tailscale/depaware v0.0.0-20201214215404-77d1e9757027/go.mod h1:p9lPsd+cx33L3H9nNoecRRxPssFKUwwI50I3pZ0yT+8= -github.com/tailscale/goexpect v0.0.0-20210902213824-6e8c725cea41/go.mod h1:/roCdA6gg6lQyw/Oz6gIIGu3ggJKYhF+WC/AQReE5XQ= -github.com/tailscale/goupnp v1.0.1-0.20210804011211-c64d0f06ea05/go.mod h1:PdCqy9JzfWMJf1H5UJW2ip33/d4YkoKN0r67yKH1mG8= -github.com/tailscale/hujson v0.0.0-20200924210142-dde312d0d6a2/go.mod h1:STqf+YV0ADdzk4ejtXFsGqDpATP9JoL0OB+hiFQbkdE= -github.com/tailscale/hujson v0.0.0-20210923003652-c3758b31534b h1:bvys7zUACfrQZBUAinXREfu9jUgq6KcNQcQnUkzl3yc= -github.com/tailscale/hujson v0.0.0-20210923003652-c3758b31534b/go.mod h1:iTDXJsA6A2wNNjurgic2rk+is6uzU4U2NLm4T+edr6M= -github.com/tailscale/netlink v1.1.1-0.20211101221916-cabfb018fe85/go.mod h1:NzVQi3Mleb+qzq8VmcWpSkcSYxXIg0DkI6XDzpVkhJ0= -github.com/tcnksm/go-httpstat v0.2.0/go.mod h1:s3JVJFtQxtBEBC9dwcdTTXS9xFnM3SXAZwPG41aurT8= +github.com/tailscale/hujson v0.0.0-20211105212140-3a0adc019d83 h1:f7nwzdAHTUUOJjHZuDvLz9CEAlUM228amCRvwzlPvsA= +github.com/tailscale/hujson v0.0.0-20211105212140-3a0adc019d83/go.mod h1:iTDXJsA6A2wNNjurgic2rk+is6uzU4U2NLm4T+edr6M= github.com/tcnksm/go-latest v0.0.0-20170313132115-e3007ae9052e h1:IWllFTiDjjLIf2oeKxpIUmtiDV5sn71VgeQgg6vcE7k= github.com/tcnksm/go-latest v0.0.0-20170313132115-e3007ae9052e/go.mod h1:d7u6HkTYKSv5m6MCKkOQlHwaShTMl3HjqSGW3XtVhXM= -github.com/tdakkota/asciicheck v0.0.0-20200416190851-d7f85be797a2/go.mod h1:yHp0ai0Z9gUljN3o0xMhYJnH/IcvkdTBOX2fmJ93JEM= -github.com/tdakkota/asciicheck v0.0.0-20200416200610-e657995f937b/go.mod h1:yHp0ai0Z9gUljN3o0xMhYJnH/IcvkdTBOX2fmJ93JEM= -github.com/tetafro/godot v1.3.0/go.mod h1:/7NLHhv08H1+8DNj0MElpAACw1ajsCuf3TKNQxA5S+0= -github.com/tetafro/godot v1.3.2/go.mod h1:ah7jjYmOMnIjS9ku2krapvGQrFNtTLo9Z/qB3dGU1eU= -github.com/timakin/bodyclose v0.0.0-20190930140734-f7f2e9bca95e/go.mod h1:Qimiffbc6q9tBWlVV6x0P9sat/ao1xEkREYPPj9hphk= -github.com/timakin/bodyclose v0.0.0-20200424151742-cb6215831a94/go.mod h1:Qimiffbc6q9tBWlVV6x0P9sat/ao1xEkREYPPj9hphk= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/tomarrell/wrapcheck v0.0.0-20200807122107-df9e8bcb914d/go.mod h1:yiFB6fFoV7saXirUGfuK+cPtUh4NX/Hf5y2WC2lehu0= -github.com/tomarrell/wrapcheck v0.0.0-20201130113247-1683564d9756/go.mod h1:yiFB6fFoV7saXirUGfuK+cPtUh4NX/Hf5y2WC2lehu0= -github.com/tommy-muehle/go-mnd v1.3.1-0.20200224220436-e6f9a994e8fa/go.mod h1:dSUh0FtTP8VhvkL1S+gUR1OKd9ZnSaozuI6r3m6wOig= -github.com/toqueteos/webbrowser v1.2.0/go.mod h1:XWoZq4cyp9WeUeak7w7LXRUQf1F1ATJMir8RTqb4ayM= github.com/twitchtv/twirp v7.1.0+incompatible/go.mod h1:RRJoFSAmTEh2weEqWtpPE3vFK5YBhA6bqp2l1kfCC5A= -github.com/u-root/uio v0.0.0-20210528114334-82958018845c/go.mod h1:LpEX5FO/cB+WF4TYGY1V5qktpaZLkKkSegbr0V4eYXA= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= -github.com/ugorji/go v1.2.6 h1:tGiWC9HENWE2tqYycIqFTNorMmFRVhNwCpDOpWqnk8E= github.com/ugorji/go v1.2.6/go.mod h1:anCg0y61KIhDlPZmnH+so+RQbysYVyDko0IMgJv0Nn0= github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= github.com/ugorji/go/codec v1.2.6 h1:7kbGefxLoDBuYXOms4yD7223OpNMMPNPZxXk5TvFcyQ= github.com/ugorji/go/codec v1.2.6/go.mod h1:V6TCNZ4PHqoHGFZuSG1W8nrCzzdgA2DozYxWFFpvxTw= -github.com/ulikunitz/xz v0.5.7/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= -github.com/ulikunitz/xz v0.5.10/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= -github.com/ultraware/funlen v0.0.3/go.mod h1:Dp4UiAus7Wdb9KUZsYWZEWiRzGuM2kXM1lPbfaF6xhA= -github.com/ultraware/whitespace v0.0.4/go.mod h1:aVMh/gQve5Maj9hQ/hg+F75lr/X5A89uZnzAmWSineA= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= -github.com/uudashr/gocognit v1.0.1/go.mod h1:j44Ayx2KW4+oB6SWMv8KsmHzZrOInQav7D3cQMJ5JUM= -github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= -github.com/valyala/fasthttp v1.16.0/go.mod h1:YOKImeEosDdBPnxc0gy7INqi3m1zK6A+xl6TwOBhHCA= -github.com/valyala/quicktemplate v1.6.3/go.mod h1:fwPzK2fHuYEODzJ9pkw0ipCPNHZ2tD5KW4lOuSdPKzY= -github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE= -github.com/vishvananda/netlink v1.1.1-0.20211101163509-b10eb8fe5cf6/go.mod h1:twkDnbuQxJYemMlGd4JFIcuhgX83tXhKS2B/PRMpOho= github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU= -github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0= -github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4= -github.com/xanzy/ssh-agent v0.3.0/go.mod h1:3s9xbODqPuuhK9JV1R321M/FlMZSBvE5aY6eAcqrDh0= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo= github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= @@ -1039,7 +811,6 @@ github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHo github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74= github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= -github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8/go.mod h1:HUYIGzjTL3rfEspMxjDjgmT5uz5wzYJKVo23qUhYTos= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 h1:QldyIu/L63oPpyvQmHgvgickp1Yw510KJOqX7H24mg8= github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778/go.mod h1:2MuV+tbUrU1zIOPMxZ5EncGwgmMJsa+9ucAQZXxsObs= @@ -1051,7 +822,6 @@ github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9dec github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= -github.com/ziutek/telnet v0.0.0-20180329124119-c3b780dc415b/go.mod h1:IZpXDfkJ6tWD3PhBK5YzgQT+xJWh7OsdwiG8hA2MkO4= github.com/zsais/go-gin-prometheus v0.1.0 h1:bkLv1XCdzqVgQ36ScgRi09MA2UC1t3tAB6nsfErsGO4= github.com/zsais/go-gin-prometheus v0.1.0/go.mod h1:Slirjzuz8uM8Cw0jmPNqbneoqcUtY2GGjn2bEd4NRLY= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= @@ -1086,19 +856,14 @@ go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ= go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= -go4.org/intern v0.0.0-20210108033219-3eb7198706b2/go.mod h1:vLqJ+12kCw61iCWsPto0EOHhBS+o4rO5VIucbc9g2Cc= go4.org/intern v0.0.0-20211027215823-ae77deb06f29 h1:UXLjNohABv4S58tHmeuIZDO6e3mHpW2Dx33gaNt03LE= go4.org/intern v0.0.0-20211027215823-ae77deb06f29/go.mod h1:cS2ma+47FKrLPdXFpr7CuxiTW3eyJbWew4qx0qtQWDA= -go4.org/mem v0.0.0-20201119185036-c04c5a6ff174/go.mod h1:reUoABIJ9ikfM5sgtSF3Wushcza7+WeD01VB9Lirh3g= go4.org/mem v0.0.0-20210711025021-927187094b94 h1:OAAkygi2Js191AJP1Ds42MhJRgeofeKGjuoUqNp1QC4= go4.org/mem v0.0.0-20210711025021-927187094b94/go.mod h1:reUoABIJ9ikfM5sgtSF3Wushcza7+WeD01VB9Lirh3g= -go4.org/unsafe/assume-no-moving-gc v0.0.0-20201222175341-b30ae309168e/go.mod h1:FftLjUGFEDu5k8lt0ddY+HcrH/qU/0qk+H8j9/nTl3E= -go4.org/unsafe/assume-no-moving-gc v0.0.0-20201222180813-1025295fd063/go.mod h1:FftLjUGFEDu5k8lt0ddY+HcrH/qU/0qk+H8j9/nTl3E= go4.org/unsafe/assume-no-moving-gc v0.0.0-20211027215541-db492cf91b37 h1:Tx9kY6yUkLge/pFG7IEMwDZy6CS2ajFc9TvQdPCW0uA= go4.org/unsafe/assume-no-moving-gc v0.0.0-20211027215541-db492cf91b37/go.mod h1:FftLjUGFEDu5k8lt0ddY+HcrH/qU/0qk+H8j9/nTl3E= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= @@ -1108,25 +873,18 @@ golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191205180655-e7c4368fe9dd/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= -golang.org/x/crypto v0.0.0-20201208171446-5f87f3452ae9/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= -golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= -golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20211117183948-ae814b36b871 h1:/pEO3GD/ABYAjuakUS6xSEmmlyVS4kxBNkeA9tLJiTI= -golang.org/x/crypto v0.0.0-20211117183948-ae814b36b871/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20211202192323-5770296d904e h1:MUP6MR3rJ7Gk9LEia0LP2ytiH6MuCfs7qYz+47jGdD8= +golang.org/x/crypto v0.0.0-20211202192323-5770296d904e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1176,7 +934,6 @@ golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190419010253-1f3472d942ba/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= @@ -1186,9 +943,8 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191002035440-2ec189313ef0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191007182048-72f939374954/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -1201,31 +957,25 @@ golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/ golang.org/x/net v0.0.0-20200505041828-1ed23360d12c/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20201216054612-986b41b23924/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210903162142-ad29c8ab022f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211101193420-4a448f8816b3/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211111083644-e5c967477495/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 h1:CIJ76btIcR3eFI5EgSo6k1qKw9KJexJuRLI9G7Hp5wE= -golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211205041911-012df41ee64c h1:7SfqwP5fxEtl/P02w5IhKc86ziJ+A25yFrkVgoy2FT8= +golang.org/x/net v0.0.0-20211205041911-012df41ee64c/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1240,6 +990,8 @@ golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210427180440-81ed05c6b58c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 h1:RerP+noqYHUQ8CMRcPlC2nvTa4dcBIjegkuWdcUDuqg= golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= @@ -1264,32 +1016,27 @@ golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190221075227-b4e8571b14e0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190411185658-b44545bcd369/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190418153312-f0ce4c0180be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190606122018-79a91cf218c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191113165036-4c7a9d0fe056/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1297,9 +1044,9 @@ golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1308,62 +1055,47 @@ golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200728102440-3e129f6d46b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200909081042-eff7692f9009/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201009025420-dfb3f7c4e634/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201018230417-eeed37f84f13/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201101102859-da207088b7d1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201109165425-215b40eba54c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201118182958-a01c418693c7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201207223542-d4d67f95c62d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201218084310-7d0127a74742/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210110051926-789bb1bd4061/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210123111255-9b0068b26619/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210216163648-f7da38b97c65/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210301091718-77cc2087c03b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210525143221-35b2ab0089ea/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210906170528-6f6e22806c34/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211110154304-99a53858aa08/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211124211545-fe61309f8881 h1:TyHqChC80pFkXWraUUf6RuB5IqFdQieMLwwCJokV2pc= -golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/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-20211205182925-97ca703d548d h1:FjkYO/PPp4Wi0EAUOVLxePm7qVW4r4ctbWpURyuOD0E= +golang.org/x/sys v0.0.0-20211205182925-97ca703d548d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210503060354-a79de5458b56/go.mod h1:tfny5GFUkzUvx4ps4ajbZsCe5lw1metzhBm9T3x7oIY= -golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b h1:9zKuko04nR4gjZ4+DNjHqRlAJqbJETHwiNKDqTfOjfE= golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1378,21 +1110,14 @@ golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxb golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20210611083556-38a9dc6acbc6/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190110163146-51295c7ec13a/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190221204921-83362c3779f5/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= -golang.org/x/tools v0.0.0-20190307163923-6a08e3108db3/go.mod h1:25r3+/G6/xytQM8iWZKq3Hn0kr0rgFKPUNVEL/dr3z4= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190311215038-5c2858a9cfe5/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190322203728-c1a832b0ad89/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190425163242-31fd60d6bfdc/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= @@ -1404,12 +1129,11 @@ golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgw golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190823170909-c4a336ef6a2f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20190910044552-dd2b5c81c578/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190907020128-2ca718005c18/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -1420,7 +1144,6 @@ golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapK golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200117220505-0cba7a3a9ee9/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= @@ -1430,47 +1153,28 @@ golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapK golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200324003944-a576cf524670/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= -golang.org/x/tools v0.0.0-20200410194907-79a7a3126eef/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200414032229-332987a829c3/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200422022333-3d57cf2e726e/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200426102838-f3a5411a4c3b/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200522201501-cb1345f3a375/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200622203043-20e05c1c8ffa/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200624225443-88f3c62a19ff/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200625211823-6506e20df31f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200717024301-6ddee64345a6/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200724022722-7017fd6b1305/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200731060945-b5fad4ed8dd6/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200812195022-5ae4c3c160a0/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200820010801-b793a1359eac/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200831203904-5a2aa26beb65/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= -golang.org/x/tools v0.0.0-20201001104356-43ebab892c4c/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= -golang.org/x/tools v0.0.0-20201002184944-ecd9fd270d5d/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= -golang.org/x/tools v0.0.0-20201007032633-0806396f153e/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= -golang.org/x/tools v0.0.0-20201011145850-ed2f50202694/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= -golang.org/x/tools v0.0.0-20201013201025-64a9e34f3752/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201118003311-bd56c0adb394/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201121010211-780cb80bd7fb/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201124202034-299f270db459/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201211185031-d93e913c1a58/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= +golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo= golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1480,10 +1184,6 @@ golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.zx2c4.com/wintun v0.0.0-20211104114900-415007cec224/go.mod h1:deeaetjYA+DHMHg+sMSMI58GrEteJUUzzw7en6TJQcI= -golang.zx2c4.com/wireguard v0.0.0-20210905140043-2ef39d47540c/go.mod h1:laHzsbfMhGSobUmruXWAyMKKHSqvIcrqZJMyHD+/3O8= -golang.zx2c4.com/wireguard v0.0.0-20211116201604-de7c702ace45/go.mod h1:evxZIqfCetExY5piKXGAxJYwvXWkps9zTCkWpkoGFxw= -golang.zx2c4.com/wireguard/windows v0.4.10/go.mod h1:v7w/8FC48tTBm1IzScDVPEEb0/GjLta+T0ybpP9UWRg= google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= @@ -1508,6 +1208,12 @@ google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjR google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= google.golang.org/api v0.44.0/go.mod h1:EBOGZqzyhtvMDoxwS97ctnh0zUmYY6CxqXsc1AvkYD8= +google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo= +google.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4= +google.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw= +google.golang.org/api v0.51.0/go.mod h1:t4HdrdoNgyN5cbEfm7Lum0lcLDLiise1F8qDKX00sOU= +google.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6z3k= +google.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -1564,7 +1270,18 @@ google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= google.golang.org/genproto v0.0.0-20210426193834-eac7f76ac494/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= +google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20210604141403-392c879c8b08/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20210608205507-b6d2f5bf0d7d/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= +google.golang.org/genproto v0.0.0-20210713002101-d411969a0d9a/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= +google.golang.org/genproto v0.0.0-20210716133855-ce7ef5c701ea/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= +google.golang.org/genproto v0.0.0-20210728212813-7823e685a01f/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= +google.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= +google.golang.org/genproto v0.0.0-20210813162853-db860fec028c/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w= +google.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= google.golang.org/genproto v0.0.0-20211104193956-4c6863e31247 h1:ZONpjmFT5e+I/0/xE3XXbG5OIvX2hRYzol04MhKBl2E= google.golang.org/genproto v0.0.0-20211104193956-4c6863e31247/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= @@ -1594,7 +1311,10 @@ google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAG google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= +google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= google.golang.org/grpc v1.42.0 h1:XT2/MFpuPFsEX2fWh3YQtHkZ+WYZFQRfaUgLZYj/p6A= google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= @@ -1623,7 +1343,6 @@ gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLks gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= @@ -1632,8 +1351,10 @@ gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMy gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s= gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/ini.v1 v1.62.0 h1:duBzk771uxoUuOlyRLkHsygud9+5lrlGjdFBb4mSKDU= gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/ini.v1 v1.63.2/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/ini.v1 v1.66.2 h1:XfR1dOYubytKy4Shzc2LHrrGhU0lDCfDGG1yLPmpgsI= +gopkg.in/ini.v1 v1.66.2/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/square/go-jose.v2 v2.5.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/square/go-jose.v2 v2.6.0 h1:NGk74WTnPKBNUhNzQX7PYcTLUjoq7mzKk2OKbvwk2iI= @@ -1651,7 +1372,6 @@ gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gorm.io/datatypes v1.0.2 h1:ChZ5VfWGB23qEr1kZosidvG9CF9HIczwoxLhBS7Ebs4= @@ -1682,26 +1402,12 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -honnef.co/go/tools v0.0.1-2020.1.6/go.mod h1:pyyisuGw24ruLjrr1ddx39WE0y9OooInRzEYLhQB2YY= -honnef.co/go/tools v0.2.1/go.mod h1:lPVVZ2BS5TfnjLyizF7o7hv7j9/L+8cZY2hLyjP9cGY= -howett.net/plist v0.0.0-20181124034731-591f970eefbb/go.mod h1:vMygbs4qMhSZSc4lCUl2OEE+rDiIIJAIdR4m7MiMcm0= -inet.af/netaddr v0.0.0-20210515010201-ad03edc7c841/go.mod h1:z0nx+Dh+7N7CC8V5ayHtHGpZpxLQZZxkIaaz6HN65Ls= inet.af/netaddr v0.0.0-20211027220019-c74959edd3b6 h1:acCzuUSQ79tGsM/O50VRFySfMm19IoMKL+sZztZkCxw= inet.af/netaddr v0.0.0-20211027220019-c74959edd3b6/go.mod h1:y3MGhcFMlh0KZPMuXXow8mpjxxAk3yoDNsp4cQz54i8= -inet.af/netstack v0.0.0-20211101182044-1c1bcf452982/go.mod h1:fG3G1dekmK8oDX3iVzt8c0zICLMLSN8SjdxbXVt0WjU= -inet.af/peercred v0.0.0-20210318190834-4259e17bb763/go.mod h1:FjawnflS/udxX+SvpsMgZfdqx2aykOlkISeAsADi5IU= -inet.af/wf v0.0.0-20210516214145-a5343001b756/go.mod h1:ViGMZRA6+RA318D7GCncrjv5gHUrPYrNDejjU12tikA= -mvdan.cc/gofumpt v0.0.0-20200802201014-ab5a8192947d/go.mod h1:bzrjFmaD6+xqohD3KYP0H2FEuxknnBmyyOxdhLdaIws= -mvdan.cc/gofumpt v0.0.0-20201129102820-5c11c50e9475/go.mod h1:E4LOcu9JQEtnYXtB1Y51drqh2Qr2Ngk9J3YrRCwcbd0= -mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed/go.mod h1:Xkxe497xwlCKkIaQYRfC7CSLworTXY9RMqwhhCm+8Nc= -mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b/go.mod h1:2odslEg/xrtNQqCYg2/jCoyKnw3vv5biOc3JnIcYfL4= -mvdan.cc/unparam v0.0.0-20200501210554-b37ab49443f7/go.mod h1:HGC5lll35J70Y5v7vCGb9oLhHoScFwkHDJm/05RdSTc= -nhooyr.io/websocket v1.8.7/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= -software.sslmate.com/src/go-pkcs12 v0.0.0-20180114231543-2291e8f0f237/go.mod h1:/xvNRWUqm0+/ZMiF4EX00vrSCMsE4/NHb+Pt3freEeQ= sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= -tailscale.com v1.18.1 h1:3hkMsdpREdz2w0O3YcmOgJkl95ChTT4Dje7wq8prD/E= -tailscale.com v1.18.1/go.mod h1:XzG4o2vtYFkVvmJWPaTGSaOzqlKSRx2WU+aJbrxaVE0= +tailscale.com v1.20.3 h1:C3g2AgmQaOi0YT5dAal9mslugPXMxwj0EXY7YfL2QrA= +tailscale.com v1.20.3/go.mod h1:kjVy3ji2OH5lZhPLIIRacoY3CN4Bo3Yyb2mtoM8nfJ4= diff --git a/integration_test.go b/integration_test.go index fc71ed15..0379429e 100644 --- a/integration_test.go +++ b/integration_test.go @@ -28,7 +28,7 @@ import ( "tailscale.com/ipn/ipnstate" ) -var tailscaleVersions = []string{"1.20.0", "1.18.2", "1.16.2", "1.14.3", "1.12.3"} +var tailscaleVersions = []string{"1.20.2", "1.18.2", "1.16.2", "1.14.3", "1.12.3"} type TestNamespace struct { count int From b4f8961e442fe8fec34701f7e6a5cc7d9d1304d0 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Fri, 28 Jan 2022 18:58:22 +0000 Subject: [PATCH 287/300] Make Unix socket permissions configurable --- acls.go | 3 +++ app.go | 9 ++++++++- cmd/headscale/cli/utils.go | 21 ++++++++++++++++++++- cmd/headscale/headscale_test.go | 2 ++ config-example.yaml | 1 + 5 files changed, 34 insertions(+), 2 deletions(-) diff --git a/acls.go b/acls.go index 4017e28e..1d54b26d 100644 --- a/acls.go +++ b/acls.go @@ -25,8 +25,11 @@ const ( ) const ( + Base8 = 8 Base10 = 10 BitSize16 = 16 + BitSize32 = 32 + BitSize64 = 64 portRangeBegin = 0 portRangeEnd = 65535 expectedTokenItems = 2 diff --git a/app.go b/app.go index b9d570c5..7ea76b2e 100644 --- a/app.go +++ b/app.go @@ -6,6 +6,7 @@ import ( "errors" "fmt" "io" + "io/fs" "net" "net/http" "net/url" @@ -95,7 +96,8 @@ type Config struct { DNSConfig *tailcfg.DNSConfig - UnixSocket string + UnixSocket string + UnixSocketPermission fs.FileMode OIDC OIDCConfig @@ -426,6 +428,11 @@ func (h *Headscale) Serve() error { return fmt.Errorf("failed to set up gRPC socket: %w", err) } + // Change socket permissions + if err := os.Chmod(h.cfg.UnixSocket, h.cfg.UnixSocketPermission); err != nil { + return fmt.Errorf("failed change permission of gRPC socket: %w", err) + } + // Handle common process-killing signals so we can gracefully shut down: sigc := make(chan os.Signal, 1) signal.Notify(sigc, os.Interrupt, syscall.SIGTERM) diff --git a/cmd/headscale/cli/utils.go b/cmd/headscale/cli/utils.go index a4856642..c2016271 100644 --- a/cmd/headscale/cli/utils.go +++ b/cmd/headscale/cli/utils.go @@ -5,10 +5,12 @@ import ( "encoding/json" "errors" "fmt" + "io/fs" "net/url" "os" "path/filepath" "regexp" + "strconv" "strings" "time" @@ -23,6 +25,10 @@ import ( "tailscale.com/types/dnstype" ) +const ( + PermissionFallback = 0o700 +) + func LoadConfig(path string) error { viper.SetConfigName("config") if path == "" { @@ -48,6 +54,7 @@ func LoadConfig(path string) error { viper.SetDefault("dns_config", nil) viper.SetDefault("unix_socket", "/var/run/headscale.sock") + viper.SetDefault("unix_socket_permission", "0o770") viper.SetDefault("cli.insecure", false) viper.SetDefault("cli.timeout", "5s") @@ -257,7 +264,8 @@ func getHeadscaleConfig() headscale.Config { ACMEEmail: viper.GetString("acme_email"), ACMEURL: viper.GetString("acme_url"), - UnixSocket: viper.GetString("unix_socket"), + UnixSocket: viper.GetString("unix_socket"), + UnixSocketPermission: GetFileMode("unix_socket_permission"), OIDC: headscale.OIDCConfig{ Issuer: viper.GetString("oidc.issuer"), @@ -448,3 +456,14 @@ func loadOIDCMatchMap() map[string]string { return strMap } + +func GetFileMode(key string) fs.FileMode { + modeStr := viper.GetString(key) + + mode, err := strconv.ParseUint(modeStr, headscale.Base8, headscale.BitSize64) + if err != nil { + return PermissionFallback + } + + return fs.FileMode(mode) +} diff --git a/cmd/headscale/headscale_test.go b/cmd/headscale/headscale_test.go index 0b56a073..218e458e 100644 --- a/cmd/headscale/headscale_test.go +++ b/cmd/headscale/headscale_test.go @@ -1,6 +1,7 @@ package main import ( + "io/fs" "io/ioutil" "os" "path/filepath" @@ -60,6 +61,7 @@ func (*Suite) TestConfigLoading(c *check.C) { c.Assert(viper.GetString("tls_letsencrypt_listen"), check.Equals, ":http") c.Assert(viper.GetString("tls_letsencrypt_challenge_type"), check.Equals, "HTTP-01") c.Assert(viper.GetStringSlice("dns_config.nameservers")[0], check.Equals, "1.1.1.1") + c.Assert(cli.GetFileMode("unix_socket_permission"), check.Equals, fs.FileMode(0o770)) } func (*Suite) TestDNSConfigLoading(c *check.C) { diff --git a/config-example.yaml b/config-example.yaml index 3301669d..3a867a36 100644 --- a/config-example.yaml +++ b/config-example.yaml @@ -149,6 +149,7 @@ dns_config: # Note: for local development, you probably want to change this to: # unix_socket: ./headscale.sock unix_socket: /var/run/headscale.sock +unix_socket_permission: "0770" # # headscale supports experimental OpenID connect support, # it is still being tested and might have some bugs, please From 25ccf5ef1808375a17337e9f1a2562858c5edb7e Mon Sep 17 00:00:00 2001 From: Csaba Sarkadi Date: Sun, 16 Jan 2022 11:59:03 +0100 Subject: [PATCH 288/300] PollNetMapStream: do not create any rows during long-poll operation --- machine.go | 8 ++++++ poll.go | 84 +++++++++++++++++++++++++++++++++++++++++++----------- 2 files changed, 75 insertions(+), 17 deletions(-) diff --git a/machine.go b/machine.go index d58c9c5c..de1764e1 100644 --- a/machine.go +++ b/machine.go @@ -319,6 +319,14 @@ func (h *Headscale) DeleteMachine(machine *Machine) error { return h.RequestMapUpdates(namespaceID) } +func (h *Headscale) TouchMachine(machine *Machine) error { + return h.db.Updates(Machine{ + ID: machine.ID, + LastSeen: machine.LastSeen, + LastSuccessfulUpdate: machine.LastSuccessfulUpdate, + }).Error +} + // HardDeleteMachine hard deletes a Machine from the database. func (h *Headscale) HardDeleteMachine(machine *Machine) error { err := h.RemoveSharedMachineFromAllNamespaces(machine) diff --git a/poll.go b/poll.go index 10389038..d7aa12e9 100644 --- a/poll.go +++ b/poll.go @@ -102,7 +102,7 @@ func (h *Headscale) PollNetMapHandler(ctx *gin.Context) { machine.Endpoints = datatypes.JSON(endpoints) machine.LastSeen = &now } - h.db.Save(&machine) + h.db.Updates(machine) data, err := h.getMapResponse(machineKey, req, machine) if err != nil { @@ -291,6 +291,10 @@ func (h *Headscale) PollNetMapStream( Str("channel", "pollData"). Err(err). Msg("Cannot update machine from database") + + // client has been removed from database + // since the stream opened, terminate connection. + return false } now := time.Now().UTC() machine.LastSeen = &now @@ -299,13 +303,22 @@ func (h *Headscale) PollNetMapStream( Set(float64(now.Unix())) machine.LastSuccessfulUpdate = &now - h.db.Save(&machine) - log.Trace(). - Str("handler", "PollNetMapStream"). - Str("machine", machine.Name). - Str("channel", "pollData"). - Int("bytes", len(data)). - Msg("Machine entry in database updated successfully after sending pollData") + err = h.TouchMachine(machine) + if err != nil { + log.Error(). + Str("handler", "PollNetMapStream"). + Str("machine", machine.Name). + Str("channel", "pollData"). + Err(err). + Msg("Cannot update machine LastSuccessfulUpdate") + } else { + log.Trace(). + Str("handler", "PollNetMapStream"). + Str("machine", machine.Name). + Str("channel", "pollData"). + Int("bytes", len(data)). + Msg("Machine entry in database updated successfully after sending pollData") + } return true @@ -344,16 +357,29 @@ func (h *Headscale) PollNetMapStream( Str("channel", "keepAlive"). Err(err). Msg("Cannot update machine from database") + + // client has been removed from database + // since the stream opened, terminate connection. + return false } now := time.Now().UTC() machine.LastSeen = &now - h.db.Save(&machine) - log.Trace(). - Str("handler", "PollNetMapStream"). - Str("machine", machine.Name). - Str("channel", "keepAlive"). - Int("bytes", len(data)). - Msg("Machine updated successfully after sending keep alive") + err = h.TouchMachine(machine) + if err != nil { + log.Error(). + Str("handler", "PollNetMapStream"). + Str("machine", machine.Name). + Str("channel", "keepAlive"). + Err(err). + Msg("Cannot update machine LastSeen") + } else { + log.Trace(). + Str("handler", "PollNetMapStream"). + Str("machine", machine.Name). + Str("channel", "keepAlive"). + Int("bytes", len(data)). + Msg("Machine updated successfully after sending keep alive") + } return true @@ -417,6 +443,10 @@ func (h *Headscale) PollNetMapStream( Str("channel", "update"). Err(err). Msg("Cannot update machine from database") + + // client has been removed from database + // since the stream opened, terminate connection. + return false } now := time.Now().UTC() @@ -424,7 +454,15 @@ func (h *Headscale) PollNetMapStream( Set(float64(now.Unix())) machine.LastSuccessfulUpdate = &now - h.db.Save(&machine) + err = h.TouchMachine(machine) + if err != nil { + log.Error(). + Str("handler", "PollNetMapStream"). + Str("machine", machine.Name). + Str("channel", "update"). + Err(err). + Msg("Cannot update machine LastSuccessfulUpdate") + } } else { log.Trace(). Str("handler", "PollNetMapStream"). @@ -452,10 +490,22 @@ func (h *Headscale) PollNetMapStream( Str("channel", "Done"). Err(err). Msg("Cannot update machine from database") + + // client has been removed from database + // since the stream opened, terminate connection. + return false } now := time.Now().UTC() machine.LastSeen = &now - h.db.Save(&machine) + err = h.TouchMachine(machine) + if err != nil { + log.Error(). + Str("handler", "PollNetMapStream"). + Str("machine", machine.Name). + Str("channel", "Done"). + Err(err). + Msg("Cannot update machine LastSeen") + } log.Trace(). Str("handler", "PollNetMapStream"). From 761147ea3be88ea0531f688ed2e89840f124d92d Mon Sep 17 00:00:00 2001 From: Csaba Sarkadi Date: Fri, 28 Jan 2022 21:48:23 +0100 Subject: [PATCH 289/300] update CHANGELOG --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 38904b0a..3d4f4aa6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ **TBD (TBD):** +- Fixed issue where hosts deleted from control server may be written back to the database, as long as they are connected to the control server [#278]((https://github.com/juanfont/headscale/pull/278) +) + **0.12.3 (2022-01-13):** **Changes**: From fbe5054a6707ce8a4020fd773061e2284a6ef6d7 Mon Sep 17 00:00:00 2001 From: Csaba Sarkadi Date: Fri, 28 Jan 2022 22:00:13 +0100 Subject: [PATCH 290/300] fixup! update CHANGELOG --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3d4f4aa6..6541b638 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ **TBD (TBD):** -- Fixed issue where hosts deleted from control server may be written back to the database, as long as they are connected to the control server [#278]((https://github.com/juanfont/headscale/pull/278) +- Fixed issue where hosts deleted from control server may be written back to the database, as long as they are connected to the control server [#278](https://github.com/juanfont/headscale/pull/278) ) **0.12.3 (2022-01-13):** From 17411b65f34334c18b446126a8f0d01e488026a0 Mon Sep 17 00:00:00 2001 From: Csaba Sarkadi Date: Sat, 29 Jan 2022 13:48:14 +0100 Subject: [PATCH 291/300] fixup! fixup! update CHANGELOG prettier changes --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6541b638..f823f0c7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,7 @@ **TBD (TBD):** - Fixed issue where hosts deleted from control server may be written back to the database, as long as they are connected to the control server [#278](https://github.com/juanfont/headscale/pull/278) -) + ) **0.12.3 (2022-01-13):** From bb27c80bad828935b6dcefff56417ce8a6dfef50 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Sat, 29 Jan 2022 14:31:42 +0000 Subject: [PATCH 292/300] Update CHANGELOG.md --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 38904b0a..e538f5fe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,11 @@ **TBD (TBD):** +**Changes**: + +- Make gRPC Unix Socket permissions configurable [#292](https://github.com/juanfont/headscale/pull/292) +- Trim whitespace before reading Private Key from file [#289](https://github.com/juanfont/headscale/pull/289) + **0.12.3 (2022-01-13):** **Changes**: From 7aace7eb6b0bf933e785ddfd2e99afc6a7761b7e Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Sat, 29 Jan 2022 14:33:12 +0000 Subject: [PATCH 293/300] Update CHANGELOG.md --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 38904b0a..99f4849a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ **TBD (TBD):** +**Changes**: + +- Add new command to generate a private key for `headscale` [#290](https://github.com/juanfont/headscale/pull/290) + **0.12.3 (2022-01-13):** **Changes**: From 2f576b2fb154b6b2314d4885b77629c16244c54b Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Sat, 29 Jan 2022 20:04:56 +0000 Subject: [PATCH 294/300] Tag 0.12.4 in CHANGELOG --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9ba96eab..e9ac7191 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,10 @@ **Changes**: +**0.12.4 (2022-01-29):** + +**Changes**: + - Make gRPC Unix Socket permissions configurable [#292](https://github.com/juanfont/headscale/pull/292) - Trim whitespace before reading Private Key from file [#289](https://github.com/juanfont/headscale/pull/289) - Add new command to generate a private key for `headscale` [#290](https://github.com/juanfont/headscale/pull/290) From 4e63bba4fe9484fe508694bfad92adbaa9c0cb7e Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Sun, 30 Jan 2022 08:55:41 +0000 Subject: [PATCH 295/300] Only compat go 1.17 in go mod tidy --- .goreleaser.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.goreleaser.yml b/.goreleaser.yml index 5073b57c..a492860c 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -2,7 +2,7 @@ # Make sure to check the documentation at http://goreleaser.com before: hooks: - - go mod tidy + - go mod tidy -compat=1.17 release: prerelease: auto From e0c22a414b0dac1f3fa698c1f3170df554af235b Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Sun, 30 Jan 2022 08:56:28 +0000 Subject: [PATCH 296/300] Remove wrong comment --- .goreleaser.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.goreleaser.yml b/.goreleaser.yml index a492860c..b240ab0c 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -1,5 +1,4 @@ -# This is an example .goreleaser.yml file with some sane defaults. -# Make sure to check the documentation at http://goreleaser.com +--- before: hooks: - go mod tidy -compat=1.17 From 71ab4c9b2cce7c2aaf4fbc14181c7551b98c4e3c Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Sun, 30 Jan 2022 08:59:25 +0000 Subject: [PATCH 297/300] Fix type according to config schema --- .goreleaser.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.goreleaser.yml b/.goreleaser.yml index b240ab0c..d1dec26f 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -32,7 +32,7 @@ builds: goarch: - arm goarm: - - 7 + - "7" env: - CC=arm-linux-gnueabihf-gcc - CXX=arm-linux-gnueabihf-g++ From 1815040d9821cd2ced960e1c21ca9b867d7ab10c Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Sun, 30 Jan 2022 09:43:48 +0000 Subject: [PATCH 298/300] Set up build build avoidance This commit configures the CI to run specific parts of the CI when relevant changes has been made. This should help us not have to deal with the integration tests when we do doc/admin changes. --- .github/workflows/lint.yml | 26 ++++++++++++++++++++++++++ .github/workflows/test-integration.yml | 17 ++++++++++++----- .github/workflows/test.yml | 22 +++++++++++++++------- 3 files changed, 53 insertions(+), 12 deletions(-) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 6fb985f7..65b37f5f 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -9,7 +9,18 @@ jobs: steps: - uses: actions/checkout@v2 + - name: Get changed files + id: changed-files + uses: tj-actions/changed-files@v14.1 + with: + files: | + go.* + **/*.go + integration_test/ + config-example.yaml + - name: golangci-lint + if: steps.changed-files.outputs.any_changed == 'true' uses: golangci/golangci-lint-action@v2 with: version: latest @@ -25,6 +36,21 @@ jobs: steps: - uses: actions/checkout@v2 + - name: Get changed files + id: changed-files + uses: tj-actions/changed-files@v14.1 + with: + files: | + **/*.md + **/*.yml + **/*.yaml + **/*.ts + **/*.js + **/*.sass + **/*.css + **/*.scss + **/*.html + - name: Prettify code uses: creyD/prettier_action@v4.0 with: diff --git a/.github/workflows/test-integration.yml b/.github/workflows/test-integration.yml index d4179ea2..c0613705 100644 --- a/.github/workflows/test-integration.yml +++ b/.github/workflows/test-integration.yml @@ -3,21 +3,28 @@ name: CI on: [pull_request] jobs: - # The "build" workflow integration-test: - # The type of runner that the job will run on runs-on: ubuntu-latest - # Steps represent a sequence of tasks that will be executed as part of the job steps: - # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - uses: actions/checkout@v2 - # Setup Go + - name: Get changed files + id: changed-files + uses: tj-actions/changed-files@v14.1 + with: + files: | + go.* + **/*.go + integration_test/ + config-example.yaml + - name: Setup Go + if: steps.changed-files.outputs.any_changed == 'true' uses: actions/setup-go@v2 with: go-version: "1.17" - name: Run Integration tests + if: steps.changed-files.outputs.any_changed == 'true' run: go test -tags integration -timeout 30m diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 651063fc..6f8ac08e 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -3,31 +3,39 @@ name: CI on: [push, pull_request] jobs: - # The "build" workflow test: - # The type of runner that the job will run on runs-on: ubuntu-latest - # Steps represent a sequence of tasks that will be executed as part of the job steps: - # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - uses: actions/checkout@v2 - # Setup Go + - name: Get changed files + id: changed-files + uses: tj-actions/changed-files@v14.1 + with: + files: | + go.* + **/*.go + integration_test/ + config-example.yaml + - name: Setup Go + if: steps.changed-files.outputs.any_changed == 'true' uses: actions/setup-go@v2 with: - go-version: "1.17" # The Go version to download (if necessary) and use. + go-version: "1.17" - # Install all the dependencies - name: Install dependencies + if: steps.changed-files.outputs.any_changed == 'true' run: | go version sudo apt update sudo apt install -y make - name: Run tests + if: steps.changed-files.outputs.any_changed == 'true' run: make test - name: Run build + if: steps.changed-files.outputs.any_changed == 'true' run: make From 991175f2aa36fb6a7f99d029cde6b1cf039cab36 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Sun, 30 Jan 2022 09:49:15 +0000 Subject: [PATCH 299/300] Add depth and avoidance for build --- .github/workflows/build.yml | 15 +++++++++++++++ .github/workflows/lint.yml | 3 +++ .github/workflows/test-integration.yml | 1 + .github/workflows/test.yml | 1 + 4 files changed, 20 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 589d8c58..b8ea7d6c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -15,21 +15,36 @@ jobs: steps: - uses: actions/checkout@v2 + - name: Get changed files + id: changed-files + uses: tj-actions/changed-files@v14.1 + with: + fetch-depth: 2 + files: | + go.* + **/*.go + integration_test/ + config-example.yaml + - name: Setup Go + if: steps.changed-files.outputs.any_changed == 'true' uses: actions/setup-go@v2 with: go-version: "1.17" - name: Install dependencies + if: steps.changed-files.outputs.any_changed == 'true' run: | go version sudo apt update sudo apt install -y make - name: Run build + if: steps.changed-files.outputs.any_changed == 'true' run: make build - uses: actions/upload-artifact@v2 + if: steps.changed-files.outputs.any_changed == 'true' with: name: headscale-linux path: headscale diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 65b37f5f..1c0e86d4 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -13,6 +13,7 @@ jobs: id: changed-files uses: tj-actions/changed-files@v14.1 with: + fetch-depth: 2 files: | go.* **/*.go @@ -40,6 +41,7 @@ jobs: id: changed-files uses: tj-actions/changed-files@v14.1 with: + fetch-depth: 2 files: | **/*.md **/*.yml @@ -52,6 +54,7 @@ jobs: **/*.html - name: Prettify code + if: steps.changed-files.outputs.any_changed == 'true' uses: creyD/prettier_action@v4.0 with: prettier_options: >- diff --git a/.github/workflows/test-integration.yml b/.github/workflows/test-integration.yml index c0613705..f6eb7b48 100644 --- a/.github/workflows/test-integration.yml +++ b/.github/workflows/test-integration.yml @@ -13,6 +13,7 @@ jobs: id: changed-files uses: tj-actions/changed-files@v14.1 with: + fetch-depth: 2 files: | go.* **/*.go diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 6f8ac08e..c2859467 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -13,6 +13,7 @@ jobs: id: changed-files uses: tj-actions/changed-files@v14.1 with: + fetch-depth: 2 files: | go.* **/*.go From 0862f60ff05546a995bf68322b159900c4635c73 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Sun, 30 Jan 2022 09:54:26 +0000 Subject: [PATCH 300/300] Put depth in the correct place --- .github/workflows/build.yml | 3 ++- .github/workflows/lint.yml | 6 ++++-- .github/workflows/test-integration.yml | 3 ++- .github/workflows/test.yml | 3 ++- 4 files changed, 10 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b8ea7d6c..d92e9e6e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -14,12 +14,13 @@ jobs: steps: - uses: actions/checkout@v2 + with: + fetch-depth: 2 - name: Get changed files id: changed-files uses: tj-actions/changed-files@v14.1 with: - fetch-depth: 2 files: | go.* **/*.go diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 1c0e86d4..26a24ae7 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -8,12 +8,13 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 + with: + fetch-depth: 2 - name: Get changed files id: changed-files uses: tj-actions/changed-files@v14.1 with: - fetch-depth: 2 files: | go.* **/*.go @@ -36,12 +37,13 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 + with: + fetch-depth: 2 - name: Get changed files id: changed-files uses: tj-actions/changed-files@v14.1 with: - fetch-depth: 2 files: | **/*.md **/*.yml diff --git a/.github/workflows/test-integration.yml b/.github/workflows/test-integration.yml index f6eb7b48..9f526f97 100644 --- a/.github/workflows/test-integration.yml +++ b/.github/workflows/test-integration.yml @@ -8,12 +8,13 @@ jobs: steps: - uses: actions/checkout@v2 + with: + fetch-depth: 2 - name: Get changed files id: changed-files uses: tj-actions/changed-files@v14.1 with: - fetch-depth: 2 files: | go.* **/*.go diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index c2859467..9ce8a779 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -8,12 +8,13 @@ jobs: steps: - uses: actions/checkout@v2 + with: + fetch-depth: 2 - name: Get changed files id: changed-files uses: tj-actions/changed-files@v14.1 with: - fetch-depth: 2 files: | go.* **/*.go