// 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";

// 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);

    // GetLogs Returns historical and/or streaming logs for a given DN with given filters from the system global
    // LogTree.
    //
    // For more information about this API, see //metropolis/pkg/logtree. But, in summary:
    //   - All logging is performed to a DN (distinguished name), which is a dot-delimited string like foo.bar.baz.
    //   - Log entries can be either raw (coming from unstructured logging from an external service, like a running
    //     process) or leveled (emitted by Metropolis code with a source line, timestamp, and severity).
    //   - The DNs form a tree of logging nodes - and when requesting logs, a given subtree of DNs can be requested,
    //     instead of just a given DN.
    //   - All supervised processes live at `root.<supervisor DN>`. For more example paths, see the console logs of
    //     a running Metropolis node, or request all logs (at DN "").
    //
    // TODO(q3k): move method and its related messages to the non-debug node endpoint once we have one.
    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;
}

// Severity level corresponding to //metropolis/pkg/logtree.Severity.
enum LeveledLogSeverity {
    INVALID = 0;
    INFO = 1;
    WARNING = 2;
    ERROR = 3;
    FATAL = 4;
}

// Filter set when requesting logs for a given DN. This message is equivalent to the following GADT enum:
// data LogFilter = WithChildren
//                | OnlyRaw
//                | OnlyLeveled
//                | LeveledWithMinimumSeverity(Severity)
//
// Multiple LogFilters can be chained/combined when requesting logs, as long as they do not conflict.
message LogFilter {
    // Entries will be returned not only for the given DN, but all child DNs as well. For instance, if the
    // requested DN is foo, entries logged to foo, foo.bar and foo.bar.baz will all be returned.
    message WithChildren {
    }
    // Only raw logging entries will be returned. Conflicts with OnlyLeveled filters.
    message OnlyRaw {
    }
    // Only leveled logging entries will be returned. Conflicts with OnlyRaw filters.
    message OnlyLeveled {
    }
    // If leveled logs are returned, all entries at severity lower than `minimum` will be discarded.
    message LeveledWithMinimumSeverity {
        LeveledLogSeverity minimum = 1;
    }
    oneof filter {
        WithChildren with_children = 1;
        OnlyRaw only_raw = 3;
        OnlyLeveled only_leveled = 4;
        LeveledWithMinimumSeverity leveled_with_minimum_severity = 5;
    }
}

message GetLogsRequest {
    // DN from which to request logs. All supervised runnables live at `root.`, the init code lives at `init.`.
    string dn = 1;
    // Filters to apply to returned data.
    repeated LogFilter filters = 2;

    enum BacklogMode {
        BACKLOG_INVALID = 0;
        // No historic data will be returned.
        BACKLOG_DISABLE = 1;
        // All available historic data will be returned.
        BACKLOG_ALL = 2;
        // At most backlog_count entries will be returned, if available.
        BACKLOG_COUNT = 3;
    }
    BacklogMode backlog_mode = 3;
    int64 backlog_count = 4;

    enum StreamMode {
        STREAM_INVALID = 0;
        // No streaming entries, gRPC stream will be closed as soon as all backlog data is served.
        STREAM_DISABLE = 1;
        // Entries will be streamed as early as available right after all backlog data is served.
        STREAM_UNBUFFERED = 2;
    }
    StreamMode stream_mode = 5;
}

message GetLogsResponse {
    // Entries from the requested historical entries (via WithBackLog). They will all be served before the first
    // stream_entries are served (if any).
    repeated LogEntry backlog_entries = 1;
    // Entries streamed as they arrive. Currently no server-side buffering is enabled, instead every line is served
    // as early as it arrives. However, this might change in the future, so this behaviour cannot be depended
    // upon.
    repeated LogEntry stream_entries = 2;
}

message LogEntry {
    message Leveled {
        repeated string lines = 1;
        int64 timestamp = 2;
        LeveledLogSeverity severity = 3;
        string location = 4;
    }
    message Raw {
        string data = 1;
        int64 original_length = 2;
    }

    string dn = 1;
    oneof kind {
        Leveled leveled = 2;
        Raw raw = 3;
    }
}

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;
}