// Copyright 2020 The Monogon Project Authors.
//
// SPDX-License-Identifier: Apache-2.0
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

syntax = "proto3";
package metropolis.proto.api;
option go_package = "source.monogon.dev/metropolis/proto/api";

import "google/protobuf/timestamp.proto";
import "metropolis/proto/api/management.proto";

// NodeDebugService exposes debug and testing endpoints that allow introspection into a running Metropolis node.
// It is not authenticated and will be disabled in production. It is currently consumed by metropolis/cli/dbg and
// by tests.
service NodeDebugService {
    // GetDebugKubeconfig issues kubeconfigs with arbitrary identities and groups for debugging
    rpc GetDebugKubeconfig(GetDebugKubeconfigRequest) returns (GetDebugKubeconfigResponse);

    // A reimplementation of metropolis.api.NodeManagement.Logs that's available
    // before the node starts up the management service.
    rpc GetLogs(GetLogsRequest) returns (stream GetLogsResponse);

    // Trace enables tracing of Metropolis using the Linux ftrace infrastructure.
    rpc Trace(TraceRequest) returns (stream TraceEvent);

    // LoadImage loads an uncompressed tarball containing a Docker v1.1, v1.2 or OCI v1 image into the local
    // containerd image store. The client streams the tarball in arbitrary-sized chunks and closes the sending side
    // once it has sent the entire image. The server then either returns an empty response if successful or a gRPC error.
    rpc LoadImage(stream ImagePart) returns (LoadImageResponse);
}

message ImagePart {
    bytes data_part = 1;
}

message LoadImageResponse {
}

message GetDebugKubeconfigRequest {
    string id = 1; // Kubernetes identity (user)
    repeated string groups = 2; // Kubernetes groups
}

message GetDebugKubeconfigResponse {
    string debug_kubeconfig = 1;
}

message TraceRequest {
    // Name of the tracer to use. Defined in https://www.kernel.org/doc/html/latest/trace/ftrace.html#the-tracers.
    // Useful ones enabled in Metropolis: function_graph, function.
    // Gets reset to nop automatically after the stream is terminated.
    string tracer = 1;

    // List of functions to trace. Accepts wildcards using the '*' character. If left empty traces all functions.
    repeated string function_filter = 2;

    // List of functions and their descendants to trace with the function_graph tracer.
    repeated string graph_function_filter = 3;
}

message TraceEvent {
    // Currently we do not parse the event data and just return what the kernel outputs, line-by-line.
    string raw_line = 1;
}
