// Copyright 2016 Google Inc.
//
// 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 google.logging.v2;

import "google.golang.org/genproto/googleapis/api/serviceconfig/annotations.proto"; // from google/api/annotations.proto
import "github.com/golang/protobuf/ptypes/empty/empty.proto"; // from google/protobuf/empty.proto
import "github.com/golang/protobuf/ptypes/timestamp/timestamp.proto"; // from google/protobuf/timestamp.proto

option java_multiple_files = true;
option java_outer_classname = "LoggingConfig";
option java_package = "com.google.logging.v2";

option go_package = "google.golang.org/genproto/googleapis/logging/v2";

// Service for configuring sinks used to export log entries outside Stackdriver
// Logging.
service ConfigServiceV2 {
  // Lists sinks.
  rpc ListSinks(ListSinksRequest) returns (ListSinksResponse) {
    option (google.api.http) = { get: "/v2/{parent=projects/*}/sinks" };
  }

  // Gets a sink.
  rpc GetSink(GetSinkRequest) returns (LogSink) {
    option (google.api.http) = { get: "/v2/{sink_name=projects/*/sinks/*}" };
  }

  // Creates a sink.
  rpc CreateSink(CreateSinkRequest) returns (LogSink) {
    option (google.api.http) = { post: "/v2/{parent=projects/*}/sinks" body: "sink" };
  }

  // Updates or creates a sink.
  rpc UpdateSink(UpdateSinkRequest) returns (LogSink) {
    option (google.api.http) = { put: "/v2/{sink_name=projects/*/sinks/*}" body: "sink" };
  }

  // Deletes a sink.
  rpc DeleteSink(DeleteSinkRequest) returns (google.protobuf.Empty) {
    option (google.api.http) = { delete: "/v2/{sink_name=projects/*/sinks/*}" };
  }
}

// Describes a sink used to export log entries outside Stackdriver Logging.
message LogSink {
  // Available log entry formats. Log entries can be written to Cloud
  // Logging in either format and can be exported in either format.
  // Version 2 is the preferred format.
  enum VersionFormat {
    // An unspecified version format will default to V2.
    VERSION_FORMAT_UNSPECIFIED = 0;

    // `LogEntry` version 2 format.
    V2 = 1;

    // `LogEntry` version 1 format.
    V1 = 2;
  }

  // Required. The client-assigned sink identifier, unique within the
  // project. Example: `"my-syslog-errors-to-pubsub"`.  Sink identifiers are
  // limited to 1000 characters and can include only the following characters:
  // `A-Z`, `a-z`, `0-9`, and the special characters `_-.`.  The maximum length
  // of the name is 100 characters.
  string name = 1;

  // Required. The export destination. See
  // [Exporting Logs With Sinks](/logging/docs/api/tasks/exporting-logs).
  // Examples:
  //
  //     "storage.googleapis.com/my-gcs-bucket"
  //     "bigquery.googleapis.com/projects/my-project-id/datasets/my-dataset"
  //     "pubsub.googleapis.com/projects/my-project/topics/my-topic"
  string destination = 3;

  // Optional. An [advanced logs filter](/logging/docs/view/advanced_filters).
  // Only log entries matching the filter are exported. The filter
  // must be consistent with the log entry format specified by the
  // `outputVersionFormat` parameter, regardless of the format of the
  // log entry that was originally written to Stackdriver Logging.
  // Example filter (V2 format):
  //
  //     logName=projects/my-projectid/logs/syslog AND severity>=ERROR
  string filter = 5;

  // Optional. The log entry version to use for this sink's exported log
  // entries.  This version does not have to correspond to the version of the
  // log entry that was written to Stackdriver Logging. If omitted, the
  // v2 format is used.
  VersionFormat output_version_format = 6;

  // Output only. The iam identity to which the destination needs to grant write
  // access.  This may be a service account or a group.
  // Examples (Do not assume these specific values):
  //    "serviceAccount:cloud-logs@system.gserviceaccount.com"
  //    "group:cloud-logs@google.com"
  //
  //   For GCS destinations, the role "roles/owner" is required on the bucket
  //   For Cloud Pubsub destinations, the role "roles/pubsub.publisher" is
  //     required on the topic
  //   For BigQuery, the role "roles/editor" is required on the dataset
  string writer_identity = 8;
}

// The parameters to `ListSinks`.
message ListSinksRequest {
  // Required. The cloud resource containing the sinks.
  // Example: `"projects/my-logging-project"`.
  string parent = 1;

  // Optional. If present, then retrieve the next batch of results from the
  // preceding call to this method.  `pageToken` must be the value of
  // `nextPageToken` from the previous response.  The values of other method
  // parameters should be identical to those in the previous call.
  string page_token = 2;

  // Optional. The maximum number of results to return from this request.
  // Non-positive values are ignored.  The presence of `nextPageToken` in the
  // response indicates that more results might be available.
  int32 page_size = 3;
}

// Result returned from `ListSinks`.
message ListSinksResponse {
  // A list of sinks.
  repeated LogSink sinks = 1;

  // If there might be more results than appear in this response, then
  // `nextPageToken` is included.  To get the next set of results, call the same
  // method again using the value of `nextPageToken` as `pageToken`.
  string next_page_token = 2;
}

// The parameters to `GetSink`.
message GetSinkRequest {
  // Required. The resource name of the sink to return.
  // Example: `"projects/my-project-id/sinks/my-sink-id"`.
  string sink_name = 1;
}

// The parameters to `CreateSink`.
message CreateSinkRequest {
  // Required. The resource in which to create the sink.
  // Example: `"projects/my-project-id"`.
  // The new sink must be provided in the request.
  string parent = 1;

  // Required. The new sink, whose `name` parameter is a sink identifier that
  // is not already in use.
  LogSink sink = 2;
}

// The parameters to `UpdateSink`.
message UpdateSinkRequest {
  // Required. The resource name of the sink to update, including the parent
  // resource and the sink identifier.  If the sink does not exist, this method
  // creates the sink.  Example: `"projects/my-project-id/sinks/my-sink-id"`.
  string sink_name = 1;

  // Required. The updated sink, whose name is the same identifier that appears
  // as part of `sinkName`.  If `sinkName` does not exist, then
  // this method creates a new sink.
  LogSink sink = 2;
}

// The parameters to `DeleteSink`.
message DeleteSinkRequest {
  // Required. The resource name of the sink to delete, including the parent
  // resource and the sink identifier.  Example:
  // `"projects/my-project-id/sinks/my-sink-id"`.  It is an error if the sink
  // does not exist.
  string sink_name = 1;
}
