// 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.monitoring.v3;

import "google/api/annotations.proto";
import "google/api/monitored_resource.proto";
import "google/monitoring/v3/common.proto";
import "google/monitoring/v3/group.proto";
import "google/protobuf/empty.proto";

option csharp_namespace = "Google.Cloud.Monitoring.V3";
option go_package = "google.golang.org/genproto/googleapis/monitoring/v3;monitoring";
option java_multiple_files = true;
option java_outer_classname = "GroupServiceProto";
option java_package = "com.google.monitoring.v3";


// The Group API lets you inspect and manage your
// [groups](google.monitoring.v3.Group).
//
// A group is a named filter that is used to identify
// a collection of monitored resources. Groups are typically used to
// mirror the physical and/or logical topology of the environment.
// Because group membership is computed dynamically, monitored
// resources that are started in the future are automatically placed
// in matching groups. By using a group to name monitored resources in,
// for example, an alert policy, the target of that alert policy is
// updated automatically as monitored resources are added and removed
// from the infrastructure.
service GroupService {
  // Lists the existing groups.
  rpc ListGroups(ListGroupsRequest) returns (ListGroupsResponse) {
    option (google.api.http) = { get: "/v3/{name=projects/*}/groups" };
  }

  // Gets a single group.
  rpc GetGroup(GetGroupRequest) returns (Group) {
    option (google.api.http) = { get: "/v3/{name=projects/*/groups/*}" };
  }

  // Creates a new group.
  rpc CreateGroup(CreateGroupRequest) returns (Group) {
    option (google.api.http) = { post: "/v3/{name=projects/*}/groups" body: "group" };
  }

  // Updates an existing group.
  // You can change any group attributes except `name`.
  rpc UpdateGroup(UpdateGroupRequest) returns (Group) {
    option (google.api.http) = { put: "/v3/{group.name=projects/*/groups/*}" body: "group" };
  }

  // Deletes an existing group.
  rpc DeleteGroup(DeleteGroupRequest) returns (google.protobuf.Empty) {
    option (google.api.http) = { delete: "/v3/{name=projects/*/groups/*}" };
  }

  // Lists the monitored resources that are members of a group.
  rpc ListGroupMembers(ListGroupMembersRequest) returns (ListGroupMembersResponse) {
    option (google.api.http) = { get: "/v3/{name=projects/*/groups/*}/members" };
  }
}

// The `ListGroup` request.
message ListGroupsRequest {
  // The project whose groups are to be listed. The format is
  // `"projects/{project_id_or_number}"`.
  string name = 7;

  // An optional filter consisting of a single group name.  The filters limit the
  // groups returned based on their parent-child relationship with the specified
  // group. If no filter is specified, all groups are returned.
  oneof filter {
    // A group name: `"projects/{project_id_or_number}/groups/{group_id}"`.
    // Returns groups whose `parentName` field contains the group
    // name.  If no groups have this parent, the results are empty.
    string children_of_group = 2;

    // A group name: `"projects/{project_id_or_number}/groups/{group_id}"`.
    // Returns groups that are ancestors of the specified group.
    // The groups are returned in order, starting with the immediate parent and
    // ending with the most distant ancestor.  If the specified group has no
    // immediate parent, the results are empty.
    string ancestors_of_group = 3;

    // A group name: `"projects/{project_id_or_number}/groups/{group_id}"`.
    // Returns the descendants of the specified group.  This is a superset of
    // the results returned by the `childrenOfGroup` filter, and includes
    // children-of-children, and so forth.
    string descendants_of_group = 4;
  }

  // A positive number that is the maximum number of results to return.
  int32 page_size = 5;

  // If this field is not empty then it must contain the `nextPageToken` value
  // returned by a previous call to this method.  Using this field causes the
  // method to return additional results from the previous method call.
  string page_token = 6;
}

// The `ListGroups` response.
message ListGroupsResponse {
  // The groups that match the specified filters.
  repeated Group group = 1;

  // If there are more results than have been returned, then this field is set
  // to a non-empty value.  To see the additional results,
  // use that value as `pageToken` in the next call to this method.
  string next_page_token = 2;
}

// The `GetGroup` request.
message GetGroupRequest {
  // The group to retrieve. The format is
  // `"projects/{project_id_or_number}/groups/{group_id}"`.
  string name = 3;
}

// The `CreateGroup` request.
message CreateGroupRequest {
  // The project in which to create the group. The format is
  // `"projects/{project_id_or_number}"`.
  string name = 4;

  // A group definition. It is an error to define the `name` field because
  // the system assigns the name.
  Group group = 2;

  // If true, validate this request but do not create the group.
  bool validate_only = 3;
}

// The `UpdateGroup` request.
message UpdateGroupRequest {
  // The new definition of the group.  All fields of the existing group,
  // excepting `name`, are replaced with the corresponding fields of this group.
  Group group = 2;

  // If true, validate this request but do not update the existing group.
  bool validate_only = 3;
}

// The `DeleteGroup` request. You can only delete a group if it has no children.
message DeleteGroupRequest {
  // The group to delete. The format is
  // `"projects/{project_id_or_number}/groups/{group_id}"`.
  string name = 3;
}

// The `ListGroupMembers` request.
message ListGroupMembersRequest {
  // The group whose members are listed. The format is
  // `"projects/{project_id_or_number}/groups/{group_id}"`.
  string name = 7;

  // A positive number that is the maximum number of results to return.
  int32 page_size = 3;

  // If this field is not empty then it must contain the `nextPageToken` value
  // returned by a previous call to this method.  Using this field causes the
  // method to return additional results from the previous method call.
  string page_token = 4;

  // An optional [list filter](/monitoring/api/learn_more#filtering) describing
  // the members to be returned.  The filter may reference the type, labels, and
  // metadata of monitored resources that comprise the group.
  // For example, to return only resources representing Compute Engine VM
  // instances, use this filter:
  //
  //     resource.type = "gce_instance"
  string filter = 5;

  // An optional time interval for which results should be returned. Only
  // members that were part of the group during the specified interval are
  // included in the response.  If no interval is provided then the group
  // membership over the last minute is returned.
  TimeInterval interval = 6;
}

// The `ListGroupMembers` response.
message ListGroupMembersResponse {
  // A set of monitored resources in the group.
  repeated google.api.MonitoredResource members = 1;

  // If there are more results than have been returned, then this field is
  // set to a non-empty value.  To see the additional results, use that value as
  // `pageToken` in the next call to this method.
  string next_page_token = 2;

  // The total number of elements matching this request.
  int32 total_size = 3;
}
