From f2734f753bc1d1f54766d4c539d8e6472644f615 Mon Sep 17 00:00:00 2001 From: Carlos Aguado Date: Fri, 19 Jan 2024 12:24:31 +0000 Subject: [PATCH 1/7] Model locations and sessions as REST resources Remove the action from the URI for the resource to allow individual referencing and collections of nested resources. --- api/openapi.yaml | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/api/openapi.yaml b/api/openapi.yaml index b319054..769a348 100644 --- a/api/openapi.yaml +++ b/api/openapi.yaml @@ -34,12 +34,13 @@ paths: '400': $ref: '#/components/responses/ErrorResponse' - /list_locations: + /locations: get: + description: Lists all the visible locations to the caller. parameters: - name: asn in: query - description: List avaible locations for peering with the given ASN + description: List available locations for peering with the given ASN required: true schema: type: integer @@ -63,9 +64,9 @@ paths: '400': $ref: '#/components/responses/ErrorResponse' - /add_sessions: + /sessions: post: - description: Request peering + description: Requests a new set of sessions to be created. requestBody: description: Request to create peering sessions content: @@ -89,8 +90,8 @@ paths: '400': $ref: '#/components/responses/ErrorResponse' - /get_status: get: + description: Lists a set of sessions visible to the caller. Each session in the set contains a summary of its current status. parameters: - name: asn in: query From 51a8552f541c86fd252be87f108e623ab4b6b9b0 Mon Sep 17 00:00:00 2001 From: Carlos Aguado Date: Fri, 19 Jan 2024 12:28:40 +0000 Subject: [PATCH 2/7] Model authorization errors when accessing a resource The current API namespace is shared across all the callers so responses will be filtered by visibility of the caller or denied in the absence of authorization to use the passed input parameters. --- api/openapi.yaml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/api/openapi.yaml b/api/openapi.yaml index 769a348..a377da7 100644 --- a/api/openapi.yaml +++ b/api/openapi.yaml @@ -63,6 +63,8 @@ paths: '400': $ref: '#/components/responses/ErrorResponse' + '403': + $ref: '#/components/responses/ErrorResponse' /sessions: post: @@ -89,6 +91,8 @@ paths: $ref: '#/components/schemas/SessionArray' '400': $ref: '#/components/responses/ErrorResponse' + '403': + $ref: '#/components/responses/ErrorResponse' get: description: Lists a set of sessions visible to the caller. Each session in the set contains a summary of its current status. @@ -114,6 +118,8 @@ paths: $ref: '#/components/schemas/SessionArray' '400': $ref: '#/components/responses/ErrorResponse' + '403': + $ref: '#/components/responses/ErrorResponse' components: schemas: From dee93db06baf6e92bf6f615cd539214ede0b1e3e Mon Sep 17 00:00:00 2001 From: Carlos Aguado Date: Fri, 19 Jan 2024 12:56:28 +0000 Subject: [PATCH 3/7] Add pagination to listing of locations and sessions Implement a paginator over the list of sessions visible to a caller. The paginator is opportunistic as it will return an upper bounded set using the client hint, and opaque as it will make no commitments on the content of the pagination token. --- api/openapi.yaml | 64 ++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 59 insertions(+), 5 deletions(-) diff --git a/api/openapi.yaml b/api/openapi.yaml index a377da7..48a2bca 100644 --- a/api/openapi.yaml +++ b/api/openapi.yaml @@ -51,16 +51,28 @@ paths: required: false schema: $ref: '#/components/schemas/LocationType' + - name: max_results + in: query + description: Hint to paginate the request with the maximum number of results the caller is able to process. + required: false + schema: + type: integer + default: 0 + minimum: 0 + maximum: 100 + - name: next_token + in: query + description: Indication of the offset to retrieve the next page on a previously initiated paginated request. + required: true + schema: + type: string responses: '200': description: OK content: application/json: schema: - type: array - items: - $ref: '#/components/schemas/Location' - + $ref: '#/components/responses/ListLocationsResponse' '400': $ref: '#/components/responses/ErrorResponse' '403': @@ -109,13 +121,28 @@ paths: required: false schema: type: string + - name: max_results + in: query + description: Hint to paginate the request with the maximum number of results the caller is able to process. + required: false + schema: + type: integer + default: 0 + minimum: 0 + maximum: 100 + - name: next_token + in: query + description: Indication of the offset to retrieve the next page on a previously initiated paginated request. + required: true + schema: + type: string responses: '200': description: OK content: application/json: schema: - $ref: '#/components/schemas/SessionArray' + $ref: '#/components/responses/ListSessionsResponse' '400': $ref: '#/components/responses/ErrorResponse' '403': @@ -145,6 +172,13 @@ components: Add choices type: string + LocationArray: + title: Locations + description: Array of peering locations + type: array + items: + $ref: '#/components/schemas/Location' + SessionArray: title: BGP Sessions description: Array of BGP Sessions @@ -214,6 +248,26 @@ components: - errors responses: + ListLocationsResponse: + title: ListLocationsResponse + description: Response to a list for locations + type: object + properties: + next_token: + type: string + locations: + $ref: '#/components/schemas/LocationArray' + + ListSessionsResponse: + title: ListSessionsResponse + description: Response to a list for sessions + type: object + properties: + next_token: + type: string + sessions: + $ref: '#/components/schemas/SessionArray' + ErrorResponse: description: API Error response content: From ef4db4f28f5fc7c2342e2d2c6a01ba1f36ba815b Mon Sep 17 00:00:00 2001 From: Carlos Aguado Date: Wed, 24 Jan 2024 13:27:58 +0000 Subject: [PATCH 4/7] Disambiguate items in batch processing for sessions The creation of sessions allows to submit a set of them to treat them as an aggregate when requesting to operate on a certain peering posture. This commit adds a field to the input and output series such that the client can univocally identify which sessions have been processed successfully or not without relying on implicit ordering of the input or result set. --- api/openapi.yaml | 58 +++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 55 insertions(+), 3 deletions(-) diff --git a/api/openapi.yaml b/api/openapi.yaml index 48a2bca..5fc3143 100644 --- a/api/openapi.yaml +++ b/api/openapi.yaml @@ -94,13 +94,13 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/SessionArray' + $ref: '#/components/responses/CreateSessionsResponse' '300': description: Request modified or partially accepted content: application/json: schema: - $ref: '#/components/schemas/SessionArray' + $ref: '#/components/responses/CreateSessionsResponse' '400': $ref: '#/components/responses/ErrorResponse' '403': @@ -179,6 +179,36 @@ components: items: $ref: '#/components/schemas/Location' + SessionRequestArray: + title: BGP Sessions requested + description: Array of BGP Sessions requested + type: array + items: + $ref: '#/components/schemas/SessionRequestItem' + + SessionRequestItem: + title: BGP Session Request + description: BGP Session Request + type: object + properties: + local_asn: + type: integer + local_ip: + type: string + peer_asn: + type: integer + peer_ip: + type: string + peer_type: + type: string + md5: # TODO or auth: md5: $key? + type: string + location: + $ref: '#/components/schemas/Location' + item_id: + type: string + description: unique identifier of the session in an aggregate + SessionArray: title: BGP Sessions description: Array of BGP Sessions @@ -207,11 +237,14 @@ components: $ref: '#/components/schemas/Location' status: $ref: '#/components/schemas/SessionStatus' - uuid: + session_id: type: string description: |- unique identifier (also serves as request id) Could separate into local_ and peer_? + item_id: + type: string + description: unique identifier of the session in an aggregate Error: title: Error type: object @@ -247,6 +280,15 @@ components: - name - errors + requests: + CreateSessionsRequest: + title: CreateSessionsRequest + description: Response to a request to create sessions + type: object + properties: + sessions: + $ref: '#/components/schemas/SessionRequestArray' + responses: ListLocationsResponse: title: ListLocationsResponse @@ -258,6 +300,16 @@ components: locations: $ref: '#/components/schemas/LocationArray' + CreateSessionsResponse: + title: CreateSessionsResponse + description: Response to a request to create sessions + type: object + properties: + sessions: + $ref: '#/components/schemas/SessionArray' + errors: + $ref: '#/components/schemas/Error' + ListSessionsResponse: title: ListSessionsResponse description: Response to a list for sessions From 4e579291259eca11697603cb778f50f3cf04acfc Mon Sep 17 00:00:00 2001 From: Carlos Aguado Date: Fri, 26 Jan 2024 09:06:01 +0000 Subject: [PATCH 5/7] Add deletion of individual sessions Implement a method to depeer by deleting existing sessions. The batched creation method does not create an obvious collection resource on the server side that may be used for a depeering situation therefore this commit only implements individual session deletion. To tackle a situation where depeering is desired for a whole metro or IX while respecting this RESTful interface, we will need to define a separate aggregate resource that can be used to operate atomically on the set of target sessions. --- api/openapi.yaml | 50 ++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 44 insertions(+), 6 deletions(-) diff --git a/api/openapi.yaml b/api/openapi.yaml index 5fc3143..89270d8 100644 --- a/api/openapi.yaml +++ b/api/openapi.yaml @@ -115,12 +115,6 @@ paths: required: true schema: type: integer - - name: request_id - in: query - description: request identifier - required: false - schema: - type: string - name: max_results in: query description: Hint to paginate the request with the maximum number of results the caller is able to process. @@ -148,6 +142,50 @@ paths: '403': $ref: '#/components/responses/ErrorResponse' + /sessions/{session_id}: + get: + description: Retrieves a given session by it server-generated ID provided on creation. + parameters: + - name: session_id + in: path + description: Server-generated stable identifier for the session. + required: true + schema: + type: string + responses: + '200': + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/Session' + '400': + $ref: '#/components/responses/ErrorResponse' + '403': + $ref: '#/components/responses/ErrorResponse' + '404': + $ref: '#/components/responses/ErrorResponse' + + delete: + description: Requests to turn the session down and delete it from the server. + parameters: + parameters: + - name: session_id + in: path + description: Server-generated stable identifier for the session. + required: true + schema: + type: string + responses: + '204': + description: Session is scheduled for deletion and no longer usable + '400': + $ref: '#/components/responses/ErrorResponse' + '403': + $ref: '#/components/responses/ErrorResponse' + '404': + $ref: '#/components/responses/ErrorResponse' + components: schemas: Location: From 62888af1f0bcd72b3a86e6eba62be6bcd44d3ba3 Mon Sep 17 00:00:00 2001 From: Carlos Aguado Date: Fri, 26 Jan 2024 11:12:04 +0000 Subject: [PATCH 6/7] Add soft-delete semantics for a collection of sessions This commit adds the soft deleted semantics described in the original spec where a set of sessions is requested for deletion and the response will include a status in the deletion of the request. This commit also recreates these semantics in the individual session deletion. --- api/openapi.yaml | 62 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 61 insertions(+), 1 deletion(-) diff --git a/api/openapi.yaml b/api/openapi.yaml index 89270d8..ca07d84 100644 --- a/api/openapi.yaml +++ b/api/openapi.yaml @@ -142,6 +142,33 @@ paths: '403': $ref: '#/components/responses/ErrorResponse' + delete: + description: Requests to turn the session down and delete it from the server. + requestBody: + description: Request to delete peering sessions + content: + application/json: + schema: + $ref: '#/components/schemas/SessionReferenceArray' + required: true + responses: + '200': + description: Sessions are scheduled for deletion and no longer usable + content: + application/json: + schema: + $ref: '#/components/responses/DeleteSessionsResponse' + '300': + description: Request modified or partially accepted + content: + application/json: + schema: + $ref: '#/components/responses/DeleteSessionsResponse' + '400': + $ref: '#/components/responses/ErrorResponse' + '403': + $ref: '#/components/responses/ErrorResponse' + /sessions/{session_id}: get: description: Retrieves a given session by it server-generated ID provided on creation. @@ -177,8 +204,12 @@ paths: schema: type: string responses: - '204': + '200': description: Session is scheduled for deletion and no longer usable + content: + application/json: + schema: + $ref: '#/components/schemas/Session' '400': $ref: '#/components/responses/ErrorResponse' '403': @@ -283,6 +314,25 @@ components: item_id: type: string description: unique identifier of the session in an aggregate + + SessionReferenceArray: + title: BGP Session References + description: Array of BGP Session References + type: array + sessions: + $ref: '#/components/schemas/SessionReference' + + SessionReference: + title: BGP Session Reference + description: Reference to univocally identify a BGP Session + type: object + properties: + session_id: + type: string + description: |- + unique identifier (also serves as request id) + Could separate into local_ and peer_? + Error: title: Error type: object @@ -358,6 +408,16 @@ components: sessions: $ref: '#/components/schemas/SessionArray' + DeleteSessionsResponse: + title: DeleteSessionsResponse + description: Response to a request to delete sessions + type: object + properties: + sessions: + $ref: '#/components/schemas/SessionArray' + errors: + $ref: '#/components/schemas/Error' + ErrorResponse: description: API Error response content: From fe47bba37861deb8525b932d0e70d0401d6e8e1d Mon Sep 17 00:00:00 2001 From: Carlos Aguado Date: Fri, 8 Mar 2024 19:00:01 +0000 Subject: [PATCH 7/7] Remove transient identifiers and partial success in response As per the different discussions, this commit removes references to identifiers used to identify parts of an inflight request that disambiguate failure scenarios. They may be addressed later. It also removes the partial successful reponse conveyed through a redirect error code. The rationale to use only the 200 success code is that the response for a batched request has been successfully processed and the response may still contain references to items which were not successful. Clients will have to introspect the response to decide what to do with those failed items. --- api/openapi.yaml | 22 ++-------------------- 1 file changed, 2 insertions(+), 20 deletions(-) diff --git a/api/openapi.yaml b/api/openapi.yaml index ca07d84..42591e3 100644 --- a/api/openapi.yaml +++ b/api/openapi.yaml @@ -63,7 +63,7 @@ paths: - name: next_token in: query description: Indication of the offset to retrieve the next page on a previously initiated paginated request. - required: true + required: false schema: type: string responses: @@ -95,12 +95,6 @@ paths: application/json: schema: $ref: '#/components/responses/CreateSessionsResponse' - '300': - description: Request modified or partially accepted - content: - application/json: - schema: - $ref: '#/components/responses/CreateSessionsResponse' '400': $ref: '#/components/responses/ErrorResponse' '403': @@ -127,7 +121,7 @@ paths: - name: next_token in: query description: Indication of the offset to retrieve the next page on a previously initiated paginated request. - required: true + required: false schema: type: string responses: @@ -158,12 +152,6 @@ paths: application/json: schema: $ref: '#/components/responses/DeleteSessionsResponse' - '300': - description: Request modified or partially accepted - content: - application/json: - schema: - $ref: '#/components/responses/DeleteSessionsResponse' '400': $ref: '#/components/responses/ErrorResponse' '403': @@ -274,9 +262,6 @@ components: type: string location: $ref: '#/components/schemas/Location' - item_id: - type: string - description: unique identifier of the session in an aggregate SessionArray: title: BGP Sessions @@ -311,9 +296,6 @@ components: description: |- unique identifier (also serves as request id) Could separate into local_ and peer_? - item_id: - type: string - description: unique identifier of the session in an aggregate SessionReferenceArray: title: BGP Session References