|
| 1 | +# gNMI Config Subscription Extension |
| 2 | + |
| 3 | +**Contributors:** Roman Dodin, Matthew MacDonald |
| 4 | + |
| 5 | +**Date:** July 29th, 2024 |
| 6 | + |
| 7 | +**Version:** 0.1.0 |
| 8 | + |
| 9 | +## 1. Purpose |
| 10 | + |
| 11 | +Performing configuration management and handling configuration drift is one of |
| 12 | +the main features of a higher-level management system or orchestrator. |
| 13 | +Configuration drift occurs when a device's configuration changes independently |
| 14 | +of the expected configuration defined by the management system. Such changes |
| 15 | +may arise from manual interventions, automated processes outside the management |
| 16 | +system, or unexpected behavior. When drift is detected, the management system |
| 17 | +can either revert the configuration back to the expected configuration or |
| 18 | +incorporate the change by updating its records to include the new configuration |
| 19 | +as the expected configuration. The configuration management tasks focus on the |
| 20 | +effective retrieval and push of configuration values. |
| 21 | + |
| 22 | +Thus, having a synchronized configuration view between the management |
| 23 | +system and the network elements is key to enabling robust and near real-time |
| 24 | +configuration management. |
| 25 | +To enable this synchronization of configuration data, the gNMI Subscribe RPC |
| 26 | +can be used. The bidirectional streaming nature of this RPC enables fast |
| 27 | +and reliable sync between the management system and the devices it manages. |
| 28 | + |
| 29 | +Unfortunately, gNMI Subscribe RPC does not have an embedded mechanism to |
| 30 | +stream updates for the configuration values only as opposed to the Get RPC, |
| 31 | +which makes this RPC rather ineffective on YANG schemas that do not employ |
| 32 | +a separation of config and state elements by using distinct containers. |
| 33 | + |
| 34 | +This proposal introduces the Config Subscription extension that allows clients |
| 35 | +to indicate to servers that they are interested in configuration values only. |
| 36 | + |
| 37 | +gNMI Config Subscription Extension proto specification is defined in |
| 38 | +[gnmi_ext.proto]( |
| 39 | +https://github.com/openconfig/gnmi/blob/master/proto/gnmi_ext/gnmi_ext.proto |
| 40 | +). |
| 41 | + |
| 42 | +## 2. Definition |
| 43 | + |
| 44 | +A `ConfigSubscription` message is embedded as an extension message in the |
| 45 | +`SubscribeRequest` or `SubscribeResponse` proto messages. |
| 46 | +If the extension is embedded in a `SubscribeRequest`, the action field |
| 47 | +must be a `ConfigSubscriptionStart`. |
| 48 | +The presence of such an extension indicates to the target that the client |
| 49 | +wants to start a ConfigSubscription. The target must return notifications |
| 50 | +pertaining to data leaves that the target considers to be writable. |
| 51 | +If the subscription type is `ON_CHANGE`, the target must separate the |
| 52 | +notifications triggered by different commits using a |
| 53 | +`ConfigSubscriptionSyncDone` in a `SubscribeResponse` message. |
| 54 | +On the other hand, if the extension is embedded in a `SubscribeResponse`, the |
| 55 | +action field must be a `ConfigSubscriptionSyncDone`. This action is used by a |
| 56 | +target to indicate a commit boundary to the client. |
| 57 | + |
| 58 | +## 2.1 Proto |
| 59 | + |
| 60 | +The extension contains a message called `ConfigSubscription` that carries |
| 61 | +one of 2 types of actions. `ConfigSubscriptionStart` or |
| 62 | +`ConfigSubscriptionSyncDone` |
| 63 | + |
| 64 | +```proto |
| 65 | +// ConfigSubscription extension allows clients to subscribe to configuration |
| 66 | +// schema nodes only. |
| 67 | +message ConfigSubscription { |
| 68 | + oneof action { |
| 69 | + // ConfigSubscriptionStart is sent by the client in the SubscribeRequest |
| 70 | + ConfigSubscriptionStart start = 1; |
| 71 | + // ConfigSubscriptionSyncDone is sent by the server in the SubscribeResponse |
| 72 | + ConfigSubscriptionSyncDone sync_done = 2; |
| 73 | + } |
| 74 | +} |
| 75 | +
|
| 76 | +// ConfigSubscriptionStart is used to indicate to a target that for a given set |
| 77 | +// of paths in the SubscribeRequest, the client wishes to receive updates |
| 78 | +// for the configuration schema nodes only. |
| 79 | +message ConfigSubscriptionStart {} |
| 80 | +
|
| 81 | +// ConfigSubscriptionSyncDone is sent by the server in the SubscribeResponse |
| 82 | +// after all the updates for the configuration schema nodes have been sent. |
| 83 | +message ConfigSubscriptionSyncDone { |
| 84 | + // ID of a commit confirm operation as assigned by the client |
| 85 | + // see Commit Confirm extension for more details. |
| 86 | + string commit_confirm_id = 1; |
| 87 | + // ID of a commit as might be assigned by the server |
| 88 | + // when registering a commit operation. |
| 89 | + string server_commit_id = 2; |
| 90 | + // If true indicates that the server is done processing the updates related to the |
| 91 | + // commit_confirm_id and/or server_commit_id. |
| 92 | + bool done = 3; |
| 93 | +} |
| 94 | +``` |
| 95 | + |
| 96 | +## 2.2 Actions |
| 97 | + |
| 98 | +### 2.2.1 ConfigSubscriptionStart |
| 99 | + |
| 100 | +A `ConfigSubscriptionStart` message is used by a gNMI client in a |
| 101 | +`SubscribeRequest` to indicate that it wants to start a ConfigSubscription. |
| 102 | +The target must respond exclusively with configuration data relevant to the |
| 103 | +created subscription. |
| 104 | + |
| 105 | +The base behavior of the `Subscribe` RPC remains unchanged: the target must |
| 106 | +respond with an initial set of updates, followed by a `SubscribeResponse` |
| 107 | +with the `sync_response` field set to true. However, if the updates_only |
| 108 | +field in the SubscribeRequest is set to true, the target should omit the |
| 109 | +initial updates and instead send only a SubscribeResponse with `sync_response` |
| 110 | +set to true, in accordance with the gNMI specification. |
| 111 | + |
| 112 | +### 2.2.2 ConfigSubscriptionSyncDone |
| 113 | + |
| 114 | +The `ConfigSubscriptionSyncDone` message is included in a `SubscribeResponse` |
| 115 | +by a gNMI target to signify a commit boundary to the client. |
| 116 | +A commit boundary represents the completion of a specific set of changes |
| 117 | +associated with a commit. It confirms that all changes in the set have been |
| 118 | +successfully committed, with no errors reported by the interface used for the |
| 119 | +commit, such as gNMI, NETCONF, CLI, etc. |
| 120 | +[See Appendix - concurrent commits handling](#appendix-concurrent-commits-handling) |
| 121 | + |
| 122 | +The `ConfigSubscriptionSyncDone` message includes three fields: |
| 123 | + |
| 124 | +* `commit_confirm_id`: A commit confirm ID assigned by the client which |
| 125 | +initiated the commit. |
| 126 | +The commit can be initiated via gNMI (using the CommitConfirmed Extension), |
| 127 | +NETCONF, or any other management interface. Applicable only if the commit |
| 128 | +confirmed option is used. |
| 129 | +* `server_commit_id`: An optional internal ID assigned by the target. |
| 130 | +* `done`: If true, indicates that the server is done processing the updates |
| 131 | +related to the commit_confirm_id and/or server_commit_id. |
| 132 | + |
| 133 | +In the case a commit happens before the `sync_response: true` the server |
| 134 | +cannot send a `ConfigSubscriptionSyncDone` until the `sync_response: true` has |
| 135 | +been sent. The server may send the committed changes updates before the |
| 136 | +`sync_response: true`. |
| 137 | + |
| 138 | +## 3. Configuration changes scenarios |
| 139 | + |
| 140 | +### 3.1 Configuration changes without Commit Confirmed |
| 141 | + |
| 142 | +1) The client subscribes to path P1 with the `ConfigSubscription` extension |
| 143 | +present with the action `ConfigSubscriptionStart`. |
| 144 | +2) The server processes the subscription request as usual but will only send |
| 145 | +updates for the configuration schema nodes under the path P1. |
| 146 | +3) The client sends a Set RPC with the configuration changes to the path P1 |
| 147 | +**without** the `CommitConfirm` extension. |
| 148 | +4) The server processes the Set RPC as usual and sends the updates for the |
| 149 | +configuration schema nodes under the path P1. |
| 150 | +5) After all the configuration updates are sent, the server sends the |
| 151 | +`ConfigSubscriptionSyncDone` message to the client in a SubscribeResponse |
| 152 | +message. |
| 153 | +This message does not contain a `commit_confirmed_id` and may contain a |
| 154 | +`server_commit_id` |
| 155 | + |
| 156 | +### 3.2 Configuration changes with Commit Confirmed |
| 157 | + |
| 158 | +1) The client subscribes to the path P1 with the `ConfigSubscription` |
| 159 | +extension present with the action `ConfigSubscriptionStart`. |
| 160 | +2) The server processes the subscription request as usual but will only send |
| 161 | +updates for the configuration schema nodes under the path P1. |
| 162 | +3) The client sends a Set RPC with the configuration changes to the path |
| 163 | +P1 and **with** the `CommitConfirm` extension present. |
| 164 | +4) The server processes the Set RPC as usual and sends the updates for |
| 165 | +the configuration schema nodes under the path P1. |
| 166 | +5) As all the configuration updates are sent, the server sends the |
| 167 | +`ConfigSubscriptionSyncDone` message to the client in a SubscribeResponse |
| 168 | +message. |
| 169 | +This message must contain the the value of the `commit_confirmed_id` |
| 170 | +received in the Set RPC in step 4 and may contain a `server_commit_id`. |
| 171 | +6) When the client sends the commit confirm message, the server confirms |
| 172 | +the commit and does not send any extra SubscribeResponse messages with the |
| 173 | +`ConfigSubscriptionSyncDone` message. |
| 174 | + |
| 175 | +### 3.3 Configuration changes with Commit Confirmed and rollback/cancellation |
| 176 | + |
| 177 | +1) The client subscribes to path P1 with the `ConfigSubscription` extension |
| 178 | +present with the action `ConfigSubscriptionStart`. |
| 179 | +2) The server processes the subscription request as usual but will only send |
| 180 | +updates for the configuration schema nodes under the path P1. |
| 181 | +3) The client sends a Set RPC with the configuration changes to the path P1 |
| 182 | +and **with** the `CommitConfirm` extension present. |
| 183 | +4) The server processes the Set RPC as usual and sends the updates for the |
| 184 | +configuration schema nodes under the path P1. |
| 185 | +5) After all the configuration updates are sent, the server sends the |
| 186 | +`ConfigSubscriptionSyncDone` message to the client in a SubscribeResponse |
| 187 | +message. |
| 188 | +This message must contain the the value of the `commit_confirmed_id` received |
| 189 | +in the Set RPC in step 4. |
| 190 | +6) When the commit confirmed rollback timer expires or a commit cancel message |
| 191 | +is received, the server: |
| 192 | + i. rolls back the configuration changes as per the Commit Confirm extension |
| 193 | + specification. |
| 194 | + ii. sends the new configuration updates for the path P1 as the configuration |
| 195 | + has changed/reverted. |
| 196 | + iii. sends the ConfigSubscriptionSyncDone message to the client in a |
| 197 | + `SubscribeResponse` message. |
| 198 | + This message must contain the the value of the `commit_confirmed_id` |
| 199 | + received in the Set RPC in step 4 and may contain a `server_commit_id`. |
| 200 | + |
| 201 | +## Appendix: Concurrent commits handling |
| 202 | + |
| 203 | +### Overlapping Update Streams |
| 204 | + |
| 205 | +In scenarios where updates from multiple configuration changes overlap during |
| 206 | +streaming, it is important to note that the `ConfigSubscriptionSyncDone` |
| 207 | +message does not guarantee that the state reflected by received updates |
| 208 | +corresponds exclusively to the commit referenced by the |
| 209 | +`ConfigSubscriptionSyncDone` message. For example: |
| 210 | + |
| 211 | +1. Timeline: |
| 212 | + |
| 213 | +t = 0: Configuration change 1 is committed. |
| 214 | +t = 1: Streaming updates for configuration change 1 begins. |
| 215 | +t = Y (Y < N): Configuration change 2 is committed. |
| 216 | +t = Y + 1: Streaming updates for configuration change 2 begins. |
| 217 | +t = N: Streaming updates for configuration change 1 ends. |
| 218 | +t = Y + N: Streaming updates for configuration change 2 ends. |
| 219 | + |
| 220 | +2. Implications: |
| 221 | + |
| 222 | +* Updates for paths impacted by configuration change 2 may be sent |
| 223 | +to the client before all updates for configuration change 1 are |
| 224 | +fully streamed. |
| 225 | +* When the client receives a `ConfigSubscriptionSyncDone` message |
| 226 | +for configuration change 1, it might already have received updates |
| 227 | +reflecting changes introduced by configuration change 2. |
| 228 | +* Coalescing updates (e.g., combining overlapping changes to a path like `/foo/bar`) |
| 229 | +If both configuration changes 1 and 2 modify `/foo/bar`, and the update for |
| 230 | +`/foo/bar` is delayed, the server may send only the final state of `/foo/bar` |
| 231 | +after configuration change 2. This approach optimizes performance but results |
| 232 | +in the client never receiving the updates for change 1. |
| 233 | + |
| 234 | +### Guarantees |
| 235 | + |
| 236 | +The `ConfigSubscriptionSyncDone` message indicates that the server has completed |
| 237 | +processing all changes associated with the referenced commit. |
| 238 | +It does not guarantee that the client has received updates exclusively for that commit. |
| 239 | + |
| 240 | +If a client requires strict state guarantees, it must implement its own |
| 241 | +mechanisms to lock configuration changes between commits. For example: |
| 242 | + |
| 243 | +* Pausing further commits until the client confirms that all updates for the |
| 244 | +current commit are processed. |
| 245 | +* Implementing a client-side commit locking mechanism |
| 246 | +to avoid overlapping streams. |
0 commit comments