2022-11-05 16:07:22 +08:00
|
|
|
// nolint
|
2021-10-27 04:42:20 +08:00
|
|
|
package headscale
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
2022-07-25 17:25:20 +08:00
|
|
|
"fmt"
|
2022-05-13 15:47:34 +08:00
|
|
|
"strings"
|
2021-11-05 06:19:27 +08:00
|
|
|
"time"
|
2021-10-27 04:42:20 +08:00
|
|
|
|
2022-04-15 19:11:41 +08:00
|
|
|
v1 "github.com/juanfont/headscale/gen/go/headscale/v1"
|
2021-11-05 06:19:27 +08:00
|
|
|
"github.com/rs/zerolog/log"
|
2022-05-13 16:17:52 +08:00
|
|
|
"google.golang.org/grpc/codes"
|
|
|
|
"google.golang.org/grpc/status"
|
2021-11-05 06:19:27 +08:00
|
|
|
"tailscale.com/tailcfg"
|
2022-11-05 16:07:22 +08:00
|
|
|
"tailscale.com/types/key"
|
2021-10-27 04:42:20 +08:00
|
|
|
)
|
|
|
|
|
2021-11-05 06:19:27 +08:00
|
|
|
type headscaleV1APIServer struct { // v1.HeadscaleServiceServer
|
|
|
|
v1.UnimplementedHeadscaleServiceServer
|
2021-10-27 04:42:20 +08:00
|
|
|
h *Headscale
|
|
|
|
}
|
|
|
|
|
2021-11-05 06:19:27 +08:00
|
|
|
func newHeadscaleV1APIServer(h *Headscale) v1.HeadscaleServiceServer {
|
2021-10-27 04:42:20 +08:00
|
|
|
return headscaleV1APIServer{
|
|
|
|
h: h,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-11-05 06:19:27 +08:00
|
|
|
func (api headscaleV1APIServer) GetNamespace(
|
2021-10-27 04:42:20 +08:00
|
|
|
ctx context.Context,
|
2021-11-05 06:19:27 +08:00
|
|
|
request *v1.GetNamespaceRequest,
|
|
|
|
) (*v1.GetNamespaceResponse, error) {
|
|
|
|
namespace, err := api.h.GetNamespace(request.GetName())
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2021-10-30 00:44:32 +08:00
|
|
|
|
2021-11-05 06:19:27 +08:00
|
|
|
return &v1.GetNamespaceResponse{Namespace: namespace.toProto()}, nil
|
2021-10-30 00:44:32 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
func (api headscaleV1APIServer) CreateNamespace(
|
|
|
|
ctx context.Context,
|
2021-11-05 06:19:27 +08:00
|
|
|
request *v1.CreateNamespaceRequest,
|
|
|
|
) (*v1.CreateNamespaceResponse, error) {
|
|
|
|
namespace, err := api.h.CreateNamespace(request.GetName())
|
2021-10-27 04:42:20 +08:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2021-11-05 06:19:27 +08:00
|
|
|
return &v1.CreateNamespaceResponse{Namespace: namespace.toProto()}, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (api headscaleV1APIServer) RenameNamespace(
|
|
|
|
ctx context.Context,
|
|
|
|
request *v1.RenameNamespaceRequest,
|
|
|
|
) (*v1.RenameNamespaceResponse, error) {
|
|
|
|
err := api.h.RenameNamespace(request.GetOldName(), request.GetNewName())
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
namespace, err := api.h.GetNamespace(request.GetNewName())
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return &v1.RenameNamespaceResponse{Namespace: namespace.toProto()}, nil
|
2021-10-30 00:44:32 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
func (api headscaleV1APIServer) DeleteNamespace(
|
|
|
|
ctx context.Context,
|
2021-11-05 06:19:27 +08:00
|
|
|
request *v1.DeleteNamespaceRequest,
|
|
|
|
) (*v1.DeleteNamespaceResponse, error) {
|
|
|
|
err := api.h.DestroyNamespace(request.GetName())
|
2021-10-30 00:44:32 +08:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2021-11-05 06:19:27 +08:00
|
|
|
return &v1.DeleteNamespaceResponse{}, nil
|
2021-10-30 00:44:32 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
func (api headscaleV1APIServer) ListNamespaces(
|
|
|
|
ctx context.Context,
|
2021-11-05 06:19:27 +08:00
|
|
|
request *v1.ListNamespacesRequest,
|
|
|
|
) (*v1.ListNamespacesResponse, error) {
|
2021-10-30 00:44:32 +08:00
|
|
|
namespaces, err := api.h.ListNamespaces()
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2021-11-05 06:19:27 +08:00
|
|
|
response := make([]*v1.Namespace, len(namespaces))
|
|
|
|
for index, namespace := range namespaces {
|
|
|
|
response[index] = namespace.toProto()
|
|
|
|
}
|
|
|
|
|
|
|
|
log.Trace().Caller().Interface("namespaces", response).Msg("")
|
|
|
|
|
|
|
|
return &v1.ListNamespacesResponse{Namespaces: response}, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (api headscaleV1APIServer) CreatePreAuthKey(
|
|
|
|
ctx context.Context,
|
|
|
|
request *v1.CreatePreAuthKeyRequest,
|
|
|
|
) (*v1.CreatePreAuthKeyResponse, error) {
|
2021-11-08 16:02:01 +08:00
|
|
|
var expiration time.Time
|
|
|
|
if request.GetExpiration() != nil {
|
|
|
|
expiration = request.GetExpiration().AsTime()
|
|
|
|
}
|
|
|
|
|
2022-09-23 15:58:06 +08:00
|
|
|
for _, tag := range request.AclTags {
|
|
|
|
err := validateTag(tag)
|
|
|
|
if err != nil {
|
|
|
|
return &v1.CreatePreAuthKeyResponse{
|
|
|
|
PreAuthKey: nil,
|
|
|
|
}, status.Error(codes.InvalidArgument, err.Error())
|
2022-08-25 18:43:15 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-11-05 06:19:27 +08:00
|
|
|
preAuthKey, err := api.h.CreatePreAuthKey(
|
|
|
|
request.GetNamespace(),
|
2021-11-09 04:49:03 +08:00
|
|
|
request.GetReusable(),
|
2021-11-05 06:19:27 +08:00
|
|
|
request.GetEphemeral(),
|
|
|
|
&expiration,
|
2022-08-25 18:03:38 +08:00
|
|
|
request.AclTags,
|
2021-11-05 06:19:27 +08:00
|
|
|
)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return &v1.CreatePreAuthKeyResponse{PreAuthKey: preAuthKey.toProto()}, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (api headscaleV1APIServer) ExpirePreAuthKey(
|
|
|
|
ctx context.Context,
|
|
|
|
request *v1.ExpirePreAuthKeyRequest,
|
|
|
|
) (*v1.ExpirePreAuthKeyResponse, error) {
|
|
|
|
preAuthKey, err := api.h.GetPreAuthKey(request.GetNamespace(), request.Key)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
err = api.h.ExpirePreAuthKey(preAuthKey)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return &v1.ExpirePreAuthKeyResponse{}, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (api headscaleV1APIServer) ListPreAuthKeys(
|
|
|
|
ctx context.Context,
|
|
|
|
request *v1.ListPreAuthKeysRequest,
|
|
|
|
) (*v1.ListPreAuthKeysResponse, error) {
|
|
|
|
preAuthKeys, err := api.h.ListPreAuthKeys(request.GetNamespace())
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
response := make([]*v1.PreAuthKey, len(preAuthKeys))
|
|
|
|
for index, key := range preAuthKeys {
|
|
|
|
response[index] = key.toProto()
|
|
|
|
}
|
|
|
|
|
|
|
|
return &v1.ListPreAuthKeysResponse{PreAuthKeys: response}, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (api headscaleV1APIServer) RegisterMachine(
|
|
|
|
ctx context.Context,
|
|
|
|
request *v1.RegisterMachineRequest,
|
|
|
|
) (*v1.RegisterMachineResponse, error) {
|
2021-11-13 16:36:45 +08:00
|
|
|
log.Trace().
|
|
|
|
Str("namespace", request.GetNamespace()).
|
2022-08-10 21:35:26 +08:00
|
|
|
Str("node_key", request.GetKey()).
|
2021-11-13 16:36:45 +08:00
|
|
|
Msg("Registering machine")
|
2022-02-28 01:42:43 +08:00
|
|
|
|
2022-02-28 16:06:39 +08:00
|
|
|
machine, err := api.h.RegisterMachineFromAuthCallback(
|
2021-11-05 06:19:27 +08:00
|
|
|
request.GetKey(),
|
|
|
|
request.GetNamespace(),
|
2022-12-15 08:10:26 +08:00
|
|
|
nil,
|
2022-02-28 01:42:43 +08:00
|
|
|
RegisterMethodCLI,
|
2021-11-05 06:19:27 +08:00
|
|
|
)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return &v1.RegisterMachineResponse{Machine: machine.toProto()}, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (api headscaleV1APIServer) GetMachine(
|
|
|
|
ctx context.Context,
|
|
|
|
request *v1.GetMachineRequest,
|
|
|
|
) (*v1.GetMachineResponse, error) {
|
|
|
|
machine, err := api.h.GetMachineByID(request.GetMachineId())
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return &v1.GetMachineResponse{Machine: machine.toProto()}, nil
|
|
|
|
}
|
|
|
|
|
2022-04-26 03:16:14 +08:00
|
|
|
func (api headscaleV1APIServer) SetTags(
|
2022-04-15 19:11:41 +08:00
|
|
|
ctx context.Context,
|
2022-04-26 03:16:14 +08:00
|
|
|
request *v1.SetTagsRequest,
|
|
|
|
) (*v1.SetTagsResponse, error) {
|
|
|
|
machine, err := api.h.GetMachineByID(request.GetMachineId())
|
2022-04-15 19:11:41 +08:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2022-05-13 15:47:34 +08:00
|
|
|
for _, tag := range request.GetTags() {
|
2022-07-25 17:25:20 +08:00
|
|
|
err := validateTag(tag)
|
|
|
|
if err != nil {
|
2022-05-13 16:17:52 +08:00
|
|
|
return &v1.SetTagsResponse{
|
2022-08-10 21:35:26 +08:00
|
|
|
Machine: nil,
|
2022-07-25 17:25:20 +08:00
|
|
|
}, status.Error(codes.InvalidArgument, err.Error())
|
2022-05-13 15:47:34 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-05-13 17:09:28 +08:00
|
|
|
err = api.h.SetTags(machine, request.GetTags())
|
|
|
|
if err != nil {
|
|
|
|
return &v1.SetTagsResponse{
|
|
|
|
Machine: nil,
|
|
|
|
}, status.Error(codes.Internal, err.Error())
|
|
|
|
}
|
2022-04-15 19:11:41 +08:00
|
|
|
|
2022-04-26 03:16:14 +08:00
|
|
|
log.Trace().
|
2022-05-17 03:41:46 +08:00
|
|
|
Str("machine", machine.Hostname).
|
2022-04-26 03:16:14 +08:00
|
|
|
Strs("tags", request.GetTags()).
|
|
|
|
Msg("Changing tags of machine")
|
2022-04-15 19:11:41 +08:00
|
|
|
|
2022-04-26 03:16:14 +08:00
|
|
|
return &v1.SetTagsResponse{Machine: machine.toProto()}, nil
|
2022-04-15 19:11:41 +08:00
|
|
|
}
|
|
|
|
|
2022-07-25 17:25:20 +08:00
|
|
|
func validateTag(tag string) error {
|
|
|
|
if strings.Index(tag, "tag:") != 0 {
|
|
|
|
return fmt.Errorf("tag must start with the string 'tag:'")
|
|
|
|
}
|
|
|
|
if strings.ToLower(tag) != tag {
|
|
|
|
return fmt.Errorf("tag should be lowercase")
|
|
|
|
}
|
|
|
|
if len(strings.Fields(tag)) > 1 {
|
|
|
|
return fmt.Errorf("tag should not contains space")
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2021-11-05 06:19:27 +08:00
|
|
|
func (api headscaleV1APIServer) DeleteMachine(
|
|
|
|
ctx context.Context,
|
|
|
|
request *v1.DeleteMachineRequest,
|
|
|
|
) (*v1.DeleteMachineResponse, error) {
|
|
|
|
machine, err := api.h.GetMachineByID(request.GetMachineId())
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
err = api.h.DeleteMachine(
|
|
|
|
machine,
|
|
|
|
)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return &v1.DeleteMachineResponse{}, nil
|
|
|
|
}
|
|
|
|
|
2021-11-21 21:40:19 +08:00
|
|
|
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().
|
2022-04-25 03:56:28 +08:00
|
|
|
Str("machine", machine.Hostname).
|
2021-11-21 21:40:19 +08:00
|
|
|
Time("expiry", *machine.Expiry).
|
|
|
|
Msg("machine expired")
|
|
|
|
|
|
|
|
return &v1.ExpireMachineResponse{Machine: machine.toProto()}, nil
|
|
|
|
}
|
|
|
|
|
2022-03-14 05:03:20 +08:00
|
|
|
func (api headscaleV1APIServer) RenameMachine(
|
|
|
|
ctx context.Context,
|
|
|
|
request *v1.RenameMachineRequest,
|
|
|
|
) (*v1.RenameMachineResponse, error) {
|
|
|
|
machine, err := api.h.GetMachineByID(request.GetMachineId())
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2022-04-25 03:56:28 +08:00
|
|
|
err = api.h.RenameMachine(
|
2022-03-14 05:03:20 +08:00
|
|
|
machine,
|
|
|
|
request.GetNewName(),
|
|
|
|
)
|
2022-04-25 03:56:28 +08:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2022-03-14 05:03:20 +08:00
|
|
|
|
|
|
|
log.Trace().
|
2022-04-25 03:56:28 +08:00
|
|
|
Str("machine", machine.Hostname).
|
2022-05-17 02:35:35 +08:00
|
|
|
Str("new_name", request.GetNewName()).
|
|
|
|
Msg("machine renamed")
|
2022-03-14 05:03:20 +08:00
|
|
|
|
|
|
|
return &v1.RenameMachineResponse{Machine: machine.toProto()}, nil
|
|
|
|
}
|
|
|
|
|
2021-11-05 06:19:27 +08:00
|
|
|
func (api headscaleV1APIServer) ListMachines(
|
|
|
|
ctx context.Context,
|
|
|
|
request *v1.ListMachinesRequest,
|
|
|
|
) (*v1.ListMachinesResponse, error) {
|
|
|
|
if request.GetNamespace() != "" {
|
|
|
|
machines, err := api.h.ListMachinesInNamespace(request.GetNamespace())
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
response := make([]*v1.Machine, len(machines))
|
|
|
|
for index, machine := range machines {
|
|
|
|
response[index] = machine.toProto()
|
|
|
|
}
|
|
|
|
|
|
|
|
return &v1.ListMachinesResponse{Machines: response}, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
machines, err := api.h.ListMachines()
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
response := make([]*v1.Machine, len(machines))
|
|
|
|
for index, machine := range machines {
|
2022-04-16 18:20:58 +08:00
|
|
|
m := machine.toProto()
|
2022-04-16 19:15:18 +08:00
|
|
|
validTags, invalidTags := getTags(
|
2022-05-05 04:56:55 +08:00
|
|
|
api.h.aclPolicy,
|
2022-04-16 19:15:18 +08:00
|
|
|
machine,
|
|
|
|
api.h.cfg.OIDC.StripEmaildomain,
|
|
|
|
)
|
2022-04-16 18:20:58 +08:00
|
|
|
m.InvalidTags = invalidTags
|
|
|
|
m.ValidTags = validTags
|
|
|
|
response[index] = m
|
2021-11-05 06:19:27 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return &v1.ListMachinesResponse{Machines: response}, nil
|
|
|
|
}
|
|
|
|
|
2022-05-01 21:44:34 +08:00
|
|
|
func (api headscaleV1APIServer) MoveMachine(
|
|
|
|
ctx context.Context,
|
|
|
|
request *v1.MoveMachineRequest,
|
|
|
|
) (*v1.MoveMachineResponse, error) {
|
|
|
|
machine, err := api.h.GetMachineByID(request.GetMachineId())
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
err = api.h.SetMachineNamespace(machine, request.GetNamespace())
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return &v1.MoveMachineResponse{Machine: machine.toProto()}, nil
|
|
|
|
}
|
|
|
|
|
2022-11-26 08:03:39 +08:00
|
|
|
func (api headscaleV1APIServer) GetRoutes(
|
2021-11-05 06:19:27 +08:00
|
|
|
ctx context.Context,
|
2022-11-26 08:03:39 +08:00
|
|
|
request *v1.GetRoutesRequest,
|
|
|
|
) (*v1.GetRoutesResponse, error) {
|
|
|
|
routes, err := api.h.GetRoutes()
|
2021-11-05 06:19:27 +08:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2022-11-26 08:03:39 +08:00
|
|
|
return &v1.GetRoutesResponse{
|
|
|
|
Routes: Routes(routes).toProto(),
|
2021-11-05 06:19:27 +08:00
|
|
|
}, nil
|
|
|
|
}
|
|
|
|
|
2022-11-26 08:03:39 +08:00
|
|
|
func (api headscaleV1APIServer) EnableRoute(
|
|
|
|
ctx context.Context,
|
|
|
|
request *v1.EnableRouteRequest,
|
|
|
|
) (*v1.EnableRouteResponse, error) {
|
|
|
|
err := api.h.EnableRoute(request.GetRouteId())
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return &v1.EnableRouteResponse{}, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (api headscaleV1APIServer) DisableRoute(
|
|
|
|
ctx context.Context,
|
|
|
|
request *v1.DisableRouteRequest,
|
|
|
|
) (*v1.DisableRouteResponse, error) {
|
|
|
|
err := api.h.DisableRoute(request.GetRouteId())
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return &v1.DisableRouteResponse{}, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (api headscaleV1APIServer) GetMachineRoutes(
|
2021-11-05 06:19:27 +08:00
|
|
|
ctx context.Context,
|
2022-11-26 08:03:39 +08:00
|
|
|
request *v1.GetMachineRoutesRequest,
|
|
|
|
) (*v1.GetMachineRoutesResponse, error) {
|
2021-11-05 06:19:27 +08:00
|
|
|
machine, err := api.h.GetMachineByID(request.GetMachineId())
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2022-11-26 08:03:39 +08:00
|
|
|
routes, err := api.h.GetMachineRoutes(machine)
|
2021-11-05 06:19:27 +08:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2022-11-26 08:03:39 +08:00
|
|
|
return &v1.GetMachineRoutesResponse{
|
|
|
|
Routes: Routes(routes).toProto(),
|
2021-11-05 06:19:27 +08:00
|
|
|
}, nil
|
|
|
|
}
|
|
|
|
|
2022-01-26 06:11:15 +08:00
|
|
|
func (api headscaleV1APIServer) CreateApiKey(
|
|
|
|
ctx context.Context,
|
|
|
|
request *v1.CreateApiKeyRequest,
|
|
|
|
) (*v1.CreateApiKeyResponse, error) {
|
|
|
|
var expiration time.Time
|
|
|
|
if request.GetExpiration() != nil {
|
|
|
|
expiration = request.GetExpiration().AsTime()
|
|
|
|
}
|
|
|
|
|
|
|
|
apiKey, _, err := api.h.CreateAPIKey(
|
|
|
|
&expiration,
|
|
|
|
)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return &v1.CreateApiKeyResponse{ApiKey: apiKey}, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (api headscaleV1APIServer) ExpireApiKey(
|
|
|
|
ctx context.Context,
|
|
|
|
request *v1.ExpireApiKeyRequest,
|
|
|
|
) (*v1.ExpireApiKeyResponse, error) {
|
|
|
|
var apiKey *APIKey
|
|
|
|
var err error
|
|
|
|
|
|
|
|
apiKey, err = api.h.GetAPIKey(request.Prefix)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
err = api.h.ExpireAPIKey(apiKey)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return &v1.ExpireApiKeyResponse{}, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (api headscaleV1APIServer) ListApiKeys(
|
|
|
|
ctx context.Context,
|
|
|
|
request *v1.ListApiKeysRequest,
|
|
|
|
) (*v1.ListApiKeysResponse, error) {
|
|
|
|
apiKeys, err := api.h.ListAPIKeys()
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
response := make([]*v1.ApiKey, len(apiKeys))
|
|
|
|
for index, key := range apiKeys {
|
|
|
|
response[index] = key.toProto()
|
|
|
|
}
|
|
|
|
|
|
|
|
return &v1.ListApiKeysResponse{ApiKeys: response}, nil
|
|
|
|
}
|
|
|
|
|
2021-11-05 06:19:27 +08:00
|
|
|
// The following service calls are for testing and debugging
|
|
|
|
func (api headscaleV1APIServer) DebugCreateMachine(
|
|
|
|
ctx context.Context,
|
|
|
|
request *v1.DebugCreateMachineRequest,
|
|
|
|
) (*v1.DebugCreateMachineResponse, error) {
|
|
|
|
namespace, err := api.h.GetNamespace(request.GetNamespace())
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2021-11-16 01:24:24 +08:00
|
|
|
routes, err := stringToIPPrefix(request.GetRoutes())
|
2021-11-05 06:19:27 +08:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2021-11-13 16:36:45 +08:00
|
|
|
log.Trace().
|
|
|
|
Caller().
|
|
|
|
Interface("route-prefix", routes).
|
|
|
|
Interface("route-str", request.GetRoutes()).
|
|
|
|
Msg("")
|
2021-11-05 06:19:27 +08:00
|
|
|
|
|
|
|
hostinfo := tailcfg.Hostinfo{
|
|
|
|
RoutableIPs: routes,
|
|
|
|
OS: "TestOS",
|
|
|
|
Hostname: "DebugTestMachine",
|
|
|
|
}
|
|
|
|
|
2022-10-21 20:42:37 +08:00
|
|
|
givenName, err := api.h.GenerateGivenName(request.GetKey(), request.GetName())
|
2022-05-17 02:32:37 +08:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2021-11-05 06:19:27 +08:00
|
|
|
newMachine := Machine{
|
|
|
|
MachineKey: request.GetKey(),
|
2022-04-25 03:56:28 +08:00
|
|
|
Hostname: request.GetName(),
|
2022-05-17 02:32:37 +08:00
|
|
|
GivenName: givenName,
|
2021-11-05 06:19:27 +08:00
|
|
|
Namespace: *namespace,
|
|
|
|
|
|
|
|
Expiry: &time.Time{},
|
|
|
|
LastSeen: &time.Time{},
|
|
|
|
LastSuccessfulUpdate: &time.Time{},
|
|
|
|
|
2022-03-02 00:34:24 +08:00
|
|
|
HostInfo: HostInfo(hostinfo),
|
2021-11-05 06:19:27 +08:00
|
|
|
}
|
2022-11-28 23:54:23 +08:00
|
|
|
|
2022-11-05 16:07:22 +08:00
|
|
|
nodeKey := key.NodePublic{}
|
|
|
|
err = nodeKey.UnmarshalText([]byte(request.GetKey()))
|
|
|
|
if err != nil {
|
|
|
|
log.Panic().Msg("can not add machine for debug. invalid node key")
|
|
|
|
}
|
2021-11-05 06:19:27 +08:00
|
|
|
|
2022-03-01 00:34:50 +08:00
|
|
|
api.h.registrationCache.Set(
|
2022-11-05 16:07:22 +08:00
|
|
|
NodePublicKeyStripPrefix(nodeKey),
|
2022-03-01 00:34:50 +08:00
|
|
|
newMachine,
|
2022-03-01 06:42:30 +08:00
|
|
|
registerCacheExpiration,
|
2022-03-01 00:34:50 +08:00
|
|
|
)
|
2021-10-30 00:44:32 +08:00
|
|
|
|
2021-11-05 06:19:27 +08:00
|
|
|
return &v1.DebugCreateMachineResponse{Machine: newMachine.toProto()}, nil
|
2021-10-27 04:42:20 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
func (api headscaleV1APIServer) mustEmbedUnimplementedHeadscaleServiceServer() {}
|