// Copyright 2017 Istio Authors
//
//   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 istio.mixer.v1.config.client;

option go_package="istio.io/api/mixer/v1/config/client";

import "gogoproto/gogo.proto";
import "google/api/field_behavior.proto";
import "mixer/v1/config/client/service.proto";

option (gogoproto.goproto_getters_all) = false;
option (gogoproto.equal_all) = false;
option (gogoproto.gostring_all) = false;
option (gogoproto.stable_marshaler_all) = true;

// Specifies runtime quota rules.
//  * Uses Istio attributes to match individual requests
//  * Specifies list of quotas to use for matched requests.
//
// Example1:
// Charge "request_count" quota with 1 amount for all requests.
//
//   QuotaSpec:
//     - rules
//       - quotas:
//           quota: request_count
//           charge: 1
//
// Example2:
// For HTTP POST requests with path are prefixed with /books or
// api.operation is create_books, charge two quotas:
// * write_count of 1 amount
// * request_count of 5 amount.
//
// ```yaml
// QuotaSpec:
//   - rules:
//     - match:
//         clause:
//           request.path:
//             string_prefix: /books
//           request.http_method:
//             string_exact: POST
//     - match:
//         clause:
//           api.operation:
//             string_exact: create_books
//     - quotas:
//         quota: write_count
//         charge: 1
//     - quotas:
//         quota: request_count
//         charge: 5
// ```

// Determines the quotas used for individual requests.
//
// <!-- go code generation tags
// +kubetype-gen
// +kubetype-gen:groupVersion=config.istio.io/v1alpha2
// +genclient
// +k8s:deepcopy-gen=true
// -->
message QuotaSpec {
  // A list of Quota rules.
  repeated QuotaRule rules = 1;
}

// Specifies a rule with list of matches and list of quotas.
// If any clause matched, the list of quotas will be used.
message QuotaRule {
  // If empty, match all request.
  // If any of match is true, it is matched.
  repeated AttributeMatch match = 1;

  // The list of quotas to charge.
  repeated Quota quotas = 2;
}

// Describes how to match a given string in HTTP headers. Match is
// case-sensitive.
message StringMatch {
  oneof match_type {
    // exact string match
    string exact = 1;
    // prefix-based match
    string prefix = 2;
    // ECMAscript style regex-based match
    string regex = 3;
  }
}

// Specifies a match clause to match Istio attributes
message AttributeMatch {
  // Map of attribute names to StringMatch type.
  // Each map element specifies one condition to match.
  //
  // Example:
  //
  //   clause:
  //     source.uid:
  //       exact: SOURCE_UID
  //     request.http_method:
  //       exact: POST
  map<string, StringMatch> clause = 1;
}

// Specifies a quota to use with quota name and amount.
message Quota {
  // The quota name to charge
  string quota = 1;

  // The quota amount to charge
  int32  charge = 2;
}

// QuotaSpecBinding defines the binding between QuotaSpecs and one or more
// IstioService.
//
// <!-- go code generation tags
// +kubetype-gen
// +kubetype-gen:groupVersion=config.istio.io/v1alpha2
// +genclient
// +k8s:deepcopy-gen=true
// -->
message QuotaSpecBinding {
  // One or more services to map the listed QuotaSpec onto.
  repeated IstioService services = 1 [(google.api.field_behavior) = REQUIRED];

  // QuotaSpecReference uniquely identifies the QuotaSpec used in the
  // Binding.
  message QuotaSpecReference {
    // The short name of the QuotaSpec. This is the resource
    // name defined by the metadata name field.
    string name = 1 [(google.api.field_behavior) = REQUIRED];

    // Optional namespace of the QuotaSpec. Defaults to the value of the
    // metadata namespace field.
    string namespace = 2;
  }

  // One or more QuotaSpec references that should be mapped to
  // the specified service(s). The aggregate collection of match
  // conditions defined in the QuotaSpecs should not overlap.
  repeated QuotaSpecReference quota_specs = 2 [(google.api.field_behavior) = REQUIRED];
}
