diff --git a/CHANGELOG.md b/CHANGELOG.md index b3911aa4..f5b5e28d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -34,6 +34,10 @@ release. - If you are running a version older than 0.25.0, you must upgrade to 0.25.1 first, then upgrade to this release - See the [upgrade path documentation](https://headscale.net/stable/about/faq/#what-is-the-recommended-update-path-can-i-skip-multiple-versions-while-updating) for detailed guidance - In version 0.29, all migrations before 0.28.0 will also be removed +- Remove ability to move nodes between users [#2922](https://github.com/juanfont/headscale/pull/2922) + - The `headscale nodes move` CLI command has been removed + - The `MoveNode` API endpoint has been removed + - Nodes are permanently associated with their user at registration time ### Changes diff --git a/cmd/headscale/cli/nodes.go b/cmd/headscale/cli/nodes.go index e1b040f0..8b4ab1ed 100644 --- a/cmd/headscale/cli/nodes.go +++ b/cmd/headscale/cli/nodes.go @@ -73,26 +73,6 @@ func init() { } nodeCmd.AddCommand(deleteNodeCmd) - moveNodeCmd.Flags().Uint64P("identifier", "i", 0, "Node identifier (ID)") - - err = moveNodeCmd.MarkFlagRequired("identifier") - if err != nil { - log.Fatal(err.Error()) - } - - moveNodeCmd.Flags().Uint64P("user", "u", 0, "New user") - - moveNodeCmd.Flags().StringP("namespace", "n", "", "User") - moveNodeNamespaceFlag := moveNodeCmd.Flags().Lookup("namespace") - moveNodeNamespaceFlag.Deprecated = deprecateNamespaceMessage - moveNodeNamespaceFlag.Hidden = true - - err = moveNodeCmd.MarkFlagRequired("user") - if err != nil { - log.Fatal(err.Error()) - } - nodeCmd.AddCommand(moveNodeCmd) - tagCmd.Flags().Uint64P("identifier", "i", 0, "Node identifier (ID)") tagCmd.MarkFlagRequired("identifier") tagCmd.Flags().StringSliceP("tags", "t", []string{}, "List of tags to add to the node") @@ -455,66 +435,6 @@ var deleteNodeCmd = &cobra.Command{ }, } -var moveNodeCmd = &cobra.Command{ - Use: "move", - Short: "Move node to another user", - Aliases: []string{"mv"}, - 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, - ) - } - - user, err := cmd.Flags().GetUint64("user") - if err != nil { - ErrorOutput( - err, - fmt.Sprintf("Error getting user: %s", err), - output, - ) - } - - ctx, client, conn, cancel := newHeadscaleCLIWithConfig() - defer cancel() - defer conn.Close() - - getRequest := &v1.GetNodeRequest{ - NodeId: identifier, - } - - _, err = client.GetNode(ctx, getRequest) - if err != nil { - ErrorOutput( - err, - "Error getting node: "+status.Convert(err).Message(), - output, - ) - } - - moveRequest := &v1.MoveNodeRequest{ - NodeId: identifier, - User: user, - } - - moveResponse, err := client.MoveNode(ctx, moveRequest) - if err != nil { - ErrorOutput( - err, - "Error moving node: "+status.Convert(err).Message(), - output, - ) - } - - SuccessOutput(moveResponse.GetNode(), "Node moved to another user", output) - }, -} - var backfillNodeIPsCmd = &cobra.Command{ Use: "backfillips", Short: "Backfill IPs missing from nodes", diff --git a/gen/go/headscale/v1/headscale.pb.go b/gen/go/headscale/v1/headscale.pb.go index 2c594f5a..7a411e06 100644 --- a/gen/go/headscale/v1/headscale.pb.go +++ b/gen/go/headscale/v1/headscale.pb.go @@ -109,7 +109,7 @@ const file_headscale_v1_headscale_proto_rawDesc = "" + "\x1cheadscale/v1/headscale.proto\x12\fheadscale.v1\x1a\x1cgoogle/api/annotations.proto\x1a\x17headscale/v1/user.proto\x1a\x1dheadscale/v1/preauthkey.proto\x1a\x17headscale/v1/node.proto\x1a\x19headscale/v1/apikey.proto\x1a\x19headscale/v1/policy.proto\"\x0f\n" + "\rHealthRequest\"E\n" + "\x0eHealthResponse\x123\n" + - "\x15database_connectivity\x18\x01 \x01(\bR\x14databaseConnectivity2\x80\x17\n" + + "\x15database_connectivity\x18\x01 \x01(\bR\x14databaseConnectivity2\x8d\x16\n" + "\x10HeadscaleService\x12h\n" + "\n" + "CreateUser\x12\x1f.headscale.v1.CreateUserRequest\x1a .headscale.v1.CreateUserResponse\"\x17\x82\xd3\xe4\x93\x02\x11:\x01*\"\f/api/v1/user\x12\x80\x01\n" + @@ -132,8 +132,7 @@ const file_headscale_v1_headscale_proto_rawDesc = "" + "ExpireNode\x12\x1f.headscale.v1.ExpireNodeRequest\x1a .headscale.v1.ExpireNodeResponse\"%\x82\xd3\xe4\x93\x02\x1f\"\x1d/api/v1/node/{node_id}/expire\x12\x81\x01\n" + "\n" + "RenameNode\x12\x1f.headscale.v1.RenameNodeRequest\x1a .headscale.v1.RenameNodeResponse\"0\x82\xd3\xe4\x93\x02*\"(/api/v1/node/{node_id}/rename/{new_name}\x12b\n" + - "\tListNodes\x12\x1e.headscale.v1.ListNodesRequest\x1a\x1f.headscale.v1.ListNodesResponse\"\x14\x82\xd3\xe4\x93\x02\x0e\x12\f/api/v1/node\x12q\n" + - "\bMoveNode\x12\x1d.headscale.v1.MoveNodeRequest\x1a\x1e.headscale.v1.MoveNodeResponse\"&\x82\xd3\xe4\x93\x02 :\x01*\"\x1b/api/v1/node/{node_id}/user\x12\x80\x01\n" + + "\tListNodes\x12\x1e.headscale.v1.ListNodesRequest\x1a\x1f.headscale.v1.ListNodesResponse\"\x14\x82\xd3\xe4\x93\x02\x0e\x12\f/api/v1/node\x12\x80\x01\n" + "\x0fBackfillNodeIPs\x12$.headscale.v1.BackfillNodeIPsRequest\x1a%.headscale.v1.BackfillNodeIPsResponse\" \x82\xd3\xe4\x93\x02\x1a\"\x18/api/v1/node/backfillips\x12p\n" + "\fCreateApiKey\x12!.headscale.v1.CreateApiKeyRequest\x1a\".headscale.v1.CreateApiKeyResponse\"\x19\x82\xd3\xe4\x93\x02\x13:\x01*\"\x0e/api/v1/apikey\x12w\n" + "\fExpireApiKey\x12!.headscale.v1.ExpireApiKeyRequest\x1a\".headscale.v1.ExpireApiKeyResponse\" \x82\xd3\xe4\x93\x02\x1a:\x01*\"\x15/api/v1/apikey/expire\x12j\n" + @@ -175,38 +174,36 @@ var file_headscale_v1_headscale_proto_goTypes = []any{ (*ExpireNodeRequest)(nil), // 15: headscale.v1.ExpireNodeRequest (*RenameNodeRequest)(nil), // 16: headscale.v1.RenameNodeRequest (*ListNodesRequest)(nil), // 17: headscale.v1.ListNodesRequest - (*MoveNodeRequest)(nil), // 18: headscale.v1.MoveNodeRequest - (*BackfillNodeIPsRequest)(nil), // 19: headscale.v1.BackfillNodeIPsRequest - (*CreateApiKeyRequest)(nil), // 20: headscale.v1.CreateApiKeyRequest - (*ExpireApiKeyRequest)(nil), // 21: headscale.v1.ExpireApiKeyRequest - (*ListApiKeysRequest)(nil), // 22: headscale.v1.ListApiKeysRequest - (*DeleteApiKeyRequest)(nil), // 23: headscale.v1.DeleteApiKeyRequest - (*GetPolicyRequest)(nil), // 24: headscale.v1.GetPolicyRequest - (*SetPolicyRequest)(nil), // 25: headscale.v1.SetPolicyRequest - (*CreateUserResponse)(nil), // 26: headscale.v1.CreateUserResponse - (*RenameUserResponse)(nil), // 27: headscale.v1.RenameUserResponse - (*DeleteUserResponse)(nil), // 28: headscale.v1.DeleteUserResponse - (*ListUsersResponse)(nil), // 29: headscale.v1.ListUsersResponse - (*CreatePreAuthKeyResponse)(nil), // 30: headscale.v1.CreatePreAuthKeyResponse - (*ExpirePreAuthKeyResponse)(nil), // 31: headscale.v1.ExpirePreAuthKeyResponse - (*ListPreAuthKeysResponse)(nil), // 32: headscale.v1.ListPreAuthKeysResponse - (*DebugCreateNodeResponse)(nil), // 33: headscale.v1.DebugCreateNodeResponse - (*GetNodeResponse)(nil), // 34: headscale.v1.GetNodeResponse - (*SetTagsResponse)(nil), // 35: headscale.v1.SetTagsResponse - (*SetApprovedRoutesResponse)(nil), // 36: headscale.v1.SetApprovedRoutesResponse - (*RegisterNodeResponse)(nil), // 37: headscale.v1.RegisterNodeResponse - (*DeleteNodeResponse)(nil), // 38: headscale.v1.DeleteNodeResponse - (*ExpireNodeResponse)(nil), // 39: headscale.v1.ExpireNodeResponse - (*RenameNodeResponse)(nil), // 40: headscale.v1.RenameNodeResponse - (*ListNodesResponse)(nil), // 41: headscale.v1.ListNodesResponse - (*MoveNodeResponse)(nil), // 42: headscale.v1.MoveNodeResponse - (*BackfillNodeIPsResponse)(nil), // 43: headscale.v1.BackfillNodeIPsResponse - (*CreateApiKeyResponse)(nil), // 44: headscale.v1.CreateApiKeyResponse - (*ExpireApiKeyResponse)(nil), // 45: headscale.v1.ExpireApiKeyResponse - (*ListApiKeysResponse)(nil), // 46: headscale.v1.ListApiKeysResponse - (*DeleteApiKeyResponse)(nil), // 47: headscale.v1.DeleteApiKeyResponse - (*GetPolicyResponse)(nil), // 48: headscale.v1.GetPolicyResponse - (*SetPolicyResponse)(nil), // 49: headscale.v1.SetPolicyResponse + (*BackfillNodeIPsRequest)(nil), // 18: headscale.v1.BackfillNodeIPsRequest + (*CreateApiKeyRequest)(nil), // 19: headscale.v1.CreateApiKeyRequest + (*ExpireApiKeyRequest)(nil), // 20: headscale.v1.ExpireApiKeyRequest + (*ListApiKeysRequest)(nil), // 21: headscale.v1.ListApiKeysRequest + (*DeleteApiKeyRequest)(nil), // 22: headscale.v1.DeleteApiKeyRequest + (*GetPolicyRequest)(nil), // 23: headscale.v1.GetPolicyRequest + (*SetPolicyRequest)(nil), // 24: headscale.v1.SetPolicyRequest + (*CreateUserResponse)(nil), // 25: headscale.v1.CreateUserResponse + (*RenameUserResponse)(nil), // 26: headscale.v1.RenameUserResponse + (*DeleteUserResponse)(nil), // 27: headscale.v1.DeleteUserResponse + (*ListUsersResponse)(nil), // 28: headscale.v1.ListUsersResponse + (*CreatePreAuthKeyResponse)(nil), // 29: headscale.v1.CreatePreAuthKeyResponse + (*ExpirePreAuthKeyResponse)(nil), // 30: headscale.v1.ExpirePreAuthKeyResponse + (*ListPreAuthKeysResponse)(nil), // 31: headscale.v1.ListPreAuthKeysResponse + (*DebugCreateNodeResponse)(nil), // 32: headscale.v1.DebugCreateNodeResponse + (*GetNodeResponse)(nil), // 33: headscale.v1.GetNodeResponse + (*SetTagsResponse)(nil), // 34: headscale.v1.SetTagsResponse + (*SetApprovedRoutesResponse)(nil), // 35: headscale.v1.SetApprovedRoutesResponse + (*RegisterNodeResponse)(nil), // 36: headscale.v1.RegisterNodeResponse + (*DeleteNodeResponse)(nil), // 37: headscale.v1.DeleteNodeResponse + (*ExpireNodeResponse)(nil), // 38: headscale.v1.ExpireNodeResponse + (*RenameNodeResponse)(nil), // 39: headscale.v1.RenameNodeResponse + (*ListNodesResponse)(nil), // 40: headscale.v1.ListNodesResponse + (*BackfillNodeIPsResponse)(nil), // 41: headscale.v1.BackfillNodeIPsResponse + (*CreateApiKeyResponse)(nil), // 42: headscale.v1.CreateApiKeyResponse + (*ExpireApiKeyResponse)(nil), // 43: headscale.v1.ExpireApiKeyResponse + (*ListApiKeysResponse)(nil), // 44: headscale.v1.ListApiKeysResponse + (*DeleteApiKeyResponse)(nil), // 45: headscale.v1.DeleteApiKeyResponse + (*GetPolicyResponse)(nil), // 46: headscale.v1.GetPolicyResponse + (*SetPolicyResponse)(nil), // 47: headscale.v1.SetPolicyResponse } var file_headscale_v1_headscale_proto_depIdxs = []int32{ 2, // 0: headscale.v1.HeadscaleService.CreateUser:input_type -> headscale.v1.CreateUserRequest @@ -225,42 +222,40 @@ var file_headscale_v1_headscale_proto_depIdxs = []int32{ 15, // 13: headscale.v1.HeadscaleService.ExpireNode:input_type -> headscale.v1.ExpireNodeRequest 16, // 14: headscale.v1.HeadscaleService.RenameNode:input_type -> headscale.v1.RenameNodeRequest 17, // 15: headscale.v1.HeadscaleService.ListNodes:input_type -> headscale.v1.ListNodesRequest - 18, // 16: headscale.v1.HeadscaleService.MoveNode:input_type -> headscale.v1.MoveNodeRequest - 19, // 17: headscale.v1.HeadscaleService.BackfillNodeIPs:input_type -> headscale.v1.BackfillNodeIPsRequest - 20, // 18: headscale.v1.HeadscaleService.CreateApiKey:input_type -> headscale.v1.CreateApiKeyRequest - 21, // 19: headscale.v1.HeadscaleService.ExpireApiKey:input_type -> headscale.v1.ExpireApiKeyRequest - 22, // 20: headscale.v1.HeadscaleService.ListApiKeys:input_type -> headscale.v1.ListApiKeysRequest - 23, // 21: headscale.v1.HeadscaleService.DeleteApiKey:input_type -> headscale.v1.DeleteApiKeyRequest - 24, // 22: headscale.v1.HeadscaleService.GetPolicy:input_type -> headscale.v1.GetPolicyRequest - 25, // 23: headscale.v1.HeadscaleService.SetPolicy:input_type -> headscale.v1.SetPolicyRequest - 0, // 24: headscale.v1.HeadscaleService.Health:input_type -> headscale.v1.HealthRequest - 26, // 25: headscale.v1.HeadscaleService.CreateUser:output_type -> headscale.v1.CreateUserResponse - 27, // 26: headscale.v1.HeadscaleService.RenameUser:output_type -> headscale.v1.RenameUserResponse - 28, // 27: headscale.v1.HeadscaleService.DeleteUser:output_type -> headscale.v1.DeleteUserResponse - 29, // 28: headscale.v1.HeadscaleService.ListUsers:output_type -> headscale.v1.ListUsersResponse - 30, // 29: headscale.v1.HeadscaleService.CreatePreAuthKey:output_type -> headscale.v1.CreatePreAuthKeyResponse - 31, // 30: headscale.v1.HeadscaleService.ExpirePreAuthKey:output_type -> headscale.v1.ExpirePreAuthKeyResponse - 32, // 31: headscale.v1.HeadscaleService.ListPreAuthKeys:output_type -> headscale.v1.ListPreAuthKeysResponse - 33, // 32: headscale.v1.HeadscaleService.DebugCreateNode:output_type -> headscale.v1.DebugCreateNodeResponse - 34, // 33: headscale.v1.HeadscaleService.GetNode:output_type -> headscale.v1.GetNodeResponse - 35, // 34: headscale.v1.HeadscaleService.SetTags:output_type -> headscale.v1.SetTagsResponse - 36, // 35: headscale.v1.HeadscaleService.SetApprovedRoutes:output_type -> headscale.v1.SetApprovedRoutesResponse - 37, // 36: headscale.v1.HeadscaleService.RegisterNode:output_type -> headscale.v1.RegisterNodeResponse - 38, // 37: headscale.v1.HeadscaleService.DeleteNode:output_type -> headscale.v1.DeleteNodeResponse - 39, // 38: headscale.v1.HeadscaleService.ExpireNode:output_type -> headscale.v1.ExpireNodeResponse - 40, // 39: headscale.v1.HeadscaleService.RenameNode:output_type -> headscale.v1.RenameNodeResponse - 41, // 40: headscale.v1.HeadscaleService.ListNodes:output_type -> headscale.v1.ListNodesResponse - 42, // 41: headscale.v1.HeadscaleService.MoveNode:output_type -> headscale.v1.MoveNodeResponse - 43, // 42: headscale.v1.HeadscaleService.BackfillNodeIPs:output_type -> headscale.v1.BackfillNodeIPsResponse - 44, // 43: headscale.v1.HeadscaleService.CreateApiKey:output_type -> headscale.v1.CreateApiKeyResponse - 45, // 44: headscale.v1.HeadscaleService.ExpireApiKey:output_type -> headscale.v1.ExpireApiKeyResponse - 46, // 45: headscale.v1.HeadscaleService.ListApiKeys:output_type -> headscale.v1.ListApiKeysResponse - 47, // 46: headscale.v1.HeadscaleService.DeleteApiKey:output_type -> headscale.v1.DeleteApiKeyResponse - 48, // 47: headscale.v1.HeadscaleService.GetPolicy:output_type -> headscale.v1.GetPolicyResponse - 49, // 48: headscale.v1.HeadscaleService.SetPolicy:output_type -> headscale.v1.SetPolicyResponse - 1, // 49: headscale.v1.HeadscaleService.Health:output_type -> headscale.v1.HealthResponse - 25, // [25:50] is the sub-list for method output_type - 0, // [0:25] is the sub-list for method input_type + 18, // 16: headscale.v1.HeadscaleService.BackfillNodeIPs:input_type -> headscale.v1.BackfillNodeIPsRequest + 19, // 17: headscale.v1.HeadscaleService.CreateApiKey:input_type -> headscale.v1.CreateApiKeyRequest + 20, // 18: headscale.v1.HeadscaleService.ExpireApiKey:input_type -> headscale.v1.ExpireApiKeyRequest + 21, // 19: headscale.v1.HeadscaleService.ListApiKeys:input_type -> headscale.v1.ListApiKeysRequest + 22, // 20: headscale.v1.HeadscaleService.DeleteApiKey:input_type -> headscale.v1.DeleteApiKeyRequest + 23, // 21: headscale.v1.HeadscaleService.GetPolicy:input_type -> headscale.v1.GetPolicyRequest + 24, // 22: headscale.v1.HeadscaleService.SetPolicy:input_type -> headscale.v1.SetPolicyRequest + 0, // 23: headscale.v1.HeadscaleService.Health:input_type -> headscale.v1.HealthRequest + 25, // 24: headscale.v1.HeadscaleService.CreateUser:output_type -> headscale.v1.CreateUserResponse + 26, // 25: headscale.v1.HeadscaleService.RenameUser:output_type -> headscale.v1.RenameUserResponse + 27, // 26: headscale.v1.HeadscaleService.DeleteUser:output_type -> headscale.v1.DeleteUserResponse + 28, // 27: headscale.v1.HeadscaleService.ListUsers:output_type -> headscale.v1.ListUsersResponse + 29, // 28: headscale.v1.HeadscaleService.CreatePreAuthKey:output_type -> headscale.v1.CreatePreAuthKeyResponse + 30, // 29: headscale.v1.HeadscaleService.ExpirePreAuthKey:output_type -> headscale.v1.ExpirePreAuthKeyResponse + 31, // 30: headscale.v1.HeadscaleService.ListPreAuthKeys:output_type -> headscale.v1.ListPreAuthKeysResponse + 32, // 31: headscale.v1.HeadscaleService.DebugCreateNode:output_type -> headscale.v1.DebugCreateNodeResponse + 33, // 32: headscale.v1.HeadscaleService.GetNode:output_type -> headscale.v1.GetNodeResponse + 34, // 33: headscale.v1.HeadscaleService.SetTags:output_type -> headscale.v1.SetTagsResponse + 35, // 34: headscale.v1.HeadscaleService.SetApprovedRoutes:output_type -> headscale.v1.SetApprovedRoutesResponse + 36, // 35: headscale.v1.HeadscaleService.RegisterNode:output_type -> headscale.v1.RegisterNodeResponse + 37, // 36: headscale.v1.HeadscaleService.DeleteNode:output_type -> headscale.v1.DeleteNodeResponse + 38, // 37: headscale.v1.HeadscaleService.ExpireNode:output_type -> headscale.v1.ExpireNodeResponse + 39, // 38: headscale.v1.HeadscaleService.RenameNode:output_type -> headscale.v1.RenameNodeResponse + 40, // 39: headscale.v1.HeadscaleService.ListNodes:output_type -> headscale.v1.ListNodesResponse + 41, // 40: headscale.v1.HeadscaleService.BackfillNodeIPs:output_type -> headscale.v1.BackfillNodeIPsResponse + 42, // 41: headscale.v1.HeadscaleService.CreateApiKey:output_type -> headscale.v1.CreateApiKeyResponse + 43, // 42: headscale.v1.HeadscaleService.ExpireApiKey:output_type -> headscale.v1.ExpireApiKeyResponse + 44, // 43: headscale.v1.HeadscaleService.ListApiKeys:output_type -> headscale.v1.ListApiKeysResponse + 45, // 44: headscale.v1.HeadscaleService.DeleteApiKey:output_type -> headscale.v1.DeleteApiKeyResponse + 46, // 45: headscale.v1.HeadscaleService.GetPolicy:output_type -> headscale.v1.GetPolicyResponse + 47, // 46: headscale.v1.HeadscaleService.SetPolicy:output_type -> headscale.v1.SetPolicyResponse + 1, // 47: headscale.v1.HeadscaleService.Health:output_type -> headscale.v1.HealthResponse + 24, // [24:48] is the sub-list for method output_type + 0, // [0:24] is the sub-list for method input_type 0, // [0:0] is the sub-list for extension type_name 0, // [0:0] is the sub-list for extension extendee 0, // [0:0] is the sub-list for field type_name diff --git a/gen/go/headscale/v1/headscale.pb.gw.go b/gen/go/headscale/v1/headscale.pb.gw.go index 2a8ac365..f6a24539 100644 --- a/gen/go/headscale/v1/headscale.pb.gw.go +++ b/gen/go/headscale/v1/headscale.pb.gw.go @@ -605,48 +605,6 @@ func local_request_HeadscaleService_ListNodes_0(ctx context.Context, marshaler r return msg, metadata, err } -func request_HeadscaleService_MoveNode_0(ctx context.Context, marshaler runtime.Marshaler, client HeadscaleServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var ( - protoReq MoveNodeRequest - metadata runtime.ServerMetadata - err error - ) - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && !errors.Is(err, io.EOF) { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) - } - val, ok := pathParams["node_id"] - if !ok { - return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "node_id") - } - protoReq.NodeId, err = runtime.Uint64(val) - if err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "node_id", err) - } - msg, err := client.MoveNode(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) - return msg, metadata, err -} - -func local_request_HeadscaleService_MoveNode_0(ctx context.Context, marshaler runtime.Marshaler, server HeadscaleServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var ( - protoReq MoveNodeRequest - metadata runtime.ServerMetadata - err error - ) - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && !errors.Is(err, io.EOF) { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) - } - val, ok := pathParams["node_id"] - if !ok { - return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "node_id") - } - protoReq.NodeId, err = runtime.Uint64(val) - if err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "node_id", err) - } - msg, err := server.MoveNode(ctx, &protoReq) - return msg, metadata, err -} - var filter_HeadscaleService_BackfillNodeIPs_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)} func request_HeadscaleService_BackfillNodeIPs_0(ctx context.Context, marshaler runtime.Marshaler, client HeadscaleServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { @@ -1167,26 +1125,6 @@ func RegisterHeadscaleServiceHandlerServer(ctx context.Context, mux *runtime.Ser } forward_HeadscaleService_ListNodes_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) - mux.Handle(http.MethodPost, pattern_HeadscaleService_MoveNode_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) - annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/headscale.v1.HeadscaleService/MoveNode", runtime.WithHTTPPathPattern("/api/v1/node/{node_id}/user")) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - resp, md, err := local_request_HeadscaleService_MoveNode_0(annotatedContext, inboundMarshaler, server, req, pathParams) - md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) - annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) - if err != nil { - runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) - return - } - forward_HeadscaleService_MoveNode_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) - }) mux.Handle(http.MethodPost, pattern_HeadscaleService_BackfillNodeIPs_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() @@ -1659,23 +1597,6 @@ func RegisterHeadscaleServiceHandlerClient(ctx context.Context, mux *runtime.Ser } forward_HeadscaleService_ListNodes_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) - mux.Handle(http.MethodPost, pattern_HeadscaleService_MoveNode_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) - annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/headscale.v1.HeadscaleService/MoveNode", runtime.WithHTTPPathPattern("/api/v1/node/{node_id}/user")) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - resp, md, err := request_HeadscaleService_MoveNode_0(annotatedContext, inboundMarshaler, client, req, pathParams) - annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) - if err != nil { - runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) - return - } - forward_HeadscaleService_MoveNode_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) - }) mux.Handle(http.MethodPost, pattern_HeadscaleService_BackfillNodeIPs_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() @@ -1832,7 +1753,6 @@ var ( pattern_HeadscaleService_ExpireNode_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3, 2, 4}, []string{"api", "v1", "node", "node_id", "expire"}, "")) pattern_HeadscaleService_RenameNode_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", "node", "node_id", "rename", "new_name"}, "")) pattern_HeadscaleService_ListNodes_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "v1", "node"}, "")) - pattern_HeadscaleService_MoveNode_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3, 2, 4}, []string{"api", "v1", "node", "node_id", "user"}, "")) pattern_HeadscaleService_BackfillNodeIPs_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"api", "v1", "node", "backfillips"}, "")) pattern_HeadscaleService_CreateApiKey_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "v1", "apikey"}, "")) pattern_HeadscaleService_ExpireApiKey_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"api", "v1", "apikey", "expire"}, "")) @@ -1860,7 +1780,6 @@ var ( forward_HeadscaleService_ExpireNode_0 = runtime.ForwardResponseMessage forward_HeadscaleService_RenameNode_0 = runtime.ForwardResponseMessage forward_HeadscaleService_ListNodes_0 = runtime.ForwardResponseMessage - forward_HeadscaleService_MoveNode_0 = runtime.ForwardResponseMessage forward_HeadscaleService_BackfillNodeIPs_0 = runtime.ForwardResponseMessage forward_HeadscaleService_CreateApiKey_0 = runtime.ForwardResponseMessage forward_HeadscaleService_ExpireApiKey_0 = runtime.ForwardResponseMessage diff --git a/gen/go/headscale/v1/headscale_grpc.pb.go b/gen/go/headscale/v1/headscale_grpc.pb.go index bd8428c2..0cbef4ef 100644 --- a/gen/go/headscale/v1/headscale_grpc.pb.go +++ b/gen/go/headscale/v1/headscale_grpc.pb.go @@ -35,7 +35,6 @@ const ( HeadscaleService_ExpireNode_FullMethodName = "/headscale.v1.HeadscaleService/ExpireNode" HeadscaleService_RenameNode_FullMethodName = "/headscale.v1.HeadscaleService/RenameNode" HeadscaleService_ListNodes_FullMethodName = "/headscale.v1.HeadscaleService/ListNodes" - HeadscaleService_MoveNode_FullMethodName = "/headscale.v1.HeadscaleService/MoveNode" HeadscaleService_BackfillNodeIPs_FullMethodName = "/headscale.v1.HeadscaleService/BackfillNodeIPs" HeadscaleService_CreateApiKey_FullMethodName = "/headscale.v1.HeadscaleService/CreateApiKey" HeadscaleService_ExpireApiKey_FullMethodName = "/headscale.v1.HeadscaleService/ExpireApiKey" @@ -69,7 +68,6 @@ type HeadscaleServiceClient interface { ExpireNode(ctx context.Context, in *ExpireNodeRequest, opts ...grpc.CallOption) (*ExpireNodeResponse, error) RenameNode(ctx context.Context, in *RenameNodeRequest, opts ...grpc.CallOption) (*RenameNodeResponse, error) ListNodes(ctx context.Context, in *ListNodesRequest, opts ...grpc.CallOption) (*ListNodesResponse, error) - MoveNode(ctx context.Context, in *MoveNodeRequest, opts ...grpc.CallOption) (*MoveNodeResponse, error) BackfillNodeIPs(ctx context.Context, in *BackfillNodeIPsRequest, opts ...grpc.CallOption) (*BackfillNodeIPsResponse, error) // --- ApiKeys start --- CreateApiKey(ctx context.Context, in *CreateApiKeyRequest, opts ...grpc.CallOption) (*CreateApiKeyResponse, error) @@ -251,16 +249,6 @@ func (c *headscaleServiceClient) ListNodes(ctx context.Context, in *ListNodesReq return out, nil } -func (c *headscaleServiceClient) MoveNode(ctx context.Context, in *MoveNodeRequest, opts ...grpc.CallOption) (*MoveNodeResponse, error) { - cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) - out := new(MoveNodeResponse) - err := c.cc.Invoke(ctx, HeadscaleService_MoveNode_FullMethodName, in, out, cOpts...) - if err != nil { - return nil, err - } - return out, nil -} - func (c *headscaleServiceClient) BackfillNodeIPs(ctx context.Context, in *BackfillNodeIPsRequest, opts ...grpc.CallOption) (*BackfillNodeIPsResponse, error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(BackfillNodeIPsResponse) @@ -364,7 +352,6 @@ type HeadscaleServiceServer interface { ExpireNode(context.Context, *ExpireNodeRequest) (*ExpireNodeResponse, error) RenameNode(context.Context, *RenameNodeRequest) (*RenameNodeResponse, error) ListNodes(context.Context, *ListNodesRequest) (*ListNodesResponse, error) - MoveNode(context.Context, *MoveNodeRequest) (*MoveNodeResponse, error) BackfillNodeIPs(context.Context, *BackfillNodeIPsRequest) (*BackfillNodeIPsResponse, error) // --- ApiKeys start --- CreateApiKey(context.Context, *CreateApiKeyRequest) (*CreateApiKeyResponse, error) @@ -434,9 +421,6 @@ func (UnimplementedHeadscaleServiceServer) RenameNode(context.Context, *RenameNo func (UnimplementedHeadscaleServiceServer) ListNodes(context.Context, *ListNodesRequest) (*ListNodesResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method ListNodes not implemented") } -func (UnimplementedHeadscaleServiceServer) MoveNode(context.Context, *MoveNodeRequest) (*MoveNodeResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method MoveNode not implemented") -} func (UnimplementedHeadscaleServiceServer) BackfillNodeIPs(context.Context, *BackfillNodeIPsRequest) (*BackfillNodeIPsResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method BackfillNodeIPs not implemented") } @@ -770,24 +754,6 @@ func _HeadscaleService_ListNodes_Handler(srv interface{}, ctx context.Context, d return interceptor(ctx, in, info, handler) } -func _HeadscaleService_MoveNode_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(MoveNodeRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(HeadscaleServiceServer).MoveNode(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: HeadscaleService_MoveNode_FullMethodName, - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(HeadscaleServiceServer).MoveNode(ctx, req.(*MoveNodeRequest)) - } - return interceptor(ctx, in, info, handler) -} - func _HeadscaleService_BackfillNodeIPs_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(BackfillNodeIPsRequest) if err := dec(in); err != nil { @@ -1003,10 +969,6 @@ var HeadscaleService_ServiceDesc = grpc.ServiceDesc{ MethodName: "ListNodes", Handler: _HeadscaleService_ListNodes_Handler, }, - { - MethodName: "MoveNode", - Handler: _HeadscaleService_MoveNode_Handler, - }, { MethodName: "BackfillNodeIPs", Handler: _HeadscaleService_BackfillNodeIPs_Handler, diff --git a/gen/go/headscale/v1/node.pb.go b/gen/go/headscale/v1/node.pb.go index f04c7e2d..191de8a4 100644 --- a/gen/go/headscale/v1/node.pb.go +++ b/gen/go/headscale/v1/node.pb.go @@ -1006,102 +1006,6 @@ func (x *ListNodesResponse) GetNodes() []*Node { return nil } -type MoveNodeRequest struct { - state protoimpl.MessageState `protogen:"open.v1"` - NodeId uint64 `protobuf:"varint,1,opt,name=node_id,json=nodeId,proto3" json:"node_id,omitempty"` - User uint64 `protobuf:"varint,2,opt,name=user,proto3" json:"user,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *MoveNodeRequest) Reset() { - *x = MoveNodeRequest{} - mi := &file_headscale_v1_node_proto_msgTypes[17] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *MoveNodeRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*MoveNodeRequest) ProtoMessage() {} - -func (x *MoveNodeRequest) ProtoReflect() protoreflect.Message { - mi := &file_headscale_v1_node_proto_msgTypes[17] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use MoveNodeRequest.ProtoReflect.Descriptor instead. -func (*MoveNodeRequest) Descriptor() ([]byte, []int) { - return file_headscale_v1_node_proto_rawDescGZIP(), []int{17} -} - -func (x *MoveNodeRequest) GetNodeId() uint64 { - if x != nil { - return x.NodeId - } - return 0 -} - -func (x *MoveNodeRequest) GetUser() uint64 { - if x != nil { - return x.User - } - return 0 -} - -type MoveNodeResponse struct { - state protoimpl.MessageState `protogen:"open.v1"` - Node *Node `protobuf:"bytes,1,opt,name=node,proto3" json:"node,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *MoveNodeResponse) Reset() { - *x = MoveNodeResponse{} - mi := &file_headscale_v1_node_proto_msgTypes[18] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *MoveNodeResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*MoveNodeResponse) ProtoMessage() {} - -func (x *MoveNodeResponse) ProtoReflect() protoreflect.Message { - mi := &file_headscale_v1_node_proto_msgTypes[18] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use MoveNodeResponse.ProtoReflect.Descriptor instead. -func (*MoveNodeResponse) Descriptor() ([]byte, []int) { - return file_headscale_v1_node_proto_rawDescGZIP(), []int{18} -} - -func (x *MoveNodeResponse) GetNode() *Node { - if x != nil { - return x.Node - } - return nil -} - type DebugCreateNodeRequest struct { state protoimpl.MessageState `protogen:"open.v1"` User string `protobuf:"bytes,1,opt,name=user,proto3" json:"user,omitempty"` @@ -1114,7 +1018,7 @@ type DebugCreateNodeRequest struct { func (x *DebugCreateNodeRequest) Reset() { *x = DebugCreateNodeRequest{} - mi := &file_headscale_v1_node_proto_msgTypes[19] + mi := &file_headscale_v1_node_proto_msgTypes[17] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1126,7 +1030,7 @@ func (x *DebugCreateNodeRequest) String() string { func (*DebugCreateNodeRequest) ProtoMessage() {} func (x *DebugCreateNodeRequest) ProtoReflect() protoreflect.Message { - mi := &file_headscale_v1_node_proto_msgTypes[19] + mi := &file_headscale_v1_node_proto_msgTypes[17] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1139,7 +1043,7 @@ func (x *DebugCreateNodeRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DebugCreateNodeRequest.ProtoReflect.Descriptor instead. func (*DebugCreateNodeRequest) Descriptor() ([]byte, []int) { - return file_headscale_v1_node_proto_rawDescGZIP(), []int{19} + return file_headscale_v1_node_proto_rawDescGZIP(), []int{17} } func (x *DebugCreateNodeRequest) GetUser() string { @@ -1179,7 +1083,7 @@ type DebugCreateNodeResponse struct { func (x *DebugCreateNodeResponse) Reset() { *x = DebugCreateNodeResponse{} - mi := &file_headscale_v1_node_proto_msgTypes[20] + mi := &file_headscale_v1_node_proto_msgTypes[18] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1191,7 +1095,7 @@ func (x *DebugCreateNodeResponse) String() string { func (*DebugCreateNodeResponse) ProtoMessage() {} func (x *DebugCreateNodeResponse) ProtoReflect() protoreflect.Message { - mi := &file_headscale_v1_node_proto_msgTypes[20] + mi := &file_headscale_v1_node_proto_msgTypes[18] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1204,7 +1108,7 @@ func (x *DebugCreateNodeResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use DebugCreateNodeResponse.ProtoReflect.Descriptor instead. func (*DebugCreateNodeResponse) Descriptor() ([]byte, []int) { - return file_headscale_v1_node_proto_rawDescGZIP(), []int{20} + return file_headscale_v1_node_proto_rawDescGZIP(), []int{18} } func (x *DebugCreateNodeResponse) GetNode() *Node { @@ -1223,7 +1127,7 @@ type BackfillNodeIPsRequest struct { func (x *BackfillNodeIPsRequest) Reset() { *x = BackfillNodeIPsRequest{} - mi := &file_headscale_v1_node_proto_msgTypes[21] + mi := &file_headscale_v1_node_proto_msgTypes[19] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1235,7 +1139,7 @@ func (x *BackfillNodeIPsRequest) String() string { func (*BackfillNodeIPsRequest) ProtoMessage() {} func (x *BackfillNodeIPsRequest) ProtoReflect() protoreflect.Message { - mi := &file_headscale_v1_node_proto_msgTypes[21] + mi := &file_headscale_v1_node_proto_msgTypes[19] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1248,7 +1152,7 @@ func (x *BackfillNodeIPsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use BackfillNodeIPsRequest.ProtoReflect.Descriptor instead. func (*BackfillNodeIPsRequest) Descriptor() ([]byte, []int) { - return file_headscale_v1_node_proto_rawDescGZIP(), []int{21} + return file_headscale_v1_node_proto_rawDescGZIP(), []int{19} } func (x *BackfillNodeIPsRequest) GetConfirmed() bool { @@ -1267,7 +1171,7 @@ type BackfillNodeIPsResponse struct { func (x *BackfillNodeIPsResponse) Reset() { *x = BackfillNodeIPsResponse{} - mi := &file_headscale_v1_node_proto_msgTypes[22] + mi := &file_headscale_v1_node_proto_msgTypes[20] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1279,7 +1183,7 @@ func (x *BackfillNodeIPsResponse) String() string { func (*BackfillNodeIPsResponse) ProtoMessage() {} func (x *BackfillNodeIPsResponse) ProtoReflect() protoreflect.Message { - mi := &file_headscale_v1_node_proto_msgTypes[22] + mi := &file_headscale_v1_node_proto_msgTypes[20] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1292,7 +1196,7 @@ func (x *BackfillNodeIPsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use BackfillNodeIPsResponse.ProtoReflect.Descriptor instead. func (*BackfillNodeIPsResponse) Descriptor() ([]byte, []int) { - return file_headscale_v1_node_proto_rawDescGZIP(), []int{22} + return file_headscale_v1_node_proto_rawDescGZIP(), []int{20} } func (x *BackfillNodeIPsResponse) GetChanges() []string { @@ -1371,12 +1275,7 @@ const file_headscale_v1_node_proto_rawDesc = "" + "\x10ListNodesRequest\x12\x12\n" + "\x04user\x18\x01 \x01(\tR\x04user\"=\n" + "\x11ListNodesResponse\x12(\n" + - "\x05nodes\x18\x01 \x03(\v2\x12.headscale.v1.NodeR\x05nodes\">\n" + - "\x0fMoveNodeRequest\x12\x17\n" + - "\anode_id\x18\x01 \x01(\x04R\x06nodeId\x12\x12\n" + - "\x04user\x18\x02 \x01(\x04R\x04user\":\n" + - "\x10MoveNodeResponse\x12&\n" + - "\x04node\x18\x01 \x01(\v2\x12.headscale.v1.NodeR\x04node\"j\n" + + "\x05nodes\x18\x01 \x03(\v2\x12.headscale.v1.NodeR\x05nodes\"j\n" + "\x16DebugCreateNodeRequest\x12\x12\n" + "\x04user\x18\x01 \x01(\tR\x04user\x12\x10\n" + "\x03key\x18\x02 \x01(\tR\x03key\x12\x12\n" + @@ -1407,7 +1306,7 @@ func file_headscale_v1_node_proto_rawDescGZIP() []byte { } var file_headscale_v1_node_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_headscale_v1_node_proto_msgTypes = make([]protoimpl.MessageInfo, 23) +var file_headscale_v1_node_proto_msgTypes = make([]protoimpl.MessageInfo, 21) var file_headscale_v1_node_proto_goTypes = []any{ (RegisterMethod)(0), // 0: headscale.v1.RegisterMethod (*Node)(nil), // 1: headscale.v1.Node @@ -1427,38 +1326,35 @@ var file_headscale_v1_node_proto_goTypes = []any{ (*RenameNodeResponse)(nil), // 15: headscale.v1.RenameNodeResponse (*ListNodesRequest)(nil), // 16: headscale.v1.ListNodesRequest (*ListNodesResponse)(nil), // 17: headscale.v1.ListNodesResponse - (*MoveNodeRequest)(nil), // 18: headscale.v1.MoveNodeRequest - (*MoveNodeResponse)(nil), // 19: headscale.v1.MoveNodeResponse - (*DebugCreateNodeRequest)(nil), // 20: headscale.v1.DebugCreateNodeRequest - (*DebugCreateNodeResponse)(nil), // 21: headscale.v1.DebugCreateNodeResponse - (*BackfillNodeIPsRequest)(nil), // 22: headscale.v1.BackfillNodeIPsRequest - (*BackfillNodeIPsResponse)(nil), // 23: headscale.v1.BackfillNodeIPsResponse - (*User)(nil), // 24: headscale.v1.User - (*timestamppb.Timestamp)(nil), // 25: google.protobuf.Timestamp - (*PreAuthKey)(nil), // 26: headscale.v1.PreAuthKey + (*DebugCreateNodeRequest)(nil), // 18: headscale.v1.DebugCreateNodeRequest + (*DebugCreateNodeResponse)(nil), // 19: headscale.v1.DebugCreateNodeResponse + (*BackfillNodeIPsRequest)(nil), // 20: headscale.v1.BackfillNodeIPsRequest + (*BackfillNodeIPsResponse)(nil), // 21: headscale.v1.BackfillNodeIPsResponse + (*User)(nil), // 22: headscale.v1.User + (*timestamppb.Timestamp)(nil), // 23: google.protobuf.Timestamp + (*PreAuthKey)(nil), // 24: headscale.v1.PreAuthKey } var file_headscale_v1_node_proto_depIdxs = []int32{ - 24, // 0: headscale.v1.Node.user:type_name -> headscale.v1.User - 25, // 1: headscale.v1.Node.last_seen:type_name -> google.protobuf.Timestamp - 25, // 2: headscale.v1.Node.expiry:type_name -> google.protobuf.Timestamp - 26, // 3: headscale.v1.Node.pre_auth_key:type_name -> headscale.v1.PreAuthKey - 25, // 4: headscale.v1.Node.created_at:type_name -> google.protobuf.Timestamp + 22, // 0: headscale.v1.Node.user:type_name -> headscale.v1.User + 23, // 1: headscale.v1.Node.last_seen:type_name -> google.protobuf.Timestamp + 23, // 2: headscale.v1.Node.expiry:type_name -> google.protobuf.Timestamp + 24, // 3: headscale.v1.Node.pre_auth_key:type_name -> headscale.v1.PreAuthKey + 23, // 4: headscale.v1.Node.created_at:type_name -> google.protobuf.Timestamp 0, // 5: headscale.v1.Node.register_method:type_name -> headscale.v1.RegisterMethod 1, // 6: headscale.v1.RegisterNodeResponse.node:type_name -> headscale.v1.Node 1, // 7: headscale.v1.GetNodeResponse.node:type_name -> headscale.v1.Node 1, // 8: headscale.v1.SetTagsResponse.node:type_name -> headscale.v1.Node 1, // 9: headscale.v1.SetApprovedRoutesResponse.node:type_name -> headscale.v1.Node - 25, // 10: headscale.v1.ExpireNodeRequest.expiry:type_name -> google.protobuf.Timestamp + 23, // 10: headscale.v1.ExpireNodeRequest.expiry:type_name -> google.protobuf.Timestamp 1, // 11: headscale.v1.ExpireNodeResponse.node:type_name -> headscale.v1.Node 1, // 12: headscale.v1.RenameNodeResponse.node:type_name -> headscale.v1.Node 1, // 13: headscale.v1.ListNodesResponse.nodes:type_name -> headscale.v1.Node - 1, // 14: headscale.v1.MoveNodeResponse.node:type_name -> headscale.v1.Node - 1, // 15: headscale.v1.DebugCreateNodeResponse.node:type_name -> headscale.v1.Node - 16, // [16:16] is the sub-list for method output_type - 16, // [16:16] is the sub-list for method input_type - 16, // [16:16] is the sub-list for extension type_name - 16, // [16:16] is the sub-list for extension extendee - 0, // [0:16] is the sub-list for field type_name + 1, // 14: headscale.v1.DebugCreateNodeResponse.node:type_name -> headscale.v1.Node + 15, // [15:15] is the sub-list for method output_type + 15, // [15:15] is the sub-list for method input_type + 15, // [15:15] is the sub-list for extension type_name + 15, // [15:15] is the sub-list for extension extendee + 0, // [0:15] is the sub-list for field type_name } func init() { file_headscale_v1_node_proto_init() } @@ -1474,7 +1370,7 @@ func file_headscale_v1_node_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_headscale_v1_node_proto_rawDesc), len(file_headscale_v1_node_proto_rawDesc)), NumEnums: 1, - NumMessages: 23, + NumMessages: 21, NumExtensions: 0, NumServices: 0, }, diff --git a/gen/openapiv2/headscale/v1/headscale.swagger.json b/gen/openapiv2/headscale/v1/headscale.swagger.json index 6a7b48ad..5b163878 100644 --- a/gen/openapiv2/headscale/v1/headscale.swagger.json +++ b/gen/openapiv2/headscale/v1/headscale.swagger.json @@ -496,45 +496,6 @@ ] } }, - "/api/v1/node/{nodeId}/user": { - "post": { - "operationId": "HeadscaleService_MoveNode", - "responses": { - "200": { - "description": "A successful response.", - "schema": { - "$ref": "#/definitions/v1MoveNodeResponse" - } - }, - "default": { - "description": "An unexpected error response.", - "schema": { - "$ref": "#/definitions/rpcStatus" - } - } - }, - "parameters": [ - { - "name": "nodeId", - "in": "path", - "required": true, - "type": "string", - "format": "uint64" - }, - { - "name": "body", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/HeadscaleServiceMoveNodeBody" - } - } - ], - "tags": [ - "HeadscaleService" - ] - } - }, "/api/v1/policy": { "get": { "summary": "--- Policy start ---", @@ -826,15 +787,6 @@ } }, "definitions": { - "HeadscaleServiceMoveNodeBody": { - "type": "object", - "properties": { - "user": { - "type": "string", - "format": "uint64" - } - } - }, "HeadscaleServiceSetApprovedRoutesBody": { "type": "object", "properties": { @@ -1142,14 +1094,6 @@ } } }, - "v1MoveNodeResponse": { - "type": "object", - "properties": { - "node": { - "$ref": "#/definitions/v1Node" - } - } - }, "v1Node": { "type": "object", "properties": { diff --git a/hscontrol/db/users.go b/hscontrol/db/users.go index 039933c7..dff235e4 100644 --- a/hscontrol/db/users.go +++ b/hscontrol/db/users.go @@ -196,26 +196,6 @@ func ListNodesByUser(tx *gorm.DB, uid types.UserID) (types.Nodes, error) { return nodes, nil } -// AssignNodeToUser assigns a Node to a user. -// Note: Validation should be done in the state layer before calling this function. -func AssignNodeToUser(tx *gorm.DB, nodeID types.NodeID, uid types.UserID) error { - // Check if the user exists - var userExists bool - if err := tx.Model(&types.User{}).Select("count(*) > 0").Where("id = ?", uid).Find(&userExists).Error; err != nil { - return fmt.Errorf("failed to check if user exists: %w", err) - } - - if !userExists { - return ErrUserNotFound - } - - if err := tx.Model(&types.Node{}).Where("id = ?", nodeID).Update("user_id", uid).Error; err != nil { - return fmt.Errorf("failed to assign node to user: %w", err) - } - - return nil -} - func (hsdb *HSDatabase) CreateUserForTest(name ...string) *types.User { if !testing.Testing() { panic("CreateUserForTest can only be called during tests") diff --git a/hscontrol/db/users_test.go b/hscontrol/db/users_test.go index 53a10e80..1ea0772c 100644 --- a/hscontrol/db/users_test.go +++ b/hscontrol/db/users_test.go @@ -165,112 +165,3 @@ func TestRenameUser(t *testing.T) { }) } } - -func TestAssignNodeToUser(t *testing.T) { - tests := []struct { - name string - test func(*testing.T, *HSDatabase) - }{ - { - name: "success_reassign_node", - test: func(t *testing.T, db *HSDatabase) { - t.Helper() - - oldUser := db.CreateUserForTest("old") - newUser := db.CreateUserForTest("new") - - pak, err := db.CreatePreAuthKey(types.UserID(oldUser.ID), false, false, nil, nil) - require.NoError(t, err) - - node := types.Node{ - ID: 12, - Hostname: "testnode", - UserID: oldUser.ID, - RegisterMethod: util.RegisterMethodAuthKey, - AuthKeyID: ptr.To(pak.ID), - } - trx := db.DB.Save(&node) - require.NoError(t, trx.Error) - assert.Equal(t, oldUser.ID, node.UserID) - - err = db.Write(func(tx *gorm.DB) error { - return AssignNodeToUser(tx, 12, types.UserID(newUser.ID)) - }) - require.NoError(t, err) - - // Reload node from database to see updated values - updatedNode, err := db.GetNodeByID(12) - require.NoError(t, err) - assert.Equal(t, newUser.ID, updatedNode.UserID) - assert.Equal(t, newUser.Name, updatedNode.User.Name) - }, - }, - { - name: "error_user_not_found", - test: func(t *testing.T, db *HSDatabase) { - t.Helper() - - oldUser := db.CreateUserForTest("old") - - pak, err := db.CreatePreAuthKey(types.UserID(oldUser.ID), false, false, nil, nil) - require.NoError(t, err) - - node := types.Node{ - ID: 12, - Hostname: "testnode", - UserID: oldUser.ID, - RegisterMethod: util.RegisterMethodAuthKey, - AuthKeyID: ptr.To(pak.ID), - } - trx := db.DB.Save(&node) - require.NoError(t, trx.Error) - - err = db.Write(func(tx *gorm.DB) error { - return AssignNodeToUser(tx, 12, 9584849) - }) - assert.ErrorIs(t, err, ErrUserNotFound) - }, - }, - { - name: "success_reassign_to_same_user", - test: func(t *testing.T, db *HSDatabase) { - t.Helper() - - user := db.CreateUserForTest("user") - - pak, err := db.CreatePreAuthKey(types.UserID(user.ID), false, false, nil, nil) - require.NoError(t, err) - - node := types.Node{ - ID: 12, - Hostname: "testnode", - UserID: user.ID, - RegisterMethod: util.RegisterMethodAuthKey, - AuthKeyID: ptr.To(pak.ID), - } - trx := db.DB.Save(&node) - require.NoError(t, trx.Error) - - err = db.Write(func(tx *gorm.DB) error { - return AssignNodeToUser(tx, 12, types.UserID(user.ID)) - }) - require.NoError(t, err) - - // Reload node from database again to see updated values - finalNode, err := db.GetNodeByID(12) - require.NoError(t, err) - assert.Equal(t, user.ID, finalNode.UserID) - assert.Equal(t, user.Name, finalNode.User.Name) - }, - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - db, err := newSQLiteTestDB() - require.NoError(t, err) - - tt.test(t, db) - }) - } -} diff --git a/hscontrol/grpcv1.go b/hscontrol/grpcv1.go index 3b8e9d47..ea37226c 100644 --- a/hscontrol/grpcv1.go +++ b/hscontrol/grpcv1.go @@ -527,22 +527,6 @@ func nodesToProto(state *state.State, nodes views.Slice[types.NodeView]) []*v1.N return response } -func (api headscaleV1APIServer) MoveNode( - ctx context.Context, - request *v1.MoveNodeRequest, -) (*v1.MoveNodeResponse, error) { - node, nodeChange, err := api.h.state.AssignNodeToUser(types.NodeID(request.GetNodeId()), types.UserID(request.GetUser())) - if err != nil { - return nil, err - } - - // TODO(kradalby): Ensure the policy is also sent - // TODO(kradalby): ensure that both the selfupdate and peer updates are sent - api.h.Change(nodeChange) - - return &v1.MoveNodeResponse{Node: node.Proto()}, nil -} - func (api headscaleV1APIServer) BackfillNodeIPs( ctx context.Context, request *v1.BackfillNodeIPsRequest, diff --git a/hscontrol/state/state.go b/hscontrol/state/state.go index e044241f..d7eb2724 100644 --- a/hscontrol/state/state.go +++ b/hscontrol/state/state.go @@ -729,34 +729,6 @@ func (s *State) RenameNode(nodeID types.NodeID, newName string) (types.NodeView, return s.persistNodeToDB(n) } -// AssignNodeToUser transfers a node to a different user. -func (s *State) AssignNodeToUser(nodeID types.NodeID, userID types.UserID) (types.NodeView, change.ChangeSet, error) { - // Validate that both node and user exist - _, found := s.GetNodeByID(nodeID) - if !found { - return types.NodeView{}, change.EmptySet, fmt.Errorf("node not found: %d", nodeID) - } - - user, err := s.GetUserByID(userID) - if err != nil { - return types.NodeView{}, change.EmptySet, fmt.Errorf("user not found: %w", err) - } - - // Update NodeStore before database to ensure consistency. The NodeStore update is - // blocking and will be the source of truth for the batcher. The database update must - // make the exact same change. - n, ok := s.nodeStore.UpdateNode(nodeID, func(n *types.Node) { - n.User = *user - n.UserID = uint(userID) - }) - - if !ok { - return types.NodeView{}, change.EmptySet, fmt.Errorf("node not found in NodeStore: %d", nodeID) - } - - return s.persistNodeToDB(n) -} - // BackfillNodeIPs assigns IP addresses to nodes that don't have them. func (s *State) BackfillNodeIPs() ([]string, error) { changes, err := s.db.BackfillNodeIPs(s.ipAlloc) diff --git a/integration/cli_test.go b/integration/cli_test.go index dca37570..fd2321b4 100644 --- a/integration/cli_test.go +++ b/integration/cli_test.go @@ -1644,178 +1644,6 @@ func TestNodeRenameCommand(t *testing.T) { assert.Contains(t, listAllAfterRenameAttempt[4].GetGivenName(), "node-5") } -func TestNodeMoveCommand(t *testing.T) { - IntegrationSkip(t) - - spec := ScenarioSpec{ - Users: []string{"old-user", "new-user"}, - } - - scenario, err := NewScenario(spec) - require.NoError(t, err) - defer scenario.ShutdownAssertNoPanics(t) - - err = scenario.CreateHeadscaleEnv([]tsic.Option{}, hsic.WithTestName("clins")) - require.NoError(t, err) - - headscale, err := scenario.Headscale() - require.NoError(t, err) - - // Randomly generated node key - regID := types.MustRegistrationID() - - userMap, err := headscale.MapUsers() - require.NoError(t, err) - - _, err = headscale.Execute( - []string{ - "headscale", - "debug", - "create-node", - "--name", - "nomad-node", - "--user", - "old-user", - "--key", - regID.String(), - "--output", - "json", - }, - ) - assert.NoError(t, err) - - var node v1.Node - assert.EventuallyWithT(t, func(c *assert.CollectT) { - err = executeAndUnmarshal( - headscale, - []string{ - "headscale", - "nodes", - "--user", - "old-user", - "register", - "--key", - regID.String(), - "--output", - "json", - }, - &node, - ) - assert.NoError(c, err) - }, 10*time.Second, 200*time.Millisecond, "Waiting for old-user node registration") - - assert.Equal(t, uint64(1), node.GetId()) - assert.Equal(t, "nomad-node", node.GetName()) - assert.Equal(t, "old-user", node.GetUser().GetName()) - - nodeID := strconv.FormatUint(node.GetId(), 10) - - assert.EventuallyWithT(t, func(c *assert.CollectT) { - err = executeAndUnmarshal( - headscale, - []string{ - "headscale", - "nodes", - "move", - "--identifier", - strconv.FormatUint(node.GetId(), 10), - "--user", - strconv.FormatUint(userMap["new-user"].GetId(), 10), - "--output", - "json", - }, - &node, - ) - assert.NoError(c, err) - }, 10*time.Second, 200*time.Millisecond, "Waiting for node move to new-user") - - assert.Equal(t, "new-user", node.GetUser().GetName()) - - var allNodes []v1.Node - assert.EventuallyWithT(t, func(c *assert.CollectT) { - err = executeAndUnmarshal( - headscale, - []string{ - "headscale", - "nodes", - "list", - "--output", - "json", - }, - &allNodes, - ) - assert.NoError(c, err) - }, 10*time.Second, 200*time.Millisecond, "Waiting for nodes list after move") - - assert.Len(t, allNodes, 1) - - assert.Equal(t, allNodes[0].GetId(), node.GetId()) - assert.Equal(t, allNodes[0].GetUser(), node.GetUser()) - assert.Equal(t, "new-user", allNodes[0].GetUser().GetName()) - - _, err = headscale.Execute( - []string{ - "headscale", - "nodes", - "move", - "--identifier", - nodeID, - "--user", - "999", - "--output", - "json", - }, - ) - assert.ErrorContains( - t, - err, - "user not found", - ) - assert.Equal(t, "new-user", node.GetUser().GetName()) - - assert.EventuallyWithT(t, func(c *assert.CollectT) { - err = executeAndUnmarshal( - headscale, - []string{ - "headscale", - "nodes", - "move", - "--identifier", - nodeID, - "--user", - strconv.FormatUint(userMap["old-user"].GetId(), 10), - "--output", - "json", - }, - &node, - ) - assert.NoError(c, err) - }, 10*time.Second, 200*time.Millisecond, "Waiting for node move back to old-user") - - assert.Equal(t, "old-user", node.GetUser().GetName()) - - assert.EventuallyWithT(t, func(c *assert.CollectT) { - err = executeAndUnmarshal( - headscale, - []string{ - "headscale", - "nodes", - "move", - "--identifier", - nodeID, - "--user", - strconv.FormatUint(userMap["old-user"].GetId(), 10), - "--output", - "json", - }, - &node, - ) - assert.NoError(c, err) - }, 10*time.Second, 200*time.Millisecond, "Waiting for node move to same user") - - assert.Equal(t, "old-user", node.GetUser().GetName()) -} - func TestPolicyCommand(t *testing.T) { IntegrationSkip(t) diff --git a/proto/headscale/v1/headscale.proto b/proto/headscale/v1/headscale.proto index 3b42a3f3..69882e43 100644 --- a/proto/headscale/v1/headscale.proto +++ b/proto/headscale/v1/headscale.proto @@ -123,13 +123,6 @@ service HeadscaleService { }; } - rpc MoveNode(MoveNodeRequest) returns (MoveNodeResponse) { - option (google.api.http) = { - post : "/api/v1/node/{node_id}/user", - body : "*" - }; - } - rpc BackfillNodeIPs(BackfillNodeIPsRequest) returns (BackfillNodeIPsResponse) { option (google.api.http) = { diff --git a/proto/headscale/v1/node.proto b/proto/headscale/v1/node.proto index fb074008..504db0be 100644 --- a/proto/headscale/v1/node.proto +++ b/proto/headscale/v1/node.proto @@ -100,13 +100,6 @@ message ListNodesRequest { string user = 1; } message ListNodesResponse { repeated Node nodes = 1; } -message MoveNodeRequest { - uint64 node_id = 1; - uint64 user = 2; -} - -message MoveNodeResponse { Node node = 1; } - message DebugCreateNodeRequest { string user = 1; string key = 2;