// 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 = "git.monogon.dev/source/nexantic.git/metropolis/proto/api";

import "metropolis/proto/api/enrolment.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);

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

    // GetGoldenTicket requests a 'golden ticket' which can be used to enroll any node into the cluster.
    // This bypasses integrity checks.
    rpc GetGoldenTicket(GetGoldenTicketRequest) returns (GetGoldenTicketResponse);
}


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 GetGoldenTicketRequest {
    // IP address at which the new node will run.
    string external_ip = 1;
}

message GetGoldenTicketResponse {
    // Ticket to use in the new node's EnrolmentConfig.
    GoldenTicket ticket = 1;
}
