syntax = "proto3";

package yandex.cloud.vpc.v1;

import "google/api/annotations.proto";
import "google/protobuf/field_mask.proto";
import "yandex/cloud/api/operation.proto";
import "yandex/cloud/vpc/v1/security_group.proto";
import "yandex/cloud/operation/operation.proto";
import "yandex/cloud/validation.proto";

option go_package = "github.com/yandex-cloud/go-genproto/yandex/cloud/vpc/v1;vpc";
option java_package = "yandex.cloud.api.vpc.v1";

service SecurityGroupService {

    rpc Get (GetSecurityGroupRequest) returns (SecurityGroup) {
      option (google.api.http) = { get: "/vpc/v1/securityGroups/{security_group_id}" };
    }

    rpc List (ListSecurityGroupsRequest) returns (ListSecurityGroupsResponse) {
      option (google.api.http) = { get: "/vpc/v1/securityGroups" };
    }

    rpc Create (CreateSecurityGroupRequest) returns (operation.Operation) {
        option (google.api.http) = { post: "/vpc/v1/securityGroups" body: "*" };
        option (yandex.cloud.api.operation) = {
            metadata: "CreateSecurityGroupMetadata"
            response: "SecurityGroup"
        };
    }

    rpc Update (UpdateSecurityGroupRequest) returns (operation.Operation) {
        option (google.api.http) = { patch: "/vpc/v1/securityGroups/{security_group_id}" body: "*" };
        option (yandex.cloud.api.operation) = {
            metadata: "UpdateSecurityGroupMetadata"
            response: "SecurityGroup"
        };
    }

    rpc UpdateRules (UpdateSecurityGroupRulesRequest) returns (operation.Operation) {
        option (google.api.http) = { patch: "/vpc/v1/securityGroups/{security_group_id}/rules" body: "*" };
        option (yandex.cloud.api.operation) = {
            metadata: "UpdateSecurityGroupMetadata"
            response: "SecurityGroup"
        };
    }

    // update rule description or labels
    rpc UpdateRule (UpdateSecurityGroupRuleRequest) returns (operation.Operation) {
        option (google.api.http) = { patch: "/vpc/v1/securityGroups/{security_group_id}/rules/{rule_id}" body: "*" };
        option (yandex.cloud.api.operation) = {
            metadata: "UpdateSecurityGroupRuleMetadata"
            response: "SecurityGroupRule"
        };
    }

    rpc Delete (DeleteSecurityGroupRequest) returns (operation.Operation) {
        option (google.api.http) = { delete: "/vpc/v1/securityGroups/{security_group_id}" };
        option (yandex.cloud.api.operation) = {
            metadata: "DeleteSecurityGroupMetadata"
            response: "google.protobuf.Empty"
        };
    }

    rpc Move (MoveSecurityGroupRequest) returns (operation.Operation) {
    option (google.api.http) = { post: "/vpc/v1/securityGroups/{security_group_id}:move" body: "*" };
        option (yandex.cloud.api.operation) = {
            metadata: "MoveSecurityGroupMetadata"
            response: "SecurityGroup"
        };
    }

    rpc ListOperations (ListSecurityGroupOperationsRequest) returns (ListSecurityGroupOperationsResponse) {
      option (google.api.http) = { get: "/vpc/v1/securityGroups/{security_group_id}/operations" };
    }
}

message GetSecurityGroupRequest {
    string security_group_id = 1 [(required) = true];
}

message ListSecurityGroupsRequest {
    string folder_id = 1 [(required) = true];
    int64 page_size = 2;
    string page_token = 3;
    string filter = 4; //filter by network_id is here
}

message ListSecurityGroupsResponse {
    repeated SecurityGroup security_groups = 1;
    string next_page_token = 2;
}

message CreateSecurityGroupRequest {
    string folder_id = 1 [(required) = true];
    string name = 2;
    string description = 3;
    map<string, string> labels = 4;

    string network_id = 5 [(required) = true];
    repeated SecurityGroupRuleSpec rule_specs = 6;
}

message SecurityGroupRuleSpec {
    string description = 1;
    map<string, string> labels = 2;

    SecurityGroupRule.Direction direction = 3 [(required) = true];
    PortRange ports = 4; // null value means any port

    // values from https://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml
    // null value means any protocol
    oneof protocol {
        string protocol_name = 5;
        int64 protocol_number = 6;
    }

    oneof target {
        option (exactly_one) = true;

        CidrBlocks cidr_blocks = 7;
        string security_group_id = 8;
        string predefined_target = 9;
        // string subnet_id = .. ;
    }
}

message CreateSecurityGroupMetadata {
    string security_group_id = 1;
}

message UpdateSecurityGroupRequest {
    string security_group_id = 1 [(required) = true];

    google.protobuf.FieldMask update_mask = 2;

    string name = 3;
    string description = 4;
    map<string, string> labels = 5;

    // all existing rules will be replaced with given list
    repeated SecurityGroupRuleSpec rule_specs = 6;
}

message UpdateSecurityGroupMetadata {
    string security_group_id = 1;
    repeated string added_rule_ids = 2;
}

message UpdateSecurityGroupRulesRequest {
    string security_group_id = 1 [(required) = true];

    repeated string deletion_rule_ids = 2; //list of rules ids to delete
    repeated SecurityGroupRuleSpec addition_rule_specs = 3;
}

message UpdateSecurityGroupRuleRequest {
    string security_group_id = 1 [(required) = true];
    string rule_id = 2 [(required) = true];

    google.protobuf.FieldMask update_mask = 3;

    string description = 4;
    map<string, string> labels = 5;
}

message UpdateSecurityGroupRuleMetadata {
    string security_group_id = 1;
    string rule_id = 2;
}

message DeleteSecurityGroupRequest {
    string security_group_id = 1 [(required) = true];
}

message DeleteSecurityGroupMetadata {
    string security_group_id = 1;
}

message ListSecurityGroupOperationsRequest {
    string security_group_id = 1 [(required) = true];
    int64 page_size = 2;
    string page_token = 3;
}

message ListSecurityGroupOperationsResponse {
    repeated operation.Operation operations = 1;
    string next_page_token = 2;
}

message MoveSecurityGroupRequest {
    string security_group_id = 1 [(required) = true];
    string destination_folder_id = 2 [(required) = true];
}

message MoveSecurityGroupMetadata {
    string security_group_id = 1;
}
