sigs.k8s.io/gateway-api@v1.0.0/geps/gep-2257.md (about)

     1  # GEP-2257: Gateway API Duration Format
     2  
     3  * Issue: [#2257](https://github.com/kubernetes-sigs/gateway-api/issues/2257)
     4  * Status: Experimental
     5  
     6  ## TL;DR
     7  
     8  As we extend the Gateway API to have more functionality, we need a standard
     9  way to represent duration values. The first instance is the [HTTPRoute
    10  Timeouts GEP][GEP-1742]; doubtless others will arise.
    11  
    12  [GEP-1742]:/geps/gep-1742
    13  
    14  ## Gateway API Duration Format
    15  
    16  The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD",
    17  "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be
    18  interpreted as described in [RFC 8174].
    19  
    20  [RFC 8174]:https://datatracker.ietf.org/doc/html/rfc8174
    21  
    22  A _Gateway API Duration_ or _GEP-2257 Duration_ is a string value that:
    23  
    24  - MUST match the regular expression `^([0-9]{1,5}(h|m|s|ms)){1,4}$` and
    25  - MUST be interpreted as specified by [Golang's `time.ParseDuration`][gotime].
    26  
    27  Since both of these conditions MUST be true, the effect is that GEP-2257
    28  Durations are a subset of what `time.ParseDuration` supports:
    29  
    30  - A GEP-2257 Duration MUST be one to four _components_, each of which consists
    31    of an integer _value_ followed immediately by a _unit_. For example, `1h`,
    32    `5m`, `1h5m`, and `1h30m30s500ms` are all valid GEP-2257 Durations.
    33  
    34  - For each component, the value MUST be one to five decimal digits. Floating
    35    point is not allowed. Leading zeroes do not mean octal; the value MUST
    36    always be interpreted as a decimal integer. For example, `1h`, `60m`, `01h`,
    37    and `00060m` are all equivalent GEP-2257 Durations.
    38  
    39  - For each component, the unit MUST be one of `h` (hour), `m` (minute), `s`
    40    (second), or `ms` (millisecond). No units larger than hours or smaller than
    41    milliseconds are supported.
    42  
    43  - The total duration expressed by a GEP-2257 Duration string is the sum of
    44    each of its components. For example, `1h30m` would be a 90-minute duration,
    45    and `1s500ms` would be a 1.5-second duration.
    46  
    47  - There is no requirement that all units must be used. A GEP-2257 Duration of
    48    `1h500ms` is supported (although probably not terribly useful).
    49  
    50  - Units MAY be repeated, although users SHOULD NOT rely on this support since
    51    this GEP is Experimental, and future revisions may remove support for
    52    repeated units. If units are repeated, the total duration remains the sum of
    53    all components: a GEP-2257 duration of `1h2h20m10m` is a duration of 3 hours
    54    30 minutes.
    55  
    56  - Since the value and the unit are both required within a component, `0` is
    57    not a valid GEP-2257 duration string (though `0s` is). Likewise the empty
    58    string is not a valid GEP-2257 duration.
    59  
    60  - Users SHOULD represent the zero duration as `0s`, although they MAY use any
    61    of `0h`, `0m`, etc. Implementations formatting a GEP-2257 Duration for
    62    output MUST render the zero duration as `0s`.
    63  
    64  - The “standard” form of a GEP-2257 Duration uses descending, nonrepeating
    65    units, using the largest unit possible for each component (so `1h` rather
    66    than `60m` or `30m1800s`, and `1h30m` rather than either `90m` or `30m1h`).
    67    Users SHOULD use this standard form when writing GEP-2257 Durations.
    68    Implementations formatting GEP-2257 Durations MUST render them using this
    69    standard form.
    70  
    71      - **Note**: Implementations of Kubernetes APIs MUST NOT modify user input.
    72        For example, implementations MUST NOT normalize `30m1800s` to `1h` in a
    73        CRD `spec`. This "standard form" requirement is limited to instances
    74        where an implementation needs to format a GEP-2257 Duration value for
    75        output.
    76  
    77  A GEP-2257 Duration parser can be easily implemented by doing a regex-match
    78  check before calling a parser equivalent to Go's `time.ParseDuration`. Such
    79  parsers are readily available in (at least) [Go itself][gotime], [Rust's
    80  `kube_core` crate from `kube-rs`][kube-core], and [Python's
    81  `durationpy`][durationpy] package. We expect that these three languages cover
    82  the vast majority of the Kubernetes ecosystem.
    83  
    84  [gotime]:https://pkg.go.dev/time#ParseDuration
    85  [kube-core]:https://docs.rs/kube-core/latest/kube_core/duration/struct.Duration.html
    86  [durationpy]:https://github.com/icholy/durationpy
    87  
    88  ## Alternatives
    89  
    90  We considered three main alternatives:
    91  
    92  - Raw Golang `time.ParseDuration` format. This is very widely used in the Go
    93    ecosystem -- however, it is a very open-ended specification and, in
    94    particular, its support for floating-point values and negative durations
    95    makes it difficult to validate.
    96  
    97  - Golang `strfmt.ParseDuration` as used in the APIServer's OpenAPI validation
    98    code. It turns out that `strfmt.ParseDuration` is a superset of
    99    `time.ParseDuration`, so all the problems in validation are still present.
   100    Additionally, `strfmt.ParseDuration` supports day and week units, requiring
   101    discussion of leap seconds.
   102  
   103  - ISO8601/RFC3339 durations. These are considerably less user-friendly than
   104    our proposal: `PT0.5S` is simply not as immediately clear as "500ms".
   105  
   106  There is (a lot) more discussion in [PR 2155].
   107  
   108  [PR 2155]:https://github.com/kubernetes-sigs/gateway-api/pull/2155
   109  
   110  ## Graduation Criteria
   111  
   112  To graduate GEP-2257 to Standard channel, we need to meet the following
   113  criteria:
   114  
   115  - Publish a set of test vectors for the GEP-2257 duration format.
   116  
   117  - Have Go, Rust, and Python implementations of the parser, with a test suite
   118    covering all the test vectors.
   119  
   120  - Have a custom CEL validator for GEP-2257 Duration fields.
   121  
   122  - Have support for GEP-2257 Durations in standard Kubernetes libraries.