Merge branch 'main' into fix-derp-example-config

This commit is contained in:
Juan Font 2021-11-24 18:57:31 +01:00 committed by GitHub
commit 45bc3f7a09
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
26 changed files with 1306 additions and 538 deletions

View File

@ -25,9 +25,6 @@ linters:
- godox
- ireturn
# In progress
- gocritic
# We should strive to enable these:
- wrapcheck
- dupl
@ -51,3 +48,9 @@ linters-settings:
- ip
- ok
- c
gocritic:
disabled-checks:
- appendAssign
# TODO(kradalby): Remove this
- ifElseChain

View File

@ -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),
}

466
api.go
View File

@ -18,7 +18,15 @@ import (
"tailscale.com/types/wgkey"
)
const reservedResponseHeaderSize = 4
const (
reservedResponseHeaderSize = 4
RegisterMethodAuthKey = "authKey"
RegisterMethodOIDC = "oidc"
RegisterMethodCLI = "cli"
ErrRegisterMethodCLIDoesNotSupportExpire = Error(
"machines registered with CLI does not support expire",
)
)
// KeyHandler provides the Headscale pub key
// Listens in /key.
@ -111,178 +119,52 @@ func (h *Headscale) RegistrationHandler(ctx *gin.Context) {
machine = &newMachine
}
if !machine.Registered && req.Auth.AuthKey != "" {
h.handleAuthKey(ctx, h.db, 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, "")
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, *machine)
return
}
ctx.Data(http.StatusOK, "application/json; charset=utf-8", respBody)
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, "")
// 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
}
machineRegistrations.WithLabelValues("update", "web", "success", machine.Namespace.Name).
Inc()
ctx.Data(http.StatusOK, "application/json; charset=utf-8", respBody)
}
// 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
}
// 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)
// 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.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)
// If the machine has AuthKey set, handle registration via PreAuthKeys
if req.Auth.AuthKey != "" {
h.handleAuthKey(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(
@ -304,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").
@ -404,19 +286,211 @@ func (h *Headscale) getMapKeepAliveResponse(
return data, nil
}
func (h *Headscale) handleMachineLogOut(
ctx *gin.Context,
machineKey wgkey.Key,
machine Machine,
) {
resp := tailcfg.RegisterResponse{}
log.Info().
Str("handler", "Registration").
Str("machine", machine.Name).
Msg("Client requested logout")
h.ExpireMachine(&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)
}
func (h *Headscale) handleMachineValidRegistration(
ctx *gin.Context,
machineKey wgkey.Key,
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, &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)
}
func (h *Headscale) handleMachineExpired(
ctx *gin.Context,
machineKey wgkey.Key,
registerRequest 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 registerRequest.Auth.AuthKey != "" {
h.handleAuthKey(ctx, machineKey, registerRequest, machine)
return
}
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").
Err(err).
Msg("Cannot encode message")
machineRegistrations.WithLabelValues("reauth", "web", "error", machine.Namespace.Name).
Inc()
ctx.String(http.StatusInternalServerError, "")
return
}
machineRegistrations.WithLabelValues("reauth", "web", "success", machine.Namespace.Name).
Inc()
ctx.Data(http.StatusOK, "application/json; charset=utf-8", respBody)
}
func (h *Headscale) handleMachineRefreshKey(
ctx *gin.Context,
machineKey wgkey.Key,
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()
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)
}
func (h *Headscale) handleMachineRegistrationNew(
ctx *gin.Context,
machineKey wgkey.Key,
registerRequest 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, "/"),
machineKey.HexString(),
)
} else {
resp.AuthURL = fmt.Sprintf("%s/register?key=%s",
strings.TrimSuffix(h.cfg.ServerURL, "/"), machineKey.HexString())
}
if !registerRequest.Expiry.IsZero() {
log.Trace().
Caller().
Str("machine", machine.Name).
Time("expiry", registerRequest.Expiry).
Msg("Non-zero expiry time requested, adding to cache")
h.requestedExpiryCache.Set(
machineKey.HexString(),
registerRequest.Expiry,
requestedExpiryCacheExpiration,
)
}
machine.NodeKey = wgkey.Key(registerRequest.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)
}
func (h *Headscale) handleAuthKey(
ctx *gin.Context,
db *gorm.DB,
idKey wgkey.Key,
reqisterRequest tailcfg.RegisterRequest,
machineKey wgkey.Key,
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").
@ -424,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").
@ -448,43 +522,53 @@ 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, registerRequest.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 = &registerRequest.Expiry
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.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 = "authKey"
db.Save(&machine)
pak.Used = true
db.Save(&pak)
h.db.Save(&pak)
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").
@ -503,6 +587,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")
}

26
app.go
View File

@ -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",
@ -96,9 +99,6 @@ type Config struct {
OIDC OIDCConfig
CLI CLIConfig
MaxMachineRegistrationDuration time.Duration
DefaultMachineRegistrationDuration time.Duration
}
type OIDCConfig struct {
@ -142,6 +142,8 @@ type Headscale struct {
oidcProvider *oidc.Provider
oauth2Config *oauth2.Config
oidcStateCache *cache.Cache
requestedExpiryCache *cache.Cache
}
// NewHeadscale returns the Headscale app.
@ -174,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()

View File

@ -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 {

View File

@ -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)

View File

@ -33,7 +33,14 @@ func init() {
}
nodeCmd.AddCommand(registerNodeCmd)
deleteNodeCmd.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().Uint64P("identifier", "i", 0, "Node identifier (ID)")
err = deleteNodeCmd.MarkFlagRequired("identifier")
if err != nil {
log.Fatalf(err.Error())
@ -45,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())
@ -57,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())
@ -177,13 +184,58 @@ 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")
identifier, err := cmd.Flags().GetUint64("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: 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",
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,
@ -199,7 +251,7 @@ var deleteNodeCmd = &cobra.Command{
defer conn.Close()
getRequest := &v1.GetMachineRequest{
MachineId: uint64(identifier),
MachineId: identifier,
}
getResponse, err := client.GetMachine(ctx, getRequest)
@ -217,7 +269,7 @@ var deleteNodeCmd = &cobra.Command{
}
deleteRequest := &v1.DeleteMachineRequest{
MachineId: uint64(identifier),
MachineId: identifier,
}
confirm := false
@ -280,7 +332,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)
@ -288,7 +340,7 @@ func sharingWorker(
}
machineRequest := &v1.GetMachineRequest{
MachineId: uint64(identifier),
MachineId: identifier,
}
machineResponse, err := client.GetMachine(ctx, machineRequest)
@ -412,6 +464,7 @@ func nodesToPtables(
"Ephemeral",
"Last seen",
"Online",
"Expired",
},
}
@ -420,12 +473,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 +496,16 @@ 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")
}
var expired string
if expiry.IsZero() || expiry.After(time.Now()) {
expired = pterm.LightGreen("no")
} else {
expired = pterm.LightRed("yes")
}
var namespace string
@ -459,6 +526,7 @@ func nodesToPtables(
strconv.FormatBool(ephemeral),
lastSeenTime,
online,
expired,
},
)
}

View File

@ -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,
}
}

View File

@ -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),
}

View File

@ -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

View File

@ -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

View File

@ -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,

View File

@ -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,
},

View File

@ -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": {

View File

@ -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,

View File

@ -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)

View File

@ -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
@ -62,44 +61,20 @@ type (
)
// For the time being this method is rather naive.
func (machine Machine) isAlreadyRegistered() bool {
func (machine Machine) isRegistered() bool {
return machine.Registered
}
// 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) {
@ -232,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 {
@ -287,6 +279,28 @@ 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.setLastStateChangeToNow(machine.Namespace.Name)
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.setLastStateChangeToNow(machine.Namespace.Name)
h.db.Save(machine)
}
// DeleteMachine softs deletes a Machine from the database.
func (h *Headscale) DeleteMachine(machine *Machine) error {
err := h.RemoveSharedMachineFromAllNamespaces(machine)
@ -624,12 +638,37 @@ 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).
Msg("Attempting to register machine")
if machine.isAlreadyRegistered() {
if machine.isRegistered() {
err := errMachineAlreadyRegistered
log.Error().
Caller().
@ -660,7 +699,8 @@ func (h *Headscale) RegisterMachine(
machine.IPAddress = ip.String()
machine.NamespaceID = namespace.ID
machine.Registered = true
machine.RegisterMethod = "cli"
machine.RegisterMethod = RegisterMethodCLI
machine.Expiry = &requestedTime
h.db.Save(&machine)
log.Trace().

View File

@ -3,6 +3,7 @@ package headscale
import (
"encoding/json"
"strconv"
"time"
"gopkg.in/check.v1"
)
@ -25,7 +26,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 +56,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 +79,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 +114,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 +145,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)
@ -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)
}

View File

@ -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),
}

113
oidc.go
View File

@ -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,16 +74,23 @@ 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
}
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().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 +99,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)
@ -117,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 {
@ -130,7 +146,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
}
@ -138,34 +158,38 @@ 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
// }
// 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),
"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,
@ -175,8 +199,16 @@ 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(mKeyStr)
machine, err := h.GetMachineByMachineKey(machineKey)
if err != nil {
log.Error().Msg("machine key not found in database")
ctx.String(
@ -187,6 +219,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(`
<html>
<body>
<h1>headscale</h1>
<p>
Reuthenticated as %s, you can now close this window.
</p>
</body>
</html>
`, claims.Email)))
return
}
now := time.Now().UTC()
if namespaceName, ok := h.getNamespaceFromEmail(claims.Email); ok {
@ -195,12 +250,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 +265,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",
@ -223,13 +296,12 @@ 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
machine.Expiry = &requestedTime
h.db.Save(&machine)
}
h.updateMachineExpiry(machine)
ctx.Data(http.StatusOK, "text/html; charset=utf-8", []byte(fmt.Sprintf(`
<html>
<body>
@ -241,9 +313,12 @@ func (h *Headscale) OIDCCallback(ctx *gin.Context) {
</html>
`, claims.Email)))
return
}
log.Error().
Caller().
Str("email", claims.Email).
Str("username", claims.Username).
Str("machine", machine.Name).

View File

@ -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),
}

View File

@ -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"

View File

@ -64,6 +64,14 @@ message DeleteMachineRequest {
message DeleteMachineResponse {
}
message ExpireMachineRequest {
uint64 machine_id = 1;
}
message ExpireMachineResponse {
Machine machine = 1;
}
message ListMachinesRequest {
string namespace = 1;
}

View File

@ -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),
}

View File

@ -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),
}

View File

@ -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)