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


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