|
| 1 | +# Meta |
| 2 | +[meta]: #meta |
| 3 | +- Name: Generic Per-Route Features |
| 4 | +- Start Date: 2024-01-08 |
| 5 | +- Author(s): @maxmoehl, @domdom82 |
| 6 | +- Status: Draft <!-- Acceptable values: Draft, Approved, On Hold, Superseded --> |
| 7 | +- RFC Pull Request: (fill in with PR link after you submit it) |
| 8 | + |
| 9 | +## Summary |
| 10 | + |
| 11 | +## Problem |
| 12 | + |
| 13 | +Implementing per-route features in Cloud Foundry is a tedious process because it requires |
| 14 | +changes to multiple components in multiple working groups. Most components will only need to be |
| 15 | +made aware of new fields without adding any significant logic but the overhead of making the |
| 16 | +change still exists. |
| 17 | + |
| 18 | +On the other side are the components that actually need to be aware of the change. Mostly the |
| 19 | +routing components (gorouter, maybe route-emitter / -registrar), the API (cloud controller) |
| 20 | +and UIs (CLI). |
| 21 | + |
| 22 | +## Proposal |
| 23 | + |
| 24 | +To reduce the overall overhead of implementing new per-route features we propose to add a generic |
| 25 | +key-value map to the definition of a route across all components. All components handling the map |
| 26 | +SHOULD ignore the contents of the map except gorouter, cloud controller and cf CLI which MUST handle |
| 27 | +the map and its values accordingly. Other components MAY limit the size of the map or size of |
| 28 | +keys / values for technical reasons. |
| 29 | + |
| 30 | +The following constraints apply (types are as specified in [RFC 8259](https://rfc-editor.org/rfc/rfc8259)): |
| 31 | +* The map MUST be representable as an object. |
| 32 | +* The map MUST only use strings as keys. |
| 33 | +* The map MUST only use numbers, strings and the literal values `true` and `false` as values. |
| 34 | + |
| 35 | +### Required Changes |
| 36 | + |
| 37 | +#### CLI |
| 38 | + |
| 39 | +Support for a generic map MUST be added to the manifest. There MAY be either individual command line |
| 40 | +flags or a single flag which supports generic key-value pairs for the `map-route` sub-command. |
| 41 | + |
| 42 | +#### Cloud Controller |
| 43 | + |
| 44 | +The API MUST specify and implement a new field to carry the map inside the route object. The API |
| 45 | +MUST implement per-field validations as features of the map are specified. The route MUST be |
| 46 | +rejected with an appropriate error message if the provided map is invalid and MUST be passed on |
| 47 | +as-is otherwise. The API also MUST store the map as a generic key-value map to ensure changes to |
| 48 | +the map do not require a change to the database schema. |
| 49 | + |
| 50 | +Implementation details: |
| 51 | +* Add a new field to the [route model](https://github.com/cloudfoundry/cloud_controller_ng/blob/main/app/models/runtime/route.rb). |
| 52 | +* Add validation to the [route validator](https://github.com/cloudfoundry/cloud_controller_ng/blob/e719d017ea4625397a97c2c14352ebdee66febe9/lib/cloud_controller/route_validator.rb#L2). |
| 53 | + |
| 54 | +#### BBS, Rep, Executor, Route-Emitter |
| 55 | + |
| 56 | +The diego components MUST add support for the new field specified by the API and forward the |
| 57 | +contents as-is without modification or, if the field exceeds technical limitations, MUST raise an |
| 58 | +error. |
| 59 | + |
| 60 | +#### Gorouter |
| 61 | + |
| 62 | +Gorouter MUST accept the new field and parse its contents. If the map cannot be parsed it MUST |
| 63 | +be ignored. If individual key-value pairs are invalid those MUST be ignored and other key-value |
| 64 | +pairs MUST still be parsed and acted upon. |
| 65 | + |
| 66 | +It MAY be decided to implement one feature as part of this RFC which would be implemented together |
| 67 | +with the generic logic for supporting the new map. |
| 68 | + |
| 69 | +As new features are specified they MUST be implemented in gorouter. |
| 70 | + |
| 71 | +Example `router.register` NATS message containing additional options (field names and values are not |
| 72 | +final): |
| 73 | + |
| 74 | +```json |
| 75 | +{ |
| 76 | + "host": "127.0.0.1", |
| 77 | + "port": 4567, |
| 78 | + "tls_port": 1234, |
| 79 | + "protocol": "http1", |
| 80 | + "uris": [ |
| 81 | + "my_first_url.localhost.routing.cf-app.com", |
| 82 | + "my_second_url.localhost.routing.cf-app.com/some-path" |
| 83 | + ], |
| 84 | + "tags": { |
| 85 | + "another_key": "another_value", |
| 86 | + "some_key": "some_value" |
| 87 | + }, |
| 88 | + "options": { |
| 89 | + "lb-algo": "least-conn", |
| 90 | + "conn-limit": 100, |
| 91 | + "cookie": "my-session-cookie", |
| 92 | + "trim-path": true |
| 93 | + }, |
| 94 | + "app": "some_app_guid", |
| 95 | + "stale_threshold_in_seconds": 120, |
| 96 | + "private_instance_id": "some_app_instance_id", |
| 97 | + "isolation_segment": "some_iso_seg_name", |
| 98 | + "server_cert_domain_san": "some_subject_alternative_name" |
| 99 | +} |
| 100 | +``` |
| 101 | + |
| 102 | +To-Do: |
| 103 | +* Can we somehow report errors from gorouter back to the user? |
| 104 | + |
| 105 | +### Specifying Features |
| 106 | + |
| 107 | +It's the responsibility of the App Runtime Platform Working Group (ARD-WG) to specify new |
| 108 | +features based on what is specified in this RFC. When a new feature is proposed the ARD-WG uses |
| 109 | +the process it would use for any new feature to decide whether and how it should be implemented. It |
| 110 | +MAY involve other working groups in the process. |
| 111 | + |
| 112 | +### Features Which Could be Implemented |
| 113 | + |
| 114 | +So far we have collected a list of features which would benefit from a more flexible approach to |
| 115 | +per-route features: |
| 116 | + |
| 117 | +- Custom Load-Balancing Algorithm |
| 118 | +- Custom Connection Limits |
| 119 | +- Custom session cookie name (currently set on platform level, mostly to `JSESSIONID`) |
| 120 | +- Option to trim path mapping on request (i.e. an app mapped to `/some-path/` receiving a request `GET /some-path/books` will see the request as `GET /books` if the `trim-path` option is set, instead of the full path) |
| 121 | + |
| 122 | +To-Do: |
| 123 | +* Collect more feedback and extend the list. |
| 124 | + |
| 125 | +All of these options are already (or could easily be made) configurable for the entire CF |
| 126 | +installation. Changing them will almost certainly break existing scenarios which is why we |
| 127 | +are looking for a cheap way to gradually allow for more configuration per route. |
0 commit comments