diff --git a/CHANGELOG.md b/CHANGELOG.md index 1432bfe99d..93bb0f330c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,12 +9,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added +- **Cloud** Support multipart uploads for builds - **Infra** Support configuring multiple S3 providers - **Infra** Support multipart uploads - **Infra** Replace Promtail-based log shipping with native Loki Docker driver -- **Infra** Add local Traefik Cloudflare proxy daemon for connecting to Cloudflare Access services +- **Infra** Local Traefik Cloudflare proxy daemon for connecting to Cloudflare Access services +- **Infra** Upload service builds to default S3 provider instead of hardcoded bucket - **Bolt** Support for connecting to Redis databases with `bolt redis sh` -- **Bolt** Add confirmation before running any command in the production namespace +- **Bolt** Confirmation before running any command in the production namespace +- **Bolt** `--start-at` flag for all infra commands +- **Bolt** Explicit database dependencies in services to reduce excess database pools ### Changed @@ -25,19 +29,28 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - **Infra** Update Consul to 1.16.0 - **Infra** Update Imagor to 1.4.7 - **Infra** Update NATS server to 2.9.20 -- **Infra** Update Node Exporter server to 1.6.1 -- **Infra** Update Nomad to 1.6.1 +- **Infra** Update Node Exporter server to 1.6.0 +- **Infra** Update Nomad to 1.6.0 - **Infra** Update Prometheus server to 2.46.0 - **Infra** Update Redis Exporter to 1.52.0 - **Infra** Update Redis to 7.0.12 - **Infra** Update Treafik to 2.10.4 +- **Bolt** PostHog events are now captured in a background task +- **Bolt** Auto-install rsync on Salt Master +- **Bolt** Recursively add dependencies from overridden services when using additional roots +- **KV** Significantly rate limit of all endpoints ### Security - Resolve [RUSTSEC-2023-0044](https://rustsec.org/advisories/RUSTSEC-2023-0044) +- Resolve [RUSTSEC-2022-0093](https://rustsec.org/advisories/RUSTSEC-2022-0093) +- Resolve [RUSTSEC-2023-0053](https://rustsec.org/advisories/RUSTSEC-2023-0053) ### Fixed - **Portal** Skip captcha if no Turnstile key provided -- **Infra** Resolve [RUSTSEC-2023-0044](https://rustsec.org/advisories/RUSTSEC-2023-0044) +- **Infra** Missing dpenedency on mounting volumn before setting permissions of /var/\* for Cockroach, ClickHouse, Prometheus, and Traffic Server +- **Chrip** Empty message parameters now have placeholder so NATS doesn't throw an error +- **Chrip** Messages with no parameters no longer have a trailing dot - **Bolt** Correctly resolve project root when building services natively +- **Bolt** Correctly determine executable path for `ExecServiceDriver::UploadedBinaryArtifact` with different Cargo names diff --git a/deny.toml b/deny.toml index 6c335c03a3..6c1b5b5c31 100644 --- a/deny.toml +++ b/deny.toml @@ -2,6 +2,9 @@ ignore = [ # chrono depends on time 0.1, which is not patched "RUSTSEC-2020-0071", + # webpki 0.21.4 only used by aws-smithy-client 0.41.0 in our deprecated + # generated clients. This is used only for type ser/de and old tests. + "RUSTSEC-2023-0052", ] [licenses] diff --git a/docs/getting_started/INTERNAL_DASHBOARDS.md b/docs/getting_started/INTERNAL_DASHBOARDS.md index 5ff86616ab..bb907fa1ed 100644 --- a/docs/getting_started/INTERNAL_DASHBOARDS.md +++ b/docs/getting_started/INTERNAL_DASHBOARDS.md @@ -6,14 +6,14 @@ Exposed tunnels & applications are configured [here](/lib/bolt/core/src/dep/terr Replace `MAIN_DOMAIN` with the value of `dns.domain.main`. -- [Consul](https://consul.MAIN_DOMAIN)) -- [Nomad](https://nomad.MAIN_DOMAIN)) -- [Cockroach](https://cockroach-http.MAIN_DOMAIN)) -- [ClickHouse](https://clickhouse-http.MAIN_DOMAIN)) -- [Prometheus (svc)](https://prometheus-svc.MAIN_DOMAIN)) -- [Prometheus (job)](https://prometheus-job.MAIN_DOMAIN)) -- [Minio](https://minio-console.MAIN_DOMAIN)) -- [Traefik (proxied)](https://ing-px.MAIN_DOMAIN)) -- [Traefik (job)](https://ing-job.MAIN_DOMAIN)) +- [Consul](https://consul.MAIN_DOMAIN) +- [Nomad](https://nomad.MAIN_DOMAIN) +- [Cockroach](https://cockroach-http.MAIN_DOMAIN) +- [ClickHouse](https://clickhouse-http.MAIN_DOMAIN) +- [Prometheus (svc)](https://prometheus-svc.MAIN_DOMAIN) +- [Prometheus (job)](https://prometheus-job.MAIN_DOMAIN) +- [Minio](https://minio-console.MAIN_DOMAIN) +- [Traefik (proxied)](https://ing-px.MAIN_DOMAIN) +- [Traefik (job)](https://ing-job.MAIN_DOMAIN) - This does not support regional dashboards at the moment (SVC-2584) - Will choose a random region until fixed diff --git a/docs/infrastructure/nats/TROUBLESHOOTING.md b/docs/infrastructure/nats/TROUBLESHOOTING.md new file mode 100644 index 0000000000..259f61faa8 --- /dev/null +++ b/docs/infrastructure/nats/TROUBLESHOOTING.md @@ -0,0 +1,9 @@ +# Troubleshooting + +## Checking the health of the cluster manually... + +1. `bolt ssh pool nats` +2. `nix-shell -p natscli` +3. `nats --server=10.0.44.2:4222 --user admin --password password context save default` +4. `nats context select default` +5. `nats server report connections` diff --git a/docs/infrastructure/saltstack/TROUBLESHOOTING.md b/docs/infrastructure/saltstack/TROUBLESHOOTING.md index 331675e0d9..5b6b57c381 100644 --- a/docs/infrastructure/saltstack/TROUBLESHOOTING.md +++ b/docs/infrastructure/saltstack/TROUBLESHOOTING.md @@ -31,3 +31,14 @@ Try a few things to figure this out: - Run `pstree -p my-pid` on the `salt-minion` process to see what subcommand is being ran - Read the `salt-minion` logs with `journalctl -u salt-minion` - Try applying specific SLS files with `salt apply 'my-minion' --sls my_file` + +## Error when bootstrapping Minion: `RSA key format is not supported` + +```bash +# Uninstall Salt +bolt ssh name staging-lnd-atl-crdb-05-2 'systemctl stop salt-minion; apt remove -y salt-cloud salt-common salt-minion; rm -rf /etc/salt /opt/saltstack /var/log/salt /var/cache/salt /run/salt /usr/bin/salt-*; echo Done' + +# Re-run install_salt_minion +(cd infra/tf/pools && terraform state rm 'module.install_salt_minion["staging-lnd-atl-crdb-05-2"]') +bolt tf apply pools +``` diff --git a/errors/glob/invalid.md b/errors/glob/invalid.md index d3acd0e3e5..aa09a269a7 100644 --- a/errors/glob/invalid.md +++ b/errors/glob/invalid.md @@ -4,6 +4,6 @@ description = "Invalid glob pattern: {error}" http_status = 400 --- -# CDN Too Many Auth Users +# Glob Invalid -The limit for auth users on a namespace has been reached. +Invalid glob pattern given diff --git a/errors/mm/auto-create-failed.md b/errors/mm/auto-create-failed.md new file mode 100644 index 0000000000..5a7cc00e3e --- /dev/null +++ b/errors/mm/auto-create-failed.md @@ -0,0 +1,9 @@ +--- +name = "MATCHMAKER_AUTO_CREATE_FAILED" +description = "Could not find a valid game mode and region pair for automatic lobby creation." +http_status = 400 +--- + +# Matchmaker Auto Create Failed + +Could not find a valid game mode and region pair for automatic lobby creation. diff --git a/errors/mm/custom-lobbies-disabled.md b/errors/mm/custom-lobbies-disabled.md new file mode 100644 index 0000000000..278aa2f096 --- /dev/null +++ b/errors/mm/custom-lobbies-disabled.md @@ -0,0 +1,9 @@ +--- +name = "MATCHMAKER_CUSTOM_LOBBIES_DISABLED" +description = "Custom lobbies are not allowed for the selected game mode." +http_status = 400 +--- + +# Matchmaker Custom Lobbies Disabled + +Custom lobbies are not allowed for the selected game mode. diff --git a/errors/mm/custom-lobby-config-invalid.md b/errors/mm/custom-lobby-config-invalid.md new file mode 100644 index 0000000000..982b743c17 --- /dev/null +++ b/errors/mm/custom-lobby-config-invalid.md @@ -0,0 +1,10 @@ +--- +name = "MATCHMAKER_CUSTOM_LOBBY_CONFIG_INVALID" +description = "The given custom lobby config is invalid: {reason}" +description_basic = "The given custom lobby config is invalid." +http_status = 400 +--- + +# Matchmaker Custom Lobby Config Invalid + +The given custom lobby config is invalid. This is most likely because it exceeds the maximum size limit of 16KiB. diff --git a/errors/mm/custom-lobby-limit-reached.md b/errors/mm/custom-lobby-limit-reached.md new file mode 100644 index 0000000000..c62f995bf2 --- /dev/null +++ b/errors/mm/custom-lobby-limit-reached.md @@ -0,0 +1,9 @@ +--- +name = "MATCHMAKER_CUSTOM_LOBBY_LIMIT_REACHED" +description = "User cannot create any more custom lobbies." +http_status = 400 +--- + +# Matchmaker Custom Lobby Limit Reached + +User cannot create any more custom lobbies. diff --git a/errors/mm/find-disabled.md b/errors/mm/find-disabled.md new file mode 100644 index 0000000000..4b9c1c7905 --- /dev/null +++ b/errors/mm/find-disabled.md @@ -0,0 +1,9 @@ +--- +name = "MATCHMAKER_FIND_DISABLED" +description = "The find endpoint has been disabled by the developer." +http_status = 400 +--- + +# Matchmaker Find Disabled + +The find endpoint has been disabled by the developer. diff --git a/errors/mm/identity-required.md b/errors/mm/identity-required.md new file mode 100644 index 0000000000..f3ab928bf1 --- /dev/null +++ b/errors/mm/identity-required.md @@ -0,0 +1,12 @@ +--- +name = "MATCHMAKER_IDENTITY_REQUIRED" +description = "This resource can not be accessed without an identity." +http_status = 400 +--- + +# Matchmaker Identity Required + +This resource can not be accessed without an identity. + +If you are a developer seeing this error, make sure your API calls to matchmaker endpoints include a bearer +token with game user entitlements. diff --git a/errors/mm/join-disabled.md b/errors/mm/join-disabled.md new file mode 100644 index 0000000000..0ed4dea4d6 --- /dev/null +++ b/errors/mm/join-disabled.md @@ -0,0 +1,9 @@ +--- +name = "MATCHMAKER_JOIN_DISABLED" +description = "The join endpoint has been disabled by the developer." +http_status = 400 +--- + +# Matchmaker Join Disabled + +The join endpoint has been disabled by the developer. diff --git a/errors/mm/region-not-enabled-for-game-mode.md b/errors/mm/region-not-enabled-for-game-mode.md index 12661c9919..3514ac8b97 100644 --- a/errors/mm/region-not-enabled-for-game-mode.md +++ b/errors/mm/region-not-enabled-for-game-mode.md @@ -4,7 +4,7 @@ description = "Region not enabled for game mode." http_status = 400 --- -# Matchmaker Region Not Enabled +# Matchmaker Region Not Enabled For Game Mode The region is not enabled for the game mode. diff --git a/errors/mm/region-not-found.md b/errors/mm/region-not-found.md new file mode 100644 index 0000000000..a7ce22092f --- /dev/null +++ b/errors/mm/region-not-found.md @@ -0,0 +1,9 @@ +--- +name = "MATCHMAKER_REGION_NOT_FOUND" +description = "One or more of the provided regions was not found." +http_status = 400 +--- + +# Matchmaker Region Not Found + +The region(s) provided were not found. diff --git a/errors/mm/registration-required.md b/errors/mm/registration-required.md new file mode 100644 index 0000000000..367229ab65 --- /dev/null +++ b/errors/mm/registration-required.md @@ -0,0 +1,12 @@ +--- +name = "MATCHMAKER_REGISTRATION_REQUIRED" +description = "This resource can not be accessed without a registered identity." +http_status = 400 +--- + +# Matchmaker Registration Required + +This resource can not be accessed without a registered identity. + +If you are a developer seeing this error, make sure your API calls to matchmaker endpoints include a bearer +token with game user entitlements, and the given game user is registered on Rivet. diff --git a/errors/mm/verification-failed.md b/errors/mm/verification-failed.md new file mode 100644 index 0000000000..80171e565a --- /dev/null +++ b/errors/mm/verification-failed.md @@ -0,0 +1,9 @@ +--- +name = "MATCHMAKER_VERIFICATION_FAILED" +description = "The user did not pass external matchmaker verification." +http_status = 400 +--- + +# Matchmaker Verification Failed + +The user did not pass external matchmaker verification. diff --git a/errors/mm/verification-request-failed.md b/errors/mm/verification-request-failed.md new file mode 100644 index 0000000000..45d905ad29 --- /dev/null +++ b/errors/mm/verification-request-failed.md @@ -0,0 +1,13 @@ +--- +name = "MATCHMAKER_VERIFICATION_REQUEST_FAILED" +description = "The external matchmaker verification system failed or returned an invalid response." +http_status = 400 +--- + +# Matchmaker Verification Request Failed + +The external matchmaker verification system failed or returned an invalid response. This is not an error that +has been caused by the user. + +If you are a developer seeing this error, check to see if your external matchmaker verification server is +correctly responding to Rivet's requests. diff --git a/fern/api/definition/cloud/games/builds.yml b/fern/api/definition/cloud/games/builds.yml index 0fe300e243..0a754c695b 100644 --- a/fern/api/definition/cloud/games/builds.yml +++ b/fern/api/definition/cloud/games/builds.yml @@ -44,6 +44,8 @@ types: docs: A tag given to the game build. type: string image_file: uploadCommons.PrepareFile + multipart_upload: + type: optional CreateGameBuildResponse: properties: @@ -51,8 +53,5 @@ types: type: uuid upload_id: type: uuid - image_presigned_request: - docs: >- - **Deprecated: use image_presigned_requests instead** - type: uploadCommons.PresignedRequest - image_presigned_requests: list + image_presigned_request: optional + image_presigned_requests: optional> diff --git a/fern/api/definition/cloud/version/matchmaker/game_mode.yml b/fern/api/definition/cloud/version/matchmaker/game_mode.yml index 3bc68c7719..543af12ddc 100644 --- a/fern/api/definition/cloud/version/matchmaker/game_mode.yml +++ b/fern/api/definition/cloud/version/matchmaker/game_mode.yml @@ -18,6 +18,15 @@ types: type: optional docker: type: optional + listable: + type: optional + + find_config: + type: optional + join_config: + type: optional + create_config: + type: optional # Region overrides tier: @@ -76,3 +85,58 @@ types: properties: min: integer max: integer + + GameModeIdentityRequirement: + docs: >- + The registration requirement for a user when joining/finding/creating a + lobby. "None" allows for connections without an identity. + enum: + - none + - guest + - registered + + GameModeVerificationConfig: + # TODO: Add link to tutorial in docs + docs: >- + Configuration that tells Rivet where to send validation requests and with + what headers. When set, Rivet will send the `verification_data` property + (given by the user in the find/join/create endpoint) to the given url + along with the headers provided and some information about the requested + lobby. The response of this request will determine if the user can join + that lobby or not. + properties: + url: string + headers: map + + GameModeFindConfig: + docs: >- + Configures the requirements and authentication for the /find endpoint. + If this value is not set in the config, the /find endpoint is still enabled. + properties: + enabled: + docs: Sets whether or not the /find endpoint is enabled. + type: boolean + identity_requirement: GameModeIdentityRequirement + verification_config: optional + + GameModeJoinConfig: + docs: >- + Configures the requirements and authentication for the /join endpoint. + If this value is not set in the config, the /join endpoint is still enabled. + properties: + enabled: + docs: Sets whether or not the /join endpoint is enabled. + type: boolean + identity_requirement: GameModeIdentityRequirement + verification_config: optional + + GameModeCreateConfig: + docs: >- + Configures the requirements and authentication for the /create endpoint. + If this value is not set in the config, the /create endpoint is NOT enabled. + properties: + identity_requirement: GameModeIdentityRequirement + verification_config: optional + enable_public: boolean + enable_private: boolean + max_lobbies_per_identity: optional diff --git a/fern/api/definition/matchmaker/common.yml b/fern/api/definition/matchmaker/common.yml index eb6a509470..c7f60cb9bc 100644 --- a/fern/api/definition/matchmaker/common.yml +++ b/fern/api/definition/matchmaker/common.yml @@ -15,6 +15,7 @@ types: max_players_direct: integer max_players_party: integer total_player_count: integer + state: optional GameModeInfo: docs: A game mode that the player can join. @@ -86,3 +87,8 @@ types: Pass this token through the socket to the lobby server. The lobby server will validate this token with `PlayerConnected.player_token` type: commons.JWT + + CustomLobbyPublicity: + enum: + - public + - private diff --git a/fern/api/definition/matchmaker/lobbies.yml b/fern/api/definition/matchmaker/lobbies.yml index 8b3e2c015f..9cdf42980a 100644 --- a/fern/api/definition/matchmaker/lobbies.yml +++ b/fern/api/definition/matchmaker/lobbies.yml @@ -24,7 +24,9 @@ service: path: /closed method: PUT docs: | - If `is_closed` is `true`, players will be prevented from joining the lobby. + If `is_closed` is `true`, the matchmaker will no longer route players to the lobby. Players can still + join using the /join endpoint (this can be disabled by the developer by rejecting all new connections + after setting the lobby to closed). Does not shutdown the lobby. request: name: SetLobbyClosedRequest @@ -32,6 +34,20 @@ service: properties: is_closed: boolean + setState: + path: /state + method: PUT + request: + name: SetLobbyStateRequest + body: optional + + getState: + path: /{lobby_id}/state + method: GET + path-parameters: + lobby_id: uuid + response: optional + find: path: /find method: POST @@ -49,6 +65,7 @@ service: regions: optional> prevent_auto_create_lobby: optional captcha: optional + verification_data: optional response: FindLobbyResponse join: @@ -64,12 +81,34 @@ service: properties: lobby_id: string captcha: optional + verification_data: optional response: JoinLobbyResponse + create: + path: /create + method: POST + docs: | + Creates a custom lobby. + request: + name: CreateLobbyRequest + body: + properties: + game_mode: string + region: optional + captcha: optional + publicity: localCommons.CustomLobbyPublicity + lobby_config: optional + verification_data: optional + response: CreateLobbyResponse + list: path: /list method: GET docs: Lists all open lobbies. + request: + name: ListLobbiesRequest + query-parameters: + include_state: optional response: ListLobbiesResponse types: @@ -85,6 +124,12 @@ types: ports: map player: matchmakerCommons.JoinPlayer + CreateLobbyResponse: + properties: + lobby: matchmakerCommons.JoinLobby + ports: map + player: matchmakerCommons.JoinPlayer + ListLobbiesResponse: properties: game_modes: list diff --git a/gen/openapi/external/spec/openapi.yml b/gen/openapi/external/spec/openapi.yml index c24c4c0d10..4abf236b72 100644 --- a/gen/openapi/external/spec/openapi.yml +++ b/gen/openapi/external/spec/openapi.yml @@ -7359,8 +7359,13 @@ paths: /lobbies/closed: put: description: > - If `is_closed` is `true`, players will be prevented from joining the - lobby. + If `is_closed` is `true`, the matchmaker will no longer route players to + the lobby. Players can still + + join using the /join endpoint (this can be disabled by the developer by + rejecting all new connections + + after setting the lobby to closed). Does not shutdown the lobby. operationId: matchmaker_lobbies_setClosed @@ -7420,6 +7425,116 @@ paths: type: boolean required: - is_closed + /lobbies/state: + put: + operationId: matchmaker_lobbies_setState + tags: + - MatchmakerLobbies + parameters: [] + responses: + '204': + description: '' + '400': + description: '' + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBody' + '403': + description: '' + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBody' + '404': + description: '' + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBody' + '408': + description: '' + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBody' + '429': + description: '' + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBody' + '500': + description: '' + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBody' + servers: + - url: https://matchmaker.api.rivet.gg/v1 + security: *ref_0 + requestBody: + required: false + content: + application/json: + schema: {} + /lobbies/{lobby_id}/state: + get: + operationId: matchmaker_lobbies_getState + tags: + - MatchmakerLobbies + parameters: + - name: lobby_id + in: path + required: true + schema: + type: string + format: uuid + responses: + '200': + description: '' + content: + application/json: + schema: {} + '400': + description: '' + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBody' + '403': + description: '' + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBody' + '404': + description: '' + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBody' + '408': + description: '' + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBody' + '429': + description: '' + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBody' + '500': + description: '' + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBody' + servers: + - url: https://matchmaker.api.rivet.gg/v1 + security: *ref_0 /lobbies/find: post: description: | @@ -7500,6 +7615,7 @@ paths: type: boolean captcha: $ref: '#/components/schemas/CaptchaConfig' + verification_data: {} required: - game_modes /lobbies/join: @@ -7569,15 +7685,95 @@ paths: type: string captcha: $ref: '#/components/schemas/CaptchaConfig' + verification_data: {} required: - lobby_id + /lobbies/create: + post: + description: | + Creates a custom lobby. + operationId: matchmaker_lobbies_create + tags: + - MatchmakerLobbies + parameters: [] + responses: + '200': + description: '' + content: + application/json: + schema: + $ref: '#/components/schemas/MatchmakerCreateLobbyResponse' + '400': + description: '' + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBody' + '403': + description: '' + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBody' + '404': + description: '' + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBody' + '408': + description: '' + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBody' + '429': + description: '' + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBody' + '500': + description: '' + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBody' + servers: + - url: https://matchmaker.api.rivet.gg/v1 + security: *ref_0 + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + game_mode: + type: string + region: + type: string + captcha: + $ref: '#/components/schemas/CaptchaConfig' + publicity: + $ref: '#/components/schemas/MatchmakerCustomLobbyPublicity' + lobby_config: {} + verification_data: {} + required: + - game_mode + - publicity /lobbies/list: get: description: Lists all open lobbies. operationId: matchmaker_lobbies_list tags: - MatchmakerLobbies - parameters: [] + parameters: + - name: include_state + in: query + required: false + schema: + type: boolean responses: '200': description: '' @@ -9882,6 +10078,8 @@ components: description: A tag given to the game build. image_file: $ref: '#/components/schemas/UploadPrepareFile' + multipart_upload: + type: boolean required: - display_name - image_tag @@ -9897,7 +10095,6 @@ components: format: uuid image_presigned_request: $ref: '#/components/schemas/UploadPresignedRequest' - description: '**Deprecated: use image_presigned_requests instead**' image_presigned_requests: type: array items: @@ -9905,8 +10102,6 @@ components: required: - build_id - upload_id - - image_presigned_request - - image_presigned_requests CloudGamesListGameCdnSitesResponse: type: object properties: @@ -10504,6 +10699,14 @@ components: type: integer docker: $ref: '#/components/schemas/CloudVersionMatchmakerGameModeRuntimeDocker' + listable: + type: boolean + find_config: + $ref: '#/components/schemas/CloudVersionMatchmakerGameModeFindConfig' + join_config: + $ref: '#/components/schemas/CloudVersionMatchmakerGameModeJoinConfig' + create_config: + $ref: '#/components/schemas/CloudVersionMatchmakerGameModeCreateConfig' tier: type: string idle_lobbies: @@ -10578,6 +10781,95 @@ components: required: - min - max + CloudVersionMatchmakerGameModeIdentityRequirement: + type: string + enum: + - none + - guest + - registered + description: >- + The registration requirement for a user when joining/finding/creating a + lobby. "None" allows for connections without an identity. + CloudVersionMatchmakerGameModeVerificationConfig: + type: object + description: >- + Configuration that tells Rivet where to send validation requests and + with what headers. When set, Rivet will send the `verification_data` + property (given by the user in the find/join/create endpoint) to the + given url along with the headers provided and some information about the + requested lobby. The response of this request will determine if the user + can join that lobby or not. + properties: + url: + type: string + headers: + type: object + additionalProperties: + type: string + required: + - url + - headers + CloudVersionMatchmakerGameModeFindConfig: + type: object + description: >- + Configures the requirements and authentication for the /find endpoint. + If this value is not set in the config, the /find endpoint is still + enabled. + properties: + enabled: + type: boolean + description: Sets whether or not the /find endpoint is enabled. + identity_requirement: + $ref: >- + #/components/schemas/CloudVersionMatchmakerGameModeIdentityRequirement + verification_config: + $ref: >- + #/components/schemas/CloudVersionMatchmakerGameModeVerificationConfig + required: + - enabled + - identity_requirement + CloudVersionMatchmakerGameModeJoinConfig: + type: object + description: >- + Configures the requirements and authentication for the /join endpoint. + If this value is not set in the config, the /join endpoint is still + enabled. + properties: + enabled: + type: boolean + description: Sets whether or not the /join endpoint is enabled. + identity_requirement: + $ref: >- + #/components/schemas/CloudVersionMatchmakerGameModeIdentityRequirement + verification_config: + $ref: >- + #/components/schemas/CloudVersionMatchmakerGameModeVerificationConfig + required: + - enabled + - identity_requirement + CloudVersionMatchmakerGameModeCreateConfig: + type: object + description: >- + Configures the requirements and authentication for the /create endpoint. + If this value is not set in the config, the /create endpoint is NOT + enabled. + properties: + identity_requirement: + $ref: >- + #/components/schemas/CloudVersionMatchmakerGameModeIdentityRequirement + verification_config: + $ref: >- + #/components/schemas/CloudVersionMatchmakerGameModeVerificationConfig + enable_public: + type: boolean + enable_private: + type: boolean + max_lobbies_per_identity: + type: integer + required: + - identity_requirement + - enable_public + - enable_private CloudVersionMatchmakerLobbyGroup: type: object description: A game mode. @@ -11667,6 +11959,7 @@ components: type: integer total_player_count: type: integer + state: {} required: - region_id - game_mode_id @@ -11783,6 +12076,11 @@ components: server will validate this token with `PlayerConnected.player_token` required: - token + MatchmakerCustomLobbyPublicity: + type: string + enum: + - public + - private MatchmakerFindLobbyResponse: type: object properties: @@ -11813,6 +12111,21 @@ components: - lobby - ports - player + MatchmakerCreateLobbyResponse: + type: object + properties: + lobby: + $ref: '#/components/schemas/MatchmakerJoinLobby' + ports: + type: object + additionalProperties: + $ref: '#/components/schemas/MatchmakerJoinPort' + player: + $ref: '#/components/schemas/MatchmakerJoinPlayer' + required: + - lobby + - ports + - player MatchmakerListLobbiesResponse: type: object properties: diff --git a/gen/openapi/internal/rust/.openapi-generator/FILES b/gen/openapi/internal/rust/.openapi-generator/FILES index 11fe5f1b45..f41adecaad 100644 --- a/gen/openapi/internal/rust/.openapi-generator/FILES +++ b/gen/openapi/internal/rust/.openapi-generator/FILES @@ -184,10 +184,15 @@ docs/CloudVersionMatchmakerCaptchaTurnstile.md docs/CloudVersionMatchmakerCaptchaTurnstileDomain.md docs/CloudVersionMatchmakerConfig.md docs/CloudVersionMatchmakerGameMode.md +docs/CloudVersionMatchmakerGameModeCreateConfig.md +docs/CloudVersionMatchmakerGameModeFindConfig.md +docs/CloudVersionMatchmakerGameModeIdentityRequirement.md docs/CloudVersionMatchmakerGameModeIdleLobbiesConfig.md +docs/CloudVersionMatchmakerGameModeJoinConfig.md docs/CloudVersionMatchmakerGameModeRegion.md docs/CloudVersionMatchmakerGameModeRuntimeDocker.md docs/CloudVersionMatchmakerGameModeRuntimeDockerPort.md +docs/CloudVersionMatchmakerGameModeVerificationConfig.md docs/CloudVersionMatchmakerLobbyGroup.md docs/CloudVersionMatchmakerLobbyGroupIdleLobbiesConfig.md docs/CloudVersionMatchmakerLobbyGroupRegion.md @@ -307,6 +312,8 @@ docs/KvListResponse.md docs/KvPutBatchRequest.md docs/KvPutEntry.md docs/KvPutRequest.md +docs/MatchmakerCreateLobbyResponse.md +docs/MatchmakerCustomLobbyPublicity.md docs/MatchmakerFindLobbyResponse.md docs/MatchmakerGameModeInfo.md docs/MatchmakerGameModeStatistics.md @@ -320,6 +327,7 @@ docs/MatchmakerJoinRegion.md docs/MatchmakerListLobbiesResponse.md docs/MatchmakerListRegionsResponse.md docs/MatchmakerLobbiesApi.md +docs/MatchmakerLobbiesCreateRequest.md docs/MatchmakerLobbiesFindRequest.md docs/MatchmakerLobbiesJoinRequest.md docs/MatchmakerLobbiesSetClosedRequest.md @@ -543,10 +551,15 @@ src/models/cloud_version_matchmaker_captcha_turnstile.rs src/models/cloud_version_matchmaker_captcha_turnstile_domain.rs src/models/cloud_version_matchmaker_config.rs src/models/cloud_version_matchmaker_game_mode.rs +src/models/cloud_version_matchmaker_game_mode_create_config.rs +src/models/cloud_version_matchmaker_game_mode_find_config.rs +src/models/cloud_version_matchmaker_game_mode_identity_requirement.rs src/models/cloud_version_matchmaker_game_mode_idle_lobbies_config.rs +src/models/cloud_version_matchmaker_game_mode_join_config.rs src/models/cloud_version_matchmaker_game_mode_region.rs src/models/cloud_version_matchmaker_game_mode_runtime_docker.rs src/models/cloud_version_matchmaker_game_mode_runtime_docker_port.rs +src/models/cloud_version_matchmaker_game_mode_verification_config.rs src/models/cloud_version_matchmaker_lobby_group.rs src/models/cloud_version_matchmaker_lobby_group_idle_lobbies_config.rs src/models/cloud_version_matchmaker_lobby_group_region.rs @@ -657,6 +670,8 @@ src/models/kv_list_response.rs src/models/kv_put_batch_request.rs src/models/kv_put_entry.rs src/models/kv_put_request.rs +src/models/matchmaker_create_lobby_response.rs +src/models/matchmaker_custom_lobby_publicity.rs src/models/matchmaker_find_lobby_response.rs src/models/matchmaker_game_mode_info.rs src/models/matchmaker_game_mode_statistics.rs @@ -669,6 +684,7 @@ src/models/matchmaker_join_port_range.rs src/models/matchmaker_join_region.rs src/models/matchmaker_list_lobbies_response.rs src/models/matchmaker_list_regions_response.rs +src/models/matchmaker_lobbies_create_request.rs src/models/matchmaker_lobbies_find_request.rs src/models/matchmaker_lobbies_join_request.rs src/models/matchmaker_lobbies_set_closed_request.rs diff --git a/gen/openapi/internal/rust/README.md b/gen/openapi/internal/rust/README.md index efa6219597..9952a42352 100644 --- a/gen/openapi/internal/rust/README.md +++ b/gen/openapi/internal/rust/README.md @@ -148,11 +148,14 @@ Class | Method | HTTP request | Description *KvApi* | [**kv_list**](docs/KvApi.md#kv_list) | **GET** /entries/list | *KvApi* | [**kv_put**](docs/KvApi.md#kv_put) | **PUT** /entries | *KvApi* | [**kv_put_batch**](docs/KvApi.md#kv_put_batch) | **PUT** /entries/batch | +*MatchmakerLobbiesApi* | [**matchmaker_lobbies_create**](docs/MatchmakerLobbiesApi.md#matchmaker_lobbies_create) | **POST** /lobbies/create | *MatchmakerLobbiesApi* | [**matchmaker_lobbies_find**](docs/MatchmakerLobbiesApi.md#matchmaker_lobbies_find) | **POST** /lobbies/find | +*MatchmakerLobbiesApi* | [**matchmaker_lobbies_get_state**](docs/MatchmakerLobbiesApi.md#matchmaker_lobbies_get_state) | **GET** /lobbies/{lobby_id}/state | *MatchmakerLobbiesApi* | [**matchmaker_lobbies_join**](docs/MatchmakerLobbiesApi.md#matchmaker_lobbies_join) | **POST** /lobbies/join | *MatchmakerLobbiesApi* | [**matchmaker_lobbies_list**](docs/MatchmakerLobbiesApi.md#matchmaker_lobbies_list) | **GET** /lobbies/list | *MatchmakerLobbiesApi* | [**matchmaker_lobbies_ready**](docs/MatchmakerLobbiesApi.md#matchmaker_lobbies_ready) | **POST** /lobbies/ready | *MatchmakerLobbiesApi* | [**matchmaker_lobbies_set_closed**](docs/MatchmakerLobbiesApi.md#matchmaker_lobbies_set_closed) | **PUT** /lobbies/closed | +*MatchmakerLobbiesApi* | [**matchmaker_lobbies_set_state**](docs/MatchmakerLobbiesApi.md#matchmaker_lobbies_set_state) | **PUT** /lobbies/state | *MatchmakerPlayersApi* | [**matchmaker_players_connected**](docs/MatchmakerPlayersApi.md#matchmaker_players_connected) | **POST** /players/connected | *MatchmakerPlayersApi* | [**matchmaker_players_disconnected**](docs/MatchmakerPlayersApi.md#matchmaker_players_disconnected) | **POST** /players/disconnected | *MatchmakerPlayersApi* | [**matchmaker_players_get_statistics**](docs/MatchmakerPlayersApi.md#matchmaker_players_get_statistics) | **GET** /players/statistics | @@ -325,10 +328,15 @@ Class | Method | HTTP request | Description - [CloudVersionMatchmakerCaptchaTurnstileDomain](docs/CloudVersionMatchmakerCaptchaTurnstileDomain.md) - [CloudVersionMatchmakerConfig](docs/CloudVersionMatchmakerConfig.md) - [CloudVersionMatchmakerGameMode](docs/CloudVersionMatchmakerGameMode.md) + - [CloudVersionMatchmakerGameModeCreateConfig](docs/CloudVersionMatchmakerGameModeCreateConfig.md) + - [CloudVersionMatchmakerGameModeFindConfig](docs/CloudVersionMatchmakerGameModeFindConfig.md) + - [CloudVersionMatchmakerGameModeIdentityRequirement](docs/CloudVersionMatchmakerGameModeIdentityRequirement.md) - [CloudVersionMatchmakerGameModeIdleLobbiesConfig](docs/CloudVersionMatchmakerGameModeIdleLobbiesConfig.md) + - [CloudVersionMatchmakerGameModeJoinConfig](docs/CloudVersionMatchmakerGameModeJoinConfig.md) - [CloudVersionMatchmakerGameModeRegion](docs/CloudVersionMatchmakerGameModeRegion.md) - [CloudVersionMatchmakerGameModeRuntimeDocker](docs/CloudVersionMatchmakerGameModeRuntimeDocker.md) - [CloudVersionMatchmakerGameModeRuntimeDockerPort](docs/CloudVersionMatchmakerGameModeRuntimeDockerPort.md) + - [CloudVersionMatchmakerGameModeVerificationConfig](docs/CloudVersionMatchmakerGameModeVerificationConfig.md) - [CloudVersionMatchmakerLobbyGroup](docs/CloudVersionMatchmakerLobbyGroup.md) - [CloudVersionMatchmakerLobbyGroupIdleLobbiesConfig](docs/CloudVersionMatchmakerLobbyGroupIdleLobbiesConfig.md) - [CloudVersionMatchmakerLobbyGroupRegion](docs/CloudVersionMatchmakerLobbyGroupRegion.md) @@ -439,6 +447,8 @@ Class | Method | HTTP request | Description - [KvPutBatchRequest](docs/KvPutBatchRequest.md) - [KvPutEntry](docs/KvPutEntry.md) - [KvPutRequest](docs/KvPutRequest.md) + - [MatchmakerCreateLobbyResponse](docs/MatchmakerCreateLobbyResponse.md) + - [MatchmakerCustomLobbyPublicity](docs/MatchmakerCustomLobbyPublicity.md) - [MatchmakerFindLobbyResponse](docs/MatchmakerFindLobbyResponse.md) - [MatchmakerGameModeInfo](docs/MatchmakerGameModeInfo.md) - [MatchmakerGameModeStatistics](docs/MatchmakerGameModeStatistics.md) @@ -451,6 +461,7 @@ Class | Method | HTTP request | Description - [MatchmakerJoinRegion](docs/MatchmakerJoinRegion.md) - [MatchmakerListLobbiesResponse](docs/MatchmakerListLobbiesResponse.md) - [MatchmakerListRegionsResponse](docs/MatchmakerListRegionsResponse.md) + - [MatchmakerLobbiesCreateRequest](docs/MatchmakerLobbiesCreateRequest.md) - [MatchmakerLobbiesFindRequest](docs/MatchmakerLobbiesFindRequest.md) - [MatchmakerLobbiesJoinRequest](docs/MatchmakerLobbiesJoinRequest.md) - [MatchmakerLobbiesSetClosedRequest](docs/MatchmakerLobbiesSetClosedRequest.md) diff --git a/gen/openapi/internal/rust/docs/CloudGamesCreateGameBuildRequest.md b/gen/openapi/internal/rust/docs/CloudGamesCreateGameBuildRequest.md index 52a1167c8b..0e0024eb05 100644 --- a/gen/openapi/internal/rust/docs/CloudGamesCreateGameBuildRequest.md +++ b/gen/openapi/internal/rust/docs/CloudGamesCreateGameBuildRequest.md @@ -7,6 +7,7 @@ Name | Type | Description | Notes **display_name** | **String** | Represent a resource's readable display name. | **image_file** | [**crate::models::UploadPrepareFile**](UploadPrepareFile.md) | | **image_tag** | **String** | A tag given to the game build. | +**multipart_upload** | Option<**bool**> | | [optional] [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/gen/openapi/internal/rust/docs/CloudGamesCreateGameBuildResponse.md b/gen/openapi/internal/rust/docs/CloudGamesCreateGameBuildResponse.md index da36496605..fb3c4a586a 100644 --- a/gen/openapi/internal/rust/docs/CloudGamesCreateGameBuildResponse.md +++ b/gen/openapi/internal/rust/docs/CloudGamesCreateGameBuildResponse.md @@ -5,8 +5,8 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- **build_id** | [**uuid::Uuid**](uuid::Uuid.md) | | -**image_presigned_request** | [**crate::models::UploadPresignedRequest**](UploadPresignedRequest.md) | | -**image_presigned_requests** | [**Vec**](UploadPresignedRequest.md) | | +**image_presigned_request** | Option<[**crate::models::UploadPresignedRequest**](UploadPresignedRequest.md)> | | [optional] +**image_presigned_requests** | Option<[**Vec**](UploadPresignedRequest.md)> | | [optional] **upload_id** | [**uuid::Uuid**](uuid::Uuid.md) | | [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/gen/openapi/internal/rust/docs/CloudVersionMatchmakerGameMode.md b/gen/openapi/internal/rust/docs/CloudVersionMatchmakerGameMode.md index 5ae158699e..7606032f36 100644 --- a/gen/openapi/internal/rust/docs/CloudVersionMatchmakerGameMode.md +++ b/gen/openapi/internal/rust/docs/CloudVersionMatchmakerGameMode.md @@ -4,8 +4,12 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- +**create_config** | Option<[**crate::models::CloudVersionMatchmakerGameModeCreateConfig**](CloudVersionMatchmakerGameModeCreateConfig.md)> | | [optional] **docker** | Option<[**crate::models::CloudVersionMatchmakerGameModeRuntimeDocker**](CloudVersionMatchmakerGameModeRuntimeDocker.md)> | | [optional] +**find_config** | Option<[**crate::models::CloudVersionMatchmakerGameModeFindConfig**](CloudVersionMatchmakerGameModeFindConfig.md)> | | [optional] **idle_lobbies** | Option<[**crate::models::CloudVersionMatchmakerGameModeIdleLobbiesConfig**](CloudVersionMatchmakerGameModeIdleLobbiesConfig.md)> | | [optional] +**join_config** | Option<[**crate::models::CloudVersionMatchmakerGameModeJoinConfig**](CloudVersionMatchmakerGameModeJoinConfig.md)> | | [optional] +**listable** | Option<**bool**> | | [optional] **max_players** | Option<**i32**> | | [optional] **max_players_direct** | Option<**i32**> | | [optional] **max_players_party** | Option<**i32**> | | [optional] diff --git a/gen/openapi/internal/rust/docs/CloudVersionMatchmakerGameModeCreateConfig.md b/gen/openapi/internal/rust/docs/CloudVersionMatchmakerGameModeCreateConfig.md new file mode 100644 index 0000000000..de317b2632 --- /dev/null +++ b/gen/openapi/internal/rust/docs/CloudVersionMatchmakerGameModeCreateConfig.md @@ -0,0 +1,15 @@ +# CloudVersionMatchmakerGameModeCreateConfig + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**enable_private** | **bool** | | +**enable_public** | **bool** | | +**identity_requirement** | [**crate::models::CloudVersionMatchmakerGameModeIdentityRequirement**](CloudVersionMatchmakerGameModeIdentityRequirement.md) | | +**max_lobbies_per_identity** | Option<**i32**> | | [optional] +**verification_config** | Option<[**crate::models::CloudVersionMatchmakerGameModeVerificationConfig**](CloudVersionMatchmakerGameModeVerificationConfig.md)> | | [optional] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/gen/openapi/internal/rust/docs/CloudVersionMatchmakerGameModeFindConfig.md b/gen/openapi/internal/rust/docs/CloudVersionMatchmakerGameModeFindConfig.md new file mode 100644 index 0000000000..aa05da2af1 --- /dev/null +++ b/gen/openapi/internal/rust/docs/CloudVersionMatchmakerGameModeFindConfig.md @@ -0,0 +1,13 @@ +# CloudVersionMatchmakerGameModeFindConfig + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**enabled** | **bool** | Sets whether or not the /find endpoint is enabled. | +**identity_requirement** | [**crate::models::CloudVersionMatchmakerGameModeIdentityRequirement**](CloudVersionMatchmakerGameModeIdentityRequirement.md) | | +**verification_config** | Option<[**crate::models::CloudVersionMatchmakerGameModeVerificationConfig**](CloudVersionMatchmakerGameModeVerificationConfig.md)> | | [optional] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/gen/openapi/internal/rust/docs/CloudVersionMatchmakerGameModeIdentityRequirement.md b/gen/openapi/internal/rust/docs/CloudVersionMatchmakerGameModeIdentityRequirement.md new file mode 100644 index 0000000000..f8d550d34d --- /dev/null +++ b/gen/openapi/internal/rust/docs/CloudVersionMatchmakerGameModeIdentityRequirement.md @@ -0,0 +1,10 @@ +# CloudVersionMatchmakerGameModeIdentityRequirement + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/gen/openapi/internal/rust/docs/CloudVersionMatchmakerGameModeJoinConfig.md b/gen/openapi/internal/rust/docs/CloudVersionMatchmakerGameModeJoinConfig.md new file mode 100644 index 0000000000..814c5de579 --- /dev/null +++ b/gen/openapi/internal/rust/docs/CloudVersionMatchmakerGameModeJoinConfig.md @@ -0,0 +1,13 @@ +# CloudVersionMatchmakerGameModeJoinConfig + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**enabled** | **bool** | Sets whether or not the /join endpoint is enabled. | +**identity_requirement** | [**crate::models::CloudVersionMatchmakerGameModeIdentityRequirement**](CloudVersionMatchmakerGameModeIdentityRequirement.md) | | +**verification_config** | Option<[**crate::models::CloudVersionMatchmakerGameModeVerificationConfig**](CloudVersionMatchmakerGameModeVerificationConfig.md)> | | [optional] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/gen/openapi/internal/rust/docs/CloudVersionMatchmakerGameModeVerificationConfig.md b/gen/openapi/internal/rust/docs/CloudVersionMatchmakerGameModeVerificationConfig.md new file mode 100644 index 0000000000..f2788127bb --- /dev/null +++ b/gen/openapi/internal/rust/docs/CloudVersionMatchmakerGameModeVerificationConfig.md @@ -0,0 +1,12 @@ +# CloudVersionMatchmakerGameModeVerificationConfig + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**headers** | **::std::collections::HashMap** | | +**url** | **String** | | + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/gen/openapi/internal/rust/docs/MatchmakerCreateLobbyResponse.md b/gen/openapi/internal/rust/docs/MatchmakerCreateLobbyResponse.md new file mode 100644 index 0000000000..d00ff19503 --- /dev/null +++ b/gen/openapi/internal/rust/docs/MatchmakerCreateLobbyResponse.md @@ -0,0 +1,13 @@ +# MatchmakerCreateLobbyResponse + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**lobby** | [**crate::models::MatchmakerJoinLobby**](MatchmakerJoinLobby.md) | | +**player** | [**crate::models::MatchmakerJoinPlayer**](MatchmakerJoinPlayer.md) | | +**ports** | [**::std::collections::HashMap**](MatchmakerJoinPort.md) | | + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/gen/openapi/internal/rust/docs/MatchmakerCustomLobbyPublicity.md b/gen/openapi/internal/rust/docs/MatchmakerCustomLobbyPublicity.md new file mode 100644 index 0000000000..9ef8998a74 --- /dev/null +++ b/gen/openapi/internal/rust/docs/MatchmakerCustomLobbyPublicity.md @@ -0,0 +1,10 @@ +# MatchmakerCustomLobbyPublicity + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/gen/openapi/internal/rust/docs/MatchmakerLobbiesApi.md b/gen/openapi/internal/rust/docs/MatchmakerLobbiesApi.md index 7ec18651a5..4d2d5985f0 100644 --- a/gen/openapi/internal/rust/docs/MatchmakerLobbiesApi.md +++ b/gen/openapi/internal/rust/docs/MatchmakerLobbiesApi.md @@ -4,14 +4,47 @@ All URIs are relative to *http://localhost* Method | HTTP request | Description ------------- | ------------- | ------------- +[**matchmaker_lobbies_create**](MatchmakerLobbiesApi.md#matchmaker_lobbies_create) | **POST** /lobbies/create | [**matchmaker_lobbies_find**](MatchmakerLobbiesApi.md#matchmaker_lobbies_find) | **POST** /lobbies/find | +[**matchmaker_lobbies_get_state**](MatchmakerLobbiesApi.md#matchmaker_lobbies_get_state) | **GET** /lobbies/{lobby_id}/state | [**matchmaker_lobbies_join**](MatchmakerLobbiesApi.md#matchmaker_lobbies_join) | **POST** /lobbies/join | [**matchmaker_lobbies_list**](MatchmakerLobbiesApi.md#matchmaker_lobbies_list) | **GET** /lobbies/list | [**matchmaker_lobbies_ready**](MatchmakerLobbiesApi.md#matchmaker_lobbies_ready) | **POST** /lobbies/ready | [**matchmaker_lobbies_set_closed**](MatchmakerLobbiesApi.md#matchmaker_lobbies_set_closed) | **PUT** /lobbies/closed | +[**matchmaker_lobbies_set_state**](MatchmakerLobbiesApi.md#matchmaker_lobbies_set_state) | **PUT** /lobbies/state | +## matchmaker_lobbies_create + +> crate::models::MatchmakerCreateLobbyResponse matchmaker_lobbies_create(matchmaker_lobbies_create_request) + + +Creates a custom lobby. + +### Parameters + + +Name | Type | Description | Required | Notes +------------- | ------------- | ------------- | ------------- | ------------- +**matchmaker_lobbies_create_request** | [**MatchmakerLobbiesCreateRequest**](MatchmakerLobbiesCreateRequest.md) | | [required] | + +### Return type + +[**crate::models::MatchmakerCreateLobbyResponse**](MatchmakerCreateLobbyResponse.md) + +### Authorization + +[BearerAuth](../README.md#BearerAuth) + +### HTTP request headers + +- **Content-Type**: application/json +- **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + + ## matchmaker_lobbies_find > crate::models::MatchmakerFindLobbyResponse matchmaker_lobbies_find(matchmaker_lobbies_find_request, origin) @@ -43,6 +76,34 @@ Name | Type | Description | Required | Notes [[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) +## matchmaker_lobbies_get_state + +> serde_json::Value matchmaker_lobbies_get_state(lobby_id) + + +### Parameters + + +Name | Type | Description | Required | Notes +------------- | ------------- | ------------- | ------------- | ------------- +**lobby_id** | **uuid::Uuid** | | [required] | + +### Return type + +[**serde_json::Value**](serde_json::Value.md) + +### Authorization + +[BearerAuth](../README.md#BearerAuth) + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + + ## matchmaker_lobbies_join > crate::models::MatchmakerJoinLobbyResponse matchmaker_lobbies_join(matchmaker_lobbies_join_request) @@ -75,14 +136,17 @@ Name | Type | Description | Required | Notes ## matchmaker_lobbies_list -> crate::models::MatchmakerListLobbiesResponse matchmaker_lobbies_list() +> crate::models::MatchmakerListLobbiesResponse matchmaker_lobbies_list(include_state) Lists all open lobbies. ### Parameters -This endpoint does not need any parameter. + +Name | Type | Description | Required | Notes +------------- | ------------- | ------------- | ------------- | ------------- +**include_state** | Option<**bool**> | | | ### Return type @@ -132,7 +196,7 @@ This endpoint does not need any parameter. > matchmaker_lobbies_set_closed(matchmaker_lobbies_set_closed_request) -If `is_closed` is `true`, players will be prevented from joining the lobby. Does not shutdown the lobby. +If `is_closed` is `true`, the matchmaker will no longer route players to the lobby. Players can still join using the /join endpoint (this can be disabled by the developer by rejecting all new connections after setting the lobby to closed). Does not shutdown the lobby. ### Parameters @@ -156,3 +220,31 @@ Name | Type | Description | Required | Notes [[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +## matchmaker_lobbies_set_state + +> matchmaker_lobbies_set_state(body) + + +### Parameters + + +Name | Type | Description | Required | Notes +------------- | ------------- | ------------- | ------------- | ------------- +**body** | Option<**serde_json::Value**> | | | + +### Return type + + (empty response body) + +### Authorization + +[BearerAuth](../README.md#BearerAuth) + +### HTTP request headers + +- **Content-Type**: application/json +- **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + diff --git a/gen/openapi/internal/rust/docs/MatchmakerLobbiesCreateRequest.md b/gen/openapi/internal/rust/docs/MatchmakerLobbiesCreateRequest.md new file mode 100644 index 0000000000..5ba0a9904c --- /dev/null +++ b/gen/openapi/internal/rust/docs/MatchmakerLobbiesCreateRequest.md @@ -0,0 +1,16 @@ +# MatchmakerLobbiesCreateRequest + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**captcha** | Option<[**crate::models::CaptchaConfig**](CaptchaConfig.md)> | | [optional] +**game_mode** | **String** | | +**lobby_config** | Option<[**serde_json::Value**](.md)> | | [optional] +**publicity** | [**crate::models::MatchmakerCustomLobbyPublicity**](MatchmakerCustomLobbyPublicity.md) | | +**region** | Option<**String**> | | [optional] +**verification_data** | Option<[**serde_json::Value**](.md)> | | [optional] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/gen/openapi/internal/rust/docs/MatchmakerLobbiesFindRequest.md b/gen/openapi/internal/rust/docs/MatchmakerLobbiesFindRequest.md index d5a37dcce6..953ba3b105 100644 --- a/gen/openapi/internal/rust/docs/MatchmakerLobbiesFindRequest.md +++ b/gen/openapi/internal/rust/docs/MatchmakerLobbiesFindRequest.md @@ -8,6 +8,7 @@ Name | Type | Description | Notes **game_modes** | **Vec** | | **prevent_auto_create_lobby** | Option<**bool**> | | [optional] **regions** | Option<**Vec**> | | [optional] +**verification_data** | Option<[**serde_json::Value**](.md)> | | [optional] [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/gen/openapi/internal/rust/docs/MatchmakerLobbiesJoinRequest.md b/gen/openapi/internal/rust/docs/MatchmakerLobbiesJoinRequest.md index c0e9afd937..afffc6e3b2 100644 --- a/gen/openapi/internal/rust/docs/MatchmakerLobbiesJoinRequest.md +++ b/gen/openapi/internal/rust/docs/MatchmakerLobbiesJoinRequest.md @@ -6,6 +6,7 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- **captcha** | Option<[**crate::models::CaptchaConfig**](CaptchaConfig.md)> | | [optional] **lobby_id** | **String** | | +**verification_data** | Option<[**serde_json::Value**](.md)> | | [optional] [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/gen/openapi/internal/rust/docs/MatchmakerLobbyInfo.md b/gen/openapi/internal/rust/docs/MatchmakerLobbyInfo.md index feeaf6596a..02f40bef1a 100644 --- a/gen/openapi/internal/rust/docs/MatchmakerLobbyInfo.md +++ b/gen/openapi/internal/rust/docs/MatchmakerLobbyInfo.md @@ -10,6 +10,7 @@ Name | Type | Description | Notes **max_players_normal** | **i32** | | **max_players_party** | **i32** | | **region_id** | **String** | | +**state** | Option<[**serde_json::Value**](.md)> | | [optional] **total_player_count** | **i32** | | [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/gen/openapi/internal/rust/src/apis/matchmaker_lobbies_api.rs b/gen/openapi/internal/rust/src/apis/matchmaker_lobbies_api.rs index f4702c54aa..11dae9a4e5 100644 --- a/gen/openapi/internal/rust/src/apis/matchmaker_lobbies_api.rs +++ b/gen/openapi/internal/rust/src/apis/matchmaker_lobbies_api.rs @@ -15,6 +15,19 @@ use crate::apis::ResponseContent; use super::{Error, configuration}; +/// struct for typed errors of method [`matchmaker_lobbies_create`] +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(untagged)] +pub enum MatchmakerLobbiesCreateError { + Status400(crate::models::ErrorBody), + Status403(crate::models::ErrorBody), + Status404(crate::models::ErrorBody), + Status408(crate::models::ErrorBody), + Status429(crate::models::ErrorBody), + Status500(crate::models::ErrorBody), + UnknownValue(serde_json::Value), +} + /// struct for typed errors of method [`matchmaker_lobbies_find`] #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(untagged)] @@ -28,6 +41,19 @@ pub enum MatchmakerLobbiesFindError { UnknownValue(serde_json::Value), } +/// struct for typed errors of method [`matchmaker_lobbies_get_state`] +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(untagged)] +pub enum MatchmakerLobbiesGetStateError { + Status400(crate::models::ErrorBody), + Status403(crate::models::ErrorBody), + Status404(crate::models::ErrorBody), + Status408(crate::models::ErrorBody), + Status429(crate::models::ErrorBody), + Status500(crate::models::ErrorBody), + UnknownValue(serde_json::Value), +} + /// struct for typed errors of method [`matchmaker_lobbies_join`] #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(untagged)] @@ -80,6 +106,51 @@ pub enum MatchmakerLobbiesSetClosedError { UnknownValue(serde_json::Value), } +/// struct for typed errors of method [`matchmaker_lobbies_set_state`] +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(untagged)] +pub enum MatchmakerLobbiesSetStateError { + Status400(crate::models::ErrorBody), + Status403(crate::models::ErrorBody), + Status404(crate::models::ErrorBody), + Status408(crate::models::ErrorBody), + Status429(crate::models::ErrorBody), + Status500(crate::models::ErrorBody), + UnknownValue(serde_json::Value), +} + + +/// Creates a custom lobby. +pub async fn matchmaker_lobbies_create(configuration: &configuration::Configuration, matchmaker_lobbies_create_request: crate::models::MatchmakerLobbiesCreateRequest) -> Result> { + let local_var_configuration = configuration; + + let local_var_client = &local_var_configuration.client; + + let local_var_uri_str = format!("{}/lobbies/create", local_var_configuration.base_path); + let mut local_var_req_builder = local_var_client.request(reqwest::Method::POST, local_var_uri_str.as_str()); + + if let Some(ref local_var_user_agent) = local_var_configuration.user_agent { + local_var_req_builder = local_var_req_builder.header(reqwest::header::USER_AGENT, local_var_user_agent.clone()); + } + if let Some(ref local_var_token) = local_var_configuration.bearer_access_token { + local_var_req_builder = local_var_req_builder.bearer_auth(local_var_token.to_owned()); + }; + local_var_req_builder = local_var_req_builder.json(&matchmaker_lobbies_create_request); + + let local_var_req = local_var_req_builder.build()?; + let local_var_resp = local_var_client.execute(local_var_req).await?; + + let local_var_status = local_var_resp.status(); + let local_var_content = local_var_resp.text().await?; + + if !local_var_status.is_client_error() && !local_var_status.is_server_error() { + serde_json::from_str(&local_var_content).map_err(Error::from) + } else { + let local_var_entity: Option = serde_json::from_str(&local_var_content).ok(); + let local_var_error = ResponseContent { status: local_var_status, content: local_var_content, entity: local_var_entity }; + Err(Error::ResponseError(local_var_error)) + } +} /// Finds a lobby based on the given criteria. If a lobby is not found and `prevent_auto_create_lobby` is `true`, a new lobby will be created. pub async fn matchmaker_lobbies_find(configuration: &configuration::Configuration, matchmaker_lobbies_find_request: crate::models::MatchmakerLobbiesFindRequest, origin: Option<&str>) -> Result> { @@ -116,6 +187,36 @@ pub async fn matchmaker_lobbies_find(configuration: &configuration::Configuratio } } +pub async fn matchmaker_lobbies_get_state(configuration: &configuration::Configuration, lobby_id: &str) -> Result> { + let local_var_configuration = configuration; + + let local_var_client = &local_var_configuration.client; + + let local_var_uri_str = format!("{}/lobbies/{lobby_id}/state", local_var_configuration.base_path, lobby_id=crate::apis::urlencode(lobby_id)); + let mut local_var_req_builder = local_var_client.request(reqwest::Method::GET, local_var_uri_str.as_str()); + + if let Some(ref local_var_user_agent) = local_var_configuration.user_agent { + local_var_req_builder = local_var_req_builder.header(reqwest::header::USER_AGENT, local_var_user_agent.clone()); + } + if let Some(ref local_var_token) = local_var_configuration.bearer_access_token { + local_var_req_builder = local_var_req_builder.bearer_auth(local_var_token.to_owned()); + }; + + let local_var_req = local_var_req_builder.build()?; + let local_var_resp = local_var_client.execute(local_var_req).await?; + + let local_var_status = local_var_resp.status(); + let local_var_content = local_var_resp.text().await?; + + if !local_var_status.is_client_error() && !local_var_status.is_server_error() { + serde_json::from_str(&local_var_content).map_err(Error::from) + } else { + let local_var_entity: Option = serde_json::from_str(&local_var_content).ok(); + let local_var_error = ResponseContent { status: local_var_status, content: local_var_content, entity: local_var_entity }; + Err(Error::ResponseError(local_var_error)) + } +} + /// Joins a specific lobby. This request will use the direct player count configured for the lobby group. pub async fn matchmaker_lobbies_join(configuration: &configuration::Configuration, matchmaker_lobbies_join_request: crate::models::MatchmakerLobbiesJoinRequest) -> Result> { let local_var_configuration = configuration; @@ -149,7 +250,7 @@ pub async fn matchmaker_lobbies_join(configuration: &configuration::Configuratio } /// Lists all open lobbies. -pub async fn matchmaker_lobbies_list(configuration: &configuration::Configuration, ) -> Result> { +pub async fn matchmaker_lobbies_list(configuration: &configuration::Configuration, include_state: Option) -> Result> { let local_var_configuration = configuration; let local_var_client = &local_var_configuration.client; @@ -157,6 +258,9 @@ pub async fn matchmaker_lobbies_list(configuration: &configuration::Configuratio let local_var_uri_str = format!("{}/lobbies/list", local_var_configuration.base_path); let mut local_var_req_builder = local_var_client.request(reqwest::Method::GET, local_var_uri_str.as_str()); + if let Some(ref local_var_str) = include_state { + local_var_req_builder = local_var_req_builder.query(&[("include_state", &local_var_str.to_string())]); + } if let Some(ref local_var_user_agent) = local_var_configuration.user_agent { local_var_req_builder = local_var_req_builder.header(reqwest::header::USER_AGENT, local_var_user_agent.clone()); } @@ -210,7 +314,7 @@ pub async fn matchmaker_lobbies_ready(configuration: &configuration::Configurati } } -/// If `is_closed` is `true`, players will be prevented from joining the lobby. Does not shutdown the lobby. +/// If `is_closed` is `true`, the matchmaker will no longer route players to the lobby. Players can still join using the /join endpoint (this can be disabled by the developer by rejecting all new connections after setting the lobby to closed). Does not shutdown the lobby. pub async fn matchmaker_lobbies_set_closed(configuration: &configuration::Configuration, matchmaker_lobbies_set_closed_request: crate::models::MatchmakerLobbiesSetClosedRequest) -> Result<(), Error> { let local_var_configuration = configuration; @@ -242,3 +346,34 @@ pub async fn matchmaker_lobbies_set_closed(configuration: &configuration::Config } } +pub async fn matchmaker_lobbies_set_state(configuration: &configuration::Configuration, body: Option) -> Result<(), Error> { + let local_var_configuration = configuration; + + let local_var_client = &local_var_configuration.client; + + let local_var_uri_str = format!("{}/lobbies/state", local_var_configuration.base_path); + let mut local_var_req_builder = local_var_client.request(reqwest::Method::PUT, local_var_uri_str.as_str()); + + if let Some(ref local_var_user_agent) = local_var_configuration.user_agent { + local_var_req_builder = local_var_req_builder.header(reqwest::header::USER_AGENT, local_var_user_agent.clone()); + } + if let Some(ref local_var_token) = local_var_configuration.bearer_access_token { + local_var_req_builder = local_var_req_builder.bearer_auth(local_var_token.to_owned()); + }; + local_var_req_builder = local_var_req_builder.json(&body); + + let local_var_req = local_var_req_builder.build()?; + let local_var_resp = local_var_client.execute(local_var_req).await?; + + let local_var_status = local_var_resp.status(); + let local_var_content = local_var_resp.text().await?; + + if !local_var_status.is_client_error() && !local_var_status.is_server_error() { + Ok(()) + } else { + let local_var_entity: Option = serde_json::from_str(&local_var_content).ok(); + let local_var_error = ResponseContent { status: local_var_status, content: local_var_content, entity: local_var_entity }; + Err(Error::ResponseError(local_var_error)) + } +} + diff --git a/gen/openapi/internal/rust/src/models/cloud_games_create_game_build_request.rs b/gen/openapi/internal/rust/src/models/cloud_games_create_game_build_request.rs index 64139e9a8f..f15f843689 100644 --- a/gen/openapi/internal/rust/src/models/cloud_games_create_game_build_request.rs +++ b/gen/openapi/internal/rust/src/models/cloud_games_create_game_build_request.rs @@ -21,6 +21,8 @@ pub struct CloudGamesCreateGameBuildRequest { /// A tag given to the game build. #[serde(rename = "image_tag")] pub image_tag: String, + #[serde(rename = "multipart_upload", skip_serializing_if = "Option::is_none")] + pub multipart_upload: Option, } impl CloudGamesCreateGameBuildRequest { @@ -29,6 +31,7 @@ impl CloudGamesCreateGameBuildRequest { display_name, image_file: Box::new(image_file), image_tag, + multipart_upload: None, } } } diff --git a/gen/openapi/internal/rust/src/models/cloud_games_create_game_build_response.rs b/gen/openapi/internal/rust/src/models/cloud_games_create_game_build_response.rs index 90a2191d66..bf7ed65cca 100644 --- a/gen/openapi/internal/rust/src/models/cloud_games_create_game_build_response.rs +++ b/gen/openapi/internal/rust/src/models/cloud_games_create_game_build_response.rs @@ -15,20 +15,20 @@ pub struct CloudGamesCreateGameBuildResponse { #[serde(rename = "build_id")] pub build_id: uuid::Uuid, - #[serde(rename = "image_presigned_request")] - pub image_presigned_request: Box, - #[serde(rename = "image_presigned_requests")] - pub image_presigned_requests: Vec, + #[serde(rename = "image_presigned_request", skip_serializing_if = "Option::is_none")] + pub image_presigned_request: Option>, + #[serde(rename = "image_presigned_requests", skip_serializing_if = "Option::is_none")] + pub image_presigned_requests: Option>, #[serde(rename = "upload_id")] pub upload_id: uuid::Uuid, } impl CloudGamesCreateGameBuildResponse { - pub fn new(build_id: uuid::Uuid, image_presigned_request: crate::models::UploadPresignedRequest, image_presigned_requests: Vec, upload_id: uuid::Uuid) -> CloudGamesCreateGameBuildResponse { + pub fn new(build_id: uuid::Uuid, upload_id: uuid::Uuid) -> CloudGamesCreateGameBuildResponse { CloudGamesCreateGameBuildResponse { build_id, - image_presigned_request: Box::new(image_presigned_request), - image_presigned_requests, + image_presigned_request: None, + image_presigned_requests: None, upload_id, } } diff --git a/gen/openapi/internal/rust/src/models/cloud_version_matchmaker_game_mode.rs b/gen/openapi/internal/rust/src/models/cloud_version_matchmaker_game_mode.rs index c9a8dc599f..cc55a3dd60 100644 --- a/gen/openapi/internal/rust/src/models/cloud_version_matchmaker_game_mode.rs +++ b/gen/openapi/internal/rust/src/models/cloud_version_matchmaker_game_mode.rs @@ -14,10 +14,18 @@ #[derive(Clone, Debug, PartialEq, Default, Serialize, Deserialize)] pub struct CloudVersionMatchmakerGameMode { + #[serde(rename = "create_config", skip_serializing_if = "Option::is_none")] + pub create_config: Option>, #[serde(rename = "docker", skip_serializing_if = "Option::is_none")] pub docker: Option>, + #[serde(rename = "find_config", skip_serializing_if = "Option::is_none")] + pub find_config: Option>, #[serde(rename = "idle_lobbies", skip_serializing_if = "Option::is_none")] pub idle_lobbies: Option>, + #[serde(rename = "join_config", skip_serializing_if = "Option::is_none")] + pub join_config: Option>, + #[serde(rename = "listable", skip_serializing_if = "Option::is_none")] + pub listable: Option, #[serde(rename = "max_players", skip_serializing_if = "Option::is_none")] pub max_players: Option, #[serde(rename = "max_players_direct", skip_serializing_if = "Option::is_none")] @@ -34,8 +42,12 @@ impl CloudVersionMatchmakerGameMode { /// A game mode. pub fn new() -> CloudVersionMatchmakerGameMode { CloudVersionMatchmakerGameMode { + create_config: None, docker: None, + find_config: None, idle_lobbies: None, + join_config: None, + listable: None, max_players: None, max_players_direct: None, max_players_party: None, diff --git a/gen/openapi/internal/rust/src/models/cloud_version_matchmaker_game_mode_create_config.rs b/gen/openapi/internal/rust/src/models/cloud_version_matchmaker_game_mode_create_config.rs new file mode 100644 index 0000000000..638492cb81 --- /dev/null +++ b/gen/openapi/internal/rust/src/models/cloud_version_matchmaker_game_mode_create_config.rs @@ -0,0 +1,42 @@ +/* + * Rivet API + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 0.0.1 + * + * Generated by: https://openapi-generator.tech + */ + +/// CloudVersionMatchmakerGameModeCreateConfig : Configures the requirements and authentication for the /create endpoint. If this value is not set in the config, the /create endpoint is NOT enabled. + + + +#[derive(Clone, Debug, PartialEq, Default, Serialize, Deserialize)] +pub struct CloudVersionMatchmakerGameModeCreateConfig { + #[serde(rename = "enable_private")] + pub enable_private: bool, + #[serde(rename = "enable_public")] + pub enable_public: bool, + #[serde(rename = "identity_requirement")] + pub identity_requirement: crate::models::CloudVersionMatchmakerGameModeIdentityRequirement, + #[serde(rename = "max_lobbies_per_identity", skip_serializing_if = "Option::is_none")] + pub max_lobbies_per_identity: Option, + #[serde(rename = "verification_config", skip_serializing_if = "Option::is_none")] + pub verification_config: Option>, +} + +impl CloudVersionMatchmakerGameModeCreateConfig { + /// Configures the requirements and authentication for the /create endpoint. If this value is not set in the config, the /create endpoint is NOT enabled. + pub fn new(enable_private: bool, enable_public: bool, identity_requirement: crate::models::CloudVersionMatchmakerGameModeIdentityRequirement) -> CloudVersionMatchmakerGameModeCreateConfig { + CloudVersionMatchmakerGameModeCreateConfig { + enable_private, + enable_public, + identity_requirement, + max_lobbies_per_identity: None, + verification_config: None, + } + } +} + + diff --git a/gen/openapi/internal/rust/src/models/cloud_version_matchmaker_game_mode_find_config.rs b/gen/openapi/internal/rust/src/models/cloud_version_matchmaker_game_mode_find_config.rs new file mode 100644 index 0000000000..697d176954 --- /dev/null +++ b/gen/openapi/internal/rust/src/models/cloud_version_matchmaker_game_mode_find_config.rs @@ -0,0 +1,37 @@ +/* + * Rivet API + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 0.0.1 + * + * Generated by: https://openapi-generator.tech + */ + +/// CloudVersionMatchmakerGameModeFindConfig : Configures the requirements and authentication for the /find endpoint. If this value is not set in the config, the /find endpoint is still enabled. + + + +#[derive(Clone, Debug, PartialEq, Default, Serialize, Deserialize)] +pub struct CloudVersionMatchmakerGameModeFindConfig { + /// Sets whether or not the /find endpoint is enabled. + #[serde(rename = "enabled")] + pub enabled: bool, + #[serde(rename = "identity_requirement")] + pub identity_requirement: crate::models::CloudVersionMatchmakerGameModeIdentityRequirement, + #[serde(rename = "verification_config", skip_serializing_if = "Option::is_none")] + pub verification_config: Option>, +} + +impl CloudVersionMatchmakerGameModeFindConfig { + /// Configures the requirements and authentication for the /find endpoint. If this value is not set in the config, the /find endpoint is still enabled. + pub fn new(enabled: bool, identity_requirement: crate::models::CloudVersionMatchmakerGameModeIdentityRequirement) -> CloudVersionMatchmakerGameModeFindConfig { + CloudVersionMatchmakerGameModeFindConfig { + enabled, + identity_requirement, + verification_config: None, + } + } +} + + diff --git a/gen/openapi/internal/rust/src/models/cloud_version_matchmaker_game_mode_identity_requirement.rs b/gen/openapi/internal/rust/src/models/cloud_version_matchmaker_game_mode_identity_requirement.rs new file mode 100644 index 0000000000..b7b86f843b --- /dev/null +++ b/gen/openapi/internal/rust/src/models/cloud_version_matchmaker_game_mode_identity_requirement.rs @@ -0,0 +1,43 @@ +/* + * Rivet API + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 0.0.1 + * + * Generated by: https://openapi-generator.tech + */ + +/// CloudVersionMatchmakerGameModeIdentityRequirement : The registration requirement for a user when joining/finding/creating a lobby. \"None\" allows for connections without an identity. + +/// The registration requirement for a user when joining/finding/creating a lobby. \"None\" allows for connections without an identity. +#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)] +pub enum CloudVersionMatchmakerGameModeIdentityRequirement { + #[serde(rename = "none")] + None, + #[serde(rename = "guest")] + Guest, + #[serde(rename = "registered")] + Registered, + +} + +impl ToString for CloudVersionMatchmakerGameModeIdentityRequirement { + fn to_string(&self) -> String { + match self { + Self::None => String::from("none"), + Self::Guest => String::from("guest"), + Self::Registered => String::from("registered"), + } + } +} + +impl Default for CloudVersionMatchmakerGameModeIdentityRequirement { + fn default() -> CloudVersionMatchmakerGameModeIdentityRequirement { + Self::None + } +} + + + + diff --git a/gen/openapi/internal/rust/src/models/cloud_version_matchmaker_game_mode_join_config.rs b/gen/openapi/internal/rust/src/models/cloud_version_matchmaker_game_mode_join_config.rs new file mode 100644 index 0000000000..afd3b65d8e --- /dev/null +++ b/gen/openapi/internal/rust/src/models/cloud_version_matchmaker_game_mode_join_config.rs @@ -0,0 +1,37 @@ +/* + * Rivet API + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 0.0.1 + * + * Generated by: https://openapi-generator.tech + */ + +/// CloudVersionMatchmakerGameModeJoinConfig : Configures the requirements and authentication for the /join endpoint. If this value is not set in the config, the /join endpoint is still enabled. + + + +#[derive(Clone, Debug, PartialEq, Default, Serialize, Deserialize)] +pub struct CloudVersionMatchmakerGameModeJoinConfig { + /// Sets whether or not the /join endpoint is enabled. + #[serde(rename = "enabled")] + pub enabled: bool, + #[serde(rename = "identity_requirement")] + pub identity_requirement: crate::models::CloudVersionMatchmakerGameModeIdentityRequirement, + #[serde(rename = "verification_config", skip_serializing_if = "Option::is_none")] + pub verification_config: Option>, +} + +impl CloudVersionMatchmakerGameModeJoinConfig { + /// Configures the requirements and authentication for the /join endpoint. If this value is not set in the config, the /join endpoint is still enabled. + pub fn new(enabled: bool, identity_requirement: crate::models::CloudVersionMatchmakerGameModeIdentityRequirement) -> CloudVersionMatchmakerGameModeJoinConfig { + CloudVersionMatchmakerGameModeJoinConfig { + enabled, + identity_requirement, + verification_config: None, + } + } +} + + diff --git a/gen/openapi/internal/rust/src/models/cloud_version_matchmaker_game_mode_verification_config.rs b/gen/openapi/internal/rust/src/models/cloud_version_matchmaker_game_mode_verification_config.rs new file mode 100644 index 0000000000..306ca5d409 --- /dev/null +++ b/gen/openapi/internal/rust/src/models/cloud_version_matchmaker_game_mode_verification_config.rs @@ -0,0 +1,33 @@ +/* + * Rivet API + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 0.0.1 + * + * Generated by: https://openapi-generator.tech + */ + +/// CloudVersionMatchmakerGameModeVerificationConfig : Configuration that tells Rivet where to send validation requests and with what headers. When set, Rivet will send the `verification_data` property (given by the user in the find/join/create endpoint) to the given url along with the headers provided and some information about the requested lobby. The response of this request will determine if the user can join that lobby or not. + + + +#[derive(Clone, Debug, PartialEq, Default, Serialize, Deserialize)] +pub struct CloudVersionMatchmakerGameModeVerificationConfig { + #[serde(rename = "headers")] + pub headers: ::std::collections::HashMap, + #[serde(rename = "url")] + pub url: String, +} + +impl CloudVersionMatchmakerGameModeVerificationConfig { + /// Configuration that tells Rivet where to send validation requests and with what headers. When set, Rivet will send the `verification_data` property (given by the user in the find/join/create endpoint) to the given url along with the headers provided and some information about the requested lobby. The response of this request will determine if the user can join that lobby or not. + pub fn new(headers: ::std::collections::HashMap, url: String) -> CloudVersionMatchmakerGameModeVerificationConfig { + CloudVersionMatchmakerGameModeVerificationConfig { + headers, + url, + } + } +} + + diff --git a/gen/openapi/internal/rust/src/models/matchmaker_create_lobby_response.rs b/gen/openapi/internal/rust/src/models/matchmaker_create_lobby_response.rs new file mode 100644 index 0000000000..0d1bcc029a --- /dev/null +++ b/gen/openapi/internal/rust/src/models/matchmaker_create_lobby_response.rs @@ -0,0 +1,34 @@ +/* + * Rivet API + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 0.0.1 + * + * Generated by: https://openapi-generator.tech + */ + + + + +#[derive(Clone, Debug, PartialEq, Default, Serialize, Deserialize)] +pub struct MatchmakerCreateLobbyResponse { + #[serde(rename = "lobby")] + pub lobby: Box, + #[serde(rename = "player")] + pub player: Box, + #[serde(rename = "ports")] + pub ports: ::std::collections::HashMap, +} + +impl MatchmakerCreateLobbyResponse { + pub fn new(lobby: crate::models::MatchmakerJoinLobby, player: crate::models::MatchmakerJoinPlayer, ports: ::std::collections::HashMap) -> MatchmakerCreateLobbyResponse { + MatchmakerCreateLobbyResponse { + lobby: Box::new(lobby), + player: Box::new(player), + ports, + } + } +} + + diff --git a/gen/openapi/internal/rust/src/models/matchmaker_custom_lobby_publicity.rs b/gen/openapi/internal/rust/src/models/matchmaker_custom_lobby_publicity.rs new file mode 100644 index 0000000000..e3dcead796 --- /dev/null +++ b/gen/openapi/internal/rust/src/models/matchmaker_custom_lobby_publicity.rs @@ -0,0 +1,39 @@ +/* + * Rivet API + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 0.0.1 + * + * Generated by: https://openapi-generator.tech + */ + + +/// +#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)] +pub enum MatchmakerCustomLobbyPublicity { + #[serde(rename = "public")] + Public, + #[serde(rename = "private")] + Private, + +} + +impl ToString for MatchmakerCustomLobbyPublicity { + fn to_string(&self) -> String { + match self { + Self::Public => String::from("public"), + Self::Private => String::from("private"), + } + } +} + +impl Default for MatchmakerCustomLobbyPublicity { + fn default() -> MatchmakerCustomLobbyPublicity { + Self::Public + } +} + + + + diff --git a/gen/openapi/internal/rust/src/models/matchmaker_lobbies_create_request.rs b/gen/openapi/internal/rust/src/models/matchmaker_lobbies_create_request.rs new file mode 100644 index 0000000000..85b37c69f2 --- /dev/null +++ b/gen/openapi/internal/rust/src/models/matchmaker_lobbies_create_request.rs @@ -0,0 +1,43 @@ +/* + * Rivet API + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 0.0.1 + * + * Generated by: https://openapi-generator.tech + */ + + + + +#[derive(Clone, Debug, PartialEq, Default, Serialize, Deserialize)] +pub struct MatchmakerLobbiesCreateRequest { + #[serde(rename = "captcha", skip_serializing_if = "Option::is_none")] + pub captcha: Option>, + #[serde(rename = "game_mode")] + pub game_mode: String, + #[serde(rename = "lobby_config", default, with = "::serde_with::rust::double_option", skip_serializing_if = "Option::is_none")] + pub lobby_config: Option>, + #[serde(rename = "publicity")] + pub publicity: crate::models::MatchmakerCustomLobbyPublicity, + #[serde(rename = "region", skip_serializing_if = "Option::is_none")] + pub region: Option, + #[serde(rename = "verification_data", default, with = "::serde_with::rust::double_option", skip_serializing_if = "Option::is_none")] + pub verification_data: Option>, +} + +impl MatchmakerLobbiesCreateRequest { + pub fn new(game_mode: String, publicity: crate::models::MatchmakerCustomLobbyPublicity) -> MatchmakerLobbiesCreateRequest { + MatchmakerLobbiesCreateRequest { + captcha: None, + game_mode, + lobby_config: None, + publicity, + region: None, + verification_data: None, + } + } +} + + diff --git a/gen/openapi/internal/rust/src/models/matchmaker_lobbies_find_request.rs b/gen/openapi/internal/rust/src/models/matchmaker_lobbies_find_request.rs index a218d9dba6..9244d5373c 100644 --- a/gen/openapi/internal/rust/src/models/matchmaker_lobbies_find_request.rs +++ b/gen/openapi/internal/rust/src/models/matchmaker_lobbies_find_request.rs @@ -21,6 +21,8 @@ pub struct MatchmakerLobbiesFindRequest { pub prevent_auto_create_lobby: Option, #[serde(rename = "regions", skip_serializing_if = "Option::is_none")] pub regions: Option>, + #[serde(rename = "verification_data", default, with = "::serde_with::rust::double_option", skip_serializing_if = "Option::is_none")] + pub verification_data: Option>, } impl MatchmakerLobbiesFindRequest { @@ -30,6 +32,7 @@ impl MatchmakerLobbiesFindRequest { game_modes, prevent_auto_create_lobby: None, regions: None, + verification_data: None, } } } diff --git a/gen/openapi/internal/rust/src/models/matchmaker_lobbies_join_request.rs b/gen/openapi/internal/rust/src/models/matchmaker_lobbies_join_request.rs index 9b9683c869..6f622e00a1 100644 --- a/gen/openapi/internal/rust/src/models/matchmaker_lobbies_join_request.rs +++ b/gen/openapi/internal/rust/src/models/matchmaker_lobbies_join_request.rs @@ -17,6 +17,8 @@ pub struct MatchmakerLobbiesJoinRequest { pub captcha: Option>, #[serde(rename = "lobby_id")] pub lobby_id: String, + #[serde(rename = "verification_data", default, with = "::serde_with::rust::double_option", skip_serializing_if = "Option::is_none")] + pub verification_data: Option>, } impl MatchmakerLobbiesJoinRequest { @@ -24,6 +26,7 @@ impl MatchmakerLobbiesJoinRequest { MatchmakerLobbiesJoinRequest { captcha: None, lobby_id, + verification_data: None, } } } diff --git a/gen/openapi/internal/rust/src/models/matchmaker_lobby_info.rs b/gen/openapi/internal/rust/src/models/matchmaker_lobby_info.rs index 552c0a9b1f..bdae0cba81 100644 --- a/gen/openapi/internal/rust/src/models/matchmaker_lobby_info.rs +++ b/gen/openapi/internal/rust/src/models/matchmaker_lobby_info.rs @@ -26,6 +26,8 @@ pub struct MatchmakerLobbyInfo { pub max_players_party: i32, #[serde(rename = "region_id")] pub region_id: String, + #[serde(rename = "state", default, with = "::serde_with::rust::double_option", skip_serializing_if = "Option::is_none")] + pub state: Option>, #[serde(rename = "total_player_count")] pub total_player_count: i32, } @@ -40,6 +42,7 @@ impl MatchmakerLobbyInfo { max_players_normal, max_players_party, region_id, + state: None, total_player_count, } } diff --git a/gen/openapi/internal/rust/src/models/mod.rs b/gen/openapi/internal/rust/src/models/mod.rs index c0cdeff2e5..99cae4fb9b 100644 --- a/gen/openapi/internal/rust/src/models/mod.rs +++ b/gen/openapi/internal/rust/src/models/mod.rs @@ -318,14 +318,24 @@ pub mod cloud_version_matchmaker_config; pub use self::cloud_version_matchmaker_config::CloudVersionMatchmakerConfig; pub mod cloud_version_matchmaker_game_mode; pub use self::cloud_version_matchmaker_game_mode::CloudVersionMatchmakerGameMode; +pub mod cloud_version_matchmaker_game_mode_create_config; +pub use self::cloud_version_matchmaker_game_mode_create_config::CloudVersionMatchmakerGameModeCreateConfig; +pub mod cloud_version_matchmaker_game_mode_find_config; +pub use self::cloud_version_matchmaker_game_mode_find_config::CloudVersionMatchmakerGameModeFindConfig; +pub mod cloud_version_matchmaker_game_mode_identity_requirement; +pub use self::cloud_version_matchmaker_game_mode_identity_requirement::CloudVersionMatchmakerGameModeIdentityRequirement; pub mod cloud_version_matchmaker_game_mode_idle_lobbies_config; pub use self::cloud_version_matchmaker_game_mode_idle_lobbies_config::CloudVersionMatchmakerGameModeIdleLobbiesConfig; +pub mod cloud_version_matchmaker_game_mode_join_config; +pub use self::cloud_version_matchmaker_game_mode_join_config::CloudVersionMatchmakerGameModeJoinConfig; pub mod cloud_version_matchmaker_game_mode_region; pub use self::cloud_version_matchmaker_game_mode_region::CloudVersionMatchmakerGameModeRegion; pub mod cloud_version_matchmaker_game_mode_runtime_docker; pub use self::cloud_version_matchmaker_game_mode_runtime_docker::CloudVersionMatchmakerGameModeRuntimeDocker; pub mod cloud_version_matchmaker_game_mode_runtime_docker_port; pub use self::cloud_version_matchmaker_game_mode_runtime_docker_port::CloudVersionMatchmakerGameModeRuntimeDockerPort; +pub mod cloud_version_matchmaker_game_mode_verification_config; +pub use self::cloud_version_matchmaker_game_mode_verification_config::CloudVersionMatchmakerGameModeVerificationConfig; pub mod cloud_version_matchmaker_lobby_group; pub use self::cloud_version_matchmaker_lobby_group::CloudVersionMatchmakerLobbyGroup; pub mod cloud_version_matchmaker_lobby_group_idle_lobbies_config; @@ -546,6 +556,10 @@ pub mod kv_put_entry; pub use self::kv_put_entry::KvPutEntry; pub mod kv_put_request; pub use self::kv_put_request::KvPutRequest; +pub mod matchmaker_create_lobby_response; +pub use self::matchmaker_create_lobby_response::MatchmakerCreateLobbyResponse; +pub mod matchmaker_custom_lobby_publicity; +pub use self::matchmaker_custom_lobby_publicity::MatchmakerCustomLobbyPublicity; pub mod matchmaker_find_lobby_response; pub use self::matchmaker_find_lobby_response::MatchmakerFindLobbyResponse; pub mod matchmaker_game_mode_info; @@ -570,6 +584,8 @@ pub mod matchmaker_list_lobbies_response; pub use self::matchmaker_list_lobbies_response::MatchmakerListLobbiesResponse; pub mod matchmaker_list_regions_response; pub use self::matchmaker_list_regions_response::MatchmakerListRegionsResponse; +pub mod matchmaker_lobbies_create_request; +pub use self::matchmaker_lobbies_create_request::MatchmakerLobbiesCreateRequest; pub mod matchmaker_lobbies_find_request; pub use self::matchmaker_lobbies_find_request::MatchmakerLobbiesFindRequest; pub mod matchmaker_lobbies_join_request; diff --git a/gen/openapi/internal/spec/openapi.yml b/gen/openapi/internal/spec/openapi.yml index 29beeb0a78..5bdf927da7 100644 --- a/gen/openapi/internal/spec/openapi.yml +++ b/gen/openapi/internal/spec/openapi.yml @@ -7927,8 +7927,13 @@ paths: /lobbies/closed: put: description: > - If `is_closed` is `true`, players will be prevented from joining the - lobby. + If `is_closed` is `true`, the matchmaker will no longer route players to + the lobby. Players can still + + join using the /join endpoint (this can be disabled by the developer by + rejecting all new connections + + after setting the lobby to closed). Does not shutdown the lobby. operationId: matchmaker_lobbies_setClosed @@ -7988,6 +7993,116 @@ paths: type: boolean required: - is_closed + /lobbies/state: + put: + operationId: matchmaker_lobbies_setState + tags: + - MatchmakerLobbies + parameters: [] + responses: + '204': + description: '' + '400': + description: '' + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBody' + '403': + description: '' + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBody' + '404': + description: '' + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBody' + '408': + description: '' + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBody' + '429': + description: '' + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBody' + '500': + description: '' + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBody' + servers: + - url: https://matchmaker.api.rivet.gg/v1 + security: *ref_0 + requestBody: + required: false + content: + application/json: + schema: {} + /lobbies/{lobby_id}/state: + get: + operationId: matchmaker_lobbies_getState + tags: + - MatchmakerLobbies + parameters: + - name: lobby_id + in: path + required: true + schema: + type: string + format: uuid + responses: + '200': + description: '' + content: + application/json: + schema: {} + '400': + description: '' + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBody' + '403': + description: '' + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBody' + '404': + description: '' + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBody' + '408': + description: '' + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBody' + '429': + description: '' + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBody' + '500': + description: '' + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBody' + servers: + - url: https://matchmaker.api.rivet.gg/v1 + security: *ref_0 /lobbies/find: post: description: | @@ -8068,6 +8183,7 @@ paths: type: boolean captcha: $ref: '#/components/schemas/CaptchaConfig' + verification_data: {} required: - game_modes /lobbies/join: @@ -8137,15 +8253,95 @@ paths: type: string captcha: $ref: '#/components/schemas/CaptchaConfig' + verification_data: {} required: - lobby_id + /lobbies/create: + post: + description: | + Creates a custom lobby. + operationId: matchmaker_lobbies_create + tags: + - MatchmakerLobbies + parameters: [] + responses: + '200': + description: '' + content: + application/json: + schema: + $ref: '#/components/schemas/MatchmakerCreateLobbyResponse' + '400': + description: '' + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBody' + '403': + description: '' + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBody' + '404': + description: '' + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBody' + '408': + description: '' + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBody' + '429': + description: '' + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBody' + '500': + description: '' + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBody' + servers: + - url: https://matchmaker.api.rivet.gg/v1 + security: *ref_0 + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + game_mode: + type: string + region: + type: string + captcha: + $ref: '#/components/schemas/CaptchaConfig' + publicity: + $ref: '#/components/schemas/MatchmakerCustomLobbyPublicity' + lobby_config: {} + verification_data: {} + required: + - game_mode + - publicity /lobbies/list: get: description: Lists all open lobbies. operationId: matchmaker_lobbies_list tags: - MatchmakerLobbies - parameters: [] + parameters: + - name: include_state + in: query + required: false + schema: + type: boolean responses: '200': description: '' @@ -10927,6 +11123,8 @@ components: description: A tag given to the game build. image_file: $ref: '#/components/schemas/UploadPrepareFile' + multipart_upload: + type: boolean required: - display_name - image_tag @@ -10942,7 +11140,6 @@ components: format: uuid image_presigned_request: $ref: '#/components/schemas/UploadPresignedRequest' - description: '**Deprecated: use image_presigned_requests instead**' image_presigned_requests: type: array items: @@ -10950,8 +11147,6 @@ components: required: - build_id - upload_id - - image_presigned_request - - image_presigned_requests CloudGamesListGameCdnSitesResponse: type: object properties: @@ -11549,6 +11744,14 @@ components: type: integer docker: $ref: '#/components/schemas/CloudVersionMatchmakerGameModeRuntimeDocker' + listable: + type: boolean + find_config: + $ref: '#/components/schemas/CloudVersionMatchmakerGameModeFindConfig' + join_config: + $ref: '#/components/schemas/CloudVersionMatchmakerGameModeJoinConfig' + create_config: + $ref: '#/components/schemas/CloudVersionMatchmakerGameModeCreateConfig' tier: type: string idle_lobbies: @@ -11623,6 +11826,95 @@ components: required: - min - max + CloudVersionMatchmakerGameModeIdentityRequirement: + type: string + enum: + - none + - guest + - registered + description: >- + The registration requirement for a user when joining/finding/creating a + lobby. "None" allows for connections without an identity. + CloudVersionMatchmakerGameModeVerificationConfig: + type: object + description: >- + Configuration that tells Rivet where to send validation requests and + with what headers. When set, Rivet will send the `verification_data` + property (given by the user in the find/join/create endpoint) to the + given url along with the headers provided and some information about the + requested lobby. The response of this request will determine if the user + can join that lobby or not. + properties: + url: + type: string + headers: + type: object + additionalProperties: + type: string + required: + - url + - headers + CloudVersionMatchmakerGameModeFindConfig: + type: object + description: >- + Configures the requirements and authentication for the /find endpoint. + If this value is not set in the config, the /find endpoint is still + enabled. + properties: + enabled: + type: boolean + description: Sets whether or not the /find endpoint is enabled. + identity_requirement: + $ref: >- + #/components/schemas/CloudVersionMatchmakerGameModeIdentityRequirement + verification_config: + $ref: >- + #/components/schemas/CloudVersionMatchmakerGameModeVerificationConfig + required: + - enabled + - identity_requirement + CloudVersionMatchmakerGameModeJoinConfig: + type: object + description: >- + Configures the requirements and authentication for the /join endpoint. + If this value is not set in the config, the /join endpoint is still + enabled. + properties: + enabled: + type: boolean + description: Sets whether or not the /join endpoint is enabled. + identity_requirement: + $ref: >- + #/components/schemas/CloudVersionMatchmakerGameModeIdentityRequirement + verification_config: + $ref: >- + #/components/schemas/CloudVersionMatchmakerGameModeVerificationConfig + required: + - enabled + - identity_requirement + CloudVersionMatchmakerGameModeCreateConfig: + type: object + description: >- + Configures the requirements and authentication for the /create endpoint. + If this value is not set in the config, the /create endpoint is NOT + enabled. + properties: + identity_requirement: + $ref: >- + #/components/schemas/CloudVersionMatchmakerGameModeIdentityRequirement + verification_config: + $ref: >- + #/components/schemas/CloudVersionMatchmakerGameModeVerificationConfig + enable_public: + type: boolean + enable_private: + type: boolean + max_lobbies_per_identity: + type: integer + required: + - identity_requirement + - enable_public + - enable_private CloudVersionMatchmakerLobbyGroup: type: object description: A game mode. @@ -12898,6 +13190,7 @@ components: type: integer total_player_count: type: integer + state: {} required: - region_id - game_mode_id @@ -13014,6 +13307,11 @@ components: server will validate this token with `PlayerConnected.player_token` required: - token + MatchmakerCustomLobbyPublicity: + type: string + enum: + - public + - private MatchmakerFindLobbyResponse: type: object properties: @@ -13044,6 +13342,21 @@ components: - lobby - ports - player + MatchmakerCreateLobbyResponse: + type: object + properties: + lobby: + $ref: '#/components/schemas/MatchmakerJoinLobby' + ports: + type: object + additionalProperties: + $ref: '#/components/schemas/MatchmakerJoinPort' + player: + $ref: '#/components/schemas/MatchmakerJoinPlayer' + required: + - lobby + - ports + - player MatchmakerListLobbiesResponse: type: object properties: diff --git a/gen/openapi/internal/spec_compat/openapi.yml b/gen/openapi/internal/spec_compat/openapi.yml index 9684cdaffa..ac638a2ee5 100644 --- a/gen/openapi/internal/spec_compat/openapi.yml +++ b/gen/openapi/internal/spec_compat/openapi.yml @@ -756,6 +756,8 @@ components: image_tag: description: A tag given to the game build. type: string + multipart_upload: + type: boolean required: - display_name - image_tag @@ -768,7 +770,6 @@ components: type: string image_presigned_request: $ref: '#/components/schemas/UploadPresignedRequest' - description: '**Deprecated: use image_presigned_requests instead**' image_presigned_requests: items: $ref: '#/components/schemas/UploadPresignedRequest' @@ -779,8 +780,6 @@ components: required: - build_id - upload_id - - image_presigned_request - - image_presigned_requests type: object CloudGamesCreateGameCdnSiteRequest: properties: @@ -2357,10 +2356,18 @@ components: CloudVersionMatchmakerGameMode: description: A game mode. properties: + create_config: + $ref: '#/components/schemas/CloudVersionMatchmakerGameModeCreateConfig' docker: $ref: '#/components/schemas/CloudVersionMatchmakerGameModeRuntimeDocker' + find_config: + $ref: '#/components/schemas/CloudVersionMatchmakerGameModeFindConfig' idle_lobbies: $ref: '#/components/schemas/CloudVersionMatchmakerGameModeIdleLobbiesConfig' + join_config: + $ref: '#/components/schemas/CloudVersionMatchmakerGameModeJoinConfig' + listable: + type: boolean max_players: type: integer max_players_direct: @@ -2374,6 +2381,49 @@ components: tier: type: string type: object + CloudVersionMatchmakerGameModeCreateConfig: + description: Configures the requirements and authentication for the /create + endpoint. If this value is not set in the config, the /create endpoint is + NOT enabled. + properties: + enable_private: + type: boolean + enable_public: + type: boolean + identity_requirement: + $ref: '#/components/schemas/CloudVersionMatchmakerGameModeIdentityRequirement' + max_lobbies_per_identity: + type: integer + verification_config: + $ref: '#/components/schemas/CloudVersionMatchmakerGameModeVerificationConfig' + required: + - identity_requirement + - enable_public + - enable_private + type: object + CloudVersionMatchmakerGameModeFindConfig: + description: Configures the requirements and authentication for the /find endpoint. + If this value is not set in the config, the /find endpoint is still enabled. + properties: + enabled: + description: Sets whether or not the /find endpoint is enabled. + type: boolean + identity_requirement: + $ref: '#/components/schemas/CloudVersionMatchmakerGameModeIdentityRequirement' + verification_config: + $ref: '#/components/schemas/CloudVersionMatchmakerGameModeVerificationConfig' + required: + - enabled + - identity_requirement + type: object + CloudVersionMatchmakerGameModeIdentityRequirement: + description: The registration requirement for a user when joining/finding/creating + a lobby. "None" allows for connections without an identity. + enum: + - none + - guest + - registered + type: string CloudVersionMatchmakerGameModeIdleLobbiesConfig: description: Configuration for how many idle lobbies a game version should have. properties: @@ -2385,6 +2435,21 @@ components: - min - max type: object + CloudVersionMatchmakerGameModeJoinConfig: + description: Configures the requirements and authentication for the /join endpoint. + If this value is not set in the config, the /join endpoint is still enabled. + properties: + enabled: + description: Sets whether or not the /join endpoint is enabled. + type: boolean + identity_requirement: + $ref: '#/components/schemas/CloudVersionMatchmakerGameModeIdentityRequirement' + verification_config: + $ref: '#/components/schemas/CloudVersionMatchmakerGameModeVerificationConfig' + required: + - enabled + - identity_requirement + type: object CloudVersionMatchmakerGameModeRegion: description: A game mode region. properties: @@ -2443,6 +2508,24 @@ components: $ref: '#/components/schemas/CloudVersionMatchmakerProxyKind' description: How this port should be proxied. Defaults to 'game-guard`. type: object + CloudVersionMatchmakerGameModeVerificationConfig: + description: Configuration that tells Rivet where to send validation requests + and with what headers. When set, Rivet will send the `verification_data` property + (given by the user in the find/join/create endpoint) to the given url along + with the headers provided and some information about the requested lobby. + The response of this request will determine if the user can join that lobby + or not. + properties: + headers: + additionalProperties: + type: string + type: object + url: + type: string + required: + - url + - headers + type: object CloudVersionMatchmakerLobbyGroup: description: A game mode. properties: @@ -4078,6 +4161,26 @@ components: A `null` value indicates the entry is deleted. Maximum length of 262,144 bytes when encoded.' + MatchmakerCreateLobbyResponse: + properties: + lobby: + $ref: '#/components/schemas/MatchmakerJoinLobby' + player: + $ref: '#/components/schemas/MatchmakerJoinPlayer' + ports: + additionalProperties: + $ref: '#/components/schemas/MatchmakerJoinPort' + type: object + required: + - lobby + - ports + - player + type: object + MatchmakerCustomLobbyPublicity: + enum: + - public + - private + type: string MatchmakerFindLobbyResponse: properties: lobby: @@ -4272,6 +4375,7 @@ components: type: integer region_id: type: string + state: {} total_player_count: type: integer required: @@ -11573,8 +11677,13 @@ paths: - GroupInvites /lobbies/closed: put: - description: 'If `is_closed` is `true`, players will be prevented from joining - the lobby. + description: 'If `is_closed` is `true`, the matchmaker will no longer route + players to the lobby. Players can still + + join using the /join endpoint (this can be disabled by the developer by rejecting + all new connections + + after setting the lobby to closed). Does not shutdown the lobby. @@ -11636,6 +11745,81 @@ paths: - url: https://matchmaker.api.rivet.gg/v1 tags: - MatchmakerLobbies + /lobbies/create: + post: + description: 'Creates a custom lobby. + + ' + operationId: matchmaker_lobbies_create + parameters: [] + requestBody: + content: + application/json: + schema: + properties: + captcha: + $ref: '#/components/schemas/CaptchaConfig' + game_mode: + type: string + lobby_config: {} + publicity: + $ref: '#/components/schemas/MatchmakerCustomLobbyPublicity' + region: + type: string + verification_data: {} + required: + - game_mode + - publicity + type: object + required: true + responses: + '200': + content: + application/json: + schema: + $ref: '#/components/schemas/MatchmakerCreateLobbyResponse' + description: '' + '400': + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBody' + description: '' + '403': + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBody' + description: '' + '404': + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBody' + description: '' + '408': + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBody' + description: '' + '429': + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBody' + description: '' + '500': + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBody' + description: '' + security: *id001 + servers: + - url: https://matchmaker.api.rivet.gg/v1 + tags: + - MatchmakerLobbies /lobbies/find: post: description: "Finds a lobby based on the given criteria.\nIf a lobby is not\ @@ -11664,6 +11848,7 @@ paths: items: type: string type: array + verification_data: {} required: - game_modes type: object @@ -11736,6 +11921,7 @@ paths: $ref: '#/components/schemas/CaptchaConfig' lobby_id: type: string + verification_data: {} required: - lobby_id type: object @@ -11792,7 +11978,12 @@ paths: get: description: Lists all open lobbies. operationId: matchmaker_lobbies_list - parameters: [] + parameters: + - in: query + name: include_state + required: false + schema: + type: boolean responses: '200': content: @@ -11891,6 +12082,116 @@ paths: - url: https://matchmaker.api.rivet.gg/v1 tags: - MatchmakerLobbies + /lobbies/state: + put: + operationId: matchmaker_lobbies_setState + parameters: [] + requestBody: + content: + application/json: + schema: {} + required: false + responses: + '204': + description: '' + '400': + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBody' + description: '' + '403': + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBody' + description: '' + '404': + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBody' + description: '' + '408': + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBody' + description: '' + '429': + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBody' + description: '' + '500': + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBody' + description: '' + security: *id001 + servers: + - url: https://matchmaker.api.rivet.gg/v1 + tags: + - MatchmakerLobbies + /lobbies/{lobby_id}/state: + get: + operationId: matchmaker_lobbies_getState + parameters: + - in: path + name: lobby_id + required: true + schema: + format: uuid + type: string + responses: + '200': + content: + application/json: + schema: {} + description: '' + '400': + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBody' + description: '' + '403': + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBody' + description: '' + '404': + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBody' + description: '' + '408': + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBody' + description: '' + '429': + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBody' + description: '' + '500': + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBody' + description: '' + security: *id001 + servers: + - url: https://matchmaker.api.rivet.gg/v1 + tags: + - MatchmakerLobbies /messages: post: description: Sends a chat message to a given topic. diff --git a/gen/secrets.baseline.json b/gen/secrets.baseline.json index fb46c0cfb6..2ab3a3914a 100644 --- a/gen/secrets.baseline.json +++ b/gen/secrets.baseline.json @@ -123,10 +123,9 @@ { "type": "Base64 High Entropy String", "filename": "infra/nix/pkgs/clickhouse.nix", - "hashed_secret": "273a651dd6def838f834c80eada3c01ac8eaef2a", + "hashed_secret": "e3a7dca573dcaf190ffc1b960638016ea80fd7e7", "is_verified": false, - "line_number": 9, - "is_secret": false + "line_number": 9 } ], "lib/bolt/core/src/utils/telemetry.rs": [ @@ -172,7 +171,7 @@ "filename": "svc/pkg/email-verification/ops/create/src/lib.rs", "hashed_secret": "670988a3ad6d12dc80cb21cf98d44dd470e653d1", "is_verified": false, - "line_number": 110 + "line_number": 108 } ], "svc/pkg/telemetry/standalone/beacon/src/lib.rs": [ @@ -185,5 +184,5 @@ } ] }, - "generated_at": "2023-06-22T11:26:52Z" + "generated_at": "2023-08-28T23:48:55Z" } diff --git a/infra/salt/pillar/top.sls b/infra/salt/pillar/top.sls index 9256acf146..d5402cf934 100644 --- a/infra/salt/pillar/top.sls +++ b/infra/salt/pillar/top.sls @@ -18,6 +18,6 @@ base: - clickhouse 'G@roles:minio': - minio - 'G@roles:traefik-cloudflare-proxy': + 'G@roles:cloudflare-proxy': - cloudflare diff --git a/infra/salt/salt/clickhouse/files/clickhouse-server.service b/infra/salt/salt/clickhouse/files/clickhouse-server.service index 62aa5d00aa..4999f0ddb3 100644 --- a/infra/salt/salt/clickhouse/files/clickhouse-server.service +++ b/infra/salt/salt/clickhouse/files/clickhouse-server.service @@ -21,7 +21,7 @@ ExecStart=/var/rivet-nix/result/clickhouse/bin/clickhouse server --config=/etc/c LimitCORE=infinity LimitNOFILE=500000 CapabilityBoundingSet=CAP_NET_ADMIN CAP_IPC_LOCK CAP_SYS_NICE CAP_NET_BIND_SERVICE -{% if pillar['rivet']['deploy']['local']['restrict_service_resources'] %} +{% if 'local' in pillar.rivet.deploy and pillar.rivet.deploy.local.restrict_service_resources %} Nice=10 CPUAffinity=0 {% endif %} diff --git a/infra/salt/salt/clickhouse/init.sls b/infra/salt/salt/clickhouse/init.sls index c23ffdcec3..ab3af39001 100644 --- a/infra/salt/salt/clickhouse/init.sls +++ b/infra/salt/salt/clickhouse/init.sls @@ -1,3 +1,23 @@ +{% if grains['volumes']['ch']['mount'] %} +{% set device = '/dev/disk/by-id/scsi-0Linode_Volume_' ~ grains['rivet']['name'] ~ '-ch' %} + +disk_create_clickhouse: + blockdev.formatted: + - name: {{ device }} + - fs_type: ext4 + +disk_mount_clickhouse: + file.directory: + - name: /var/lib/clickhouse + - makedirs: True + mount.mounted: + - name: /var/lib/clickhouse + - device: {{ device }} + - fstype: ext4 + - require: + - blockdev: disk_create_clickhouse +{% endif %} + create_clickhouse_user: user.present: - name: clickhouse @@ -26,24 +46,16 @@ mkdir_clickhouse: - mode: 700 - require: - user: create_clickhouse_user + {%- if grains['volumes']['ch']['mount'] %} + - mount: disk_mount_clickhouse + {%- endif %} -{% if grains['volumes']['ch']['mount'] %} -{% set device = '/dev/disk/by-id/scsi-0Linode_Volume_' ~ grains['rivet']['name'] ~ '-ch' %} - -disk_create_clickhouse: - blockdev.formatted: - - name: {{ device }} - - fs_type: ext4 - -disk_mount_clickhouse: - mount.mounted: - - name: /var/lib/clickhouse - - device: {{ device }} - - fstype: ext4 - - require: - - blockdev: disk_create_clickhouse - - file: mkdir_clickhouse -{% endif %} +# Remove old config directories with residual files +remove_etc_clickhouse_server_dirs: + file.absent: + - names: + - /etc/clickhouse-server/config.d + - /etc/clickhouse-server/users.d push_etc_clickhouse_server: file.managed: diff --git a/infra/salt/salt/traefik_cloudflare_proxy/files/traefik_cloudflare_proxy.service b/infra/salt/salt/cloudflare_proxy/files/cloudflare-proxy.service similarity index 73% rename from infra/salt/salt/traefik_cloudflare_proxy/files/traefik_cloudflare_proxy.service rename to infra/salt/salt/cloudflare_proxy/files/cloudflare-proxy.service index 4109a13f9a..0947b52340 100644 --- a/infra/salt/salt/traefik_cloudflare_proxy/files/traefik_cloudflare_proxy.service +++ b/infra/salt/salt/cloudflare_proxy/files/cloudflare-proxy.service @@ -4,9 +4,9 @@ After=network-online.target Wants=network-online.target systemd-networkd-wait-online.service [Service] -User=traefik_cloudflare_proxy -Group=traefik_cloudflare_proxy -ExecStart=/usr/bin/traefik --configFile=/etc/traefik_cloudflare_proxy/traefik.toml +User=cloudflare_proxy +Group=cloudflare_proxy +ExecStart=/usr/bin/traefik --configFile=/etc/cloudflare_proxy/traefik.toml PrivateTmp=true PrivateDevices=false ProtectHome=true diff --git a/infra/salt/salt/cloudflare_proxy/files/consul/cloudflare-proxy.hcl b/infra/salt/salt/cloudflare_proxy/files/consul/cloudflare-proxy.hcl new file mode 100644 index 0000000000..b562dd36ce --- /dev/null +++ b/infra/salt/salt/cloudflare_proxy/files/consul/cloudflare-proxy.hcl @@ -0,0 +1,15 @@ +services { + name = "cloudflare-proxy" + tags = ["traefik"] + + port = 9060 + checks = [ + { + name = "Reachable on 9060" + tcp = "127.0.0.1:9060" + interval = "10s" + timeout = "1s" + } + ] +} + diff --git a/infra/salt/salt/traefik_cloudflare_proxy/files/dynamic/common.toml.j2 b/infra/salt/salt/cloudflare_proxy/files/dynamic/common.toml.j2 similarity index 100% rename from infra/salt/salt/traefik_cloudflare_proxy/files/dynamic/common.toml.j2 rename to infra/salt/salt/cloudflare_proxy/files/dynamic/common.toml.j2 diff --git a/infra/salt/salt/traefik_cloudflare_proxy/files/traefik.toml.j2 b/infra/salt/salt/cloudflare_proxy/files/traefik.toml.j2 similarity index 63% rename from infra/salt/salt/traefik_cloudflare_proxy/files/traefik.toml.j2 rename to infra/salt/salt/cloudflare_proxy/files/traefik.toml.j2 index dfb3c3dba4..c6194f5cc7 100644 --- a/infra/salt/salt/traefik_cloudflare_proxy/files/traefik.toml.j2 +++ b/infra/salt/salt/cloudflare_proxy/files/traefik.toml.j2 @@ -4,4 +4,4 @@ [providers] [providers.file] - directory = "/etc/traefik_cloudflare_proxy/dynamic" + directory = "/etc/cloudflare_proxy/dynamic" diff --git a/infra/salt/salt/cloudflare_proxy/init.sls b/infra/salt/salt/cloudflare_proxy/init.sls new file mode 100644 index 0000000000..ffcf9456e2 --- /dev/null +++ b/infra/salt/salt/cloudflare_proxy/init.sls @@ -0,0 +1,72 @@ +create_cloudflare_proxy_user: + user.present: + - name: cloudflare_proxy + - shell: /bin/false + - system: True + - usergroup: True + +create_etc_cloudflare_proxy: + file.directory: + - names: + - /etc/cloudflare_proxy/: {} + - /etc/cloudflare_proxy/dynamic/: {} + - user: cloudflare_proxy + - group: cloudflare_proxy + - mode: 550 + - require: + - user: create_cloudflare_proxy_user + +push_etc_cloudflare_proxy: + file.managed: + - names: + # Static config + - /etc/cloudflare_proxy/traefik.toml: + - source: salt://cloudflare_proxy/files/traefik.toml.j2 + + # Dynamic configs + - /etc/cloudflare_proxy/dynamic/common.toml: + - source: salt://cloudflare_proxy/files/dynamic/common.toml.j2 + + - user: cloudflare_proxy + - group: cloudflare_proxy + - template: jinja + - context: + loki_url: "{{ pillar['rivet']['logging']['loki']['endpoint'] }}" + access_client_id: "{{ pillar['cloudflare']['access']['proxy']['client_id'] }}" + access_client_secret: "{{ pillar['cloudflare']['access']['proxy']['client_secret'] }}" + - mode: 440 + - require: + - file: create_etc_cloudflare_proxy + +push_cloudflare_proxy_service: + file.managed: + - name: /etc/systemd/system/cloudflare-proxy.service + - source: salt://cloudflare_proxy/files/cloudflare-proxy.service + +# Manually restart the Traefik service yourself in order to prevent terminating +# connections needlessly +start_cloudflare_proxy_service: + service.running: + - name: cloudflare-proxy + - enable: True + - require: + - file: push_cloudflare_proxy_service + - file: push_etc_cloudflare_proxy + +{%- if 'consul-client' in grains['roles'] %} +push_etc_consul_cloudflare_proxy_hcl: + file.managed: + - name: /etc/consul.d/cloudflare-proxy.hcl + - source: salt://cloudflare_proxy/files/consul/cloudflare-proxy.hcl + - template: jinja + - require: + - file: create_etc_consul + cmd.run: + - name: consul reload + - require: + - service: start_consul_service + - file: push_etc_consul_cloudflare_proxy_hcl + - onchanges: + - file: push_etc_consul_cloudflare_proxy_hcl +{%- endif %} + diff --git a/infra/salt/salt/cloudflared/files/cloudflared.service b/infra/salt/salt/cloudflared/files/cloudflared.service index 686d901868..c9bd5f7e1a 100644 --- a/infra/salt/salt/cloudflared/files/cloudflared.service +++ b/infra/salt/salt/cloudflared/files/cloudflared.service @@ -8,7 +8,7 @@ Type=notify ExecStart=/var/rivet-nix/result/cloudflared/bin/cloudflared --no-autoupdate --config /etc/cloudflared/config.yml tunnel run Restart=on-failure RestartSec=5s -{% if pillar['rivet']['deploy']['local']['restrict_service_resources'] %} +{% if 'local' in pillar.rivet.deploy and pillar.rivet.deploy.local.restrict_service_resources %} Nice=10 CPUAffinity=0 {% endif %} diff --git a/infra/salt/salt/cockroach/files/cockroach.service.j2 b/infra/salt/salt/cockroach/files/cockroach.service.j2 index 06886385b5..b77136a8bd 100644 --- a/infra/salt/salt/cockroach/files/cockroach.service.j2 +++ b/infra/salt/salt/cockroach/files/cockroach.service.j2 @@ -28,7 +28,7 @@ ExecStart=/usr/local/bin/cockroach start \ TimeoutStopSec=60 Restart=always RestartSec=10 -{% if pillar['rivet']['deploy']['local']['restrict_service_resources'] %} +{% if 'local' in pillar.rivet.deploy and pillar.rivet.deploy.local.restrict_service_resources %} Nice=10 CPUAffinity=0 {% endif %} diff --git a/infra/salt/salt/cockroach/init.sls b/infra/salt/salt/cockroach/init.sls index f4282b3450..2454d22d32 100644 --- a/infra/salt/salt/cockroach/init.sls +++ b/infra/salt/salt/cockroach/init.sls @@ -13,13 +13,14 @@ disk_create_cockroach: - fs_type: ext4 disk_mount_cockroach: + file.directory: + - name: /var/lib/cockroach mount.mounted: - name: /var/lib/cockroach - device: {{ device }} - fstype: ext4 - require: - blockdev: disk_create_cockroach - - file: mkdir_crdb {% endif %} @@ -67,6 +68,9 @@ mkdir_crdb: - /usr/local/lib/cockroach: [] - require: - user: create_crdb_user + {%- if grains['volumes']['crdb']['mount'] %} + - mount: disk_mount_cockroach + {%- endif %} install_crdb: diff --git a/infra/salt/salt/consul/files/consul.service b/infra/salt/salt/consul/files/consul.service index 9ac93b15d9..cc929ebc64 100644 --- a/infra/salt/salt/consul/files/consul.service +++ b/infra/salt/salt/consul/files/consul.service @@ -24,7 +24,7 @@ KillSignal=SIGTERM LimitNOFILE=65536 Restart=always RestartSec=2 -{% if pillar['rivet']['deploy']['local']['restrict_service_resources'] %} +{% if 'local' in pillar.rivet.deploy and pillar.rivet.deploy.local.restrict_service_resources %} Nice=10 CPUAffinity=0 {% endif %} diff --git a/infra/salt/salt/traefik/files/consul/traefik.hcl.j2 b/infra/salt/salt/ingress_proxy/files/consul/ingress-proxy.hcl.j2 similarity index 87% rename from infra/salt/salt/traefik/files/consul/traefik.hcl.j2 rename to infra/salt/salt/ingress_proxy/files/consul/ingress-proxy.hcl.j2 index aa61b4a163..abfc7d2f6f 100644 --- a/infra/salt/salt/traefik/files/consul/traefik.hcl.j2 +++ b/infra/salt/salt/ingress_proxy/files/consul/ingress-proxy.hcl.j2 @@ -1,5 +1,5 @@ services { - id = "traefik-lb-80" + id = "ingress-proxy-lb-80" name = "{{service_name}}" tags = ["traefik", "lb-80"] @@ -15,7 +15,7 @@ services { } services { - id = "traefik-lb-443" + id = "ingress-proxy-lb-443" name = "{{service_name}}" tags = ["traefik", "lb-443"] @@ -31,7 +31,7 @@ services { } services { - id = "traefik-client" + id = "ingress-proxy-client" name = "{{service_name}}" tags = ["traefik", "api"] diff --git a/infra/salt/salt/traefik/files/dynamic/common.toml.j2 b/infra/salt/salt/ingress_proxy/files/dynamic/common.toml.j2 similarity index 100% rename from infra/salt/salt/traefik/files/dynamic/common.toml.j2 rename to infra/salt/salt/ingress_proxy/files/dynamic/common.toml.j2 diff --git a/infra/salt/salt/traefik/files/dynamic/tls.toml.j2 b/infra/salt/salt/ingress_proxy/files/dynamic/tls.toml.j2 similarity index 53% rename from infra/salt/salt/traefik/files/dynamic/tls.toml.j2 rename to infra/salt/salt/ingress_proxy/files/dynamic/tls.toml.j2 index 87018329cb..b5a536b690 100644 --- a/infra/salt/salt/traefik/files/dynamic/tls.toml.j2 +++ b/infra/salt/salt/ingress_proxy/files/dynamic/tls.toml.j2 @@ -1,12 +1,12 @@ {%- for cert_id in traefik.tls_certs %} [[tls.certificates]] - certFile = "/etc/traefik/tls/{{ cert_id }}_cert.pem" - keyFile = "/etc/traefik/tls/{{ cert_id }}_key.pem" + certFile = "/etc/ingress_proxy/tls/{{ cert_id }}_cert.pem" + keyFile = "/etc/ingress_proxy/tls/{{ cert_id }}_key.pem" {%- endfor %} {%- if traefik.tls_client_cert %} [tls.options.default.clientAuth] - caFiles = ["/etc/traefik/tls/traefik_client.crt"] + caFiles = ["/etc/ingress_proxy/tls/traefik_client.crt"] clientAuthType = "RequireAndVerifyClientCert" {%- endif %} diff --git a/infra/salt/salt/traefik/files/traefik.service b/infra/salt/salt/ingress_proxy/files/ingress-proxy.service similarity index 66% rename from infra/salt/salt/traefik/files/traefik.service rename to infra/salt/salt/ingress_proxy/files/ingress-proxy.service index fe2a885f30..1be388aa25 100644 --- a/infra/salt/salt/traefik/files/traefik.service +++ b/infra/salt/salt/ingress_proxy/files/ingress-proxy.service @@ -1,14 +1,14 @@ # See https://doc.traefik.io/traefik-enterprise/installing/on-premise/#systemd-linux-only [Unit] -Description=Traefik +Description=Traefik Ingress proxy After=network-online.target Wants=network-online.target systemd-networkd-wait-online.service [Service] -User=traefik -Group=traefik -ExecStart=/usr/bin/traefik +User=ingress_proxy +Group=ingress_proxy +ExecStart=/usr/bin/traefik --configFile=/etc/ingress_proxy/traefik.toml PrivateTmp=true PrivateDevices=false ProtectHome=true @@ -19,7 +19,7 @@ LimitNOFILE=32768 AmbientCapabilities=CAP_NET_BIND_SERVICE Restart=always RestartSec=2 -{% if pillar['rivet']['deploy']['local']['restrict_service_resources'] %} +{% if 'local' in pillar.rivet.deploy and pillar.rivet.deploy.local.restrict_service_resources %} Nice=10 CPUAffinity=0 {% endif %} diff --git a/infra/salt/salt/traefik/files/traefik.toml.j2 b/infra/salt/salt/ingress_proxy/files/traefik.toml.j2 similarity index 93% rename from infra/salt/salt/traefik/files/traefik.toml.j2 rename to infra/salt/salt/ingress_proxy/files/traefik.toml.j2 index 6d7b0d9a07..6a92b3eb32 100644 --- a/infra/salt/salt/traefik/files/traefik.toml.j2 +++ b/infra/salt/salt/ingress_proxy/files/traefik.toml.j2 @@ -54,12 +54,12 @@ [log] level = "{{ pillar['rivet']['traefik']['log_level'] }}" - filePath = "/opt/traefik/traefik.log" + filePath = "/opt/ingress_proxy/traefik.log" format = "json" {% if pillar['rivet']['traefik']['access_logs'] %} [accessLog] - filePath = "/opt/traefik/access.log" + filePath = "/opt/ingress_proxy/access.log" format = "json" fields.defaultMode = "keep" fields.headers.defaultMode = "keep" @@ -74,7 +74,7 @@ [providers] [providers.file] - directory = "/etc/traefik/dynamic" + directory = "/etc/ingress_proxy/dynamic" {%- if 'consul-client' in grains['roles'] %} [providers.consulCatalog] diff --git a/infra/salt/salt/ingress_proxy/init.sls b/infra/salt/salt/ingress_proxy/init.sls new file mode 100644 index 0000000000..12f2f7914d --- /dev/null +++ b/infra/salt/salt/ingress_proxy/init.sls @@ -0,0 +1,127 @@ +{% set pool = grains['rivet']['pool_id'] %} +{% if pool == 'ing-px' or pool == 'local' %} + {% set tls_certs = ['cloudflare_rivet_gg'] %} + {% set tls_client_cert = true %} +{% elif pool == 'ing-job' %} + {% set tls_certs = ['letsencrypt_rivet_job'] %} + {% set tls_client_cert = false %} +{% endif %} + +# See on-prem installation instructions: https://doc.traefik.io/traefik-enterprise/installing/on-premise/#systemd-linux-only + +create_ingress_proxy_user: + user.present: + - name: ingress_proxy + - shell: /bin/false + - system: True + - usergroup: True + +create_etc_ingress_proxy: + file.directory: + - names: + - /etc/ingress_proxy/: {} + - /etc/ingress_proxy/dynamic/: {} + - /etc/ingress_proxy/tls/: {} + - /opt/ingress_proxy/: {} + - user: ingress_proxy + - group: ingress_proxy + - mode: 550 + - require: + - user: create_ingress_proxy_user + +push_etc_ingress_proxy: + file.managed: + - names: + # Static config + - /etc/ingress_proxy/traefik.toml: + - source: salt://ingress_proxy/files/traefik.toml.j2 + + # Dynamic configs + - /etc/ingress_proxy/dynamic/common.toml: + - source: salt://ingress_proxy/files/dynamic/common.toml.j2 + - /etc/ingress_proxy/dynamic/tls.toml: + - source: salt://ingress_proxy/files/dynamic/tls.toml.j2 + + # TLS certs + {%- for cert_id in tls_certs %} + - /etc/ingress_proxy/tls/{{ cert_id }}_cert.pem: + - contents: | + {{ pillar['tls']['tls_certs'][cert_id]['cert_pem'] | indent(12) }} + - /etc/ingress_proxy/tls/{{ cert_id }}_key.pem: + - contents: | + {{ pillar['tls']['tls_certs'][cert_id]['key_pem'] | indent(12) }} + {%- endfor %} + + # TLS client cert + {%- if tls_client_cert %} + - /etc/ingress_proxy/tls/traefik_client.crt: + - source: https://developers.cloudflare.com/ssl/static/authenticated_origin_pull_ca.pem + - source_hash: c1a581133a27f5fc98cbb1f32d048925470deab627e6b5f1b586f6df075d8493ec7d08ede04d0f31ec2c2cd74de27ed0df866e3874ad54a9e962695759ba7e5b + {%- endif %} + + - user: ingress_proxy + - group: ingress_proxy + - template: jinja + - context: + provider_http: + endpoint: 'https://route.api.{{ pillar['rivet']['domain']['base'] }}/v1/traefik/config?region={{grains['rivet']['region_id']}}&pool={{grains['rivet']['pool_id']}}&token={{pillar['rivet']['api-route']['token']}}' + {%- if pool == 'ing-px' %} + poll_interval: '2.5s' + {%- else %} + poll_interval: '1s' + {%- endif %} + namespace: {{ pillar['rivet']['namespace'] }} + pool: {{ pool }} + domain: {{ pillar['rivet']['domain'] }} + nebula_ipv4: {{ grains['nebula']['ipv4'] }} + traefik: + tls_certs: {{ tls_certs }} + tls_client_cert: {{ tls_client_cert }} + - mode: 440 + - require: + - file: create_etc_ingress_proxy + +push_ingress_proxy_service: + file.managed: + - name: /etc/systemd/system/ingress-proxy.service + - source: salt://ingress_proxy/files/ingress-proxy.service + - template: jinja + +# Stop and disable the old service under the old name first +stop_traefik_service: + service.dead: + - name: traefik + - enable: False + +# Manually restart the Traefik service yourself in order to prevent terminating +# connections needlessly +start_ingress_proxy_service: + service.running: + - name: ingress-proxy + - enable: True + - require: + - file: install_traefik + - file: push_ingress_proxy_service + - file: push_etc_ingress_proxy + - service: stop_traefik_service + +{%- if 'consul-client' in grains['roles'] %} +push_etc_consul_ingress_proxy_hcl: + file.managed: + - name: /etc/consul.d/ingress-proxy.hcl + - source: salt://ingress_proxy/files/consul/ingress-proxy.hcl.j2 + - template: jinja + - context: + service_name: {{ pool }} + nebula_ipv4: {{ grains['nebula']['ipv4'] }} + - require: + - file: create_etc_consul + cmd.run: + - name: consul reload + - require: + - service: start_consul_service + - file: push_etc_consul_ingress_proxy_hcl + - onchanges: + - file: push_etc_consul_ingress_proxy_hcl +{%- endif %} + diff --git a/infra/salt/salt/minio/files/minio.service b/infra/salt/salt/minio/files/minio.service index 42c5b8ffa7..bd2deb9294 100644 --- a/infra/salt/salt/minio/files/minio.service +++ b/infra/salt/salt/minio/files/minio.service @@ -18,7 +18,7 @@ LimitNOFILE=1048576 TasksMax=infinity TimeoutStopSec=infinity SendSIGKILL=no -{% if pillar['rivet']['deploy']['local']['restrict_service_resources'] %} +{% if 'local' in pillar.rivet.deploy and pillar.rivet.deploy.local.restrict_service_resources %} Nice=10 CPUAffinity=0 {% endif %} diff --git a/infra/salt/salt/nats/files/nats-server.service b/infra/salt/salt/nats/files/nats-server.service index b5e70460ae..e95cd18e2a 100644 --- a/infra/salt/salt/nats/files/nats-server.service +++ b/infra/salt/salt/nats/files/nats-server.service @@ -14,7 +14,7 @@ ExecReload=/bin/kill -s HUP $MAINPID ExecStop=/bin/kill -s SIGINT $MAINPID Restart=always RestartSec=2 -{% if pillar['rivet']['deploy']['local']['restrict_service_resources'] %} +{% if 'local' in pillar.rivet.deploy and pillar.rivet.deploy.local.restrict_service_resources %} Nice=10 CPUAffinity=0 {% endif %} diff --git a/infra/salt/salt/node_exporter/files/node_exporter.service b/infra/salt/salt/node_exporter/files/node_exporter.service index 312919755d..227f0d3262 100644 --- a/infra/salt/salt/node_exporter/files/node_exporter.service +++ b/infra/salt/salt/node_exporter/files/node_exporter.service @@ -10,7 +10,7 @@ Type=simple ExecStart=/usr/bin/node_exporter --collector.cgroups --collector.network_route --collector.systemd Restart=always RestartSec=2 -{% if pillar['rivet']['deploy']['local']['restrict_service_resources'] %} +{% if 'local' in pillar.rivet.deploy and pillar.rivet.deploy.local.restrict_service_resources %} Nice=10 CPUAffinity=0 {% endif %} diff --git a/infra/salt/salt/nomad/files/nomad.service.j2 b/infra/salt/salt/nomad/files/nomad.service.j2 index 7a3b88199e..cb746dc319 100644 --- a/infra/salt/salt/nomad/files/nomad.service.j2 +++ b/infra/salt/salt/nomad/files/nomad.service.j2 @@ -32,7 +32,7 @@ Restart=always RestartSec=2 TasksMax=infinity OOMScoreAdjust=-1000 -{% if pillar['rivet']['deploy']['local']['restrict_service_resources'] %} +{% if 'local' in pillar.rivet.deploy and pillar.rivet.deploy.local.restrict_service_resources %} Nice=10 CPUAffinity=0 {% endif %} diff --git a/infra/salt/salt/nomad/init.sls b/infra/salt/salt/nomad/init.sls index c9ed45b37f..62833c2dd7 100644 --- a/infra/salt/salt/nomad/init.sls +++ b/infra/salt/salt/nomad/init.sls @@ -1,5 +1,5 @@ # https://github.com/hashicorp/nomad/releases -{% set version = '1.6.1' %} +{% set version = '1.6.0' %} {% set create_nomad_user = 'nomad-server' in grains['roles'] %} {% if create_nomad_user %} diff --git a/infra/salt/salt/prometheus/files/prometheus.service.j2 b/infra/salt/salt/prometheus/files/prometheus.service.j2 index c3b826e873..918be473b2 100644 --- a/infra/salt/salt/prometheus/files/prometheus.service.j2 +++ b/infra/salt/salt/prometheus/files/prometheus.service.j2 @@ -17,7 +17,7 @@ ExecStart=/usr/bin/prometheus \ ExecReload=/bin/kill -HUP $MAINPID Restart=always RestartSec=2 -{% if pillar['rivet']['deploy']['local']['restrict_service_resources'] %} +{% if 'local' in pillar.rivet.deploy and pillar.rivet.deploy.local.restrict_service_resources %} Nice=10 CPUAffinity=0 {% endif %} diff --git a/infra/salt/salt/prometheus/init.sls b/infra/salt/salt/prometheus/init.sls index 6a042b2428..0940db8022 100644 --- a/infra/salt/salt/prometheus/init.sls +++ b/infra/salt/salt/prometheus/init.sls @@ -3,23 +3,6 @@ {% set pool = grains['rivet']['pool_id'] %} -create_prometheus_user: - user.present: - - name: prometheus - - shell: /bin/false - - system: True - - usergroup: True - -mkdir_prometheus: - file.directory: - - names: - - /mnt/prometheus: - - user: prometheus - - group: prometheus - - mode: 700 - - require: - - user: create_prometheus_user - {% if grains['volumes']['prm']['mount'] %} {% set device = '/dev/disk/by-id/scsi-0Linode_Volume_' ~ grains['rivet']['name'] ~ '-prm' %} @@ -29,15 +12,37 @@ disk_create_prometheus: - fs_type: ext4 disk_mount_prometheus: + file.directory: + - name: /mnt/prometheus + - makedirs: True mount.mounted: - name: /mnt/prometheus - device: {{device}} - fstype: ext4 - require: - - file: mkdir_prometheus - blockdev: disk_create_prometheus {% endif %} +create_prometheus_user: + user.present: + - name: prometheus + - shell: /bin/false + - system: True + - usergroup: True + +mkdir_prometheus: + file.directory: + - names: + - /mnt/prometheus: + - user: prometheus + - group: prometheus + - mode: 700 + - require: + - user: create_prometheus_user + {%- if grains['volumes']['prm']['mount'] %} + - mount: disk_mount_prometheus + {%- endif %} + install_prometheus: archive.extracted: - name: /opt/prometheus_{{version}}/ diff --git a/infra/salt/salt/redis/files/redis.service.j2 b/infra/salt/salt/redis/files/redis.service.j2 index 281b363660..e743b0caec 100644 --- a/infra/salt/salt/redis/files/redis.service.j2 +++ b/infra/salt/salt/redis/files/redis.service.j2 @@ -14,7 +14,7 @@ ExecStartPre=-/usr/bin/docker stop {{container_name}} ExecStartPre=-/usr/bin/docker rm {{container_name}} ExecStartPre=/usr/bin/docker pull {{image}} ExecStart=/bin/sh -c '/usr/bin/docker run --rm --name {{container_name}} --user "$(id -u redis):$(id -g redis)" -v /etc/redis/{{db}}.conf:/etc/redis/{{db}}.conf {% if persistent %}-v /var/lib/redis/{{db}}/db:/var/lib/redis/{{db}}/db{% endif %} --network host -p "{{port}}:{{port}}" {{image}} /etc/redis/{{db}}.conf' -{% if pillar['rivet']['deploy']['local']['restrict_service_resources'] %} +{% if 'local' in pillar.rivet.deploy and pillar.rivet.deploy.local.restrict_service_resources %} Nice=10 CPUAffinity=0 {% endif %} diff --git a/infra/salt/salt/top.sls b/infra/salt/salt/top.sls index 572811fb94..163aff876a 100644 --- a/infra/salt/salt/top.sls +++ b/infra/salt/salt/top.sls @@ -32,7 +32,9 @@ base: - minio 'G@roles:traefik': - traefik - 'G@roles:traefik-cloudflare-proxy': - - traefik_cloudflare_proxy + 'G@roles:ingress-proxy': + - ingress_proxy + 'G@roles:cloudflare-proxy': + - cloudflare_proxy 'G@roles:docker-plugin-loki': - docker_plugin_loki diff --git a/infra/salt/salt/traefik/init.sls b/infra/salt/salt/traefik/init.sls index 3031c037d5..c545a3c05a 100644 --- a/infra/salt/salt/traefik/init.sls +++ b/infra/salt/salt/traefik/init.sls @@ -1,18 +1,7 @@ # https://github.com/traefik/traefik/releases {% set version = '2.10.4' %} -{% set pool = grains['rivet']['pool_id'] %} -{% if pool == 'ing-px' or pool == 'local' %} - {% set tls_certs = ['cloudflare_rivet_gg'] %} - {% set tls_client_cert = true %} -{% elif pool == 'ing-job' %} - {% set tls_certs = ['letsencrypt_rivet_job'] %} - {% set tls_client_cert = false %} -{% endif %} - -# See on-prem installation instructions: https://doc.traefik.io/traefik-enterprise/installing/on-premise/#systemd-linux-only - -create_traefik_exporter_user: +create_traefik_user: user.present: - name: traefik - shell: /bin/false @@ -34,6 +23,7 @@ install_traefik: - group: traefik - mode: 755 - require: + - user: create_traefik_user - archive: install_traefik cmd.run: - name: traefik version @@ -43,104 +33,17 @@ install_traefik: - onchanges: - file: install_traefik -create_etc_traefik: - file.directory: - - names: - - /etc/traefik/: {} - - /etc/traefik/dynamic/: {} - - /etc/traefik/tls/: {} - - /opt/traefik/: {} - - user: traefik - - group: traefik - - mode: 550 - -push_etc_traefik: - file.managed: - - names: - # Static config - - /etc/traefik/traefik.toml: - - source: salt://traefik/files/traefik.toml.j2 - - # Dynamic configs - - /etc/traefik/dynamic/common.toml: - - source: salt://traefik/files/dynamic/common.toml.j2 - - /etc/traefik/dynamic/tls.toml: - - source: salt://traefik/files/dynamic/tls.toml.j2 - - # TLS certs - {%- for cert_id in tls_certs %} - - /etc/traefik/tls/{{ cert_id }}_cert.pem: - - contents: | - {{ pillar['tls']['tls_certs'][cert_id]['cert_pem'] | indent(12) }} - - /etc/traefik/tls/{{ cert_id }}_key.pem: - - contents: | - {{ pillar['tls']['tls_certs'][cert_id]['key_pem'] | indent(12) }} - {%- endfor %} - - # TLS client cert - {%- if tls_client_cert %} - - /etc/traefik/tls/traefik_client.crt: - - source: https://developers.cloudflare.com/ssl/static/authenticated_origin_pull_ca.pem - - source_hash: c1a581133a27f5fc98cbb1f32d048925470deab627e6b5f1b586f6df075d8493ec7d08ede04d0f31ec2c2cd74de27ed0df866e3874ad54a9e962695759ba7e5b - {%- endif %} - - - user: traefik - - group: traefik - - template: jinja - - context: - provider_http: - endpoint: 'https://route.api.{{ pillar['rivet']['domain']['base'] }}/v1/traefik/config?region={{grains['rivet']['region_id']}}&pool={{grains['rivet']['pool_id']}}&token={{pillar['rivet']['api-route']['token']}}' - {%- if pool == 'ing-px' %} - poll_interval: '2.5s' - {%- else %} - poll_interval: '1s' - {%- endif %} - namespace: {{ pillar['rivet']['namespace'] }} - pool: {{ pool }} - domain: {{ pillar['rivet']['domain'] }} - nebula_ipv4: {{ grains['nebula']['ipv4'] }} - traefik: - tls_certs: {{ tls_certs }} - tls_client_cert: {{ tls_client_cert }} - - mode: 440 - - require: - - file: create_etc_traefik - - -push_traefik_service: - file.managed: - - name: /etc/systemd/system/traefik.service - - source: salt://traefik/files/traefik.service - - template: jinja - -# Manually restart the Traefik service yourself in order to prevent terminating -# connections needlessly -start_traefik_service: - service.running: - - name: traefik - - enable: True - - require: - - file: install_traefik - - file: push_traefik_service - - file: push_etc_traefik - {%- if 'consul-client' in grains['roles'] %} -push_etc_consul_traefik_hcl: - file.managed: +# Delete old Treafik Consul file that was moved +remove_etc_consul_traefik_hcl: + file.absent: - name: /etc/consul.d/traefik.hcl - - source: salt://traefik/files/consul/traefik.hcl.j2 - - template: jinja - - context: - service_name: {{ pool }} - nebula_ipv4: {{ grains['nebula']['ipv4'] }} - - require: - - file: create_etc_consul cmd.run: - name: consul reload - require: - service: start_consul_service - - file: push_etc_consul_traefik_hcl + - file: remove_etc_consul_traefik_hcl - onchanges: - - file: push_etc_consul_traefik_hcl + - file: remove_etc_consul_traefik_hcl {%- endif %} diff --git a/infra/salt/salt/traefik_cloudflare_proxy/init.sls b/infra/salt/salt/traefik_cloudflare_proxy/init.sls deleted file mode 100644 index c6464acfc3..0000000000 --- a/infra/salt/salt/traefik_cloudflare_proxy/init.sls +++ /dev/null @@ -1,54 +0,0 @@ -{% import_json "/srv/salt-context/rivet/secrets.json" as rivet_secrets %} - -create_traefik_cloudflare_proxy_user: - user.present: - - name: traefik_cloudflare_proxy - - shell: /bin/false - - system: True - - usergroup: True - -create_etc_traefik_cloudflare_proxy: - file.directory: - - names: - - /etc/traefik_cloudflare_proxy/: {} - - /etc/traefik_cloudflare_proxy/dynamic/: {} - - user: traefik_cloudflare_proxy - - group: traefik_cloudflare_proxy - - mode: 550 - -push_etc_traefik_cloudflare_proxy: - file.managed: - - names: - # Static config - - /etc/traefik_cloudflare_proxy/traefik.toml: - - source: salt://traefik_cloudflare_proxy/files/traefik.toml.j2 - - # Dynamic configs - - /etc/traefik_cloudflare_proxy/dynamic/common.toml: - - source: salt://traefik_cloudflare_proxy/files/dynamic/common.toml.j2 - - - user: traefik_cloudflare_proxy - - group: traefik_cloudflare_proxy - - template: jinja - - context: - loki_url: "{{ pillar['rivet']['logging']['loki']['endpoint'] }}" - access_client_id: "{{ pillar['cloudflare']['access']['proxy']['client_id'] }}" - access_client_secret: "{{ pillar['cloudflare']['access']['proxy']['client_secret'] }}" - - mode: 440 - - require: - - file: create_etc_traefik_cloudflare_proxy - -push_traefik_cloudflare_proxy_service: - file.managed: - - name: /etc/systemd/system/traefik_cloudflare_proxy.service - - source: salt://traefik_cloudflare_proxy/files/traefik_cloudflare_proxy.service - -# Manually restart the Traefik service yourself in order to prevent terminating -# connections needlessly -start_traefik_cloudflare_proxy_service: - service.running: - - name: traefik_cloudflare_proxy - - enable: True - - require: - - file: push_traefik_cloudflare_proxy_service - - file: push_etc_traefik_cloudflare_proxy diff --git a/infra/salt/salt/traffic_server/files/consul/traffic_server.hcl.j2 b/infra/salt/salt/traffic_server/files/consul/traffic_server.hcl.j2 index 6337cdc181..d0df35a654 100644 --- a/infra/salt/salt/traffic_server/files/consul/traffic_server.hcl.j2 +++ b/infra/salt/salt/traffic_server/files/consul/traffic_server.hcl.j2 @@ -42,24 +42,23 @@ services { # and https://imagekit.io/blog/ultimate-guide-to-http-caching-for-static-assets/ "{{prefix}}.http.middlewares.ats-cdn-cache-control.headers.customResponseHeaders.Cache-Control=public, max-age=604800, immutable", - # MARK: routers.ats-build - # "{{prefix}}.http.routers.ats-build.entryPoints=lb-443", - # "{{prefix}}.http.routers.ats-build.rule=Host(`cdn.{{domain['base']}}`) && PathPrefix(`/build/`)", - # "{{prefix}}.http.routers.ats-build.middlewares=ats-build-auth, ats-build-path, ats-cdn-lfs", - # "{{prefix}}.http.routers.ats-build.tls=true", - - # MARK: middlewares.ats-build-auth - # TODO: Add more secure per-game authentication with https://doc.traefik.io/traefik/middlewares/http/forwardauth/ - # "{{prefix}}.http.middlewares.ats-build-auth.basicAuth.users=job_run_image:$apr1$0peMM8t1$/ST0ckxxbp4AY.SUzkk4E1", - # Without this, we'll receive a `SignatureDoesNotMatch` error - # "{{prefix}}.http.middlewares.ats-build-auth.basicAuth.removeHeader=true", - - # MARK: middlewares.ats-build-path - # "{{prefix}}.http.middlewares.ats-build-path.replacePathRegex.regex=^/build/(.*)", - # "{{prefix}}.http.middlewares.ats-build-path.replacePathRegex.replacement=/s3-cache/{{namespace}}-bucket-build/${1}", + {% for provider, _ in s3_providers.items() %} + {% for bucket in ["job-log", "team-billing", "lobby-history-export", "nomad-log-export"] %} + # MARK: http.routers-{{provider}}-{{bucket}} + "{{prefix}}.http.routers.ats-{{provider}}-{{bucket}}.entryPoints=lb-443", + "{{prefix}}.http.routers.ats-{{provider}}-{{bucket}}.rule=Host(`cdn.{{domain['base']}}`) && PathPrefix(`/{{provider}}/{{bucket}}/`)", + "{{prefix}}.http.routers.ats-{{provider}}-{{bucket}}.middlewares=ats-{{bucket}}-path, ats-cors, ats-cdn", + "{{prefix}}.http.routers.ats-{{provider}}-{{bucket}}.tls=true", + + # MARK: middlewares.ats-{{provider}}-{{bucket}}-path + "{{prefix}}.http.middlewares.ats-{{provider}}-{{bucket}}-path.replacePathRegex.regex=^/{{provider}}/{{bucket}}/(.*)", + "{{prefix}}.http.middlewares.ats-{{provider}}-{{bucket}}-path.replacePathRegex.replacement=/s3-cache/{{provider}}/{{namespace}}-bucket-{{bucket}}/${1}", + {% endfor %} + {% endfor %} {% for bucket in ["job-log", "team-billing", "lobby-history-export", "nomad-log-export"] %} # MARK: http.routers-{{bucket}} + # Default route for backwards compatibility "{{prefix}}.http.routers.ats-{{bucket}}.entryPoints=lb-443", "{{prefix}}.http.routers.ats-{{bucket}}.rule=Host(`cdn.{{domain['base']}}`) && PathPrefix(`/{{bucket}}/`)", "{{prefix}}.http.routers.ats-{{bucket}}.middlewares=ats-{{bucket}}-path, ats-cors, ats-cdn", diff --git a/infra/salt/salt/traffic_server/files/etc/dynamic/remap.config.j2 b/infra/salt/salt/traffic_server/files/etc/dynamic/remap.config.j2 index 6f3d1a6157..ab80114b21 100644 --- a/infra/salt/salt/traffic_server/files/etc/dynamic/remap.config.j2 +++ b/infra/salt/salt/traffic_server/files/etc/dynamic/remap.config.j2 @@ -1,2 +1,7 @@ -map /s3-cache {{s3_endpoint}} @plugin=s3_auth.so @pparam=--config @pparam=s3_auth_v4.config +{%- for provider_name, provider in s3_providers.items() %} +map /s3-cache/{{provider_name}} {{provider['endpoint_internal']}} @plugin=s3_auth.so @pparam=--config @pparam=s3_auth_v4_{{provider_name}}.config +{%- endfor %} +{%- if 'default' in s3_providers %} +map /s3-cache {{s3_providers['default']['endpoint_internal']}} @plugin=s3_auth.so @pparam=--config @pparam=s3_auth_v4_default.config +{%- endif %} diff --git a/infra/salt/salt/traffic_server/files/etc/dynamic/s3_auth_v4.config.j2 b/infra/salt/salt/traffic_server/files/etc/dynamic/s3_auth_v4.config.j2 index 784fe57e17..c7a626b3b7 100644 --- a/infra/salt/salt/traffic_server/files/etc/dynamic/s3_auth_v4.config.j2 +++ b/infra/salt/salt/traffic_server/files/etc/dynamic/s3_auth_v4.config.j2 @@ -2,4 +2,4 @@ access_key={{s3_access_key_id}} secret_key={{s3_secret_access_key}} version=4 -v4-region-map=s3_region_map.config +v4-region-map={{s3_region_map_file_name}}.config diff --git a/infra/salt/salt/traffic_server/files/etc/dynamic/s3_region_map.config.j2 b/infra/salt/salt/traffic_server/files/etc/dynamic/s3_region_map.config.j2 index a232ea92fc..331ede7ef4 100644 --- a/infra/salt/salt/traffic_server/files/etc/dynamic/s3_region_map.config.j2 +++ b/infra/salt/salt/traffic_server/files/etc/dynamic/s3_region_map.config.j2 @@ -1,5 +1,5 @@ -{% set s3_host = s3_endpoint.split('://')[1] if s3_endpoint is not none and '://' in s3_endpoint else s3_endpoint %} -{% set s3_hostname = s3_host.split(':')[0] if s3_host is not none and ':' in s3_host else s3_host %} +{% set s3_host = s3_endpoint.split('://')[1] if '://' in s3_endpoint else s3_endpoint %} +{% set s3_hostname = s3_host.split(':')[0] if s3_host and ':' in s3_host else s3_host %} # Default region {{s3_hostname}}: {{s3_region}} diff --git a/infra/salt/salt/traffic_server/files/trafficserver.service b/infra/salt/salt/traffic_server/files/trafficserver.service index 3cd4a9ba15..f6e3cb85d9 100644 --- a/infra/salt/salt/traffic_server/files/trafficserver.service +++ b/infra/salt/salt/traffic_server/files/trafficserver.service @@ -6,11 +6,11 @@ After=network-online.target Type=simple User=trafficserver Group=trafficserver -EnvironmentFile=-/etc/default/trafficserver +Environment="TM_START=yes" PIDFile=/run/trafficserver/manager.lock ExecStart=/var/rivet-nix/result/traffic_server/bin/traffic_manager $TM_DAEMON_ARGS ExecReload=/var/rivet-nix/result/traffic_server/bin/traffic_manager config reload -{% if pillar['rivet']['deploy']['local']['restrict_service_resources'] %} +{% if 'local' in pillar.rivet.deploy and pillar.rivet.deploy.local.restrict_service_resources %} Nice=10 CPUAffinity=0 {% endif %} diff --git a/infra/salt/salt/traffic_server/init.sls b/infra/salt/salt/traffic_server/init.sls index b7c9eb6cb3..ce5dbaba32 100644 --- a/infra/salt/salt/traffic_server/init.sls +++ b/infra/salt/salt/traffic_server/init.sls @@ -8,7 +8,7 @@ disk_create_traffic_serer: disk_mount_traffic_server: file.directory: - name: /mnt/trafficserver - + - makedirs: True mount.mounted: - name: /mnt/trafficserver - device: {{ device }} @@ -26,31 +26,23 @@ create_trafficserver_user: create_mnt_db_trafficserver: file.directory: - - name: /mnt/trafficserver/db - - user: trafficserver - - group: trafficserver - - mode: 700 - - makedirs: True - {%- if grains['volumes']['ats']['mount'] %} - - require: - - mount: disk_mount_traffic_server - {% endif %} - -create_var_log_trafficserver: - file.directory: - - name: /var/log/trafficserver + - names: + - /mnt/trafficserver/db + - /var/log/trafficserver + - /run/trafficserver - user: trafficserver - group: trafficserver - mode: 700 - makedirs: True - {%- if grains['volumes']['ats']['mount'] %} - require: + - user: create_trafficserver_user + {%- if grains['volumes']['ats']['mount'] %} - mount: disk_mount_traffic_server - {% endif %} + {%- endif %} push_trafficserver_service: file.managed: - - name: /lib/systemd/system/trafficserver.service + - name: /etc/systemd/system/trafficserver.service - source: salt://traffic_server/files/trafficserver.service - template: jinja - onchanges: @@ -62,7 +54,6 @@ start_trafficserver_service: - require: - file: create_mnt_db_trafficserver - file: push_trafficserver_service - - file: create_var_log_trafficserver - onchanges: - file: push_trafficserver_service @@ -70,10 +61,14 @@ push_etc_trafficserver_static: file.recurse: - name: /etc/trafficserver/ - source: salt://traffic_server/files/etc/static/ + - user: trafficserver + - group: trafficserver - file_mode: 644 - dir_mode: 755 # Keep other files, since we'll also be writing files in push_etc_trafficserver_dynamic - clean: False + - require: + - user: create_trafficserver_user push_etc_trafficserver_dynamic: file.managed: @@ -82,21 +77,42 @@ push_etc_trafficserver_dynamic: - source: salt://traffic_server/files/etc/dynamic/records.config.j2 - /etc/trafficserver/remap.config: - source: salt://traffic_server/files/etc/dynamic/remap.config.j2 - - /etc/trafficserver/s3_auth_v4.config: - - source: salt://traffic_server/files/etc/dynamic/s3_auth_v4.config.j2 - - /etc/trafficserver/s3_region_map.config: - - source: salt://traffic_server/files/etc/dynamic/s3_region_map.config.j2 - - /etc/trafficserver/stored.config: + - /etc/trafficserver/storage.config: - source: salt://traffic_server/files/etc/dynamic/storage.config.j2 + - user: trafficserver + - group: trafficserver - mode: 644 - template: jinja - context: nebula_ipv4: {{ grains['nebula']['ipv4'] }} - s3_endpoint: {{ pillar['s3']['config']['default']['endpoint_internal'] }} - s3_region: {{ pillar['s3']['config']['default']['region'] }} - s3_access_key_id: {{ pillar['s3']['access']['default']['persistent_access_key_id'] }} - s3_secret_access_key: {{ pillar['s3']['access']['default']['persistent_access_key_secret'] }} + s3_providers: {{ pillar['s3']['config'] }} volume_size_cache: {{ grains['volumes']['ats']['size']|int - 1 }}G + - require: + - file: push_etc_trafficserver_static + - user: create_trafficserver_user + +{%- for provider, _ in pillar['s3']['config'].items() %} +push_etc_trafficserver_dynamic_{{provider}}: + file.managed: + - names: + - /etc/trafficserver/s3_auth_v4_{{provider}}.config: + - source: salt://traffic_server/files/etc/dynamic/s3_auth_v4.config.j2 + - /etc/trafficserver/s3_region_map_{{provider}}.config: + - source: salt://traffic_server/files/etc/dynamic/s3_region_map.config.j2 + - user: trafficserver + - group: trafficserver + - mode: 644 + - template: jinja + - context: + s3_endpoint: {{ pillar['s3']['config'][provider]['endpoint_internal'] }} + s3_region: {{ pillar['s3']['config'][provider]['region'] }} + s3_access_key_id: {{ pillar['s3']['access'][provider]['persistent_access_key_id'] }} + s3_secret_access_key: {{ pillar['s3']['access'][provider]['persistent_access_key_secret'] }} + s3_region_map_file_name: s3_region_map_{{provider}} + - require: + - file: push_etc_trafficserver_static + - user: create_trafficserver_user +{%- endfor %} reload_traffic_server_config: cmd.run: @@ -105,9 +121,15 @@ reload_traffic_server_config: - cmd: start_trafficserver_service - file: push_etc_trafficserver_static - file: push_etc_trafficserver_dynamic + {%- for provider, _ in pillar['s3']['config'].items() %} + - push_etc_trafficserver_dynamic_{{provider}} + {%- endfor %} - onchanges: - file: push_etc_trafficserver_static - file: push_etc_trafficserver_dynamic + {%- for provider, _ in pillar['s3']['config'].items() %} + - push_etc_trafficserver_dynamic_{{provider}} + {%- endfor %} push_etc_consul_traffic_server_hcl: file.managed: @@ -118,6 +140,7 @@ push_etc_consul_traffic_server_hcl: namespace: {{ pillar['rivet']['namespace'] }} domain: {{ pillar['rivet']['domain'] }} nebula_ipv4: {{ grains['nebula']['ipv4'] }} + s3_providers: {{ pillar['s3']['config'] }} - require: - file: create_etc_consul cmd.run: diff --git a/infra/tests/standalone/main.tf b/infra/tests/standalone/main.tf index 953cac3c70..25906539a4 100644 --- a/infra/tests/standalone/main.tf +++ b/infra/tests/standalone/main.tf @@ -43,19 +43,21 @@ module "server" { inbound_ipv4_cidr = ["0.0.0.0/0"] inbound_ipv6_cidr = ["::/0"] }, + + # TODO: Nebula IPv6 is theoretically supported (https://nebula.defined.net/docs/config/preferred-ranges/#how-nebula-orders-underlay-ip-addresses-it-learns-about), but seems to be problematic { label = "nebula-udp" ports = "4242" protocol = "udp" inbound_ipv4_cidr = ["0.0.0.0/0"] - inbound_ipv6_cidr = ["::/0"] + inbound_ipv6_cidr = [] }, { label = "nebula-tcp" ports = "4242" protocol = "tcp" inbound_ipv4_cidr = ["0.0.0.0/0"] - inbound_ipv6_cidr = ["::/0"] + inbound_ipv6_cidr = [] }, ] } diff --git a/infra/tests/stress-param/job-param.nomad b/infra/tests/stress-param/job-param.nomad index 3701abf2ec..ac234ff8b4 100644 --- a/infra/tests/stress-param/job-param.nomad +++ b/infra/tests/stress-param/job-param.nomad @@ -45,7 +45,7 @@ job "test-param" { } artifact { - source = "https://assets.rivet.gg/graphics/landing.png" + source = "https://assets2.rivet.gg/graphics/landing.png" destination = "local/landing.png" } diff --git a/infra/tf/cloudflare_workers/main.tf b/infra/tf/cloudflare_workers/main.tf index 53848a6384..ac7b062ae0 100644 --- a/infra/tf/cloudflare_workers/main.tf +++ b/infra/tf/cloudflare_workers/main.tf @@ -15,12 +15,11 @@ module "secrets" { locals { cf_request_meta_routes = toset([ - "matchmaker.api.${var.domain_main}/v1/lobbies/list", + "matchmaker.api.${var.domain_main}/v1/lobbies/create", + "matchmaker.api.${var.domain_main}/v1/lobbies/find", "matchmaker.api.${var.domain_main}/v1/lobbies/join", + "matchmaker.api.${var.domain_main}/v1/lobbies/list", "matchmaker.api.${var.domain_main}/v1/regions", - "matchmaker.api.${var.domain_main}/v1/lobbies/find", - "party.api.${var.domain_main}/v1/parties/self/activity/matchmaker/lobbies/find", - "party.api.${var.domain_main}/v1/parties/self/activity/matchmaker/lobbies/join", ]) } diff --git a/infra/tf/master_cluster/nebula_lighthouse.tf b/infra/tf/master_cluster/nebula_lighthouse.tf index f65205bde6..5c5e988f99 100644 --- a/infra/tf/master_cluster/nebula_lighthouse.tf +++ b/infra/tf/master_cluster/nebula_lighthouse.tf @@ -25,20 +25,21 @@ module "nebula_lighthouse_server" { ] backup = true + # Nebula does not support IPv6 firewall_inbound = [ { label = "nebula-udp" ports = "4242" protocol = "udp" inbound_ipv4_cidr = ["0.0.0.0/0"] - inbound_ipv6_cidr = ["::/0"] + inbound_ipv6_cidr = [] }, { label = "nebula-tcp" ports = "4242" protocol = "tcp" inbound_ipv4_cidr = ["0.0.0.0/0"] - inbound_ipv6_cidr = ["::/0"] + inbound_ipv6_cidr = [] }, ] } diff --git a/infra/tf/modules/install_nebula/main.tf b/infra/tf/modules/install_nebula/main.tf index ad22969d6f..0066351257 100644 --- a/infra/tf/modules/install_nebula/main.tf +++ b/infra/tf/modules/install_nebula/main.tf @@ -18,6 +18,16 @@ locals { lighthouse = { am_lighthouse = var.is_lighthouse hosts = var.is_lighthouse ? null : sort(var.lighthouse_hosts) + + # Disable IPv6 + remote_allow_list = { + "0.0.0.0/0" = true + "::/0" = false + } + local_allow_list = { + "0.0.0.0/0" = true + "::/0" = false + } } listen = { host = "0.0.0.0" diff --git a/infra/tf/modules/secrets/main.tf b/infra/tf/modules/secrets/main.tf index 6fbccc4dec..4124127005 100644 --- a/infra/tf/modules/secrets/main.tf +++ b/infra/tf/modules/secrets/main.tf @@ -10,6 +10,6 @@ terraform { data "external" "bolt_secret" { for_each = var.keys - program = var.optional ? ["bolt", "secret", "get", "--format=json", "--optional", each.key] : ["bolt", "secret", "get", "--format=json", each.key] + program = ["${path.module}/scripts/get_secret.sh", each.key, var.optional ? "true" : "false"] } diff --git a/infra/tf/modules/secrets/scripts/get_secret.sh b/infra/tf/modules/secrets/scripts/get_secret.sh new file mode 100755 index 0000000000..7558d481ff --- /dev/null +++ b/infra/tf/modules/secrets/scripts/get_secret.sh @@ -0,0 +1,14 @@ +#!/usr/bin/env bash +set -euf + +export BOLT_HEADLESS=1 + +KEY="$1" +OPTIONAL="$2" + +if [ "$OPTIONAL" == "true" ]; then + bolt secret get --format=json --optional "$KEY" +else + bolt secret get --format=json "$KEY" +fi + diff --git a/infra/tf/nomad/files/imagor/imagor.nomad.tpl b/infra/tf/nomad/files/imagor/imagor.nomad.tpl index 2ce0c2dcc8..461582a088 100644 --- a/infra/tf/nomad/files/imagor/imagor.nomad.tpl +++ b/infra/tf/nomad/files/imagor/imagor.nomad.tpl @@ -75,14 +75,41 @@ job "imagor:${dc}" { "${prefix}.http.middlewares.imagor-cdn-cache-control.headers.customResponseHeaders.Cache-Control=public, max-age=604800, immutable", # "${prefix}.http.middlewares.imagor-cdn-cache-control.headers.customResponseHeaders.Vary=Accept", + # Individual S3 providers + %{ for preset in imagor_presets } + %{ for provider in s3_providers } + # routers.imagor-${provider}-${preset.key} + "${prefix}.http.routers.imagor-${provider}-${preset.key}.entrypoints=lb-443", + "${prefix}.http.routers.imagor-${provider}-${preset.key}.priority=${preset.priority}", + %{ if preset.query != null } + "${prefix}.http.routers.imagor-${provider}-${preset.key}.rule=HostRegexp(`media.${shared.domain.base}`, `media.{region:.+}.${shared.domain.base}`) && Path(`/${provider}${preset.path}`) && Query(%{ for x in preset.query }`${x[0]}=${x[1]}`,%{ endfor })", + %{ else } + "${prefix}.http.routers.imagor-${provider}-${preset.key}.rule=HostRegexp(`media.${shared.domain.base}`, `media.{region:.+}.${shared.domain.base}`) && Path(`/${provider}${preset.path}`)", + %{ endif } + + %{ if preset.game_cors } + "${prefix}.http.routers.imagor-${provider}-${preset.key}.middlewares=imagor-${provider}-${preset.key}-path, imagor-cors-game, imagor-cdn", + %{ else } + "${prefix}.http.routers.imagor-${provider}-${preset.key}.middlewares=imagor-${provider}-${preset.key}-path, imagor-cors, imagor-cdn", + %{ endif } + "${prefix}.http.routers.imagor-${provider}-${preset.key}.tls=true", + + # middlewares.imagor-${provider}-${preset.key}-path + "${prefix}.http.middlewares.imagor-${provider}-${preset.key}-path.replacePathRegex.regex=/${provider}${preset.path_regexp}", + # Escape replacement and replace `s3-cache/` with `s3-cache/{provider}/` + "${prefix}.http.middlewares.imagor-${provider}-${preset.key}-path.replacePathRegex.replacement=${replace(replace(preset.path_regex_replacement, "$${", "$$${"), "s3-cache%2F", "s3-cache%2F${provider}%2F")}", + %{ endfor } + %{ endfor } + + # Default S3 provider %{ for preset in imagor_presets } # routers.imagor-${preset.key} "${prefix}.http.routers.imagor-${preset.key}.entrypoints=lb-443", "${prefix}.http.routers.imagor-${preset.key}.priority=${preset.priority}", %{ if preset.query != null } - "${prefix}.http.routers.imagor-${preset.key}.rule=(Host(`media.${shared.domain.base}`) || HostRegexp(`media.{region:.+}.${shared.domain.base}`)) && Path(`${preset.path}`) && Query(%{ for x in preset.query }`${x[0]}=${x[1]}`,%{ endfor })", + "${prefix}.http.routers.imagor-${preset.key}.rule=HostRegexp(`media.${shared.domain.base}`, `media.{region:.+}.${shared.domain.base}`) && Path(`${preset.path}`) && Query(%{ for x in preset.query }`${x[0]}=${x[1]}`,%{ endfor })", %{ else } - "${prefix}.http.routers.imagor-${preset.key}.rule=(Host(`media.${shared.domain.base}`) || HostRegexp(`media.{region:.+}.${shared.domain.base}`)) && Path(`${preset.path}`)", + "${prefix}.http.routers.imagor-${preset.key}.rule=HostRegexp(`media.${shared.domain.base}`, `media.{region:.+}.${shared.domain.base}`) && Path(`${preset.path}`)", %{ endif } %{ if preset.game_cors } "${prefix}.http.routers.imagor-${preset.key}.middlewares=imagor-${preset.key}-path, imagor-cors-game, imagor-cdn", diff --git a/infra/tf/nomad/imagor.tf b/infra/tf/nomad/imagor.tf index 319863e5ec..16d969e2ee 100644 --- a/infra/tf/nomad/imagor.tf +++ b/infra/tf/nomad/imagor.tf @@ -31,5 +31,6 @@ resource "nomad_job" "imagor" { result_storage_s3_access_key_id = var.s3_persistent_access_key_id result_storage_s3_secret_access_key = nonsensitive(var.s3_persistent_access_key_secret) result_storage_s3_bucket = "${var.namespace}-bucket-imagor-result-storage" + s3_providers = var.s3_providers }) } diff --git a/infra/tf/nomad/vars.tf b/infra/tf/nomad/vars.tf index 48030d5035..e080e3dccb 100644 --- a/infra/tf/nomad/vars.tf +++ b/infra/tf/nomad/vars.tf @@ -67,3 +67,6 @@ variable "s3_persistent_access_key_secret" { sensitive = true } +variable "s3_providers" { + type = list(string) +} diff --git a/infra/tf/s3_backblaze/buckets.tf b/infra/tf/s3_backblaze/buckets.tf index 3e9a69c8b2..366bcac749 100644 --- a/infra/tf/s3_backblaze/buckets.tf +++ b/infra/tf/s3_backblaze/buckets.tf @@ -1,6 +1,11 @@ resource "b2_bucket" "bucket" { for_each = var.s3_buckets + lifecycle { + # TODO: Remove this. Fixes an issue with accidentally enabled file locks that can't be disabled. + ignore_changes = ["file_lock_configuration"] + } + bucket_name = each.key bucket_type = "allPrivate" diff --git a/lib/api-helper/build/Cargo.toml b/lib/api-helper/build/Cargo.toml index 48b3040eda..36a4cf56f9 100644 --- a/lib/api-helper/build/Cargo.toml +++ b/lib/api-helper/build/Cargo.toml @@ -37,7 +37,7 @@ serde = { version = "1.0", features = ["derive"] } serde_array_query = { git = "https://github.com/rivet-gg/serde_array_query.git", rev = "b9f8bfad77aea6f01dccc6cb77146b8c5daecaa3" } serde_json = "1.0" thiserror = "1.0" -tokio = { version = "1.21" } +tokio = { version = "1.29" } tracing = "0.1" tracing-subscriber = { version = "0.3", default-features = false, features = ["fmt", "json", "ansi"] } types = { path = "../../types/core" } diff --git a/lib/api-helper/build/src/start.rs b/lib/api-helper/build/src/start.rs index 67c32b0d0e..6c9d67bbee 100644 --- a/lib/api-helper/build/src/start.rs +++ b/lib/api-helper/build/src/start.rs @@ -5,6 +5,8 @@ use hyper::{ Body, Request, Response, Server, }; use std::{convert::Infallible, future::Future, net::SocketAddr, sync::Arc, time::Instant}; +use tokio::sync::Semaphore; +use tokio::time::{sleep, Duration}; use tracing::Instrument; use uuid::Uuid; @@ -66,9 +68,13 @@ where .and_then(|v| v.parse::().ok()) .unwrap(); + // let semaphore = Arc::new(Semaphore::new(8)); + // A `MakeService` that produces a `Service` to handle each connection let health_check_config = Arc::new(health_check_config); let make_service = make_service_fn(move |conn: &AddrStream| { + // let semaphore = semaphore.clone(); + let shared_client = shared_client.clone(); let pools = pools.clone(); let cache = cache.clone(); @@ -79,6 +85,8 @@ where let service = service_fn(move |req: Request| { let start = Instant::now(); + // let semaphore = semaphore.clone(); + let shared_client = shared_client.clone(); let pools = pools.clone(); let cache = cache.clone(); @@ -88,28 +96,71 @@ where let ray_id = Uuid::new_v4(); let req_span = tracing::info_span!("http request", method = %req.method(), uri = %req.uri(), %ray_id); async move { + let sem_start = Instant::now(); + // let _semaphor_acquire = semaphore.acquire().await.unwrap(); + // let semaphor_duration = sem_start.elapsed(); + tracing::info!( method = %req.method(), uri = %req.uri(), headers = ?req.headers(), body_size_hint = ?req.body().size_hint(), remote_addr = %remote_addr, + // semaphor_duration = ?semaphor_duration, "http request meta" ); - let res: Response = - match rivet_health_checks::handle(&*health_check_config, req).await { - Ok(res) => res, - Err(req) => { - let mut response = handle(shared_client, pools, cache, ray_id, req) - .instrument(tracing::info_span!("request_handle")) - .await?; - response - .headers_mut() - .insert("rvt-ray-id", ray_id.to_string().parse()?); - response + let res = tokio::task::Builder::new() + .name("api_helper::handle") + .spawn(async move { + // let res = Response::builder() + // .status(http::StatusCode::OK) + // .body(Body::from("ok"))?; + + let res = match rivet_health_checks::handle(&*health_check_config, req) + .await + { + Ok(res) => res, + Err(req) => { + // Response::builder() + // .status(http::StatusCode::OK) + // .body(Body::from("ok"))? + + let mut response = handle(shared_client, pools, cache, ray_id, req) + .instrument(tracing::info_span!("request_handle")) + .await?; + response + .headers_mut() + .insert("rvt-ray-id", ray_id.to_string().parse()?); + response + } + }; + + Result::, http::Error>::Ok(res) + }); + let res = match res { + Ok(res) => match res.await { + Ok(res) => match res { + Ok(res) => res, + Err(err) => { + tracing::error!(?err, "http error"); + return Err(err); + } + }, + Err(_) => { + tracing::error!("http error"); + return Ok(Response::builder() + .status(http::StatusCode::INTERNAL_SERVER_ERROR) + .body(Body::empty())?); } - }; + }, + Err(err) => { + tracing::error!(?err, "http error"); + return Ok(Response::builder() + .status(http::StatusCode::INTERNAL_SERVER_ERROR) + .body(Body::empty())?); + } + }; if res.status().is_server_error() { tracing::error!(status = ?res.status().as_u16(), "http server error"); diff --git a/lib/bolt/Cargo.lock b/lib/bolt/Cargo.lock index c78a3a3d18..714e80490e 100644 --- a/lib/bolt/Cargo.lock +++ b/lib/bolt/Cargo.lock @@ -2,6 +2,21 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "addr2line" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + [[package]] name = "ahash" version = "0.7.6" @@ -15,9 +30,9 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "1.0.2" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43f6cb1bf222025340178f382c426f13757b2960e89779dfcb319c32542a5a41" +checksum = "6748e8def348ed4d14996fa801f4122cd763fff530258cdc03f64b25f89d3a5a" dependencies = [ "memchr", ] @@ -39,24 +54,23 @@ dependencies = [ [[package]] name = "anstream" -version = "0.3.2" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ca84f3628370c59db74ee214b3263d58f9aadd9b4fe7e711fd87dc452b7f163" +checksum = "b1f58811cfac344940f1a400b6e6231ce35171f614f26439e80f8c1465c5cc0c" dependencies = [ "anstyle", "anstyle-parse", "anstyle-query", "anstyle-wincon", "colorchoice", - "is-terminal", "utf8parse", ] [[package]] name = "anstyle" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a30da5c5f2d5e72842e00bcb57657162cdabef0931f40e2deb9b4140440cecd" +checksum = "15c4c2c83f81532e5845a733998b6971faca23490340a418e9b72a3ec9de12ea" [[package]] name = "anstyle-parse" @@ -78,9 +92,9 @@ dependencies = [ [[package]] name = "anstyle-wincon" -version = "1.0.1" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "180abfa45703aebe0093f79badacc01b8fd4ea2e35118747e5811127f926e188" +checksum = "58f54d10c6dfa51283a066ceab3ec1ab78d13fae00aa49243a45e4571fb79dfd" dependencies = [ "anstyle", "windows-sys 0.48.0", @@ -88,9 +102,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.71" +version = "1.0.75" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8" +checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" [[package]] name = "async-posthog" @@ -118,13 +132,13 @@ dependencies = [ [[package]] name = "async-trait" -version = "0.1.68" +version = "0.1.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9ccdd8f2a161be9bd5c023df56f1b2a0bd1d83872ae53b71a84a12c9bf6e842" +checksum = "bc00ceb34980c03614e35a3a4e218276a0a824e911d07651cd0d858a51e8c0f0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.29", ] [[package]] @@ -186,7 +200,7 @@ dependencies = [ "aws-types", "bytes", "bytes-utils", - "fastrand", + "fastrand 1.9.0", "http", "http-body", "tokio-stream", @@ -225,7 +239,7 @@ dependencies = [ "percent-encoding", "regex", "sha2", - "time 0.3.22", + "time 0.3.28", "tracing", ] @@ -285,7 +299,7 @@ dependencies = [ "aws-smithy-http-tower 0.41.0", "aws-smithy-types 0.41.0", "bytes", - "fastrand", + "fastrand 1.9.0", "http", "http-body", "pin-project", @@ -306,7 +320,7 @@ dependencies = [ "aws-smithy-http-tower 0.52.0", "aws-smithy-types 0.52.0", "bytes", - "fastrand", + "fastrand 1.9.0", "http", "http-body", "hyper", @@ -411,7 +425,7 @@ dependencies = [ "itoa", "num-integer", "ryu", - "time 0.3.22", + "time 0.3.28", ] [[package]] @@ -424,7 +438,7 @@ dependencies = [ "itoa", "num-integer", "ryu", - "time 0.3.22", + "time 0.3.28", ] [[package]] @@ -452,6 +466,21 @@ dependencies = [ "zeroize", ] +[[package]] +name = "backtrace" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + [[package]] name = "base64" version = "0.13.1" @@ -460,9 +489,9 @@ checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" [[package]] name = "base64" -version = "0.21.2" +version = "0.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "604178f6c5c21f02dc555784810edfb88d34ac2c73b2eae109655649ee73ce3d" +checksum = "414dcefbc63d77c526a76b3afcf6fbb9b5e2791c19c3aa2297733208750c6e53" [[package]] name = "base64-simd" @@ -491,6 +520,12 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "bitflags" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" + [[package]] name = "block-buffer" version = "0.10.4" @@ -531,7 +566,9 @@ dependencies = [ "heck 0.3.3", "serde", "serde_json", - "toml 0.7.4", + "strum", + "strum_macros", + "toml 0.7.6", "uuid", ] @@ -568,7 +605,7 @@ dependencies = [ "tempfile", "thiserror", "tokio", - "toml 0.7.4", + "toml 0.7.6", "toml_edit", "types", "url", @@ -613,9 +650,12 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.79" +version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +dependencies = [ + "libc", +] [[package]] name = "cfg-if" @@ -658,9 +698,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.3.5" +version = "4.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2686c4115cb0810d9a984776e197823d08ec94f176549a89a9efded477c456dc" +checksum = "7c8d502cbaec4595d2e7d5f61e318f05417bd2b66fdc3809498f0d3fdf0bea27" dependencies = [ "clap_builder", "clap_derive", @@ -669,34 +709,33 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.3.5" +version = "4.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e53afce1efce6ed1f633cf0e57612fe51db54a1ee4fd8f8503d078fe02d69ae" +checksum = "5891c7bc0edb3e1c2204fc5e94009affabeb1821c9e5fdc3959536c5c0bb984d" dependencies = [ "anstream", "anstyle", - "bitflags", "clap_lex", "strsim", ] [[package]] name = "clap_derive" -version = "4.3.2" +version = "4.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8cd2b2a819ad6eec39e8f1d6b53001af1e5469f8c177579cdaeb313115b825f" +checksum = "c9fd1a5729c4548118d7d70ff234a44868d00489a4b6597b0b020918a0e91a1a" dependencies = [ "heck 0.4.1", "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.29", ] [[package]] name = "clap_lex" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2da6da31387c7e4ef160ffab6d5e7f00c42626fe39aea70a7b0f1773f7dd6c1b" +checksum = "cd7cc57abe963c6d3b9d8be5b06ba7c8957a930305ca90304f24ef040aa6f961" [[package]] name = "colorchoice" @@ -735,18 +774,18 @@ checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" [[package]] name = "cpufeatures" -version = "0.2.8" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03e69e28e9f7f77debdedbaafa2866e1de9ba56df55a8bd7cfc724c25a09987c" +checksum = "a17b76ff3a4162b0b27f354a0c87015ddad39d35f9c0c36607a3bdd175dde1f1" dependencies = [ "libc", ] [[package]] name = "crc32c" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dfea2db42e9927a3845fb268a10a72faed6d416065f77873f05e411457c363e" +checksum = "d8f48d60e5b4d2c53d5c2b1d8a58c849a70ae5e5509b08a48d047e3b65714a74" dependencies = [ "rustc_version", ] @@ -805,6 +844,12 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "deranged" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2696e8a945f658fd14dc3b87242e6b80cd0f36ff04ea560fa39082368847946" + [[package]] name = "derive_builder" version = "0.12.0" @@ -861,9 +906,9 @@ dependencies = [ [[package]] name = "either" -version = "1.8.1" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" +checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" [[package]] name = "encode_unicode" @@ -873,18 +918,24 @@ checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" [[package]] name = "encoding_rs" -version = "0.8.32" +version = "0.8.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071a31f4ee85403370b58aca746f01041ede6f0da2730960ad001edc2b71b394" +checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" dependencies = [ "cfg-if", ] +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + [[package]] name = "errno" -version = "0.3.1" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" +checksum = "136526188508e25c6fef639d7927dfb3e0e3084488bf202267829cf7fc23dbdd" dependencies = [ "errno-dragonfly", "libc", @@ -910,6 +961,12 @@ dependencies = [ "instant", ] +[[package]] +name = "fastrand" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6999dc1837253364c2ebb0704ba97994bd874e8f195d665c50b7548f6ea92764" + [[package]] name = "fixedbitset" version = "0.4.2" @@ -951,7 +1008,7 @@ name = "formatted-error" version = "0.1.0" dependencies = [ "gray_matter", - "hashbrown", + "hashbrown 0.12.3", "http", "indoc", "lazy_static", @@ -981,7 +1038,7 @@ checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" dependencies = [ "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.29", ] [[package]] @@ -1031,6 +1088,12 @@ dependencies = [ "wasi 0.11.0+wasi-snapshot-preview1", ] +[[package]] +name = "gimli" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" + [[package]] name = "global-error" version = "0.1.5" @@ -1057,9 +1120,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.3.19" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d357c7ae988e7d2182f7d7871d0b963962420b0678b0997ce7de72001aeab782" +checksum = "91fc23aa11be92976ef4729127f1a74adf36d8436f7816b185d18df956790833" dependencies = [ "bytes", "fnv", @@ -1067,7 +1130,7 @@ dependencies = [ "futures-sink", "futures-util", "http", - "indexmap", + "indexmap 1.9.3", "slab", "tokio", "tokio-util", @@ -1097,6 +1160,12 @@ dependencies = [ "ahash", ] +[[package]] +name = "hashbrown" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" + [[package]] name = "heck" version = "0.3.3" @@ -1114,18 +1183,9 @@ checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" [[package]] name = "hermit-abi" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" -dependencies = [ - "libc", -] - -[[package]] -name = "hermit-abi" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" +checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b" [[package]] name = "hex" @@ -1172,15 +1232,15 @@ checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" [[package]] name = "httpdate" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" [[package]] name = "hyper" -version = "0.14.26" +version = "0.14.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab302d72a6f11a3b910431ff93aae7e773078c769f0a3ef15fb9ec692ed147d4" +checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468" dependencies = [ "bytes", "futures-channel", @@ -1193,7 +1253,7 @@ dependencies = [ "httpdate", "itoa", "pin-project-lite", - "socket2", + "socket2 0.4.9", "tokio", "tower-service", "tracing", @@ -1209,22 +1269,23 @@ dependencies = [ "http", "hyper", "log", - "rustls 0.20.8", + "rustls 0.20.9", "rustls-native-certs", "tokio", "tokio-rustls 0.23.4", - "webpki-roots", + "webpki-roots 0.22.6", ] [[package]] name = "hyper-rustls" -version = "0.24.0" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0646026eb1b3eea4cd9ba47912ea5ce9cc07713d105b1a14698f4e6433d348b7" +checksum = "8d78e1e73ec14cf7375674f74d7dde185c8206fd9dea6fb6295e8a98098aaa97" dependencies = [ + "futures-util", "http", "hyper", - "rustls 0.21.2", + "rustls 0.21.7", "tokio", "tokio-rustls 0.24.1", ] @@ -1288,7 +1349,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" dependencies = [ "autocfg", - "hashbrown", + "hashbrown 0.12.3", +] + +[[package]] +name = "indexmap" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d" +dependencies = [ + "equivalent", + "hashbrown 0.14.0", ] [[package]] @@ -1327,38 +1398,15 @@ dependencies = [ "cfg-if", ] -[[package]] -name = "io-lifetimes" -version = "1.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" -dependencies = [ - "hermit-abi 0.3.1", - "libc", - "windows-sys 0.48.0", -] - [[package]] name = "ipnet" -version = "2.7.2" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12b6ee2129af8d4fb011108c73d99a1b83a85977f23b82460c0ae2e25bb4b57f" +checksum = "28b29a3cd74f0f4598934efe3aeba42bae0eb4680554128851ebbecb02af14e6" dependencies = [ "serde", ] -[[package]] -name = "is-terminal" -version = "0.4.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adcf93614601c8129ddf72e2d5633df827ba6551541c6d8c59520a371475be1f" -dependencies = [ - "hermit-abi 0.3.1", - "io-lifetimes", - "rustix", - "windows-sys 0.48.0", -] - [[package]] name = "itertools" version = "0.10.5" @@ -1370,9 +1418,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.6" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" +checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" [[package]] name = "js-sys" @@ -1391,9 +1439,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.146" +version = "0.2.147" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f92be4933c13fd498862a9e02a3055f8a8d9c039ce33db97306fd5a6caa7f29b" +checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" [[package]] name = "linked-hash-map" @@ -1403,9 +1451,9 @@ checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" [[package]] name = "linux-raw-sys" -version = "0.3.8" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" +checksum = "57bcfdad1b858c2db7c38303a6d2ad4dfaf5eb53dfeb0910128b2c26d6158503" [[package]] name = "lock_api" @@ -1419,9 +1467,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.19" +version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4" +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" [[package]] name = "maplit" @@ -1440,9 +1488,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.5.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" +checksum = "76fc44e2588d5b436dbc3c6cf62aef290f90dab6235744a93dfe1cc18f451e2c" [[package]] name = "mime" @@ -1450,6 +1498,15 @@ version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" +[[package]] +name = "miniz_oxide" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +dependencies = [ + "adler", +] + [[package]] name = "mio" version = "0.8.8" @@ -1497,20 +1554,20 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" +checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2" dependencies = [ "autocfg", ] [[package]] name = "num_cpus" -version = "1.15.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" dependencies = [ - "hermit-abi 0.2.6", + "hermit-abi", "libc", ] @@ -1520,6 +1577,15 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" +[[package]] +name = "object" +version = "0.32.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ac5bbd07aea88c60a577a1ce218075ffd59208b2d7ca97adf9bfc5aeb21ebe" +dependencies = [ + "memchr", +] + [[package]] name = "once_cell" version = "1.18.0" @@ -1528,11 +1594,11 @@ checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" [[package]] name = "openssl" -version = "0.10.55" +version = "0.10.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "345df152bc43501c5eb9e4654ff05f794effb78d4efe3d53abc158baddc0703d" +checksum = "bac25ee399abb46215765b1cb35bc0212377e58a061560d8b29b024fd0430e7c" dependencies = [ - "bitflags", + "bitflags 2.4.0", "cfg-if", "foreign-types", "libc", @@ -1549,7 +1615,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.29", ] [[package]] @@ -1560,9 +1626,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" -version = "0.9.90" +version = "0.9.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "374533b0e45f3a7ced10fcaeccca020e66656bc03dac384f852e4e5a7a8104a6" +checksum = "db7e971c2c2bba161b2d2fdf37080177eff520b3bc044787c7f1f5f9e78d869b" dependencies = [ "cc", "libc", @@ -1617,7 +1683,7 @@ dependencies = [ "libc", "redox_syscall", "smallvec", - "windows-targets 0.48.0", + "windows-targets 0.48.5", ] [[package]] @@ -1628,9 +1694,9 @@ checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" [[package]] name = "pest" -version = "2.6.1" +version = "2.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16833386b02953ca926d19f64af613b9bf742c48dcd5e09b32fbfc9740bf84e2" +checksum = "1acb4a4365a13f749a93f1a094a7805e5cfa0955373a9de860d962eaa3a5fe5a" dependencies = [ "thiserror", "ucd-trie", @@ -1638,9 +1704,9 @@ dependencies = [ [[package]] name = "pest_derive" -version = "2.6.1" +version = "2.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7763190f9406839f99e5197afee8c9e759969f7dbfa40ad3b8dbee8757b745b5" +checksum = "666d00490d4ac815001da55838c500eafb0320019bbaa44444137c48b443a853" dependencies = [ "pest", "pest_generator", @@ -1648,22 +1714,22 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.6.1" +version = "2.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "249061b22e99973da1f5f5f1410284419e283bb60b79255bf5f42a94b66a2e00" +checksum = "68ca01446f50dbda87c1786af8770d535423fa8a53aec03b8f4e3d7eb10e0929" dependencies = [ "pest", "pest_meta", "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.29", ] [[package]] name = "pest_meta" -version = "2.6.1" +version = "2.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "457c310cfc9cf3f22bc58901cc7f0d3410ac5d6298e432a4f9a6138565cb6df6" +checksum = "56af0a30af74d0445c0bf6d9d051c979b516a1a5af790d251daee76005420a48" dependencies = [ "once_cell", "pest", @@ -1672,39 +1738,39 @@ dependencies = [ [[package]] name = "petgraph" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dd7d28ee937e54fe3080c91faa1c3a46c06de6252988a7f4592ba2310ef22a4" +checksum = "e1d3afd2628e69da2be385eb6f2fd57c8ac7977ceeff6dc166ff1657b0e386a9" dependencies = [ "fixedbitset", - "indexmap", + "indexmap 2.0.0", ] [[package]] name = "pin-project" -version = "1.1.0" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c95a7476719eab1e366eaf73d0260af3021184f18177925b07f54b30089ceead" +checksum = "fda4ed1c6c173e3fc7a83629421152e01d7b1f9b7f65fb301e490e8cfc656422" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.0" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39407670928234ebc5e6e580247dd567ad73a3578460c5990f9503df207e8f07" +checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" dependencies = [ "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.29", ] [[package]] name = "pin-project-lite" -version = "0.2.9" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" [[package]] name = "pin-utils" @@ -1780,9 +1846,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.60" +version = "1.0.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dec2b086b7a862cf4de201096214fa870344cf922b2b30c167badb3af3195406" +checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" dependencies = [ "unicode-ident", ] @@ -1876,9 +1942,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.28" +version = "1.0.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9ab9c7eadfd8df19006f1cf1a4aed13540ed5cbc047010ece5826e10825488" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" dependencies = [ "proc-macro2", ] @@ -1919,14 +1985,26 @@ version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" dependencies = [ - "bitflags", + "bitflags 1.3.2", ] [[package]] name = "regex" -version = "1.8.4" +version = "1.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12de2eff854e5fa4b1295edd650e227e9d8fb0c9e90b12e7f36d6a6811791a29" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0ab3ca65655bb1e41f2a8c8cd662eb4fb035e67c3f78da1d61dffe89d07300f" +checksum = "49530408a136e16e5b486e883fbb6ba058e8e4e8ae6621a77b048b314336e629" dependencies = [ "aho-corasick", "memchr", @@ -1935,17 +2013,17 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.7.2" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "436b050e76ed2903236f032a59761c1eb99e1b0aead2c257922771dab1fc8c78" +checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" [[package]] name = "reqwest" -version = "0.11.18" +version = "0.11.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cde824a14b7c14f85caff81225f411faacc04a2013f41670f41443742b1c1c55" +checksum = "3e9ad3fe7488d7e34558a2033d45a0c90b72d97b4f80705666fea71472e2e6a1" dependencies = [ - "base64 0.21.2", + "base64 0.21.3", "bytes", "encoding_rs", "futures-core", @@ -1954,7 +2032,7 @@ dependencies = [ "http", "http-body", "hyper", - "hyper-rustls 0.24.0", + "hyper-rustls 0.24.1", "hyper-tls", "ipnet", "js-sys", @@ -1964,7 +2042,7 @@ dependencies = [ "once_cell", "percent-encoding", "pin-project-lite", - "rustls 0.21.2", + "rustls 0.21.7", "rustls-pemfile", "serde", "serde_json", @@ -1977,7 +2055,7 @@ dependencies = [ "wasm-bindgen", "wasm-bindgen-futures", "web-sys", - "webpki-roots", + "webpki-roots 0.25.2", "winreg", ] @@ -2048,6 +2126,12 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "rustc-demangle" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" + [[package]] name = "rustc_version" version = "0.4.0" @@ -2059,13 +2143,12 @@ dependencies = [ [[package]] name = "rustix" -version = "0.37.20" +version = "0.38.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b96e891d04aa506a6d1f318d2771bcb1c7dfda84e126660ace067c9b474bb2c0" +checksum = "ed6248e1caa625eb708e266e06159f135e8c26f2bb7ceb72dc4b2766d0340964" dependencies = [ - "bitflags", + "bitflags 2.4.0", "errno", - "io-lifetimes", "libc", "linux-raw-sys", "windows-sys 0.48.0", @@ -2073,9 +2156,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.20.8" +version = "0.20.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fff78fc74d175294f4e83b28343315ffcfb114b156f0185e9741cb5570f50e2f" +checksum = "1b80e3dec595989ea8510028f30c408a4630db12c9cbb8de34203b89d6577e99" dependencies = [ "log", "ring", @@ -2085,9 +2168,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.21.2" +version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e32ca28af694bc1bbf399c33a516dbdf1c90090b8ab23c2bc24f834aa2247f5f" +checksum = "cd8d6c9f025a446bc4d18ad9632e69aec8f287aa84499ee335599fabd20c3fd8" dependencies = [ "log", "ring", @@ -2109,28 +2192,34 @@ dependencies = [ [[package]] name = "rustls-pemfile" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d194b56d58803a43635bdc398cd17e383d6f71f9182b9a192c127ca42494a59b" +checksum = "2d3987094b1d07b653b7dfdc3f70ce9a1da9c51ac18c1b06b662e4f9a0e9f4b2" dependencies = [ - "base64 0.21.2", + "base64 0.21.3", ] [[package]] name = "rustls-webpki" -version = "0.100.1" +version = "0.101.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6207cd5ed3d8dca7816f8f3725513a34609c0c765bf652b8c3cb4cfd87db46b" +checksum = "7d93931baf2d282fff8d3a532bbfd7653f734643161b87e3e01e59a04439bf0d" dependencies = [ "ring", "untrusted", ] +[[package]] +name = "rustversion" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" + [[package]] name = "ryu" -version = "1.0.13" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" +checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" [[package]] name = "s3-util" @@ -2148,11 +2237,11 @@ dependencies = [ [[package]] name = "schannel" -version = "0.1.21" +version = "0.1.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "713cfb06c7059f3588fb8044c0fad1d09e3c01d225e25b9220dbfdcf16dbb1b3" +checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88" dependencies = [ - "windows-sys 0.42.0", + "windows-sys 0.48.0", ] [[package]] @@ -2167,9 +2256,9 @@ dependencies = [ [[package]] name = "scopeguard" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "sct" @@ -2183,11 +2272,11 @@ dependencies = [ [[package]] name = "security-framework" -version = "2.9.1" +version = "2.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fc758eb7bffce5b308734e9b0c1468893cae9ff70ebf13e7090be8dcbcc83a8" +checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" dependencies = [ - "bitflags", + "bitflags 1.3.2", "core-foundation", "core-foundation-sys", "libc", @@ -2196,9 +2285,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.9.0" +version = "2.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f51d0c0d83bec45f16480d0ce0058397a69e48fcdc52d1dc8855fb68acbd31a7" +checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" dependencies = [ "core-foundation-sys", "libc", @@ -2206,35 +2295,35 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.17" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed" +checksum = "b0293b4b29daaf487284529cc2f5675b8e57c61f70167ba415a463651fd6a918" [[package]] name = "serde" -version = "1.0.164" +version = "1.0.188" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e8c8cf938e98f769bc164923b06dce91cea1751522f46f8466461af04c9027d" +checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.164" +version = "1.0.188" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9735b638ccc51c28bf6914d90a2e9725b377144fc612c49a611fddd1b631d68" +checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.29", ] [[package]] name = "serde_json" -version = "1.0.97" +version = "1.0.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdf3bf93142acad5821c99197022e170842cdbc1c30482b98750c688c640842a" +checksum = "693151e1ac27563d6dbcec9dee9fbd5da8539b20fa14ad3752b2e6d363ace360" dependencies = [ "itoa", "ryu", @@ -2243,9 +2332,9 @@ dependencies = [ [[package]] name = "serde_spanned" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93107647184f6027e3b7dcb2e11034cf95ffa1e3a682c67951963ac69c1c007d" +checksum = "96426c9936fd7a0124915f9185ea1d20aa9445cc9821142f0a73bc9207a2e186" dependencies = [ "serde", ] @@ -2314,18 +2403,18 @@ dependencies = [ [[package]] name = "slab" -version = "0.4.8" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" dependencies = [ "autocfg", ] [[package]] name = "smallvec" -version = "1.10.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" +checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9" [[package]] name = "socket2" @@ -2337,6 +2426,16 @@ dependencies = [ "winapi", ] +[[package]] +name = "socket2" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2538b18701741680e0322a2302176d3253a35388e2e62f172f64f4f16605f877" +dependencies = [ + "libc", + "windows-sys 0.48.0", +] + [[package]] name = "spin" version = "0.5.2" @@ -2349,6 +2448,25 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" +[[package]] +name = "strum" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290d54ea6f91c969195bdbcd7442c8c2a2ba87da8bf60a7ee86a235d4bc1e125" + +[[package]] +name = "strum_macros" +version = "0.25.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad8d03b598d3d0fff69bf533ee3ef19b8eeb342729596df84bcc7e1f96ec4059" +dependencies = [ + "heck 0.4.1", + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.29", +] + [[package]] name = "subtle" version = "2.5.0" @@ -2368,9 +2486,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.18" +version = "2.0.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32d41677bcbe24c20c52e7c70b0d8db04134c5d1066bf98662e2871ad200ea3e" +checksum = "c324c494eba9d92503e6f1ef2e6df781e78f6a7705a0202d9801b198807d518a" dependencies = [ "proc-macro2", "quote", @@ -2403,13 +2521,12 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.6.0" +version = "3.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31c0432476357e58790aaa47a8efb0c5138f137343f3b5f23bd36a27e3b0a6d6" +checksum = "cb94d2f3cc536af71caac6b6fcebf65860b347e7ce0cc9ebe8f70d3e521054ef" dependencies = [ - "autocfg", "cfg-if", - "fastrand", + "fastrand 2.0.0", "redox_syscall", "rustix", "windows-sys 0.48.0", @@ -2427,22 +2544,22 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.40" +version = "1.0.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac" +checksum = "97a802ec30afc17eee47b2855fc72e0c4cd62be9b4efe6591edde0ec5bd68d8f" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.40" +version = "1.0.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" +checksum = "6bb623b56e39ab7dcd4b1b98bb6c8f8d907ed255b18de254088016b27a8ee19b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.29", ] [[package]] @@ -2458,10 +2575,11 @@ dependencies = [ [[package]] name = "time" -version = "0.3.22" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea9e1b3cf1243ae005d9e74085d4d542f3125458f3a81af210d901dcd7411efd" +checksum = "17f6bb557fd245c28e6411aa56b6403c689ad95061f50e4be16c274e70a17e48" dependencies = [ + "deranged", "serde", "time-core", "time-macros", @@ -2475,9 +2593,9 @@ checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb" [[package]] name = "time-macros" -version = "0.2.9" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "372950940a5f07bf38dbe211d7283c9e6d7327df53794992d293e534c733d09b" +checksum = "1a942f44339478ef67935ab2bbaec2fb0322496cf3cbe84b261e06ac3814c572" dependencies = [ "time-core", ] @@ -2499,11 +2617,11 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.28.2" +version = "1.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94d7b1cfd2aa4011f2de74c2c4c63665e27a71006b0a192dcd2710272e73dfa2" +checksum = "17ed6077ed6cd6c74735e21f37eb16dc3935f96878b1fe961074089cc80893f9" dependencies = [ - "autocfg", + "backtrace", "bytes", "libc", "mio", @@ -2511,7 +2629,7 @@ dependencies = [ "parking_lot", "pin-project-lite", "signal-hook-registry", - "socket2", + "socket2 0.5.3", "tokio-macros", "windows-sys 0.48.0", ] @@ -2524,7 +2642,7 @@ checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.29", ] [[package]] @@ -2543,7 +2661,7 @@ version = "0.23.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c43ee83903113e03984cb9e5cebe6c04a5116269e900e3ddba8f068a62adda59" dependencies = [ - "rustls 0.20.8", + "rustls 0.20.9", "tokio", "webpki", ] @@ -2554,7 +2672,7 @@ version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" dependencies = [ - "rustls 0.21.2", + "rustls 0.21.7", "tokio", ] @@ -2594,9 +2712,9 @@ dependencies = [ [[package]] name = "toml" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6135d499e69981f9ff0ef2167955a5333c35e36f6937d382974566b3d5b94ec" +checksum = "c17e963a819c331dcacd7ab957d80bc2b9a9c1e71c804826d2f283dd65306542" dependencies = [ "serde", "serde_spanned", @@ -2606,20 +2724,20 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a76a9312f5ba4c2dec6b9161fdf25d87ad8a09256ccea5a556fef03c706a10f" +checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" dependencies = [ "serde", ] [[package]] name = "toml_edit" -version = "0.19.10" +version = "0.19.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2380d56e8670370eee6566b0bfd4265f65b3f432e8c6d85623f728d4fa31f739" +checksum = "f8123f27e969974a3dfba720fdb560be359f57b44302d280ba72e76a74480e8a" dependencies = [ - "indexmap", + "indexmap 2.0.0", "serde", "serde_spanned", "toml_datetime", @@ -2669,13 +2787,13 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.25" +version = "0.1.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8803eee176538f94ae9a14b55b2804eb7e1441f8210b1c31290b3bccdccff73b" +checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" dependencies = [ "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.29", ] [[package]] @@ -2725,14 +2843,14 @@ dependencies = [ "regex", "schemac", "serde", - "toml 0.7.4", + "toml 0.7.6", ] [[package]] name = "ucd-trie" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e79c4d996edb816c91e4308506774452e55e95c3c9de07b6729e17e15a5ef81" +checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" [[package]] name = "unicode-bidi" @@ -2742,9 +2860,9 @@ checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" [[package]] name = "unicode-ident" -version = "1.0.9" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b15811caf2415fb889178633e7724bad2509101cde276048e013b9def5e51fa0" +checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c" [[package]] name = "unicode-normalization" @@ -2775,9 +2893,9 @@ checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" [[package]] name = "url" -version = "2.4.0" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50bff7831e19200a85b17131d085c25d7811bc4e186efdaf54bbd132994a88cb" +checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5" dependencies = [ "form_urlencoded", "idna", @@ -2786,9 +2904,9 @@ dependencies = [ [[package]] name = "urlencoding" -version = "2.1.2" +version = "2.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8db7427f936968176eaa7cdf81b7f98b980b18495ec28f1b5791ac3bfe3eea9" +checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" [[package]] name = "utf8parse" @@ -2798,9 +2916,9 @@ checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" [[package]] name = "uuid" -version = "1.3.4" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa2982af2eec27de306107c027578ff7f423d65f7250e40ce0fea8f45248b81" +checksum = "79daa5ed5740825c40b389c5e50312b9c86df53fccd33f281df655642b43869d" dependencies = [ "getrandom", "serde", @@ -2860,7 +2978,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.29", "wasm-bindgen-shared", ] @@ -2894,7 +3012,7 @@ checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.29", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -2934,6 +3052,12 @@ dependencies = [ "webpki", ] +[[package]] +name = "webpki-roots" +version = "0.25.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14247bb57be4f377dfb94c72830b8ce8fc6beac03cf4bf7b9732eadd414123fc" + [[package]] name = "which" version = "4.4.0" @@ -2979,22 +3103,7 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" dependencies = [ - "windows-targets 0.48.0", -] - -[[package]] -name = "windows-sys" -version = "0.42.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" -dependencies = [ - "windows_aarch64_gnullvm 0.42.2", - "windows_aarch64_msvc 0.42.2", - "windows_i686_gnu 0.42.2", - "windows_i686_msvc 0.42.2", - "windows_x86_64_gnu 0.42.2", - "windows_x86_64_gnullvm 0.42.2", - "windows_x86_64_msvc 0.42.2", + "windows-targets 0.48.5", ] [[package]] @@ -3012,7 +3121,7 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ - "windows-targets 0.48.0", + "windows-targets 0.48.5", ] [[package]] @@ -3032,17 +3141,17 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" dependencies = [ - "windows_aarch64_gnullvm 0.48.0", - "windows_aarch64_msvc 0.48.0", - "windows_i686_gnu 0.48.0", - "windows_i686_msvc 0.48.0", - "windows_x86_64_gnu 0.48.0", - "windows_x86_64_gnullvm 0.48.0", - "windows_x86_64_msvc 0.48.0", + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", ] [[package]] @@ -3053,9 +3162,9 @@ checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_msvc" @@ -3065,9 +3174,9 @@ checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" [[package]] name = "windows_aarch64_msvc" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_i686_gnu" @@ -3077,9 +3186,9 @@ checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" [[package]] name = "windows_i686_gnu" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_msvc" @@ -3089,9 +3198,9 @@ checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" [[package]] name = "windows_i686_msvc" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_x86_64_gnu" @@ -3101,9 +3210,9 @@ checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" [[package]] name = "windows_x86_64_gnu" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnullvm" @@ -3113,9 +3222,9 @@ checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" [[package]] name = "windows_x86_64_gnullvm" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_msvc" @@ -3125,26 +3234,27 @@ checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" [[package]] name = "windows_x86_64_msvc" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "winnow" -version = "0.4.7" +version = "0.5.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca0ace3845f0d96209f0375e6d367e3eb87eb65d27d445bdc9f1843a26f39448" +checksum = "7c2e3184b9c4e92ad5167ca73039d0c42476302ab603e2fec4487511f38ccefc" dependencies = [ "memchr", ] [[package]] name = "winreg" -version = "0.10.1" +version = "0.50.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" +checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" dependencies = [ - "winapi", + "cfg-if", + "windows-sys 0.48.0", ] [[package]] diff --git a/lib/bolt/cli/Cargo.toml b/lib/bolt/cli/Cargo.toml index 8e5e0adee7..e4f2c37958 100644 --- a/lib/bolt/cli/Cargo.toml +++ b/lib/bolt/cli/Cargo.toml @@ -13,4 +13,4 @@ clap = { version = "4.3", features = ["derive", "env"] } duct = "0.13" serde_json = "1.0" tempfile = "3.2" -tokio = { version = "1.21", features = ["full"] } +tokio = { version = "1.29", features = ["full"] } diff --git a/lib/bolt/cli/src/commands/config.rs b/lib/bolt/cli/src/commands/config.rs index ce7db62a25..9571fda88f 100644 --- a/lib/bolt/cli/src/commands/config.rs +++ b/lib/bolt/cli/src/commands/config.rs @@ -21,6 +21,12 @@ pub enum SubCommand { /// Adds missing regions from supported cloud providers to default_regions.toml. #[clap(hide(true))] GenerateDefaultRegions, + ServiceDependencies { + #[clap(index = 1)] + svc_name: String, + #[clap(long, short = 'r')] + recursive: bool, + }, } impl SubCommand { @@ -34,6 +40,29 @@ impl SubCommand { tasks::config::set_namespace(&namespace).await?; } Self::GenerateDefaultRegions => tasks::config::generate_default_regions().await?, + Self::ServiceDependencies { + svc_name, + recursive, + } => { + // Build project + let ctx = bolt_core::context::ProjectContextData::new( + std::env::var("BOLT_NAMESPACE").ok(), + ) + .await; + + // Read deps + let deps = if *recursive { + ctx.recursive_dependencies(&[&svc_name]).await + } else { + let svc = ctx.service_with_name(svc_name).await; + svc.dependencies().await + }; + + // Print deps + for dep in deps { + println!("{}", dep.name()); + } + } } Ok(()) diff --git a/lib/bolt/cli/src/commands/db/migrate.rs b/lib/bolt/cli/src/commands/db/migrate.rs index d95808668f..548af74e08 100644 --- a/lib/bolt/cli/src/commands/db/migrate.rs +++ b/lib/bolt/cli/src/commands/db/migrate.rs @@ -21,6 +21,8 @@ pub enum SubCommand { /// /// Helpful when dealing with bugged migrations. Force { service: String, num: usize }, + /// Lists migrations + List, /// Drops the entire database. Drop { service: String }, } @@ -61,6 +63,11 @@ impl SubCommand { Self::Force { service, num } => { tasks::migrate::force(&ctx, &ctx.service_with_name(&service).await, num).await?; } + Self::List => { + for svc in ctx.services_with_migrations().await { + println!("{}", svc.name()); + } + } Self::Drop { service } => { tasks::migrate::drop(&ctx, &ctx.service_with_name(&service).await).await?; } diff --git a/lib/bolt/cli/src/commands/infra.rs b/lib/bolt/cli/src/commands/infra.rs index 1f68472b5d..e9897f2cfd 100644 --- a/lib/bolt/cli/src/commands/infra.rs +++ b/lib/bolt/cli/src/commands/infra.rs @@ -8,16 +8,23 @@ use clap::Parser; #[derive(Parser)] pub enum SubCommand { /// Prints out the plan used to provision the Rivet cluster. - Plan, + Plan { + #[clap(long)] + start_at: Option, + }, /// Provisions all infrastructure required for the Rivet cluster. Up { #[clap(long, short = 'y')] yes: bool, + #[clap(long)] + start_at: Option, }, /// Destroys all provisioned infrastructure. Destroy { #[clap(long, short = 'y')] yes: bool, + #[clap(long)] + start_at: Option, }, /// Manages infrastructure migrations. #[clap(hide(true))] @@ -35,16 +42,24 @@ pub enum MigrateSubCommand { impl SubCommand { pub async fn execute(self, ctx: ProjectContext) -> Result<()> { match self { - Self::Plan => { - let plan = tasks::infra::build_plan(&ctx)?; - println!("{plan:#?}"); + Self::Plan { start_at } => { + let plan = tasks::infra::build_plan(&ctx, start_at)?; + for step in plan { + println!("{}: {:?}", step.name_id, step.kind); + } } - Self::Up { yes: auto_approve } => { - let plan = tasks::infra::build_plan(&ctx)?; + Self::Up { + yes: auto_approve, + start_at, + } => { + let plan = tasks::infra::build_plan(&ctx, start_at)?; tasks::infra::execute_plan(&ctx, &plan, ExecutePlanOpts { auto_approve }).await?; } - Self::Destroy { yes: auto_approve } => { - let plan = tasks::infra::build_plan(&ctx)?; + Self::Destroy { + yes: auto_approve, + start_at, + } => { + let plan = tasks::infra::build_plan(&ctx, start_at)?; tasks::infra::destroy_plan(&ctx, &plan, ExecutePlanOpts { auto_approve }).await?; } Self::Migrate { command } => match command { diff --git a/lib/bolt/cli/src/commands/init.rs b/lib/bolt/cli/src/commands/init.rs index ae0a69179a..a94c2b334a 100644 --- a/lib/bolt/cli/src/commands/init.rs +++ b/lib/bolt/cli/src/commands/init.rs @@ -26,7 +26,7 @@ impl InitOpts { let ctx = context::ProjectContextData::new(Some(self.namespace.clone())).await; // Apply infra - let plan = tasks::infra::build_plan(&ctx)?; + let plan = tasks::infra::build_plan(&ctx, None)?; tasks::infra::execute_plan( &ctx, &plan, diff --git a/lib/bolt/cli/src/main.rs b/lib/bolt/cli/src/main.rs index 454d5466b2..4a45be3b52 100644 --- a/lib/bolt/cli/src/main.rs +++ b/lib/bolt/cli/src/main.rs @@ -134,6 +134,10 @@ async fn main() -> Result { fn prompt_prod() -> Result<()> { use std::io::Write; + if std::env::var("BOLT_HEADLESS").ok() == Some("1".to_string()) { + return Ok(()); + } + let mut input = String::new(); print!("Are you sure you want to run this command in prod? (yes) "); diff --git a/lib/bolt/config/Cargo.toml b/lib/bolt/config/Cargo.toml index 083575c75c..8f1211728e 100644 --- a/lib/bolt/config/Cargo.toml +++ b/lib/bolt/config/Cargo.toml @@ -9,5 +9,7 @@ license = "Apache-2.0" heck = "0.3" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" +strum = "0.25" +strum_macros = "0.25" toml = "0.7" uuid = "1.3" diff --git a/lib/bolt/config/default_regions.toml b/lib/bolt/config/default_regions.toml index e422e62313..56c7bf7e69 100644 --- a/lib/bolt/config/default_regions.toml +++ b/lib/bolt/config/default_regions.toml @@ -7,6 +7,7 @@ provider = "linode" provider_region = "us-southeast" netnum = 0 preferred_subnets = ["192.168.128.0/17"] +supports_vlan = true [lnd-sfo] id = "19f1b737-0ff1-4676-a834-1af8c4e9890f" diff --git a/lib/bolt/config/src/ns.rs b/lib/bolt/config/src/ns.rs index c33a2dde7a..7728936d16 100644 --- a/lib/bolt/config/src/ns.rs +++ b/lib/bolt/config/src/ns.rs @@ -403,6 +403,8 @@ pub struct Rivet { pub profanity: Profanity, #[serde(default)] pub upload: Upload, + #[serde(default)] + pub matchmaker: Matchmaker, } #[derive(Serialize, Deserialize, Clone, Debug, Default)] @@ -445,6 +447,24 @@ pub struct Upload { pub nsfw_error_verbose: bool, } +#[derive(Serialize, Deserialize, Clone, Debug, Default)] +#[serde(deny_unknown_fields)] +pub struct Matchmaker { + #[serde(default)] + pub lobby_delivery_method: MatchmakerLobbyDeliveryMethod, +} + +#[derive(Serialize, Deserialize, Clone, Debug, Default, strum_macros::Display)] +pub enum MatchmakerLobbyDeliveryMethod { + #[serde(rename = "s3_direct")] + #[strum(serialize = "s3_direct")] + #[default] + S3Direct, + #[serde(rename = "traffic_server")] + #[strum(serialize = "traffic_server")] + TrafficServer, +} + fn default_regions() -> HashMap { toml::from_str(include_str!("../default_regions.toml")) .expect("failed to parse default_regions.toml") diff --git a/lib/bolt/config/src/service.rs b/lib/bolt/config/src/service.rs index a96c7aaea5..4cffb37727 100644 --- a/lib/bolt/config/src/service.rs +++ b/lib/bolt/config/src/service.rs @@ -25,6 +25,10 @@ pub struct ServiceConfig { pub runtime: RuntimeKind, + /// Database dependencies that need a pool for this service. + #[serde(default)] + pub databases: HashMap, + /// Secrets that need to be exposed for this service. #[serde(default)] pub secrets: HashMap, @@ -50,6 +54,10 @@ pub struct Service { pub test_only: bool, } +#[derive(Deserialize, Clone, Debug)] +#[serde(rename_all = "kebab-case", deny_unknown_fields)] +pub struct Database {} + #[derive(Deserialize, Clone, Debug)] #[serde(rename_all = "kebab-case", deny_unknown_fields)] pub struct Secret { diff --git a/lib/bolt/core/Cargo.toml b/lib/bolt/core/Cargo.toml index 491a0cddae..ae063eda33 100644 --- a/lib/bolt/core/Cargo.toml +++ b/lib/bolt/core/Cargo.toml @@ -34,7 +34,7 @@ serde = { version ="1.0", features = ["derive"] } serde_json = "1.0" tempfile = "3.2" thiserror = "1.0" -tokio = { version = "1.21", features = ["full"] } +tokio = { version = "1.29", features = ["full"] } toml = "0.7" toml_edit = "0.19" types = { path = "../../types/core" } diff --git a/lib/bolt/core/src/context/project.rs b/lib/bolt/core/src/context/project.rs index ac469f523e..9e61ed6f08 100644 --- a/lib/bolt/core/src/context/project.rs +++ b/lib/bolt/core/src/context/project.rs @@ -112,7 +112,7 @@ impl ProjectContextData { // Assign references to all services after we're done for svc in &ctx.svc_ctxs { - *svc.project.write().await = Arc::downgrade(&ctx); + svc.set_project(Arc::downgrade(&ctx)).await; } ctx @@ -172,6 +172,7 @@ impl ProjectContextData { // Load the service let svc_ctx = context::service::ServiceContextData::from_path( Weak::new(), + &svc_ctxs_map, &workspace_path, &worker_path, ) @@ -218,6 +219,7 @@ impl ProjectContextData { // Load the service let svc_ctx = context::service::ServiceContextData::from_path( Weak::new(), + &svc_ctxs_map, workspace_path, &entry.path(), ) @@ -439,10 +441,11 @@ impl ProjectContextData { impl ProjectContextData { /// Origin used for building links to the Hub. pub fn origin_hub(&self) -> String { - self.ns().dns.hub_origin.clone().map_or_else( - || self.ns().dns.domain.main.clone(), - |x| format!("https://hub.{x}"), - ) + self.ns() + .dns + .hub_origin + .clone() + .unwrap_or_else(|| format!("https://hub.{}", self.ns().dns.domain.main.clone())) } pub fn domain_main(&self) -> String { self.ns().dns.domain.main.clone() @@ -532,65 +535,63 @@ pub struct S3Config { pub region: String, } -#[derive(Clone, Copy)] -pub enum S3Provider { - Minio, - Backblaze, - Aws, -} - impl ProjectContextData { - pub fn default_s3_provider(self: &Arc) -> Result<(S3Provider, config::ns::S3Provider)> { + pub fn default_s3_provider( + self: &Arc, + ) -> Result<(s3_util::Provider, config::ns::S3Provider)> { let providers = &self.ns().s3.providers; // Find the provider with the default flag set if let Some(p) = &providers.minio { if p.default { - return Ok((S3Provider::Minio, p.clone())); + return Ok((s3_util::Provider::Minio, p.clone())); } } if let Some(p) = &providers.backblaze { if p.default { - return Ok((S3Provider::Backblaze, p.clone())); + return Ok((s3_util::Provider::Backblaze, p.clone())); } } if let Some(p) = &providers.aws { if p.default { - return Ok((S3Provider::Aws, p.clone())); + return Ok((s3_util::Provider::Aws, p.clone())); } } // If nonoe have the default flag, return the first provider if let Some(p) = &providers.minio { - return Ok((S3Provider::Minio, p.clone())); + return Ok((s3_util::Provider::Minio, p.clone())); } else if let Some(p) = &providers.backblaze { - return Ok((S3Provider::Backblaze, p.clone())); + return Ok((s3_util::Provider::Backblaze, p.clone())); } else if let Some(p) = &providers.aws { - return Ok((S3Provider::Aws, p.clone())); + return Ok((s3_util::Provider::Aws, p.clone())); } bail!("no s3 provider configured") } /// Returns the appropriate S3 connection configuration for the provided S3 provider. - pub async fn s3_credentials(self: &Arc, provider: S3Provider) -> Result { + pub async fn s3_credentials( + self: &Arc, + provider: s3_util::Provider, + ) -> Result { match provider { - S3Provider::Minio => Ok(S3Credentials { + s3_util::Provider::Minio => Ok(S3Credentials { access_key_id: "root".into(), access_key_secret: self .read_secret(&["minio", "users", "root", "password"]) .await?, }), - S3Provider::Backblaze => { + s3_util::Provider::Backblaze => { let service_key = s3::fetch_service_key(&self, &["b2", "terraform"]).await?; Ok(S3Credentials { access_key_id: service_key.key_id, access_key_secret: service_key.key, }) } - S3Provider::Aws => { + s3_util::Provider::Aws => { let service_key = s3::fetch_service_key(&self, &["aws", "terraform"]).await?; Ok(S3Credentials { access_key_id: service_key.key_id, @@ -601,9 +602,9 @@ impl ProjectContextData { } /// Returns the appropriate S3 connection configuration for the provided S3 provider. - pub async fn s3_config(self: &Arc, provider: S3Provider) -> Result { + pub async fn s3_config(self: &Arc, provider: s3_util::Provider) -> Result { match provider { - S3Provider::Minio => { + s3_util::Provider::Minio => { let s3 = terraform::output::read_s3_minio(&*self).await; Ok(S3Config { endpoint_internal: (*s3.s3_endpoint_internal).clone(), @@ -611,7 +612,7 @@ impl ProjectContextData { region: (*s3.s3_region).clone(), }) } - S3Provider::Backblaze => { + s3_util::Provider::Backblaze => { let s3 = terraform::output::read_s3_backblaze(&*self).await; Ok(S3Config { endpoint_internal: (*s3.s3_endpoint_internal).clone(), @@ -619,7 +620,7 @@ impl ProjectContextData { region: (*s3.s3_region).clone(), }) } - S3Provider::Aws => { + s3_util::Provider::Aws => { let s3 = terraform::output::read_s3_aws(&*self).await; Ok(S3Config { endpoint_internal: (*s3.s3_endpoint_internal).clone(), diff --git a/lib/bolt/core/src/context/service.rs b/lib/bolt/core/src/context/service.rs index 95a8977a84..a51caeb19f 100644 --- a/lib/bolt/core/src/context/service.rs +++ b/lib/bolt/core/src/context/service.rs @@ -1,12 +1,12 @@ +use anyhow::{bail, ensure, Context, Result}; +use async_recursion::async_recursion; +use s3_util::aws_sdk_s3; use std::{ collections::HashMap, hash::{Hash, Hasher}, path::{Path, PathBuf}, sync::{Arc, Weak}, }; - -use anyhow::{bail, ensure, Context, Result}; -use s3_util::aws_sdk_s3; use tempfile::NamedTempFile; use tokio::{fs, process::Command, sync::RwLock}; @@ -15,7 +15,7 @@ use crate::{ self, service::{RuntimeKind, ServiceKind}, }, - context::{self, BuildContext, ProjectContext, RunContext, S3Provider}, + context::{self, BuildContext, ProjectContext, RunContext}, dep::{self, cloudflare, s3}, utils, }; @@ -25,7 +25,9 @@ use super::BuildOptimization; pub type ServiceContext = Arc; pub struct ServiceContextData { - pub(in crate::context) project: RwLock>, + project: RwLock>, + /// If this is overriding a service from an additional root, then this will be specified. + overridden_service: Option, config: config::service::ServiceConfig, path: PathBuf, workspace_path: PathBuf, @@ -45,6 +47,18 @@ impl Hash for ServiceContextData { } impl ServiceContextData { + /// Sets the reference to the project once the project context is finished initiating. + #[async_recursion] + pub(in crate::context) async fn set_project( + &self, + project: Weak, + ) { + *self.project.write().await = project.clone(); + if let Some(overridden_service) = &self.overridden_service { + overridden_service.set_project(project.clone()).await; + } + } + pub async fn project(&self) -> ProjectContext { self.project .read() @@ -69,6 +83,7 @@ impl ServiceContextData { impl ServiceContextData { pub async fn from_path( project: Weak, + svc_ctxs_map: &HashMap, workspace_path: &Path, path: &Path, ) -> Option { @@ -92,8 +107,12 @@ impl ServiceContextData { Err(_) => None, }; + // Read overridden service + let overridden_service = svc_ctxs_map.get(&config.service.name).cloned(); + Some(Arc::new(ServiceContextData::new( project, + overridden_service, config, workspace_path, path, @@ -103,6 +122,7 @@ impl ServiceContextData { fn new( project: Weak, + overridden_service: Option, config: config::service::ServiceConfig, workspace_path: &Path, path: &Path, @@ -111,6 +131,7 @@ impl ServiceContextData { // Build context let ctx = ServiceContextData { project: RwLock::new(project), + overridden_service, config, path: path.to_owned(), workspace_path: workspace_path.to_owned(), @@ -139,6 +160,8 @@ impl ServiceContextData { .supports_component_class(&component_class), "runtime does not support component class" ); + + // TODO: Validate that all services in `config.databases` are actually databases } } @@ -332,16 +355,32 @@ impl ServiceContextData { #[derive(Debug, Clone)] pub enum ServiceBuildPlan { /// Build exists locally. - ExistingLocalBuild { output_path: PathBuf }, + ExistingLocalBuild { + /// Absolute path to the executable on the host system. + exec_path: PathBuf, + }, /// Build exists on S3 server. - ExistingUploadedBuild { build_key: String }, + ExistingUploadedBuild { + build_key: String, + + /// Path to the executable in the archive. + exec_path: String, + }, /// Build the service locally. - BuildLocally { output_path: PathBuf }, + BuildLocally { + /// Absolute path to the executable on the host system. + exec_path: PathBuf, + }, /// Build the service and upload to S3. - BuildAndUpload { build_key: String }, + BuildAndUpload { + build_key: String, + + /// Path to the executable in the archive. + exec_path: String, + }, /// Run a Docker container. Docker { image_tag: String }, @@ -369,36 +408,52 @@ impl ServiceContextData { .await; if force_build { - return Ok(ServiceBuildPlan::BuildLocally { output_path }); + return Ok(ServiceBuildPlan::BuildLocally { + exec_path: output_path, + }); } // Check if there's an existing build we can use let build_exists = tokio::fs::metadata(&output_path).await.is_ok(); if build_exists { - return Ok(ServiceBuildPlan::ExistingLocalBuild { output_path }); + return Ok(ServiceBuildPlan::ExistingLocalBuild { + exec_path: output_path, + }); } // Default to building - Ok(ServiceBuildPlan::BuildLocally { output_path }) + Ok(ServiceBuildPlan::BuildLocally { + exec_path: output_path, + }) } // Build and upload to S3 config::ns::ClusterKind::Distributed { .. } => { // Derive the build key let key = self.s3_build_key(build_context).await?; + let exec_path = self.cargo_name().expect("no cargo name").to_string(); if force_build { - return Ok(ServiceBuildPlan::BuildAndUpload { build_key: key }); + return Ok(ServiceBuildPlan::BuildAndUpload { + build_key: key, + exec_path, + }); } // Check if there's an existing build we can use let s3_client = project_ctx.s3_client_service_builds().await?; let build_exists = s3::check_exists_cached(&project_ctx, &s3_client, &key).await?; if build_exists { - return Ok(ServiceBuildPlan::ExistingUploadedBuild { build_key: key }); + return Ok(ServiceBuildPlan::ExistingUploadedBuild { + build_key: key, + exec_path, + }); } // Default to building - Ok(ServiceBuildPlan::BuildAndUpload { build_key: key }) + Ok(ServiceBuildPlan::BuildAndUpload { + build_key: key, + exec_path, + }) } } } @@ -406,6 +461,7 @@ impl ServiceContextData { // Dependencies impl ServiceContextData { + #[async_recursion] pub async fn dependencies(&self) -> Vec { let project = self.project().await; @@ -413,45 +469,54 @@ impl ServiceContextData { let mut dep_ctxs = Vec::::new(); - // TODO: Find a cleaner way of specifying database dependencies - // HACK: Mark all database & S3 dependencies as dependencies for all services in order to - // expose the env - for svc in all_svcs { - if matches!( - svc.config().kind, - ServiceKind::Database { .. } | ServiceKind::Cache { .. } - ) { - dep_ctxs.push(svc.clone()); - } - } - // TODO: Add dev dependencies if building for tests // Add operation dependencies from Cargo.toml + // + // You cannot depend on these services from the Service.toml, only as a Cargo dependency if let Some(cargo) = &self.cargo { - let svc_path = self.path(); let svcs = cargo .dependencies .iter() - .filter_map(|(_, x)| { - if let config::service::CargoDependency::Path { path } = x { - Some(path) + .filter_map(|(name, dep)| { + if let config::service::CargoDependency::Path { .. } = dep { + Some(name) } else { None } }) - .filter_map(|path| { - let absolute_path = svc_path.join(path); + // Remove overridden service from deps list + .filter(|name| { + self.overridden_service + .as_ref() + .map(|osvc| &&osvc.name() != name) + .unwrap_or(true) + }) + .filter_map(|name| { all_svcs .iter() - .filter(|x| x.path() == absolute_path) + .filter(|x| x.name() == *name) .next() .cloned() }); + // TOOD: Use the path to find the service instead of the name. This is difficult with multiple roots. + // .filter_map(|path| { + // let absolute_path = svc_path.join(path); + // all_svcs + // .iter() + // .filter(|x| x.path() == absolute_path) + // .next() + // .cloned() + // }); dep_ctxs.extend(svcs); } - // Check that these are services you can explicitly depend on + // Inherit dependencies from the service that was overridden + if let Some(overriden_svc) = &self.overridden_service { + dep_ctxs.extend(overriden_svc.dependencies().await); + } + + // Check that these are services you can explicitly depend on in the Service.toml for dep in &dep_ctxs { if !self.config().service.test_only && dep.config().service.test_only { panic!( @@ -463,7 +528,9 @@ impl ServiceContextData { if !matches!( dep.config().kind, - ServiceKind::Database { .. } | ServiceKind::Cache { .. } + ServiceKind::Database { .. } + | ServiceKind::Cache { .. } + | ServiceKind::Operation { .. } ) { panic!( "{} -> {}: cannot explicitly depend on this kind of service", @@ -476,63 +543,90 @@ impl ServiceContextData { dep_ctxs } - pub async fn crdb_dependencies(&self) -> Vec { - self.dependencies() + pub async fn database_dependencies(&self) -> HashMap { + let dbs = self + .project() .await - .iter() + .recursive_dependencies(&[self.name()]) + .await + .into_iter() + // Filter filter services to include only operations, since these run in-process .filter(|svc| { - if let RuntimeKind::CRDB { .. } = svc.config().runtime { - true - } else { - false - } + **svc == *self || matches!(svc.config().kind, ServiceKind::Operation { .. }) }) - .cloned() + // Aggregate secrets from all dependencies + .flat_map(|x| x.config().databases.clone().into_iter()) + // Dedupe + .collect::>(); + + dbs + } + + pub async fn crdb_dependencies(&self) -> Vec { + let dep_names = self + .database_dependencies() + .await + .into_iter() + .map(|(k, _)| k) + .collect::>(); + self.project() + .await + .services_with_names(&dep_names) + .await + .into_iter() + .filter(|svc| matches!(svc.config().runtime, RuntimeKind::CRDB { .. })) .collect() } pub async fn redis_dependencies(&self) -> Vec { - self.dependencies() + let default_deps = ["redis-chirp".to_string(), "redis-cache".to_string()]; + + let dep_names = self + .database_dependencies() .await - .iter() - .filter(|svc| { - if let RuntimeKind::Redis { .. } = svc.config().runtime { - true - } else { - false - } - }) - .cloned() + .into_iter() + .map(|(k, _)| k) + .chain(default_deps) + .collect::>(); + + self.project() + .await + .services_with_names(&dep_names) + .await + .into_iter() + .filter(|svc| matches!(svc.config().runtime, RuntimeKind::Redis { .. })) .collect() } pub async fn s3_dependencies(&self) -> Vec { - self.dependencies() + let dep_names = self + .database_dependencies() .await - .iter() - .filter(|svc| { - if let RuntimeKind::S3 { .. } = svc.config().runtime { - true - } else { - false - } - }) - .cloned() + .into_iter() + .map(|(k, _)| k) + .collect::>(); + self.project() + .await + .services_with_names(&dep_names) + .await + .into_iter() + .filter(|svc| matches!(svc.config().runtime, RuntimeKind::S3 { .. })) .collect() } pub async fn nats_dependencies(&self) -> Vec { - self.dependencies() + let dep_names = self + .database_dependencies() .await - .iter() - .filter(|svc| { - if let RuntimeKind::Nats { .. } = svc.config().runtime { - true - } else { - false - } - }) - .cloned() + .into_iter() + .map(|(k, _)| k) + .collect::>(); + self.project() + .await + .services_with_names(&dep_names) + .await + .into_iter() + .filter(|svc| matches!(svc.config().runtime, RuntimeKind::Nats { .. })) .collect() } } @@ -691,7 +785,7 @@ impl ServiceContextData { env.push(( "TOKIO_WORKER_THREADS".into(), match ns_service_config.resources.cpu { - config::ns::CpuResources::CpuCores(cores) => cores.max(2), + config::ns::CpuResources::CpuCores(cores) => cores.max(cores), config::ns::CpuResources::Cpu(_) => 2, } .to_string(), @@ -719,7 +813,7 @@ impl ServiceContextData { env.push(("TOKIO_CONSOLE_ENABLE".into(), "1".into())); env.push(( "TOKIO_CONSOLE_BIND".into(), - r#"0.0.0.0:{{env "NOMAD_PORT_tokio_console"}}"#.into(), + r#"0.0.0.0:${NOMAD_PORT_tokio-console}"#.into(), )); } @@ -873,7 +967,7 @@ impl ServiceContextData { // NATS config env.push(( "NATS_URL".into(), - // TODO: Add back passsing multiple NATS nodes for failover instead of using DNS resolution + // TODO: Add back passing multiple NATS nodes for failover instead of using DNS resolution access_service( &project_ctx, &mut tunnel_configs, @@ -991,44 +1085,28 @@ impl ServiceContextData { } // Add default provider - let default_provider_name = match project_ctx.default_s3_provider()? { - (S3Provider::Minio, _) => "MINIO", - (S3Provider::Backblaze, _) => "BACKBLAZE", - (S3Provider::Aws, _) => "AWS", - }; + let (default_provider, _) = project_ctx.default_s3_provider()?; env.push(( "S3_DEFAULT_PROVIDER".to_string(), - default_provider_name.to_string(), + default_provider.to_string(), )); // Add all configured providers let providers = &project_ctx.ns().s3.providers; if providers.minio.is_some() { - add_s3_env( - &project_ctx, - &mut env, - &s3_dep, - context::project::S3Provider::Minio, - ) - .await?; + add_s3_env(&project_ctx, &mut env, &s3_dep, s3_util::Provider::Minio).await?; } if providers.backblaze.is_some() { add_s3_env( &project_ctx, &mut env, &s3_dep, - context::project::S3Provider::Backblaze, + s3_util::Provider::Backblaze, ) .await?; } if providers.aws.is_some() { - add_s3_env( - &project_ctx, - &mut env, - &s3_dep, - context::project::S3Provider::Aws, - ) - .await?; + add_s3_env(&project_ctx, &mut env, &s3_dep, s3_util::Provider::Aws).await?; } } @@ -1099,6 +1177,15 @@ impl ServiceContextData { } .into(), )); + env.push(( + "RIVET_MM_LOBBY_DELIVERY_METHOD".into(), + project_ctx + .ns() + .rivet + .matchmaker + .lobby_delivery_method + .to_string(), + )); // Sort env by keys so it's always in the same order env.sort_by_cached_key(|x| x.0.clone()); @@ -1219,7 +1306,7 @@ impl ServiceContextData { } ); - let service = project_ctx + let mut service = project_ctx .ns() .services .get(&self.name()) @@ -1235,7 +1322,7 @@ impl ServiceContextData { }, }, config::ns::ClusterKind::Distributed { .. } => config::ns::Service { - count: if is_singleton { 1 } else { 2 }, + count: 2, resources: config::ns::ServiceResources { cpu: config::ns::CpuResources::Cpu(250), memory: 256, @@ -1244,8 +1331,9 @@ impl ServiceContextData { }, }); + // Force single count if singleton if is_singleton { - assert_eq!(service.count, 1) + service.count = 1; } service @@ -1256,13 +1344,9 @@ async fn add_s3_env( project_ctx: &ProjectContext, env: &mut Vec<(String, String)>, s3_dep: &Arc, - provider: S3Provider, + provider: s3_util::Provider, ) -> Result<()> { - let provider_name = match provider { - S3Provider::Minio => "MINIO", - S3Provider::Backblaze => "BACKBLAZE", - S3Provider::Aws => "AWS", - }; + let provider_name = provider.to_string(); let s3_dep_name = s3_dep.name_screaming_snake(); let s3_config = project_ctx.s3_config(provider).await?; let s3_creds = project_ctx.s3_credentials(provider).await?; diff --git a/lib/bolt/core/src/dep/cargo/cli.rs b/lib/bolt/core/src/dep/cargo/cli.rs index 638147008e..288c96dbd0 100644 --- a/lib/bolt/core/src/dep/cargo/cli.rs +++ b/lib/bolt/core/src/dep/cargo/cli.rs @@ -61,12 +61,10 @@ pub async fn build<'a, T: AsRef>(ctx: &ProjectContext, opts: BuildOpts<'a, .collect::>() .join(" "); - // TODO: Not sure why the .cargo/config.toml isn't working with nested projects, have to hardcode - // the target dir indoc::formatdoc!( " if [ $? -eq 0 ]; then - (cd {path} && cargo build {jobs_flag} {format_flag} {release_flag} {bin_flags} --target-dir $TARGET_DIR) + (cd {path} && cargo build {jobs_flag} {format_flag} {release_flag} {bin_flags}) fi " ) @@ -77,7 +75,10 @@ pub async fn build<'a, T: AsRef>(ctx: &ProjectContext, opts: BuildOpts<'a, // Generate build script let build_script = indoc::formatdoc!( r#" - TARGET_DIR=$(readlink -f ./target) + # TODO: Not sure why the .cargo/config.toml isn't working with nested projects, have to hardcode + # the target dir + export CARGO_TARGET_DIR=$(readlink -f ./target) + echo "CARGO_TARGET_DIR=$CARGO_TARGET_DIR" # Used for Tokio Console. See https://github.com/tokio-rs/console#using-it export RUSTFLAGS="--cfg tokio_unstable" # Used for debugging @@ -116,7 +117,7 @@ pub async fn build<'a, T: AsRef>(ctx: &ProjectContext, opts: BuildOpts<'a, cmd.arg("--rm") .arg("--interactive") .arg("--tty") - .arg("clux/muslrust:1.65.0-stable"); + .arg("clux/muslrust:1.72.0-stable"); cmd.arg("sh").arg("-c").arg(indoc::formatdoc!( r#" # HACK: Link musl-g++ diff --git a/lib/bolt/core/src/dep/nomad/gen.rs b/lib/bolt/core/src/dep/nomad/gen.rs index b7b52ace76..b50eca3a8b 100644 --- a/lib/bolt/core/src/dep/nomad/gen.rs +++ b/lib/bolt/core/src/dep/nomad/gen.rs @@ -25,11 +25,13 @@ pub enum ExecServiceDriver { }, UploadedBinaryArtifact { artifact_key: String, + /// Path to the executable within the archive. + exec_path: String, args: Vec, }, LocalBinaryArtifact { - /// Path relative to the project root. - path: PathBuf, + /// Path to the executable relative to the project root. + exec_path: PathBuf, args: Vec, }, } @@ -79,6 +81,11 @@ pub async fn gen_svc(region_id: &str, exec_ctx: &ExecServiceContext) -> Job { svc_ctx.config().kind, ServiceKind::Headless { .. } | ServiceKind::Consumer { .. } | ServiceKind::Api { .. } ); + let crdb_dep = svc_ctx + .crdb_dependencies() + .await + .first() + .map(|svc| svc.name()); let has_metrics = matches!( svc_ctx.config().kind, @@ -183,32 +190,32 @@ pub async fn gen_svc(region_id: &str, exec_ctx: &ExecServiceContext) -> Job { name: Some("svc".into()), // TODO: Add autoscaling count: Some(ns_service_config.count as i64), - update: if enable_update { - Some( - // Wait for services to be healthy before progressing deploy - if has_health { - Update { - max_parallel: Some(1), - health_check: Some("checks".to_owned()), - min_healthy_time: Some(chrono::secs(10)), - healthy_deadline: Some(chrono::min(5)), - progress_deadline: Some(chrono::min(10)), - auto_revert: Some(true), - canary: Some(0), - stagger: Some(chrono::secs(30)), - ..Default::default() - } - } else { - // Just monitor the task status - Update { - health_check: Some("task_states".into()), - ..Default::default() - } - }, - ) - } else { - None - }, + // update: if enable_update { + // Some( + // // Wait for services to be healthy before progressing deploy + // if has_health { + // Update { + // max_parallel: Some(1), + // health_check: Some("checks".to_owned()), + // min_healthy_time: Some(chrono::secs(10)), + // healthy_deadline: Some(chrono::min(5)), + // progress_deadline: Some(chrono::min(10)), + // auto_revert: Some(true), + // canary: Some(0), + // stagger: Some(chrono::secs(30)), + // ..Default::default() + // } + // } else { + // // Just monitor the task status + // Update { + // health_check: Some("task_states".into()), + // ..Default::default() + // } + // }, + // ) + // } else { + // None + // }, reschedule_policy: Some(ReschedulePolicy { delay: Some(chrono::secs(30)), delay_function: Some("constant".into()), @@ -239,7 +246,7 @@ pub async fn gen_svc(region_id: &str, exec_ctx: &ExecServiceContext) -> Job { }]), ephemeral_disk: Some(json!({ // Prevent exhausting all storage resources on the local machine. We don't - // accept anything over 512 MB since our dev machiens are limited in space. + // accept anything over 512 MB since our dev machines are limited in space. "SizeMB": ns_service_config.resources.ephemeral_disk, })), services: Some({ @@ -268,15 +275,15 @@ pub async fn gen_svc(region_id: &str, exec_ctx: &ExecServiceContext) -> Job { let mut checks = Vec::new(); // Require a healthy health check before booting - let interval = chrono::secs(15); - let on_update = "require_healthy"; + let interval = chrono::secs(5); + let on_update = "ignore"; checks.push(Check { name: Some("Health Server Liveness".into()), check_type: Some("http".into()), port_label: Some("health".into()), path: Some("/health/liveness".into()), - interval: Some(chrono::secs(15)), + interval: Some(chrono::secs(5)), timeout: Some(chrono::secs(5)), on_update: Some(on_update.into()), // This indicates the runtime might @@ -286,13 +293,22 @@ pub async fn gen_svc(region_id: &str, exec_ctx: &ExecServiceContext) -> Job { // // Ignore in staging since we have // `on_update` set to `ignore`. - check_restart: Some(CheckRestart { - limit: Some(3), - ..Default::default() - }), + // check_restart: Some(CheckRestart { + // limit: Some(3), + // ..Default::default() + // }), ..Default::default() }); + if let Some(crdb_dep) = crdb_dep { + checks.push(build_conn_check( + "Cockroach", + &format!("/health/crdb/{}", crdb_dep), + interval, + on_update, + )); + } + checks.push(build_conn_check( "Nats Connection", "/health/nats", @@ -425,19 +441,19 @@ pub async fn gen_svc(region_id: &str, exec_ctx: &ExecServiceContext) -> Job { "logging": nomad_loki_plugin_config(&project_ctx, &svc_ctx).await.unwrap(), }) } - ExecServiceDriver::LocalBinaryArtifact { path, args } => { + ExecServiceDriver::LocalBinaryArtifact { exec_path, args } => { json!({ "image": "alpine:3.18", "args": args, - "command": Path::new("/var/rivet/backend").join(path), + "command": Path::new("/var/rivet/backend").join(exec_path), "auth": nomad_docker_io_auth(&project_ctx).await.unwrap(), "logging": nomad_loki_plugin_config(&project_ctx, &svc_ctx).await.unwrap(), }) } - ExecServiceDriver::UploadedBinaryArtifact { args, .. } => { + ExecServiceDriver::UploadedBinaryArtifact { exec_path, args, .. } => { json!({ "image": "alpine:3.18", - "command": format!("${{NOMAD_TASK_DIR}}/build/{}", svc_ctx.name()), + "command": format!("${{NOMAD_TASK_DIR}}/build/{exec_path}"), "args": args, "auth": nomad_docker_io_auth(&project_ctx).await.unwrap(), "logging": nomad_loki_plugin_config(&project_ctx, &svc_ctx).await.unwrap(), @@ -469,15 +485,28 @@ pub async fn gen_svc(region_id: &str, exec_ctx: &ExecServiceContext) -> Job { let s3_config = project_ctx.s3_config(default_provider).await.unwrap(); let s3_creds = project_ctx.s3_credentials(default_provider).await.unwrap(); + // The getter source is not a standard URL, so we have to hardcode it + // ourselves. + // + // Using the region in the domain causes it to throw an invalid URL error. + let getter_source = match default_provider { + s3_util::Provider::Aws => { + format!("s3::https://s3.amazonaws.com/{bucket}/{artifact_key}") + } + s3_util::Provider::Backblaze => { + format!( + "s3::{endpoint}/{bucket}/{key}", + endpoint = s3_config.endpoint_external, + key = urlencoding::encode(artifact_key), + ) + } + _ => todo!(), + }; + Some(json!([ { "GetterMode": "dir", - "GetterSource": format!( - "s3::{endpoint}/{bucket}/{key}", - endpoint = s3_config.endpoint_internal, - bucket = bucket, - key = urlencoding::encode(artifact_key), - ), + "GetterSource": getter_source, "GetterOptions": { "region": s3_config.region, "aws_access_key_id": s3_creds.access_key_id, diff --git a/lib/bolt/core/src/dep/salt/cli.rs b/lib/bolt/core/src/dep/salt/cli.rs index 2c2cc8fa55..b11518fa78 100644 --- a/lib/bolt/core/src/dep/salt/cli.rs +++ b/lib/bolt/core/src/dep/salt/cli.rs @@ -31,7 +31,19 @@ pub async fn apply( let mut event = utils::telemetry::build_event(ctx, "bolt_salt_apply").await?; event.insert_prop("filter", filter)?; event.insert_prop("sls", &opts.sls)?; - utils::telemetry::capture_event(ctx, event).await?; + utils::telemetry::capture_event(ctx, event)?; + + // Install rsync + if let config::ns::ClusterKind::Distributed { .. } = ctx.ns().cluster.kind { + eprintln!(); + rivet_term::status::progress("Installing rsync on Salt Master", ""); + tasks::ssh::pool( + &ctx, + "salt_master", + Some("if ! which rsync; then apt update -y && apt install -y rsync; fi"), + ) + .await?; + } // Write Salt configs eprintln!(); @@ -59,19 +71,22 @@ pub async fn apply( } config::ns::ClusterKind::Distributed { .. } => { tokio::try_join!( - // /srv/salt - async { rsync_dir(ctx, &ctx.salt_path().join("salt"), "/srv/salt").await }, - // /srv/pillar - async { rsync_dir(ctx, &ctx.salt_path().join("pillar"), "/srv/pillar").await }, - // /srv/rivet-nix async { + // /srv/salt + rsync_dir(ctx, &ctx.salt_path().join("salt"), "/srv/salt").await?; + + // /srv/salt/nix/files/source rsync_dir( ctx, - &ctx.salt_path().join("pillar"), + &ctx.path().join("infra").join("nix"), "/srv/salt/nix/files/source", ) - .await + .await?; + + Ok(()) }, + // /srv/pillar + async { rsync_dir(ctx, &ctx.salt_path().join("pillar"), "/srv/pillar").await }, // /srv/salt-context async { let tmp_dir = tempfile::TempDir::new()?; diff --git a/lib/bolt/core/src/dep/salt/config.rs b/lib/bolt/core/src/dep/salt/config.rs index bda33f0707..17d9afbaee 100644 --- a/lib/bolt/core/src/dep/salt/config.rs +++ b/lib/bolt/core/src/dep/salt/config.rs @@ -3,7 +3,7 @@ use serde_json::{json, Value}; use crate::{ config::{self, ns::LoggingProvider, service::RuntimeKind}, - context::{ProjectContext, S3Provider}, + context::ProjectContext, dep, }; @@ -49,7 +49,11 @@ pub async fn build(ctx: &ProjectContext, opts: &BuildOpts) -> Result { vars["cloudflare"] = cloudflare(ctx)?; - vars["s3"] = s3(ctx, opts.skip_s3).await?; + vars["s3"] = if opts.skip_s3 { + json!({}) + } else { + s3(ctx).await? + }; vars["logging"] = logging(ctx)?; @@ -60,23 +64,9 @@ pub async fn build(ctx: &ProjectContext, opts: &BuildOpts) -> Result { Ok(vars) } -async fn s3(ctx: &ProjectContext, skip: bool) -> Result { +async fn s3(ctx: &ProjectContext) -> Result { let mut res = serde_json::Map::with_capacity(1); - if skip { - // Provide filler values so the pillars can still render - res.insert( - "default".to_string(), - json!({ - "endpoint_internal": "", - "endpoint_external": "", - "region": "", - }), - ); - - return Ok(res.into()); - } - let (default_provider, _) = ctx.default_s3_provider()?; let default_s3_config = ctx.s3_config(default_provider).await?; res.insert( @@ -90,7 +80,7 @@ async fn s3(ctx: &ProjectContext, skip: bool) -> Result { let providers = &ctx.ns().s3.providers; if providers.minio.is_some() { - let s3_config = ctx.s3_config(S3Provider::Minio).await?; + let s3_config = ctx.s3_config(s3_util::Provider::Minio).await?; res.insert( "minio".to_string(), json!({ @@ -101,7 +91,7 @@ async fn s3(ctx: &ProjectContext, skip: bool) -> Result { ); } if providers.backblaze.is_some() { - let s3_config = ctx.s3_config(S3Provider::Backblaze).await?; + let s3_config = ctx.s3_config(s3_util::Provider::Backblaze).await?; res.insert( "backblaze".to_string(), json!({ @@ -112,7 +102,7 @@ async fn s3(ctx: &ProjectContext, skip: bool) -> Result { ); } if providers.aws.is_some() { - let s3_config = ctx.s3_config(S3Provider::Aws).await?; + let s3_config = ctx.s3_config(s3_util::Provider::Aws).await?; res.insert( "aws".to_string(), json!({ @@ -128,7 +118,8 @@ async fn s3(ctx: &ProjectContext, skip: bool) -> Result { fn cloudflare(ctx: &ProjectContext) -> Result { #[allow(irrefutable_let_patterns)] - let config::ns::DnsProvider::Cloudflare { access, .. } = &ctx.ns().dns.provider else { + let config::ns::DnsProvider::Cloudflare { access, .. } = &ctx.ns().dns.provider + else { return Ok(json!(null)); }; @@ -145,7 +136,8 @@ fn cloudflare(ctx: &ProjectContext) -> Result { fn logging(ctx: &ProjectContext) -> Result { #[allow(irrefutable_let_patterns)] - let Some(logging) = &ctx.ns().logging else { + let Some(logging) = &ctx.ns().logging + else { return Ok(json!(null)); }; diff --git a/lib/bolt/core/src/dep/salt/secrets.rs b/lib/bolt/core/src/dep/salt/secrets.rs index 89ae47c0a6..bd13b2c3b1 100644 --- a/lib/bolt/core/src/dep/salt/secrets.rs +++ b/lib/bolt/core/src/dep/salt/secrets.rs @@ -1,7 +1,7 @@ use anyhow::*; use serde_json::{json, Value}; -use crate::context::{ProjectContext, S3Provider}; +use crate::context::ProjectContext; /// Generates a config that will be exposed to Salt. pub async fn build_secrets(ctx: &ProjectContext) -> Result { @@ -15,6 +15,16 @@ pub async fn build_secrets(ctx: &ProjectContext) -> Result { secrets["s3"] = s3(ctx).await?; + if ctx.ns().s3.providers.minio.is_some() { + secrets["minio"] = json!({ + "users": { + "root": { + "password": ctx.read_secret(&["minio", "users", "root", "password"]).await?, + }, + }, + }); + } + secrets["clickhouse"] = json!({ "users": { "bolt": { @@ -29,14 +39,6 @@ pub async fn build_secrets(ctx: &ProjectContext) -> Result { }, }); - secrets["minio"] = json!({ - "users": { - "root": { - "password": ctx.read_secret(&["minio", "users", "root", "password"]).await?, - }, - }, - }); - if let (Some(client_id), Some(client_secret)) = ( ctx.read_secret_opt(&["cloudflare", "access", "proxy", "client_id"]) .await?, @@ -71,7 +73,7 @@ async fn s3(ctx: &ProjectContext) -> Result { let providers = &ctx.ns().s3.providers; if providers.minio.is_some() { - let s3_creds = ctx.s3_credentials(S3Provider::Minio).await?; + let s3_creds = ctx.s3_credentials(s3_util::Provider::Minio).await?; res.insert( "minio".to_string(), json!({ @@ -81,7 +83,7 @@ async fn s3(ctx: &ProjectContext) -> Result { ); } if providers.backblaze.is_some() { - let s3_creds = ctx.s3_credentials(S3Provider::Backblaze).await?; + let s3_creds = ctx.s3_credentials(s3_util::Provider::Backblaze).await?; res.insert( "backblaze".to_string(), json!({ @@ -91,7 +93,7 @@ async fn s3(ctx: &ProjectContext) -> Result { ); } if providers.aws.is_some() { - let s3_creds = ctx.s3_credentials(S3Provider::Aws).await?; + let s3_creds = ctx.s3_credentials(s3_util::Provider::Aws).await?; res.insert( "aws".to_string(), json!({ diff --git a/lib/bolt/core/src/dep/terraform/.nebula_firewall_rules.rs.swp b/lib/bolt/core/src/dep/terraform/.nebula_firewall_rules.rs.swp new file mode 100644 index 0000000000..13b7ea1f9c Binary files /dev/null and b/lib/bolt/core/src/dep/terraform/.nebula_firewall_rules.rs.swp differ diff --git a/lib/bolt/core/src/dep/terraform/.pools.rs.swp b/lib/bolt/core/src/dep/terraform/.pools.rs.swp new file mode 100644 index 0000000000..e2b3954f60 Binary files /dev/null and b/lib/bolt/core/src/dep/terraform/.pools.rs.swp differ diff --git a/lib/bolt/core/src/dep/terraform/cli.rs b/lib/bolt/core/src/dep/terraform/cli.rs index 44b03e35a7..0534aa6b1f 100644 --- a/lib/bolt/core/src/dep/terraform/cli.rs +++ b/lib/bolt/core/src/dep/terraform/cli.rs @@ -100,7 +100,7 @@ pub async fn apply( ) -> Result<()> { let mut event = utils::telemetry::build_event(ctx, "bolt_terraform_apply").await?; event.insert_prop("plan_id", plan_id)?; - utils::telemetry::capture_event(ctx, event).await?; + utils::telemetry::capture_event(ctx, event)?; let mut cmd = build_command(ctx, plan_id).await; cmd.arg("apply") @@ -117,7 +117,7 @@ pub async fn apply( pub async fn destroy(ctx: &ProjectContext, plan_id: &str, varfile_path: &Path) -> Result<()> { let mut event = utils::telemetry::build_event(ctx, "bolt_terraform_destroy").await?; event.insert_prop("plan_id", plan_id)?; - utils::telemetry::capture_event(ctx, event).await?; + utils::telemetry::capture_event(ctx, event)?; let mut cmd = build_command(&ctx, plan_id).await; cmd.arg("destroy") diff --git a/lib/bolt/core/src/dep/terraform/gen.rs b/lib/bolt/core/src/dep/terraform/gen.rs index 69e9b183c0..f82d794d25 100644 --- a/lib/bolt/core/src/dep/terraform/gen.rs +++ b/lib/bolt/core/src/dep/terraform/gen.rs @@ -389,6 +389,25 @@ async fn vars(ctx: &ProjectContext) { "s3_persistent_access_key_secret".into(), json!(credentials.access_key_secret), ); + + // Build providers list + let ns_s3_providers = &ctx.ns().s3.providers; + let mut s3_providers = Vec::with_capacity(1); + + if ns_s3_providers.backblaze.is_some() { + s3_providers.push("backblaze"); + } + if ns_s3_providers.minio.is_some() { + s3_providers.push("minio"); + } + if ns_s3_providers.aws.is_some() { + s3_providers.push("aws"); + } + + vars.insert( + "s3_providers".into(), + Into::::into(s3_providers), + ); } // Media presets diff --git a/lib/bolt/core/src/dep/terraform/nebula_firewall_rules.rs b/lib/bolt/core/src/dep/terraform/nebula_firewall_rules.rs index 7343a1feeb..fa3be47e6b 100644 --- a/lib/bolt/core/src/dep/terraform/nebula_firewall_rules.rs +++ b/lib/bolt/core/src/dep/terraform/nebula_firewall_rules.rs @@ -119,6 +119,7 @@ pub fn traffic_server() -> Vec { vec![ Rule::group("pool:svc", RuleProtocol::TCP, "9300"), Rule::group("pool:ing-px", RuleProtocol::TCP, "9300"), + Rule::group("pool:job", RuleProtocol::TCP, "9300"), ] } diff --git a/lib/bolt/core/src/dep/terraform/pools.rs b/lib/bolt/core/src/dep/terraform/pools.rs index f6c563938f..60e4d07870 100644 --- a/lib/bolt/core/src/dep/terraform/pools.rs +++ b/lib/bolt/core/src/dep/terraform/pools.rs @@ -60,6 +60,9 @@ pub enum PoolLocalMode { /// Run this only when developing locally. LocalOnly, + /// Run this locally and remotely when developing. + LocalAndRemote, + /// Treat the pool normally. Keep, } @@ -186,18 +189,8 @@ pub async fn build_pools(ctx: &ProjectContext) -> Result> ); let mut svc_roles = vec!["docker", "nomad-client", "consul-client"]; - // Add logging roles - if ctx.ns().logging.is_some() - && ctx - .read_secret_opt(&["cloudflare", "access", "proxy", "client_id"]) - .await? - .is_some() - && ctx - .read_secret_opt(&["cloudflare", "access", "proxy", "client_secret"]) - .await? - .is_some() - { - svc_roles.extend(["traefik-cloudflare-proxy", "docker-plugin-loki"]); + if ctx.ns().logging.is_some() { + svc_roles.extend(["traefik", "cloudflare-proxy", "docker-plugin-loki"]); } pools.insert( "svc".into(), @@ -250,7 +243,7 @@ pub async fn build_pools(ctx: &ProjectContext) -> Result> .vpc(true) // TODO: We need a new PoolLocalMode for running locally and being able to run remote // nodes - .local_mode(PoolLocalMode::Locally) + .local_mode(PoolLocalMode::LocalAndRemote) .volumes(hashmap! { "ats".into() => PoolVolume {}, }) @@ -469,7 +462,7 @@ pub async fn build_pools(ctx: &ProjectContext) -> Result> pools.insert( "ing-px".into(), PoolBuilder::default() - .roles(vec!["traefik", "consul-client"]) + .roles(vec!["traefik", "ingress-proxy", "consul-client"]) .vpc(true) .local_mode(PoolLocalMode::Locally) .tunnels(hashmap! { @@ -549,7 +542,7 @@ pub async fn build_pools(ctx: &ProjectContext) -> Result> pools.insert( "ing-job".into(), PoolBuilder::default() - .roles(vec!["traefik"]) + .roles(vec!["traefik", "ingress-proxy"]) .vpc(false) .local_mode(PoolLocalMode::Keep) .tunnels(hashmap! { @@ -659,7 +652,7 @@ pub async fn build_pools(ctx: &ProjectContext) -> Result> }, FirewallRule { label: "nomad-dynamic-udp".into(), - ports: "20000-25999".into(), + ports: "20000-31999".into(), protocol: "udp".into(), inbound_ipv4_cidr: vec!["0.0.0.0/0".into()], inbound_ipv6_cidr: vec!["::/0".into()], @@ -715,7 +708,10 @@ fn filter_pools( new_pools.extend( pools .iter() - .filter(|(_, x)| x.local_mode == PoolLocalMode::Keep) + .filter(|(_, x)| { + x.local_mode == PoolLocalMode::Keep + || x.local_mode == PoolLocalMode::LocalAndRemote + }) .map(|(k, v)| (k.clone(), v.clone())), ); @@ -725,6 +721,7 @@ fn filter_pools( .filter(|(_, x)| { x.local_mode == PoolLocalMode::Locally || x.local_mode == PoolLocalMode::LocalOnly + || x.local_mode == PoolLocalMode::LocalAndRemote }) .map(|(_, x)| x) .collect::>(); diff --git a/lib/bolt/core/src/dep/terraform/remote_states.rs b/lib/bolt/core/src/dep/terraform/remote_states.rs index a5901d1f24..ded39cde1c 100644 --- a/lib/bolt/core/src/dep/terraform/remote_states.rs +++ b/lib/bolt/core/src/dep/terraform/remote_states.rs @@ -2,7 +2,7 @@ use derive_builder::Builder; use maplit::hashmap; use std::collections::HashMap; -use crate::context::{ProjectContext, S3Provider}; +use crate::context::ProjectContext; /// Defines the dependency graph for the Terraform plans. /// @@ -16,9 +16,9 @@ pub fn dependency_graph(ctx: &ProjectContext) -> HashMap<&'static str, Vec { let (default_s3_provider, _) = ctx.default_s3_provider().unwrap(); let provider_plan_id = match default_s3_provider { - S3Provider::Minio => "s3_minio", - S3Provider::Backblaze => "s3_backblaze", - S3Provider::Aws => "s3_aws", + s3_util::Provider::Minio => "s3_minio", + s3_util::Provider::Backblaze => "s3_backblaze", + s3_util::Provider::Aws => "s3_aws", }; vec![RemoteStateBuilder::default() diff --git a/lib/bolt/core/src/dep/terraform/servers.rs b/lib/bolt/core/src/dep/terraform/servers.rs index d92296584e..8d23646bbc 100644 --- a/lib/bolt/core/src/dep/terraform/servers.rs +++ b/lib/bolt/core/src/dep/terraform/servers.rs @@ -96,7 +96,7 @@ pub fn build_servers( netnum: pool.netnum, volumes, - // Tags that will be assgned to the servers. + // Tags that will be assigned to the servers. tags: vec![ ns.to_string(), format!("{ns}-{region_id}"), diff --git a/lib/bolt/core/src/tasks/api.rs b/lib/bolt/core/src/tasks/api.rs index 772ade07ee..812586cfae 100644 --- a/lib/bolt/core/src/tasks/api.rs +++ b/lib/bolt/core/src/tasks/api.rs @@ -34,7 +34,7 @@ pub async fn convert_team(project_ctx: &ProjectContext, team_id: String) -> Resu bail!( "failed to convert team ({}):\n{:#?}", response.status().as_u16(), - response.json().await? + response.json::().await? ); } diff --git a/lib/bolt/core/src/tasks/check.rs b/lib/bolt/core/src/tasks/check.rs index 11a72c0480..1aa9ec00e7 100644 --- a/lib/bolt/core/src/tasks/check.rs +++ b/lib/bolt/core/src/tasks/check.rs @@ -122,6 +122,7 @@ async fn check_svcs( let mut cmd = Command::new("cargo"); cmd.current_dir(path); cmd.env("RUSTFLAGS", "--cfg tokio_unstable"); + cmd.env("CARGO_TARGET_DIR", ctx.path().join("target")); cmd.arg("clippy"); // Check tests, which will also check the main module. Using diff --git a/lib/bolt/core/src/tasks/config/generate.rs b/lib/bolt/core/src/tasks/config/generate.rs index ce98108084..2d015e1a93 100644 --- a/lib/bolt/core/src/tasks/config/generate.rs +++ b/lib/bolt/core/src/tasks/config/generate.rs @@ -431,7 +431,7 @@ pub async fn generate(project_path: &Path, ns_id: &str) -> Result<()> { let mut event = utils::telemetry::build_event(&ctx, "bolt_config_generate").await?; event.insert_prop("ns_id", ns_id)?; - utils::telemetry::capture_event(&ctx, event).await?; + utils::telemetry::capture_event(&ctx, event)?; eprintln!(); rivet_term::status::success( diff --git a/lib/bolt/core/src/tasks/infra/migrate/break_infra_terraform_monolith.rs b/lib/bolt/core/src/tasks/infra/migrate/break_infra_terraform_monolith.rs index 6c98b9444b..4f40a56016 100644 --- a/lib/bolt/core/src/tasks/infra/migrate/break_infra_terraform_monolith.rs +++ b/lib/bolt/core/src/tasks/infra/migrate/break_infra_terraform_monolith.rs @@ -21,10 +21,10 @@ pub async fn run(ctx: &ProjectContext) -> Result<()> { crate::tasks::gen::generate_project(&ctx).await; migrate_nebula(ctx).await?; migrate_master_cluster(ctx).await?; - // migrate_pools(ctx).await?; - // migrate_dns(ctx).await?; - // migrate_cloudflare_workers(ctx).await?; - // migrate_cloudflare_tunnels(ctx).await?; + migrate_pools(ctx).await?; + migrate_dns(ctx).await?; + migrate_cloudflare_workers(ctx).await?; + migrate_cloudflare_tunnels(ctx).await?; migrate_s3(ctx).await?; Ok(()) } @@ -429,14 +429,14 @@ async fn migrate_dns(ctx: &ProjectContext) -> Result<()> { ) .await?; - copy_resource( - ctx, - &src_infra, - (None, "managed", "cloudflare_certificate_pack", "rivet_game"), - &mut dst, - (None, "managed", "cloudflare_certificate_pack", "rivet_game"), - ) - .await?; + // copy_resource( + // ctx, + // &src_infra, + // (None, "managed", "cloudflare_certificate_pack", "rivet_game"), + // &mut dst, + // (None, "managed", "cloudflare_certificate_pack", "rivet_game"), + // ) + // .await?; copy_resource( ctx, diff --git a/lib/bolt/core/src/tasks/infra/mod.rs b/lib/bolt/core/src/tasks/infra/mod.rs index 33df4a785d..bb9f529988 100644 --- a/lib/bolt/core/src/tasks/infra/mod.rs +++ b/lib/bolt/core/src/tasks/infra/mod.rs @@ -16,7 +16,13 @@ pub struct ExecutePlanOpts { } #[derive(Debug, Clone)] -pub enum PlanStep { +pub struct PlanStep { + pub name_id: &'static str, + pub kind: PlanStepKind, +} + +#[derive(Debug, Clone)] +pub enum PlanStepKind { Terraform { plan_id: String, @@ -38,10 +44,10 @@ pub enum PlanStep { Up, } -impl PlanStep { +impl PlanStepKind { async fn execute(&self, ctx: ProjectContext, opts: &ExecutePlanOpts) -> Result<()> { match self { - PlanStep::Terraform { plan_id, .. } => { + PlanStepKind::Terraform { plan_id, .. } => { let varfile_path = ctx.gen_tf_env_path(); let mut cmd = terraform::cli::build_command(&ctx, plan_id).await; @@ -55,7 +61,7 @@ impl PlanStep { terraform::output::clear_cache(&ctx, &plan_id).await; } - PlanStep::Salt { + PlanStepKind::Salt { filter, sls, config_opts, @@ -70,10 +76,10 @@ impl PlanStep { salt::cli::apply_all(&ctx, &apply_opts, config_opts).await?; } } - PlanStep::Migrate => { + PlanStepKind::Migrate => { tasks::migrate::up_all(&ctx).await?; } - PlanStep::Up => { + PlanStepKind::Up => { tasks::up::up_all( &ctx, tasks::up::UpOpts { @@ -90,7 +96,7 @@ impl PlanStep { async fn destroy(&self, ctx: ProjectContext, opts: &ExecutePlanOpts) -> Result<()> { match self { - PlanStep::Terraform { + PlanStepKind::Terraform { plan_id, needs_destroy, } => { @@ -111,7 +117,7 @@ impl PlanStep { terraform::output::clear_cache(&ctx, &plan_id).await; } - PlanStep::Salt { .. } | PlanStep::Migrate | PlanStep::Up => { + PlanStepKind::Salt { .. } | PlanStepKind::Migrate | PlanStepKind::Up => { // Do nothing } } @@ -120,70 +126,97 @@ impl PlanStep { } } -pub fn build_plan(ctx: &ProjectContext) -> Result> { +pub fn build_plan(ctx: &ProjectContext, start_at: Option) -> Result> { let mut plan = Vec::new(); // TLS - plan.push(PlanStep::Terraform { - plan_id: "tls".into(), - needs_destroy: true, + plan.push(PlanStep { + name_id: "tf-tls", + kind: PlanStepKind::Terraform { + plan_id: "tls".into(), + needs_destroy: true, + }, }); // Nebula - plan.push(PlanStep::Terraform { - plan_id: "nebula".into(), - needs_destroy: false, + plan.push(PlanStep { + name_id: "tf-nebula", + kind: PlanStepKind::Terraform { + plan_id: "nebula".into(), + needs_destroy: false, + }, }); // Master match ctx.ns().cluster.kind { ClusterKind::SingleNode { .. } => { - plan.push(PlanStep::Terraform { - plan_id: "master_local".into(), - needs_destroy: false, + plan.push(PlanStep { + name_id: "tf-master-local", + kind: PlanStepKind::Terraform { + plan_id: "master_local".into(), + needs_destroy: false, + }, }); } ClusterKind::Distributed { .. } => { - plan.push(PlanStep::Terraform { - plan_id: "master_cluster".into(), - needs_destroy: true, + plan.push(PlanStep { + name_id: "tf-master-cluster", + kind: PlanStepKind::Terraform { + plan_id: "master_cluster".into(), + needs_destroy: true, + }, }); } } // Pools - plan.push(PlanStep::Terraform { - plan_id: "pools".into(), - needs_destroy: true, + plan.push(PlanStep { + name_id: "tf-pools", + kind: PlanStepKind::Terraform { + plan_id: "pools".into(), + needs_destroy: true, + }, }); // DNS - plan.push(PlanStep::Terraform { - plan_id: "dns".into(), - needs_destroy: true, + plan.push(PlanStep { + name_id: "tf-dns", + kind: PlanStepKind::Terraform { + plan_id: "dns".into(), + needs_destroy: true, + }, }); // Cloudflare - plan.push(PlanStep::Terraform { - plan_id: "cloudflare_workers".into(), - needs_destroy: true, + plan.push(PlanStep { + name_id: "tf-cf-workers", + kind: PlanStepKind::Terraform { + plan_id: "cloudflare_workers".into(), + needs_destroy: true, + }, }); if let config::ns::DnsProvider::Cloudflare { access: Some(_), .. } = ctx.ns().dns.provider { - plan.push(PlanStep::Terraform { - plan_id: "cloudflare_tunnels".into(), - needs_destroy: true, + plan.push(PlanStep { + name_id: "tf-cf-tunnels", + kind: PlanStepKind::Terraform { + plan_id: "cloudflare_tunnels".into(), + needs_destroy: true, + }, }); } // Grafana if ctx.ns().grafana.is_some() { - plan.push(PlanStep::Terraform { - plan_id: "grafana".into(), - needs_destroy: true, + plan.push(PlanStep { + name_id: "tf-grafana", + kind: PlanStepKind::Terraform { + plan_id: "grafana".into(), + needs_destroy: true, + }, }); } @@ -191,55 +224,89 @@ pub fn build_plan(ctx: &ProjectContext) -> Result> { let s3_providers = &ctx.ns().s3.providers; if s3_providers.minio.is_some() { // Install Minio for s3_minio Terraform plan - plan.push(PlanStep::Salt { - filter: Some("G@roles:minio".into()), - sls: None, - config_opts: salt::config::BuildOpts { skip_s3: true }, + plan.push(PlanStep { + name_id: "salt-minio", + kind: PlanStepKind::Salt { + filter: Some("G@roles:minio".into()), + sls: None, + config_opts: salt::config::BuildOpts { skip_s3: true }, + }, }); - plan.push(PlanStep::Terraform { - plan_id: "s3_minio".into(), - needs_destroy: false, + plan.push(PlanStep { + name_id: "tf-s3-minio", + kind: PlanStepKind::Terraform { + plan_id: "s3_minio".into(), + needs_destroy: false, + }, }); } if s3_providers.backblaze.is_some() { - plan.push(PlanStep::Terraform { - plan_id: "s3_backblaze".into(), - needs_destroy: true, + plan.push(PlanStep { + name_id: "tf-s3-backblaze", + kind: PlanStepKind::Terraform { + plan_id: "s3_backblaze".into(), + needs_destroy: true, + }, }); } if s3_providers.aws.is_some() { - plan.push(PlanStep::Terraform { - plan_id: "s3_aws".into(), - needs_destroy: true, + plan.push(PlanStep { + name_id: "tf-s3-aws", + kind: PlanStepKind::Terraform { + plan_id: "s3_aws".into(), + needs_destroy: true, + }, }); } // Apply the rest of the Salt configs - plan.push(PlanStep::Salt { - filter: None, - sls: None, - config_opts: Default::default(), + plan.push(PlanStep { + name_id: "salt", + kind: PlanStepKind::Salt { + filter: None, + sls: None, + config_opts: Default::default(), + }, }); - plan.push(PlanStep::Terraform { - plan_id: "nomad".into(), - needs_destroy: false, + plan.push(PlanStep { + name_id: "tf-nomad", + kind: PlanStepKind::Terraform { + plan_id: "nomad".into(), + needs_destroy: false, + }, }); - plan.push(PlanStep::Migrate); + plan.push(PlanStep { + name_id: "migrate", + kind: PlanStepKind::Migrate, + }); - plan.push(PlanStep::Up); + plan.push(PlanStep { + name_id: "up", + kind: PlanStepKind::Up, + }); + + // Start at the specified step + if let Some(start_at) = start_at { + let idx = plan + .iter() + .position(|x| x.name_id == start_at) + .ok_or_else(|| anyhow!("invalid start_at value: {}", start_at))?; + + plan = plan[idx..].to_vec(); + } Ok(plan) } /// List all of the Terraform plans in use for the generated plan. pub fn all_terraform_plans(ctx: &ProjectContext) -> Result> { - let plan_ids = build_plan(ctx)? + let plan_ids = build_plan(ctx, None)? .into_iter() .flat_map(|x| { - if let PlanStep::Terraform { plan_id, .. } = x { + if let PlanStepKind::Terraform { plan_id, .. } = x.kind { Some(plan_id) } else { None @@ -260,8 +327,11 @@ pub async fn execute_plan( for (i, step) in plan.iter().enumerate() { eprintln!(); eprintln!(); - rivet_term::status::info("Executing", format!("({}/{}) {step:?}", i + 1, plan.len())); - step.execute(ctx.clone(), &opts).await?; + rivet_term::status::info( + "Executing", + format!("({}/{}) {}", i + 1, plan.len(), step.name_id), + ); + step.kind.execute(ctx.clone(), &opts).await?; } Ok(()) @@ -277,8 +347,11 @@ pub async fn destroy_plan( for (i, step) in plan.iter().enumerate().rev() { eprintln!(); eprintln!(); - rivet_term::status::info("Destroying", format!("({}/{}) {step:?}", i + 1, plan.len())); - step.destroy(ctx.clone(), &opts).await?; + rivet_term::status::info( + "Destroying", + format!("({}/{}) {}", i + 1, plan.len(), step.name_id), + ); + step.kind.destroy(ctx.clone(), &opts).await?; } Ok(()) diff --git a/lib/bolt/core/src/tasks/test.rs b/lib/bolt/core/src/tasks/test.rs index efa24c78df..9b454314d2 100644 --- a/lib/bolt/core/src/tasks/test.rs +++ b/lib/bolt/core/src/tasks/test.rs @@ -277,6 +277,7 @@ async fn run_test(svc_ctx: &ServiceContext, test_name: Option<&str>) -> TestResu let mut cmd = Command::new("cargo"); cmd.current_dir(svc_ctx.path()); cmd.env("RUSTFLAGS", "--cfg tokio_unstable"); + cmd.env("CARGO_TARGET_DIR", project_ctx.path().join("target")); cmd.arg("test"); if let Some(jobs) = project_ctx.config_local().rust.num_jobs { cmd.arg("--jobs").arg(jobs.to_string()); diff --git a/lib/bolt/core/src/tasks/up.rs b/lib/bolt/core/src/tasks/up.rs index 833a65354a..fa37e0d46c 100644 --- a/lib/bolt/core/src/tasks/up.rs +++ b/lib/bolt/core/src/tasks/up.rs @@ -65,7 +65,7 @@ pub async fn up_services>( opts: UpOpts, ) -> Result> { let event = utils::telemetry::build_event(ctx, "bolt_up").await?; - utils::telemetry::capture_event(ctx, event).await?; + utils::telemetry::capture_event(ctx, event)?; // let run_context = RunContext::Service; let build_context = BuildContext::Bin { @@ -260,16 +260,21 @@ pub async fn up_services>( svc_ctx: svc_ctx.clone().clone(), build_context, driver: match &build_plan { - ServiceBuildPlan::ExistingLocalBuild { output_path } - | ServiceBuildPlan::BuildLocally { output_path } => { - derive_local_build_driver(svc_ctx, output_path.clone()).await + ServiceBuildPlan::ExistingLocalBuild { exec_path } + | ServiceBuildPlan::BuildLocally { exec_path } => { + derive_local_build_driver(svc_ctx, exec_path.clone()).await } ServiceBuildPlan::ExistingUploadedBuild { build_key: artifact_key, + exec_path, } | ServiceBuildPlan::BuildAndUpload { build_key: artifact_key, - } => derive_uploaded_svc_driver(svc_ctx, artifact_key.clone()).await, + exec_path, + } => { + derive_uploaded_svc_driver(svc_ctx, artifact_key.clone(), exec_path.clone()) + .await + } ServiceBuildPlan::Docker { image_tag } => ExecServiceDriver::Docker { image: image_tag.clone(), force_pull: false, @@ -395,12 +400,12 @@ async fn build_svc(svc_ctx: &ServiceContext, optimization: BuildOptimization) { async fn derive_local_build_driver( svc_ctx: &ServiceContext, - output_path: PathBuf, + exec_path: PathBuf, ) -> ExecServiceDriver { match &svc_ctx.config().runtime { RuntimeKind::Rust {} => ExecServiceDriver::LocalBinaryArtifact { // Convert path to be relative to the project root - path: output_path + exec_path: exec_path .strip_prefix(svc_ctx.project().await.path()) .expect("rust binary path not inside of project dir") .to_owned(), @@ -419,10 +424,12 @@ async fn derive_local_build_driver( async fn derive_uploaded_svc_driver( svc_ctx: &ServiceContext, artifact_key: String, + exec_path: String, ) -> ExecServiceDriver { match &svc_ctx.config().runtime { RuntimeKind::Rust {} => ExecServiceDriver::UploadedBinaryArtifact { artifact_key, + exec_path, args: Vec::new(), }, RuntimeKind::CRDB { .. } diff --git a/lib/bolt/core/src/utils/telemetry.rs b/lib/bolt/core/src/utils/telemetry.rs index 899e53d487..f2f868a2fb 100644 --- a/lib/bolt/core/src/utils/telemetry.rs +++ b/lib/bolt/core/src/utils/telemetry.rs @@ -92,9 +92,14 @@ pub async fn build_event(ctx: &ProjectContext, name: &str) -> Result Result<()> { +pub fn capture_event(ctx: &ProjectContext, event: async_posthog::Event) -> Result<()> { if !ctx.ns().rivet.telemetry.disable { - build_client().capture(event).await?; + tokio::spawn(async move { + match build_client().capture(event).await { + Ok(_) => {} + Err(err) => println!("Failed to capture event: {err:?}"), + } + }); } Ok(()) diff --git a/lib/cache/build/Cargo.toml b/lib/cache/build/Cargo.toml index 36ab1b569e..a84d4a99b0 100644 --- a/lib/cache/build/Cargo.toml +++ b/lib/cache/build/Cargo.toml @@ -15,7 +15,7 @@ rivet-pools = { path = "../../pools" } rivet-util = { path = "../../util/core" } serde = { version = "1.0", features = ["derive"] } thiserror = "1.0" -tokio = { version = "1.21", features = ["full"] } +tokio = { version = "1.29", features = ["full"] } tracing = "0.1" types = { path = "../../types/core" } uuid = { version = "1", features = ["v4"] } diff --git a/lib/chirp/client/Cargo.toml b/lib/chirp/client/Cargo.toml index f58f4dac4b..09ecdf309d 100644 --- a/lib/chirp/client/Cargo.toml +++ b/lib/chirp/client/Cargo.toml @@ -19,8 +19,8 @@ rivet-pools = { path = "../../pools" } rivet-util = { path = "../../util/core" } serde = { version = "1.0", features = ["derive"] } thiserror = "1.0" -tokio = { version = "1.21", features = ["full"] } -tokio-util = "0.6" +tokio = { version = "1.29", features = ["full"] } +tokio-util = "0.7" tracing = "0.1" types = { path = "../../types/core" } urlencoding = "2.1" diff --git a/lib/chirp/client/src/client.rs b/lib/chirp/client/src/client.rs index f6cd7ac023..09a79e8a8b 100644 --- a/lib/chirp/client/src/client.rs +++ b/lib/chirp/client/src/client.rs @@ -65,12 +65,12 @@ impl SharedClient { redis_cache: RedisPool, region: String, ) -> SharedClientHandle { - let spawn_res = tokio::task::Builder::new() - .name("chirp_client::metrics_update_update") - .spawn(metrics::start_update_uptime()); - if let Err(err) = spawn_res { - tracing::error!(?err, "failed to spawn user_presence_touch task"); - } + // let spawn_res = tokio::task::Builder::new() + // .name("chirp_client::metrics_update_update") + // .spawn(metrics::start_update_uptime()); + // if let Err(err) = spawn_res { + // tracing::error!(?err, "failed to spawn user_presence_touch task"); + // } Arc::new(SharedClient { nats, @@ -553,6 +553,12 @@ impl Client { .map_err(|x| ClientError::CreateSubscription(x.into()))?; // Manually publish message + tracing::trace!( + ?subject, + ?reply, + req_len = req_buf.len(), + "publishing rpc call to nats" + ); self.nats .publish_with_reply_and_headers( subject.clone(), @@ -768,86 +774,86 @@ impl Client { // Write message to Redis stream let span = self.perf().start(M::PERF_LABEL_WRITE_STREAM).await; - let mut backoff = rivet_util::Backoff::default_infinite(); - loop { - // Ignore for infinite backoff - backoff.tick().await; + // let mut backoff = rivet_util::Backoff::default_infinite(); + // loop { + // // Ignore for infinite backoff + // backoff.tick().await; - let mut conn = self.redis_chirp.clone(); - - let mut pipe = redis::pipe(); - pipe.atomic(); + let mut conn = self.redis_chirp.clone(); - // Write to stream - let topic_key = redis_keys::message_topic(M::NAME); - pipe.xadd_maxlen( - &topic_key, - redis::streams::StreamMaxlen::Approx(8192), - "*", - &[("m", &message_buf)], - ) - .ignore(); + let mut pipe = redis::pipe(); + pipe.atomic(); - // Write tails for all permuted parameters - for wildcard_parameters in &permuted_wildcard_parameters { - // Write tail - if let Some(ttl) = M::TAIL_TTL { - // Write single tail message + // Write to stream + let topic_key = redis_keys::message_topic(M::NAME); + pipe.xadd_maxlen( + &topic_key, + redis::streams::StreamMaxlen::Approx(8192), + "*", + &[("m", &message_buf)], + ) + .ignore(); + + // Write tails for all permuted parameters + for wildcard_parameters in &permuted_wildcard_parameters { + // Write tail + if let Some(ttl) = M::TAIL_TTL { + // Write single tail message + + let tail_key = redis_keys::message_tail::(wildcard_parameters); + + // Save message + pipe.hset( + &tail_key, + redis_keys::message_tail::REQUEST_ID, + req_id.to_string(), + ) + .ignore(); + pipe.hset(&tail_key, redis_keys::message_tail::TS, ts) + .ignore(); + pipe.hset(&tail_key, redis_keys::message_tail::BODY, message_buf) + .ignore(); - let tail_key = redis_keys::message_tail::(wildcard_parameters); + // Automatically expire + pipe.expire(&tail_key, ttl as usize).ignore(); + + // Write history + if M::HISTORY { + let history_key = redis_keys::message_history::(wildcard_parameters); + + // Remove old entries 10% of the time. + // + // This is a slow operation, so we perform this + // sparingly. + if rand::thread_rng().gen_bool(0.1) { + pipe.cmd("ZREMRANGEBYSCORE") + .arg(&history_key) + .arg("-inf") + .arg(rivet_util::timestamp::now() - ttl * 1000) + .ignore(); + } // Save message - pipe.hset( - &tail_key, - redis_keys::message_tail::REQUEST_ID, - req_id.to_string(), - ) - .ignore(); - pipe.hset(&tail_key, redis_keys::message_tail::TS, ts) - .ignore(); - pipe.hset(&tail_key, redis_keys::message_tail::BODY, message_buf) - .ignore(); + pipe.zadd(&history_key, message_buf, ts).ignore(); // Automatically expire - pipe.expire(&tail_key, ttl as usize).ignore(); - - // Write history - if M::HISTORY { - let history_key = redis_keys::message_history::(wildcard_parameters); - - // Remove old entries 10% of the time. - // - // This is a slow operation, so we perform this - // sparingly. - if rand::thread_rng().gen_bool(0.1) { - pipe.cmd("ZREMRANGEBYSCORE") - .arg(&history_key) - .arg("-inf") - .arg(rivet_util::timestamp::now() - ttl * 1000) - .ignore(); - } - - // Save message - pipe.zadd(&history_key, message_buf, ts).ignore(); - - // Automatically expire - pipe.expire(&history_key, ttl as usize).ignore(); - } else { - } + pipe.expire(&history_key, ttl as usize).ignore(); + } else { } } + } - // Write to Redis - match pipe.query_async::<_, ()>(&mut conn).await { - Ok(_) => { - tracing::debug!("write to redis stream succeeded"); - break; - } - Err(err) => { - tracing::error!(?err, "failed to write to redis"); - } + // Write to Redis + match pipe.query_async::<_, ()>(&mut conn).await { + Ok(_) => { + tracing::debug!("write to redis stream succeeded"); + // break; + } + Err(err) => { + tracing::error!(?err, "failed to write to redis"); } } + // } span.end(); } @@ -863,34 +869,39 @@ impl Client { // // Infinite backoff since we want to wait until the service reboots. let span = self.perf().start(M::PERF_LABEL_PUBLISH).await; - let mut backoff = rivet_util::Backoff::default_infinite(); - loop { - // Ignore for infinite backoff - backoff.tick().await; - - let nats_subject = nats_subject.to_owned(); - let message_buf = message_buf.to_vec(); - - if let Err(err) = self - .nats - .publish(nats_subject.clone(), message_buf.into()) - .await - { - tracing::warn!(?err, "publish message failed, trying again"); - continue; - } - - // TODO: Most messages don't need to be flushed immediately. We - // should add an option to enable high performance message - // publishing to enable flushing immediately after publishing. - // if let Err(err) = self.nats.flush().await { - // tracing::error!(?err, "flush message failed, the message probably sent"); - // break; - // } - - tracing::debug!("publish nats message succeeded"); - break; + // let mut backoff = rivet_util::Backoff::default_infinite(); + // loop { + // // Ignore for infinite backoff + // backoff.tick().await; + + let nats_subject = nats_subject.to_owned(); + let message_buf = message_buf.to_vec(); + + tracing::trace!( + ?nats_subject, + message_len = message_buf.len(), + "publishing message to nats" + ); + if let Err(err) = self + .nats + .publish(nats_subject.clone(), message_buf.into()) + .await + { + tracing::warn!(?err, "publish message failed, trying again"); + // continue; } + + // // TODO: Most messages don't need to be flushed immediately. We + // // should add an option to enable high performance message + // // publishing to enable flushing immediately after publishing. + // // if let Err(err) = self.nats.flush().await { + // // tracing::error!(?err, "flush message failed, the message probably sent"); + // // break; + // // } + + // tracing::debug!("publish nats message succeeded"); + // break; + // } span.end(); } diff --git a/lib/chirp/client/src/message.rs b/lib/chirp/client/src/message.rs index 92381f6848..bbe2df5205 100644 --- a/lib/chirp/client/src/message.rs +++ b/lib/chirp/client/src/message.rs @@ -22,6 +22,10 @@ pub fn serialize_message_params(parameters: &[impl AsRef], join: &str) -> S .map(|x| { if x == "*" { x.to_string() + } else if x.is_empty() { + // Provide a null value since NATS requires a valid subject + // TODO: Find a better null placeholder that doesn't conflict with manual value + "__NULL__".to_string() } else { urlencoding::encode(x).to_string() } @@ -35,11 +39,15 @@ where M: Message, S: AsRef, { - format!( - "chirp.msg.{}.{}", - M::NAME, - serialize_message_params(parameters, ".") - ) + if parameters.is_empty() { + format!("chirp.msg.{}", M::NAME) + } else { + format!( + "chirp.msg.{}.{}", + M::NAME, + serialize_message_params(parameters, ".") + ) + } } /// A message received from a Chirp subscription. diff --git a/lib/chirp/perf/Cargo.toml b/lib/chirp/perf/Cargo.toml index b4482c78b0..45a2e10feb 100644 --- a/lib/chirp/perf/Cargo.toml +++ b/lib/chirp/perf/Cargo.toml @@ -12,7 +12,7 @@ types = { path = "../../types/core" } rivet-metrics = { path = "../../metrics" } rivet-pools = { path = "../../pools" } thiserror = "1.0" -tokio = { version = "1.21", features = ["full", "tracing"] } +tokio = { version = "1.29", features = ["full", "tracing"] } tracing = "0.1" [dependencies.uuid] diff --git a/lib/chirp/worker-attributes/src/lib.rs b/lib/chirp/worker-attributes/src/lib.rs index 094d3b58d5..b5073f216e 100644 --- a/lib/chirp/worker-attributes/src/lib.rs +++ b/lib/chirp/worker-attributes/src/lib.rs @@ -97,48 +97,58 @@ pub fn worker(attr: TokenStream, item: TokenStream) -> TokenStream { // Extract the inner request type let ty = match &*pat.ty { - syn::Type::Path(path) => { - let final_segment = path.path.segments.last().unwrap(); - if final_segment.ident != "OperationContext" { - return error( - final_segment.ident.span(), - "argument must be a `OperationContext`", - ); + syn::Type::Reference(syn::TypeReference { + elem: inner_type, + mutability, + .. + }) => { + if let Some(mutability) = mutability { + return error(mutability.span(), "context cannot be mutable"); } - // Read the generic type - match &final_segment.arguments { - syn::PathArguments::AngleBracketed(args) => { - if args.args.len() != 1 { + match &**inner_type { + syn::Type::Path(path) => { + let final_segment = path.path.segments.last().unwrap(); + if final_segment.ident != "OperationContext" { return error( - final_segment.span(), - "must have exactly 1 generic argument", + final_segment.ident.span(), + "argument must be a `OperationContext`", ); } - // Match the correct generic type - match &args.args[0] { - syn::GenericArgument::Type(ty) => ty, - arg => { - return error(arg.span(), "generic argument must be a type"); + // Read the generic type + match &final_segment.arguments { + syn::PathArguments::AngleBracketed(args) => { + if args.args.len() != 1 { + return error( + final_segment.span(), + "must have exactly 1 generic argument", + ); + } + + // Match the correct generic type + match &args.args[0] { + syn::GenericArgument::Type(ty) => ty, + arg => { + return error( + arg.span(), + "generic argument must be a type", + ); + } + } } + _ => return error(final_segment.span(), "invalid generic args"), } } - _ => { - return error(final_segment.span(), "invalid generic args"); - } + _ => return error(pat.ty.span(), "unsupported type"), } } - _ => { - return error(pat.ty.span(), "unsupported type"); - } + _ => return error(pat.ty.span(), "unsupported type, must be a reference"), }; (ident, ty) } - _ => { - return error(input.sig.inputs[0].span(), "invalid function argument"); - } + _ => return error(input.sig.inputs[0].span(), "invalid function argument"), }; // Derive res type @@ -178,9 +188,7 @@ pub fn worker(attr: TokenStream, item: TokenStream) -> TokenStream { } } } - _ => { - return error(final_segment.span(), "invalid generic args"); - } + _ => return error(final_segment.span(), "invalid generic args"), } } _ => return error(ty.span(), "invalid return type"), diff --git a/lib/chirp/worker-attributes/tests/test.rs b/lib/chirp/worker-attributes/tests/test.rs index d5824fc945..cf0a554e4b 100644 --- a/lib/chirp/worker-attributes/tests/test.rs +++ b/lib/chirp/worker-attributes/tests/test.rs @@ -7,7 +7,7 @@ struct TestRequest {} struct TestResponse {} #[chirp_worker_attributes::worker] -async fn worker(ctx: OperationContext) -> GlobalResult { +async fn worker(ctx: &OperationContext) -> GlobalResult { tracing::info!(body = ?req, "hello, world!"); Ok(TestResponse {}) diff --git a/lib/chirp/worker-attributes/tests/test_err.rs b/lib/chirp/worker-attributes/tests/test_err.rs index daf1ff9075..8f5d8d3c18 100644 --- a/lib/chirp/worker-attributes/tests/test_err.rs +++ b/lib/chirp/worker-attributes/tests/test_err.rs @@ -13,7 +13,7 @@ enum TestError { } #[chirp_worker_attributes::worker] -async fn worker(ctx: OperationContext) -> GlobalResult { +async fn worker(ctx: &OperationContext) -> GlobalResult { tracing::info!(body = ?req, "hello, world!"); do_something()?; diff --git a/lib/chirp/worker/Cargo.toml b/lib/chirp/worker/Cargo.toml index 06e1211535..9f82ce0771 100644 --- a/lib/chirp/worker/Cargo.toml +++ b/lib/chirp/worker/Cargo.toml @@ -32,7 +32,7 @@ rivet-runtime = { path = "../../runtime" } rivet-util = { path = "../../util/core" } serde_json = "1.0" thiserror = "1.0" -tokio = { version = "1.21", features = ["full", "tracing"] } +tokio = { version = "1.29", features = ["full", "tracing"] } tracing = "0.1" types = { path = "../../types/core" } tracing-subscriber = { version = "0.3", optional = true, default-features = false, features = ["fmt", "json", "ansi"] } # Used with attribute diff --git a/lib/chirp/worker/src/manager.rs b/lib/chirp/worker/src/manager.rs index 1c7227ba69..340a507936 100644 --- a/lib/chirp/worker/src/manager.rs +++ b/lib/chirp/worker/src/manager.rs @@ -1,6 +1,6 @@ use chirp_metrics as metrics; use futures_util::StreamExt; -use global_error::{GlobalResult, GlobalError}; +use global_error::{GlobalError, GlobalResult}; use prost::Message; use redis::{self, AsyncCommands}; use rivet_connection::Connection; @@ -276,7 +276,7 @@ where .arg(pending_retry_time.as_millis() as i64) .arg("-") .arg("+") - .arg(16usize) + .arg(1usize) .query_async::<_, redis::streams::StreamPendingCountReply>(redis_chirp_conn) .await { @@ -451,7 +451,7 @@ where let read_options = redis::streams::StreamReadOptions::default() .group(&group, &consumer) .block(30_000) - .count(16); + .count(1); let res = match redis_chirp_conn .xread_options::<_, _, redis::streams::StreamReadReply>(keys, &[">"], &read_options) .await @@ -857,36 +857,42 @@ where self: Arc, req: &Request, ) -> GlobalResult { - // Will retry 4 times. This will take a maximum of 15 seconds. - let mut backoff = rivet_util::Backoff::new(5, Some(4), 1_000, 1_000); - loop { - let res = self - .worker - .handle(req.op_ctx()) - .instrument(tracing::info_span!("handle", name = %W::NAME)) - .await; - - // Attempt to retry the request with backoff - if matches!( - res, - Err(GlobalError::Internal { - retry_immediately: true, - .. - }) - ) { - tracing::info!("ticking request retry backoff"); - - if backoff.tick().await { - tracing::warn!("retry request failed too many times"); - return res; - } else { - tracing::info!("retrying request"); - } - } else { - // Return result immediately - return res; - } - } + self.worker + .handle(req.op_ctx()) + .instrument(tracing::info_span!("handle", name = %W::NAME)) + .await + + // // TODO: Add back + // // Will retry 4 times. This will take a maximum of 15 seconds. + // let mut backoff = rivet_util::Backoff::new(5, Some(4), 1_000, 1_000); + // loop { + // let res = self + // .worker + // .handle(req.op_ctx()) + // .instrument(tracing::info_span!("handle", name = %W::NAME)) + // .await; + + // // Attempt to retry the request with backoff + // if matches!( + // res, + // Err(GlobalError::Internal { + // retry_immediately: true, + // .. + // }) + // ) { + // tracing::info!("ticking request retry backoff"); + + // if backoff.tick().await { + // tracing::warn!("retry request failed too many times"); + // return res; + // } else { + // tracing::info!("retrying request"); + // } + // } else { + // // Return result immediately + // return res; + // } + // } } #[tracing::instrument(level = "trace", skip_all)] @@ -1028,11 +1034,11 @@ where #[tracing::instrument] async fn consumer_ack(self: Arc, msg_meta: RedisMessageMeta) { let mut backoff = rivet_util::Backoff::default(); - loop { - if backoff.tick().await { - tracing::error!("acking stream message failed too many times, aborting"); - return; - } + // loop { + // if backoff.tick().await { + // tracing::error!("acking stream message failed too many times, aborting"); + // return; + // } // Acknowledge the messages let mut redis_chirp = self.redis_chirp.clone(); @@ -1042,13 +1048,13 @@ where { Ok(_) => { tracing::info!(?msg_meta, "acknowledged stream message"); - break; + // break; } Err(err) => { tracing::error!(?err, "failed to ack message"); } } - } + // } } } diff --git a/lib/chirp/worker/src/test.rs b/lib/chirp/worker/src/test.rs index a6fe9b9502..18cca88a9e 100644 --- a/lib/chirp/worker/src/test.rs +++ b/lib/chirp/worker/src/test.rs @@ -74,8 +74,4 @@ impl TestCtx { pub async fn redis_user_presence(&self) -> Result { self.op_ctx.redis_user_presence().await } - - pub async fn redis_search(&self) -> Result { - self.op_ctx.redis_search().await - } } diff --git a/lib/connection/src/lib.rs b/lib/connection/src/lib.rs index 24633a1598..588f50390f 100644 --- a/lib/connection/src/lib.rs +++ b/lib/connection/src/lib.rs @@ -86,10 +86,6 @@ impl Connection { self.pools.redis("redis-user-presence") } - pub async fn redis_search(&self) -> Result { - self.pools.redis("redis-search") - } - pub fn perf(&self) -> &chirp_perf::PerfCtx { self.client.perf() } diff --git a/lib/convert/src/convert/game.rs b/lib/convert/src/convert/game.rs index 0ae85fa3af..4cd0c3cd54 100644 --- a/lib/convert/src/convert/game.rs +++ b/lib/convert/src/convert/game.rs @@ -10,13 +10,9 @@ pub fn handle(game: &backend::game::Game) -> GlobalResult { name_id: game.name_id.to_owned(), display_name: game.display_name.to_owned(), logo_url: util::route::game_logo( - game.logo_upload_id.map(|x| x.as_uuid()), - game.logo_file_name.as_ref(), - ), + &game), banner_url: util::route::game_banner( - game.banner_upload_id.map(|x| x.as_uuid()), - game.banner_file_name.as_ref(), - ), + &game), }) } @@ -36,13 +32,9 @@ pub fn summary( name_id: game.name_id.to_owned(), display_name: game.display_name.to_owned(), logo_url: util::route::game_logo( - game.logo_upload_id.map(|x| x.as_uuid()), - game.logo_file_name.as_ref(), - ), + &game), banner_url: util::route::game_banner( - game.banner_upload_id.map(|x| x.as_uuid()), - game.banner_file_name.as_ref(), - ), + &game), url: game_url, developer: Box::new(convert::group::handle(dev_team, true)?), }) diff --git a/lib/convert/src/convert/group.rs b/lib/convert/src/convert/group.rs index 00e733d153..95243c0339 100644 --- a/lib/convert/src/convert/group.rs +++ b/lib/convert/src/convert/group.rs @@ -12,10 +12,7 @@ pub fn handle(team: &backend::team::Team, is_developer: bool) -> GlobalResult { pub presences_ctx: &'a fetch::identity::PresencesCtx, pub teams_ctx: &'a fetch::identity::TeamsCtx, @@ -229,11 +218,7 @@ pub fn profile( identity_id: user_id, display_name: user.display_name.to_owned(), account_number: user.account_number as i32, - avatar_url: util::route::user_avatar( - &user.avatar_id, - user.profile_upload_id.map(|x| x.as_uuid()), - user.profile_file_name.as_ref(), - ), + avatar_url: util::route::user_avatar(&user), presence: Some(Box::new(presence( user_presence, &pctx.presences_ctx.games, @@ -293,14 +278,12 @@ pub fn presence( public_metadata: game_activity .public_metadata .as_ref() - .map(|s| serde_json::from_str(s)) - .transpose()?, + .and_then(|s| serde_json::from_str(s).ok()), mutual_metadata: if is_mutual_following { game_activity .friend_metadata .as_ref() - .map(|s| serde_json::from_str(s)) - .transpose()? + .and_then(|s| serde_json::from_str(s).ok()) } else { None }, diff --git a/lib/convert/src/convert/mod.rs b/lib/convert/src/convert/mod.rs index ee3e1c052f..b8d2ccc76f 100644 --- a/lib/convert/src/convert/mod.rs +++ b/lib/convert/src/convert/mod.rs @@ -8,6 +8,7 @@ pub mod game; pub mod group; pub mod identity; +#[derive(Debug)] pub struct GameWithNamespaceIds { pub namespace_ids: Vec, pub game: backend::game::Game, diff --git a/lib/convert/src/fetch/identity.rs b/lib/convert/src/fetch/identity.rs index 3146b3998c..ba4ccd7a76 100644 --- a/lib/convert/src/fetch/identity.rs +++ b/lib/convert/src/fetch/identity.rs @@ -9,12 +9,14 @@ use rivet_operation::prelude::*; use crate::{convert, fetch}; +#[derive(Debug)] pub struct TeamsCtx { pub user_teams: user::team_list::Response, pub teams: Vec, pub dev_teams: team_dev::get::Response, } +#[derive(Debug)] pub struct PresencesCtx { pub res: user_presence::get::Response, pub games: Vec, @@ -334,23 +336,24 @@ pub async fn mutual_follows( current_user_id: Uuid, raw_user_ids: Vec, ) -> GlobalResult { - // Converts to hashmap to remove duplicate queries - let queries = raw_user_ids - .clone() - .into_iter() - .flat_map(|user_id| [(current_user_id, user_id), (user_id, current_user_id)]) - .collect::>() - .into_iter() - .map(|(user_a_id, user_b_id)| user_follow::get::request::Query { - follower_user_id: Some(user_a_id.into()), - following_user_id: Some(user_b_id.into()), - }) - .collect::>(); - - op!([ctx] user_follow_get { - queries: queries, - }) - .await + return Ok(user_follow::get::Response { follows: vec![] }); + // // Converts to hashmap to remove duplicate queries + // let queries = raw_user_ids + // .clone() + // .into_iter() + // .flat_map(|user_id| [(current_user_id, user_id), (user_id, current_user_id)]) + // .collect::>() + // .into_iter() + // .map(|(user_a_id, user_b_id)| user_follow::get::request::Query { + // follower_user_id: Some(user_a_id.into()), + // following_user_id: Some(user_b_id.into()), + // }) + // .collect::>(); + + // op!([ctx] user_follow_get { + // queries: queries, + // }) + // .await } async fn linked_accounts( diff --git a/lib/convert/src/impls/cloud/mod.rs b/lib/convert/src/impls/cloud/mod.rs index 741ae4df14..715770edb0 100644 --- a/lib/convert/src/impls/cloud/mod.rs +++ b/lib/convert/src/impls/cloud/mod.rs @@ -2,9 +2,9 @@ use proto::{ backend::{self, pkg::*}, perf, }; +use rivet_api::models as new_models; use rivet_cloud_server::models; use rivet_operation::prelude::*; -use rivet_api::models as new_models; use crate::{ApiFrom, ApiTryFrom, ApiTryInto}; @@ -65,13 +65,9 @@ impl ApiTryFrom for models::GameHandle { name_id: value.name_id.to_owned(), display_name: value.display_name.to_owned(), logo_url: util::route::game_logo( - value.logo_upload_id.map(|x| *x), - value.logo_file_name.as_ref(), - ), + &value), banner_url: util::route::game_banner( - value.banner_upload_id.map(|x| *x), - value.banner_file_name.as_ref(), - ), + &value), }) } } diff --git a/lib/convert/src/impls/cloud/version/matchmaker/game_mode.rs b/lib/convert/src/impls/cloud/version/matchmaker/game_mode.rs index 9d1c45412f..7372030317 100644 --- a/lib/convert/src/impls/cloud/version/matchmaker/game_mode.rs +++ b/lib/convert/src/impls/cloud/version/matchmaker/game_mode.rs @@ -4,7 +4,7 @@ use proto::backend::{self, pkg::*}; use rivet_api::models; use rivet_operation::prelude::*; -use crate::{ApiInto, ApiTryFrom, ApiTryInto}; +use crate::{ApiFrom, ApiInto, ApiTryFrom, ApiTryInto}; pub fn game_mode_to_proto( name_id: String, @@ -139,8 +139,25 @@ pub fn game_mode_to_proto( max_players_normal: max_players_normal.try_into()?, max_players_direct: max_players_direct.try_into()?, max_players_party: max_players_party.try_into()?, + listable: game_mode.listable.unwrap_or(true), runtime, + + find_config: game_mode + .find_config + .clone() + .map(|x| ApiTryInto::try_into(*x)) + .transpose()?, + join_config: game_mode + .join_config + .clone() + .map(|x| ApiTryInto::try_into(*x)) + .transpose()?, + create_config: game_mode + .create_config + .clone() + .map(|x| ApiTryInto::try_into(*x)) + .transpose()?, }) } @@ -234,9 +251,26 @@ pub fn game_mode_to_openapi( max_players: Some(value.max_players_normal.try_into()?), max_players_direct: Some(value.max_players_direct.try_into()?), max_players_party: Some(value.max_players_party.try_into()?), + listable: Some(value.listable), docker: Some(Box::new(docker)), + find_config: value + .find_config + .map(ApiTryInto::try_into) + .transpose()? + .map(Box::new), + join_config: value + .join_config + .map(ApiTryInto::try_into) + .transpose()? + .map(Box::new), + create_config: value + .create_config + .map(ApiTryInto::try_into) + .transpose()? + .map(Box::new), + // Overrides idle_lobbies: None, tier: None, @@ -344,3 +378,204 @@ impl ApiTryFrom }) } } + +impl ApiFrom + for backend::matchmaker::IdentityRequirement +{ + fn api_from( + value: models::CloudVersionMatchmakerGameModeIdentityRequirement, + ) -> backend::matchmaker::IdentityRequirement { + match value { + models::CloudVersionMatchmakerGameModeIdentityRequirement::None => { + backend::matchmaker::IdentityRequirement::None + } + models::CloudVersionMatchmakerGameModeIdentityRequirement::Guest => { + backend::matchmaker::IdentityRequirement::Guest + } + models::CloudVersionMatchmakerGameModeIdentityRequirement::Registered => { + backend::matchmaker::IdentityRequirement::Registered + } + } + } +} + +impl ApiFrom + for models::CloudVersionMatchmakerGameModeIdentityRequirement +{ + fn api_from(value: backend::matchmaker::IdentityRequirement) -> Self { + match value { + backend::matchmaker::IdentityRequirement::None => { + models::CloudVersionMatchmakerGameModeIdentityRequirement::None + } + backend::matchmaker::IdentityRequirement::Guest => { + models::CloudVersionMatchmakerGameModeIdentityRequirement::Guest + } + backend::matchmaker::IdentityRequirement::Registered => { + models::CloudVersionMatchmakerGameModeIdentityRequirement::Registered + } + } + } +} + +impl ApiTryFrom + for backend::matchmaker::VerificationConfig +{ + type Error = GlobalError; + + fn try_from( + value: models::CloudVersionMatchmakerGameModeVerificationConfig, + ) -> GlobalResult { + Ok(backend::matchmaker::VerificationConfig { + url: value.url, + headers: value.headers, + }) + } +} + +impl ApiTryFrom + for models::CloudVersionMatchmakerGameModeVerificationConfig +{ + type Error = GlobalError; + + fn try_from(value: backend::matchmaker::VerificationConfig) -> GlobalResult { + Ok(models::CloudVersionMatchmakerGameModeVerificationConfig { + url: value.url, + headers: value.headers, + }) + } +} + +impl ApiTryFrom + for backend::matchmaker::FindConfig +{ + type Error = GlobalError; + + fn try_from(value: models::CloudVersionMatchmakerGameModeFindConfig) -> GlobalResult { + Ok(backend::matchmaker::FindConfig { + enabled: value.enabled, + identity_requirement: ApiInto::::api_into( + value.identity_requirement, + ) as i32, + verification_config: value + .verification_config + .map(|x| ApiTryInto::try_into(*x)) + .transpose()?, + }) + } +} + +impl ApiTryFrom + for models::CloudVersionMatchmakerGameModeFindConfig +{ + type Error = GlobalError; + + fn try_from(value: backend::matchmaker::FindConfig) -> GlobalResult { + Ok(models::CloudVersionMatchmakerGameModeFindConfig { + enabled: value.enabled, + identity_requirement: internal_unwrap_owned!( + backend::matchmaker::IdentityRequirement::from_i32(value.identity_requirement), + "invalid identity requirement variant" + ) + .api_into(), + verification_config: value + .verification_config + .map(ApiTryInto::try_into) + .transpose()? + .map(Box::new), + }) + } +} + +impl ApiTryFrom + for backend::matchmaker::JoinConfig +{ + type Error = GlobalError; + + fn try_from(value: models::CloudVersionMatchmakerGameModeJoinConfig) -> GlobalResult { + Ok(backend::matchmaker::JoinConfig { + enabled: value.enabled, + identity_requirement: ApiInto::::api_into( + value.identity_requirement, + ) as i32, + verification_config: value + .verification_config + .map(|x| ApiTryInto::try_into(*x)) + .transpose()?, + }) + } +} + +impl ApiTryFrom + for models::CloudVersionMatchmakerGameModeJoinConfig +{ + type Error = GlobalError; + + fn try_from(value: backend::matchmaker::JoinConfig) -> GlobalResult { + Ok(models::CloudVersionMatchmakerGameModeJoinConfig { + enabled: value.enabled, + identity_requirement: internal_unwrap_owned!( + backend::matchmaker::IdentityRequirement::from_i32(value.identity_requirement), + "invalid identity requirement variant" + ) + .api_into(), + verification_config: value + .verification_config + .map(ApiTryInto::try_into) + .transpose()? + .map(Box::new), + }) + } +} + +impl ApiTryFrom + for backend::matchmaker::CreateConfig +{ + type Error = GlobalError; + + fn try_from(value: models::CloudVersionMatchmakerGameModeCreateConfig) -> GlobalResult { + if let Some(max_lobbies_per_identity) = value.max_lobbies_per_identity { + assert_with!( + max_lobbies_per_identity >= 0, + MATCHMAKER_INVALID_VERSION_CONFIG, + error = "`create_config.max_lobbies_per_identity` out of bounds" + ); + } + + Ok(backend::matchmaker::CreateConfig { + identity_requirement: ApiInto::::api_into( + value.identity_requirement, + ) as i32, + verification_config: value + .verification_config + .map(|x| ApiTryInto::try_into(*x)) + .transpose()?, + enable_public: value.enable_public, + enable_private: value.enable_private, + max_lobbies_per_identity: value.max_lobbies_per_identity.map(ApiTryInto::try_into).transpose()?, + }) + } +} + +impl ApiTryFrom + for models::CloudVersionMatchmakerGameModeCreateConfig +{ + type Error = GlobalError; + + fn try_from(value: backend::matchmaker::CreateConfig) -> GlobalResult { + Ok(models::CloudVersionMatchmakerGameModeCreateConfig { + identity_requirement: internal_unwrap_owned!( + backend::matchmaker::IdentityRequirement::from_i32(value.identity_requirement), + "invalid identity requirement variant" + ) + .api_into(), + verification_config: value + .verification_config + .map(ApiTryInto::try_into) + .transpose()? + .map(Box::new), + enable_public: value.enable_public, + enable_private: value.enable_private, + max_lobbies_per_identity: value.max_lobbies_per_identity.map(ApiTryInto::try_into).transpose()?, + }) + } +} \ No newline at end of file diff --git a/lib/convert/src/impls/cloud/version/matchmaker/lobby_group.rs b/lib/convert/src/impls/cloud/version/matchmaker/lobby_group.rs index 6c30784ae0..78b6b8657e 100644 --- a/lib/convert/src/impls/cloud/version/matchmaker/lobby_group.rs +++ b/lib/convert/src/impls/cloud/version/matchmaker/lobby_group.rs @@ -35,8 +35,13 @@ impl ApiTryFrom for backend::matchmake max_players_normal: value.max_players_normal as u32, max_players_direct: value.max_players_direct as u32, max_players_party: value.max_players_party as u32, + listable: true, runtime: Some((*value.runtime).try_into()?), + + find_config: None, + join_config: None, + create_config: None, }) } } diff --git a/lib/convert/src/impls/cloud/version/mod.rs b/lib/convert/src/impls/cloud/version/mod.rs index b351ccb732..a824be04e3 100644 --- a/lib/convert/src/impls/cloud/version/mod.rs +++ b/lib/convert/src/impls/cloud/version/mod.rs @@ -33,7 +33,8 @@ pub async fn config_to_proto( }, kv: value.kv.map(|_| backend::kv::VersionConfig {}), identity: value.identity.map(|x| (*x).try_into()).transpose()?, - module: todo!(), + // TODO: + module: None, }) } diff --git a/lib/convert/src/impls/mod.rs b/lib/convert/src/impls/mod.rs index 91c5b8dfca..4405cfe668 100644 --- a/lib/convert/src/impls/mod.rs +++ b/lib/convert/src/impls/mod.rs @@ -43,4 +43,20 @@ mod num { std::convert::TryInto::try_into(v) } } + + impl ApiTryFrom for i32 { + type Error = std::num::TryFromIntError; + + fn try_from(v: u64) -> Result { + std::convert::TryInto::try_into(v) + } + } + + impl ApiTryFrom for u64 { + type Error = std::num::TryFromIntError; + + fn try_from(v: i32) -> Result { + std::convert::TryInto::try_into(v) + } + } } diff --git a/lib/health-checks/Cargo.toml b/lib/health-checks/Cargo.toml index 44a400cea8..886a1e5303 100644 --- a/lib/health-checks/Cargo.toml +++ b/lib/health-checks/Cargo.toml @@ -12,7 +12,7 @@ rivet-pools = { path = "../pools" } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" thiserror = "1.0" -tokio = { version = "1.21", features = ["tracing"] } +tokio = { version = "1.29", features = ["tracing"] } tracing = "0.1" uuid = { version = "1", features = ["v4"] } diff --git a/lib/nomad-util/Cargo.toml b/lib/nomad-util/Cargo.toml index 4cc94c4770..4da6abae79 100644 --- a/lib/nomad-util/Cargo.toml +++ b/lib/nomad-util/Cargo.toml @@ -15,6 +15,6 @@ rivet-pools = { path = "../pools" } serde = { version = "1.0", features = ["derive"] } serde_json = { version = "1.0", features = ["raw_value"] } thiserror = "1.0" -tokio = { version = "1.21", features = ["full"] } +tokio = { version = "1.29", features = ["full"] } tracing = "0.1" diff --git a/lib/operation/core/Cargo.toml b/lib/operation/core/Cargo.toml index fb40076ee6..0cc3195145 100644 --- a/lib/operation/core/Cargo.toml +++ b/lib/operation/core/Cargo.toml @@ -23,6 +23,6 @@ rivet-pools = { path = "../../pools" } rivet-util = { path = "../../util/core" } serde_json = "1.0" thiserror = "1.0" -tokio = { version = "1.21", features = ["full", "tracing"] } +tokio = { version = "1.29", features = ["full", "tracing"] } tracing = "0.1" types = { path = "../../types/core" } diff --git a/lib/operation/core/src/lib.rs b/lib/operation/core/src/lib.rs index 05dad6afd8..22a17126d0 100644 --- a/lib/operation/core/src/lib.rs +++ b/lib/operation/core/src/lib.rs @@ -90,7 +90,14 @@ where // TODO: Throw dedicated "timed out" error here // Process the request - let res = tokio::time::timeout(O::TIMEOUT, O::handle(self.wrap::(body)?)).await?; + let req_op_ctx = self.wrap::(body)?; + let timeout_fut = tokio::time::timeout(O::TIMEOUT, O::handle(req_op_ctx)); + let res = tokio::task::Builder::new() + .name("operation::handle") + .spawn(timeout_fut)? + .await??; + + tracing::info!(?res, "operation response"); // Record metrics { @@ -123,17 +130,18 @@ where .observe(dt); } - // Submit perf - let chirp = self.conn.chirp().clone(); - tokio::task::Builder::new().name("operation::perf").spawn( - async move { - // HACK: Force submit performance metrics after delay in order to ensure - // all spans have ended appropriately - tokio::time::sleep(Duration::from_secs(5)).await; - chirp.perf().submit().await; - } - .instrument(tracing::info_span!("operation_perf")), - )?; + // TODO: Add back + // // Submit perf + // let chirp = self.conn.chirp().clone(); + // tokio::task::Builder::new().name("operation::perf").spawn( + // async move { + // // HACK: Force submit performance metrics after delay in order to ensure + // // all spans have ended appropriately + // tokio::time::sleep(Duration::from_secs(5)).await; + // chirp.perf().submit().await; + // } + // .instrument(tracing::info_span!("operation_perf")), + // )?; res } @@ -285,10 +293,6 @@ where self.conn.redis_user_presence().await } - pub async fn redis_search(&self) -> Result { - self.conn.redis_search().await - } - pub fn perf(&self) -> &chirp_perf::PerfCtx { self.conn.perf() } diff --git a/lib/pools/Cargo.toml b/lib/pools/Cargo.toml index 74e89cc618..3d171ccb68 100644 --- a/lib/pools/Cargo.toml +++ b/lib/pools/Cargo.toml @@ -6,27 +6,26 @@ authors = ["Rivet Gaming, LLC "] license = "Apache-2.0" [dependencies] -async-nats = "0.29" +async-nats = "0.31" funty = "=1.1.0" # Fixes issue with sqlx dependency, see https://github.com/bitvecto-rs/bitvec/issues/105#issuecomment-778570981 global-error = { path = "../global-error" } lazy_static = "1.4" rand = "0.8" rivet-metrics = { path = "../metrics" } thiserror = "1.0" -tokio = { version = "1.21", features = ["tracing"] } -tokio-util = "0.6" +tokio = { version = "1.29", features = ["tracing"] } +tokio-util = "0.7" tracing = "0.1" [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false features = [ - "runtime-tokio-native-tls", + "runtime-tokio", "postgres", "macros", "uuid", "json", - "tls", ] [dependencies.redis] diff --git a/lib/pools/src/lib.rs b/lib/pools/src/lib.rs index c24645495b..1e280184df 100644 --- a/lib/pools/src/lib.rs +++ b/lib/pools/src/lib.rs @@ -75,7 +75,7 @@ async fn nats_from_env(client_name: String) -> Result, Error> { async move { match event { async_nats::Event::Connected => { - tracing::debug!(?server_addrs, "nats reconnected"); + tracing::info!(?server_addrs, "nats reconnected"); } async_nats::Event::Disconnected => { tracing::error!(?server_addrs, "nats disconnected"); @@ -100,12 +100,12 @@ async fn nats_from_env(client_name: String) -> Result, Error> { // NATS has built in backoff with jitter (with max of 4s), so // once the connection is established, we never have to worry // about disconnections that aren't handled by NATS. - tracing::debug!(?server_addrs, "nats connecting"); + tracing::info!(?server_addrs, "nats connecting"); let conn = options .connect(&server_addrs[..]) .await .map_err(Error::BuildNats)?; - tracing::debug!(?server_addrs, "nats connected"); + tracing::info!(?server_addrs, "nats connected"); Ok(Some(conn)) } else { @@ -120,40 +120,53 @@ fn crdb_from_env(client_name: String) -> Result, Error if let Some(svc_name_screaming) = key.strip_prefix("CRDB_URL_") { let svc_name = svc_name_screaming.to_lowercase().replace("_", "-"); - tracing::debug!(%url, "crdb creating connection"); + tracing::info!(%url, "crdb creating connection"); let client_name = client_name.clone(); let pool = sqlx::postgres::PgPoolOptions::new() // The default connection timeout is too high .acquire_timeout(Duration::from_secs(15)) + .max_lifetime(Duration::from_secs(60 * 5)) // Remove connections after a while in order to reduce load // on CRDB after bursts .idle_timeout(Some(Duration::from_secs(60))) // Open a connection // immediately on startup - .min_connections(1) + .min_connections(0) // Raise the cap, since this is effectively the amount of // simultaneous requests we can handle. See // https://www.cockroachlabs.com/docs/stable/connection-pooling.html - .max_connections(512) + .max_connections(20_000) // Speeds up requests at the expense of potential // failures // .test_before_acquire(false) - .after_connect({ - let url = url.clone(); - move |conn, _| { - let client_name = client_name.clone(); - let url = url.clone(); - Box::pin(async move { - tracing::debug!(%url, "crdb connected"); - sqlx::query("SET application_name = $1;") - .bind(&client_name) - .execute(conn) - .await?; - Ok(()) - }) - } - }) + // .after_connect(|conn, _meta| { + // Box::pin(async move { + // tracing::info!("pg connected"); + // Ok(()) + // }) + // }) + // .after_release(|conn, meta| { + // Box::pin(async move { + // tracing::info!("pg released"); + // Ok(false) + // }) + // }) + // .after_connect({ + // let url = url.clone(); + // move |conn, _| { + // let client_name = client_name.clone(); + // let url = url.clone(); + // Box::pin(async move { + // tracing::info!(%url, "crdb connected"); + // sqlx::query("SET application_name = $1;") + // .bind(&client_name) + // .execute(conn) + // .await?; + // Ok(()) + // }) + // } + // }) .connect_lazy(&url) .map_err(Error::BuildSqlx)?; @@ -177,13 +190,13 @@ async fn redis_from_env() -> Result, Error> { let pool = if let Some(existing) = existing_pools.get(&url) { existing.clone() } else { - tracing::debug!(%url, "redis connecting"); + tracing::info!(%url, "redis connecting"); let conn = redis::Client::open(url.as_str()) .map_err(Error::BuildRedis)? .get_tokio_connection_manager() .await .map_err(Error::BuildRedis)?; - tracing::debug!(%url, "redis connected"); + tracing::info!(%url, "redis connected"); conn }; diff --git a/lib/pools/src/pools.rs b/lib/pools/src/pools.rs index 619f30f265..8a4778b4e7 100644 --- a/lib/pools/src/pools.rs +++ b/lib/pools/src/pools.rs @@ -100,6 +100,16 @@ impl PoolsInner { async fn record_metrics(&self) { use crate::metrics::*; + let mut dbs = self + .crdb_map() + .clone() + .into_iter() + .map(|(k, v)| (k, v.size(), v.num_idle())) + .filter(|x| x.1 > 0) + .collect::>(); + dbs.sort_by_key(|(_, size, _)| *size); + dbs.reverse(); + // CRDB for (db_name, pool) in self.crdb_map() { let label = &[db_name.as_str()]; diff --git a/lib/runtime/Cargo.toml b/lib/runtime/Cargo.toml index 1b36d438e9..0989f3febd 100644 --- a/lib/runtime/Cargo.toml +++ b/lib/runtime/Cargo.toml @@ -10,7 +10,7 @@ console-subscriber = "0.1" lazy_static = "1.4" rivet-metrics = { path = "../metrics" } thiserror = "1.0" -tokio = { version = "1.21", features = ["full", "tracing"] } +tokio = { version = "1.29", features = ["full", "tracing"] } tracing = "0.1" tracing-subscriber = { version = "0.3", default-features = false, features = ["fmt", "json", "ansi"] } # Used with attribute diff --git a/lib/s3-util/Cargo.toml b/lib/s3-util/Cargo.toml index 79bd355205..1ae703da3a 100644 --- a/lib/s3-util/Cargo.toml +++ b/lib/s3-util/Cargo.toml @@ -13,5 +13,5 @@ aws-smithy-types = { version = "0.52" } http = "0.2" thiserror = "1.0" tracing = "0.1" -tokio = { version = "1.21" } +tokio = { version = "1.29" } diff --git a/lib/s3-util/src/lib.rs b/lib/s3-util/src/lib.rs index cd3bc66b5d..84f0142b0a 100644 --- a/lib/s3-util/src/lib.rs +++ b/lib/s3-util/src/lib.rs @@ -33,7 +33,7 @@ pub enum EndpointKind { External, } -#[derive(Debug)] +#[derive(Clone, Copy, Debug)] pub enum Provider { Minio, Backblaze, diff --git a/lib/util/core/Cargo.toml b/lib/util/core/Cargo.toml index 6896abdaf1..4c1804f180 100644 --- a/lib/util/core/Cargo.toml +++ b/lib/util/core/Cargo.toml @@ -24,7 +24,7 @@ rivet-util-macros = { path = "../macros" } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" thiserror = "1.0" -tokio = { version = "1.21", default-features = false, features = ["time", "sync", "fs", "parking_lot", "test-util", "macros"] } +tokio = { version = "1.29", default-features = false, features = ["time", "sync", "fs", "parking_lot", "test-util", "macros"] } types = { path = "../../types/core" } uuid = { version = "1", features = ["v4", "serde"] } diff --git a/lib/util/core/src/route.rs b/lib/util/core/src/route.rs index b526b17b44..13ff7c84f4 100644 --- a/lib/util/core/src/route.rs +++ b/lib/util/core/src/route.rs @@ -1,3 +1,5 @@ +use global_error::prelude::*; +use types::rivet::backend; use uuid::Uuid; use crate::env::{domain_main, origin_hub}; @@ -30,33 +32,44 @@ pub fn game_profile(game_name_id: &str) -> String { format!("{}/games/{}", origin_hub(), game_name_id) } -pub fn user_avatar(avatar_id: &str, upload_id: Option, file_name: Option<&String>) -> String { - if let (Some(upload_id), Some(file_name)) = (upload_id, file_name) { +pub fn user_avatar(user: &backend::user::User) -> String { + if let (Some(upload_id), Some(file_name), Some(provider)) = ( + user.profile_upload_id, + user.profile_file_name.as_ref(), + user.profile_provider, + ) { format!( - "https://media.{}/user-avatar/{}/{}", + "https://media.{}{}/user-avatar/{}/{}", domain_main(), + provider_str(provider), upload_id, file_name ) } else { - format!("https://assets.rivet.gg/avatars/{}.png", avatar_id) + format!("https://assets2.rivet.gg/avatars/{}.png", user.avatar_id) } } -pub fn custom_avatar(upload_id: Uuid, file_name: &str) -> String { +pub fn custom_avatar(upload_id: Uuid, file_name: &str, provider: i32) -> String { format!( - "https://media.{}/user-avatar/{}/{}", + "https://media.{}/{}/user-avatar/{}/{}", domain_main(), + provider_str(provider), upload_id, file_name ) } -pub fn team_avatar(upload_id: Option, file_name: Option<&String>) -> Option { - if let (Some(upload_id), Some(file_name)) = (upload_id, file_name) { +pub fn team_avatar(team: &backend::team::Team) -> Option { + if let (Some(upload_id), Some(file_name), Some(provider)) = ( + team.profile_upload_id, + team.profile_file_name.as_ref(), + team.profile_provider, + ) { Some(format!( - "https://media.{}/team-avatar/{}/{}", + "https://media.{}/{}/team-avatar/{}/{}", domain_main(), + provider_str(provider), upload_id, file_name )) @@ -65,11 +78,16 @@ pub fn team_avatar(upload_id: Option, file_name: Option<&String>) -> Optio } } -pub fn game_logo(upload_id: Option, file_name: Option<&String>) -> Option { - if let (Some(upload_id), Some(file_name)) = (upload_id, file_name) { +pub fn game_logo(game: &backend::game::Game) -> Option { + if let (Some(upload_id), Some(file_name), Some(provider)) = ( + game.logo_upload_id, + game.logo_file_name.as_ref(), + game.logo_provider, + ) { Some(format!( - "https://media.{}/game-logo/{}/{}", + "https://media.{}/{}/game-logo/{}/{}", domain_main(), + provider_str(provider), upload_id, file_name )) @@ -78,11 +96,16 @@ pub fn game_logo(upload_id: Option, file_name: Option<&String>) -> Option< } } -pub fn game_banner(upload_id: Option, file_name: Option<&String>) -> Option { - if let (Some(upload_id), Some(file_name)) = (upload_id, file_name) { +pub fn game_banner(game: &backend::game::Game) -> Option { + if let (Some(upload_id), Some(file_name), Some(provider)) = ( + game.banner_upload_id, + game.banner_file_name.as_ref(), + game.banner_provider, + ) { Some(format!( - "https://media.{}/game-banner/{}/{}", + "https://media.{}/{}/game-banner/{}/{}", domain_main(), + provider_str(provider), upload_id, file_name )) @@ -96,9 +119,18 @@ pub fn identity_game_link(link_token: &str) -> String { } pub fn cloud_device_link(link_token: &str) -> String { - format!("{}/developer/devices/link/{}", origin_hub(), link_token) + format!("{}/devices/link/{}", origin_hub(), link_token) } pub fn team_billing(team_id: Uuid) -> String { format!("{}/groups/{}/billing", origin_hub(), team_id) } + +fn provider_str(provider: i32) -> &'static str { + // Default gracefully + match backend::upload::Provider::from_i32(provider).unwrap_or_default() { + backend::upload::Provider::Minio => "minio", + backend::upload::Provider::Backblaze => "backblaze", + backend::upload::Provider::Aws => "aws", + } +} diff --git a/lib/util/env/src/lib.rs b/lib/util/env/src/lib.rs index 2b3d6dee62..6f04d441e8 100644 --- a/lib/util/env/src/lib.rs +++ b/lib/util/env/src/lib.rs @@ -5,17 +5,17 @@ pub async fn read_secret(key: &[impl AsRef]) -> Result]) -> Result, std::env::VarError> { +pub async fn read_secret_opt( + key: &[impl AsRef], +) -> Result, std::env::VarError> { let env_var = read_secret(key).await; - + match env_var { Ok(v) => Ok(Some(v)), - Err(var_error) => { - match var_error { - std::env::VarError::NotPresent => Ok(None), - std::env::VarError::NotUnicode(_) => Err(var_error), - } - } + Err(var_error) => match var_error { + std::env::VarError::NotPresent => Ok(None), + std::env::VarError::NotUnicode(_) => Err(var_error), + }, } } diff --git a/proto/backend/game.proto b/proto/backend/game.proto index 58f7a076d6..4c5849d588 100644 --- a/proto/backend/game.proto +++ b/proto/backend/game.proto @@ -3,6 +3,7 @@ syntax = "proto3"; package rivet.backend.game; import "proto/common.proto"; +import "proto/backend/upload.proto"; message Game { rivet.common.Uuid game_id = 1; @@ -13,10 +14,13 @@ message Game { rivet.common.Uuid developer_team_id = 6; string description = 7; repeated string tags = 8; + optional rivet.common.Uuid logo_upload_id = 9; optional string logo_file_name = 10; + optional upload.Provider logo_provider = 15; optional rivet.common.Uuid banner_upload_id = 11; optional string banner_file_name = 12; + optional upload.Provider banner_provider = 16; optional string plan_code = 13; optional rivet.common.Uuid subscription_id = 14; diff --git a/proto/backend/matchmaker.proto b/proto/backend/matchmaker.proto index d92e33a3d6..89b0b00bfa 100644 --- a/proto/backend/matchmaker.proto +++ b/proto/backend/matchmaker.proto @@ -41,8 +41,13 @@ message LobbyGroup { uint32 max_players_normal = 102; uint32 max_players_direct = 103; uint32 max_players_party = 104; + bool listable = 105; LobbyRuntime runtime = 201; + + optional FindConfig find_config = 301; + optional JoinConfig join_config = 302; + optional CreateConfig create_config = 303; } message LobbyRuntime { @@ -102,6 +107,39 @@ message LobbyRuntime { }; } +enum IdentityRequirement { + NONE = 0; + GUEST = 1; + REGISTERED = 2; +} + +message VerificationConfig { + string url = 1; + map headers = 2; +} + +message FindConfig { + bool enabled = 1; + IdentityRequirement identity_requirement = 2; + optional VerificationConfig verification_config = 3; +} + +message JoinConfig { + bool enabled = 1; + IdentityRequirement identity_requirement = 2; + optional VerificationConfig verification_config = 3; +} + +message CreateConfig { + IdentityRequirement identity_requirement = 1; + optional VerificationConfig verification_config = 2; + + bool enable_public = 3; + bool enable_private = 4; + + optional uint64 max_lobbies_per_identity = 5; +} + // MARK: Game Version Config Context // Context required to publish a new version. message VersionConfigCtx { @@ -148,6 +186,11 @@ message LobbyRuntimeMeta { // MARK: Lobby State message Lobby { + enum Publicity { + PUBLIC = 0; + PRIVATE = 1; + } + reserved 10; rivet.common.Uuid lobby_id = 1; @@ -161,6 +204,9 @@ message Lobby { bool is_closed = 11; rivet.common.Uuid namespace_id = 9; optional rivet.common.Uuid create_ray_id = 12; + optional rivet.common.Uuid creator_user_id = 15; + bool is_custom = 16; + Publicity publicity = 17; uint32 max_players_normal = 101; uint32 max_players_direct = 102; diff --git a/proto/backend/matchmaker/query.proto b/proto/backend/matchmaker/query.proto index c104d5b717..56c2f11ca9 100644 --- a/proto/backend/matchmaker/query.proto +++ b/proto/backend/matchmaker/query.proto @@ -23,4 +23,3 @@ message AutoCreate { rivet.common.Uuid lobby_group_id = 1; rivet.common.Uuid region_id = 2; } - diff --git a/proto/backend/net.proto b/proto/backend/net.proto index 869936d49f..060ce92c4b 100644 --- a/proto/backend/net.proto +++ b/proto/backend/net.proto @@ -13,3 +13,15 @@ message IpInfo { double longitude = 3; } +enum HttpMethod { + GET = 0; + POST = 1; + PUT = 2; + DELETE = 3; +} + +message ExternalRequestConfig { + string url = 1; + HttpMethod method = 2; + map headers = 3; +} diff --git a/proto/backend/team.proto b/proto/backend/team.proto index 00794eec2a..6342377299 100644 --- a/proto/backend/team.proto +++ b/proto/backend/team.proto @@ -4,6 +4,7 @@ package rivet.backend.team; import "proto/common.proto"; import "proto/backend/user.proto"; +import "proto/backend/upload.proto"; message Team { reserved 5, 8; @@ -14,6 +15,7 @@ message Team { string bio = 4; optional rivet.common.Uuid profile_upload_id = 9; optional string profile_file_name = 10; + optional upload.Provider profile_provider = 11; int64 create_ts = 6; Publicity publicity = 7; } diff --git a/proto/backend/user.proto b/proto/backend/user.proto index 6e3471c966..9004b243e2 100644 --- a/proto/backend/user.proto +++ b/proto/backend/user.proto @@ -3,6 +3,7 @@ syntax = "proto3"; package rivet.backend.user; import "proto/common.proto"; +import "proto/backend/upload.proto"; message User { reserved 5, 9; @@ -13,6 +14,7 @@ message User { string avatar_id = 4; optional rivet.common.Uuid profile_upload_id = 10; optional string profile_file_name = 11; + optional upload.Provider profile_provider = 14; int64 join_ts = 6; string bio = 7; bool is_admin = 8; diff --git a/shell.nix b/shell.nix index fbcc93de4a..a6d47230d0 100644 --- a/shell.nix +++ b/shell.nix @@ -46,7 +46,7 @@ in redis # For the redis-cli # Runtimes - nodejs-slim # Required for Fern + nodejs # Required for Fern # Compilers clang diff --git a/svc/Cargo.lock b/svc/Cargo.lock index 77caa4870a..be8497feea 100644 --- a/svc/Cargo.lock +++ b/svc/Cargo.lock @@ -2,6 +2,15 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "addr2line" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +dependencies = [ + "gimli", +] + [[package]] name = "adler" version = "1.0.2" @@ -26,24 +35,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f" dependencies = [ "cfg-if", + "getrandom", "once_cell", "version_check", ] [[package]] name = "aho-corasick" -version = "1.0.2" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43f6cb1bf222025340178f382c426f13757b2960e89779dfcb319c32542a5a41" +checksum = "6748e8def348ed4d14996fa801f4122cd763fff530258cdc03f64b25f89d3a5a" dependencies = [ "memchr", ] [[package]] name = "allocator-api2" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56fc6cf8dc8c4158eed8649f9b8b0ea1518eb62b544fe9490d66fa0b349eafe9" +checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" [[package]] name = "analytics-worker" @@ -80,9 +90,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.71" +version = "1.0.75" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8" +checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" [[package]] name = "api-admin" @@ -645,6 +655,7 @@ version = "0.0.1" dependencies = [ "api-helper", "async-trait", + "bytes", "captcha-hcaptcha-config-get", "captcha-request", "captcha-verify", @@ -662,6 +673,7 @@ dependencies = [ "game-get", "game-namespace-get", "game-namespace-resolve-url", + "game-user-get", "http", "hyper", "job-run-get", @@ -672,6 +684,7 @@ dependencies = [ "mm-lobby-get", "mm-lobby-list-for-namespace", "mm-lobby-player-count", + "mm-lobby-state-get", "prost 0.10.4", "region-get", "region-recommend", @@ -693,10 +706,12 @@ dependencies = [ "serde_json", "thiserror", "token-create", + "token-revoke", "tokio", "tracing", "tracing-subscriber", "url", + "user-identity-get", "uuid", ] @@ -897,17 +912,15 @@ checksum = "bddcadddf5e9015d310179a59bb28c4d4b9920ad0f11e8e14dbadf654890c9a6" [[package]] name = "async-nats" -version = "0.29.0" +version = "0.31.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1174495e436c928905018f10a36160f7a8a6786450f50f4ce7fba05d1539704c" +checksum = "8257238e2a3629ee5618502a75d1b91f8017c24638c75349fc8d2d80cf1f7c4c" dependencies = [ - "async-nats-tokio-rustls-deps", - "base64 0.13.1", - "base64-url", + "base64 0.21.3", "bytes", "futures", "http", - "itoa 1.0.6", + "itoa 1.0.9", "memchr", "nkeys", "nuid", @@ -917,29 +930,20 @@ dependencies = [ "ring", "rustls-native-certs 0.6.3", "rustls-pemfile", + "rustls-webpki", "serde", "serde_json", "serde_nanos", "serde_repr", "thiserror", - "time 0.3.22", + "time 0.3.28", "tokio", "tokio-retry", + "tokio-rustls 0.24.1", "tracing", "url", ] -[[package]] -name = "async-nats-tokio-rustls-deps" -version = "0.24.0-ALPHA.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cdefe54cd7867d937c0a507d2a3a830af410044282cd3e4002b5b7860e1892e" -dependencies = [ - "rustls 0.21.2", - "tokio", - "webpki 0.22.0", -] - [[package]] name = "async-posthog" version = "0.2.3" @@ -955,13 +959,13 @@ dependencies = [ [[package]] name = "async-trait" -version = "0.1.68" +version = "0.1.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9ccdd8f2a161be9bd5c023df56f1b2a0bd1d83872ae53b71a84a12c9bf6e842" +checksum = "bc00ceb34980c03614e35a3a4e218276a0a824e911d07651cd0d858a51e8c0f0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.29", ] [[package]] @@ -972,9 +976,9 @@ checksum = "2ce4f10ea3abcd6617873bae9f91d1c5332b4a778bd9ce34d0cd517474c1de82" [[package]] name = "atoi" -version = "1.0.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7c57d12312ff59c811c0643f4d80830505833c9ffaebd193d819392b265be8e" +checksum = "f28d99ec8bfea296261ca1af174f24225171fea9664ba9003cbebee704810528" dependencies = [ "num-traits", ] @@ -1038,7 +1042,7 @@ dependencies = [ "aws-types", "bytes", "bytes-utils", - "fastrand", + "fastrand 1.9.0", "http", "http-body", "tokio-stream", @@ -1076,8 +1080,8 @@ dependencies = [ "once_cell", "percent-encoding", "regex", - "sha2 0.10.7", - "time 0.3.22", + "sha2", + "time 0.3.28", "tracing", ] @@ -1122,7 +1126,7 @@ dependencies = [ "md-5", "pin-project-lite", "sha1 0.10.5", - "sha2 0.10.7", + "sha2", "tracing", ] @@ -1137,7 +1141,7 @@ dependencies = [ "aws-smithy-http-tower 0.41.0", "aws-smithy-types 0.41.0", "bytes", - "fastrand", + "fastrand 1.9.0", "http", "http-body", "hyper", @@ -1161,7 +1165,7 @@ dependencies = [ "aws-smithy-http-tower 0.52.0", "aws-smithy-types 0.52.0", "bytes", - "fastrand", + "fastrand 1.9.0", "http", "http-body", "hyper", @@ -1274,10 +1278,10 @@ version = "0.41.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7c7f957a2250cc0fa4ccf155e00aeac9a81f600df7cd4ecc910c75030e6534f5" dependencies = [ - "itoa 1.0.6", + "itoa 1.0.9", "num-integer", "ryu", - "time 0.3.22", + "time 0.3.28", ] [[package]] @@ -1287,10 +1291,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "987b1e37febb9bd409ca0846e82d35299e572ad8279bc404778caeb5fc05ad56" dependencies = [ "base64-simd", - "itoa 1.0.6", + "itoa 1.0.9", "num-integer", "ryu", - "time 0.3.22", + "time 0.3.28", ] [[package]] @@ -1320,19 +1324,19 @@ dependencies = [ [[package]] name = "axum" -version = "0.6.18" +version = "0.6.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8175979259124331c1d7bf6586ee7e0da434155e4b2d48ec2c8386281d8df39" +checksum = "3b829e4e32b91e643de6eafe82b1d90675f5874230191a4ffbc1b336dec4d6bf" dependencies = [ "async-trait", "axum-core", - "bitflags", + "bitflags 1.3.2", "bytes", "futures-util", "http", "http-body", "hyper", - "itoa 1.0.6", + "itoa 1.0.9", "matchit", "memchr", "mime", @@ -1363,6 +1367,21 @@ dependencies = [ "tower-service", ] +[[package]] +name = "backtrace" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + [[package]] name = "base64" version = "0.13.1" @@ -1371,9 +1390,9 @@ checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" [[package]] name = "base64" -version = "0.21.2" +version = "0.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "604178f6c5c21f02dc555784810edfb88d34ac2c73b2eae109655649ee73ce3d" +checksum = "414dcefbc63d77c526a76b3afcf6fbb9b5e2791c19c3aa2297733208750c6e53" [[package]] name = "base64-simd" @@ -1384,20 +1403,11 @@ dependencies = [ "simd-abstraction", ] -[[package]] -name = "base64-url" -version = "1.4.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67a99c239d0c7e77c85dddfa9cebce48704b3c49550fcd3b84dd637e4484899f" -dependencies = [ - "base64 0.13.1", -] - [[package]] name = "base64ct" -version = "1.1.1" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6b4d9b1225d28d360ec6a231d65af1fd99a2a095154c8040689617290569c5c" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" [[package]] name = "bcrypt" @@ -1424,12 +1434,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] -name = "block-buffer" -version = "0.9.0" +name = "bitflags" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" dependencies = [ - "generic-array", + "serde", ] [[package]] @@ -1458,15 +1468,17 @@ dependencies = [ "heck 0.3.3", "serde", "serde_json", - "toml 0.7.4", + "strum 0.25.0", + "strum_macros 0.25.2", + "toml 0.7.6", "uuid", ] [[package]] name = "bstr" -version = "1.5.0" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a246e68bb43f6cd9db24bea052a53e40405417c5fb372e3d1a8a7f770a564ef5" +checksum = "6798148dccfbff0fae41c7574d2fa8f1ef3492fba0face179de5d8d447d67b05" dependencies = [ "memchr", ] @@ -1555,6 +1567,9 @@ name = "bytes" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" +dependencies = [ + "serde", +] [[package]] name = "bytes-utils" @@ -1622,9 +1637,12 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.79" +version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +dependencies = [ + "libc", +] [[package]] name = "cdn-namespace-auth-user-remove" @@ -2182,7 +2200,7 @@ dependencies = [ "serde", "thiserror", "tokio", - "tokio-util 0.6.10", + "tokio-util 0.7.8", "tracing", "types", "urlencoding", @@ -2259,7 +2277,7 @@ version = "0.1.0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.29", ] [[package]] @@ -2544,9 +2562,9 @@ dependencies = [ [[package]] name = "console-subscriber" -version = "0.1.9" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57ab2224a0311582eb03adba4caaf18644f7b1f10a760803a803b9b605187fc7" +checksum = "d4cf42660ac07fcebed809cfe561dd8730bcd35b075215e6479c516bcd0d11cb" dependencies = [ "console-api", "crossbeam-channel", @@ -2578,9 +2596,9 @@ dependencies = [ [[package]] name = "const-oid" -version = "0.6.2" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d6f2aa4d0537bcc1c74df8755072bd31c1ef1a3a1b85a68e8404a8c353b7b8b" +checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f" [[package]] name = "core-foundation" @@ -2600,18 +2618,33 @@ checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" [[package]] name = "cpufeatures" -version = "0.2.8" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03e69e28e9f7f77debdedbaafa2866e1de9ba56df55a8bd7cfc724c25a09987c" +checksum = "a17b76ff3a4162b0b27f354a0c87015ddad39d35f9c0c36607a3bdd175dde1f1" dependencies = [ "libc", ] +[[package]] +name = "crc" +version = "3.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86ec7a15cbe22e59248fc7eadb1907dab5ba09372595da4d73dd805ed4417dfe" +dependencies = [ + "crc-catalog", +] + +[[package]] +name = "crc-catalog" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cace84e55f07e7301bae1c519df89cdad8cc3cd868413d3fdbdeca9ff3db484" + [[package]] name = "crc32c" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dfea2db42e9927a3845fb268a10a72faed6d416065f77873f05e411457c363e" +checksum = "d8f48d60e5b4d2c53d5c2b1d8a58c849a70ae5e5509b08a48d047e3b65714a74" dependencies = [ "rustc_version", ] @@ -2671,7 +2704,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "626ae34994d3d8d668f4269922248239db4ae42d538b14c398b74a52208e8086" dependencies = [ "csv-core", - "itoa 1.0.6", + "itoa 1.0.9", "ryu", "serde", ] @@ -2696,15 +2729,29 @@ dependencies = [ [[package]] name = "curve25519-dalek" -version = "3.2.0" +version = "4.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b9fdf9972b2bd6af2d913799d9ebc165ea4d2e65878e329d9c6b372c4491b61" +checksum = "f711ade317dd348950a9910f81c5947e3d8907ebd2b83f76203ff1807e6a2bc2" dependencies = [ - "byteorder", - "digest 0.9.0", - "rand_core 0.5.1", + "cfg-if", + "cpufeatures", + "curve25519-dalek-derive", + "digest", + "fiat-crypto", + "platforms", + "rustc_version", "subtle", - "zeroize", +] + +[[package]] +name = "curve25519-dalek-derive" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83fdaf97f4804dcebfa5862639bc9ce4121e82140bec2a987ac5140294865b5b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.29", ] [[package]] @@ -2738,9 +2785,9 @@ dependencies = [ [[package]] name = "darling" -version = "0.20.1" +version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0558d22a7b463ed0241e993f76f09f30b126687447751a8638587b864e4b3944" +checksum = "0209d94da627ab5605dcccf08bb18afa5009cfbef48d8a8b7d7bdbc79be25c5e" dependencies = [ "darling_core", "darling_macro", @@ -2748,27 +2795,27 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.20.1" +version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab8bfa2e259f8ee1ce5e97824a3c55ec4404a0d772ca7fa96bf19f0752a046eb" +checksum = "177e3443818124b357d8e76f53be906d60937f0d3a90773a664fa63fa253e621" dependencies = [ "fnv", "ident_case", "proc-macro2", "quote", "strsim", - "syn 2.0.18", + "syn 2.0.29", ] [[package]] name = "darling_macro" -version = "0.20.1" +version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29a358ff9f12ec09c3e61fef9b5a9902623a695a46a917b07f269bff1445611a" +checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" dependencies = [ "darling_core", "quote", - "syn 2.0.18", + "syn 2.0.29", ] [[package]] @@ -2793,20 +2840,22 @@ dependencies = [ [[package]] name = "der" -version = "0.4.5" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79b71cca7d95d7681a4b3b9cdf63c8dbc3730d0584c2c74e31416d64a90493f4" +checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" dependencies = [ "const-oid", + "pem-rfc7468", + "zeroize", ] [[package]] -name = "digest" -version = "0.9.0" +name = "deranged" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +checksum = "f2696e8a945f658fd14dc3b87242e6b80cd0f36ff04ea560fa39082368847946" dependencies = [ - "generic-array", + "serde", ] [[package]] @@ -2815,31 +2864,12 @@ version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ - "block-buffer 0.10.4", + "block-buffer", + "const-oid", "crypto-common", "subtle", ] -[[package]] -name = "dirs" -version = "4.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059" -dependencies = [ - "dirs-sys", -] - -[[package]] -name = "dirs-sys" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" -dependencies = [ - "libc", - "redox_users", - "winapi", -] - [[package]] name = "dotenvy" version = "0.15.7" @@ -2848,30 +2878,33 @@ checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" [[package]] name = "ed25519" -version = "1.5.3" +version = "2.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91cff35c70bba8a626e3185d8cd48cc11b5437e1a5bcd15b9b5fa3c64b6dfee7" +checksum = "60f6d271ca33075c88028be6f04d502853d63a5ece419d269c15315d4fc1cf1d" dependencies = [ "signature", ] [[package]] name = "ed25519-dalek" -version = "1.0.1" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c762bae6dcaf24c4c84667b8579785430908723d5c889f469d76a41d59cc7a9d" +checksum = "7277392b266383ef8396db7fdeb1e77b6c52fed775f5df15bb24f35b72156980" dependencies = [ "curve25519-dalek", "ed25519", - "sha2 0.9.9", - "zeroize", + "sha2", + "signature", ] [[package]] name = "either" -version = "1.8.1" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" +checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" +dependencies = [ + "serde", +] [[package]] name = "email-address-parser" @@ -2938,31 +2971,37 @@ dependencies = [ [[package]] name = "encoding_rs" -version = "0.8.32" +version = "0.8.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071a31f4ee85403370b58aca746f01041ede6f0da2730960ad001edc2b71b394" +checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" dependencies = [ "cfg-if", ] +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + [[package]] name = "erased-serde" -version = "0.3.25" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f2b0c2380453a92ea8b6c8e5f64ecaafccddde8ceab55ff7a8ac1029f894569" +checksum = "6c138974f9d5e7fe373eb04df7cae98833802ae4b11c24ac7039a21d5af4b26c" dependencies = [ "serde", ] [[package]] name = "errno" -version = "0.3.1" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" +checksum = "136526188508e25c6fef639d7927dfb3e0e3084488bf202267829cf7fc23dbdd" dependencies = [ "errno-dragonfly", "libc", - "windows-sys 0.48.0", + "windows-sys", ] [[package]] @@ -2975,12 +3014,52 @@ dependencies = [ "libc", ] +[[package]] +name = "etcetera" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "136d1b5283a1ab77bd9257427ffd09d8667ced0570b6f938942bc7568ed5b943" +dependencies = [ + "cfg-if", + "home", + "windows-sys", +] + [[package]] name = "event-listener" version = "2.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" +[[package]] +name = "external-request-validate" +version = "0.0.1" +dependencies = [ + "chirp-client", + "chirp-worker", + "chrono", + "http", + "prost 0.10.4", + "reqwest", + "rivet-operation", + "serde", + "serde_json", + "sqlx", +] + +[[package]] +name = "external-worker" +version = "0.0.1" +dependencies = [ + "chirp-client", + "chirp-worker", + "chrono", + "reqwest", + "rivet-health-checks", + "rivet-metrics", + "rivet-runtime", +] + [[package]] name = "faker-build" version = "0.0.1" @@ -3166,6 +3245,12 @@ dependencies = [ "instant", ] +[[package]] +name = "fastrand" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6999dc1837253364c2ebb0704ba97994bd874e8f195d665c50b7548f6ea92764" + [[package]] name = "fcm" version = "0.9.2" @@ -3180,6 +3265,12 @@ dependencies = [ "serde_json", ] +[[package]] +name = "fiat-crypto" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e825f6987101665dea6ec934c09ec6d721de7bc1bf92248e1d5810c8cd636b77" + [[package]] name = "fixedbitset" version = "0.4.2" @@ -3188,14 +3279,26 @@ checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" [[package]] name = "flate2" -version = "1.0.26" +version = "1.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b9429470923de8e8cbd4d2dc513535400b4b3fef0319fb5c4e1f520a7bef743" +checksum = "c6c98ee8095e9d1dcbf2fcc6d95acccb90d1c81db1e44725c6a984b1dbdfb010" dependencies = [ "crc32fast", "miniz_oxide", ] +[[package]] +name = "flume" +version = "0.10.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1657b4441c3403d9f7b3409e47575237dac27b1b5726df654a6ecbf92f0f7577" +dependencies = [ + "futures-core", + "futures-sink", + "pin-project", + "spin 0.9.8", +] + [[package]] name = "fnv" version = "1.0.7" @@ -3288,13 +3391,13 @@ dependencies = [ [[package]] name = "futures-intrusive" -version = "0.4.2" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a604f7a68fbf8103337523b1fadc8ade7361ee3f112f7c680ad179651616aed5" +checksum = "1d930c203dd0b6ff06e0201a4a2fe9149b43c684fd4420555b26d21b1a02956f" dependencies = [ "futures-core", "lock_api", - "parking_lot 0.11.2", + "parking_lot", ] [[package]] @@ -3311,7 +3414,7 @@ checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" dependencies = [ "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.29", ] [[package]] @@ -3754,6 +3857,7 @@ version = "0.0.1" dependencies = [ "chirp-client", "chirp-worker", + "external-request-validate", "faker-game", "game-version-get", "game-version-list", @@ -3792,6 +3896,12 @@ dependencies = [ "wasi 0.11.0+wasi-snapshot-preview1", ] +[[package]] +name = "gimli" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" + [[package]] name = "global-error" version = "0.1.5" @@ -3818,9 +3928,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.3.19" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d357c7ae988e7d2182f7d7871d0b963962420b0678b0997ce7de72001aeab782" +checksum = "91fc23aa11be92976ef4729127f1a74adf36d8436f7816b185d18df956790833" dependencies = [ "bytes", "fnv", @@ -3828,7 +3938,7 @@ dependencies = [ "futures-sink", "futures-util", "http", - "indexmap", + "indexmap 1.9.3", "slab", "tokio", "tokio-util 0.7.8", @@ -3856,9 +3966,9 @@ dependencies = [ [[package]] name = "hashlink" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "312f66718a2d7789ffef4f4b7b213138ed9f1eb3aa1d0d82fc99f88fb3ffd26f" +checksum = "e8094feaf31ff591f651a2664fb9cfd92bba7a60ce3197265e9482ebe753c8f7" dependencies = [ "hashbrown 0.14.0", ] @@ -3883,7 +3993,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f3e372db8e5c0d213e0cd0b9be18be2aca3d44cf2fe30a9d46a65581cd454584" dependencies = [ "base64 0.13.1", - "bitflags", + "bitflags 1.3.2", "bytes", "headers-core", "http", @@ -3921,18 +4031,9 @@ dependencies = [ [[package]] name = "hermit-abi" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" -dependencies = [ - "libc", -] - -[[package]] -name = "hermit-abi" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" +checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b" [[package]] name = "hex" @@ -3955,7 +4056,16 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" dependencies = [ - "digest 0.10.7", + "digest", +] + +[[package]] +name = "home" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb" +dependencies = [ + "windows-sys", ] [[package]] @@ -3966,7 +4076,7 @@ checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" dependencies = [ "bytes", "fnv", - "itoa 1.0.6", + "itoa 1.0.9", ] [[package]] @@ -3988,9 +4098,9 @@ checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" [[package]] name = "httpdate" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" [[package]] name = "humantime" @@ -4000,9 +4110,9 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "hyper" -version = "0.14.26" +version = "0.14.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab302d72a6f11a3b910431ff93aae7e773078c769f0a3ef15fb9ec692ed147d4" +checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468" dependencies = [ "bytes", "futures-channel", @@ -4013,9 +4123,9 @@ dependencies = [ "http-body", "httparse", "httpdate", - "itoa 1.0.6", + "itoa 1.0.9", "pin-project-lite", - "socket2", + "socket2 0.4.9", "tokio", "tower-service", "tracing", @@ -4048,22 +4158,23 @@ dependencies = [ "http", "hyper", "log", - "rustls 0.20.8", + "rustls 0.20.9", "rustls-native-certs 0.6.3", "tokio", "tokio-rustls 0.23.4", - "webpki-roots", + "webpki-roots 0.22.6", ] [[package]] name = "hyper-rustls" -version = "0.24.0" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0646026eb1b3eea4cd9ba47912ea5ce9cc07713d105b1a14698f4e6433d348b7" +checksum = "8d78e1e73ec14cf7375674f74d7dde185c8206fd9dea6fb6295e8a98098aaa97" dependencies = [ + "futures-util", "http", "hyper", - "rustls 0.21.2", + "rustls 0.21.7", "tokio", "tokio-rustls 0.24.1", ] @@ -4203,6 +4314,16 @@ dependencies = [ "serde", ] +[[package]] +name = "indexmap" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d" +dependencies = [ + "equivalent", + "hashbrown 0.14.0", +] + [[package]] name = "indoc" version = "1.0.9" @@ -4227,17 +4348,6 @@ dependencies = [ "cfg-if", ] -[[package]] -name = "io-lifetimes" -version = "1.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" -dependencies = [ - "hermit-abi 0.3.1", - "libc", - "windows-sys 0.48.0", -] - [[package]] name = "ip-info" version = "0.0.1" @@ -4255,9 +4365,9 @@ dependencies = [ [[package]] name = "ipnet" -version = "2.7.2" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12b6ee2129af8d4fb011108c73d99a1b83a85977f23b82460c0ae2e25bb4b57f" +checksum = "28b29a3cd74f0f4598934efe3aeba42bae0eb4680554128851ebbecb02af14e6" [[package]] name = "itertools" @@ -4276,9 +4386,9 @@ checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" [[package]] name = "itoa" -version = "1.0.6" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" +checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" [[package]] name = "job-gc" @@ -4444,13 +4554,13 @@ dependencies = [ "rivet-metrics", "rivet-runtime", "rivet-util-job", - "rustls 0.20.8", + "rustls 0.20.9", "serde", - "sha2 0.10.7", + "sha2", "sqlx", "token-create", "webpki 0.22.0", - "webpki-roots", + "webpki-roots 0.22.6", ] [[package]] @@ -4468,7 +4578,7 @@ version = "8.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6971da4d9c3aa03c3d8f3ff0f4155b534aad021292003895a469716b2a230378" dependencies = [ - "base64 0.21.2", + "base64 0.21.3", "pem", "ring", "serde", @@ -4576,12 +4686,32 @@ name = "lazy_static" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +dependencies = [ + "spin 0.5.2", +] [[package]] name = "libc" -version = "0.2.146" +version = "0.2.147" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" + +[[package]] +name = "libm" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7012b1bbb0719e1097c47611d3898568c546d597c2e74d66f6087edd5233ff4" + +[[package]] +name = "libsqlite3-sys" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f92be4933c13fd498862a9e02a3055f8a8d9c039ce33db97306fd5a6caa7f29b" +checksum = "afc22eff61b133b115c6e8c74e818c628d6d5e7a502afea6f64dee076dd94326" +dependencies = [ + "cc", + "pkg-config", + "vcpkg", +] [[package]] name = "linked-hash-map" @@ -4591,9 +4721,9 @@ checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" [[package]] name = "linux-raw-sys" -version = "0.3.8" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" +checksum = "57bcfdad1b858c2db7c38303a6d2ad4dfaf5eb53dfeb0910128b2c26d6158503" [[package]] name = "lock_api" @@ -4607,9 +4737,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.19" +version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4" +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" [[package]] name = "lz4" @@ -4637,14 +4767,14 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" dependencies = [ - "regex-automata", + "regex-automata 0.1.10", ] [[package]] name = "matchit" -version = "0.7.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b87248edafb776e59e6ee64a79086f65890d3510f2c656c000bf2a7e8a0aea40" +checksum = "ed1202b2a6f884ae56f04cff409ab315c5ce26b5e58d7412e484f01fd52f52ef" [[package]] name = "md-5" @@ -4652,14 +4782,14 @@ version = "0.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6365506850d44bff6e2fbcb5176cf63650e48bd45ef2fe2665ae1570e0f4b9ca" dependencies = [ - "digest 0.10.7", + "digest", ] [[package]] name = "memchr" -version = "2.5.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" +checksum = "76fc44e2588d5b436dbc3c6cf62aef290f90dab6235744a93dfe1cc18f451e2c" [[package]] name = "mime" @@ -4700,7 +4830,7 @@ checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" dependencies = [ "libc", "wasi 0.11.0+wasi-snapshot-preview1", - "windows-sys 0.48.0", + "windows-sys", ] [[package]] @@ -4997,6 +5127,18 @@ dependencies = [ "sqlx", ] +[[package]] +name = "mm-lobby-list-for-user-id" +version = "0.0.1" +dependencies = [ + "chirp-client", + "chirp-worker", + "faker-mm-lobby", + "prost 0.10.4", + "rivet-operation", + "sqlx", +] + [[package]] name = "mm-lobby-player-count" version = "0.0.1" @@ -5030,6 +5172,19 @@ dependencies = [ "sqlx", ] +[[package]] +name = "mm-lobby-state-get" +version = "0.0.1" +dependencies = [ + "chirp-client", + "chirp-worker", + "faker-mm-lobby", + "prost 0.10.4", + "rivet-operation", + "rivet-util-mm", + "sqlx", +] + [[package]] name = "mm-player-count-for-namespace" version = "0.0.1" @@ -5069,10 +5224,12 @@ dependencies = [ "faker-game-version", "faker-mm-lobby", "faker-region", + "faker-user", "game-get", "game-namespace-get", "game-namespace-version-set", "game-version-get", + "heck 0.3.3", "http", "job-run-get", "lazy_static", @@ -5086,10 +5243,12 @@ dependencies = [ "mm-lobby-get", "mm-lobby-idle-update", "mm-lobby-player-count", + "mm-lobby-state-get", "nomad-client", "nomad-util", "redis-util", "region-get", + "region-list", "reqwest", "rivet-health-checks", "rivet-metrics", @@ -5105,6 +5264,7 @@ dependencies = [ "upload-complete", "upload-get", "upload-prepare", + "user-identity-create", ] [[package]] @@ -5262,12 +5422,13 @@ dependencies = [ [[package]] name = "nkeys" -version = "0.2.0" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e66a7cd1358277b2a6f77078e70aea7315ff2f20db969cc61153103ec162594" +checksum = "aad178aad32087b19042ee36dfd450b73f5f934fbfb058b59b198684dfec4c47" dependencies = [ "byteorder", "data-encoding", + "ed25519", "ed25519-dalek", "getrandom", "log", @@ -5407,15 +5568,32 @@ dependencies = [ [[package]] name = "num-bigint" -version = "0.4.3" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f93ab6289c7b344a8a9f60f88d80aa20032336fe78da341afc91c8a2341fc75f" +checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" dependencies = [ "autocfg", "num-integer", "num-traits", ] +[[package]] +name = "num-bigint-dig" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc84195820f291c7697304f3cbdadd1cb7199c0efc917ff5eafd71225c136151" +dependencies = [ + "byteorder", + "lazy_static", + "libm", + "num-integer", + "num-iter", + "num-traits", + "rand", + "smallvec", + "zeroize", +] + [[package]] name = "num-integer" version = "0.1.45" @@ -5426,44 +5604,59 @@ dependencies = [ "num-traits", ] +[[package]] +name = "num-iter" +version = "0.1.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + [[package]] name = "num-traits" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" +checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2" dependencies = [ "autocfg", + "libm", ] [[package]] name = "num_cpus" -version = "1.15.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" dependencies = [ - "hermit-abi 0.2.6", + "hermit-abi", "libc", ] [[package]] -name = "once_cell" -version = "1.18.0" +name = "object" +version = "0.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" +checksum = "77ac5bbd07aea88c60a577a1ce218075ffd59208b2d7ca97adf9bfc5aeb21ebe" +dependencies = [ + "memchr", +] [[package]] -name = "opaque-debug" -version = "0.3.0" +name = "once_cell" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" [[package]] name = "openssl" -version = "0.10.55" +version = "0.10.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "345df152bc43501c5eb9e4654ff05f794effb78d4efe3d53abc158baddc0703d" +checksum = "bac25ee399abb46215765b1cb35bc0212377e58a061560d8b29b024fd0430e7c" dependencies = [ - "bitflags", + "bitflags 2.4.0", "cfg-if", "foreign-types", "libc", @@ -5480,7 +5673,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.29", ] [[package]] @@ -5491,9 +5684,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" -version = "0.9.90" +version = "0.9.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "374533b0e45f3a7ced10fcaeccca020e66656bc03dac384f852e4e5a7a8104a6" +checksum = "db7e971c2c2bba161b2d2fdf37080177eff520b3bc044787c7f1f5f9e78d869b" dependencies = [ "cc", "libc", @@ -5513,17 +5706,6 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" -[[package]] -name = "parking_lot" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" -dependencies = [ - "instant", - "lock_api", - "parking_lot_core 0.8.6", -] - [[package]] name = "parking_lot" version = "0.12.1" @@ -5531,21 +5713,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" dependencies = [ "lock_api", - "parking_lot_core 0.9.8", -] - -[[package]] -name = "parking_lot_core" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60a2cfe6f0ad2bfc16aefa463b497d5c7a5ecd44a23efa72aa342d90177356dc" -dependencies = [ - "cfg-if", - "instant", - "libc", - "redox_syscall 0.2.16", - "smallvec", - "winapi", + "parking_lot_core", ] [[package]] @@ -5556,16 +5724,16 @@ checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.3.5", + "redox_syscall", "smallvec", "windows-targets", ] [[package]] name = "paste" -version = "1.0.12" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f746c4065a8fa3fe23974dd82f15431cc8d40779821001404d10d2e79ca7d79" +checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" [[package]] name = "pem" @@ -5578,9 +5746,9 @@ dependencies = [ [[package]] name = "pem-rfc7468" -version = "0.2.4" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84e93a3b1cc0510b03020f33f21e62acdde3dcaef432edc95bea377fbd4c2cd4" +checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" dependencies = [ "base64ct", ] @@ -5603,9 +5771,9 @@ dependencies = [ [[package]] name = "pest" -version = "2.6.1" +version = "2.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16833386b02953ca926d19f64af613b9bf742c48dcd5e09b32fbfc9740bf84e2" +checksum = "1acb4a4365a13f749a93f1a094a7805e5cfa0955373a9de860d962eaa3a5fe5a" dependencies = [ "thiserror", "ucd-trie", @@ -5613,9 +5781,9 @@ dependencies = [ [[package]] name = "pest_derive" -version = "2.6.1" +version = "2.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7763190f9406839f99e5197afee8c9e759969f7dbfa40ad3b8dbee8757b745b5" +checksum = "666d00490d4ac815001da55838c500eafb0320019bbaa44444137c48b443a853" dependencies = [ "pest", "pest_generator", @@ -5623,63 +5791,63 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.6.1" +version = "2.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "249061b22e99973da1f5f5f1410284419e283bb60b79255bf5f42a94b66a2e00" +checksum = "68ca01446f50dbda87c1786af8770d535423fa8a53aec03b8f4e3d7eb10e0929" dependencies = [ "pest", "pest_meta", "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.29", ] [[package]] name = "pest_meta" -version = "2.6.1" +version = "2.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "457c310cfc9cf3f22bc58901cc7f0d3410ac5d6298e432a4f9a6138565cb6df6" +checksum = "56af0a30af74d0445c0bf6d9d051c979b516a1a5af790d251daee76005420a48" dependencies = [ "once_cell", "pest", - "sha2 0.10.7", + "sha2", ] [[package]] name = "petgraph" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dd7d28ee937e54fe3080c91faa1c3a46c06de6252988a7f4592ba2310ef22a4" +checksum = "e1d3afd2628e69da2be385eb6f2fd57c8ac7977ceeff6dc166ff1657b0e386a9" dependencies = [ "fixedbitset", - "indexmap", + "indexmap 2.0.0", ] [[package]] name = "pin-project" -version = "1.1.0" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c95a7476719eab1e366eaf73d0260af3021184f18177925b07f54b30089ceead" +checksum = "fda4ed1c6c173e3fc7a83629421152e01d7b1f9b7f65fb301e490e8cfc656422" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.0" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39407670928234ebc5e6e580247dd567ad73a3578460c5990f9503df207e8f07" +checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" dependencies = [ "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.29", ] [[package]] name = "pin-project-lite" -version = "0.2.9" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" [[package]] name = "pin-utils" @@ -5687,16 +5855,25 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "pkcs1" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f" +dependencies = [ + "der", + "pkcs8", + "spki", +] + [[package]] name = "pkcs8" -version = "0.7.6" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee3ef9b64d26bad0536099c816c6734379e45bbd5f14798def6809e5cc350447" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" dependencies = [ "der", - "pem-rfc7468", "spki", - "zeroize", ] [[package]] @@ -5705,6 +5882,12 @@ version = "0.3.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" +[[package]] +name = "platforms" +version = "3.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4503fa043bf02cee09a9582e9554b4c6403b2ef55e4612e96561d294419429f8" + [[package]] name = "playground" version = "0.0.1" @@ -5799,9 +5982,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.60" +version = "1.0.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dec2b086b7a862cf4de201096214fa870344cf922b2b30c167badb3af3195406" +checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" dependencies = [ "unicode-ident", ] @@ -5828,7 +6011,7 @@ dependencies = [ "fnv", "lazy_static", "memchr", - "parking_lot 0.12.1", + "parking_lot", "protobuf", "thiserror", ] @@ -5951,9 +6134,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.28" +version = "1.0.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9ab9c7eadfd8df19006f1cf1a4aed13540ed5cbc047010ece5826e10825488" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" dependencies = [ "proc-macro2", ] @@ -5966,7 +6149,7 @@ checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", "rand_chacha", - "rand_core 0.6.4", + "rand_core", ] [[package]] @@ -5976,15 +6159,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", - "rand_core 0.6.4", + "rand_core", ] -[[package]] -name = "rand_core" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" - [[package]] name = "rand_core" version = "0.6.4" @@ -6006,7 +6183,7 @@ dependencies = [ "combine", "futures", "futures-util", - "itoa 1.0.6", + "itoa 1.0.9", "native-tls", "percent-encoding", "pin-project-lite", @@ -6027,44 +6204,25 @@ dependencies = [ "regex", ] -[[package]] -name = "redox_syscall" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" -dependencies = [ - "bitflags", -] - [[package]] name = "redox_syscall" version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" dependencies = [ - "bitflags", -] - -[[package]] -name = "redox_users" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" -dependencies = [ - "getrandom", - "redox_syscall 0.2.16", - "thiserror", + "bitflags 1.3.2", ] [[package]] name = "regex" -version = "1.8.4" +version = "1.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0ab3ca65655bb1e41f2a8c8cd662eb4fb035e67c3f78da1d61dffe89d07300f" +checksum = "12de2eff854e5fa4b1295edd650e227e9d8fb0c9e90b12e7f36d6a6811791a29" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.7.2", + "regex-automata 0.3.7", + "regex-syntax 0.7.5", ] [[package]] @@ -6076,6 +6234,17 @@ dependencies = [ "regex-syntax 0.6.29", ] +[[package]] +name = "regex-automata" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49530408a136e16e5b486e883fbb6ba058e8e4e8ae6621a77b048b314336e629" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax 0.7.5", +] + [[package]] name = "regex-syntax" version = "0.6.29" @@ -6084,9 +6253,9 @@ checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" [[package]] name = "regex-syntax" -version = "0.7.2" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "436b050e76ed2903236f032a59761c1eb99e1b0aead2c257922771dab1fc8c78" +checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" [[package]] name = "region-get" @@ -6145,11 +6314,11 @@ dependencies = [ [[package]] name = "reqwest" -version = "0.11.18" +version = "0.11.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cde824a14b7c14f85caff81225f411faacc04a2013f41670f41443742b1c1c55" +checksum = "3e9ad3fe7488d7e34558a2033d45a0c90b72d97b4f80705666fea71472e2e6a1" dependencies = [ - "base64 0.21.2", + "base64 0.21.3", "bytes", "encoding_rs", "futures-core", @@ -6158,7 +6327,7 @@ dependencies = [ "http", "http-body", "hyper", - "hyper-rustls 0.24.0", + "hyper-rustls 0.24.1", "hyper-tls", "ipnet", "js-sys", @@ -6169,7 +6338,7 @@ dependencies = [ "once_cell", "percent-encoding", "pin-project-lite", - "rustls 0.21.2", + "rustls 0.21.7", "rustls-pemfile", "serde", "serde_json", @@ -6184,7 +6353,7 @@ dependencies = [ "wasm-bindgen-futures", "wasm-streams", "web-sys", - "webpki-roots", + "webpki-roots 0.25.2", "winreg", ] @@ -6197,7 +6366,7 @@ dependencies = [ "cc", "libc", "once_cell", - "spin", + "spin 0.5.2", "untrusted", "web-sys", "winapi", @@ -6570,7 +6739,7 @@ version = "0.1.0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.29", ] [[package]] @@ -6587,7 +6756,7 @@ dependencies = [ "sqlx", "thiserror", "tokio", - "tokio-util 0.6.10", + "tokio-util 0.7.8", "tracing", ] @@ -6744,9 +6913,16 @@ name = "rivet-util-mm" version = "0.1.0" dependencies = [ "bit-vec", + "chirp-client", + "http", + "mm-lobby-list-for-user-id", + "region-get", + "rivet-operation", "rivet-util", "serde", - "strum", + "serde_json", + "strum 0.24.1", + "user-identity-get", "uuid", ] @@ -6781,6 +6957,34 @@ dependencies = [ "uuid", ] +[[package]] +name = "rsa" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ab43bb47d23c1a631b4b680199a45255dce26fa9ab2fa902581f624ff13e6a8" +dependencies = [ + "byteorder", + "const-oid", + "digest", + "num-bigint-dig", + "num-integer", + "num-iter", + "num-traits", + "pkcs1", + "pkcs8", + "rand_core", + "signature", + "spki", + "subtle", + "zeroize", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" + [[package]] name = "rustc_version" version = "0.4.0" @@ -6792,16 +6996,15 @@ dependencies = [ [[package]] name = "rustix" -version = "0.37.20" +version = "0.38.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b96e891d04aa506a6d1f318d2771bcb1c7dfda84e126660ace067c9b474bb2c0" +checksum = "ed6248e1caa625eb708e266e06159f135e8c26f2bb7ceb72dc4b2766d0340964" dependencies = [ - "bitflags", + "bitflags 2.4.0", "errno", - "io-lifetimes", "libc", "linux-raw-sys", - "windows-sys 0.48.0", + "windows-sys", ] [[package]] @@ -6819,9 +7022,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.20.8" +version = "0.20.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fff78fc74d175294f4e83b28343315ffcfb114b156f0185e9741cb5570f50e2f" +checksum = "1b80e3dec595989ea8510028f30c408a4630db12c9cbb8de34203b89d6577e99" dependencies = [ "log", "ring", @@ -6831,9 +7034,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.21.2" +version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e32ca28af694bc1bbf399c33a516dbdf1c90090b8ab23c2bc24f834aa2247f5f" +checksum = "cd8d6c9f025a446bc4d18ad9632e69aec8f287aa84499ee335599fabd20c3fd8" dependencies = [ "log", "ring", @@ -6867,18 +7070,18 @@ dependencies = [ [[package]] name = "rustls-pemfile" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d194b56d58803a43635bdc398cd17e383d6f71f9182b9a192c127ca42494a59b" +checksum = "2d3987094b1d07b653b7dfdc3f70ce9a1da9c51ac18c1b06b662e4f9a0e9f4b2" dependencies = [ - "base64 0.21.2", + "base64 0.21.3", ] [[package]] name = "rustls-webpki" -version = "0.100.1" +version = "0.101.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6207cd5ed3d8dca7816f8f3725513a34609c0c765bf652b8c3cb4cfd87db46b" +checksum = "7d93931baf2d282fff8d3a532bbfd7653f734643161b87e3e01e59a04439bf0d" dependencies = [ "ring", "untrusted", @@ -6886,15 +7089,15 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.12" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f3208ce4d8448b3f3e7d168a73f5e0c43a61e32930de3bceeccedb388b6bf06" +checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" [[package]] name = "ryu" -version = "1.0.13" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" +checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" [[package]] name = "s3-util" @@ -6912,11 +7115,11 @@ dependencies = [ [[package]] name = "schannel" -version = "0.1.21" +version = "0.1.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "713cfb06c7059f3588fb8044c0fad1d09e3c01d225e25b9220dbfdcf16dbb1b3" +checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88" dependencies = [ - "windows-sys 0.42.0", + "windows-sys", ] [[package]] @@ -6931,9 +7134,9 @@ dependencies = [ [[package]] name = "scopeguard" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "sct" @@ -6969,11 +7172,11 @@ dependencies = [ [[package]] name = "security-framework" -version = "2.9.1" +version = "2.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fc758eb7bffce5b308734e9b0c1468893cae9ff70ebf13e7090be8dcbcc83a8" +checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" dependencies = [ - "bitflags", + "bitflags 1.3.2", "core-foundation", "core-foundation-sys", "libc", @@ -6982,9 +7185,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.9.0" +version = "2.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f51d0c0d83bec45f16480d0ce0058397a69e48fcdc52d1dc8855fb68acbd31a7" +checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" dependencies = [ "core-foundation-sys", "libc", @@ -6992,15 +7195,15 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.17" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed" +checksum = "b0293b4b29daaf487284529cc2f5675b8e57c61f70167ba415a463651fd6a918" [[package]] name = "serde" -version = "1.0.164" +version = "1.0.188" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e8c8cf938e98f769bc164923b06dce91cea1751522f46f8466461af04c9027d" +checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" dependencies = [ "serde_derive", ] @@ -7016,13 +7219,13 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.164" +version = "1.0.188" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9735b638ccc51c28bf6914d90a2e9725b377144fc612c49a611fddd1b631d68" +checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.29", ] [[package]] @@ -7038,11 +7241,11 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.97" +version = "1.0.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdf3bf93142acad5821c99197022e170842cdbc1c30482b98750c688c640842a" +checksum = "693151e1ac27563d6dbcec9dee9fbd5da8539b20fa14ad3752b2e6d363ace360" dependencies = [ - "itoa 1.0.6", + "itoa 1.0.9", "ryu", "serde", ] @@ -7058,20 +7261,20 @@ dependencies = [ [[package]] name = "serde_repr" -version = "0.1.12" +version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcec881020c684085e55a25f7fd888954d56609ef363479dc5a1305eb0d40cab" +checksum = "8725e1dfadb3a50f7e5ce0b1a540466f6ed3fe7a0fca2ac2b8b831d31316bd00" dependencies = [ "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.29", ] [[package]] name = "serde_spanned" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93107647184f6027e3b7dcb2e11034cf95ffa1e3a682c67951963ac69c1c007d" +checksum = "96426c9936fd7a0124915f9185ea1d20aa9445cc9821142f0a73bc9207a2e186" dependencies = [ "serde", ] @@ -7083,7 +7286,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" dependencies = [ "form_urlencoded", - "itoa 1.0.6", + "itoa 1.0.9", "ryu", "serde", ] @@ -7097,11 +7300,11 @@ dependencies = [ "base64 0.13.1", "chrono", "hex", - "indexmap", + "indexmap 1.9.3", "serde", "serde_json", "serde_with_macros", - "time 0.3.22", + "time 0.3.28", ] [[package]] @@ -7113,7 +7316,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.29", ] [[package]] @@ -7133,7 +7336,7 @@ checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3" dependencies = [ "cfg-if", "cpufeatures", - "digest 0.10.7", + "digest", ] [[package]] @@ -7142,19 +7345,6 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ae1a47186c03a32177042e55dbc5fd5aee900b8e0069a8d70fba96a9375cd012" -[[package]] -name = "sha2" -version = "0.9.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" -dependencies = [ - "block-buffer 0.9.0", - "cfg-if", - "cpufeatures", - "digest 0.9.0", - "opaque-debug", -] - [[package]] name = "sha2" version = "0.10.7" @@ -7163,7 +7353,7 @@ checksum = "479fb9d862239e610720565ca91403019f2f00410f1864c5aa7479b950a76ed8" dependencies = [ "cfg-if", "cpufeatures", - "digest 0.10.7", + "digest", ] [[package]] @@ -7186,21 +7376,25 @@ dependencies = [ [[package]] name = "signatory" -version = "0.23.2" +version = "0.27.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dfecc059e81632eef1dd9b79e22fc28b8fe69b30d3357512a77a0ad8ee3c782" +checksum = "c1e303f8205714074f6068773f0e29527e0453937fe837c9717d066635b65f31" dependencies = [ "pkcs8", - "rand_core 0.6.4", + "rand_core", "signature", "zeroize", ] [[package]] name = "signature" -version = "1.6.4" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" +checksum = "8fe458c98333f9c8152221191a77e2a44e8325d0193484af2e9421a53019e57d" +dependencies = [ + "digest", + "rand_core", +] [[package]] name = "simd-abstraction" @@ -7220,23 +7414,23 @@ dependencies = [ "num-bigint", "num-traits", "thiserror", - "time 0.3.22", + "time 0.3.28", ] [[package]] name = "slab" -version = "0.4.8" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" dependencies = [ "autocfg", ] [[package]] name = "smallvec" -version = "1.10.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" +checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9" [[package]] name = "socket2" @@ -7248,18 +7442,38 @@ dependencies = [ "winapi", ] +[[package]] +name = "socket2" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2538b18701741680e0322a2302176d3253a35388e2e62f172f64f4f16605f877" +dependencies = [ + "libc", + "windows-sys", +] + [[package]] name = "spin" version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +dependencies = [ + "lock_api", +] + [[package]] name = "spki" -version = "0.4.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c01a0c15da1b0b0e1494112e7af814a678fec9bd157881b49beac661e9b6f32" +checksum = "9d1e996ef02c474957d681f1b05213dfb0abab947b446a62d37770b23500184a" dependencies = [ + "base64ct", "der", ] @@ -7276,94 +7490,203 @@ dependencies = [ [[package]] name = "sqlx" -version = "0.6.3" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8de3b03a925878ed54a954f621e64bf55a3c1bd29652d0d1a17830405350188" +checksum = "8e58421b6bc416714d5115a2ca953718f6c621a51b68e4f4922aea5a4391a721" dependencies = [ "sqlx-core", "sqlx-macros", + "sqlx-mysql", + "sqlx-postgres", + "sqlx-sqlite", ] [[package]] name = "sqlx-core" -version = "0.6.3" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa8241483a83a3f33aa5fff7e7d9def398ff9990b2752b6c6112b83c6d246029" +checksum = "dd4cef4251aabbae751a3710927945901ee1d97ee96d757f6880ebb9a79bfd53" dependencies = [ - "ahash 0.7.6", + "ahash 0.8.3", "atoi", - "base64 0.13.1", "bit-vec", - "bitflags", "byteorder", "bytes", + "crc", "crossbeam-queue", - "dirs", "dotenvy", "either", "event-listener", "futures-channel", "futures-core", "futures-intrusive", + "futures-io", "futures-util", "hashlink", "hex", - "hkdf", - "hmac", - "indexmap", - "itoa 1.0.6", - "libc", + "indexmap 2.0.0", "log", - "md-5", "memchr", "once_cell", "paste", "percent-encoding", - "rand", "serde", "serde_json", - "sha1 0.10.5", - "sha2 0.10.7", + "sha2", "smallvec", "sqlformat", - "sqlx-rt", - "stringprep", "thiserror", + "tokio", "tokio-stream", + "tracing", "url", "uuid", - "whoami", ] [[package]] name = "sqlx-macros" -version = "0.6.3" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9966e64ae989e7e575b19d7265cb79d7fc3cbbdf179835cb0d716f294c2049c9" +checksum = "208e3165167afd7f3881b16c1ef3f2af69fa75980897aac8874a0696516d12c2" +dependencies = [ + "proc-macro2", + "quote", + "sqlx-core", + "sqlx-macros-core", + "syn 1.0.109", +] + +[[package]] +name = "sqlx-macros-core" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a4a8336d278c62231d87f24e8a7a74898156e34c1c18942857be2acb29c7dfc" dependencies = [ "dotenvy", "either", "heck 0.4.1", + "hex", "once_cell", "proc-macro2", "quote", + "serde", "serde_json", + "sha2", "sqlx-core", - "sqlx-rt", + "sqlx-mysql", + "sqlx-postgres", + "sqlx-sqlite", "syn 1.0.109", + "tempfile", + "tokio", "url", ] [[package]] -name = "sqlx-rt" -version = "0.6.3" +name = "sqlx-mysql" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "804d3f245f894e61b1e6263c84b23ca675d96753b5abfd5cc8597d86806e8024" +checksum = "8ca69bf415b93b60b80dc8fda3cb4ef52b2336614d8da2de5456cc942a110482" dependencies = [ - "native-tls", + "atoi", + "base64 0.21.3", + "bitflags 2.4.0", + "byteorder", + "bytes", + "crc", + "digest", + "dotenvy", + "either", + "futures-channel", + "futures-core", + "futures-io", + "futures-util", + "generic-array", + "hex", + "hkdf", + "hmac", + "itoa 1.0.9", + "log", + "md-5", + "memchr", "once_cell", - "tokio", - "tokio-native-tls", + "percent-encoding", + "rand", + "rsa", + "serde", + "sha1 0.10.5", + "sha2", + "smallvec", + "sqlx-core", + "stringprep", + "thiserror", + "tracing", + "uuid", + "whoami", +] + +[[package]] +name = "sqlx-postgres" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0db2df1b8731c3651e204629dd55e52adbae0462fa1bdcbed56a2302c18181e" +dependencies = [ + "atoi", + "base64 0.21.3", + "bit-vec", + "bitflags 2.4.0", + "byteorder", + "crc", + "dotenvy", + "etcetera", + "futures-channel", + "futures-core", + "futures-io", + "futures-util", + "hex", + "hkdf", + "hmac", + "home", + "itoa 1.0.9", + "log", + "md-5", + "memchr", + "once_cell", + "rand", + "serde", + "serde_json", + "sha1 0.10.5", + "sha2", + "smallvec", + "sqlx-core", + "stringprep", + "thiserror", + "tracing", + "uuid", + "whoami", +] + +[[package]] +name = "sqlx-sqlite" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be4c21bf34c7cae5b283efb3ac1bcc7670df7561124dc2f8bdc0b59be40f79a2" +dependencies = [ + "atoi", + "flume", + "futures-channel", + "futures-core", + "futures-executor", + "futures-intrusive", + "futures-util", + "libsqlite3-sys", + "log", + "percent-encoding", + "serde", + "sqlx-core", + "tracing", + "url", + "uuid", ] [[package]] @@ -7374,9 +7697,9 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" [[package]] name = "stringprep" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ee348cb74b87454fff4b551cbf727025810a004f88aeacae7f85b87f4e9a1c1" +checksum = "db3737bde7edce97102e0e2b15365bf7a20bfdb5f60f4f9e8d7004258a51a8da" dependencies = [ "unicode-bidi", "unicode-normalization", @@ -7394,9 +7717,15 @@ version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "063e6045c0e62079840579a7e47a355ae92f60eb74daaf156fb1e84ba164e63f" dependencies = [ - "strum_macros", + "strum_macros 0.24.3", ] +[[package]] +name = "strum" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290d54ea6f91c969195bdbcd7442c8c2a2ba87da8bf60a7ee86a235d4bc1e125" + [[package]] name = "strum_macros" version = "0.24.3" @@ -7410,6 +7739,19 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "strum_macros" +version = "0.25.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad8d03b598d3d0fff69bf533ee3ef19b8eeb342729596df84bcc7e1f96ec4059" +dependencies = [ + "heck 0.4.1", + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.29", +] + [[package]] name = "subtle" version = "2.5.0" @@ -7429,9 +7771,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.18" +version = "2.0.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32d41677bcbe24c20c52e7c70b0d8db04134c5d1066bf98662e2871ad200ea3e" +checksum = "c324c494eba9d92503e6f1ef2e6df781e78f6a7705a0202d9801b198807d518a" dependencies = [ "proc-macro2", "quote", @@ -7811,36 +8153,35 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.6.0" +version = "3.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31c0432476357e58790aaa47a8efb0c5138f137343f3b5f23bd36a27e3b0a6d6" +checksum = "cb94d2f3cc536af71caac6b6fcebf65860b347e7ce0cc9ebe8f70d3e521054ef" dependencies = [ - "autocfg", "cfg-if", - "fastrand", - "redox_syscall 0.3.5", + "fastrand 2.0.0", + "redox_syscall", "rustix", - "windows-sys 0.48.0", + "windows-sys", ] [[package]] name = "thiserror" -version = "1.0.40" +version = "1.0.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac" +checksum = "97a802ec30afc17eee47b2855fc72e0c4cd62be9b4efe6591edde0ec5bd68d8f" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.40" +version = "1.0.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" +checksum = "6bb623b56e39ab7dcd4b1b98bb6c8f8d907ed255b18de254088016b27a8ee19b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.29", ] [[package]] @@ -7876,11 +8217,12 @@ dependencies = [ [[package]] name = "time" -version = "0.3.22" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea9e1b3cf1243ae005d9e74085d4d542f3125458f3a81af210d901dcd7411efd" +checksum = "17f6bb557fd245c28e6411aa56b6403c689ad95061f50e4be16c274e70a17e48" dependencies = [ - "itoa 1.0.6", + "deranged", + "itoa 1.0.9", "serde", "time-core", "time-macros", @@ -7894,9 +8236,9 @@ checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb" [[package]] name = "time-macros" -version = "0.2.9" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "372950940a5f07bf38dbe211d7283c9e6d7327df53794992d293e534c733d09b" +checksum = "1a942f44339478ef67935ab2bbaec2fb0322496cf3cbe84b261e06ac3814c572" dependencies = [ "time-core", ] @@ -7973,22 +8315,22 @@ dependencies = [ [[package]] name = "tokio" -version = "1.28.2" +version = "1.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94d7b1cfd2aa4011f2de74c2c4c63665e27a71006b0a192dcd2710272e73dfa2" +checksum = "17ed6077ed6cd6c74735e21f37eb16dc3935f96878b1fe961074089cc80893f9" dependencies = [ - "autocfg", + "backtrace", "bytes", "libc", "mio", "num_cpus", - "parking_lot 0.12.1", + "parking_lot", "pin-project-lite", "signal-hook-registry", - "socket2", + "socket2 0.5.3", "tokio-macros", "tracing", - "windows-sys 0.48.0", + "windows-sys", ] [[package]] @@ -8009,7 +8351,7 @@ checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.29", ] [[package]] @@ -8050,7 +8392,7 @@ version = "0.23.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c43ee83903113e03984cb9e5cebe6c04a5116269e900e3ddba8f068a62adda59" dependencies = [ - "rustls 0.20.8", + "rustls 0.20.9", "tokio", "webpki 0.22.0", ] @@ -8061,7 +8403,7 @@ version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" dependencies = [ - "rustls 0.21.2", + "rustls 0.21.7", "tokio", ] @@ -8115,9 +8457,9 @@ dependencies = [ [[package]] name = "toml" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6135d499e69981f9ff0ef2167955a5333c35e36f6937d382974566b3d5b94ec" +checksum = "c17e963a819c331dcacd7ab957d80bc2b9a9c1e71c804826d2f283dd65306542" dependencies = [ "serde", "serde_spanned", @@ -8127,20 +8469,20 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a76a9312f5ba4c2dec6b9161fdf25d87ad8a09256ccea5a556fef03c706a10f" +checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" dependencies = [ "serde", ] [[package]] name = "toml_edit" -version = "0.19.10" +version = "0.19.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2380d56e8670370eee6566b0bfd4265f65b3f432e8c6d85623f728d4fa31f739" +checksum = "f8123f27e969974a3dfba720fdb560be359f57b44302d280ba72e76a74480e8a" dependencies = [ - "indexmap", + "indexmap 2.0.0", "serde", "serde_spanned", "toml_datetime", @@ -8155,7 +8497,7 @@ checksum = "3082666a3a6433f7f511c7192923fa1fe07c69332d3c6a2e6bb040b569199d5a" dependencies = [ "async-trait", "axum", - "base64 0.21.2", + "base64 0.21.3", "bytes", "futures-core", "futures-util", @@ -8183,7 +8525,7 @@ checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" dependencies = [ "futures-core", "futures-util", - "indexmap", + "indexmap 1.9.3", "pin-project", "pin-project-lite", "rand", @@ -8222,13 +8564,13 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.25" +version = "0.1.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8803eee176538f94ae9a14b55b2804eb7e1441f8210b1c31290b3bccdccff73b" +checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" dependencies = [ "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.29", ] [[package]] @@ -8318,20 +8660,20 @@ dependencies = [ "regex", "schemac", "serde", - "toml 0.7.4", + "toml 0.7.6", ] [[package]] name = "ucd-trie" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e79c4d996edb816c91e4308506774452e55e95c3c9de07b6729e17e15a5ef81" +checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" [[package]] name = "unicase" -version = "2.6.0" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6" +checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89" dependencies = [ "version_check", ] @@ -8344,9 +8686,9 @@ checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" [[package]] name = "unicode-ident" -version = "1.0.9" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b15811caf2415fb889178633e7724bad2509101cde276048e013b9def5e51fa0" +checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c" [[package]] name = "unicode-normalization" @@ -8496,9 +8838,9 @@ dependencies = [ [[package]] name = "url" -version = "2.4.0" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50bff7831e19200a85b17131d085c25d7811bc4e186efdaf54bbd132994a88cb" +checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5" dependencies = [ "form_urlencoded", "idna", @@ -8507,9 +8849,9 @@ dependencies = [ [[package]] name = "urlencoding" -version = "2.1.2" +version = "2.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8db7427f936968176eaa7cdf81b7f98b980b18495ec28f1b5791ac3bfe3eea9" +checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" [[package]] name = "user-avatar-upload-complete" @@ -8949,9 +9291,9 @@ dependencies = [ [[package]] name = "uuid" -version = "1.3.4" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa2982af2eec27de306107c027578ff7f423d65f7250e40ce0fea8f45248b81" +checksum = "79daa5ed5740825c40b389c5e50312b9c86df53fccd33f281df655642b43869d" dependencies = [ "getrandom", "serde", @@ -9017,7 +9359,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.29", "wasm-bindgen-shared", ] @@ -9051,7 +9393,7 @@ checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.29", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -9064,9 +9406,9 @@ checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" [[package]] name = "wasm-streams" -version = "0.2.3" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bbae3363c08332cadccd13b67db371814cd214c2524020932f0804b8cf7c078" +checksum = "b4609d447824375f43e1ffbc051b50ad8f4b3ae8219680c94452ea05eb240ac7" dependencies = [ "futures-util", "js-sys", @@ -9114,6 +9456,12 @@ dependencies = [ "webpki 0.22.0", ] +[[package]] +name = "webpki-roots" +version = "0.25.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14247bb57be4f377dfb94c72830b8ce8fc6beac03cf4bf7b9732eadd414123fc" + [[package]] name = "which" version = "4.4.0" @@ -9127,13 +9475,9 @@ dependencies = [ [[package]] name = "whoami" -version = "1.4.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c70234412ca409cc04e864e89523cb0fc37f5e1344ebed5a3ebf4192b6b9f68" -dependencies = [ - "wasm-bindgen", - "web-sys", -] +checksum = "22fc3756b8a9133049b26c7f61ab35416c130e8c09b660f5b3958b446f52cc50" [[package]] name = "winapi" @@ -9166,21 +9510,6 @@ dependencies = [ "windows-targets", ] -[[package]] -name = "windows-sys" -version = "0.42.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" -dependencies = [ - "windows_aarch64_gnullvm 0.42.2", - "windows_aarch64_msvc 0.42.2", - "windows_i686_gnu 0.42.2", - "windows_i686_msvc 0.42.2", - "windows_x86_64_gnu 0.42.2", - "windows_x86_64_gnullvm 0.42.2", - "windows_x86_64_msvc 0.42.2", -] - [[package]] name = "windows-sys" version = "0.48.0" @@ -9192,119 +9521,78 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" dependencies = [ - "windows_aarch64_gnullvm 0.48.0", - "windows_aarch64_msvc 0.48.0", - "windows_i686_gnu 0.48.0", - "windows_i686_msvc 0.48.0", - "windows_x86_64_gnu 0.48.0", - "windows_x86_64_gnullvm 0.48.0", - "windows_x86_64_msvc 0.48.0", + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", ] [[package]] name = "windows_aarch64_gnullvm" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_msvc" -version = "0.42.2" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_i686_gnu" -version = "0.42.2" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" - -[[package]] -name = "windows_i686_gnu" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" - -[[package]] -name = "windows_i686_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_msvc" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_x86_64_gnu" -version = "0.42.2" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnullvm" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.42.2" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_msvc" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "winnow" -version = "0.4.7" +version = "0.5.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca0ace3845f0d96209f0375e6d367e3eb87eb65d27d445bdc9f1843a26f39448" +checksum = "7c2e3184b9c4e92ad5167ca73039d0c42476302ab603e2fec4487511f38ccefc" dependencies = [ "memchr", ] [[package]] name = "winreg" -version = "0.10.1" +version = "0.50.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" +checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" dependencies = [ - "winapi", + "cfg-if", + "windows-sys", ] [[package]] @@ -9327,17 +9615,3 @@ name = "zeroize" version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" -dependencies = [ - "zeroize_derive", -] - -[[package]] -name = "zeroize_derive" -version = "1.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.18", -] diff --git a/svc/Cargo.toml b/svc/Cargo.toml index aaf6159c54..41d0303187 100644 --- a/svc/Cargo.toml +++ b/svc/Cargo.toml @@ -1,7 +1,7 @@ # This is generated by Bolt. Do not modify. [workspace] -members = ["api/cloud", "api/group", "api/route", "api/portal", "api/job", "api/cf-verification", "api/module", "api/identity", "api/admin", "api/matchmaker", "api/chat", "api/status", "api/kv", "api/auth", "pkg/push-notification/worker", "pkg/cdn/worker", "pkg/cdn/ops/ns-enable-domain-public-auth-set", "pkg/cdn/ops/namespace-get", "pkg/cdn/ops/version-get", "pkg/cdn/ops/namespace-create", "pkg/cdn/ops/namespace-domain-remove", "pkg/cdn/ops/namespace-auth-user-update", "pkg/cdn/ops/site-get", "pkg/cdn/ops/namespace-resolve-domain", "pkg/cdn/ops/version-publish", "pkg/cdn/ops/namespace-auth-user-remove", "pkg/cdn/ops/namespace-domain-create", "pkg/cdn/ops/site-list-for-game", "pkg/cdn/ops/version-prepare", "pkg/cdn/ops/site-create", "pkg/cdn/ops/ns-auth-type-set", "pkg/captcha/ops/hcaptcha-verify", "pkg/captcha/ops/verify", "pkg/captcha/ops/request", "pkg/captcha/ops/hcaptcha-config-get", "pkg/email-verification/ops/complete", "pkg/email-verification/ops/create", "pkg/team/worker", "pkg/team/standalone/billing-collect", "pkg/team/ops/member-get", "pkg/team/ops/member-relationship-get", "pkg/team/ops/resolve-display-name", "pkg/team/ops/profile-validate", "pkg/team/ops/user-ban-get", "pkg/team/ops/get", "pkg/team/ops/join-request-list", "pkg/team/ops/recommend", "pkg/team/ops/user-ban-list", "pkg/team/ops/search", "pkg/team/ops/avatar-upload-complete", "pkg/team/ops/validate", "pkg/team/ops/billing-aggregate", "pkg/team/ops/member-count", "pkg/team/ops/member-list", "pkg/cloud/worker", "pkg/cloud/ops/namespace-token-development-create", "pkg/cloud/ops/game-config-get", "pkg/cloud/ops/namespace-get", "pkg/cloud/ops/version-get", "pkg/cloud/ops/namespace-create", "pkg/cloud/ops/namespace-token-public-create", "pkg/cloud/ops/version-publish", "pkg/cloud/ops/game-config-create", "pkg/cloud/ops/game-token-create", "pkg/cloud/ops/device-link-create", "pkg/nomad-log/worker", "pkg/nomad-log/standalone/follower", "pkg/nomad-log/ops/read", "pkg/faker/ops/mm-player", "pkg/faker/ops/job-template", "pkg/faker/ops/team", "pkg/faker/ops/region", "pkg/faker/ops/game-version", "pkg/faker/ops/build", "pkg/faker/ops/cdn-site", "pkg/faker/ops/user", "pkg/faker/ops/mm-lobby", "pkg/faker/ops/game", "pkg/faker/ops/job-run", "pkg/faker/ops/game-namespace", "pkg/faker/ops/mm-lobby-row", "pkg/token/ops/get", "pkg/token/ops/exchange", "pkg/token/ops/create", "pkg/token/ops/revoke", "pkg/user-follow/worker", "pkg/user-follow/ops/relationship-get", "pkg/user-follow/ops/request-list", "pkg/user-follow/ops/get", "pkg/user-follow/ops/toggle", "pkg/user-follow/ops/count", "pkg/user-follow/ops/list", "pkg/user-notification-auth/ops/register", "pkg/user-notification-auth/ops/unregister", "pkg/chat-thread/worker", "pkg/chat-thread/ops/unread-count", "pkg/chat-thread/ops/participant-list", "pkg/chat-thread/ops/get", "pkg/chat-thread/ops/get-or-create-for-topic", "pkg/chat-thread/ops/list-for-participant", "pkg/chat-thread/ops/get-for-topic", "pkg/chat-thread/ops/recent-for-user", "pkg/region/ops/get", "pkg/region/ops/recommend", "pkg/region/ops/list", "pkg/region/ops/resolve", "pkg/user-dev/worker", "pkg/custom-user-avatar/ops/upload-complete", "pkg/custom-user-avatar/ops/list-for-game", "pkg/kv-config/ops/namespace-get", "pkg/kv-config/ops/version-get", "pkg/kv-config/ops/namespace-create", "pkg/kv-config/ops/version-publish", "pkg/kv-config/ops/version-prepare", "pkg/telemetry/standalone/beacon", "pkg/nsfw/ops/image-score", "pkg/build/standalone/default-create", "pkg/build/ops/get", "pkg/build/ops/list-for-game", "pkg/build/ops/create", "pkg/job/standalone/gc", "pkg/cf/ops/turnstile-verify", "pkg/analytics/worker", "pkg/team-invite/worker", "pkg/team-invite/ops/get", "pkg/misc/standalone/playground", "pkg/email/ops/send", "pkg/profanity/ops/check", "pkg/user-identity/ops/delete", "pkg/user-identity/ops/get", "pkg/user-identity/ops/create", "pkg/user/worker", "pkg/user/standalone/delete-pending", "pkg/user/standalone/search-user-gc", "pkg/user/ops/pending-delete-toggle", "pkg/user/ops/thread-typing-status-set", "pkg/user/ops/profile-validate", "pkg/user/ops/get", "pkg/user/ops/mutual-friend-list", "pkg/user/ops/search", "pkg/user/ops/resolve-email", "pkg/user/ops/token-create", "pkg/user/ops/avatar-upload-complete", "pkg/user/ops/team-list", "pkg/module/worker", "pkg/module/ops/game-version-get", "pkg/module/ops/version-get", "pkg/module/ops/game-version-publish", "pkg/module/ops/get", "pkg/module/ops/ns-instance-get", "pkg/module/ops/instance-call", "pkg/module/ops/instance-get", "pkg/module/ops/game-version-prepare", "pkg/team-dev/worker", "pkg/team-dev/standalone/halt-collect", "pkg/team-dev/ops/get", "pkg/team-dev/ops/halt", "pkg/team-dev/ops/game-list", "pkg/user-presence/worker", "pkg/user-presence/standalone/gc", "pkg/user-presence/ops/touch", "pkg/user-presence/ops/get", "pkg/mm/worker", "pkg/mm/standalone/gc", "pkg/mm/standalone/gc-full", "pkg/mm/ops/lobby-player-count", "pkg/mm/ops/lobby-idle-update", "pkg/mm/ops/player-count-for-namespace", "pkg/mm/ops/lobby-find-try-complete", "pkg/mm/ops/lobby-find-fail", "pkg/mm/ops/lobby-get", "pkg/mm/ops/player-get", "pkg/mm/ops/lobby-list-for-namespace", "pkg/mm/ops/lobby-find-lobby-query-list", "pkg/mm/ops/lobby-history", "pkg/mm/ops/lobby-runtime-aggregate", "pkg/mm/ops/dev-player-token-create", "pkg/ip/ops/info", "pkg/mm-config/ops/namespace-get", "pkg/mm-config/ops/version-get", "pkg/mm-config/ops/namespace-create", "pkg/mm-config/ops/lobby-group-resolve-version", "pkg/mm-config/ops/version-publish", "pkg/mm-config/ops/lobby-group-get", "pkg/mm-config/ops/version-prepare", "pkg/mm-config/ops/lobby-group-resolve-name-id", "pkg/mm-config/ops/namespace-config-set", "pkg/mm-config/ops/namespace-config-validate", "pkg/chat-message/worker", "pkg/chat-message/ops/body-validate", "pkg/chat-message/ops/create-with-topic", "pkg/chat-message/ops/get", "pkg/chat-message/ops/list-for-user", "pkg/chat-message/ops/list", "pkg/chat-message/ops/validate", "pkg/user-report/worker", "pkg/game/ops/namespace-resolve-name-id", "pkg/game/ops/namespace-get", "pkg/game/ops/version-get", "pkg/game/ops/namespace-resolve-url", "pkg/game/ops/namespace-create", "pkg/game/ops/version-create", "pkg/game/ops/namespace-version-history-list", "pkg/game/ops/resolve-name-id", "pkg/game/ops/get", "pkg/game/ops/token-development-validate", "pkg/game/ops/version-validate", "pkg/game/ops/recommend", "pkg/game/ops/namespace-validate", "pkg/game/ops/banner-upload-complete", "pkg/game/ops/resolve-namespace-id", "pkg/game/ops/namespace-version-set", "pkg/game/ops/list-all", "pkg/game/ops/validate", "pkg/game/ops/namespace-list", "pkg/game/ops/create", "pkg/game/ops/logo-upload-complete", "pkg/game/ops/version-list", "pkg/identity-config/ops/namespace-get", "pkg/identity-config/ops/version-get", "pkg/identity-config/ops/namespace-create", "pkg/identity-config/ops/version-publish", "pkg/identity-config/ops/version-prepare", "pkg/job-run/worker", "pkg/job-run/standalone/alloc-update-monitor", "pkg/job-run/standalone/alloc-plan-monitor", "pkg/job-run/standalone/eval-update-monitor", "pkg/job-run/ops/get", "pkg/job-run/ops/metrics-log", "pkg/chat/worker", "pkg/chat/ops/last-read-ts-get", "pkg/game-user/worker", "pkg/game-user/ops/recent-session-list", "pkg/game-user/ops/get", "pkg/game-user/ops/recommend", "pkg/game-user/ops/link-create", "pkg/game-user/ops/link-get", "pkg/game-user/ops/list-for-user", "pkg/game-user/ops/create", "pkg/debug/ops/email-res", "pkg/cf-custom-hostname/worker", "pkg/cf-custom-hostname/ops/resolve-hostname", "pkg/cf-custom-hostname/ops/get", "pkg/cf-custom-hostname/ops/list-for-namespace-id", "pkg/upload/worker", "pkg/upload/standalone/provider-fill", "pkg/upload/ops/complete", "pkg/upload/ops/file-list", "pkg/upload/ops/get", "pkg/upload/ops/prepare", "pkg/upload/ops/list-for-user", "pkg/kv/worker", "pkg/kv/ops/get", "pkg/kv/ops/list", "pkg/tier/ops/list", "pkg/perf/ops/log-get"] +members = ["api/cloud", "api/group", "api/route", "api/portal", "api/job", "api/cf-verification", "api/module", "api/identity", "api/admin", "api/matchmaker", "api/chat", "api/status", "api/kv", "api/auth", "pkg/push-notification/worker", "pkg/cdn/worker", "pkg/cdn/ops/ns-enable-domain-public-auth-set", "pkg/cdn/ops/namespace-get", "pkg/cdn/ops/version-get", "pkg/cdn/ops/namespace-create", "pkg/cdn/ops/namespace-domain-remove", "pkg/cdn/ops/namespace-auth-user-update", "pkg/cdn/ops/site-get", "pkg/cdn/ops/namespace-resolve-domain", "pkg/cdn/ops/version-publish", "pkg/cdn/ops/namespace-auth-user-remove", "pkg/cdn/ops/namespace-domain-create", "pkg/cdn/ops/site-list-for-game", "pkg/cdn/ops/version-prepare", "pkg/cdn/ops/site-create", "pkg/cdn/ops/ns-auth-type-set", "pkg/captcha/ops/hcaptcha-verify", "pkg/captcha/ops/verify", "pkg/captcha/ops/request", "pkg/captcha/ops/hcaptcha-config-get", "pkg/email-verification/ops/complete", "pkg/email-verification/ops/create", "pkg/team/worker", "pkg/team/standalone/billing-collect", "pkg/team/ops/member-get", "pkg/team/ops/member-relationship-get", "pkg/team/ops/resolve-display-name", "pkg/team/ops/profile-validate", "pkg/team/ops/user-ban-get", "pkg/team/ops/get", "pkg/team/ops/join-request-list", "pkg/team/ops/recommend", "pkg/team/ops/user-ban-list", "pkg/team/ops/search", "pkg/team/ops/avatar-upload-complete", "pkg/team/ops/validate", "pkg/team/ops/billing-aggregate", "pkg/team/ops/member-count", "pkg/team/ops/member-list", "pkg/cloud/worker", "pkg/cloud/ops/namespace-token-development-create", "pkg/cloud/ops/game-config-get", "pkg/cloud/ops/namespace-get", "pkg/cloud/ops/version-get", "pkg/cloud/ops/namespace-create", "pkg/cloud/ops/namespace-token-public-create", "pkg/cloud/ops/version-publish", "pkg/cloud/ops/game-config-create", "pkg/cloud/ops/game-token-create", "pkg/cloud/ops/device-link-create", "pkg/external/worker", "pkg/external/ops/request-validate", "pkg/nomad-log/worker", "pkg/nomad-log/standalone/follower", "pkg/nomad-log/ops/read", "pkg/faker/ops/mm-player", "pkg/faker/ops/job-template", "pkg/faker/ops/team", "pkg/faker/ops/region", "pkg/faker/ops/game-version", "pkg/faker/ops/build", "pkg/faker/ops/cdn-site", "pkg/faker/ops/user", "pkg/faker/ops/mm-lobby", "pkg/faker/ops/game", "pkg/faker/ops/job-run", "pkg/faker/ops/game-namespace", "pkg/faker/ops/mm-lobby-row", "pkg/token/ops/get", "pkg/token/ops/exchange", "pkg/token/ops/create", "pkg/token/ops/revoke", "pkg/user-follow/worker", "pkg/user-follow/ops/relationship-get", "pkg/user-follow/ops/request-list", "pkg/user-follow/ops/get", "pkg/user-follow/ops/toggle", "pkg/user-follow/ops/count", "pkg/user-follow/ops/list", "pkg/user-notification-auth/ops/register", "pkg/user-notification-auth/ops/unregister", "pkg/chat-thread/worker", "pkg/chat-thread/ops/unread-count", "pkg/chat-thread/ops/participant-list", "pkg/chat-thread/ops/get", "pkg/chat-thread/ops/get-or-create-for-topic", "pkg/chat-thread/ops/list-for-participant", "pkg/chat-thread/ops/get-for-topic", "pkg/chat-thread/ops/recent-for-user", "pkg/region/ops/get", "pkg/region/ops/recommend", "pkg/region/ops/list", "pkg/region/ops/resolve", "pkg/user-dev/worker", "pkg/custom-user-avatar/ops/upload-complete", "pkg/custom-user-avatar/ops/list-for-game", "pkg/kv-config/ops/namespace-get", "pkg/kv-config/ops/version-get", "pkg/kv-config/ops/namespace-create", "pkg/kv-config/ops/version-publish", "pkg/kv-config/ops/version-prepare", "pkg/telemetry/standalone/beacon", "pkg/nsfw/ops/image-score", "pkg/build/standalone/default-create", "pkg/build/ops/get", "pkg/build/ops/list-for-game", "pkg/build/ops/create", "pkg/job/standalone/gc", "pkg/cf/ops/turnstile-verify", "pkg/analytics/worker", "pkg/team-invite/worker", "pkg/team-invite/ops/get", "pkg/misc/standalone/playground", "pkg/email/ops/send", "pkg/profanity/ops/check", "pkg/user-identity/ops/delete", "pkg/user-identity/ops/get", "pkg/user-identity/ops/create", "pkg/user/worker", "pkg/user/standalone/delete-pending", "pkg/user/standalone/search-user-gc", "pkg/user/ops/pending-delete-toggle", "pkg/user/ops/thread-typing-status-set", "pkg/user/ops/profile-validate", "pkg/user/ops/get", "pkg/user/ops/mutual-friend-list", "pkg/user/ops/search", "pkg/user/ops/resolve-email", "pkg/user/ops/token-create", "pkg/user/ops/avatar-upload-complete", "pkg/user/ops/team-list", "pkg/module/worker", "pkg/module/ops/game-version-get", "pkg/module/ops/version-get", "pkg/module/ops/game-version-publish", "pkg/module/ops/get", "pkg/module/ops/ns-instance-get", "pkg/module/ops/instance-call", "pkg/module/ops/instance-get", "pkg/module/ops/game-version-prepare", "pkg/team-dev/worker", "pkg/team-dev/standalone/halt-collect", "pkg/team-dev/ops/get", "pkg/team-dev/ops/halt", "pkg/team-dev/ops/game-list", "pkg/user-presence/worker", "pkg/user-presence/standalone/gc", "pkg/user-presence/ops/touch", "pkg/user-presence/ops/get", "pkg/mm/worker", "pkg/mm/standalone/gc", "pkg/mm/standalone/gc-full", "pkg/mm/ops/lobby-state-get", "pkg/mm/ops/lobby-player-count", "pkg/mm/ops/lobby-idle-update", "pkg/mm/ops/player-count-for-namespace", "pkg/mm/ops/lobby-find-try-complete", "pkg/mm/ops/lobby-find-fail", "pkg/mm/ops/lobby-get", "pkg/mm/ops/player-get", "pkg/mm/ops/lobby-list-for-namespace", "pkg/mm/ops/lobby-find-lobby-query-list", "pkg/mm/ops/lobby-history", "pkg/mm/ops/lobby-runtime-aggregate", "pkg/mm/ops/dev-player-token-create", "pkg/mm/ops/lobby-list-for-user-id", "pkg/ip/ops/info", "pkg/mm-config/ops/namespace-get", "pkg/mm-config/ops/version-get", "pkg/mm-config/ops/namespace-create", "pkg/mm-config/ops/lobby-group-resolve-version", "pkg/mm-config/ops/version-publish", "pkg/mm-config/ops/lobby-group-get", "pkg/mm-config/ops/version-prepare", "pkg/mm-config/ops/lobby-group-resolve-name-id", "pkg/mm-config/ops/namespace-config-set", "pkg/mm-config/ops/namespace-config-validate", "pkg/chat-message/worker", "pkg/chat-message/ops/body-validate", "pkg/chat-message/ops/create-with-topic", "pkg/chat-message/ops/get", "pkg/chat-message/ops/list-for-user", "pkg/chat-message/ops/list", "pkg/chat-message/ops/validate", "pkg/user-report/worker", "pkg/game/ops/namespace-resolve-name-id", "pkg/game/ops/namespace-get", "pkg/game/ops/version-get", "pkg/game/ops/namespace-resolve-url", "pkg/game/ops/namespace-create", "pkg/game/ops/version-create", "pkg/game/ops/namespace-version-history-list", "pkg/game/ops/resolve-name-id", "pkg/game/ops/get", "pkg/game/ops/token-development-validate", "pkg/game/ops/version-validate", "pkg/game/ops/recommend", "pkg/game/ops/namespace-validate", "pkg/game/ops/banner-upload-complete", "pkg/game/ops/resolve-namespace-id", "pkg/game/ops/namespace-version-set", "pkg/game/ops/list-all", "pkg/game/ops/validate", "pkg/game/ops/namespace-list", "pkg/game/ops/create", "pkg/game/ops/logo-upload-complete", "pkg/game/ops/version-list", "pkg/identity-config/ops/namespace-get", "pkg/identity-config/ops/version-get", "pkg/identity-config/ops/namespace-create", "pkg/identity-config/ops/version-publish", "pkg/identity-config/ops/version-prepare", "pkg/job-run/worker", "pkg/job-run/standalone/alloc-update-monitor", "pkg/job-run/standalone/alloc-plan-monitor", "pkg/job-run/standalone/eval-update-monitor", "pkg/job-run/ops/get", "pkg/job-run/ops/metrics-log", "pkg/chat/worker", "pkg/chat/ops/last-read-ts-get", "pkg/game-user/worker", "pkg/game-user/ops/recent-session-list", "pkg/game-user/ops/get", "pkg/game-user/ops/recommend", "pkg/game-user/ops/link-create", "pkg/game-user/ops/link-get", "pkg/game-user/ops/list-for-user", "pkg/game-user/ops/create", "pkg/debug/ops/email-res", "pkg/cf-custom-hostname/worker", "pkg/cf-custom-hostname/ops/resolve-hostname", "pkg/cf-custom-hostname/ops/get", "pkg/cf-custom-hostname/ops/list-for-namespace-id", "pkg/upload/worker", "pkg/upload/standalone/provider-fill", "pkg/upload/ops/complete", "pkg/upload/ops/file-list", "pkg/upload/ops/get", "pkg/upload/ops/prepare", "pkg/upload/ops/list-for-user", "pkg/kv/worker", "pkg/kv/ops/get", "pkg/kv/ops/list", "pkg/tier/ops/list", "pkg/perf/ops/log-get"] # Speed up compilation [profile.dev] diff --git a/svc/api/admin/Cargo.toml b/svc/api/admin/Cargo.toml index b113ac624d..885dae3e39 100644 --- a/svc/api/admin/Cargo.toml +++ b/svc/api/admin/Cargo.toml @@ -27,7 +27,7 @@ s3-util = { path = "../../../lib/s3-util" } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" thiserror = "1.0" -tokio = { version = "1.21" } +tokio = { version = "1.29" } tracing = "0.1" tracing-futures = "0.2" tracing-subscriber = { version = "0.3", default-features = false, features = ["fmt", "json", "ansi"] } diff --git a/svc/api/admin/src/auth.rs b/svc/api/admin/src/auth.rs index d7313b00e5..44c06adb3c 100644 --- a/svc/api/admin/src/auth.rs +++ b/svc/api/admin/src/auth.rs @@ -23,9 +23,11 @@ impl ApiAuth for Auth { API_FORBIDDEN, reason = "Invalid auth" ); - } - Ok(Auth { _claims: None }) + Ok(Auth { _claims: None }) + } else { + internal_panic!("unreachable"); + } } async fn rate_limit(_rate_limit_ctx: AuthRateLimitCtx<'_>) -> GlobalResult<()> { diff --git a/svc/api/auth/Cargo.toml b/svc/api/auth/Cargo.toml index 8a6d905749..9b167b29cc 100644 --- a/svc/api/auth/Cargo.toml +++ b/svc/api/auth/Cargo.toml @@ -24,7 +24,7 @@ rivet-pools = { path = "../../../lib/pools" } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" thiserror = "1.0" -tokio = { version = "1.21" } +tokio = { version = "1.29" } tracing = "0.1" tracing-subscriber = { version = "0.3", default-features = false, features = ["fmt", "json", "ansi"] } url = "2.2.2" diff --git a/svc/api/cf-verification/Cargo.toml b/svc/api/cf-verification/Cargo.toml index ceb3b9e93a..6d267634f7 100644 --- a/svc/api/cf-verification/Cargo.toml +++ b/svc/api/cf-verification/Cargo.toml @@ -24,7 +24,7 @@ rivet-pools = { path = "../../../lib/pools" } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" thiserror = "1.0" -tokio = { version = "1.21" } +tokio = { version = "1.29" } tracing = "0.1" tracing-subscriber = { version = "0.3", default-features = false, features = ["fmt", "json", "ansi"] } url = "2.2.2" diff --git a/svc/api/chat/Cargo.toml b/svc/api/chat/Cargo.toml index 84b210c7c8..0b3fa8dfad 100644 --- a/svc/api/chat/Cargo.toml +++ b/svc/api/chat/Cargo.toml @@ -25,7 +25,7 @@ rivet-pools = { path = "../../../lib/pools" } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" thiserror = "1.0" -tokio = { version = "1.21" } +tokio = { version = "1.29" } tracing = "0.1" tracing-subscriber = { version = "0.3", default-features = false, features = ["fmt", "json", "ansi"] } url = "2.2.2" diff --git a/svc/api/chat/src/convert/identity.rs b/svc/api/chat/src/convert/identity.rs index 65bd0f94bf..1c50a22c10 100644 --- a/svc/api/chat/src/convert/identity.rs +++ b/svc/api/chat/src/convert/identity.rs @@ -13,11 +13,7 @@ pub fn handle_without_presence( identity_id: user_id.to_string(), display_name: user.display_name.to_owned(), account_number: user.account_number as i32, - avatar_url: util::route::user_avatar( - &user.avatar_id, - user.profile_upload_id.map(|x| x.as_uuid()), - user.profile_file_name.as_ref(), - ), + avatar_url: util::route::user_avatar(&user), presence: None, is_registered: true, // TODO: external: models::IdentityExternalLinks { diff --git a/svc/api/chat/src/convert/mod.rs b/svc/api/chat/src/convert/mod.rs index fccc853c95..c2c9fd80fa 100644 --- a/svc/api/chat/src/convert/mod.rs +++ b/svc/api/chat/src/convert/mod.rs @@ -18,14 +18,8 @@ pub fn game_handle(game: &backend::game::Game) -> GlobalResult>>()?, + )) + } else { + None + }; + + let image_presigned_requests = if multipart_upload { + Some( + create_res + .image_presigned_requests + .iter() + .cloned() + .map(ApiTryInto::try_into) + .collect::>>()?, + ) + } else { + None + }; + + Ok(new_models::CloudGamesCreateGameBuildResponse { + build_id: internal_unwrap!(create_res.build_id).as_uuid(), + upload_id: internal_unwrap!(create_res.upload_id).as_uuid(), + image_presigned_request, + image_presigned_requests, }) } diff --git a/svc/api/cloud/src/route/games/mod.rs b/svc/api/cloud/src/route/games/mod.rs index c19fe0f2f9..7f0c792307 100644 --- a/svc/api/cloud/src/route/games/mod.rs +++ b/svc/api/cloud/src/route/games/mod.rs @@ -177,6 +177,7 @@ async fn gen_default_version_config( max_players_normal: 32, max_players_direct: 32, max_players_party: 32, + listable: true, runtime: Some( backend::matchmaker::lobby_runtime::Docker { @@ -200,6 +201,10 @@ async fn gen_default_version_config( } .into(), ), + + find_config: None, + join_config: None, + create_config: None, }], captcha: None, }), diff --git a/svc/api/cloud/tests/basic.rs b/svc/api/cloud/tests/basic.rs index 4c674be3f1..322b7b2469 100644 --- a/svc/api/cloud/tests/basic.rs +++ b/svc/api/cloud/tests/basic.rs @@ -527,6 +527,11 @@ async fn generic() { region_id: Some(primary_region_id.into()), create_ray_id: None, preemptively_created: false, + + creator_user_id: None, + is_custom: false, + publicity: None, + lobby_config_json: None, }) .await .unwrap(); diff --git a/svc/api/group/Cargo.toml b/svc/api/group/Cargo.toml index c5791e5fc2..9bbb657332 100644 --- a/svc/api/group/Cargo.toml +++ b/svc/api/group/Cargo.toml @@ -25,7 +25,7 @@ rivet-pools = { path = "../../../lib/pools" } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" thiserror = "1.0" -tokio = { version = "1.21" } +tokio = { version = "1.29" } tracing = "0.1" tracing-subscriber = { version = "0.3", default-features = false, features = ["fmt", "json", "ansi"] } url = "2.2.2" diff --git a/svc/api/group/src/convert/group.rs b/svc/api/group/src/convert/group.rs index 6005200ab1..7681bedbcb 100644 --- a/svc/api/group/src/convert/group.rs +++ b/svc/api/group/src/convert/group.rs @@ -9,10 +9,7 @@ pub fn handle(team: &backend::team::Team, is_developer: bool) -> GlobalResult(metadata.as_str())) .transpose()?, mutual_metadata: if is_mutual_following { game_activity .friend_metadata .as_ref() - .map(serde_json::to_value) + .map(|metadata| serde_json::from_str::(metadata.as_str())) .transpose()? } else { None diff --git a/svc/api/group/src/convert/mod.rs b/svc/api/group/src/convert/mod.rs index a47011a88f..ad89a9031b 100644 --- a/svc/api/group/src/convert/mod.rs +++ b/svc/api/group/src/convert/mod.rs @@ -20,14 +20,8 @@ pub fn game_handle(game: &backend::game::Game) -> GlobalResult>(), 1024)?; - let thumbnail_url = util::route::user_avatar( - &sender.avatar_id, - sender.profile_upload_id.map(|id| id.as_uuid()), - sender.profile_file_name.as_ref(), - ); + let thumbnail_url = util::route::user_avatar(&sender); let url = util::route::thread(thread_id.as_uuid()); Ok(Some(models::IdentityGlobalEventNotification { @@ -81,14 +77,16 @@ pub async fn get_namespace_id(ctx: &Ctx) -> GlobalResult { pub async fn resolve_user_with_game_user_id( ctx: &Ctx, game_user_id: Uuid, -) -> GlobalResult { +) -> GlobalResult> { let game_user_res = op!([ctx] game_user_get { game_user_ids: vec![game_user_id.into()] }) .await?; - let game_user = internal_unwrap_owned!(game_user_res.game_users.first()).clone(); + let Some(game_user) = game_user_res.game_users.first().clone() else { + return Ok(None); + }; - Ok(internal_unwrap!(game_user.user_id).as_uuid()) + Ok(Some(internal_unwrap!(game_user.user_id).as_uuid())) } pub fn touch_user_presence(ctx: OperationContext<()>, user_id: Uuid, silent: bool) { diff --git a/svc/api/identity/tests/basic.rs b/svc/api/identity/tests/basic.rs index fdf9b39e5d..12f261ea16 100644 --- a/svc/api/identity/tests/basic.rs +++ b/svc/api/identity/tests/basic.rs @@ -127,6 +127,7 @@ impl Ctx { max_players_normal: 8, max_players_direct: 10, max_players_party: 12, + listable: true, runtime: Some(backend::matchmaker::lobby_runtime::Docker { build_id: build_res.build_id, @@ -157,6 +158,10 @@ impl Ctx { }, ], }.into()), + + find_config: None, + join_config: None, + create_config: None, }], }), ..Default::default() diff --git a/svc/api/job/Cargo.toml b/svc/api/job/Cargo.toml index 8e809daf93..b53305d27b 100644 --- a/svc/api/job/Cargo.toml +++ b/svc/api/job/Cargo.toml @@ -23,7 +23,7 @@ rivet-pools = { path = "../../../lib/pools" } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" thiserror = "1.0" -tokio = { version = "1.21" } +tokio = { version = "1.29" } tracing = "0.1" tracing-subscriber = { version = "0.3", default-features = false, features = ["fmt", "json", "ansi"] } url = "2.2.2" diff --git a/svc/api/kv/Cargo.toml b/svc/api/kv/Cargo.toml index c315b12f04..2af83b60a0 100644 --- a/svc/api/kv/Cargo.toml +++ b/svc/api/kv/Cargo.toml @@ -26,7 +26,7 @@ rivet-pools = { path = "../../../lib/pools" } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" thiserror = "1.0" -tokio = { version = "1.21" } +tokio = { version = "1.29" } tracing = "0.1" tracing-subscriber = { version = "0.3", default-features = false, features = ["fmt", "json", "ansi"] } url = "2.2.2" diff --git a/svc/api/kv/src/route/mod.rs b/svc/api/kv/src/route/mod.rs index a07de78553..d849fd9a94 100644 --- a/svc/api/kv/src/route/mod.rs +++ b/svc/api/kv/src/route/mod.rs @@ -22,17 +22,59 @@ define_router! { cors: CorsConfigBuilder::public().build(), routes: { "entries": { - GET: operations::get(query: operations::SingleQuery), - PUT: operations::put(body: models::KvPutRequest), - DELETE: operations::delete(query: operations::SingleQuery), + GET: operations::get( + query: operations::SingleQuery, + rate_limit: { + buckets: [ + { count: 1_000_000 }, + ], + }, + ), + PUT: operations::put( + body: models::KvPutRequest, + rate_limit: { + buckets: [ + { count: 100_000 }, + ], + }, + ), + DELETE: operations::delete( + query: operations::SingleQuery, + rate_limit: { + buckets: [ + { count: 100_000 }, + ], + }, + ), }, "entries" / "list": { GET: operations::list(query: operations::ListQuery), }, "entries" / "batch": { - GET: batch_operations::get_batch(query: batch_operations::BatchQuery), - PUT: batch_operations::put_batch(body: models::KvPutBatchRequest), - DELETE: batch_operations::delete_batch(query: batch_operations::BatchQuery), + GET: batch_operations::get_batch( + query: batch_operations::BatchQuery, + rate_limit: { + buckets: [ + { count: 1_000_000 }, + ], + }, + ), + PUT: batch_operations::put_batch( + body: models::KvPutBatchRequest, + rate_limit: { + buckets: [ + { count: 100_000 }, + ], + }, + ), + DELETE: batch_operations::delete_batch( + query: batch_operations::BatchQuery, + rate_limit: { + buckets: [ + { count: 100_000 }, + ], + }, + ), }, }, } diff --git a/svc/api/kv/tests/basic.rs b/svc/api/kv/tests/basic.rs index b189831ddb..e6932b3b40 100644 --- a/svc/api/kv/tests/basic.rs +++ b/svc/api/kv/tests/basic.rs @@ -86,6 +86,11 @@ impl Ctx { region_id: Some(self.primary_region_id.into()), create_ray_id: None, preemptively_created: false, + + creator_user_id: None, + is_custom: false, + publicity: None, + lobby_config_json: None, }) .await .unwrap(); @@ -156,6 +161,7 @@ impl Ctx { max_players_normal: 8, max_players_direct: 10, max_players_party: 12, + listable: true, runtime: Some(backend::matchmaker::lobby_runtime::Docker { build_id: build_res.build_id, @@ -186,6 +192,10 @@ impl Ctx { }, ], }.into()), + + find_config: None, + join_config: None, + create_config: None, }], }), ..Default::default() diff --git a/svc/api/matchmaker/Cargo.toml b/svc/api/matchmaker/Cargo.toml index 10dfbd2ade..cce9c42f93 100644 --- a/svc/api/matchmaker/Cargo.toml +++ b/svc/api/matchmaker/Cargo.toml @@ -9,6 +9,7 @@ license = "Apache-2.0" rivet-convert = { path = "../../../lib/convert" } api-helper = { path = "../../../lib/api-helper/build" } async-trait = "0.1" +bytes = "1.0" chirp-client = { path = "../../../lib/chirp/client" } rivet-operation = { path = "../../../lib/operation/core" } chrono = "0.4" @@ -25,7 +26,7 @@ rivet-pools = { path = "../../../lib/pools" } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" thiserror = "1.0" -tokio = { version = "1.21" } +tokio = { version = "1.29" } tracing = "0.1" tracing-subscriber = { version = "0.3", default-features = false, features = ["fmt", "json", "ansi"] } url = "2.2.2" @@ -37,6 +38,7 @@ captcha-verify = { path = "../../pkg/captcha/ops/verify" } cdn-namespace-get = { path = "../../pkg/cdn/ops/namespace-get" } game-namespace-get = { path = "../../pkg/game/ops/namespace-get" } game-namespace-resolve-url = { path = "../../pkg/game/ops/namespace-resolve-url" } +game-user-get = { path = "../../pkg/game-user/ops/get" } captcha-hcaptcha-config-get = { path = "../../pkg/captcha/ops/hcaptcha-config-get" } job-run-get = { path = "../../pkg/job-run/ops/get" } mm-config-lobby-group-resolve-version = { path = "../../pkg/mm-config/ops/lobby-group-resolve-version" } @@ -45,10 +47,13 @@ mm-dev-player-token-create = { path = "../../pkg/mm/ops/dev-player-token-create" mm-lobby-get = { path = "../../pkg/mm/ops/lobby-get" } mm-lobby-list-for-namespace = { path = "../../pkg/mm/ops/lobby-list-for-namespace" } mm-lobby-player-count = { path = "../../pkg/mm/ops/lobby-player-count" } +mm-lobby-state-get = { path = "../../pkg/mm/ops/lobby-state-get" } region-get = { path = "../../pkg/region/ops/get" } region-recommend = { path = "../../pkg/region/ops/recommend" } region-resolve = { path = "../../pkg/region/ops/resolve" } token-create = { path = "../../pkg/token/ops/create" } +token-revoke = { path = "../../pkg/token/ops/revoke" } +user-identity-get = { path = "../../pkg/user-identity/ops/get" } [dev-dependencies] reqwest = "0.11" diff --git a/svc/api/matchmaker/src/auth.rs b/svc/api/matchmaker/src/auth.rs index 5f8eb016e7..62b8e1a168 100644 --- a/svc/api/matchmaker/src/auth.rs +++ b/svc/api/matchmaker/src/auth.rs @@ -110,4 +110,34 @@ impl Auth { Ok(None) } } + + pub async fn fetch_game_user_option( + &self, + ctx: &OperationContext<()>, + ) -> GlobalResult> { + if let Ok(claims) = self.claims() { + if let Ok(game_user_ent) = claims.as_game_user() { + let game_user_res = op!([ctx] game_user_get { + game_user_ids: vec![game_user_ent.game_user_id.into()] + }) + .await?; + let game_user = internal_unwrap_owned!(game_user_res.game_users.first()); + + // Verify that game user is not deleted + if game_user.deleted_ts.is_some() { + let jti = internal_unwrap_owned!(claims.jti); + op!([ctx] token_revoke { + jtis: vec![jti], + }) + .await?; + + panic_with!(TOKEN_REVOKED); + } + + return Ok(Some(internal_unwrap!(game_user.user_id).as_uuid())); + } + } + + Ok(None) + } } diff --git a/svc/api/matchmaker/src/route/lobbies.rs b/svc/api/matchmaker/src/route/lobbies.rs index f6475bcb83..931b2b1b86 100644 --- a/svc/api/matchmaker/src/route/lobbies.rs +++ b/svc/api/matchmaker/src/route/lobbies.rs @@ -1,3 +1,8 @@ +use std::{ + collections::{HashMap, HashSet}, + str::FromStr, +}; + use api_helper::{anchor::WatchIndexQuery, ctx::Ctx}; use proto::{ backend::{self, pkg::*}, @@ -6,11 +11,8 @@ use proto::{ use rivet_api::models; use rivet_convert::ApiTryInto; use rivet_operation::prelude::*; +use serde::Deserialize; use serde_json::json; -use std::{ - collections::{HashMap, HashSet}, - str::FromStr, -}; use crate::{ auth::Auth, @@ -66,7 +68,15 @@ pub async fn join( lobby, ports, player, - } = find_inner(&ctx, &ns_data, find_query, body.captcha).await?; + } = find_inner( + &ctx, + &ns_data, + find_query, + None, + body.captcha, + VerificationType::UserData(body.verification_data.flatten()), + ) + .await?; Ok(models::MatchmakerJoinLobbyResponse { lobby, @@ -128,56 +138,9 @@ pub async fn find( }) .collect::>>()?; - // Resolve the region IDs. - // - // `region_ids` represents the requested regions in order of priority. - let region_ids = if let Some(region_name_ids) = body.regions { - // Resolve the region ID corresponding to the name IDs - let resolve_res = op!([ctx] region_resolve { - name_ids: region_name_ids.clone(), - }) - .await?; - - // Map to region IDs and decide - let region_ids = region_name_ids - .iter() - .flat_map(|name_id| resolve_res.regions.iter().find(|r| r.name_id == *name_id)) - .flat_map(|r| r.region_id.as_ref()) - .map(common::Uuid::as_uuid) - .collect::>(); - - internal_assert_eq!(region_ids.len(), region_name_ids.len(), "region not found"); - - region_ids - } else { - // Find all enabled region IDs in all requested lobby groups - let enabled_region_ids = lobby_groups - .iter() - .flat_map(|(lg, _)| { - lg.regions - .iter() - .filter_map(|r| r.region_id.as_ref()) - .map(common::Uuid::as_uuid) - .collect::>() - }) - .collect::>() - .into_iter() - .map(Into::::into) - .collect::>(); - - // Auto-select the closest region - let recommend_res = op!([ctx] region_recommend { - latitude: Some(lat), - longitude: Some(long), - region_ids: enabled_region_ids, - ..Default::default() - }) - .await?; - let primary_region = internal_unwrap_owned!(recommend_res.regions.first()); - let primary_region_id = internal_unwrap!(primary_region.region_id).as_uuid(); - - vec![primary_region_id] - }; + // Resolve region IDs + let region_ids = + resolve_region_ids(&ctx, lat, long, body.regions.as_ref(), &lobby_groups).await?; // Validate that there is a lobby group and region pair that is valid. // @@ -220,7 +183,7 @@ pub async fn find( let auto_create = if let Some(auto_create) = auto_create { auto_create } else { - internal_panic!("no valid lobby group and region id pair found for auto-create"); + panic_with!(MATCHMAKER_AUTO_CREATE_FAILED); }; // Build query and find lobby @@ -245,7 +208,15 @@ pub async fn find( lobby, ports, player, - } = find_inner(&ctx, &ns_data, find_query, body.captcha).await?; + } = find_inner( + &ctx, + &ns_data, + find_query, + None, + body.captcha, + VerificationType::UserData(body.verification_data.flatten()), + ) + .await?; Ok(models::MatchmakerFindLobbyResponse { lobby, @@ -254,16 +225,171 @@ pub async fn find( }) } +// MARK: POST /lobbies/create +pub async fn create( + ctx: Ctx, + body: models::MatchmakerLobbiesCreateRequest, +) -> GlobalResult { + let (lat, long) = internal_unwrap_owned!(ctx.coords()); + + // Mock response + if let Some(ns_dev_ent) = ctx.auth().game_ns_dev_option()? { + let FindResponse { + lobby, + ports, + player, + } = dev_mock_lobby(&ctx, &ns_dev_ent).await?; + return Ok(models::MatchmakerCreateLobbyResponse { + lobby, + ports, + player, + }); + } + + // Verify bearer auth and get user ID + let (game_ns, user_id) = tokio::try_join!( + ctx.auth().game_ns(&ctx), + ctx.auth().fetch_game_user_option(ctx.op_ctx()), + )?; + let ns_data = fetch_ns(&ctx, &game_ns).await?; + + // Fetch version config + let version_config_res = op!([ctx] mm_config_version_get { + version_ids: vec![ns_data.version_id.into()], + }) + .await?; + let version_data = internal_unwrap_owned!(version_config_res.versions.first()); + let version_config = internal_unwrap!(version_data.config); + let version_meta = internal_unwrap!(version_data.config_meta); + + // Find lobby groups that match the requested game mode + let (lobby_group, lobby_group_meta) = unwrap_with_owned!( + version_config + .lobby_groups + .iter() + .zip(version_meta.lobby_groups.iter()) + .find(|(lgc, _)| lgc.name_id == body.game_mode), + MATCHMAKER_GAME_MODE_NOT_FOUND + ); + + let publicity = match body.publicity { + models::MatchmakerCustomLobbyPublicity::Public => { + backend::matchmaker::lobby::Publicity::Public + } + models::MatchmakerCustomLobbyPublicity::Private => { + backend::matchmaker::lobby::Publicity::Private + } + }; + + // Verify that lobby creation is enabled and user can create a lobby + util_mm::verification::verify_config( + ctx.op_ctx(), + &util_mm::verification::VerifyConfigOpts { + kind: util_mm::verification::ConnectionKind::Create, + namespace_id: ns_data.namespace_id, + user_id, + lobby_group, + lobby_group_meta, + lobby_info: None, + lobby_state_json: None, + verification_data_json: body + .verification_data + .as_ref() + .map(|o| o.as_ref().map(serde_json::to_string)) + .flatten() + .transpose()? + .as_deref(), + lobby_config_json: body + .lobby_config + .as_ref() + .map(|o| o.as_ref().map(serde_json::to_string)) + .flatten() + .transpose()? + .as_deref(), + custom_lobby_publicity: Some(publicity), + }, + ) + .await?; + + // Resolve region IDs + let region_ids = resolve_region_ids( + &ctx, + lat, + long, + body.region.map(|r| vec![r]).as_ref(), + &[(lobby_group, lobby_group_meta)], + ) + .await?; + let region_id = *unwrap_with_owned!(region_ids.first(), MATCHMAKER_REGION_NOT_FOUND); + + let lobby_id = Uuid::new_v4(); + let lobby_create_res = + msg!([ctx] mm::msg::lobby_create(lobby_id) -> mm::msg::lobby_create_complete { + lobby_id: Some(lobby_id.into()), + namespace_id: Some(ns_data.namespace_id.into()), + lobby_group_id: lobby_group_meta.lobby_group_id, + region_id: Some(region_id.into()), + create_ray_id: Some(ctx.op_ctx().ray_id().into()), + preemptively_created: false, + + creator_user_id: user_id.map(Into::into), + is_custom: true, + publicity: Some(publicity as i32), + lobby_config_json: body.lobby_config + .as_ref() + .map(serde_json::to_string) + .transpose()?, + }) + .await?; + + // Join the lobby that was just created + let find_query = + mm::msg::lobby_find::message::Query::Direct(backend::matchmaker::query::Direct { + lobby_id: lobby_create_res.lobby_id, + }); + let FindResponse { + lobby, + ports, + player, + } = find_inner( + &ctx, + &ns_data, + find_query, + Some(version_config.clone()), + body.captcha, + VerificationType::Bypass, + ) + .await?; + + // TODO: Remove this hack to give Treafik time to update + tokio::time::sleep(std::time::Duration::from_secs(1)).await; + + // TODO: Cleanup lobby if find failed + + Ok(models::MatchmakerCreateLobbyResponse { + lobby, + ports, + player, + }) +} + +#[derive(Deserialize)] +pub struct ListQuery { + #[serde(default)] + include_state: bool, +} + // MARK: GET /lobbies/list pub async fn list( ctx: Ctx, _watch_index: WatchIndexQuery, + query: ListQuery, ) -> GlobalResult { let (lat, long) = internal_unwrap_owned!(ctx.coords()); // Mock response if let Some(ns_dev_ent) = ctx.auth().game_ns_dev_option()? { - return dev_mock_lobby_list(&ctx, &ns_dev_ent).await; + return dev_mock_lobby_list(&ctx, &ns_dev_ent, query.include_state).await; } let game_ns = ctx.auth().game_ns(&ctx).await?; @@ -273,7 +399,7 @@ pub async fn list( // Fetch version config and lobbies let (meta, lobbies) = tokio::try_join!( fetch_lobby_list_meta(ctx.op_ctx(), game_ns.namespace_id, lat, long), - fetch_lobby_list(ctx.op_ctx(), game_ns.namespace_id), + fetch_lobby_list(ctx.op_ctx(), game_ns.namespace_id, query.include_state), )?; let regions = meta @@ -290,8 +416,16 @@ pub async fn list( }) .collect(); + // Count lobbies by lobby group id + let mut lobbies_by_lobby_group_id: HashMap = HashMap::new(); + for lobby in &lobbies { + let lobby_group_id = internal_unwrap!(lobby.lobby.lobby_group_id).as_uuid(); + let entry = lobbies_by_lobby_group_id.entry(lobby_group_id).or_default(); + *entry += 1; + } + let lobbies = lobbies - .iter() + .into_iter() // Join with lobby group .filter_map(|lobby| { if let Some((lobby_group, _)) = meta @@ -305,20 +439,26 @@ pub async fn list( None } }) - // Filter out empty lobbies - .filter(|(lobby, _)| { + // Filter out empty and unlistable lobbies + .filter(|(lobby, lobby_group)| { + // Hide if not listable + if !lobby_group.listable { + return false; + } + // Keep if lobby not empty if lobby.player_count.registered_player_count != 0 { return true; } - // Keep if this is the only lobby in this lobby group - if lobbies - .iter() - .filter(|x| x.lobby.lobby_group_id == lobby.lobby.lobby_group_id) - .count() == 1 - { - return true; + // Keep if this is the only lobby in this lobby group (even if its empty) + if let Some(lobby_group_id) = lobby.lobby.lobby_group_id { + if *lobbies_by_lobby_group_id + .get(&lobby_group_id.as_uuid()) + .unwrap_or(&0) == 1 + { + return true; + } } // This lobby is empty (i.e. idle) and should not be listed @@ -335,16 +475,13 @@ pub async fn list( region_id: region.name_id.clone(), game_mode_id: lobby_group.name_id.clone(), lobby_id: internal_unwrap!(lobby.lobby.lobby_id).as_uuid(), - max_players_normal: std::convert::TryInto::try_into( - lobby.lobby.max_players_normal, - )?, - max_players_direct: std::convert::TryInto::try_into( - lobby.lobby.max_players_direct, - )?, - max_players_party: std::convert::TryInto::try_into(lobby.lobby.max_players_party)?, - total_player_count: std::convert::TryInto::try_into( + max_players_normal: ApiTryInto::try_into(lobby.lobby.max_players_normal)?, + max_players_direct: ApiTryInto::try_into(lobby.lobby.max_players_direct)?, + max_players_party: ApiTryInto::try_into(lobby.lobby.max_players_party)?, + total_player_count: ApiTryInto::try_into( lobby.player_count.registered_player_count, )?, + state: lobby.state.map(Some), }) }) .collect::>>()?; @@ -356,76 +493,6 @@ pub async fn list( }) } -async fn dev_mock_lobby_list( - ctx: &Ctx, - ns_dev_ent: &rivet_claims::ent::GameNamespaceDevelopment, -) -> GlobalResult { - // Read the version config - let ns_res = op!([ctx] game_namespace_get { - namespace_ids: vec![ns_dev_ent.namespace_id.into()], - }) - .await?; - let ns_data = internal_unwrap_owned!(ns_res.namespaces.first()); - let version_id = internal_unwrap!(ns_data.version_id).as_uuid(); - - let version_res = op!([ctx] mm_config_version_get { - version_ids: vec![version_id.into()], - }) - .await?; - let version = internal_unwrap_owned!( - version_res.versions.first(), - "no matchmaker config for namespace" - ); - let version_config = internal_unwrap!(version.config); - - // Create fake region - let region = models::MatchmakerRegionInfo { - region_id: util_mm::consts::DEV_REGION_ID.into(), - provider_display_name: util_mm::consts::DEV_PROVIDER_NAME.into(), - region_display_name: util_mm::consts::DEV_REGION_NAME.into(), - datacenter_coord: Box::new(models::GeoCoord { - latitude: 0.0, - longitude: 0.0, - }), - datacenter_distance_from_client: Box::new(models::GeoDistance { - kilometers: 0.0, - miles: 0.0, - }), - }; - - // List game modes - let game_modes = version_config - .lobby_groups - .iter() - .map(|lg| models::MatchmakerGameModeInfo { - game_mode_id: lg.name_id.clone(), - }) - .collect(); - - // Create a fake lobby in each game mode - let lobbies = version_config - .lobby_groups - .iter() - .map(|lg| { - GlobalResult::Ok(models::MatchmakerLobbyInfo { - region_id: util_mm::consts::DEV_REGION_ID.into(), - game_mode_id: lg.name_id.clone(), - lobby_id: Uuid::nil(), - max_players_normal: std::convert::TryInto::try_into(lg.max_players_normal)?, - max_players_direct: std::convert::TryInto::try_into(lg.max_players_direct)?, - max_players_party: std::convert::TryInto::try_into(lg.max_players_party)?, - total_player_count: 0, - }) - }) - .collect::>>()?; - - Ok(models::MatchmakerListLobbiesResponse { - regions: vec![region], - game_modes, - lobbies, - }) -} - struct FetchLobbyListMeta { lobby_groups: Vec<( backend::matchmaker::LobbyGroup, @@ -510,12 +577,14 @@ async fn fetch_lobby_list_meta( struct FetchLobbyListEntry { lobby: backend::matchmaker::Lobby, player_count: mm::lobby_player_count::response::Lobby, + state: Option, } /// Fetches all the lobbies and their associated player counts. async fn fetch_lobby_list( ctx: &OperationContext<()>, namespace_id: Uuid, + include_state: bool, ) -> GlobalResult> { // Fetch lobby IDs let lobby_ids = { @@ -530,7 +599,7 @@ async fn fetch_lobby_list( // Fetch all lobbies let lobbies = { - let (lobby_get_res, player_count_res) = tokio::try_join!( + let (lobby_get_res, player_count_res, lobby_states) = tokio::try_join!( op!([ctx] mm_lobby_get { lobby_ids: lobby_ids.clone(), include_stopped: false, @@ -538,30 +607,60 @@ async fn fetch_lobby_list( op!([ctx] mm_lobby_player_count { lobby_ids: lobby_ids.clone(), }), + async { + if include_state { + let lobbies_res = op!([ctx] mm_lobby_state_get { + lobby_ids: lobby_ids.clone(), + }) + .await?; + + Ok(lobbies_res.lobbies) + } else { + Ok(Vec::new()) + } + }, )?; - // Match lobby data with player counts + // Match lobby data with player counts and states lobby_get_res .lobbies .iter() - .filter_map(|lobby| { - player_count_res + .filter(|x| { + matches!( + backend::matchmaker::lobby::Publicity::from_i32(x.publicity as i32), + Some(backend::matchmaker::lobby::Publicity::Public) + ) + }) + .map(|lobby| { + let player_count = player_count_res .lobbies .iter() - .find(|pc| pc.lobby_id == lobby.lobby_id) - .map(|pc| FetchLobbyListEntry { + .find(|pc| pc.lobby_id == lobby.lobby_id); + let state = lobby_states.iter().find(|ls| ls.lobby_id == lobby.lobby_id); + + if let (Some(player_count), Some(state)) = (player_count, state) { + Ok(Some(FetchLobbyListEntry { lobby: lobby.clone(), - player_count: pc.clone(), - }) + player_count: player_count.clone(), + state: state + .state_json + .as_ref() + .map(|s| serde_json::from_str::(&s)) + .transpose()?, + })) + } else { + Ok(None) + } }) - .collect::>() + .filter_map(|res| res.transpose()) + .collect::>>()? }; Ok(lobbies) } // MARK: PUT /lobbies/closed -pub async fn closed( +pub async fn set_closed( ctx: Ctx, body: models::MatchmakerLobbiesSetClosedRequest, ) -> GlobalResult { @@ -581,6 +680,59 @@ pub async fn closed( Ok(json!({})) } +// MARK: PUT /lobbies/state +pub async fn set_state(ctx: Ctx, body: bytes::Bytes) -> GlobalResult { + // Mock response + if ctx.auth().game_ns_dev_option()?.is_some() { + return Ok(json!({})); + } + + let lobby_ent = ctx.auth().lobby()?; + let state = if !body.is_empty() { + let parsed = serde_json::from_slice::(&body[..])?; + + Some(serde_json::to_string(&parsed)?) + } else { + None + }; + + msg!([ctx] mm::msg::lobby_state_set(lobby_ent.lobby_id) { + lobby_id: Some(lobby_ent.lobby_id.into()), + state_json: state, + }) + .await?; + + Ok(json!({})) +} + +// MARK: GET /lobbies/{}/state +pub async fn get_state( + ctx: Ctx, + lobby_id: Uuid, + _watch_index: WatchIndexQuery, +) -> GlobalResult> { + // Mock response + if ctx.auth().game_ns_dev_option()?.is_some() { + return Ok(Some(json!({}))); + } + + let lobby_ent = ctx.auth().lobby()?; + + let lobbies_res = op!([ctx] mm_lobby_state_get { + lobby_ids: vec![lobby_id.into()], + }) + .await?; + let lobby = internal_unwrap_owned!(lobbies_res.lobbies.first()); + + let state = lobby + .state_json + .as_ref() + .map(|state_json| serde_json::from_str::(&state_json)) + .transpose()?; + + Ok(state) +} + // MARK: Utilities struct FindResponse { lobby: Box, @@ -588,21 +740,38 @@ struct FindResponse { player: Box, } +#[derive(Debug)] +enum VerificationType { + UserData(Option), + Bypass, +} + #[tracing::instrument(err, skip(ctx, game_ns))] async fn find_inner( ctx: &Ctx, game_ns: &NamespaceData, query: mm::msg::lobby_find::message::Query, + version_config: Option, captcha: Option>, + verification: VerificationType, ) -> GlobalResult { - // Get version config - let version_config_res = op!([ctx] mm_config_version_get { - version_ids: vec![game_ns.version_id.into()], - }) - .await?; + let (version_config, user_id) = tokio::try_join!( + // Fetch version config if it was not passed as an argument + async { + if let Some(version_config) = version_config { + Ok(version_config) + } else { + let version_config_res = op!([ctx] mm_config_version_get { + version_ids: vec![game_ns.version_id.into()], + }) + .await?; - let version_config = internal_unwrap_owned!(version_config_res.versions.first()); - let version_config = internal_unwrap!(version_config.config); + let version_config = internal_unwrap_owned!(version_config_res.versions.first()); + Ok(internal_unwrap!(version_config.config).clone()) + } + }, + ctx.auth().fetch_game_user_option(ctx.op_ctx()), + )?; // Validate captcha if let Some(captcha_config) = &version_config.captcha { @@ -695,7 +864,9 @@ async fn find_inner( // Find lobby let query_id = Uuid::new_v4(); - let find_res = msg!([ctx] @notrace mm::msg::lobby_find(game_ns.namespace_id, query_id) -> Result { + let find_res = msg!([ctx] @notrace mm::msg::lobby_find(game_ns.namespace_id, query_id) + -> Result + { namespace_id: Some(game_ns.namespace_id.into()), query_id: Some(query_id.into()), join_kind: backend::matchmaker::query::JoinKind::Normal as i32, @@ -705,6 +876,16 @@ async fn find_inner( client_info: Some(ctx.client_info()), }], query: Some(query), + user_id: user_id.map(Into::into), + verification_data_json: if let VerificationType::UserData(verification_data) = &verification { + verification_data + .as_ref() + .map(|data| serde_json::to_string(&data)) + .transpose()? + } else { + None + }, + bypass_verification: matches!(verification, VerificationType::Bypass), }) .await?; let lobby_id = match find_res @@ -728,6 +909,13 @@ async fn find_inner( RegionNotEnabled => panic_with!(MATCHMAKER_REGION_NOT_ENABLED_FOR_GAME_MODE), DevTeamInvalidStatus => panic_with!(GROUP_INVALID_DEVELOPER_STATUS), + + FindDisabled => panic_with!(MATCHMAKER_FIND_DISABLED), + JoinDisabled => panic_with!(MATCHMAKER_JOIN_DISABLED), + VerificationFailed => panic_with!(MATCHMAKER_VERIFICATION_FAILED), + VerificationRequestFailed => panic_with!(MATCHMAKER_VERIFICATION_REQUEST_FAILED), + IdentityRequired => panic_with!(MATCHMAKER_IDENTITY_REQUIRED), + RegistrationRequired => panic_with!(MATCHMAKER_REGISTRATION_REQUIRED), }; } Err(None) => internal_panic!("failed to parse find error code"), @@ -771,6 +959,7 @@ async fn find_inner( }) .await?; + // NOTE: The matchmaker config is fetched again to account for outdated lobbies let version_id = internal_unwrap_owned!(version_res.versions.first()); let version_id = internal_unwrap!(version_id.version_id); let version_res = op!([ctx] mm_config_version_get { @@ -799,7 +988,6 @@ async fn find_inner( // Convert the ports to client-friendly ports let run = internal_unwrap_owned!(run_res.runs.first()); - let ports = docker_runtime .ports .iter() @@ -837,6 +1025,71 @@ async fn find_inner( }) } +async fn resolve_region_ids( + ctx: &Ctx, + lat: f64, + long: f64, + regions: Option<&Vec>, + lobby_groups: &[( + &backend::matchmaker::LobbyGroup, + &backend::matchmaker::LobbyGroupMeta, + )], +) -> GlobalResult> { + // Represents the requested regions in order of priority. + let region_ids = if let Some(region_name_ids) = regions { + // Resolve the region ID corresponding to the name IDs + let resolve_res = op!([ctx] region_resolve { + name_ids: region_name_ids.clone(), + }) + .await?; + + // Map to region IDs and decide + let region_ids = resolve_res + .regions + .iter() + .map(|r| Ok(internal_unwrap!(r.region_id).as_uuid())) + .collect::>>()?; + + assert_eq_with!( + region_ids.len(), + region_name_ids.len(), + MATCHMAKER_REGION_NOT_FOUND + ); + + region_ids + } else { + // Find all enabled region IDs in all requested lobby groups + let enabled_region_ids = lobby_groups + .iter() + .flat_map(|(lg, _)| { + lg.regions + .iter() + .filter_map(|r| r.region_id.as_ref()) + .map(common::Uuid::as_uuid) + .collect::>() + }) + .collect::>() + .into_iter() + .map(Into::::into) + .collect::>(); + + // Auto-select the closest region + let recommend_res = op!([ctx] region_recommend { + latitude: Some(lat), + longitude: Some(long), + region_ids: enabled_region_ids, + ..Default::default() + }) + .await?; + let primary_region = internal_unwrap_owned!(recommend_res.regions.first()); + let primary_region_id = internal_unwrap!(primary_region.region_id).as_uuid(); + + vec![primary_region_id] + }; + + Ok(region_ids) +} + #[tracing::instrument(err, skip(ctx))] async fn dev_mock_lobby( ctx: &Ctx, @@ -903,6 +1156,78 @@ async fn dev_mock_lobby( }) } +async fn dev_mock_lobby_list( + ctx: &Ctx, + ns_dev_ent: &rivet_claims::ent::GameNamespaceDevelopment, + include_state: bool, +) -> GlobalResult { + // Read the version config + let ns_res = op!([ctx] game_namespace_get { + namespace_ids: vec![ns_dev_ent.namespace_id.into()], + }) + .await?; + let ns_data = internal_unwrap_owned!(ns_res.namespaces.first()); + let version_id = internal_unwrap!(ns_data.version_id).as_uuid(); + + let version_res = op!([ctx] mm_config_version_get { + version_ids: vec![version_id.into()], + }) + .await?; + let version = internal_unwrap_owned!( + version_res.versions.first(), + "no matchmaker config for namespace" + ); + let version_config = internal_unwrap!(version.config); + + // Create fake region + let region = models::MatchmakerRegionInfo { + region_id: util_mm::consts::DEV_REGION_ID.into(), + provider_display_name: util_mm::consts::DEV_PROVIDER_NAME.into(), + region_display_name: util_mm::consts::DEV_REGION_NAME.into(), + datacenter_coord: Box::new(models::GeoCoord { + latitude: 0.0, + longitude: 0.0, + }), + datacenter_distance_from_client: Box::new(models::GeoDistance { + kilometers: 0.0, + miles: 0.0, + }), + }; + + // List game modes + let game_modes = version_config + .lobby_groups + .iter() + .map(|lg| models::MatchmakerGameModeInfo { + game_mode_id: lg.name_id.clone(), + }) + .collect(); + + // Create a fake lobby in each game mode + let lobbies = version_config + .lobby_groups + .iter() + .map(|lg| { + GlobalResult::Ok(models::MatchmakerLobbyInfo { + region_id: util_mm::consts::DEV_REGION_ID.into(), + game_mode_id: lg.name_id.clone(), + lobby_id: Uuid::nil(), + max_players_normal: std::convert::TryInto::try_into(lg.max_players_normal)?, + max_players_direct: std::convert::TryInto::try_into(lg.max_players_direct)?, + max_players_party: std::convert::TryInto::try_into(lg.max_players_party)?, + total_player_count: 0, + state: Some(Some(json!({ "foo": "bar" }))), + }) + }) + .collect::>>()?; + + Ok(models::MatchmakerListLobbiesResponse { + regions: vec![region], + game_modes, + lobbies, + }) +} + // TODO: Copied to api-identity fn build_port( run: &backend::job::Run, diff --git a/svc/api/matchmaker/src/route/mod.rs b/svc/api/matchmaker/src/route/mod.rs index 3949d9f8aa..0584d06505 100644 --- a/svc/api/matchmaker/src/route/mod.rs +++ b/svc/api/matchmaker/src/route/mod.rs @@ -61,8 +61,20 @@ define_router! { }, ), }, + "lobbies" / "create": { + POST: lobbies::create( + body: rivet_api::models::MatchmakerLobbiesCreateRequest, + opt_auth: true, + rate_limit: { + key: "lobby-create", + buckets: [ + { count: 3 }, + ], + }, + ), + }, "lobbies" / "closed": { - PUT: lobbies::closed( + PUT: lobbies::set_closed( body: rivet_api::models::MatchmakerLobbiesSetClosedRequest, rate_limit: { buckets: [ @@ -71,9 +83,23 @@ define_router! { }, ), }, + "lobbies" / "state": { + PUT: lobbies::set_state( + body_as_bytes: true, + rate_limit: { + buckets: [ + { count: 1024 }, + ], + }, + ), + }, + "lobbies" / Uuid / "state": { + GET: lobbies::get_state(), + }, "lobbies" / "list": { GET: lobbies::list( opt_auth: true, + query: lobbies::ListQuery, rate_limit: { key: "lobby-list", buckets: [ diff --git a/svc/api/matchmaker/tests/basic.rs b/svc/api/matchmaker/tests/basic.rs index 3937db13b5..e8f696e16d 100644 --- a/svc/api/matchmaker/tests/basic.rs +++ b/svc/api/matchmaker/tests/basic.rs @@ -1,9 +1,13 @@ use std::{collections::HashSet, str::FromStr, sync::Once}; use proto::backend::{self, pkg::*}; -use rivet_api::apis::{configuration::Configuration, *}; +use rivet_api::{ + apis::{configuration::Configuration, *}, + models, +}; use rivet_matchmaker::model; use rivet_operation::prelude::*; +use serde_json::json; const LOBBY_GROUP_NAME_ID_BRIDGE: &str = "test-bridge"; const LOBBY_GROUP_NAME_ID_HOST: &str = "test-host"; @@ -108,7 +112,8 @@ impl Ctx { fn config(&self, bearer_token: String) -> Configuration { Configuration { - base_path: util::env::svc_router_url("api-matchmaker"), + base_path: format!("https://matchmaker.api.{}/v1", util::env::domain_main()), + // base_path: util::env::svc_router_url("api-matchmaker"), bearer_access_token: Some(bearer_token), ..Default::default() } @@ -170,11 +175,18 @@ impl Ctx { regions: vec![backend::matchmaker::lobby_group::Region { region_id: Some(region_id.into()), tier_name_id: "basic-1d8".into(), - idle_lobbies: None, + idle_lobbies: Some(backend::matchmaker::lobby_group::IdleLobbies { + min_idle_lobbies: 0, + // Set a high max lobby count in case this is + // coming from a test that test mm-lobby-create + // without creating an associated player + max_idle_lobbies: 32, + }), }], max_players_normal: 8, max_players_direct: 10, max_players_party: 12, + listable: true, runtime: Some(backend::matchmaker::lobby_runtime::Docker { build_id: build_res.build_id, @@ -226,6 +238,17 @@ impl Ctx { }, ], }.into()), + + find_config: None, + join_config: None, + create_config: Some(backend::matchmaker::CreateConfig { + identity_requirement: backend::matchmaker::IdentityRequirement::None as i32, + verification_config: None, + + enable_public: true, + enable_private: true, + max_lobbies_per_identity: Some(1), + }), }, backend::matchmaker::LobbyGroup { name_id: LOBBY_GROUP_NAME_ID_HOST.into(), @@ -238,6 +261,7 @@ impl Ctx { max_players_normal: 8, max_players_direct: 10, max_players_party: 12, + listable: true, runtime: Some(backend::matchmaker::lobby_runtime::Docker { build_id: build_res.build_id, @@ -288,6 +312,10 @@ impl Ctx { }, ], }.into()), + + find_config: None, + join_config: None, + create_config: None, }, ], }), @@ -401,7 +429,7 @@ async fn find_with_regions() { .await .unwrap(); - assert_lobby_state(&ctx, res.lobby().unwrap()).await; + assert_lobby_state_smithy(&ctx, res.lobby().unwrap()).await; } } @@ -424,7 +452,37 @@ async fn find_without_regions() { .await .unwrap(); - assert_lobby_state(&ctx, res.lobby().unwrap()).await; + assert_lobby_state_smithy(&ctx, res.lobby().unwrap()).await; + } +} + +#[tokio::test(flavor = "multi_thread")] +async fn create_custom_lobby() { + let ctx = Ctx::init().await; + + { + tracing::info!("creating custom lobby"); + + let res = matchmaker_lobbies_api::matchmaker_lobbies_create( + &ctx.config(ctx.ns_auth_token.clone()), + models::MatchmakerLobbiesCreateRequest { + game_mode: LOBBY_GROUP_NAME_ID_BRIDGE.to_string(), + region: Some(ctx.primary_region_name_id.clone()), + publicity: models::MatchmakerCustomLobbyPublicity::Public, + lobby_config: Some(Some(json!({ "foo": "bar" }))), + verification_data: None, + captcha: Some(Box::new(models::CaptchaConfig { + hcaptcha: Some(Box::new(models::CaptchaConfigHcaptcha { + client_response: "10000000-aaaa-bbbb-cccc-000000000001".to_string(), + })), + turnstile: None, + })), + }, + ) + .await + .unwrap(); + + assert_lobby_state(&ctx, &res.lobby).await; } } @@ -465,6 +523,7 @@ async fn list_lobbies() { query: Some(mm::msg::lobby_find::message::Query::Direct(backend::matchmaker::query::Direct { lobby_id: Some(lobby_id.into()), })), + ..Default::default() }) .await .unwrap().unwrap(); @@ -521,7 +580,7 @@ async fn lobby_lifecycle() { .await .unwrap(); let lobby = res.lobby().unwrap(); - assert_lobby_state(&ctx, lobby).await; + assert_lobby_state_smithy(&ctx, lobby).await; let lobby_token = ctx.lobby_token(lobby.lobby_id().unwrap()).await; @@ -554,7 +613,7 @@ async fn lobby_lifecycle() { .await .unwrap(); let lobby = res.lobby().unwrap(); - assert_lobby_state(&ctx, lobby).await; + assert_lobby_state_smithy(&ctx, lobby).await; let lobby_token = ctx.lobby_token(lobby.lobby_id().unwrap()).await; @@ -815,7 +874,7 @@ async fn find_domain_auth() { .send() .await .unwrap(); - assert_lobby_state(&ctx, res.lobby().unwrap()).await; + assert_lobby_state_smithy(&ctx, res.lobby().unwrap()).await; } // Custom domain @@ -832,7 +891,7 @@ async fn find_domain_auth() { .send() .await .unwrap(); - assert_lobby_state(&ctx, res.lobby().unwrap()).await; + assert_lobby_state_smithy(&ctx, res.lobby().unwrap()).await; } } @@ -852,7 +911,7 @@ async fn player_statistics() { tracing::info!(?player_count, ?game_modes); } -async fn assert_lobby_state( +async fn assert_lobby_state_smithy( ctx: &Ctx, lobby: &model::MatchmakerLobbyJoinInfo, ) -> backend::matchmaker::Lobby { @@ -869,29 +928,30 @@ async fn assert_lobby_state( // Validate ports { - tracing::info!(ports = ?lobby.ports().unwrap(), "validating ports"); - assert_eq!(6, lobby.ports().unwrap().len()); + let ports = lobby.ports().unwrap(); + tracing::info!(?ports, "validating ports"); + assert_eq!(6, ports.len()); { - let p = lobby.ports().unwrap().get("test-80-http").unwrap(); + let p = ports.get("test-80-http").unwrap(); assert_eq!(80, p.port().unwrap()); assert!(!p.is_tls().unwrap()); } { - let p = lobby.ports().unwrap().get("test-80-https").unwrap(); + let p = ports.get("test-80-https").unwrap(); assert_eq!(443, p.port().unwrap()); assert!(p.is_tls().unwrap()); } { - let p = lobby.ports().unwrap().get("test-5050-https").unwrap(); + let p = ports.get("test-5050-https").unwrap(); assert_eq!(443, p.port().unwrap()); assert!(p.is_tls().unwrap()); } { - let p = lobby.ports().unwrap().get("test-5051-tcp").unwrap(); + let p = ports.get("test-5051-tcp").unwrap(); assert!( p.port().unwrap() >= util_job::consts::MIN_INGRESS_PORT_TCP as i32 && p.port().unwrap() <= util_job::consts::MAX_INGRESS_PORT_TCP as i32 @@ -900,7 +960,7 @@ async fn assert_lobby_state( } { - let p = lobby.ports().unwrap().get("test-5051-tls").unwrap(); + let p = ports.get("test-5051-tls").unwrap(); assert!( p.port().unwrap() >= util_job::consts::MIN_INGRESS_PORT_TCP as i32 && p.port().unwrap() <= util_job::consts::MAX_INGRESS_PORT_TCP as i32 @@ -909,7 +969,7 @@ async fn assert_lobby_state( } { - let p = lobby.ports().unwrap().get("test-5052-udp").unwrap(); + let p = ports.get("test-5052-udp").unwrap(); assert!( p.port().unwrap() >= util_job::consts::MIN_INGRESS_PORT_UDP as i32 && p.port().unwrap() <= util_job::consts::MAX_INGRESS_PORT_UDP as i32 @@ -921,6 +981,76 @@ async fn assert_lobby_state( lobby_data.clone() } +async fn assert_lobby_state( + ctx: &Ctx, + lobby: &models::MatchmakerJoinLobby, +) -> backend::matchmaker::Lobby { + // Fetch lobby data + let lobby_res = op!([ctx] mm_lobby_get { + lobby_ids: vec![lobby.lobby_id.into()], + ..Default::default() + }) + .await + .unwrap(); + let lobby_data = lobby_res.lobbies.first().expect("lobby not created"); + assert!(lobby_data.ready_ts.is_some(), "lobby not ready"); + assert!(lobby_data.run_id.is_some(), "no run id"); + + // Validate ports + { + let ports = &lobby.ports; + tracing::info!(?ports, "validating ports"); + assert_eq!(6, ports.len()); + + { + let p = ports.get("test-80-http").unwrap(); + assert_eq!(80, p.port.unwrap()); + assert!(!p.is_tls); + } + + { + let p = ports.get("test-80-https").unwrap(); + assert_eq!(443, p.port.unwrap()); + assert!(p.is_tls); + } + + { + let p = ports.get("test-5050-https").unwrap(); + assert_eq!(443, p.port.unwrap()); + assert!(p.is_tls); + } + + { + let p = ports.get("test-5051-tcp").unwrap(); + assert!( + p.port.unwrap() >= util_job::consts::MIN_INGRESS_PORT_TCP as i32 + && p.port.unwrap() <= util_job::consts::MAX_INGRESS_PORT_TCP as i32 + ); + assert!(!p.is_tls); + } + + { + let p = ports.get("test-5051-tls").unwrap(); + assert!( + p.port.unwrap() >= util_job::consts::MIN_INGRESS_PORT_TCP as i32 + && p.port.unwrap() <= util_job::consts::MAX_INGRESS_PORT_TCP as i32 + ); + assert!(p.is_tls); + } + + { + let p = ports.get("test-5052-udp").unwrap(); + assert!( + p.port.unwrap() >= util_job::consts::MIN_INGRESS_PORT_UDP as i32 + && p.port.unwrap() <= util_job::consts::MAX_INGRESS_PORT_UDP as i32 + ); + assert!(!p.is_tls); + } + } + + lobby_data.clone() +} + fn captcha_config() -> model::CaptchaConfig { model::CaptchaConfig::Hcaptcha( model::captcha_config_hcaptcha::Builder::default() @@ -941,6 +1071,11 @@ async fn create_lobby( region_id: Some(ctx.primary_region_id.into()), create_ray_id: None, preemptively_created: false, + + creator_user_id: None, + is_custom: false, + publicity: None, + lobby_config_json: None, }) .await .unwrap(); diff --git a/svc/api/module/Cargo.toml b/svc/api/module/Cargo.toml index 613197bf4e..cb5006ff0e 100644 --- a/svc/api/module/Cargo.toml +++ b/svc/api/module/Cargo.toml @@ -26,7 +26,7 @@ rivet-pools = { path = "../../../lib/pools" } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" thiserror = "1.0" -tokio = { version = "1.21" } +tokio = { version = "1.29" } tracing = "0.1" tracing-subscriber = { version = "0.3", default-features = false, features = ["fmt", "json", "ansi"] } url = "2.2.2" diff --git a/svc/api/module/tests/basic.rs b/svc/api/module/tests/basic.rs index f9a33b1da4..600b0b9e6b 100644 --- a/svc/api/module/tests/basic.rs +++ b/svc/api/module/tests/basic.rs @@ -97,6 +97,7 @@ impl Ctx { region_id: Some(self.primary_region_id.into()), create_ray_id: None, preemptively_created: false, + ..Default::default() }) .await .unwrap(); @@ -250,6 +251,7 @@ impl Ctx { }, ], }.into()), + ..Default::default() }], }), ..Default::default() diff --git a/svc/api/portal/Cargo.toml b/svc/api/portal/Cargo.toml index 548f8b1888..000165a2e4 100644 --- a/svc/api/portal/Cargo.toml +++ b/svc/api/portal/Cargo.toml @@ -26,7 +26,7 @@ rivet-portal-server = { path = "../../../lib/smithy-output/api-portal/rust-serve serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" thiserror = "1.0" -tokio = { version = "1.21" } +tokio = { version = "1.29" } tracing = "0.1" tracing-subscriber = { version = "0.3", default-features = false, features = ["fmt", "json", "ansi"] } url = "2.2.2" diff --git a/svc/api/portal/src/build.rs b/svc/api/portal/src/build.rs index bca42cee26..627fcb5981 100644 --- a/svc/api/portal/src/build.rs +++ b/svc/api/portal/src/build.rs @@ -55,13 +55,7 @@ pub async fn group_summaries( group_id: team_id.to_string(), display_name: team_data.display_name.clone(), bio: team_data.bio.clone(), - avatar_url: util::route::team_avatar( - team_data - .profile_upload_id - .as_ref() - .map(common::Uuid::as_uuid), - team_data.profile_file_name.as_ref(), - ), + avatar_url: util::route::team_avatar(&team_data), external: models::GroupExternalLinks { profile: util::route::team_profile(team_id), chat: util::route::team_chat(team_id), diff --git a/svc/api/portal/src/convert.rs b/svc/api/portal/src/convert.rs index 19a13e0047..c3bf6f65af 100644 --- a/svc/api/portal/src/convert.rs +++ b/svc/api/portal/src/convert.rs @@ -10,16 +10,10 @@ pub fn game_summary( ) -> GlobalResult { Ok(models::GameSummary { game_id: internal_unwrap!(game.game_id).as_uuid().to_string(), - name_id: game.name_id, - display_name: game.display_name, - logo_url: util::route::game_logo( - game.logo_upload_id.as_ref().map(common::Uuid::as_uuid), - game.logo_file_name.as_ref(), - ), - banner_url: util::route::game_banner( - game.banner_upload_id.as_ref().map(common::Uuid::as_uuid), - game.banner_file_name.as_ref(), - ), + name_id: game.name_id.clone(), + display_name: game.display_name.clone(), + logo_url: util::route::game_logo(&game), + banner_url: util::route::game_banner(&game), url: game.url, developer: group_handle(team, true)?, @@ -36,10 +30,7 @@ pub fn group_handle( Ok(models::GroupHandle { group_id: team_id.to_string(), display_name: team.display_name.to_owned(), - avatar_url: util::route::team_avatar( - team.profile_upload_id.as_ref().map(common::Uuid::as_uuid), - team.profile_file_name.as_ref(), - ), + avatar_url: util::route::team_avatar(&team), external: models::GroupExternalLinks { profile: util::route::team_profile(team_id), chat: util::route::team_chat(team_id), diff --git a/svc/api/portal/src/route/games.rs b/svc/api/portal/src/route/games.rs index 03d4d14dd9..530f2e3ed3 100644 --- a/svc/api/portal/src/route/games.rs +++ b/svc/api/portal/src/route/games.rs @@ -41,14 +41,8 @@ pub async fn profile( game_id: game_id.to_string(), name_id: game.name_id.clone(), display_name: game.display_name.clone(), - logo_url: util::route::game_logo( - game.logo_upload_id.as_ref().map(common::Uuid::as_uuid), - game.logo_file_name.as_ref(), - ), - banner_url: util::route::game_banner( - game.banner_upload_id.as_ref().map(common::Uuid::as_uuid), - game.banner_file_name.as_ref(), - ), + logo_url: util::route::game_logo(&game), + banner_url: util::route::game_banner(&game), url: game.url.clone(), developer: developer_team.clone(), diff --git a/svc/api/route/Cargo.toml b/svc/api/route/Cargo.toml index de9453193a..7e5d209319 100644 --- a/svc/api/route/Cargo.toml +++ b/svc/api/route/Cargo.toml @@ -25,7 +25,7 @@ s3-util = { path = "../../../lib/s3-util" } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" thiserror = "1.0" -tokio = { version = "1.21" } +tokio = { version = "1.29" } toml = "0.5" tracing = "0.1" tracing-subscriber = { version = "0.3", default-features = false, features = ["fmt", "json", "ansi"] } diff --git a/svc/api/route/Service.toml b/svc/api/route/Service.toml index 65fdf5fcc2..3bc19aee52 100644 --- a/svc/api/route/Service.toml +++ b/svc/api/route/Service.toml @@ -12,3 +12,8 @@ subdomain = "route.api" [secrets] "rivet/api_route/token" = {} + +[databases] +redis-job = {} +redis-cdn = {} + diff --git a/svc/api/status/Cargo.toml b/svc/api/status/Cargo.toml index e936d1551f..c05ee0ae9c 100644 --- a/svc/api/status/Cargo.toml +++ b/svc/api/status/Cargo.toml @@ -30,7 +30,7 @@ s3-util = { path = "../../../lib/s3-util" } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" thiserror = "1.0" -tokio = { version = "1.21" } +tokio = { version = "1.29" } tracing = "0.1" tracing-subscriber = { version = "0.3", default-features = false, features = ["fmt", "json", "ansi"] } url = "2.2.2" diff --git a/svc/api/status/src/auth.rs b/svc/api/status/src/auth.rs index c3ceb470f0..43d7568e6b 100644 --- a/svc/api/status/src/auth.rs +++ b/svc/api/status/src/auth.rs @@ -14,7 +14,6 @@ impl ApiAuth for Auth { ) -> GlobalResult { Self::rate_limit(rate_limit_ctx).await?; - // TODO: Don't hardcode this // TODO: Use JWT if let Some(api_token) = api_token { assert_eq_with!( @@ -23,9 +22,10 @@ impl ApiAuth for Auth { API_FORBIDDEN, reason = "Invalid auth" ); + Ok(Auth { _claims: None }) + } else { + internal_panic!("unreachable"); } - - Ok(Auth { _claims: None }) } async fn rate_limit(_rate_limit_ctx: AuthRateLimitCtx<'_>) -> GlobalResult<()> { diff --git a/svc/pkg/analytics/worker/Service.toml b/svc/pkg/analytics/worker/Service.toml index 4b25b9a501..3c77681a65 100644 --- a/svc/pkg/analytics/worker/Service.toml +++ b/svc/pkg/analytics/worker/Service.toml @@ -8,3 +8,6 @@ kind = "rust" [secrets] "clickhouse/users/chirp/password" = {} + +[databases] +db-analytics = {} diff --git a/svc/pkg/analytics/worker/src/workers/event_create.rs b/svc/pkg/analytics/worker/src/workers/event_create.rs index 74fa851eb7..ef11824531 100644 --- a/svc/pkg/analytics/worker/src/workers/event_create.rs +++ b/svc/pkg/analytics/worker/src/workers/event_create.rs @@ -15,7 +15,7 @@ struct Event { } #[worker(name = "analytics-event-create")] -async fn worker(ctx: OperationContext) -> GlobalResult<()> { +async fn worker(ctx: &OperationContext) -> GlobalResult<()> { let ray_id = ctx.ray_id(); let client = clickhouse::Client::default() diff --git a/svc/pkg/build/ops/create/Cargo.toml b/svc/pkg/build/ops/create/Cargo.toml index fbe7d31a5c..dd4c68f86b 100644 --- a/svc/pkg/build/ops/create/Cargo.toml +++ b/svc/pkg/build/ops/create/Cargo.toml @@ -14,7 +14,7 @@ game-get = { path = "../../../game/ops/get" } upload-prepare = { path = "../../../upload/ops/prepare" } [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/build/ops/create/Service.toml b/svc/pkg/build/ops/create/Service.toml index 78d3120655..7613d40be5 100644 --- a/svc/pkg/build/ops/create/Service.toml +++ b/svc/pkg/build/ops/create/Service.toml @@ -5,3 +5,6 @@ name = "build-create" kind = "rust" [operation] + +[databases] +db-build = {} diff --git a/svc/pkg/build/ops/create/src/lib.rs b/svc/pkg/build/ops/create/src/lib.rs index d2422e08fc..180548d67a 100644 --- a/svc/pkg/build/ops/create/src/lib.rs +++ b/svc/pkg/build/ops/create/src/lib.rs @@ -72,7 +72,7 @@ async fn handle( path: "image.tar".into(), mime: Some("application/x-tar".into()), content_length: image_file.content_length, - multipart: true, + multipart: ctx.multipart, ..Default::default() }, ], diff --git a/svc/pkg/build/ops/get/Cargo.toml b/svc/pkg/build/ops/get/Cargo.toml index 3fbdce1fea..8597e7384e 100644 --- a/svc/pkg/build/ops/get/Cargo.toml +++ b/svc/pkg/build/ops/get/Cargo.toml @@ -11,7 +11,7 @@ chirp-client = { path = "../../../../../lib/chirp/client" } prost = "0.10" [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/build/ops/get/Service.toml b/svc/pkg/build/ops/get/Service.toml index b6ed83d359..f38353ab6d 100644 --- a/svc/pkg/build/ops/get/Service.toml +++ b/svc/pkg/build/ops/get/Service.toml @@ -5,3 +5,6 @@ name = "build-get" kind = "rust" [operation] + +[databases] +db-build = {} diff --git a/svc/pkg/build/ops/list-for-game/Cargo.toml b/svc/pkg/build/ops/list-for-game/Cargo.toml index 3e8ec2ad1f..671466daad 100644 --- a/svc/pkg/build/ops/list-for-game/Cargo.toml +++ b/svc/pkg/build/ops/list-for-game/Cargo.toml @@ -11,7 +11,7 @@ chirp-client = { path = "../../../../../lib/chirp/client" } prost = "0.10" [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/build/ops/list-for-game/Service.toml b/svc/pkg/build/ops/list-for-game/Service.toml index 531d4154c7..e88fc3a723 100644 --- a/svc/pkg/build/ops/list-for-game/Service.toml +++ b/svc/pkg/build/ops/list-for-game/Service.toml @@ -5,3 +5,6 @@ name = "build-list-for-game" kind = "rust" [operation] + +[databases] +db-build = {} diff --git a/svc/pkg/build/standalone/default-create/Cargo.toml b/svc/pkg/build/standalone/default-create/Cargo.toml index 86ef376ed3..8e8a55d70d 100644 --- a/svc/pkg/build/standalone/default-create/Cargo.toml +++ b/svc/pkg/build/standalone/default-create/Cargo.toml @@ -14,7 +14,7 @@ prost = "0.10" rivet-connection = { path = "../../../../../lib/connection" } reqwest = "0.11" rivet-pools = { path = "../../../../../lib/pools" } -tokio = { version = "1.21", features = ["full"] } +tokio = { version = "1.29", features = ["full"] } tracing = "0.1" tracing-subscriber = { version = "0.3", default-features = false, features = ["fmt", "json", "ansi"] } uuid = { version = "1", features = ["v4"] } @@ -23,14 +23,13 @@ upload-complete = { path = "../../../upload/ops/complete" } upload-prepare = { path = "../../../upload/ops/prepare" } [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false features = [ - "runtime-tokio-native-tls", + "runtime-tokio", "postgres", "uuid", "json", - "tls", ] [dev-dependencies] diff --git a/svc/pkg/build/types/create.proto b/svc/pkg/build/types/create.proto index a186324dac..3ac96e19e3 100644 --- a/svc/pkg/build/types/create.proto +++ b/svc/pkg/build/types/create.proto @@ -10,6 +10,7 @@ message Request { string display_name = 2; optional string image_tag = 4; optional rivet.backend.upload.PrepareFile image_file = 3; + bool multipart = 6; // If provided, will look up the pre-uploaded upload ID for a given kind. optional string default_build_kind = 5; diff --git a/svc/pkg/captcha/ops/request/Cargo.toml b/svc/pkg/captcha/ops/request/Cargo.toml index dc4fdd8346..3c028a13ae 100644 --- a/svc/pkg/captcha/ops/request/Cargo.toml +++ b/svc/pkg/captcha/ops/request/Cargo.toml @@ -13,7 +13,7 @@ chrono = "0.4" util-captcha = { package = "rivet-util-captcha", path = "../../util" } [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/captcha/ops/request/Service.toml b/svc/pkg/captcha/ops/request/Service.toml index dbcd8c472d..150d722f42 100644 --- a/svc/pkg/captcha/ops/request/Service.toml +++ b/svc/pkg/captcha/ops/request/Service.toml @@ -5,3 +5,6 @@ name = "captcha-request" kind = "rust" [operation] + +[databases] +db-captcha = {} diff --git a/svc/pkg/captcha/ops/request/src/lib.rs b/svc/pkg/captcha/ops/request/src/lib.rs index faae8a5413..c3a44c9ef3 100644 --- a/svc/pkg/captcha/ops/request/src/lib.rs +++ b/svc/pkg/captcha/ops/request/src/lib.rs @@ -37,7 +37,12 @@ async fn handle( let needs_verification = if let Some((success_complete_ts,)) = success_res { let duration_since_verification = ctx.ts() - success_complete_ts; if duration_since_verification >= captcha_config.verification_ttl { - tracing::info!(?duration_since_verification, verification_ttl = ?captcha_config.verification_ttl, "been too long since last verification"); + tracing::info!( + ?duration_since_verification, + verification_ttl = ?captcha_config.verification_ttl, + "been too long since last verification" + ); + true } else { // Fetch requests since the last success. Include limit since we diff --git a/svc/pkg/captcha/ops/verify/Service.toml b/svc/pkg/captcha/ops/verify/Service.toml index ea9c8b040c..4934847fa8 100644 --- a/svc/pkg/captcha/ops/verify/Service.toml +++ b/svc/pkg/captcha/ops/verify/Service.toml @@ -8,3 +8,6 @@ kind = "rust" [secrets] "turnstile/rivet_game/secret_key" = { optional = true } + +[databases] +db-captcha = {} diff --git a/svc/pkg/cdn/ops/namespace-auth-user-remove/Cargo.toml b/svc/pkg/cdn/ops/namespace-auth-user-remove/Cargo.toml index 8af25eb0f8..f21760268f 100644 --- a/svc/pkg/cdn/ops/namespace-auth-user-remove/Cargo.toml +++ b/svc/pkg/cdn/ops/namespace-auth-user-remove/Cargo.toml @@ -11,7 +11,7 @@ chirp-client = { path = "../../../../../lib/chirp/client" } prost = "0.10" [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/cdn/ops/namespace-auth-user-remove/Service.toml b/svc/pkg/cdn/ops/namespace-auth-user-remove/Service.toml index 55f1330b37..1c284e4fea 100644 --- a/svc/pkg/cdn/ops/namespace-auth-user-remove/Service.toml +++ b/svc/pkg/cdn/ops/namespace-auth-user-remove/Service.toml @@ -5,3 +5,6 @@ name = "cdn-namespace-auth-user-remove" kind = "rust" [operation] + +[databases] +db-cdn = {} diff --git a/svc/pkg/cdn/ops/namespace-auth-user-update/Cargo.toml b/svc/pkg/cdn/ops/namespace-auth-user-update/Cargo.toml index 6defc8026e..cf89c5ca25 100644 --- a/svc/pkg/cdn/ops/namespace-auth-user-update/Cargo.toml +++ b/svc/pkg/cdn/ops/namespace-auth-user-update/Cargo.toml @@ -11,7 +11,7 @@ chirp-client = { path = "../../../../../lib/chirp/client" } prost = "0.10" [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/cdn/ops/namespace-auth-user-update/Service.toml b/svc/pkg/cdn/ops/namespace-auth-user-update/Service.toml index 8398831715..6c953ded75 100644 --- a/svc/pkg/cdn/ops/namespace-auth-user-update/Service.toml +++ b/svc/pkg/cdn/ops/namespace-auth-user-update/Service.toml @@ -5,3 +5,6 @@ name = "cdn-namespace-auth-user-update" kind = "rust" [operation] + +[databases] +db-cdn = {} diff --git a/svc/pkg/cdn/ops/namespace-create/Cargo.toml b/svc/pkg/cdn/ops/namespace-create/Cargo.toml index a95e157fdc..a5414d3cc6 100644 --- a/svc/pkg/cdn/ops/namespace-create/Cargo.toml +++ b/svc/pkg/cdn/ops/namespace-create/Cargo.toml @@ -11,7 +11,7 @@ chirp-client = { path = "../../../../../lib/chirp/client" } prost = "0.10" [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/cdn/ops/namespace-domain-create/Cargo.toml b/svc/pkg/cdn/ops/namespace-domain-create/Cargo.toml index 48d1ae2534..6a88d323d3 100644 --- a/svc/pkg/cdn/ops/namespace-domain-create/Cargo.toml +++ b/svc/pkg/cdn/ops/namespace-domain-create/Cargo.toml @@ -14,7 +14,7 @@ game-get = { path = "../../../game/ops/get" } game-resolve-namespace-id = { path = "../../../game/ops/resolve-namespace-id" } [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/cdn/ops/namespace-domain-create/Service.toml b/svc/pkg/cdn/ops/namespace-domain-create/Service.toml index e8408d3882..539ad774aa 100644 --- a/svc/pkg/cdn/ops/namespace-domain-create/Service.toml +++ b/svc/pkg/cdn/ops/namespace-domain-create/Service.toml @@ -5,3 +5,6 @@ name = "cdn-namespace-domain-create" kind = "rust" [operation] + +[databases] +db-cdn = {} diff --git a/svc/pkg/cdn/ops/namespace-domain-remove/Cargo.toml b/svc/pkg/cdn/ops/namespace-domain-remove/Cargo.toml index cb9cf7f996..73c2b52ea1 100644 --- a/svc/pkg/cdn/ops/namespace-domain-remove/Cargo.toml +++ b/svc/pkg/cdn/ops/namespace-domain-remove/Cargo.toml @@ -14,7 +14,7 @@ game-get = { path = "../../../game/ops/get" } game-resolve-namespace-id = { path = "../../../game/ops/resolve-namespace-id" } [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/cdn/ops/namespace-domain-remove/Service.toml b/svc/pkg/cdn/ops/namespace-domain-remove/Service.toml index a072431f26..ede383ee1f 100644 --- a/svc/pkg/cdn/ops/namespace-domain-remove/Service.toml +++ b/svc/pkg/cdn/ops/namespace-domain-remove/Service.toml @@ -5,3 +5,6 @@ name = "cdn-namespace-domain-remove" kind = "rust" [operation] + +[databases] +db-cdn = {} diff --git a/svc/pkg/cdn/ops/namespace-get/Cargo.toml b/svc/pkg/cdn/ops/namespace-get/Cargo.toml index b5bb186bfa..9bd9b8eefb 100644 --- a/svc/pkg/cdn/ops/namespace-get/Cargo.toml +++ b/svc/pkg/cdn/ops/namespace-get/Cargo.toml @@ -11,7 +11,7 @@ chirp-client = { path = "../../../../../lib/chirp/client" } prost = "0.10" [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/cdn/ops/namespace-get/Service.toml b/svc/pkg/cdn/ops/namespace-get/Service.toml index bb940f6adb..24c2de8a52 100644 --- a/svc/pkg/cdn/ops/namespace-get/Service.toml +++ b/svc/pkg/cdn/ops/namespace-get/Service.toml @@ -5,3 +5,6 @@ name = "cdn-namespace-get" kind = "rust" [operation] + +[databases] +db-cdn = {} diff --git a/svc/pkg/cdn/ops/namespace-resolve-domain/Cargo.toml b/svc/pkg/cdn/ops/namespace-resolve-domain/Cargo.toml index 0708028a9b..9777553afd 100644 --- a/svc/pkg/cdn/ops/namespace-resolve-domain/Cargo.toml +++ b/svc/pkg/cdn/ops/namespace-resolve-domain/Cargo.toml @@ -11,7 +11,7 @@ chirp-client = { path = "../../../../../lib/chirp/client" } prost = "0.10" [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/cdn/ops/ns-auth-type-set/Cargo.toml b/svc/pkg/cdn/ops/ns-auth-type-set/Cargo.toml index 99577b1d5a..64374820ab 100644 --- a/svc/pkg/cdn/ops/ns-auth-type-set/Cargo.toml +++ b/svc/pkg/cdn/ops/ns-auth-type-set/Cargo.toml @@ -11,7 +11,7 @@ chirp-client = { path = "../../../../../lib/chirp/client" } prost = "0.10" [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/cdn/ops/ns-auth-type-set/Service.toml b/svc/pkg/cdn/ops/ns-auth-type-set/Service.toml index 5eb2334848..dc3a17e933 100644 --- a/svc/pkg/cdn/ops/ns-auth-type-set/Service.toml +++ b/svc/pkg/cdn/ops/ns-auth-type-set/Service.toml @@ -5,3 +5,6 @@ name = "cdn-ns-auth-type-set" kind = "rust" [operation] + +[databases] +db-cdn = {} diff --git a/svc/pkg/cdn/ops/ns-enable-domain-public-auth-set/Cargo.toml b/svc/pkg/cdn/ops/ns-enable-domain-public-auth-set/Cargo.toml index af4ae6edce..cf30bce172 100644 --- a/svc/pkg/cdn/ops/ns-enable-domain-public-auth-set/Cargo.toml +++ b/svc/pkg/cdn/ops/ns-enable-domain-public-auth-set/Cargo.toml @@ -11,7 +11,7 @@ chirp-client = { path = "../../../../../lib/chirp/client" } prost = "0.10" [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/cdn/ops/ns-enable-domain-public-auth-set/Service.toml b/svc/pkg/cdn/ops/ns-enable-domain-public-auth-set/Service.toml index 5a8b6e82a5..549429565c 100644 --- a/svc/pkg/cdn/ops/ns-enable-domain-public-auth-set/Service.toml +++ b/svc/pkg/cdn/ops/ns-enable-domain-public-auth-set/Service.toml @@ -5,3 +5,6 @@ name = "cdn-ns-enable-domain-public-auth-set" kind = "rust" [operation] + +[databases] +db-cdn = {} diff --git a/svc/pkg/cdn/ops/site-create/Cargo.toml b/svc/pkg/cdn/ops/site-create/Cargo.toml index deced8872b..70c503f842 100644 --- a/svc/pkg/cdn/ops/site-create/Cargo.toml +++ b/svc/pkg/cdn/ops/site-create/Cargo.toml @@ -14,7 +14,7 @@ game-get = { path = "../../../game/ops/get" } upload-prepare = { path = "../../../upload/ops/prepare" } [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/cdn/ops/site-create/Service.toml b/svc/pkg/cdn/ops/site-create/Service.toml index 865c4c2ddc..952eaba1e9 100644 --- a/svc/pkg/cdn/ops/site-create/Service.toml +++ b/svc/pkg/cdn/ops/site-create/Service.toml @@ -5,3 +5,6 @@ name = "cdn-site-create" kind = "rust" [operation] + +[databases] +db-cdn = {} diff --git a/svc/pkg/cdn/ops/site-get/Cargo.toml b/svc/pkg/cdn/ops/site-get/Cargo.toml index 1e741f055f..32d72113a1 100644 --- a/svc/pkg/cdn/ops/site-get/Cargo.toml +++ b/svc/pkg/cdn/ops/site-get/Cargo.toml @@ -11,7 +11,7 @@ chirp-client = { path = "../../../../../lib/chirp/client" } prost = "0.10" [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/cdn/ops/site-get/Service.toml b/svc/pkg/cdn/ops/site-get/Service.toml index 8348eb1692..626670bdc3 100644 --- a/svc/pkg/cdn/ops/site-get/Service.toml +++ b/svc/pkg/cdn/ops/site-get/Service.toml @@ -5,3 +5,6 @@ name = "cdn-site-get" kind = "rust" [operation] + +[databases] +db-cdn = {} diff --git a/svc/pkg/cdn/ops/site-list-for-game/Cargo.toml b/svc/pkg/cdn/ops/site-list-for-game/Cargo.toml index c191f605cb..dbd26586ee 100644 --- a/svc/pkg/cdn/ops/site-list-for-game/Cargo.toml +++ b/svc/pkg/cdn/ops/site-list-for-game/Cargo.toml @@ -11,7 +11,7 @@ chirp-client = { path = "../../../../../lib/chirp/client" } prost = "0.10" [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/cdn/ops/site-list-for-game/Service.toml b/svc/pkg/cdn/ops/site-list-for-game/Service.toml index 639492995c..4682155fb3 100644 --- a/svc/pkg/cdn/ops/site-list-for-game/Service.toml +++ b/svc/pkg/cdn/ops/site-list-for-game/Service.toml @@ -5,3 +5,6 @@ name = "cdn-site-list-for-game" kind = "rust" [operation] + +[databases] +db-cdn = {} diff --git a/svc/pkg/cdn/ops/version-get/Cargo.toml b/svc/pkg/cdn/ops/version-get/Cargo.toml index 5aea2f4077..ed7e13849e 100644 --- a/svc/pkg/cdn/ops/version-get/Cargo.toml +++ b/svc/pkg/cdn/ops/version-get/Cargo.toml @@ -11,7 +11,7 @@ chirp-client = { path = "../../../../../lib/chirp/client" } prost = "0.10" [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/cdn/ops/version-get/Service.toml b/svc/pkg/cdn/ops/version-get/Service.toml index 45c678fc3f..9ea882d2e9 100644 --- a/svc/pkg/cdn/ops/version-get/Service.toml +++ b/svc/pkg/cdn/ops/version-get/Service.toml @@ -5,3 +5,6 @@ name = "cdn-version-get" kind = "rust" [operation] + +[databases] +db-cdn = {} diff --git a/svc/pkg/cdn/ops/version-publish/Cargo.toml b/svc/pkg/cdn/ops/version-publish/Cargo.toml index 827bee0f84..70535c0673 100644 --- a/svc/pkg/cdn/ops/version-publish/Cargo.toml +++ b/svc/pkg/cdn/ops/version-publish/Cargo.toml @@ -13,7 +13,7 @@ unzip-n = "0.1.2" itertools = "0.10.5" [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/cdn/ops/version-publish/Service.toml b/svc/pkg/cdn/ops/version-publish/Service.toml index 5850d9f538..357dc8812f 100644 --- a/svc/pkg/cdn/ops/version-publish/Service.toml +++ b/svc/pkg/cdn/ops/version-publish/Service.toml @@ -5,3 +5,6 @@ name = "cdn-version-publish" kind = "rust" [operation] + +[databases] +db-cdn = {} diff --git a/svc/pkg/cdn/worker/Service.toml b/svc/pkg/cdn/worker/Service.toml index 1e51ad7bd7..6cd999b24d 100644 --- a/svc/pkg/cdn/worker/Service.toml +++ b/svc/pkg/cdn/worker/Service.toml @@ -5,3 +5,7 @@ name = "cdn-worker" kind = "rust" [consumer] + +[databases] +redis-cdn = {} + diff --git a/svc/pkg/cdn/worker/src/workers/ns_config_populate.rs b/svc/pkg/cdn/worker/src/workers/ns_config_populate.rs index c54035c1da..9fa0e9c54e 100644 --- a/svc/pkg/cdn/worker/src/workers/ns_config_populate.rs +++ b/svc/pkg/cdn/worker/src/workers/ns_config_populate.rs @@ -3,7 +3,7 @@ use proto::backend::{self, pkg::*}; use redis::AsyncCommands; #[worker(name = "cdn-ns-config-populate")] -async fn worker(ctx: OperationContext) -> GlobalResult<()> { +async fn worker(ctx: &OperationContext) -> GlobalResult<()> { let namespace_id = internal_unwrap_owned!(ctx.namespace_id).as_uuid(); if let Some((game, ns, cdn_ns_config, cdn_version)) = get_cdn_version(ctx, namespace_id).await? diff --git a/svc/pkg/cf-custom-hostname/ops/get/Cargo.toml b/svc/pkg/cf-custom-hostname/ops/get/Cargo.toml index 5a1bfdd049..186288f1ff 100644 --- a/svc/pkg/cf-custom-hostname/ops/get/Cargo.toml +++ b/svc/pkg/cf-custom-hostname/ops/get/Cargo.toml @@ -11,7 +11,7 @@ chirp-client = { path = "../../../../../lib/chirp/client" } prost = "0.10" [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/cf-custom-hostname/ops/get/Service.toml b/svc/pkg/cf-custom-hostname/ops/get/Service.toml index a8f09e148c..1711d11f9c 100644 --- a/svc/pkg/cf-custom-hostname/ops/get/Service.toml +++ b/svc/pkg/cf-custom-hostname/ops/get/Service.toml @@ -5,3 +5,6 @@ name = "cf-custom-hostname-get" kind = "rust" [operation] + +[databases] +db-cf-custom-hostname = {} diff --git a/svc/pkg/cf-custom-hostname/ops/list-for-namespace-id/Cargo.toml b/svc/pkg/cf-custom-hostname/ops/list-for-namespace-id/Cargo.toml index 829ab4e10d..a41c3f82a1 100644 --- a/svc/pkg/cf-custom-hostname/ops/list-for-namespace-id/Cargo.toml +++ b/svc/pkg/cf-custom-hostname/ops/list-for-namespace-id/Cargo.toml @@ -11,7 +11,7 @@ chirp-client = { path = "../../../../../lib/chirp/client" } prost = "0.10" [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/cf-custom-hostname/ops/list-for-namespace-id/Service.toml b/svc/pkg/cf-custom-hostname/ops/list-for-namespace-id/Service.toml index b819108e71..80a66f15e3 100644 --- a/svc/pkg/cf-custom-hostname/ops/list-for-namespace-id/Service.toml +++ b/svc/pkg/cf-custom-hostname/ops/list-for-namespace-id/Service.toml @@ -5,3 +5,6 @@ name = "cf-custom-hostname-list-for-namespace-id" kind = "rust" [operation] + +[databases] +db-cf-custom-hostname = {} diff --git a/svc/pkg/cf-custom-hostname/ops/resolve-hostname/Cargo.toml b/svc/pkg/cf-custom-hostname/ops/resolve-hostname/Cargo.toml index a355f6a8d9..f7f7ef8f28 100644 --- a/svc/pkg/cf-custom-hostname/ops/resolve-hostname/Cargo.toml +++ b/svc/pkg/cf-custom-hostname/ops/resolve-hostname/Cargo.toml @@ -11,7 +11,7 @@ chirp-client = { path = "../../../../../lib/chirp/client" } prost = "0.10" [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/cf-custom-hostname/ops/resolve-hostname/Service.toml b/svc/pkg/cf-custom-hostname/ops/resolve-hostname/Service.toml index 1ca76e2c8e..c2153212d1 100644 --- a/svc/pkg/cf-custom-hostname/ops/resolve-hostname/Service.toml +++ b/svc/pkg/cf-custom-hostname/ops/resolve-hostname/Service.toml @@ -5,3 +5,6 @@ name = "cf-custom-hostname-resolve-hostname" kind = "rust" [operation] + +[databases] +db-cf-custom-hostname = {} diff --git a/svc/pkg/cf-custom-hostname/worker/Service.toml b/svc/pkg/cf-custom-hostname/worker/Service.toml index c6101d381b..4b2ef37949 100644 --- a/svc/pkg/cf-custom-hostname/worker/Service.toml +++ b/svc/pkg/cf-custom-hostname/worker/Service.toml @@ -6,3 +6,5 @@ kind = "rust" [consumer] +[databases] +db-cf-custom-hostname = {} diff --git a/svc/pkg/cf-custom-hostname/worker/src/workers/create.rs b/svc/pkg/cf-custom-hostname/worker/src/workers/create.rs index 656413b909..70da032d3d 100644 --- a/svc/pkg/cf-custom-hostname/worker/src/workers/create.rs +++ b/svc/pkg/cf-custom-hostname/worker/src/workers/create.rs @@ -51,7 +51,7 @@ async fn fail( #[worker(name = "cf-custom-hostname-create")] async fn worker( - ctx: OperationContext, + ctx: &OperationContext, ) -> GlobalResult<()> { let namespace_id = internal_unwrap!(ctx.namespace_id).as_uuid(); diff --git a/svc/pkg/cf-custom-hostname/worker/src/workers/delete.rs b/svc/pkg/cf-custom-hostname/worker/src/workers/delete.rs index ad452abbe3..3bd35eb583 100644 --- a/svc/pkg/cf-custom-hostname/worker/src/workers/delete.rs +++ b/svc/pkg/cf-custom-hostname/worker/src/workers/delete.rs @@ -15,7 +15,7 @@ struct CloudflareErrorEntry { #[worker(name = "cf-custom-hostname-delete")] async fn worker( - ctx: OperationContext, + ctx: &OperationContext, ) -> GlobalResult<()> { let namespace_id = internal_unwrap!(ctx.namespace_id).as_uuid(); let crdb = ctx.crdb("db-cf-custom-hostname").await?; diff --git a/svc/pkg/cf-custom-hostname/worker/src/workers/status_set.rs b/svc/pkg/cf-custom-hostname/worker/src/workers/status_set.rs index e64fe8583a..d57b723fee 100644 --- a/svc/pkg/cf-custom-hostname/worker/src/workers/status_set.rs +++ b/svc/pkg/cf-custom-hostname/worker/src/workers/status_set.rs @@ -3,7 +3,7 @@ use proto::backend::{self, pkg::*}; #[worker(name = "cf-custom-hostname-status-set")] async fn worker( - ctx: OperationContext, + ctx: &OperationContext, ) -> GlobalResult<()> { let identifier = internal_unwrap!(ctx.identifier).as_uuid(); diff --git a/svc/pkg/chat-message/ops/get/Cargo.toml b/svc/pkg/chat-message/ops/get/Cargo.toml index 2e07aea2ad..d1aefa9c6f 100644 --- a/svc/pkg/chat-message/ops/get/Cargo.toml +++ b/svc/pkg/chat-message/ops/get/Cargo.toml @@ -12,7 +12,7 @@ chrono = "0.4" prost = "0.10" [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/chat-message/ops/get/Service.toml b/svc/pkg/chat-message/ops/get/Service.toml index 74ec508b18..df8787c87d 100644 --- a/svc/pkg/chat-message/ops/get/Service.toml +++ b/svc/pkg/chat-message/ops/get/Service.toml @@ -5,3 +5,6 @@ name = "chat-message-get" kind = "rust" [operation] + +[databases] +db-chat = {} diff --git a/svc/pkg/chat-message/ops/list-for-user/Cargo.toml b/svc/pkg/chat-message/ops/list-for-user/Cargo.toml index 61e9bcbdd3..e3f6bbfa72 100644 --- a/svc/pkg/chat-message/ops/list-for-user/Cargo.toml +++ b/svc/pkg/chat-message/ops/list-for-user/Cargo.toml @@ -12,7 +12,7 @@ chrono = "0.4" prost = "0.10" [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/chat-message/ops/list-for-user/Service.toml b/svc/pkg/chat-message/ops/list-for-user/Service.toml index bbdd89cdfb..f188b5b0a1 100644 --- a/svc/pkg/chat-message/ops/list-for-user/Service.toml +++ b/svc/pkg/chat-message/ops/list-for-user/Service.toml @@ -5,3 +5,6 @@ name = "chat-message-list-for-user" kind = "rust" [operation] + +[databases] +db-chat = {} diff --git a/svc/pkg/chat-message/ops/list/Cargo.toml b/svc/pkg/chat-message/ops/list/Cargo.toml index 9f0d52395e..4fe04e50f1 100644 --- a/svc/pkg/chat-message/ops/list/Cargo.toml +++ b/svc/pkg/chat-message/ops/list/Cargo.toml @@ -12,7 +12,7 @@ chrono = "0.4" prost = "0.10" [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/chat-message/ops/list/Service.toml b/svc/pkg/chat-message/ops/list/Service.toml index 647166db58..73beaf7b62 100644 --- a/svc/pkg/chat-message/ops/list/Service.toml +++ b/svc/pkg/chat-message/ops/list/Service.toml @@ -5,3 +5,6 @@ name = "chat-message-list" kind = "rust" [operation] + +[databases] +db-chat = {} diff --git a/svc/pkg/chat-message/worker/Service.toml b/svc/pkg/chat-message/worker/Service.toml index 72b4702bce..e2909ff291 100644 --- a/svc/pkg/chat-message/worker/Service.toml +++ b/svc/pkg/chat-message/worker/Service.toml @@ -6,3 +6,5 @@ kind = "rust" [consumer] +[databases] +db-chat = {} diff --git a/svc/pkg/chat-message/worker/src/workers/create.rs b/svc/pkg/chat-message/worker/src/workers/create.rs index f5e2352189..497cd2207c 100644 --- a/svc/pkg/chat-message/worker/src/workers/create.rs +++ b/svc/pkg/chat-message/worker/src/workers/create.rs @@ -7,7 +7,7 @@ lazy_static::lazy_static! { } #[worker(name = "chat-message-create")] -async fn worker(ctx: OperationContext) -> GlobalResult<()> { +async fn worker(ctx: &OperationContext) -> GlobalResult<()> { let crdb = ctx.crdb("db-chat").await?; let chat_message_id = internal_unwrap!(ctx.chat_message_id).as_uuid(); diff --git a/svc/pkg/chat-message/worker/src/workers/edit.rs b/svc/pkg/chat-message/worker/src/workers/edit.rs index 16b2e10800..80ba7fae2a 100644 --- a/svc/pkg/chat-message/worker/src/workers/edit.rs +++ b/svc/pkg/chat-message/worker/src/workers/edit.rs @@ -7,7 +7,7 @@ lazy_static::lazy_static! { // TODO: Implement editing for `Text` message bodies with an `edited` property (See RIV-460) #[worker(name = "chat-message-edit")] -async fn worker(ctx: OperationContext) -> GlobalResult<()> { +async fn worker(ctx: &OperationContext) -> GlobalResult<()> { let crdb = ctx.crdb("db-chat").await?; let chat_message_id = internal_unwrap!(ctx.chat_message_id).as_uuid(); diff --git a/svc/pkg/chat-thread/ops/get-for-topic/Cargo.toml b/svc/pkg/chat-thread/ops/get-for-topic/Cargo.toml index 40a8fce677..7d3d4395a5 100644 --- a/svc/pkg/chat-thread/ops/get-for-topic/Cargo.toml +++ b/svc/pkg/chat-thread/ops/get-for-topic/Cargo.toml @@ -12,7 +12,7 @@ chrono = "0.4" prost = "0.10" [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/chat-thread/ops/get-for-topic/Service.toml b/svc/pkg/chat-thread/ops/get-for-topic/Service.toml index 99c1198ff8..b18d685576 100644 --- a/svc/pkg/chat-thread/ops/get-for-topic/Service.toml +++ b/svc/pkg/chat-thread/ops/get-for-topic/Service.toml @@ -5,3 +5,6 @@ name = "chat-thread-get-for-topic" kind = "rust" [operation] + +[databases] +db-chat = {} diff --git a/svc/pkg/chat-thread/ops/get/Cargo.toml b/svc/pkg/chat-thread/ops/get/Cargo.toml index afea653a48..02f309572f 100644 --- a/svc/pkg/chat-thread/ops/get/Cargo.toml +++ b/svc/pkg/chat-thread/ops/get/Cargo.toml @@ -12,7 +12,7 @@ chrono = "0.4" prost = "0.10" [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/chat-thread/ops/get/Service.toml b/svc/pkg/chat-thread/ops/get/Service.toml index 910d2ec5a4..eff80e891a 100644 --- a/svc/pkg/chat-thread/ops/get/Service.toml +++ b/svc/pkg/chat-thread/ops/get/Service.toml @@ -5,3 +5,6 @@ name = "chat-thread-get" kind = "rust" [operation] + +[databases] +db-chat = {} diff --git a/svc/pkg/chat-thread/ops/list-for-participant/Cargo.toml b/svc/pkg/chat-thread/ops/list-for-participant/Cargo.toml index ace6222fa9..7dca39cf89 100644 --- a/svc/pkg/chat-thread/ops/list-for-participant/Cargo.toml +++ b/svc/pkg/chat-thread/ops/list-for-participant/Cargo.toml @@ -14,7 +14,7 @@ prost = "0.10" user-team-list = { path = "../../../user/ops/team-list" } [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/chat-thread/ops/list-for-participant/Service.toml b/svc/pkg/chat-thread/ops/list-for-participant/Service.toml index 9af95dc6b7..d705574b73 100644 --- a/svc/pkg/chat-thread/ops/list-for-participant/Service.toml +++ b/svc/pkg/chat-thread/ops/list-for-participant/Service.toml @@ -5,3 +5,6 @@ name = "chat-thread-list-for-participant" kind = "rust" [operation] + +[databases] +db-chat = {} diff --git a/svc/pkg/chat-thread/ops/recent-for-user/Cargo.toml b/svc/pkg/chat-thread/ops/recent-for-user/Cargo.toml index db74712745..af7831fda5 100644 --- a/svc/pkg/chat-thread/ops/recent-for-user/Cargo.toml +++ b/svc/pkg/chat-thread/ops/recent-for-user/Cargo.toml @@ -17,7 +17,7 @@ chat-thread-get = { path = "../get" } chat-thread-list-for-participant = { path = "../list-for-participant" } [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/chat-thread/ops/recent-for-user/Service.toml b/svc/pkg/chat-thread/ops/recent-for-user/Service.toml index e958dcf631..a6adf773ef 100644 --- a/svc/pkg/chat-thread/ops/recent-for-user/Service.toml +++ b/svc/pkg/chat-thread/ops/recent-for-user/Service.toml @@ -5,3 +5,6 @@ name = "chat-thread-recent-for-user" kind = "rust" [operation] + +[databases] +db-chat = {} diff --git a/svc/pkg/chat-thread/ops/unread-count/Cargo.toml b/svc/pkg/chat-thread/ops/unread-count/Cargo.toml index b75664defe..853f61db9d 100644 --- a/svc/pkg/chat-thread/ops/unread-count/Cargo.toml +++ b/svc/pkg/chat-thread/ops/unread-count/Cargo.toml @@ -15,7 +15,7 @@ serde_json = "1.0" chat-last-read-ts-get = { path = "../../../chat/ops/last-read-ts-get" } [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/chat-thread/ops/unread-count/Service.toml b/svc/pkg/chat-thread/ops/unread-count/Service.toml index 0ba8c18e06..db031ad34c 100644 --- a/svc/pkg/chat-thread/ops/unread-count/Service.toml +++ b/svc/pkg/chat-thread/ops/unread-count/Service.toml @@ -5,3 +5,6 @@ name = "chat-thread-unread-count" kind = "rust" [operation] + +[databases] +db-chat = {} diff --git a/svc/pkg/chat-thread/worker/Cargo.toml b/svc/pkg/chat-thread/worker/Cargo.toml index 0afb80b59b..ec40af319d 100644 --- a/svc/pkg/chat-thread/worker/Cargo.toml +++ b/svc/pkg/chat-thread/worker/Cargo.toml @@ -15,7 +15,7 @@ lazy_static = "1.4.0" chrono = "0.4" [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/chat-thread/worker/Service.toml b/svc/pkg/chat-thread/worker/Service.toml index 02cea01918..6501755b0e 100644 --- a/svc/pkg/chat-thread/worker/Service.toml +++ b/svc/pkg/chat-thread/worker/Service.toml @@ -5,3 +5,6 @@ name = "chat-thread-worker" kind = "rust" [consumer] + +[databases] +db-chat = {} diff --git a/svc/pkg/chat-thread/worker/src/workers/create.rs b/svc/pkg/chat-thread/worker/src/workers/create.rs index 30e6bc7b47..873ab74cdc 100644 --- a/svc/pkg/chat-thread/worker/src/workers/create.rs +++ b/svc/pkg/chat-thread/worker/src/workers/create.rs @@ -3,7 +3,7 @@ use proto::backend::{self, pkg::*}; use serde_json::json; #[worker(name = "chat-thread-create")] -async fn worker(ctx: OperationContext) -> GlobalResult<()> { +async fn worker(ctx: &OperationContext) -> GlobalResult<()> { let crdb = ctx.crdb("db-chat").await?; let request_id = internal_unwrap!(ctx.request_id).as_uuid(); diff --git a/svc/pkg/chat/ops/last-read-ts-get/Cargo.toml b/svc/pkg/chat/ops/last-read-ts-get/Cargo.toml index bc21da748b..d9aa23f091 100644 --- a/svc/pkg/chat/ops/last-read-ts-get/Cargo.toml +++ b/svc/pkg/chat/ops/last-read-ts-get/Cargo.toml @@ -12,7 +12,7 @@ chrono = "0.4" prost = "0.10" [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/chat/ops/last-read-ts-get/Service.toml b/svc/pkg/chat/ops/last-read-ts-get/Service.toml index ec198ec2e6..e7015bd354 100644 --- a/svc/pkg/chat/ops/last-read-ts-get/Service.toml +++ b/svc/pkg/chat/ops/last-read-ts-get/Service.toml @@ -5,3 +5,6 @@ name = "chat-last-read-ts-get" kind = "rust" [operation] + +[databases] +db-chat = {} diff --git a/svc/pkg/chat/worker/Service.toml b/svc/pkg/chat/worker/Service.toml index 35a490b98e..61d16cc71e 100644 --- a/svc/pkg/chat/worker/Service.toml +++ b/svc/pkg/chat/worker/Service.toml @@ -5,3 +5,6 @@ name = "chat-worker" kind = "rust" [consumer] + +[databases] +db-chat = {} diff --git a/svc/pkg/chat/worker/src/workers/last_read_ts_set.rs b/svc/pkg/chat/worker/src/workers/last_read_ts_set.rs index df294bdfe7..9805b8e160 100644 --- a/svc/pkg/chat/worker/src/workers/last_read_ts_set.rs +++ b/svc/pkg/chat/worker/src/workers/last_read_ts_set.rs @@ -2,7 +2,7 @@ use chirp_worker::prelude::*; use proto::backend::pkg::*; #[worker(name = "chat-last-read-ts-set")] -async fn worker(ctx: OperationContext) -> GlobalResult<()> { +async fn worker(ctx: &OperationContext) -> GlobalResult<()> { let crdb = ctx.crdb("db-chat").await?; let user_id = internal_unwrap!(ctx.user_id).as_uuid(); diff --git a/svc/pkg/cloud/ops/game-config-create/Cargo.toml b/svc/pkg/cloud/ops/game-config-create/Cargo.toml index 3deb7aa33d..94af0569df 100644 --- a/svc/pkg/cloud/ops/game-config-create/Cargo.toml +++ b/svc/pkg/cloud/ops/game-config-create/Cargo.toml @@ -11,7 +11,7 @@ chirp-client = { path = "../../../../../lib/chirp/client" } prost = "0.10" [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/cloud/ops/game-config-create/Service.toml b/svc/pkg/cloud/ops/game-config-create/Service.toml index bbc5ec48c5..e80e01c5e3 100644 --- a/svc/pkg/cloud/ops/game-config-create/Service.toml +++ b/svc/pkg/cloud/ops/game-config-create/Service.toml @@ -5,3 +5,6 @@ name = "cloud-game-config-create" kind = "rust" [operation] + +[databases] +db-cloud = {} diff --git a/svc/pkg/cloud/ops/game-config-get/Cargo.toml b/svc/pkg/cloud/ops/game-config-get/Cargo.toml index f710928b59..2fc404c910 100644 --- a/svc/pkg/cloud/ops/game-config-get/Cargo.toml +++ b/svc/pkg/cloud/ops/game-config-get/Cargo.toml @@ -11,7 +11,7 @@ chirp-client = { path = "../../../../../lib/chirp/client" } prost = "0.10" [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/cloud/ops/game-config-get/Service.toml b/svc/pkg/cloud/ops/game-config-get/Service.toml index 8631b9b06c..ee5f5de7e8 100644 --- a/svc/pkg/cloud/ops/game-config-get/Service.toml +++ b/svc/pkg/cloud/ops/game-config-get/Service.toml @@ -5,3 +5,6 @@ name = "cloud-game-config-get" kind = "rust" [operation] + +[databases] +db-cloud = {} diff --git a/svc/pkg/cloud/ops/game-token-create/Cargo.toml b/svc/pkg/cloud/ops/game-token-create/Cargo.toml index 2c9996c3e4..fb1c97a00c 100644 --- a/svc/pkg/cloud/ops/game-token-create/Cargo.toml +++ b/svc/pkg/cloud/ops/game-token-create/Cargo.toml @@ -13,7 +13,7 @@ prost = "0.10" token-create = { path = "../../../token/ops/create" } [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/cloud/ops/game-token-create/Service.toml b/svc/pkg/cloud/ops/game-token-create/Service.toml index b5355068c5..3da51dee5e 100644 --- a/svc/pkg/cloud/ops/game-token-create/Service.toml +++ b/svc/pkg/cloud/ops/game-token-create/Service.toml @@ -5,3 +5,6 @@ name = "cloud-game-token-create" kind = "rust" [operation] + +[databases] +db-cloud = {} diff --git a/svc/pkg/cloud/ops/namespace-create/Cargo.toml b/svc/pkg/cloud/ops/namespace-create/Cargo.toml index 68b8f9e7fe..a4f75a47e8 100644 --- a/svc/pkg/cloud/ops/namespace-create/Cargo.toml +++ b/svc/pkg/cloud/ops/namespace-create/Cargo.toml @@ -18,7 +18,7 @@ kv-config-namespace-create = { path = "../../../kv-config/ops/namespace-create" identity-config-namespace-create = { path = "../../../identity-config/ops/namespace-create" } [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/cloud/ops/namespace-create/Service.toml b/svc/pkg/cloud/ops/namespace-create/Service.toml index 432695de58..7c9c89a4d1 100644 --- a/svc/pkg/cloud/ops/namespace-create/Service.toml +++ b/svc/pkg/cloud/ops/namespace-create/Service.toml @@ -5,3 +5,6 @@ name = "cloud-namespace-create" kind = "rust" [operation] + +[databases] +db-cloud = {} diff --git a/svc/pkg/cloud/ops/namespace-get/Cargo.toml b/svc/pkg/cloud/ops/namespace-get/Cargo.toml index 8cc109f520..9d3d60fcf8 100644 --- a/svc/pkg/cloud/ops/namespace-get/Cargo.toml +++ b/svc/pkg/cloud/ops/namespace-get/Cargo.toml @@ -16,7 +16,7 @@ kv-config-namespace-get = { path = "../../../kv-config/ops/namespace-get" } mm-config-namespace-get = { path = "../../../mm-config/ops/namespace-get" } [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/cloud/ops/namespace-get/Service.toml b/svc/pkg/cloud/ops/namespace-get/Service.toml index 5d1e3dfdf3..9a57da9d00 100644 --- a/svc/pkg/cloud/ops/namespace-get/Service.toml +++ b/svc/pkg/cloud/ops/namespace-get/Service.toml @@ -5,3 +5,6 @@ name = "cloud-namespace-get" kind = "rust" [operation] + +[databases] +db-cloud = {} diff --git a/svc/pkg/cloud/ops/namespace-token-development-create/Cargo.toml b/svc/pkg/cloud/ops/namespace-token-development-create/Cargo.toml index b935e592a5..16e8a2ae4e 100644 --- a/svc/pkg/cloud/ops/namespace-token-development-create/Cargo.toml +++ b/svc/pkg/cloud/ops/namespace-token-development-create/Cargo.toml @@ -15,7 +15,7 @@ game-token-development-validate = { path = "../../../game/ops/token-development- token-create = { path = "../../../token/ops/create" } [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/cloud/ops/namespace-token-development-create/Service.toml b/svc/pkg/cloud/ops/namespace-token-development-create/Service.toml index 44c0af3b10..b99580e51a 100644 --- a/svc/pkg/cloud/ops/namespace-token-development-create/Service.toml +++ b/svc/pkg/cloud/ops/namespace-token-development-create/Service.toml @@ -5,3 +5,6 @@ name = "cloud-namespace-token-development-create" kind = "rust" [operation] + +[databases] +db-cloud = {} diff --git a/svc/pkg/cloud/ops/namespace-token-development-create/src/lib.rs b/svc/pkg/cloud/ops/namespace-token-development-create/src/lib.rs index 8f6aafda24..143a4ef1fe 100644 --- a/svc/pkg/cloud/ops/namespace-token-development-create/src/lib.rs +++ b/svc/pkg/cloud/ops/namespace-token-development-create/src/lib.rs @@ -60,7 +60,17 @@ async fn handle( let token = internal_unwrap!(token_res.token); let token_session_id = internal_unwrap!(token_res.session_id).as_uuid(); - sqlx::query("INSERT INTO game_namespace_development_tokens (namespace_id, token_session_id) VALUES ($1, $2)").bind(namespace_id).bind(token_session_id).execute(&ctx.crdb("db-cloud").await?).await?; + sqlx::query(indoc!( + " + INSERT INTO game_namespace_development_tokens + (namespace_id, token_session_id) + VALUES ($1, $2) + " + )) + .bind(namespace_id) + .bind(token_session_id) + .execute(&ctx.crdb("db-cloud").await?) + .await?; Ok(cloud::namespace_token_development_create::Response { token: token.token.clone(), diff --git a/svc/pkg/cloud/ops/namespace-token-public-create/Cargo.toml b/svc/pkg/cloud/ops/namespace-token-public-create/Cargo.toml index 3d6563061f..2ba6eb987b 100644 --- a/svc/pkg/cloud/ops/namespace-token-public-create/Cargo.toml +++ b/svc/pkg/cloud/ops/namespace-token-public-create/Cargo.toml @@ -15,7 +15,7 @@ game-namespace-get = { path = "../../../game/ops/namespace-get" } token-create = { path = "../../../token/ops/create" } [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/cloud/ops/namespace-token-public-create/Service.toml b/svc/pkg/cloud/ops/namespace-token-public-create/Service.toml index da3fedf479..08dc0915c4 100644 --- a/svc/pkg/cloud/ops/namespace-token-public-create/Service.toml +++ b/svc/pkg/cloud/ops/namespace-token-public-create/Service.toml @@ -5,3 +5,6 @@ name = "cloud-namespace-token-public-create" kind = "rust" [operation] + +[databases] +db-cloud = {} diff --git a/svc/pkg/cloud/ops/namespace-token-public-create/src/lib.rs b/svc/pkg/cloud/ops/namespace-token-public-create/src/lib.rs index 0aa57f35e1..128b4fc300 100644 --- a/svc/pkg/cloud/ops/namespace-token-public-create/src/lib.rs +++ b/svc/pkg/cloud/ops/namespace-token-public-create/src/lib.rs @@ -40,9 +40,13 @@ async fn handle( let token = internal_unwrap!(token_res.token); let token_session_id = internal_unwrap!(token_res.session_id).as_uuid(); - sqlx::query( - "INSERT INTO game_namespace_public_tokens (namespace_id, token_session_id) VALUES ($1, $2)", - ) + sqlx::query(indoc!( + " + INSERT INTO game_namespace_public_tokens + (namespace_id, token_session_id) + VALUES ($1, $2) + " + )) .bind(namespace_id) .bind(token_session_id) .execute(&ctx.crdb("db-cloud").await?) diff --git a/svc/pkg/cloud/ops/version-get/Cargo.toml b/svc/pkg/cloud/ops/version-get/Cargo.toml index f6d4ce3cc5..e22fc993c6 100644 --- a/svc/pkg/cloud/ops/version-get/Cargo.toml +++ b/svc/pkg/cloud/ops/version-get/Cargo.toml @@ -18,7 +18,7 @@ mm-config-version-get = { path = "../../../mm-config/ops/version-get" } module-game-version-get = { path = "../../../module/ops/game-version-get" } [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/cloud/ops/version-get/Service.toml b/svc/pkg/cloud/ops/version-get/Service.toml index f6356d2dd9..4e51b2a554 100644 --- a/svc/pkg/cloud/ops/version-get/Service.toml +++ b/svc/pkg/cloud/ops/version-get/Service.toml @@ -5,3 +5,6 @@ name = "cloud-version-get" kind = "rust" [operation] + +[databases] +db-cloud = {} diff --git a/svc/pkg/cloud/ops/version-get/tests/integration.rs b/svc/pkg/cloud/ops/version-get/tests/integration.rs index d835ba3187..2f00f80138 100644 --- a/svc/pkg/cloud/ops/version-get/tests/integration.rs +++ b/svc/pkg/cloud/ops/version-get/tests/integration.rs @@ -38,6 +38,7 @@ async fn empty(ctx: TestCtx) { max_players_normal: 8, max_players_direct: 10, max_players_party: 12, + listable: true, runtime: Some(backend::matchmaker::lobby_runtime::Docker { build_id: build_res.build_id, @@ -59,6 +60,10 @@ async fn empty(ctx: TestCtx) { }, ], }.into()), + + find_config: None, + join_config: None, + create_config: None, }, ], captcha: None, diff --git a/svc/pkg/cloud/ops/version-publish/Cargo.toml b/svc/pkg/cloud/ops/version-publish/Cargo.toml index 47cbc69a45..43da7e59e4 100644 --- a/svc/pkg/cloud/ops/version-publish/Cargo.toml +++ b/svc/pkg/cloud/ops/version-publish/Cargo.toml @@ -25,7 +25,7 @@ module-game-version-prepare = { path = "../../../module/ops/game-version-prepare module-game-version-publish = { path = "../../../module/ops/game-version-publish" } [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/cloud/ops/version-publish/Service.toml b/svc/pkg/cloud/ops/version-publish/Service.toml index a262c7bfce..1bfb3ecdbc 100644 --- a/svc/pkg/cloud/ops/version-publish/Service.toml +++ b/svc/pkg/cloud/ops/version-publish/Service.toml @@ -5,3 +5,6 @@ name = "cloud-version-publish" kind = "rust" [operation] + +[databases] +db-cloud = {} diff --git a/svc/pkg/cloud/ops/version-publish/tests/integration.rs b/svc/pkg/cloud/ops/version-publish/tests/integration.rs index e3717e56ab..bc39f543db 100644 --- a/svc/pkg/cloud/ops/version-publish/tests/integration.rs +++ b/svc/pkg/cloud/ops/version-publish/tests/integration.rs @@ -45,6 +45,7 @@ async fn empty(ctx: TestCtx) { max_players_normal: 8, max_players_direct: 10, max_players_party: 12, + listable: true, runtime: Some(backend::matchmaker::lobby_runtime::Docker { build_id: build_res.build_id, @@ -66,6 +67,10 @@ async fn empty(ctx: TestCtx) { }, ], }.into()), + + find_config: None, + join_config: None, + create_config: None, }, ], captcha: None, diff --git a/svc/pkg/cloud/worker/src/workers/device_link_complete.rs b/svc/pkg/cloud/worker/src/workers/device_link_complete.rs index 282e75a9af..e167f2dd7d 100644 --- a/svc/pkg/cloud/worker/src/workers/device_link_complete.rs +++ b/svc/pkg/cloud/worker/src/workers/device_link_complete.rs @@ -3,7 +3,7 @@ use proto::backend::pkg::*; #[worker(name = "cloud-device-link-complete")] async fn worker( - ctx: OperationContext, + ctx: &OperationContext, ) -> GlobalResult<()> { let device_link_id = internal_unwrap!(ctx.device_link_id).as_uuid(); diff --git a/svc/pkg/custom-user-avatar/ops/list-for-game/Cargo.toml b/svc/pkg/custom-user-avatar/ops/list-for-game/Cargo.toml index 24e87ab191..4fce1dc75b 100644 --- a/svc/pkg/custom-user-avatar/ops/list-for-game/Cargo.toml +++ b/svc/pkg/custom-user-avatar/ops/list-for-game/Cargo.toml @@ -11,7 +11,7 @@ chirp-client = { path = "../../../../../lib/chirp/client" } prost = "0.10" [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/custom-user-avatar/ops/list-for-game/Service.toml b/svc/pkg/custom-user-avatar/ops/list-for-game/Service.toml index 63334a14bf..bd5eca33d0 100644 --- a/svc/pkg/custom-user-avatar/ops/list-for-game/Service.toml +++ b/svc/pkg/custom-user-avatar/ops/list-for-game/Service.toml @@ -5,3 +5,6 @@ name = "custom-user-avatar-list-for-game" kind = "rust" [operation] + +[databases] +db-game-custom-avatar = {} diff --git a/svc/pkg/custom-user-avatar/ops/upload-complete/Cargo.toml b/svc/pkg/custom-user-avatar/ops/upload-complete/Cargo.toml index 4f85ad4e95..24abf1e7b6 100644 --- a/svc/pkg/custom-user-avatar/ops/upload-complete/Cargo.toml +++ b/svc/pkg/custom-user-avatar/ops/upload-complete/Cargo.toml @@ -13,7 +13,7 @@ prost = "0.10" upload-complete = { path = "../../../upload/ops/complete" } [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/custom-user-avatar/ops/upload-complete/Service.toml b/svc/pkg/custom-user-avatar/ops/upload-complete/Service.toml index b063a0fb02..6d9787909d 100644 --- a/svc/pkg/custom-user-avatar/ops/upload-complete/Service.toml +++ b/svc/pkg/custom-user-avatar/ops/upload-complete/Service.toml @@ -5,3 +5,6 @@ name = "custom-user-avatar-upload-complete" kind = "rust" [operation] + +[databases] +db-game-custom-avatar = {} diff --git a/svc/pkg/debug/ops/email-res/Cargo.toml b/svc/pkg/debug/ops/email-res/Cargo.toml index 2e32780ca8..009dc7a79a 100644 --- a/svc/pkg/debug/ops/email-res/Cargo.toml +++ b/svc/pkg/debug/ops/email-res/Cargo.toml @@ -13,7 +13,7 @@ rand = "0.8" serde_json = "1.0" [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/email-verification/ops/complete/Cargo.toml b/svc/pkg/email-verification/ops/complete/Cargo.toml index aff5e415de..0dcf81bd18 100644 --- a/svc/pkg/email-verification/ops/complete/Cargo.toml +++ b/svc/pkg/email-verification/ops/complete/Cargo.toml @@ -12,7 +12,7 @@ chrono = "0.4" prost = "0.10" [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/email-verification/ops/complete/Service.toml b/svc/pkg/email-verification/ops/complete/Service.toml index 91dd750891..475849a66b 100644 --- a/svc/pkg/email-verification/ops/complete/Service.toml +++ b/svc/pkg/email-verification/ops/complete/Service.toml @@ -5,3 +5,6 @@ name = "email-verification-complete" kind = "rust" [operation] + +[databases] +db-email-verification = {} diff --git a/svc/pkg/email-verification/ops/create/Cargo.toml b/svc/pkg/email-verification/ops/create/Cargo.toml index 5a0847998f..46bfea86ad 100644 --- a/svc/pkg/email-verification/ops/create/Cargo.toml +++ b/svc/pkg/email-verification/ops/create/Cargo.toml @@ -18,7 +18,7 @@ email-send = { path = "../../../email/ops/send" } game-get = { path = "../../../game/ops/get" } [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/email-verification/ops/create/Service.toml b/svc/pkg/email-verification/ops/create/Service.toml index 511b1a6511..b42d5018e9 100644 --- a/svc/pkg/email-verification/ops/create/Service.toml +++ b/svc/pkg/email-verification/ops/create/Service.toml @@ -5,3 +5,6 @@ name = "email-verification-create" kind = "rust" [operation] + +[databases] +db-email-verification = {} diff --git a/svc/pkg/email-verification/ops/create/src/lib.rs b/svc/pkg/email-verification/ops/create/src/lib.rs index 368e2c6bbf..0cf8d43568 100644 --- a/svc/pkg/email-verification/ops/create/src/lib.rs +++ b/svc/pkg/email-verification/ops/create/src/lib.rs @@ -52,9 +52,7 @@ async fn handle( json!({ "game_display_name": game.display_name.clone(), "game_logo_url": util::route::game_logo( - game.logo_upload_id.as_ref().map(common::Uuid::as_uuid), - game.logo_file_name.as_ref(), - ), + &game), "verification_code": code, }), ) diff --git a/svc/pkg/external/ops/request-validate/Cargo.toml b/svc/pkg/external/ops/request-validate/Cargo.toml new file mode 100644 index 0000000000..e52a7f4686 --- /dev/null +++ b/svc/pkg/external/ops/request-validate/Cargo.toml @@ -0,0 +1,23 @@ +[package] +name = "external-request-validate" +version = "0.0.1" +edition = "2018" +authors = ["Rivet Gaming, LLC "] +license = "Apache-2.0" + +[dependencies] +chirp-client = { path = "../../../../../lib/chirp/client" } +chrono = "0.4" +http = "0.2" +prost = "0.10" +reqwest = { version = "0.11" } +rivet-operation = { path = "../../../../../lib/operation/core" } +serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0" + +[dependencies.sqlx] +version = "0.7" +default-features = false + +[dev-dependencies] +chirp-worker = { path = "../../../../../lib/chirp/worker" } diff --git a/svc/pkg/external/ops/request-validate/README.md b/svc/pkg/external/ops/request-validate/README.md new file mode 100644 index 0000000000..120b8e9d0b --- /dev/null +++ b/svc/pkg/external/ops/request-validate/README.md @@ -0,0 +1 @@ +# external-request-validate diff --git a/svc/pkg/external/ops/request-validate/Service.toml b/svc/pkg/external/ops/request-validate/Service.toml new file mode 100644 index 0000000000..5f986171cd --- /dev/null +++ b/svc/pkg/external/ops/request-validate/Service.toml @@ -0,0 +1,7 @@ +[service] +name = "external-request-validate" + +[runtime] +kind = "rust" + +[operation] diff --git a/svc/pkg/external/ops/request-validate/src/lib.rs b/svc/pkg/external/ops/request-validate/src/lib.rs new file mode 100644 index 0000000000..d24e06b4be --- /dev/null +++ b/svc/pkg/external/ops/request-validate/src/lib.rs @@ -0,0 +1,131 @@ +use http::{uri::Scheme, HeaderName, HeaderValue, Uri}; +use std::{net::IpAddr, str::FromStr}; + +use proto::backend::pkg::*; +use rivet_operation::prelude::*; + +#[operation(name = "external-request-validate")] +async fn handle( + ctx: OperationContext, +) -> GlobalResult { + let config = internal_unwrap!(ctx.config); + let mut errors = Vec::new(); + + // Parse URL + if let Ok(url) = config.url.parse::() { + if let Some(host) = url.host() { + // Validate as IP + if let Ok(ip) = IpAddr::from_str(host) { + // Validate that IP is global + if !is_global_ip(ip) { + errors.push(util::err_path!["url", "invalid-ip"]); + } + } + // Validate that URL is not internal + else if host.ends_with(".consul") { + errors.push(util::err_path!["url", "invalid"]); + } + + // Validate URL scheme + if let Some(scheme) = url.scheme() { + if scheme != &Scheme::HTTP && scheme != &Scheme::HTTPS { + errors.push(util::err_path!["url", "invalid-scheme"]); + } + } else { + errors.push(util::err_path!["url", "invalid-scheme"]); + } + } else { + errors.push(util::err_path!["url", "no-host"]); + } + } else { + errors.push(util::err_path!["url", "invalid"]); + } + + // Validate DNS + if errors.is_empty() { + let req = reqwest::Client::new() + .get(&config.url) + .timeout(std::time::Duration::from_secs(5)); + + if let Err(err) = req.send().await { + if err.is_connect() { + errors.push(util::err_path!["url", "dns-failed"]); + } else if err.is_timeout() { + errors.push(util::err_path!["url", "dns-timeout"]); + } else { + // Throw error if its not a connection or timeout problem + return Err(err.into()); + } + } + } + + if config.headers.len() > 32 { + errors.push(util::err_path!["headers-meta", "too-many"]); + } + + // Validate headers + for (k, v) in config.headers.iter().take(32) { + let header_label = format!("*{}*", k); + + if HeaderName::from_str(k).is_err() { + errors.push(util::err_path!["headers", header_label, "invalid-name"]); + } + if HeaderValue::from_str(v).is_err() { + errors.push(util::err_path!["headers", header_label, "invalid-value"]); + } + } + + Ok(external::request_validate::Response { + errors: errors + .into_iter() + .map(|path| external::request_validate::response::Error { path }) + .collect::>(), + }) +} + +// TODO: Replace with `IpAddr::is_global` whenever that stabilizes +#[allow(clippy::manual_range_contains)] +fn is_global_ip(ip: IpAddr) -> bool { + match ip { + IpAddr::V4(ip) => { + !(ip.octets()[0] == 0 // "This network" + || ip.is_private() + || (ip.octets()[0] == 100 && (ip.octets()[1] & 0b1100_0000 == 0b0100_0000)) + || ip.is_loopback() + || ip.is_link_local() + // addresses reserved for future protocols (`192.0.0.0/24`) + ||(ip.octets()[0] == 192 && ip.octets()[1] == 0 && ip.octets()[2] == 0) + || ip.is_documentation() + || (ip.octets()[0] == 198 && (ip.octets()[1] & 0xfe) == 18) + || (ip.octets()[0] & 240 == 240 && !ip.is_broadcast()) + || ip.is_broadcast()) + } + IpAddr::V6(ip) => { + !(ip.is_unspecified() + || ip.is_loopback() + // IPv4-mapped Address (`::ffff:0:0/96`) + || matches!(ip.segments(), [0, 0, 0, 0, 0, 0xffff, _, _]) + // IPv4-IPv6 Translat. (`64:ff9b:1::/48`) + || matches!(ip.segments(), [0x64, 0xff9b, 1, _, _, _, _, _]) + // Discard-Only Address Block (`100::/64`) + || matches!(ip.segments(), [0x100, 0, 0, 0, _, _, _, _]) + // IETF Protocol Assignments (`2001::/23`) + || (matches!(ip.segments(), [0x2001, b, _, _, _, _, _, _] if b < 0x200) + && !( + // Port Control Protocol Anycast (`2001:1::1`) + u128::from_be_bytes(ip.octets()) == 0x2001_0001_0000_0000_0000_0000_0000_0001 + // Traversal Using Relays around NAT Anycast (`2001:1::2`) + || u128::from_be_bytes(ip.octets()) == 0x2001_0001_0000_0000_0000_0000_0000_0002 + // AMT (`2001:3::/32`) + || matches!(ip.segments(), [0x2001, 3, _, _, _, _, _, _]) + // AS112-v6 (`2001:4:112::/48`) + || matches!(ip.segments(), [0x2001, 4, 0x112, _, _, _, _, _]) + // ORCHIDv2 (`2001:20::/28`) + || matches!(ip.segments(), [0x2001, b, _, _, _, _, _, _] if b >= 0x20 && b <= 0x2F) + )) + || ((ip.segments()[0] == 0x2001) && (ip.segments()[1] == 0xdb8)) + || ((ip.segments()[0] & 0xfe00) == 0xfc00) + || ((ip.segments()[0] & 0xffc0) == 0xfe80)) + } + } +} diff --git a/svc/pkg/external/ops/request-validate/tests/integration.rs b/svc/pkg/external/ops/request-validate/tests/integration.rs new file mode 100644 index 0000000000..071e625af7 --- /dev/null +++ b/svc/pkg/external/ops/request-validate/tests/integration.rs @@ -0,0 +1,42 @@ +use std::collections::HashMap; + +use chirp_worker::prelude::*; +use proto::backend; + +#[worker_test] +async fn empty(ctx: TestCtx) { + let headers = IntoIterator::into_iter([( + " invalid name ".to_string(), + "\ninvalid value".to_string(), + )]) + .collect::>(); + + let res = op!([ctx] external_request_validate { + config: Some(backend::net::ExternalRequestConfig { + url: "ssh://example.com".to_string(), + method: backend::net::HttpMethod::Get as i32, + headers, + }), + }) + .await + .unwrap(); + + tracing::info!(errors=?res.errors); + assert_eq!(3, res.errors.len()); +} + +#[worker_test] +async fn dns(ctx: TestCtx) { + let res = op!([ctx] external_request_validate { + config: Some(backend::net::ExternalRequestConfig { + url: "https://httpstat.us/200?sleep=6000".to_string(), + method: backend::net::HttpMethod::Get as i32, + headers: HashMap::new(), + }), + }) + .await + .unwrap(); + + tracing::info!(errors=?res.errors); + assert_eq!(1, res.errors.len()); +} diff --git a/svc/pkg/external/types/msg/request-call-complete.proto b/svc/pkg/external/types/msg/request-call-complete.proto new file mode 100644 index 0000000000..3b59c2c5f0 --- /dev/null +++ b/svc/pkg/external/types/msg/request-call-complete.proto @@ -0,0 +1,16 @@ +syntax = "proto3"; + +package rivet.backend.pkg.external.msg.request_call_complete; + +import "proto/common.proto"; + +/// name = "msg-external-request-call-complete" +/// parameters = [ +/// { name = "request_id" }, +/// ] +message Message { + rivet.common.Uuid request_id = 1; + uint32 status_code = 2; + // This property is only set if `read_response_body` is true in the `external-request-call` message + optional bytes body = 3; +} diff --git a/svc/pkg/external/types/msg/request-call-fail.proto b/svc/pkg/external/types/msg/request-call-fail.proto new file mode 100644 index 0000000000..8fa51de69c --- /dev/null +++ b/svc/pkg/external/types/msg/request-call-fail.proto @@ -0,0 +1,21 @@ +syntax = "proto3"; + +package rivet.backend.pkg.external.msg.request_call_fail; + +import "proto/common.proto"; + +enum ErrorCode { + UNKNOWN = 0; + + REQUEST_FAILED = 1; +} + +/// name = "msg-external-request-call-fail" +/// parameters = [ +/// { name = "request_id" }, +/// ] +message Message { + rivet.common.Uuid request_id = 1; + ErrorCode error_code = 2; +} + diff --git a/svc/pkg/external/types/msg/request-call.proto b/svc/pkg/external/types/msg/request-call.proto new file mode 100644 index 0000000000..c668a75954 --- /dev/null +++ b/svc/pkg/external/types/msg/request-call.proto @@ -0,0 +1,19 @@ +syntax = "proto3"; + +package rivet.backend.pkg.external.msg.request_call; + +import "proto/common.proto"; +import "proto/backend/net.proto"; + +/// name = "msg-external-request-call" +/// parameters = [ +/// { name = "request_id" }, +/// ] +message Message { + rivet.common.Uuid request_id = 1; + rivet.backend.net.ExternalRequestConfig config = 2; + // 0 for no timeout + uint64 timeout = 3; + optional bytes body = 4; + bool read_response_body = 5; +} diff --git a/svc/pkg/external/types/request-validate.proto b/svc/pkg/external/types/request-validate.proto new file mode 100644 index 0000000000..893cc38125 --- /dev/null +++ b/svc/pkg/external/types/request-validate.proto @@ -0,0 +1,18 @@ +syntax = "proto3"; + +package rivet.backend.pkg.external.request_validate; + +import "proto/common.proto"; +import "proto/backend/net.proto"; + +message Request { + rivet.backend.net.ExternalRequestConfig config = 1; +} + +message Response { + message Error { + repeated string path = 1; + } + + repeated Error errors = 1; +} diff --git a/svc/pkg/external/worker/Cargo.toml b/svc/pkg/external/worker/Cargo.toml new file mode 100644 index 0000000000..f64c5805bd --- /dev/null +++ b/svc/pkg/external/worker/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "external-worker" +version = "0.0.1" +edition = "2018" +authors = ["Rivet Gaming, LLC "] +license = "Apache-2.0" + +[dependencies] +chirp-worker = { path = "../../../../lib/chirp/worker" } +chirp-client = { path = "../../../../lib/chirp/client" } +reqwest = { version = "0.11" } +rivet-health-checks = { path = "../../../../lib/health-checks" } +rivet-metrics = { path = "../../../../lib/metrics" } +rivet-runtime = { path = "../../../../lib/runtime" } +chrono = "0.4" + +[dev-dependencies] +chirp-worker = { path = "../../../../lib/chirp/worker" } diff --git a/svc/pkg/external/worker/Service.toml b/svc/pkg/external/worker/Service.toml new file mode 100644 index 0000000000..62db18d071 --- /dev/null +++ b/svc/pkg/external/worker/Service.toml @@ -0,0 +1,7 @@ +[service] +name = "external-worker" + +[runtime] +kind = "rust" + +[consumer] diff --git a/svc/pkg/external/worker/src/main.rs b/svc/pkg/external/worker/src/main.rs new file mode 100644 index 0000000000..fc7071fc27 --- /dev/null +++ b/svc/pkg/external/worker/src/main.rs @@ -0,0 +1,14 @@ +use chirp_worker::prelude::*; +use chirp_worker::ManagerError; + +mod workers; +use workers::*; + +fn main() -> Result<(), ManagerError> { + // Start runtime + rivet_runtime::run(async move { + worker_group![request_call].await; + + Result::<_, ManagerError>::Ok(()) + })? +} diff --git a/svc/pkg/external/worker/src/workers/mod.rs b/svc/pkg/external/worker/src/workers/mod.rs new file mode 100644 index 0000000000..a1682bc1f2 --- /dev/null +++ b/svc/pkg/external/worker/src/workers/mod.rs @@ -0,0 +1 @@ +pub mod request_call; diff --git a/svc/pkg/external/worker/src/workers/request_call.rs b/svc/pkg/external/worker/src/workers/request_call.rs new file mode 100644 index 0000000000..9353d6850b --- /dev/null +++ b/svc/pkg/external/worker/src/workers/request_call.rs @@ -0,0 +1,103 @@ +use std::str::FromStr; + +use chirp_worker::prelude::*; +use proto::backend::{net::HttpMethod, pkg::*}; +use reqwest::{ + header::{HeaderMap, HeaderName, HeaderValue}, + StatusCode, +}; + +#[tracing::instrument] +async fn fail( + ctx: &OperationContext, + request_id: Uuid, + error_code: external::msg::request_call_fail::ErrorCode, +) -> GlobalResult<()> { + msg!([ctx] external::msg::request_call_fail(request_id) { + request_id: Some(request_id.into()), + error_code: error_code as i32, + }) + .await?; + + Ok(()) +} + +#[worker(name = "external-request-call")] +async fn worker(ctx: &OperationContext) -> GlobalResult<()> { + let request_id = internal_unwrap!(ctx.request_id).as_uuid(); + let config = internal_unwrap!(ctx.config); + + let req = reqwest::Client::new(); + + // Add method + let method = internal_unwrap_owned!(HttpMethod::from_i32(config.method), "invalid http method"); + let req = match method { + HttpMethod::Get => req.get(&config.url), + HttpMethod::Post => req.post(&config.url), + HttpMethod::Put => req.put(&config.url), + HttpMethod::Delete => req.delete(&config.url), + }; + + // Add body + // TODO: Figure out a way to not clone this + let req = if let Some(body) = ctx.body.clone() { + req.body(body) + } else { + req + }; + + // Add headers (NOTE: If using a config that has been validated by `external-request-validate`, the + // creation of this header map should be infallible) + let headers = config + .headers + .iter() + .map(|(k, v)| Ok((HeaderName::from_str(k)?, HeaderValue::from_str(v)?))) + .collect::>()?; + let req = req.headers(headers); + + // Add timeout + let req = if ctx.timeout != 0 { + let timeout = std::time::Duration::from_millis(ctx.timeout); + req.timeout(timeout) + } else { + req + }; + + // Execute + let (status, body) = match req.send().await { + Ok(res) => ( + res.status().as_u16(), + if ctx.read_response_body { + Some(res.bytes().await?.to_vec()) + } else { + None + }, + ), + Err(err) => { + // Coerce reqwest timeout into http request timeout + if err.is_timeout() { + (StatusCode::REQUEST_TIMEOUT.as_u16(), None) + } else { + tracing::info!(?err, "external request failed"); + + fail( + ctx, + request_id, + external::msg::request_call_fail::ErrorCode::RequestFailed, + ) + .await?; + + return Ok(()); + } + } + }; + + msg!([ctx] external::msg::request_call_complete(request_id) { + request_id: ctx.request_id, + status_code: status as u32, + body: body, + }) + .await?; + + Ok(()) +} diff --git a/svc/pkg/external/worker/tests/request_call.rs b/svc/pkg/external/worker/tests/request_call.rs new file mode 100644 index 0000000000..86c2b5f7c3 --- /dev/null +++ b/svc/pkg/external/worker/tests/request_call.rs @@ -0,0 +1,69 @@ +use std::collections::HashMap; + +use chirp_worker::prelude::*; +use proto::backend::{self, pkg::*}; + +#[worker_test] +async fn empty(ctx: TestCtx) { + let request_id = Uuid::new_v4(); + let res = + msg!([ctx] external::msg::request_call(request_id) -> external::msg::request_call_complete { + request_id: Some(request_id.into()), + config: Some(backend::net::ExternalRequestConfig { + url: "https://example.com".to_string(), + method: backend::net::HttpMethod::Get as i32, + headers: HashMap::new(), + }), + timeout: 0, + body: None, + read_response_body: true, + }) + .await + .unwrap(); + + assert_eq!(200, res.status_code); + // TODO: Verify body + tracing::info!(body=?std::str::from_utf8(res.body.as_ref().unwrap())); +} + +#[worker_test] +async fn delete(ctx: TestCtx) { + let request_id = Uuid::new_v4(); + let res = + msg!([ctx] external::msg::request_call(request_id) -> external::msg::request_call_complete { + request_id: Some(request_id.into()), + config: Some(backend::net::ExternalRequestConfig { + url: "https://example.com".to_string(), + method: backend::net::HttpMethod::Delete as i32, + headers: HashMap::new(), + }), + timeout: 0, + body: None, + read_response_body: false, + }) + .await + .unwrap(); + + assert_eq!(405, res.status_code); +} + +#[worker_test] +async fn timeout(ctx: TestCtx) { + let request_id = Uuid::new_v4(); + let res = + msg!([ctx] external::msg::request_call(request_id) -> external::msg::request_call_complete { + request_id: Some(request_id.into()), + config: Some(backend::net::ExternalRequestConfig { + url: "https://httpstat.us/200?sleep=10000".to_string(), + method: backend::net::HttpMethod::Get as i32, + headers: HashMap::new(), + }), + timeout: 1000, + body: None, + read_response_body: false, + }) + .await + .unwrap(); + + assert_eq!(408, res.status_code); +} diff --git a/svc/pkg/faker/ops/game-version/src/lib.rs b/svc/pkg/faker/ops/game-version/src/lib.rs index 036d2dca40..e64262f137 100644 --- a/svc/pkg/faker/ops/game-version/src/lib.rs +++ b/svc/pkg/faker/ops/game-version/src/lib.rs @@ -12,67 +12,68 @@ async fn handle( }) .await?; - let config = if let Some(config) = ctx.override_config.clone() { - config - } else { - backend::cloud::VersionConfig { - cdn: if let Some(config) = ctx.override_cdn_config.clone() { - config.config - } else { - let cdn_site_res = op!([ctx] faker_cdn_site { - game_id: Some(*game_id), - }) - .await?; - let site_id = internal_unwrap!(cdn_site_res.site_id); + let config = + if let Some(config) = ctx.override_config.clone() { + config + } else { + backend::cloud::VersionConfig { + cdn: if let Some(config) = ctx.override_cdn_config.clone() { + config.config + } else { + let cdn_site_res = op!([ctx] faker_cdn_site { + game_id: Some(*game_id), + }) + .await?; + let site_id = internal_unwrap!(cdn_site_res.site_id); - Some(VersionConfig { - site_id: Some(*site_id), - routes: vec![ - Route { - glob: Some(util::glob::Glob::parse("test-glob")?.into()), - priority: 0, - middlewares: vec![Middleware { - kind: Some(middleware::Kind::CustomHeaders( - CustomHeadersMiddleware { - headers: vec![custom_headers_middleware::Header { - name: "header-name".to_string(), - value: "header-value".to_string(), - }], - }, - )), - }], - }, - Route { - glob: Some(util::glob::Glob::parse("test-glob2")?.into()), - priority: 1, - middlewares: vec![Middleware { - kind: Some(middleware::Kind::CustomHeaders( - CustomHeadersMiddleware { - headers: vec![custom_headers_middleware::Header { - name: "header-name2".to_string(), - value: "header-value2".to_string(), - }], - }, - )), - }], - }, - ], - }) - }, - matchmaker: if let Some(config) = ctx.override_mm_config.clone() { - config.config - } else { - let build_res = op!([ctx] faker_build { - game_id: Some(*game_id), - image: faker::build::Image::MmLobbyAutoReady as i32, - }) - .await?; - let build_id = internal_unwrap!(build_res.build_id); + Some(VersionConfig { + site_id: Some(*site_id), + routes: vec![ + Route { + glob: Some(util::glob::Glob::parse("test-glob")?.into()), + priority: 0, + middlewares: vec![Middleware { + kind: Some(middleware::Kind::CustomHeaders( + CustomHeadersMiddleware { + headers: vec![custom_headers_middleware::Header { + name: "header-name".to_string(), + value: "header-value".to_string(), + }], + }, + )), + }], + }, + Route { + glob: Some(util::glob::Glob::parse("test-glob2")?.into()), + priority: 1, + middlewares: vec![Middleware { + kind: Some(middleware::Kind::CustomHeaders( + CustomHeadersMiddleware { + headers: vec![custom_headers_middleware::Header { + name: "header-name2".to_string(), + value: "header-value2".to_string(), + }], + }, + )), + }], + }, + ], + }) + }, + matchmaker: if let Some(config) = ctx.override_mm_config.clone() { + config.config + } else { + let build_res = op!([ctx] faker_build { + game_id: Some(*game_id), + image: faker::build::Image::MmLobbyAutoReady as i32, + }) + .await?; + let build_id = internal_unwrap!(build_res.build_id); - Some(backend::matchmaker::VersionConfig { - lobby_groups: ctx.override_lobby_groups.clone().map_or_else( - || { - vec![backend::matchmaker::LobbyGroup { + Some(backend::matchmaker::VersionConfig { + lobby_groups: ctx.override_lobby_groups.clone().map_or_else( + || { + vec![backend::matchmaker::LobbyGroup { name_id: "test-1".into(), regions: region_list_res @@ -82,13 +83,20 @@ async fn handle( .map(|region_id| backend::matchmaker::lobby_group::Region { region_id: Some(region_id), tier_name_id: util_mm::test::TIER_NAME_ID.to_owned(), - idle_lobbies: None, + idle_lobbies: Some(backend::matchmaker::lobby_group::IdleLobbies { + min_idle_lobbies: 0, + // Set a high max lobby count in case this is + // coming from a test that test mm-lobby-create + // without creating an associated player + max_idle_lobbies: 32, + }), }) .collect(), max_players_normal: 8, max_players_direct: 10, max_players_party: 12, + listable: true, runtime: Some( backend::matchmaker::lobby_runtime::Docker { @@ -102,40 +110,44 @@ async fn handle( } .into(), ), + + find_config: None, + join_config: None, + create_config: None, }] - }, - |v| v.lobby_groups, - ), - captcha: ctx - .override_captcha - .clone() - .map_or_else(|| None, |config| config.captcha_config), - }) - }, - kv: if let Some(config) = ctx.override_kv_config.clone() { - config.config - } else { - Some(backend::kv::VersionConfig {}) - }, - identity: if let Some(config) = ctx.override_identity_config.clone() { - config.config - } else { - Some(backend::identity::VersionConfig { - custom_display_names: vec![backend::identity::CustomDisplayName { - display_name: "Guest".to_string(), - }], - custom_avatars: Vec::new(), - }) - }, - module: if let Some(config) = ctx.override_module_config.clone() { - config.config - } else { - Some(backend::module::GameVersionConfig { - dependencies: Vec::new(), - }) - }, - } - }; + }, + |v| v.lobby_groups, + ), + captcha: ctx + .override_captcha + .clone() + .map_or_else(|| None, |config| config.captcha_config), + }) + }, + kv: if let Some(config) = ctx.override_kv_config.clone() { + config.config + } else { + Some(backend::kv::VersionConfig {}) + }, + identity: if let Some(config) = ctx.override_identity_config.clone() { + config.config + } else { + Some(backend::identity::VersionConfig { + custom_display_names: vec![backend::identity::CustomDisplayName { + display_name: "Guest".to_string(), + }], + custom_avatars: Vec::new(), + }) + }, + module: if let Some(config) = ctx.override_module_config.clone() { + config.config + } else { + Some(backend::module::GameVersionConfig { + dependencies: Vec::new(), + }) + }, + } + }; let version_create_res = op!([ctx] cloud_version_publish { game_id: Some(*game_id), diff --git a/svc/pkg/faker/ops/mm-lobby-row/Service.toml b/svc/pkg/faker/ops/mm-lobby-row/Service.toml index 08cd30484b..34c3861515 100644 --- a/svc/pkg/faker/ops/mm-lobby-row/Service.toml +++ b/svc/pkg/faker/ops/mm-lobby-row/Service.toml @@ -6,3 +6,7 @@ test-only = true kind = "rust" [operation] + +[databases] +db-mm-state = {} +redis-mm = {} diff --git a/svc/pkg/faker/ops/mm-lobby/src/lib.rs b/svc/pkg/faker/ops/mm-lobby/src/lib.rs index 5f66a919a0..53e07b961b 100644 --- a/svc/pkg/faker/ops/mm-lobby/src/lib.rs +++ b/svc/pkg/faker/ops/mm-lobby/src/lib.rs @@ -70,11 +70,18 @@ async fn handle( regions: vec![backend::matchmaker::lobby_group::Region { region_id: region_res.region_id, tier_name_id: util_mm::test::TIER_NAME_ID.to_owned(), - idle_lobbies: None, + idle_lobbies: Some(backend::matchmaker::lobby_group::IdleLobbies { + min_idle_lobbies: 0, + // Set a high max lobby count in case this is + // coming from a test that test mm-lobby-create + // without creating an associated player + max_idle_lobbies: 32, + }), }], max_players_normal, max_players_direct, max_players_party, + listable: true, runtime: Some(backend::matchmaker::lobby_runtime::Docker { build_id: build_res.build_id, @@ -83,6 +90,10 @@ async fn handle( network_mode: backend::matchmaker::lobby_runtime::NetworkMode::Bridge as i32, ports: Vec::new(), }.into()), + + find_config: None, + join_config: None, + create_config: None, }], }), ..Default::default() @@ -127,6 +138,11 @@ async fn handle( region_id: region_res.region_id, create_ray_id: Some(ctx.ray_id().into()), preemptively_created: false, + + creator_user_id: ctx.creator_user_id, + is_custom: ctx.is_custom, + publicity: ctx.publicity, + lobby_config_json: ctx.lobby_config_json.clone(), }) .await?; let run_id = internal_unwrap!(complete_msg.run_id).as_uuid(); diff --git a/svc/pkg/faker/ops/mm-player/src/lib.rs b/svc/pkg/faker/ops/mm-player/src/lib.rs index a28bc80dcf..b8402cea1f 100644 --- a/svc/pkg/faker/ops/mm-player/src/lib.rs +++ b/svc/pkg/faker/ops/mm-player/src/lib.rs @@ -44,7 +44,9 @@ async fn handle( // Find lobby let query_id = Uuid::new_v4(); - let find_res = msg!([ctx] @notrace mm::msg::lobby_find(namespace_id, query_id) -> Result { + let find_res = msg!([ctx] @notrace mm::msg::lobby_find(namespace_id, query_id) + -> Result + { namespace_id: ctx.namespace_id, query_id: Some(query_id.into()), join_kind: backend::matchmaker::query::JoinKind::Normal as i32, @@ -56,6 +58,7 @@ async fn handle( query: Some(mm::msg::lobby_find::message::Query::Direct(backend::matchmaker::query::Direct { lobby_id: ctx.lobby_id, })), + ..Default::default() }) .await?; @@ -79,6 +82,13 @@ async fn handle( RegionNotEnabled => panic_with!(MATCHMAKER_REGION_NOT_ENABLED_FOR_GAME_MODE), DevTeamInvalidStatus => panic_with!(GROUP_INVALID_DEVELOPER_STATUS), + + FindDisabled => panic_with!(MATCHMAKER_FIND_DISABLED), + JoinDisabled => panic_with!(MATCHMAKER_JOIN_DISABLED), + VerificationFailed => panic_with!(MATCHMAKER_VERIFICATION_FAILED), + VerificationRequestFailed => panic_with!(MATCHMAKER_VERIFICATION_REQUEST_FAILED), + IdentityRequired => panic_with!(MATCHMAKER_IDENTITY_REQUIRED), + RegistrationRequired => panic_with!(MATCHMAKER_REGISTRATION_REQUIRED), }; } Err(None) => internal_panic!("failed to parse find error code"), diff --git a/svc/pkg/faker/ops/region/Cargo.toml b/svc/pkg/faker/ops/region/Cargo.toml index 51d1ad74e2..8d867ec66c 100644 --- a/svc/pkg/faker/ops/region/Cargo.toml +++ b/svc/pkg/faker/ops/region/Cargo.toml @@ -14,7 +14,7 @@ region-get = { path = "../../../region/ops/get" } region-list = { path = "../../../region/ops/list" } [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/faker/types/mm-lobby.proto b/svc/pkg/faker/types/mm-lobby.proto index e1ce34743f..1fa2fbd6db 100644 --- a/svc/pkg/faker/types/mm-lobby.proto +++ b/svc/pkg/faker/types/mm-lobby.proto @@ -14,6 +14,11 @@ message Request { uint32 max_players_party = 3; bool skip_set_ready = 4; optional rivet.backend.pkg.faker.build.Image image = 5; + + optional rivet.common.Uuid creator_user_id = 8; + bool is_custom = 9; + optional rivet.backend.matchmaker.Lobby.Publicity publicity = 10; + optional string lobby_config_json = 11; } message Response { diff --git a/svc/pkg/game-user/ops/create/Cargo.toml b/svc/pkg/game-user/ops/create/Cargo.toml index 1bc747b181..6f51cbe6e9 100644 --- a/svc/pkg/game-user/ops/create/Cargo.toml +++ b/svc/pkg/game-user/ops/create/Cargo.toml @@ -15,7 +15,7 @@ util-game-user = { package = "rivet-util-game-user", path = "../../util" } token-create = { path = "../../../token/ops/create" } [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/game-user/ops/create/Service.toml b/svc/pkg/game-user/ops/create/Service.toml index cea7b33b52..b189dd3875 100644 --- a/svc/pkg/game-user/ops/create/Service.toml +++ b/svc/pkg/game-user/ops/create/Service.toml @@ -5,3 +5,6 @@ name = "game-user-create" kind = "rust" [operation] + +[databases] +db-game-user = {} diff --git a/svc/pkg/game-user/ops/get/Cargo.toml b/svc/pkg/game-user/ops/get/Cargo.toml index 7caeebcac5..b9e18a51f1 100644 --- a/svc/pkg/game-user/ops/get/Cargo.toml +++ b/svc/pkg/game-user/ops/get/Cargo.toml @@ -12,7 +12,7 @@ chrono = "0.4" prost = "0.10" [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/game-user/ops/get/Service.toml b/svc/pkg/game-user/ops/get/Service.toml index 43193758fb..02d65ae196 100644 --- a/svc/pkg/game-user/ops/get/Service.toml +++ b/svc/pkg/game-user/ops/get/Service.toml @@ -5,3 +5,6 @@ name = "game-user-get" kind = "rust" [operation] + +[databases] +db-game-user = {} diff --git a/svc/pkg/game-user/ops/link-create/Cargo.toml b/svc/pkg/game-user/ops/link-create/Cargo.toml index 2641a89814..6dc921d1bd 100644 --- a/svc/pkg/game-user/ops/link-create/Cargo.toml +++ b/svc/pkg/game-user/ops/link-create/Cargo.toml @@ -15,7 +15,7 @@ game-user-get = { path = "../get" } token-create = { path = "../../../token/ops/create" } [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/game-user/ops/link-create/Service.toml b/svc/pkg/game-user/ops/link-create/Service.toml index 82fa919652..fa2fa399d8 100644 --- a/svc/pkg/game-user/ops/link-create/Service.toml +++ b/svc/pkg/game-user/ops/link-create/Service.toml @@ -5,3 +5,6 @@ name = "game-user-link-create" kind = "rust" [operation] + +[databases] +db-game-user = {} diff --git a/svc/pkg/game-user/ops/link-get/Cargo.toml b/svc/pkg/game-user/ops/link-get/Cargo.toml index 27f3cac553..ac06ab5f1a 100644 --- a/svc/pkg/game-user/ops/link-get/Cargo.toml +++ b/svc/pkg/game-user/ops/link-get/Cargo.toml @@ -12,7 +12,7 @@ chrono = "0.4" prost = "0.10" [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/game-user/ops/link-get/Service.toml b/svc/pkg/game-user/ops/link-get/Service.toml index b828238bcf..89d0120797 100644 --- a/svc/pkg/game-user/ops/link-get/Service.toml +++ b/svc/pkg/game-user/ops/link-get/Service.toml @@ -5,3 +5,6 @@ name = "game-user-link-get" kind = "rust" [operation] + +[databases] +db-game-user = {} diff --git a/svc/pkg/game-user/ops/list-for-user/Cargo.toml b/svc/pkg/game-user/ops/list-for-user/Cargo.toml index f517494567..091a0886ee 100644 --- a/svc/pkg/game-user/ops/list-for-user/Cargo.toml +++ b/svc/pkg/game-user/ops/list-for-user/Cargo.toml @@ -12,7 +12,7 @@ chrono = "0.4" prost = "0.10" [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/game-user/ops/list-for-user/Service.toml b/svc/pkg/game-user/ops/list-for-user/Service.toml index d9955f5fd4..2cf10fc022 100644 --- a/svc/pkg/game-user/ops/list-for-user/Service.toml +++ b/svc/pkg/game-user/ops/list-for-user/Service.toml @@ -5,3 +5,6 @@ name = "game-user-list-for-user" kind = "rust" [operation] + +[databases] +db-game-user = {} diff --git a/svc/pkg/game-user/ops/recent-session-list/Cargo.toml b/svc/pkg/game-user/ops/recent-session-list/Cargo.toml index 7f43946381..ac365db3b5 100644 --- a/svc/pkg/game-user/ops/recent-session-list/Cargo.toml +++ b/svc/pkg/game-user/ops/recent-session-list/Cargo.toml @@ -12,7 +12,7 @@ chrono = "0.4" prost = "0.10" [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/game-user/ops/recent-session-list/Service.toml b/svc/pkg/game-user/ops/recent-session-list/Service.toml index fe7a274c39..59be6062bd 100644 --- a/svc/pkg/game-user/ops/recent-session-list/Service.toml +++ b/svc/pkg/game-user/ops/recent-session-list/Service.toml @@ -5,3 +5,6 @@ name = "game-user-recent-session-list" kind = "rust" [operation] + +[databases] +db-game-user = {} diff --git a/svc/pkg/game-user/ops/recommend/Service.toml b/svc/pkg/game-user/ops/recommend/Service.toml index ae7da96a06..df06fdc2e0 100644 --- a/svc/pkg/game-user/ops/recommend/Service.toml +++ b/svc/pkg/game-user/ops/recommend/Service.toml @@ -5,3 +5,6 @@ name = "game-user-recommend" kind = "rust" [operation] + +[databases] +db-game-user = {} diff --git a/svc/pkg/game-user/worker/Cargo.toml b/svc/pkg/game-user/worker/Cargo.toml index 7bb8d102a3..58c0914233 100644 --- a/svc/pkg/game-user/worker/Cargo.toml +++ b/svc/pkg/game-user/worker/Cargo.toml @@ -19,7 +19,7 @@ token-exchange = { path = "../../token/ops/exchange" } token-revoke = { path = "../../token/ops/revoke" } [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/game-user/worker/Service.toml b/svc/pkg/game-user/worker/Service.toml index 2815fcd4d5..fd65986596 100644 --- a/svc/pkg/game-user/worker/Service.toml +++ b/svc/pkg/game-user/worker/Service.toml @@ -5,3 +5,7 @@ name = "game-user-worker" kind = "rust" [consumer] + + +[databases] +db-game-user = {} diff --git a/svc/pkg/game-user/worker/src/workers/link_complete.rs b/svc/pkg/game-user/worker/src/workers/link_complete.rs index c985c266ed..9e902f281b 100644 --- a/svc/pkg/game-user/worker/src/workers/link_complete.rs +++ b/svc/pkg/game-user/worker/src/workers/link_complete.rs @@ -3,7 +3,9 @@ use proto::backend::pkg::*; use serde_json::json; #[worker(name = "game-user-link-complete")] -async fn worker(ctx: OperationContext) -> GlobalResult<()> { +async fn worker( + ctx: &OperationContext, +) -> GlobalResult<()> { let crdb = ctx.crdb("db-game-user").await?; let user_id = internal_unwrap!(ctx.user_id).as_uuid(); diff --git a/svc/pkg/game-user/worker/src/workers/session_create.rs b/svc/pkg/game-user/worker/src/workers/session_create.rs index fb4ffffa80..47ca0b21a4 100644 --- a/svc/pkg/game-user/worker/src/workers/session_create.rs +++ b/svc/pkg/game-user/worker/src/workers/session_create.rs @@ -3,7 +3,7 @@ use proto::backend::pkg::*; #[worker(name = "game-user-session-create")] async fn worker( - ctx: OperationContext, + ctx: &OperationContext, ) -> GlobalResult<()> { let crdb = ctx.crdb("db-game-user").await?; diff --git a/svc/pkg/game/ops/banner-upload-complete/Cargo.toml b/svc/pkg/game/ops/banner-upload-complete/Cargo.toml index 810390d9db..59078fd7c5 100644 --- a/svc/pkg/game/ops/banner-upload-complete/Cargo.toml +++ b/svc/pkg/game/ops/banner-upload-complete/Cargo.toml @@ -13,7 +13,7 @@ prost = "0.10" upload-complete = { path = "../../../upload/ops/complete" } [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/game/ops/banner-upload-complete/Service.toml b/svc/pkg/game/ops/banner-upload-complete/Service.toml index a8025b82a3..62c47f84df 100644 --- a/svc/pkg/game/ops/banner-upload-complete/Service.toml +++ b/svc/pkg/game/ops/banner-upload-complete/Service.toml @@ -5,3 +5,6 @@ name = "game-banner-upload-complete" kind = "rust" [operation] + +[databases] +db-game = {} diff --git a/svc/pkg/game/ops/create/Cargo.toml b/svc/pkg/game/ops/create/Cargo.toml index 3bd77072fa..e9560bd588 100644 --- a/svc/pkg/game/ops/create/Cargo.toml +++ b/svc/pkg/game/ops/create/Cargo.toml @@ -14,7 +14,7 @@ game-validate = { path = "../validate" } team-dev-get = { path = "../../../team-dev/ops/get" } [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/game/ops/create/Service.toml b/svc/pkg/game/ops/create/Service.toml index 270f08e546..8918fb2716 100644 --- a/svc/pkg/game/ops/create/Service.toml +++ b/svc/pkg/game/ops/create/Service.toml @@ -5,3 +5,6 @@ name = "game-create" kind = "rust" [operation] + +[databases] +db-game = {} diff --git a/svc/pkg/game/ops/get/Cargo.toml b/svc/pkg/game/ops/get/Cargo.toml index 95c61992f2..9411390013 100644 --- a/svc/pkg/game/ops/get/Cargo.toml +++ b/svc/pkg/game/ops/get/Cargo.toml @@ -14,7 +14,7 @@ upload-file-list = { path = "../../../upload/ops/file-list" } upload-get = { path = "../../../upload/ops/get" } [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/game/ops/get/Service.toml b/svc/pkg/game/ops/get/Service.toml index aa620e688a..cc526ae161 100644 --- a/svc/pkg/game/ops/get/Service.toml +++ b/svc/pkg/game/ops/get/Service.toml @@ -5,3 +5,6 @@ name = "game-get" kind = "rust" [operation] + +[databases] +db-game = {} diff --git a/svc/pkg/game/ops/get/src/lib.rs b/svc/pkg/game/ops/get/src/lib.rs index 08209ded0d..5d7932e8f2 100644 --- a/svc/pkg/game/ops/get/src/lib.rs +++ b/svc/pkg/game/ops/get/src/lib.rs @@ -79,7 +79,7 @@ async fn handle(ctx: OperationContext) -> GlobalResult::into); // Fetch all information relating to the logo image - let (logo_upload_complete_ts, logo_file_name) = { + let (logo_upload_complete_ts, logo_file_name, logo_provider) = { let upload = upload_res .uploads .iter() @@ -95,14 +95,14 @@ async fn handle(ctx: OperationContext) -> GlobalResult) -> GlobalResult) -> GlobalResult { - tracing::info!("lobby idle updated successfully"); + tracing::info!( + ?namespace_id, + "lobby idle updated successfully" + ); } Err(err) => { tracing::error!(?err, "failed to update idle lobbies"); diff --git a/svc/pkg/game/ops/recommend/Cargo.toml b/svc/pkg/game/ops/recommend/Cargo.toml index 6cafddf829..ea56c140ed 100644 --- a/svc/pkg/game/ops/recommend/Cargo.toml +++ b/svc/pkg/game/ops/recommend/Cargo.toml @@ -11,7 +11,7 @@ chirp-client = { path = "../../../../../lib/chirp/client" } prost = "0.10" [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/game/ops/recommend/Service.toml b/svc/pkg/game/ops/recommend/Service.toml index c37d267980..3609950de2 100644 --- a/svc/pkg/game/ops/recommend/Service.toml +++ b/svc/pkg/game/ops/recommend/Service.toml @@ -5,3 +5,6 @@ name = "game-recommend" kind = "rust" [operation] + +[databases] +db-game = {} diff --git a/svc/pkg/game/ops/resolve-name-id/Cargo.toml b/svc/pkg/game/ops/resolve-name-id/Cargo.toml index 1295e1eb25..14574a25f7 100644 --- a/svc/pkg/game/ops/resolve-name-id/Cargo.toml +++ b/svc/pkg/game/ops/resolve-name-id/Cargo.toml @@ -11,7 +11,7 @@ chirp-client = { path = "../../../../../lib/chirp/client" } prost = "0.10" [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/game/ops/resolve-name-id/Service.toml b/svc/pkg/game/ops/resolve-name-id/Service.toml index dbaecc6402..1e86d89ace 100644 --- a/svc/pkg/game/ops/resolve-name-id/Service.toml +++ b/svc/pkg/game/ops/resolve-name-id/Service.toml @@ -5,3 +5,6 @@ name = "game-resolve-name-id" kind = "rust" [operation] + +[databases] +db-game = {} diff --git a/svc/pkg/game/ops/resolve-namespace-id/Cargo.toml b/svc/pkg/game/ops/resolve-namespace-id/Cargo.toml index 8eb3d1f302..c6bfe53d79 100644 --- a/svc/pkg/game/ops/resolve-namespace-id/Cargo.toml +++ b/svc/pkg/game/ops/resolve-namespace-id/Cargo.toml @@ -11,7 +11,7 @@ chirp-client = { path = "../../../../../lib/chirp/client" } prost = "0.10" [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/game/ops/resolve-namespace-id/Service.toml b/svc/pkg/game/ops/resolve-namespace-id/Service.toml index f36e14fe65..12d7b8ebba 100644 --- a/svc/pkg/game/ops/resolve-namespace-id/Service.toml +++ b/svc/pkg/game/ops/resolve-namespace-id/Service.toml @@ -5,3 +5,6 @@ name = "game-resolve-namespace-id" kind = "rust" [operation] + +[databases] +db-game = {} diff --git a/svc/pkg/game/ops/version-create/Cargo.toml b/svc/pkg/game/ops/version-create/Cargo.toml index 27b5ae49d7..dfac123c99 100644 --- a/svc/pkg/game/ops/version-create/Cargo.toml +++ b/svc/pkg/game/ops/version-create/Cargo.toml @@ -14,7 +14,7 @@ game-version-get = { path = "../version-get" } game-version-list = { path = "../version-list" } [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/game/ops/version-create/Service.toml b/svc/pkg/game/ops/version-create/Service.toml index a7311a0f18..f9e77537f9 100644 --- a/svc/pkg/game/ops/version-create/Service.toml +++ b/svc/pkg/game/ops/version-create/Service.toml @@ -5,3 +5,6 @@ name = "game-version-create" kind = "rust" [operation] + +[databases] +db-game = {} diff --git a/svc/pkg/game/ops/version-get/Cargo.toml b/svc/pkg/game/ops/version-get/Cargo.toml index 3abae2834b..612bab18b0 100644 --- a/svc/pkg/game/ops/version-get/Cargo.toml +++ b/svc/pkg/game/ops/version-get/Cargo.toml @@ -11,7 +11,7 @@ chirp-client = { path = "../../../../../lib/chirp/client" } prost = "0.10" [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/game/ops/version-get/Service.toml b/svc/pkg/game/ops/version-get/Service.toml index f31b1578f2..48486e3dd9 100644 --- a/svc/pkg/game/ops/version-get/Service.toml +++ b/svc/pkg/game/ops/version-get/Service.toml @@ -5,3 +5,6 @@ name = "game-version-get" kind = "rust" [operation] + +[databases] +db-game = {} diff --git a/svc/pkg/game/ops/version-list/Cargo.toml b/svc/pkg/game/ops/version-list/Cargo.toml index d2a257d93a..dc3d9c4563 100644 --- a/svc/pkg/game/ops/version-list/Cargo.toml +++ b/svc/pkg/game/ops/version-list/Cargo.toml @@ -11,7 +11,7 @@ chirp-client = { path = "../../../../../lib/chirp/client" } prost = "0.10" [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/game/ops/version-list/Service.toml b/svc/pkg/game/ops/version-list/Service.toml index 283f37d8d4..db9b6bed33 100644 --- a/svc/pkg/game/ops/version-list/Service.toml +++ b/svc/pkg/game/ops/version-list/Service.toml @@ -5,3 +5,6 @@ name = "game-version-list" kind = "rust" [operation] + +[databases] +db-game = {} diff --git a/svc/pkg/game/ops/version-validate/Cargo.toml b/svc/pkg/game/ops/version-validate/Cargo.toml index b934339ba0..fe99260561 100644 --- a/svc/pkg/game/ops/version-validate/Cargo.toml +++ b/svc/pkg/game/ops/version-validate/Cargo.toml @@ -11,6 +11,7 @@ rivet-operation = { path = "../../../../../lib/operation/core" } prost = "0.10" util-mm = { package = "rivet-util-mm", path = "../../../mm/util" } +external-request-validate = { path = "../../../external/ops/request-validate"} game-version-get = { path = "../version-get" } game-version-list = { path = "../version-list" } module-version-get = { path = "../../../module/ops/version-get" } diff --git a/svc/pkg/game/ops/version-validate/src/lib.rs b/svc/pkg/game/ops/version-validate/src/lib.rs index 001c251b0e..cc19ee352a 100644 --- a/svc/pkg/game/ops/version-validate/src/lib.rs +++ b/svc/pkg/game/ops/version-validate/src/lib.rs @@ -79,7 +79,7 @@ async fn handle( } if cdn.routes.len() > 32 { - errors.push(util::err_path!["config", "cdn", "routes-meta", "too-many",]); + errors.push(util::err_path!["config", "cdn", "routes-meta", "too-many"]); } let mut unique_globs = HashSet::::new(); @@ -976,6 +976,68 @@ async fn handle( "no-runtime", ]); } + + // Validate find config + if let Some(matchmaker::FindConfig { + verification_config: Some(verification_config), + .. + }) = &lobby_group.find_config + { + let validation_res = op!([ctx] external_request_validate { + config: Some(backend::net::ExternalRequestConfig { + url: verification_config.url.clone(), + headers: verification_config.headers.clone(), + ..Default::default() + }), + }) + .await?; + + // Append errors from external request validation + errors.extend(validation_res.errors.iter().map(|err| { + util::err_path![ + "config", + "matchmaker", + "game-modes", + lobby_group_label, + "find-config", + "verification-config" + ] + .into_iter() + .chain(err.path.clone()) + .collect::>() + })); + } + + // Validate join config + if let Some(matchmaker::JoinConfig { + verification_config: Some(verification_config), + .. + }) = &lobby_group.join_config + { + let validation_res = op!([ctx] external_request_validate { + config: Some(backend::net::ExternalRequestConfig { + url: verification_config.url.clone(), + headers: verification_config.headers.clone(), + ..Default::default() + }), + }) + .await?; + + // Append errors from external request validation + errors.extend(validation_res.errors.iter().map(|err| { + util::err_path![ + "config", + "matchmaker", + "game-modes", + lobby_group_label, + "join-config", + "verification-config" + ] + .into_iter() + .chain(err.path.clone()) + .collect::>() + })); + } } } diff --git a/svc/pkg/game/ops/version-validate/tests/integration.rs b/svc/pkg/game/ops/version-validate/tests/integration.rs index 5ad4243c33..4309e00c76 100644 --- a/svc/pkg/game/ops/version-validate/tests/integration.rs +++ b/svc/pkg/game/ops/version-validate/tests/integration.rs @@ -52,6 +52,8 @@ async fn empty(ctx: TestCtx) { max_players_normal: 33, max_players_direct: 0, max_players_party: 16, + listable: true, + runtime: Some(matchmaker::LobbyRuntime { runtime: Some(matchmaker::lobby_runtime::Runtime::Docker( matchmaker::lobby_runtime::Docker { @@ -127,6 +129,10 @@ async fn empty(ctx: TestCtx) { }, )), }), + + find_config: None, + join_config: None, + create_config: None, }, matchmaker::LobbyGroup { name_id: "name".to_owned(), @@ -138,6 +144,8 @@ async fn empty(ctx: TestCtx) { max_players_normal: 33, max_players_direct: 0, max_players_party: 16, + listable: true, + runtime: Some(matchmaker::LobbyRuntime { runtime: Some(matchmaker::lobby_runtime::Runtime::Docker( matchmaker::lobby_runtime::Docker { @@ -150,6 +158,10 @@ async fn empty(ctx: TestCtx) { }, )), }), + + find_config: None, + join_config: None, + create_config: None, }, ], captcha: Some(backend::captcha::CaptchaConfig { diff --git a/svc/pkg/identity-config/ops/namespace-create/Cargo.toml b/svc/pkg/identity-config/ops/namespace-create/Cargo.toml index c99f4a7d4e..16f36fc6bf 100644 --- a/svc/pkg/identity-config/ops/namespace-create/Cargo.toml +++ b/svc/pkg/identity-config/ops/namespace-create/Cargo.toml @@ -11,7 +11,7 @@ chirp-client = { path = "../../../../../lib/chirp/client" } prost = "0.10" [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/identity-config/ops/namespace-create/Service.toml b/svc/pkg/identity-config/ops/namespace-create/Service.toml index ce6f90609a..ad025e88f1 100644 --- a/svc/pkg/identity-config/ops/namespace-create/Service.toml +++ b/svc/pkg/identity-config/ops/namespace-create/Service.toml @@ -5,3 +5,6 @@ name = "identity-config-namespace-create" kind = "rust" [operation] + +[databases] +db-identity-config = {} diff --git a/svc/pkg/identity-config/ops/namespace-get/Cargo.toml b/svc/pkg/identity-config/ops/namespace-get/Cargo.toml index 271a92c8b7..9e10d10335 100644 --- a/svc/pkg/identity-config/ops/namespace-get/Cargo.toml +++ b/svc/pkg/identity-config/ops/namespace-get/Cargo.toml @@ -11,7 +11,7 @@ chirp-client = { path = "../../../../../lib/chirp/client" } prost = "0.10" [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/identity-config/ops/namespace-get/Service.toml b/svc/pkg/identity-config/ops/namespace-get/Service.toml index f6606ad23b..c9f8eff125 100644 --- a/svc/pkg/identity-config/ops/namespace-get/Service.toml +++ b/svc/pkg/identity-config/ops/namespace-get/Service.toml @@ -5,3 +5,6 @@ name = "identity-config-namespace-get" kind = "rust" [operation] + +[databases] +db-identity-config = {} diff --git a/svc/pkg/identity-config/ops/version-get/Cargo.toml b/svc/pkg/identity-config/ops/version-get/Cargo.toml index 27b839bbe6..5806f2419a 100644 --- a/svc/pkg/identity-config/ops/version-get/Cargo.toml +++ b/svc/pkg/identity-config/ops/version-get/Cargo.toml @@ -11,7 +11,7 @@ chirp-client = { path = "../../../../../lib/chirp/client" } prost = "0.10" [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/identity-config/ops/version-get/Service.toml b/svc/pkg/identity-config/ops/version-get/Service.toml index c5f692ca3d..a7ad9eb5b2 100644 --- a/svc/pkg/identity-config/ops/version-get/Service.toml +++ b/svc/pkg/identity-config/ops/version-get/Service.toml @@ -5,3 +5,6 @@ name = "identity-config-version-get" kind = "rust" [operation] + +[databases] +db-identity-config = {} diff --git a/svc/pkg/identity-config/ops/version-publish/Cargo.toml b/svc/pkg/identity-config/ops/version-publish/Cargo.toml index 3144022677..11d21644b0 100644 --- a/svc/pkg/identity-config/ops/version-publish/Cargo.toml +++ b/svc/pkg/identity-config/ops/version-publish/Cargo.toml @@ -11,7 +11,7 @@ chirp-client = { path = "../../../../../lib/chirp/client" } prost = "0.10" [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/identity-config/ops/version-publish/Service.toml b/svc/pkg/identity-config/ops/version-publish/Service.toml index 2079d579cf..abf5b5b3a5 100644 --- a/svc/pkg/identity-config/ops/version-publish/Service.toml +++ b/svc/pkg/identity-config/ops/version-publish/Service.toml @@ -5,3 +5,6 @@ name = "identity-config-version-publish" kind = "rust" [operation] + +[databases] +db-identity-config = {} diff --git a/svc/pkg/ip/ops/info/Cargo.toml b/svc/pkg/ip/ops/info/Cargo.toml index 2d46bec7bc..6a4d648e25 100644 --- a/svc/pkg/ip/ops/info/Cargo.toml +++ b/svc/pkg/ip/ops/info/Cargo.toml @@ -15,7 +15,7 @@ serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/ip/ops/info/Service.toml b/svc/pkg/ip/ops/info/Service.toml index 0bca82308b..8617e1695a 100644 --- a/svc/pkg/ip/ops/info/Service.toml +++ b/svc/pkg/ip/ops/info/Service.toml @@ -5,3 +5,6 @@ name = "ip-info" kind = "rust" [operation] + +[databases] +db-ip-info = {} diff --git a/svc/pkg/job-run/ops/get/Cargo.toml b/svc/pkg/job-run/ops/get/Cargo.toml index dfe7e9e405..8f17d2dc9b 100644 --- a/svc/pkg/job-run/ops/get/Cargo.toml +++ b/svc/pkg/job-run/ops/get/Cargo.toml @@ -14,7 +14,7 @@ nomad-client = "0.0.9" util-job = { package = "rivet-util-job", path = "../../../job/util" } [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/job-run/ops/get/Service.toml b/svc/pkg/job-run/ops/get/Service.toml index 5c8ac1b830..c174a2ae35 100644 --- a/svc/pkg/job-run/ops/get/Service.toml +++ b/svc/pkg/job-run/ops/get/Service.toml @@ -5,3 +5,6 @@ name = "job-run-get" kind = "rust" [operation] + +[databases] +db-job-state = {} diff --git a/svc/pkg/job-run/standalone/alloc-plan-monitor/Cargo.toml b/svc/pkg/job-run/standalone/alloc-plan-monitor/Cargo.toml index abb4b417b4..b664f524e3 100644 --- a/svc/pkg/job-run/standalone/alloc-plan-monitor/Cargo.toml +++ b/svc/pkg/job-run/standalone/alloc-plan-monitor/Cargo.toml @@ -21,7 +21,7 @@ rivet-pools = { path = "../../../../../lib/pools" } rivet-runtime = { path = "../../../../../lib/runtime" } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" -tokio = { version = "1.21", features = ["full"] } +tokio = { version = "1.29", features = ["full"] } tracing = "0.1" tracing-subscriber = { version = "0.3", default-features = false, features = ["fmt", "json", "ansi"] } util-job = { package = "rivet-util-job", path = "../../../job/util" } diff --git a/svc/pkg/job-run/standalone/alloc-plan-monitor/Service.toml b/svc/pkg/job-run/standalone/alloc-plan-monitor/Service.toml index 3e0b565653..69688ebd02 100644 --- a/svc/pkg/job-run/standalone/alloc-plan-monitor/Service.toml +++ b/svc/pkg/job-run/standalone/alloc-plan-monitor/Service.toml @@ -9,3 +9,5 @@ kind = "rust" [headless] singleton = true +[databases] +redis-job = {} diff --git a/svc/pkg/job-run/standalone/alloc-update-monitor/Cargo.toml b/svc/pkg/job-run/standalone/alloc-update-monitor/Cargo.toml index 770cd4a191..067b4db479 100644 --- a/svc/pkg/job-run/standalone/alloc-update-monitor/Cargo.toml +++ b/svc/pkg/job-run/standalone/alloc-update-monitor/Cargo.toml @@ -21,13 +21,13 @@ rivet-pools = { path = "../../../../../lib/pools" } rivet-runtime = { path = "../../../../../lib/runtime" } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" -tokio = { version = "1.21", features = ["full"] } +tokio = { version = "1.29", features = ["full"] } tracing = "0.1" tracing-subscriber = { version = "0.3", default-features = false, features = ["fmt", "json", "ansi"] } util-job = { package = "rivet-util-job", path = "../../../job/util" } [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/job-run/standalone/alloc-update-monitor/Service.toml b/svc/pkg/job-run/standalone/alloc-update-monitor/Service.toml index 3a70d12f29..d41d306163 100644 --- a/svc/pkg/job-run/standalone/alloc-update-monitor/Service.toml +++ b/svc/pkg/job-run/standalone/alloc-update-monitor/Service.toml @@ -9,3 +9,5 @@ kind = "rust" [headless] singleton = true +[databases] +redis-job = {} diff --git a/svc/pkg/job-run/standalone/eval-update-monitor/Cargo.toml b/svc/pkg/job-run/standalone/eval-update-monitor/Cargo.toml index fd067b76cd..8e48c64371 100644 --- a/svc/pkg/job-run/standalone/eval-update-monitor/Cargo.toml +++ b/svc/pkg/job-run/standalone/eval-update-monitor/Cargo.toml @@ -22,13 +22,13 @@ rivet-pools = { path = "../../../../../lib/pools" } rivet-runtime = { path = "../../../../../lib/runtime" } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" -tokio = { version = "1.21", features = ["full"] } +tokio = { version = "1.29", features = ["full"] } tracing = "0.1" tracing-subscriber = { version = "0.3", default-features = false, features = ["fmt", "json", "ansi"] } util-job = { package = "rivet-util-job", path = "../../../job/util" } [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false diff --git a/svc/pkg/job-run/standalone/eval-update-monitor/Service.toml b/svc/pkg/job-run/standalone/eval-update-monitor/Service.toml index 9b3b6fd49b..d884ff0eb9 100644 --- a/svc/pkg/job-run/standalone/eval-update-monitor/Service.toml +++ b/svc/pkg/job-run/standalone/eval-update-monitor/Service.toml @@ -9,3 +9,5 @@ kind = "rust" [headless] singleton = true +[databases] +redis-job = {} diff --git a/svc/pkg/job-run/worker/Cargo.toml b/svc/pkg/job-run/worker/Cargo.toml index 2446d476ea..8ddf0edd90 100644 --- a/svc/pkg/job-run/worker/Cargo.toml +++ b/svc/pkg/job-run/worker/Cargo.toml @@ -27,7 +27,7 @@ region-get = { path = "../../region/ops/get" } token-create = { path = "../../token/ops/create" } [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/job-run/worker/Service.toml b/svc/pkg/job-run/worker/Service.toml index 54486e8e4c..547bbd8b89 100644 --- a/svc/pkg/job-run/worker/Service.toml +++ b/svc/pkg/job-run/worker/Service.toml @@ -6,3 +6,6 @@ kind = "rust" [consumer] +[databases] +db-job-state = {} +redis-job = {} diff --git a/svc/pkg/job-run/worker/src/workers/cleanup.rs b/svc/pkg/job-run/worker/src/workers/cleanup.rs index 1b6344392b..a521a70325 100644 --- a/svc/pkg/job-run/worker/src/workers/cleanup.rs +++ b/svc/pkg/job-run/worker/src/workers/cleanup.rs @@ -16,7 +16,7 @@ struct RunMetaNomadRow { } #[worker(name = "job-run-cleanup")] -async fn worker(ctx: OperationContext) -> GlobalResult<()> { +async fn worker(ctx: &OperationContext) -> GlobalResult<()> { // NOTE: Idempotent let crdb = ctx.crdb("db-job-state").await?; @@ -24,7 +24,8 @@ async fn worker(ctx: OperationContext) -> Global let run_id = internal_unwrap!(ctx.run_id).as_uuid(); let Some((run_row, run_meta_nomad_row)) = - rivet_pools::utils::crdb::tx(&crdb, |tx| Box::pin(update_db(ctx.ts(), run_id, tx))).await? else { + rivet_pools::utils::crdb::tx(&crdb, |tx| Box::pin(update_db(ctx.ts(), run_id, tx))).await? + else { if ctx.req_dt() > util::duration::minutes(5) { tracing::error!("discarding stale message"); return Ok(()); @@ -73,7 +74,7 @@ async fn update_db( " )) .bind(run_id) - .fetch_optional(&mut *tx) + .fetch_optional(&mut **tx) .await?; tracing::info!(?run_row, "run row"); @@ -90,7 +91,7 @@ async fn update_db( " )) .bind(run_id) - .fetch_optional(&mut *tx) + .fetch_optional(&mut **tx) .await?; tracing::info!(?run_meta_nomad_row, "run meta row"); @@ -116,7 +117,7 @@ async fn update_db( sqlx::query("UPDATE runs SET cleanup_ts = $2 WHERE run_id = $1") .bind(run_id) .bind(now) - .execute(&mut *tx) + .execute(&mut **tx) .await?; } diff --git a/svc/pkg/job-run/worker/src/workers/create/mod.rs b/svc/pkg/job-run/worker/src/workers/create/mod.rs index 3ac69cc066..0a3da93060 100644 --- a/svc/pkg/job-run/worker/src/workers/create/mod.rs +++ b/svc/pkg/job-run/worker/src/workers/create/mod.rs @@ -33,7 +33,7 @@ async fn fail( } #[worker(name = "job-run-create")] -async fn worker(ctx: OperationContext) -> GlobalResult<()> { +async fn worker(ctx: &OperationContext) -> GlobalResult<()> { let crdb = ctx.crdb("db-job-state").await?; let run_id = internal_unwrap!(ctx.run_id).as_uuid(); @@ -238,12 +238,12 @@ async fn write_to_db_before_run( .bind(region_id) .bind(ts) .bind(token_session_id) - .execute(&mut *tx) + .execute(&mut **tx) .await?; sqlx::query(indoc!("INSERT INTO run_meta_nomad (run_id) VALUES ($1)")) .bind(run_id) - .execute(&mut *tx) + .execute(&mut **tx) .await?; // Validate that the proxied ports point to existing ports @@ -289,7 +289,7 @@ async fn write_to_db_before_run( .bind(ingress_hostnames_sorted.join(",")) .bind(proxied_port.proxy_protocol) .bind(proxied_port.ssl_domain_mode) - .execute(&mut *tx) + .execute(&mut **tx) .await?; } diff --git a/svc/pkg/job-run/worker/src/workers/nomad_monitor_alloc_plan.rs b/svc/pkg/job-run/worker/src/workers/nomad_monitor_alloc_plan.rs index 461c4ae902..885aefed64 100644 --- a/svc/pkg/job-run/worker/src/workers/nomad_monitor_alloc_plan.rs +++ b/svc/pkg/job-run/worker/src/workers/nomad_monitor_alloc_plan.rs @@ -27,7 +27,7 @@ struct ProxiedPort { #[worker(name = "job-run-nomad-monitor-alloc-plan")] async fn worker( - ctx: OperationContext, + ctx: &OperationContext, ) -> GlobalResult<()> { let crdb = ctx.crdb("db-job-state").await?; let mut redis_job = ctx.redis_job().await?; @@ -105,7 +105,8 @@ async fn worker( run_id, region_id, proxied_ports, - }) = db_output else { + }) = db_output + else { if ctx.req_dt() > util::duration::minutes(5) { tracing::error!("discarding stale message"); return Ok(()); @@ -199,7 +200,7 @@ async fn update_db( " )) .bind(&job_id) - .fetch_optional(&mut *tx) + .fetch_optional(&mut **tx) .await?; // Check if run found @@ -225,7 +226,7 @@ async fn update_db( .bind(&alloc_id) .bind(now) .bind(&nomad_node_id) - .execute(&mut *tx) + .execute(&mut **tx) .await?; // Save the ports to the db @@ -240,7 +241,7 @@ async fn update_db( .bind(run_id) .bind(&network.mode) .bind(&network.ip) - .execute(&mut *tx) + .execute(&mut **tx) .await?; } @@ -258,7 +259,7 @@ async fn update_db( .bind(port.source as i64) .bind(port.target as i64) .bind(&port.ip) - .execute(&mut *tx) + .execute(&mut **tx) .await?; } } @@ -272,7 +273,7 @@ async fn update_db( " )) .bind(run_id) - .fetch_all(&mut *tx) + .fetch_all(&mut **tx) .await?; tracing::info!(?proxied_ports, "fetched proxied ports"); diff --git a/svc/pkg/job-run/worker/src/workers/nomad_monitor_alloc_update.rs b/svc/pkg/job-run/worker/src/workers/nomad_monitor_alloc_update.rs index 52e628f102..670b070b03 100644 --- a/svc/pkg/job-run/worker/src/workers/nomad_monitor_alloc_update.rs +++ b/svc/pkg/job-run/worker/src/workers/nomad_monitor_alloc_update.rs @@ -17,7 +17,7 @@ enum TaskState { #[worker(name = "job-run-nomad-monitor-alloc-update")] async fn worker( - ctx: OperationContext, + ctx: &OperationContext, ) -> GlobalResult<()> { let crdb = ctx.crdb("db-job-state").await?; diff --git a/svc/pkg/job-run/worker/src/workers/nomad_monitor_eval_update.rs b/svc/pkg/job-run/worker/src/workers/nomad_monitor_eval_update.rs index 48fccbd2f1..22c7141b79 100644 --- a/svc/pkg/job-run/worker/src/workers/nomad_monitor_eval_update.rs +++ b/svc/pkg/job-run/worker/src/workers/nomad_monitor_eval_update.rs @@ -28,7 +28,7 @@ struct RunRow { #[worker(name = "job-run-nomad-monitor-eval-update")] async fn worker( - ctx: OperationContext, + ctx: &OperationContext, ) -> GlobalResult<()> { let crdb = ctx.crdb("db-job-state").await?; diff --git a/svc/pkg/job-run/worker/src/workers/stop.rs b/svc/pkg/job-run/worker/src/workers/stop.rs index 764454c076..d4d5f80c75 100644 --- a/svc/pkg/job-run/worker/src/workers/stop.rs +++ b/svc/pkg/job-run/worker/src/workers/stop.rs @@ -19,7 +19,7 @@ struct RunMetaNomadRow { } #[worker(name = "job-run-stop")] -async fn worker(ctx: OperationContext) -> GlobalResult<()> { +async fn worker(ctx: &OperationContext) -> GlobalResult<()> { // NOTE: Idempotent let crdb = ctx.crdb("db-job-state").await?; @@ -36,7 +36,8 @@ async fn worker(ctx: OperationContext) -> GlobalRes .await?; let Some((run_row, run_meta_nomad_row)) = - rivet_pools::utils::crdb::tx(&crdb, |tx| Box::pin(update_db(ctx.ts(), run_id, tx))).await? else { + rivet_pools::utils::crdb::tx(&crdb, |tx| Box::pin(update_db(ctx.ts(), run_id, tx))).await? + else { if ctx.req_dt() > util::duration::minutes(5) { tracing::error!("discarding stale message"); return Ok(()); @@ -99,7 +100,7 @@ async fn update_db( " )) .bind(run_id) - .fetch_optional(&mut *tx) + .fetch_optional(&mut **tx) .await?; tracing::info!(?run_row, "fetched run"); @@ -116,7 +117,7 @@ async fn update_db( " )) .bind(run_id) - .fetch_optional(&mut *tx) + .fetch_optional(&mut **tx) .await?; tracing::info!(?run_meta_nomad_row, "fetched run meta nomad"); @@ -143,7 +144,7 @@ async fn update_db( sqlx::query("UPDATE runs SET stop_ts = $2 WHERE run_id = $1") .bind(run_id) .bind(now) - .execute(&mut *tx) + .execute(&mut **tx) .await?; } diff --git a/svc/pkg/job/standalone/gc/Cargo.toml b/svc/pkg/job/standalone/gc/Cargo.toml index 08c104429d..1b258c00b9 100644 --- a/svc/pkg/job/standalone/gc/Cargo.toml +++ b/svc/pkg/job/standalone/gc/Cargo.toml @@ -21,20 +21,19 @@ rivet-operation = { path = "../../../../../lib/operation/core" } rivet-pools = { path = "../../../../../lib/pools" } rivet-runtime = { path = "../../../../../lib/runtime" } serde_json = "1.0" -tokio = { version = "1.21", features = ["full"] } +tokio = { version = "1.29", features = ["full"] } tracing = "0.1" tracing-subscriber = { version = "0.3", default-features = false, features = ["fmt", "json", "ansi"] } uuid = { version = "1", features = ["serde"] } [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false features = [ - "runtime-tokio-native-tls", + "runtime-tokio", "postgres", "uuid", "json", - "tls", "macros", ] diff --git a/svc/pkg/job/standalone/gc/Service.toml b/svc/pkg/job/standalone/gc/Service.toml index 15d3e69b01..f85ad5fca6 100644 --- a/svc/pkg/job/standalone/gc/Service.toml +++ b/svc/pkg/job/standalone/gc/Service.toml @@ -7,3 +7,5 @@ kind = "rust" [headless] singleton = true +[databases] +db-job-state = {} diff --git a/svc/pkg/kv-config/ops/namespace-create/Cargo.toml b/svc/pkg/kv-config/ops/namespace-create/Cargo.toml index 75442b79c5..be592fb6bb 100644 --- a/svc/pkg/kv-config/ops/namespace-create/Cargo.toml +++ b/svc/pkg/kv-config/ops/namespace-create/Cargo.toml @@ -11,7 +11,7 @@ chirp-client = { path = "../../../../../lib/chirp/client" } prost = "0.10" [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/kv-config/ops/namespace-create/Service.toml b/svc/pkg/kv-config/ops/namespace-create/Service.toml index 4b658ca7c3..f957238a0b 100644 --- a/svc/pkg/kv-config/ops/namespace-create/Service.toml +++ b/svc/pkg/kv-config/ops/namespace-create/Service.toml @@ -5,3 +5,6 @@ name = "kv-config-namespace-create" kind = "rust" [operation] + +[databases] +db-kv-config = {} diff --git a/svc/pkg/kv-config/ops/namespace-get/Cargo.toml b/svc/pkg/kv-config/ops/namespace-get/Cargo.toml index f7b7d6a4fa..7e1d404d9a 100644 --- a/svc/pkg/kv-config/ops/namespace-get/Cargo.toml +++ b/svc/pkg/kv-config/ops/namespace-get/Cargo.toml @@ -11,7 +11,7 @@ chirp-client = { path = "../../../../../lib/chirp/client" } prost = "0.10" [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/kv-config/ops/namespace-get/Service.toml b/svc/pkg/kv-config/ops/namespace-get/Service.toml index 3bf4e2afd8..277244ddde 100644 --- a/svc/pkg/kv-config/ops/namespace-get/Service.toml +++ b/svc/pkg/kv-config/ops/namespace-get/Service.toml @@ -5,3 +5,6 @@ name = "kv-config-namespace-get" kind = "rust" [operation] + +[databases] +db-kv-config = {} diff --git a/svc/pkg/kv-config/ops/version-get/Cargo.toml b/svc/pkg/kv-config/ops/version-get/Cargo.toml index a090067124..7a222e0cf6 100644 --- a/svc/pkg/kv-config/ops/version-get/Cargo.toml +++ b/svc/pkg/kv-config/ops/version-get/Cargo.toml @@ -11,7 +11,7 @@ chirp-client = { path = "../../../../../lib/chirp/client" } prost = "0.10" [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/kv-config/ops/version-get/Service.toml b/svc/pkg/kv-config/ops/version-get/Service.toml index 8fbb7e5fd3..b907deb201 100644 --- a/svc/pkg/kv-config/ops/version-get/Service.toml +++ b/svc/pkg/kv-config/ops/version-get/Service.toml @@ -5,3 +5,6 @@ name = "kv-config-version-get" kind = "rust" [operation] + +[databases] +db-kv-config = {} diff --git a/svc/pkg/kv-config/ops/version-publish/Cargo.toml b/svc/pkg/kv-config/ops/version-publish/Cargo.toml index bb410d8fda..ea9a969853 100644 --- a/svc/pkg/kv-config/ops/version-publish/Cargo.toml +++ b/svc/pkg/kv-config/ops/version-publish/Cargo.toml @@ -11,7 +11,7 @@ chirp-client = { path = "../../../../../lib/chirp/client" } prost = "0.10" [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/kv-config/ops/version-publish/Service.toml b/svc/pkg/kv-config/ops/version-publish/Service.toml index 8523d2ce35..8cb5d45863 100644 --- a/svc/pkg/kv-config/ops/version-publish/Service.toml +++ b/svc/pkg/kv-config/ops/version-publish/Service.toml @@ -5,3 +5,6 @@ name = "kv-config-version-publish" kind = "rust" [operation] + +[databases] +db-kv-config = {} diff --git a/svc/pkg/kv/ops/get/Cargo.toml b/svc/pkg/kv/ops/get/Cargo.toml index d0c0712946..a82289ad81 100644 --- a/svc/pkg/kv/ops/get/Cargo.toml +++ b/svc/pkg/kv/ops/get/Cargo.toml @@ -11,7 +11,7 @@ chirp-client = { path = "../../../../../lib/chirp/client" } prost = "0.10" [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/kv/ops/get/Service.toml b/svc/pkg/kv/ops/get/Service.toml index 4f984ee1c7..7c2cb9d917 100644 --- a/svc/pkg/kv/ops/get/Service.toml +++ b/svc/pkg/kv/ops/get/Service.toml @@ -5,3 +5,6 @@ name = "kv-get" kind = "rust" [operation] + +[databases] +db-kv = {} diff --git a/svc/pkg/kv/ops/list/Service.toml b/svc/pkg/kv/ops/list/Service.toml index 559f2af224..2ab8a6336d 100644 --- a/svc/pkg/kv/ops/list/Service.toml +++ b/svc/pkg/kv/ops/list/Service.toml @@ -5,3 +5,6 @@ name = "kv-list" kind = "rust" [operation] + +[databases] +db-kv = {} diff --git a/svc/pkg/kv/worker/Service.toml b/svc/pkg/kv/worker/Service.toml index fe3149cfad..0722da274e 100644 --- a/svc/pkg/kv/worker/Service.toml +++ b/svc/pkg/kv/worker/Service.toml @@ -5,3 +5,6 @@ name = "kv-worker" kind = "rust" [consumer] + +[databases] +db-kv = {} diff --git a/svc/pkg/kv/worker/src/workers/write.rs b/svc/pkg/kv/worker/src/workers/write.rs index f51d448609..754110bbdd 100644 --- a/svc/pkg/kv/worker/src/workers/write.rs +++ b/svc/pkg/kv/worker/src/workers/write.rs @@ -2,7 +2,7 @@ use chirp_worker::prelude::*; use proto::backend::pkg::*; #[worker(name = "kv-write")] -async fn worker(ctx: OperationContext) -> GlobalResult<()> { +async fn worker(ctx: &OperationContext) -> GlobalResult<()> { let crdb = ctx.crdb("db-kv").await?; let namespace_id = internal_unwrap!(ctx.namespace_id).as_uuid(); diff --git a/svc/pkg/misc/db/redis-search/Service.toml b/svc/pkg/misc/db/redis-search/Service.toml deleted file mode 100644 index 38f72eb893..0000000000 --- a/svc/pkg/misc/db/redis-search/Service.toml +++ /dev/null @@ -1,10 +0,0 @@ -[service] -name = "redis-search" - -[runtime] -kind = "redis" -index = 7 -persistent = true - -[cache] - diff --git a/svc/pkg/misc/standalone/playground/Cargo.toml b/svc/pkg/misc/standalone/playground/Cargo.toml index d88cb3051e..9e66ff40f4 100644 --- a/svc/pkg/misc/standalone/playground/Cargo.toml +++ b/svc/pkg/misc/standalone/playground/Cargo.toml @@ -24,7 +24,7 @@ rivet-pools = { path = "../../../../../lib/pools" } s3-util = { path = "../../../../../lib/s3-util" } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" -tokio = { version = "1.21", features = ["full"] } +tokio = { version = "1.29", features = ["full"] } tracing = "0.1" tracing-subscriber = { version = "0.3", default-features = false, features = ["fmt", "json", "ansi"] } util-mm = { package = "rivet-util-mm", path = "../../../mm/util" } @@ -42,14 +42,13 @@ region-list = { path = "../../../region/ops/list" } upload-complete = { path = "../../../upload/ops/complete" } [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false features = [ - "runtime-tokio-native-tls", + "runtime-tokio", "postgres", "uuid", "json", - "tls", ] [dev-dependencies] diff --git a/svc/pkg/misc/standalone/playground/Service.toml b/svc/pkg/misc/standalone/playground/Service.toml index 20b9a37831..20cf841218 100644 --- a/svc/pkg/misc/standalone/playground/Service.toml +++ b/svc/pkg/misc/standalone/playground/Service.toml @@ -7,3 +7,6 @@ kind = "rust" [oneshot] +[databases] +db-team = {} +db-build = {} diff --git a/svc/pkg/misc/standalone/playground/src/pull_game.rs b/svc/pkg/misc/standalone/playground/src/pull_game.rs index 2fcd1eb8e9..8ec0859be9 100644 --- a/svc/pkg/misc/standalone/playground/src/pull_game.rs +++ b/svc/pkg/misc/standalone/playground/src/pull_game.rs @@ -57,7 +57,10 @@ pub async fn run( let s3_client = s3_util::Client::from_env("bucket-build").await?; let lobby_group = internal_unwrap_owned!(matchmaker.lobby_groups.first()); - let backend::matchmaker::LobbyRuntime { runtime: Some(backend::matchmaker::lobby_runtime::Runtime::Docker(docker)) } = internal_unwrap!(lobby_group.runtime) else { + let backend::matchmaker::LobbyRuntime { + runtime: Some(backend::matchmaker::lobby_runtime::Runtime::Docker(docker)), + } = internal_unwrap!(lobby_group.runtime) + else { internal_panic!("invalid runtime"); }; let build_id = internal_unwrap_owned!(docker.build_id); diff --git a/svc/pkg/misc/standalone/playground/src/push_game.rs b/svc/pkg/misc/standalone/playground/src/push_game.rs index 9fd7a0decb..8a2b72944e 100644 --- a/svc/pkg/misc/standalone/playground/src/push_game.rs +++ b/svc/pkg/misc/standalone/playground/src/push_game.rs @@ -108,7 +108,10 @@ pub async fn run( lobby_group.regions = vec![primary_region]; // Override the build with the new build - let Some(backend::matchmaker::LobbyRuntime { runtime: Some(backend::matchmaker::lobby_runtime::Runtime::Docker(docker)) }) = lobby_group.runtime.as_mut() else { + let Some(backend::matchmaker::LobbyRuntime { + runtime: Some(backend::matchmaker::lobby_runtime::Runtime::Docker(docker)), + }) = lobby_group.runtime.as_mut() + else { internal_panic!("invalid runtime") }; docker.build_id = Some(build_id.into()); diff --git a/svc/pkg/mm-config/db/mm-config/migrations/20230711222029_add_find_join_config.down.sql b/svc/pkg/mm-config/db/mm-config/migrations/20230711222029_add_find_join_config.down.sql new file mode 100644 index 0000000000..e69de29bb2 diff --git a/svc/pkg/mm-config/db/mm-config/migrations/20230711222029_add_find_join_config.up.sql b/svc/pkg/mm-config/db/mm-config/migrations/20230711222029_add_find_join_config.up.sql new file mode 100644 index 0000000000..53da5e9ca9 --- /dev/null +++ b/svc/pkg/mm-config/db/mm-config/migrations/20230711222029_add_find_join_config.up.sql @@ -0,0 +1,4 @@ +ALTER TABLE lobby_groups + ADD COLUMN find_config BYTES, + ADD COLUMN join_config BYTES, + ADD COLUMN create_config BYTES; diff --git a/svc/pkg/mm-config/db/mm-config/migrations/20230715175430_add_listable.down.sql b/svc/pkg/mm-config/db/mm-config/migrations/20230715175430_add_listable.down.sql new file mode 100644 index 0000000000..e69de29bb2 diff --git a/svc/pkg/mm-config/db/mm-config/migrations/20230715175430_add_listable.up.sql b/svc/pkg/mm-config/db/mm-config/migrations/20230715175430_add_listable.up.sql new file mode 100644 index 0000000000..493252de25 --- /dev/null +++ b/svc/pkg/mm-config/db/mm-config/migrations/20230715175430_add_listable.up.sql @@ -0,0 +1,2 @@ +ALTER TABLE lobby_groups + ADD COLUMN listable BOOLEAN NOT NULL DEFAULT true; diff --git a/svc/pkg/mm-config/ops/lobby-group-get/Cargo.toml b/svc/pkg/mm-config/ops/lobby-group-get/Cargo.toml index 6873d039d5..fb30db9814 100644 --- a/svc/pkg/mm-config/ops/lobby-group-get/Cargo.toml +++ b/svc/pkg/mm-config/ops/lobby-group-get/Cargo.toml @@ -11,7 +11,7 @@ chirp-client = { path = "../../../../../lib/chirp/client" } prost = "0.10" [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/mm-config/ops/lobby-group-get/Service.toml b/svc/pkg/mm-config/ops/lobby-group-get/Service.toml index 15fdd92bd4..5dd5686a8c 100644 --- a/svc/pkg/mm-config/ops/lobby-group-get/Service.toml +++ b/svc/pkg/mm-config/ops/lobby-group-get/Service.toml @@ -5,3 +5,6 @@ name = "mm-config-lobby-group-get" kind = "rust" [operation] + +[databases] +db-mm-config = {} diff --git a/svc/pkg/mm-config/ops/lobby-group-resolve-name-id/Cargo.toml b/svc/pkg/mm-config/ops/lobby-group-resolve-name-id/Cargo.toml index 7a0a856665..0deb4d059c 100644 --- a/svc/pkg/mm-config/ops/lobby-group-resolve-name-id/Cargo.toml +++ b/svc/pkg/mm-config/ops/lobby-group-resolve-name-id/Cargo.toml @@ -12,7 +12,7 @@ prost = "0.10" util-mm = { package = "rivet-util-mm", path = "../../../mm/util" } [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/mm-config/ops/lobby-group-resolve-name-id/Service.toml b/svc/pkg/mm-config/ops/lobby-group-resolve-name-id/Service.toml index 3129309f56..3f804de276 100644 --- a/svc/pkg/mm-config/ops/lobby-group-resolve-name-id/Service.toml +++ b/svc/pkg/mm-config/ops/lobby-group-resolve-name-id/Service.toml @@ -5,3 +5,6 @@ name = "mm-config-lobby-group-resolve-name-id" kind = "rust" [operation] + +[databases] +db-mm-config = {} diff --git a/svc/pkg/mm-config/ops/lobby-group-resolve-name-id/tests/integration.rs b/svc/pkg/mm-config/ops/lobby-group-resolve-name-id/tests/integration.rs index 5ef2af9f20..5a497faf54 100644 --- a/svc/pkg/mm-config/ops/lobby-group-resolve-name-id/tests/integration.rs +++ b/svc/pkg/mm-config/ops/lobby-group-resolve-name-id/tests/integration.rs @@ -35,6 +35,7 @@ async fn empty(ctx: TestCtx) { max_players_normal: 1, max_players_direct: 1, max_players_party: 1, + listable: true, runtime: Some(backend::matchmaker::lobby_runtime::Docker { build_id: build_res.build_id, @@ -43,6 +44,10 @@ async fn empty(ctx: TestCtx) { network_mode: backend::matchmaker::lobby_runtime::NetworkMode::Bridge as i32, ports: Vec::new(), }.into()), + + find_config: None, + join_config: None, + create_config: None, }) .collect(), }), diff --git a/svc/pkg/mm-config/ops/lobby-group-resolve-version/Cargo.toml b/svc/pkg/mm-config/ops/lobby-group-resolve-version/Cargo.toml index f3cbc54bc0..193bba2ab0 100644 --- a/svc/pkg/mm-config/ops/lobby-group-resolve-version/Cargo.toml +++ b/svc/pkg/mm-config/ops/lobby-group-resolve-version/Cargo.toml @@ -11,7 +11,7 @@ chirp-client = { path = "../../../../../lib/chirp/client" } prost = "0.10" [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/mm-config/ops/lobby-group-resolve-version/Service.toml b/svc/pkg/mm-config/ops/lobby-group-resolve-version/Service.toml index cc49280e93..a00f44b9c2 100644 --- a/svc/pkg/mm-config/ops/lobby-group-resolve-version/Service.toml +++ b/svc/pkg/mm-config/ops/lobby-group-resolve-version/Service.toml @@ -5,3 +5,6 @@ name = "mm-config-lobby-group-resolve-version" kind = "rust" [operation] + +[databases] +db-mm-config = {} diff --git a/svc/pkg/mm-config/ops/namespace-config-set/Cargo.toml b/svc/pkg/mm-config/ops/namespace-config-set/Cargo.toml index ac89aa1ce9..99f57bc749 100644 --- a/svc/pkg/mm-config/ops/namespace-config-set/Cargo.toml +++ b/svc/pkg/mm-config/ops/namespace-config-set/Cargo.toml @@ -13,7 +13,7 @@ prost = "0.10" mm-config-namespace-config-validate = { path = "../namespace-config-validate" } [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/mm-config/ops/namespace-config-set/Service.toml b/svc/pkg/mm-config/ops/namespace-config-set/Service.toml index 54000c2687..df1834e249 100644 --- a/svc/pkg/mm-config/ops/namespace-config-set/Service.toml +++ b/svc/pkg/mm-config/ops/namespace-config-set/Service.toml @@ -5,3 +5,6 @@ name = "mm-config-namespace-config-set" kind = "rust" [operation] + +[databases] +db-mm-config = {} diff --git a/svc/pkg/mm-config/ops/namespace-create/Cargo.toml b/svc/pkg/mm-config/ops/namespace-create/Cargo.toml index e24738c96b..8368c6dd6c 100644 --- a/svc/pkg/mm-config/ops/namespace-create/Cargo.toml +++ b/svc/pkg/mm-config/ops/namespace-create/Cargo.toml @@ -11,7 +11,7 @@ chirp-client = { path = "../../../../../lib/chirp/client" } prost = "0.10" [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/mm-config/ops/namespace-create/Service.toml b/svc/pkg/mm-config/ops/namespace-create/Service.toml index d123a1d328..d098e7c702 100644 --- a/svc/pkg/mm-config/ops/namespace-create/Service.toml +++ b/svc/pkg/mm-config/ops/namespace-create/Service.toml @@ -5,3 +5,6 @@ name = "mm-config-namespace-create" kind = "rust" [operation] + +[databases] +db-mm-config = {} diff --git a/svc/pkg/mm-config/ops/namespace-get/Cargo.toml b/svc/pkg/mm-config/ops/namespace-get/Cargo.toml index 9cda257e09..2b85007637 100644 --- a/svc/pkg/mm-config/ops/namespace-get/Cargo.toml +++ b/svc/pkg/mm-config/ops/namespace-get/Cargo.toml @@ -11,7 +11,7 @@ chirp-client = { path = "../../../../../lib/chirp/client" } prost = "0.10" [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/mm-config/ops/namespace-get/Service.toml b/svc/pkg/mm-config/ops/namespace-get/Service.toml index b26f93615d..0b5f75f607 100644 --- a/svc/pkg/mm-config/ops/namespace-get/Service.toml +++ b/svc/pkg/mm-config/ops/namespace-get/Service.toml @@ -5,3 +5,6 @@ name = "mm-config-namespace-get" kind = "rust" [operation] + +[databases] +db-mm-config = {} diff --git a/svc/pkg/mm-config/ops/version-get/Cargo.toml b/svc/pkg/mm-config/ops/version-get/Cargo.toml index 936aa68e83..63597698f0 100644 --- a/svc/pkg/mm-config/ops/version-get/Cargo.toml +++ b/svc/pkg/mm-config/ops/version-get/Cargo.toml @@ -12,7 +12,7 @@ prost = "0.10" util-mm = { package = "rivet-util-mm", path = "../../../mm/util" } [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/mm-config/ops/version-get/Service.toml b/svc/pkg/mm-config/ops/version-get/Service.toml index 450ee75c0a..57621a0450 100644 --- a/svc/pkg/mm-config/ops/version-get/Service.toml +++ b/svc/pkg/mm-config/ops/version-get/Service.toml @@ -5,3 +5,6 @@ name = "mm-config-version-get" kind = "rust" [operation] + +[databases] +db-mm-config = {} diff --git a/svc/pkg/mm-config/ops/version-get/src/lib.rs b/svc/pkg/mm-config/ops/version-get/src/lib.rs index 5a518b95ad..c49d63ef35 100644 --- a/svc/pkg/mm-config/ops/version-get/src/lib.rs +++ b/svc/pkg/mm-config/ops/version-get/src/lib.rs @@ -17,9 +17,13 @@ struct LobbyGroup { max_players_normal: i64, max_players_direct: i64, max_players_party: i64, + listable: bool, runtime: Vec, runtime_meta: Vec, + find_config: Option>, + join_config: Option>, + create_config: Option>, } #[derive(Clone, sqlx::FromRow)] @@ -100,8 +104,9 @@ async fn fetch_versions( SELECT lobby_group_id, version_id, name_id, - max_players_normal, max_players_direct, max_players_party, - runtime, runtime_meta + max_players_normal, max_players_direct, max_players_party, listable, + runtime, runtime_meta, + find_config, join_config, create_config FROM lobby_groups WHERE version_id = ANY($1) " @@ -117,19 +122,19 @@ async fn fetch_versions( let (lobby_group_regions, lobby_group_idle_lobbies) = tokio::try_join!( sqlx::query_as::<_, LobbyGroupRegion>(indoc!( " - SELECT lobby_group_id, region_id, tier_name_id - FROM lobby_group_regions - WHERE lobby_group_id = ANY($1) - " + SELECT lobby_group_id, region_id, tier_name_id + FROM lobby_group_regions + WHERE lobby_group_id = ANY($1) + " )) .bind(&all_lobby_group_ids) .fetch_all(sql_pool), sqlx::query_as::<_, LobbyGroupIdleLobbies>(indoc!( " - SELECT lobby_group_id, region_id, min_idle_lobbies, max_idle_lobbies - FROM lobby_group_idle_lobbies - WHERE lobby_group_id = ANY($1) - " + SELECT lobby_group_id, region_id, min_idle_lobbies, max_idle_lobbies + FROM lobby_group_idle_lobbies + WHERE lobby_group_id = ANY($1) + " )) .bind(&all_lobby_group_ids) .fetch_all(sql_pool), @@ -167,6 +172,23 @@ async fn fetch_versions( let runtime = backend::matchmaker::LobbyRuntime::decode(lg.runtime.as_ref())?; + let find_config = lg + .find_config + .as_ref() + .map(|fc| backend::matchmaker::FindConfig::decode(fc.as_ref())) + .transpose()?; + let join_config = lg + .join_config + .as_ref() + .map(|jc| backend::matchmaker::JoinConfig::decode(jc.as_ref())) + .transpose()?; + let create_config = lg + .create_config + .as_ref() + .map(|jc| { + backend::matchmaker::CreateConfig::decode(jc.as_ref()) + }) + .transpose()?; Ok(backend::matchmaker::LobbyGroup { name_id: lg.name_id.clone(), @@ -197,8 +219,13 @@ async fn fetch_versions( max_players_normal: lg.max_players_normal as u32, max_players_direct: lg.max_players_direct as u32, max_players_party: lg.max_players_party as u32, + listable: lg.listable, runtime: Some(runtime), + + find_config, + join_config, + create_config, }) }) .collect::>>()?, diff --git a/svc/pkg/mm-config/ops/version-get/tests/integration.rs b/svc/pkg/mm-config/ops/version-get/tests/integration.rs index 2934cc0b12..69cbf32d85 100644 --- a/svc/pkg/mm-config/ops/version-get/tests/integration.rs +++ b/svc/pkg/mm-config/ops/version-get/tests/integration.rs @@ -40,6 +40,7 @@ impl TestVersion { max_players_normal: 8, max_players_direct: 10, max_players_party: 12, + listable: true, runtime: Some( backend::matchmaker::lobby_runtime::Docker { @@ -63,6 +64,10 @@ impl TestVersion { } .into(), ), + + find_config: None, + join_config: None, + create_config: None, }], captcha: None, }; diff --git a/svc/pkg/mm-config/ops/version-prepare/src/lib.rs b/svc/pkg/mm-config/ops/version-prepare/src/lib.rs index 9f102d34cc..6f6e766d78 100644 --- a/svc/pkg/mm-config/ops/version-prepare/src/lib.rs +++ b/svc/pkg/mm-config/ops/version-prepare/src/lib.rs @@ -124,6 +124,8 @@ async fn validate_build( let build_game_id = internal_unwrap!(build.game_id).as_uuid(); internal_assert_eq!(game_id, build_game_id); + tracing::info!(?build); + // Validate build has completed uploading let upload_res = op!([ctx] upload_get { upload_ids: vec![build_upload_id.into()], diff --git a/svc/pkg/mm-config/ops/version-prepare/tests/integration.rs b/svc/pkg/mm-config/ops/version-prepare/tests/integration.rs index 11da12a09a..e944879b8c 100644 --- a/svc/pkg/mm-config/ops/version-prepare/tests/integration.rs +++ b/svc/pkg/mm-config/ops/version-prepare/tests/integration.rs @@ -36,6 +36,7 @@ async fn empty(ctx: TestCtx) { max_players_normal: 8, max_players_direct: 10, max_players_party: 12, + listable: true, runtime: Some(backend::matchmaker::lobby_runtime::Docker { build_id: build_res.build_id, @@ -57,6 +58,10 @@ async fn empty(ctx: TestCtx) { }, ], }.into()), + + find_config: None, + join_config: None, + create_config: None, }, backend::matchmaker::LobbyGroup { name_id: "test-host".into(), @@ -71,6 +76,7 @@ async fn empty(ctx: TestCtx) { max_players_normal: 8, max_players_direct: 10, max_players_party: 12, + listable: true, runtime: Some(backend::matchmaker::lobby_runtime::Docker { build_id: build_res.build_id, @@ -133,6 +139,10 @@ async fn empty(ctx: TestCtx) { }, ], }.into()), + + find_config: None, + join_config: None, + create_config: None, }, ], captcha: None, diff --git a/svc/pkg/mm-config/ops/version-publish/Cargo.toml b/svc/pkg/mm-config/ops/version-publish/Cargo.toml index 1e769f9c9b..c67b20794b 100644 --- a/svc/pkg/mm-config/ops/version-publish/Cargo.toml +++ b/svc/pkg/mm-config/ops/version-publish/Cargo.toml @@ -12,14 +12,13 @@ prost = "0.10" util-mm = { package = "rivet-util-mm", path = "../../../mm/util" } [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false features = [ - "runtime-tokio-native-tls", + "runtime-tokio", "postgres", "uuid", "json", - "tls", "bit-vec", ] diff --git a/svc/pkg/mm-config/ops/version-publish/Service.toml b/svc/pkg/mm-config/ops/version-publish/Service.toml index 9b1d4d6ee1..d91d144327 100644 --- a/svc/pkg/mm-config/ops/version-publish/Service.toml +++ b/svc/pkg/mm-config/ops/version-publish/Service.toml @@ -5,3 +5,6 @@ name = "mm-config-version-publish" kind = "rust" [operation] + +[databases] +db-mm-config = {} diff --git a/svc/pkg/mm-config/ops/version-publish/src/lib.rs b/svc/pkg/mm-config/ops/version-publish/src/lib.rs index 4e22f70988..009a186f7d 100644 --- a/svc/pkg/mm-config/ops/version-publish/src/lib.rs +++ b/svc/pkg/mm-config/ops/version-publish/src/lib.rs @@ -42,10 +42,9 @@ async fn handle( .bind(version_id) .bind(captcha_buf) .bind(util_mm::version_migrations::all()) - .execute(&mut tx) + .execute(&mut *tx) .await?; - // TODO: Parallelize all futures in this for loop // Save lobby groups internal_assert_eq!(config.lobby_groups.len(), config_ctx.lobby_groups.len()); for (lobby_group, lobby_group_ctx) in config @@ -61,8 +60,7 @@ async fn handle( let (runtime, runtime_meta) = publish_runtime( internal_unwrap!(runtime.runtime), internal_unwrap!(runtime_ctx.runtime), - ) - .await?; + )?; // Encode runtime data let (runtime_buf, runtime_meta_buf) = { @@ -75,6 +73,38 @@ async fn handle( (runtime_buf, runtime_meta_buf) }; + // Encode config data + let find_config_buf = lobby_group + .find_config + .as_ref() + .map(|config| { + let mut buf = Vec::with_capacity(config.encoded_len()); + config.encode(&mut buf)?; + + GlobalResult::Ok(buf) + }) + .transpose()?; + let join_config_buf = lobby_group + .join_config + .as_ref() + .map(|config| { + let mut buf = Vec::with_capacity(config.encoded_len()); + config.encode(&mut buf)?; + + GlobalResult::Ok(buf) + }) + .transpose()?; + let create_config_buf = lobby_group + .create_config + .as_ref() + .map(|config| { + let mut buf = Vec::with_capacity(config.encoded_len()); + config.encode(&mut buf)?; + + GlobalResult::Ok(buf) + }) + .transpose()?; + sqlx::query(indoc!( " INSERT INTO lobby_groups ( @@ -86,11 +116,15 @@ async fn handle( max_players_normal, max_players_direct, max_players_party, + listable, runtime, - runtime_meta + runtime_meta, + find_config, + join_config, + create_config ) - VALUES ($1, $2, $3, $4, $5, $6, $7, $8) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12) " )) .bind(lobby_group_id) @@ -99,31 +133,46 @@ async fn handle( .bind(lobby_group.max_players_normal as i64) .bind(lobby_group.max_players_direct as i64) .bind(lobby_group.max_players_party as i64) + .bind(lobby_group.listable) .bind(&runtime_buf) .bind(&runtime_meta_buf) - .execute(&mut tx) + .bind(&find_config_buf) + .bind(&join_config_buf) + .bind(&create_config_buf) + .execute(&mut *tx) .await?; for region in &lobby_group.regions { let region_id = internal_unwrap!(region.region_id).as_uuid(); - sqlx::query( - "INSERT INTO lobby_group_regions (lobby_group_id, region_id, tier_name_id) VALUES ($1, $2, $3)", - ) + sqlx::query(indoc!( + " + INSERT INTO lobby_group_regions ( + lobby_group_id, region_id, tier_name_id + ) + VALUES ($1, $2, $3) + " + )) .bind(lobby_group_id) .bind(region_id) .bind(®ion.tier_name_id) - .execute(&mut tx) + .execute(&mut *tx) .await?; if let Some(idle_lobbies) = ®ion.idle_lobbies { - sqlx::query( - "INSERT INTO lobby_group_idle_lobbies (lobby_group_id, region_id, min_idle_lobbies, max_idle_lobbies) VALUES ($1, $2, $3, $4)", - ) - .bind(lobby_group_id) - .bind(region_id) - .bind(idle_lobbies.min_idle_lobbies as i64).bind(idle_lobbies.max_idle_lobbies as i64) - .execute(&mut tx) - .await?; + sqlx::query(indoc!( + " + INSERT INTO lobby_group_idle_lobbies ( + lobby_group_id, region_id, min_idle_lobbies, max_idle_lobbies + ) + VALUES ($1, $2, $3, $4) + " + )) + .bind(lobby_group_id) + .bind(region_id) + .bind(idle_lobbies.min_idle_lobbies as i64) + .bind(idle_lobbies.max_idle_lobbies as i64) + .execute(&mut *tx) + .await?; } } } @@ -142,7 +191,7 @@ async fn handle( /// /// For example: a docker image with an input of `nginx` would have the tag resolved against the /// registry to `nginx:1.21.1` in order to pin the version. -async fn publish_runtime( +fn publish_runtime( runtime: &backend::matchmaker::lobby_runtime::Runtime, runtime_ctx: &backend::matchmaker::lobby_runtime_ctx::Runtime, ) -> GlobalResult<( diff --git a/svc/pkg/mm-config/ops/version-publish/tests/integration.rs b/svc/pkg/mm-config/ops/version-publish/tests/integration.rs index 0b47ca6b84..c9afa09d85 100644 --- a/svc/pkg/mm-config/ops/version-publish/tests/integration.rs +++ b/svc/pkg/mm-config/ops/version-publish/tests/integration.rs @@ -34,6 +34,7 @@ async fn empty(ctx: TestCtx) { max_players_normal: 8, max_players_direct: 8, max_players_party: 8, + listable: true, runtime: Some(backend::matchmaker::LobbyRuntime { runtime: Some(backend::matchmaker::lobby_runtime::Runtime::Docker( @@ -59,6 +60,10 @@ async fn empty(ctx: TestCtx) { } )), }), + + find_config: None, + join_config: None, + create_config: None, }, ], captcha: None, @@ -85,6 +90,7 @@ async fn empty(ctx: TestCtx) { max_players_normal: 8, max_players_direct: 10, max_players_party: 12, + listable: true, runtime: Some( backend::matchmaker::lobby_runtime::Docker { @@ -109,6 +115,10 @@ async fn empty(ctx: TestCtx) { } .into() ), + + find_config: None, + join_config: None, + create_config: None, }, ], captcha: None, diff --git a/svc/pkg/mm/db/state/migrations/20230714001053_add_creator_user_id.down.sql b/svc/pkg/mm/db/state/migrations/20230714001053_add_creator_user_id.down.sql new file mode 100644 index 0000000000..e69de29bb2 diff --git a/svc/pkg/mm/db/state/migrations/20230714001053_add_creator_user_id.up.sql b/svc/pkg/mm/db/state/migrations/20230714001053_add_creator_user_id.up.sql new file mode 100644 index 0000000000..f48255d291 --- /dev/null +++ b/svc/pkg/mm/db/state/migrations/20230714001053_add_creator_user_id.up.sql @@ -0,0 +1,4 @@ +ALTER TABLE lobbies + ADD COLUMN creator_user_id UUID, + ADD COLUMN is_custom BOOLEAN NOT NULL DEFAULT false, + ADD COLUMN publicity INT NOT NULL DEFAULT 0; diff --git a/svc/pkg/mm/ops/lobby-find-fail/Service.toml b/svc/pkg/mm/ops/lobby-find-fail/Service.toml index 5064c09582..de5a3712b5 100644 --- a/svc/pkg/mm/ops/lobby-find-fail/Service.toml +++ b/svc/pkg/mm/ops/lobby-find-fail/Service.toml @@ -5,3 +5,7 @@ name = "mm-lobby-find-fail" kind = "rust" [operation] + +[databases] +db-mm-state = {} +redis-mm = {} diff --git a/svc/pkg/mm/ops/lobby-find-lobby-query-list/Service.toml b/svc/pkg/mm/ops/lobby-find-lobby-query-list/Service.toml index e32f0f7ecb..9553d6a8c6 100644 --- a/svc/pkg/mm/ops/lobby-find-lobby-query-list/Service.toml +++ b/svc/pkg/mm/ops/lobby-find-lobby-query-list/Service.toml @@ -5,3 +5,6 @@ name = "mm-lobby-find-lobby-query-list" kind = "rust" [operation] + +[databases] +redis-mm = {} diff --git a/svc/pkg/mm/ops/lobby-find-try-complete/Service.toml b/svc/pkg/mm/ops/lobby-find-try-complete/Service.toml index ad1af16d07..1fd8d635d0 100644 --- a/svc/pkg/mm/ops/lobby-find-try-complete/Service.toml +++ b/svc/pkg/mm/ops/lobby-find-try-complete/Service.toml @@ -5,3 +5,7 @@ name = "mm-lobby-find-try-complete" kind = "rust" [operation] + +[databases] +db-mm-state = {} +redis-mm = {} diff --git a/svc/pkg/mm/ops/lobby-get/Cargo.toml b/svc/pkg/mm/ops/lobby-get/Cargo.toml index dc98e3031a..79977d367d 100644 --- a/svc/pkg/mm/ops/lobby-get/Cargo.toml +++ b/svc/pkg/mm/ops/lobby-get/Cargo.toml @@ -12,7 +12,7 @@ chrono = "0.4" prost = "0.10" [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/mm/ops/lobby-get/Service.toml b/svc/pkg/mm/ops/lobby-get/Service.toml index 548f15fd30..5e44cbdfda 100644 --- a/svc/pkg/mm/ops/lobby-get/Service.toml +++ b/svc/pkg/mm/ops/lobby-get/Service.toml @@ -6,3 +6,5 @@ kind = "rust" [operation] +[databases] +db-mm-state = {} diff --git a/svc/pkg/mm/ops/lobby-get/src/lib.rs b/svc/pkg/mm/ops/lobby-get/src/lib.rs index b9d7e19a44..73b278973f 100644 --- a/svc/pkg/mm/ops/lobby-get/src/lib.rs +++ b/svc/pkg/mm/ops/lobby-get/src/lib.rs @@ -14,6 +14,9 @@ struct LobbyRow { is_closed: bool, namespace_id: Uuid, create_ray_id: Option, + creator_user_id: Option, + is_custom: bool, + publicity: i64, max_players_normal: i64, max_players_direct: i64, @@ -34,6 +37,9 @@ impl From for backend::matchmaker::Lobby { is_closed: value.is_closed, namespace_id: Some(value.namespace_id.into()), create_ray_id: value.create_ray_id.map(Into::into), + creator_user_id: value.creator_user_id.map(Into::into), + is_custom: value.is_custom, + publicity: value.publicity as i32, max_players_normal: value.max_players_normal as u32, max_players_direct: value.max_players_direct as u32, @@ -68,6 +74,9 @@ async fn handle( is_closed, namespace_id, create_ray_id, + creator_user_id, + is_custom, + publicity, max_players_normal, max_players_direct, diff --git a/svc/pkg/mm/ops/lobby-history/Cargo.toml b/svc/pkg/mm/ops/lobby-history/Cargo.toml index 1d1a1e82b2..eaaad61e40 100644 --- a/svc/pkg/mm/ops/lobby-history/Cargo.toml +++ b/svc/pkg/mm/ops/lobby-history/Cargo.toml @@ -12,7 +12,7 @@ chrono = "0.4" prost = "0.10" [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/mm/ops/lobby-history/Service.toml b/svc/pkg/mm/ops/lobby-history/Service.toml index a7fa6d7509..7e1fb1e243 100644 --- a/svc/pkg/mm/ops/lobby-history/Service.toml +++ b/svc/pkg/mm/ops/lobby-history/Service.toml @@ -5,3 +5,6 @@ name = "mm-lobby-history" kind = "rust" [operation] + +[databases] +db-mm-state = {} diff --git a/svc/pkg/mm/ops/lobby-idle-update/Cargo.toml b/svc/pkg/mm/ops/lobby-idle-update/Cargo.toml index 39bafc58ad..d661f9702e 100644 --- a/svc/pkg/mm/ops/lobby-idle-update/Cargo.toml +++ b/svc/pkg/mm/ops/lobby-idle-update/Cargo.toml @@ -17,7 +17,7 @@ game-namespace-get = { path = "../../../game/ops/namespace-get" } mm-config-version-get = { path = "../../../mm-config/ops/version-get" } [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/mm/ops/lobby-idle-update/Service.toml b/svc/pkg/mm/ops/lobby-idle-update/Service.toml index a48b62a4ed..ea4dbd13f5 100644 --- a/svc/pkg/mm/ops/lobby-idle-update/Service.toml +++ b/svc/pkg/mm/ops/lobby-idle-update/Service.toml @@ -6,3 +6,6 @@ kind = "rust" [operation] +[databases] +db-mm-state = {} +redis-mm = {} diff --git a/svc/pkg/mm/ops/lobby-idle-update/src/lib.rs b/svc/pkg/mm/ops/lobby-idle-update/src/lib.rs index 6b196418ec..7c1a90908e 100644 --- a/svc/pkg/mm/ops/lobby-idle-update/src/lib.rs +++ b/svc/pkg/mm/ops/lobby-idle-update/src/lib.rs @@ -74,6 +74,11 @@ async fn handle( region_id: Some(region_id.into()), create_ray_id: Some(ctx.ray_id().into()), preemptively_created: false, + + creator_user_id: None, + is_custom: false, + publicity: None, + lobby_config_json: None, })); } futures_util::future::try_join_all(create_futs).await?; diff --git a/svc/pkg/mm/ops/lobby-idle-update/tests/integration.rs b/svc/pkg/mm/ops/lobby-idle-update/tests/integration.rs index e4b7712e3f..67546a229a 100644 --- a/svc/pkg/mm/ops/lobby-idle-update/tests/integration.rs +++ b/svc/pkg/mm/ops/lobby-idle-update/tests/integration.rs @@ -76,6 +76,7 @@ impl Ctx { max_players_normal: 1, max_players_direct: 1, max_players_party: 1, + listable: true, runtime: Some(backend::matchmaker::lobby_runtime::Docker { build_id: build_res.build_id, @@ -84,6 +85,10 @@ impl Ctx { network_mode: backend::matchmaker::lobby_runtime::NetworkMode::Bridge as i32, ports: Vec::new(), }.into()), + + find_config: None, + join_config: None, + create_config: None, }], }), ..Default::default() @@ -507,7 +512,9 @@ async fn test_find_idle_lobby(ctx: TestCtx) { tracing::info!("finding lobby"); let player_id = Uuid::new_v4(); let query_id = Uuid::new_v4(); - let find_res = msg!([ctx] @notrace mm::msg::lobby_find(test_ctx.namespace_id, query_id) -> Result { + let find_res = msg!([ctx] @notrace mm::msg::lobby_find(test_ctx.namespace_id, query_id) + -> Result + { namespace_id: Some(test_ctx.namespace_id.into()), query_id: Some(query_id.into()), join_kind: backend::matchmaker::query::JoinKind::Normal as i32, @@ -524,9 +531,11 @@ async fn test_find_idle_lobby(ctx: TestCtx) { region_ids: vec![test_ctx.region_id.into()], auto_create: None, })), + ..Default::default() }) .await - .unwrap().unwrap(); + .unwrap() + .unwrap(); let find_lobby_id = find_res.lobby_id.as_ref().unwrap().as_uuid(); assert!( diff --git a/svc/pkg/mm/ops/lobby-list-for-namespace/Cargo.toml b/svc/pkg/mm/ops/lobby-list-for-namespace/Cargo.toml index 9bc3acc1f1..0a47a9e80e 100644 --- a/svc/pkg/mm/ops/lobby-list-for-namespace/Cargo.toml +++ b/svc/pkg/mm/ops/lobby-list-for-namespace/Cargo.toml @@ -12,7 +12,7 @@ prost = "0.10" util-mm = { package = "rivet-util-mm", path = "../../util" } [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/mm/ops/lobby-list-for-namespace/Service.toml b/svc/pkg/mm/ops/lobby-list-for-namespace/Service.toml index 6013b25cc4..f068c396f1 100644 --- a/svc/pkg/mm/ops/lobby-list-for-namespace/Service.toml +++ b/svc/pkg/mm/ops/lobby-list-for-namespace/Service.toml @@ -5,3 +5,6 @@ name = "mm-lobby-list-for-namespace" kind = "rust" [operation] + +[databases] +redis-mm = {} diff --git a/svc/pkg/mm/ops/lobby-list-for-user-id/Cargo.toml b/svc/pkg/mm/ops/lobby-list-for-user-id/Cargo.toml new file mode 100644 index 0000000000..8dcb2904b6 --- /dev/null +++ b/svc/pkg/mm/ops/lobby-list-for-user-id/Cargo.toml @@ -0,0 +1,20 @@ +[package] +name = "mm-lobby-list-for-user-id" +version = "0.0.1" +edition = "2018" +authors = ["Rivet Gaming, LLC "] +license = "Apache-2.0" + +[dependencies] +chirp-client = { path = "../../../../../lib/chirp/client" } +rivet-operation = { path = "../../../../../lib/operation/core" } +prost = "0.10" + +[dependencies.sqlx] +version = "0.7" +default-features = false + +[dev-dependencies] +chirp-worker = { path = "../../../../../lib/chirp/worker" } + +faker-mm-lobby = { path = "../../../faker/ops/mm-lobby" } diff --git a/svc/pkg/mm/ops/lobby-list-for-user-id/README.md b/svc/pkg/mm/ops/lobby-list-for-user-id/README.md new file mode 100644 index 0000000000..7fa275934d --- /dev/null +++ b/svc/pkg/mm/ops/lobby-list-for-user-id/README.md @@ -0,0 +1 @@ +# mm-lobby-list-for-user-id diff --git a/svc/pkg/mm/ops/lobby-list-for-user-id/Service.toml b/svc/pkg/mm/ops/lobby-list-for-user-id/Service.toml new file mode 100644 index 0000000000..13ccef1f2d --- /dev/null +++ b/svc/pkg/mm/ops/lobby-list-for-user-id/Service.toml @@ -0,0 +1,10 @@ +[service] +name = "mm-lobby-list-for-user-id" + +[runtime] +kind = "rust" + +[operation] + +[databases] +db-mm-state = {} diff --git a/svc/pkg/mm/ops/lobby-list-for-user-id/src/lib.rs b/svc/pkg/mm/ops/lobby-list-for-user-id/src/lib.rs new file mode 100644 index 0000000000..4a1f4d2d2b --- /dev/null +++ b/svc/pkg/mm/ops/lobby-list-for-user-id/src/lib.rs @@ -0,0 +1,51 @@ +use proto::backend::{self, pkg::*}; +use rivet_operation::prelude::*; + +#[derive(sqlx::FromRow)] +struct LobbyRow { + lobby_id: Uuid, + creator_user_id: Uuid, +} + +#[operation(name = "mm-lobby-list-for-user-id")] +async fn handle( + ctx: OperationContext, +) -> GlobalResult { + let crdb = ctx.crdb("db-mm-state").await?; + let user_ids = ctx + .user_ids + .iter() + .map(common::Uuid::as_uuid) + .collect::>(); + + let lobbies = sqlx::query_as::<_, LobbyRow>(indoc!( + " + SELECT + lobby_id, + creator_user_id + FROM lobbies + WHERE creator_user_id = ANY($1) + " + )) + .bind(&user_ids) + .fetch_all(&crdb) + .await?; + + Ok(mm::lobby_list_for_user_id::Response { + users: user_ids + .into_iter() + .map(|user_id| { + let lobby_ids = lobbies + .iter() + .filter(|l| l.creator_user_id == user_id) + .map(|l| l.lobby_id.into()) + .collect::>(); + + mm::lobby_list_for_user_id::response::User { + user_id: Some(user_id.into()), + lobby_ids, + } + }) + .collect::>(), + }) +} diff --git a/svc/pkg/mm/ops/lobby-list-for-user-id/tests/integration.rs b/svc/pkg/mm/ops/lobby-list-for-user-id/tests/integration.rs new file mode 100644 index 0000000000..a1189959a4 --- /dev/null +++ b/svc/pkg/mm/ops/lobby-list-for-user-id/tests/integration.rs @@ -0,0 +1,26 @@ +use chirp_worker::prelude::*; + +#[worker_test] +async fn empty(ctx: TestCtx) { + let user_id = Uuid::new_v4(); + let lobby_res = op!([ctx] faker_mm_lobby { + creator_user_id: Some(user_id.into()), + ..Default::default() + }) + .await + .unwrap(); + + let res = op!([ctx] mm_lobby_list_for_user_id { + user_ids: vec![user_id.into()], + }) + .await + .unwrap(); + let user = res.users.first().unwrap(); + + assert!( + user.lobby_ids + .iter() + .any(|lobby_id| &lobby_res.lobby_id.unwrap() == lobby_id), + "lobby not listed" + ); +} diff --git a/svc/pkg/mm/ops/lobby-player-count/Cargo.toml b/svc/pkg/mm/ops/lobby-player-count/Cargo.toml index 70f25c6427..444f358103 100644 --- a/svc/pkg/mm/ops/lobby-player-count/Cargo.toml +++ b/svc/pkg/mm/ops/lobby-player-count/Cargo.toml @@ -12,7 +12,7 @@ prost = "0.10" util-mm = { package = "rivet-util-mm", path = "../../util" } [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/mm/ops/lobby-player-count/Service.toml b/svc/pkg/mm/ops/lobby-player-count/Service.toml index 57539a6628..56247c32c2 100644 --- a/svc/pkg/mm/ops/lobby-player-count/Service.toml +++ b/svc/pkg/mm/ops/lobby-player-count/Service.toml @@ -5,3 +5,6 @@ name = "mm-lobby-player-count" kind = "rust" [operation] + +[databases] +redis-mm = {} diff --git a/svc/pkg/mm/ops/lobby-player-count/tests/integration.rs b/svc/pkg/mm/ops/lobby-player-count/tests/integration.rs index 71b3d490dc..26177a3d8e 100644 --- a/svc/pkg/mm/ops/lobby-player-count/tests/integration.rs +++ b/svc/pkg/mm/ops/lobby-player-count/tests/integration.rs @@ -67,6 +67,7 @@ async fn empty(ctx: TestCtx) { query: Some(mm::msg::lobby_find::message::Query::Direct(backend::matchmaker::query::Direct { lobby_id: Some(player.lobby_id.into()), })), + ..Default::default() }) .await .unwrap().unwrap(); diff --git a/svc/pkg/mm/ops/lobby-runtime-aggregate/Cargo.toml b/svc/pkg/mm/ops/lobby-runtime-aggregate/Cargo.toml index 3c982285b8..b38c035ffd 100644 --- a/svc/pkg/mm/ops/lobby-runtime-aggregate/Cargo.toml +++ b/svc/pkg/mm/ops/lobby-runtime-aggregate/Cargo.toml @@ -16,7 +16,7 @@ mm-config-lobby-group-resolve-version = { path = "../../../mm-config/ops/lobby-g mm-config-version-get = { path = "../../../mm-config/ops/version-get" } [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/mm/ops/lobby-runtime-aggregate/Service.toml b/svc/pkg/mm/ops/lobby-runtime-aggregate/Service.toml index 4a44cb9ce4..4914e1f0e7 100644 --- a/svc/pkg/mm/ops/lobby-runtime-aggregate/Service.toml +++ b/svc/pkg/mm/ops/lobby-runtime-aggregate/Service.toml @@ -6,3 +6,6 @@ kind = "rust" [operation] +[databases] +db-mm-state = {} +redis-mm = {} diff --git a/svc/pkg/mm/ops/lobby-state-get/Cargo.toml b/svc/pkg/mm/ops/lobby-state-get/Cargo.toml new file mode 100644 index 0000000000..6fea787221 --- /dev/null +++ b/svc/pkg/mm/ops/lobby-state-get/Cargo.toml @@ -0,0 +1,21 @@ +[package] +name = "mm-lobby-state-get" +version = "0.0.1" +edition = "2018" +authors = ["Rivet Gaming, LLC "] +license = "Apache-2.0" + +[dependencies] +chirp-client = { path = "../../../../../lib/chirp/client" } +rivet-operation = { path = "../../../../../lib/operation/core" } +prost = "0.10" +util-mm = { package = "rivet-util-mm", path = "../../util" } + +[dependencies.sqlx] +version = "0.7" +default-features = false + +[dev-dependencies] +chirp-worker = { path = "../../../../../lib/chirp/worker" } + +faker-mm-lobby = { path = "../../../faker/ops/mm-lobby" } diff --git a/svc/pkg/mm/ops/lobby-state-get/README.md b/svc/pkg/mm/ops/lobby-state-get/README.md new file mode 100644 index 0000000000..3ca22cf41b --- /dev/null +++ b/svc/pkg/mm/ops/lobby-state-get/README.md @@ -0,0 +1 @@ +# mm-lobby-state-get diff --git a/svc/pkg/mm/ops/lobby-state-get/Service.toml b/svc/pkg/mm/ops/lobby-state-get/Service.toml new file mode 100644 index 0000000000..15dc0911a7 --- /dev/null +++ b/svc/pkg/mm/ops/lobby-state-get/Service.toml @@ -0,0 +1,10 @@ +[service] +name = "mm-lobby-state-get" + +[runtime] +kind = "rust" + +[operation] + +[databases] +redis-mm = {} diff --git a/svc/pkg/mm/ops/lobby-state-get/src/lib.rs b/svc/pkg/mm/ops/lobby-state-get/src/lib.rs new file mode 100644 index 0000000000..de38f15985 --- /dev/null +++ b/svc/pkg/mm/ops/lobby-state-get/src/lib.rs @@ -0,0 +1,37 @@ +use proto::backend::pkg::*; +use rivet_operation::prelude::*; + +#[operation(name = "mm-lobby-state-get")] +async fn handle( + ctx: OperationContext, +) -> GlobalResult { + let lobby_ids = ctx + .lobby_ids + .iter() + .map(common::Uuid::as_uuid) + .collect::>(); + + // Fetch lobby states + let mut pipe = redis::pipe(); + for lobby_id in &lobby_ids { + pipe.hget( + util_mm::key::lobby_config(*lobby_id), + util_mm::key::lobby_config::STATE_JSON, + ); + } + let states = pipe + .query_async::<_, Vec>>(&mut ctx.redis_mm().await?) + .await?; + + // Map to lobbies + let lobbies = lobby_ids + .iter() + .zip(states.into_iter()) + .map(|(lobby_id, state)| mm::lobby_state_get::response::Lobby { + lobby_id: Some((*lobby_id).into()), + state_json: state, + }) + .collect::>(); + + Ok(mm::lobby_state_get::Response { lobbies }) +} diff --git a/svc/pkg/mm/ops/lobby-state-get/tests/integration.rs b/svc/pkg/mm/ops/lobby-state-get/tests/integration.rs new file mode 100644 index 0000000000..717e140899 --- /dev/null +++ b/svc/pkg/mm/ops/lobby-state-get/tests/integration.rs @@ -0,0 +1,30 @@ +use chirp_worker::prelude::*; +use proto::backend::pkg::*; + +#[worker_test] +async fn empty(ctx: TestCtx) { + let lobby = op!([ctx] faker_mm_lobby { + ..Default::default() + }) + .await + .unwrap(); + let lobby_id = lobby.lobby_id.unwrap(); + + let json = Some(r#"{ "foo": "bar" }"#.to_string()); + msg!([ctx] mm::msg::lobby_state_set(lobby_id) -> mm::msg::lobby_state_set_complete { + lobby_id: Some(lobby_id), + state_json: json.clone(), + }) + .await + .unwrap(); + + let res = op!([ctx] mm_lobby_state_get { + lobby_ids: vec![lobby_id, Uuid::new_v4().into()], + }) + .await + .unwrap(); + assert!(res.lobbies.len() == 2); + + let lobby = res.lobbies.first().unwrap(); + assert_eq!(json, lobby.state_json); +} diff --git a/svc/pkg/mm/ops/player-count-for-namespace/Cargo.toml b/svc/pkg/mm/ops/player-count-for-namespace/Cargo.toml index 3d6ae46aee..f2d8e76505 100644 --- a/svc/pkg/mm/ops/player-count-for-namespace/Cargo.toml +++ b/svc/pkg/mm/ops/player-count-for-namespace/Cargo.toml @@ -12,7 +12,7 @@ prost = "0.10" util-mm = { package = "rivet-util-mm", path = "../../util" } [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/mm/ops/player-count-for-namespace/Service.toml b/svc/pkg/mm/ops/player-count-for-namespace/Service.toml index 1c58bed41c..387e46f55f 100644 --- a/svc/pkg/mm/ops/player-count-for-namespace/Service.toml +++ b/svc/pkg/mm/ops/player-count-for-namespace/Service.toml @@ -5,3 +5,6 @@ name = "mm-player-count-for-namespace" kind = "rust" [operation] + +[databases] +redis-mm = {} diff --git a/svc/pkg/mm/ops/player-count-for-namespace/tests/integration.rs b/svc/pkg/mm/ops/player-count-for-namespace/tests/integration.rs index 479e532587..c76a35c93c 100644 --- a/svc/pkg/mm/ops/player-count-for-namespace/tests/integration.rs +++ b/svc/pkg/mm/ops/player-count-for-namespace/tests/integration.rs @@ -29,6 +29,7 @@ async fn empty(ctx: TestCtx) { query: Some(mm::msg::lobby_find::message::Query::Direct(backend::matchmaker::query::Direct { lobby_id: Some(lobby_id), })), + ..Default::default() }) .await .unwrap().unwrap(); diff --git a/svc/pkg/mm/ops/player-get/Cargo.toml b/svc/pkg/mm/ops/player-get/Cargo.toml index 9464425cdc..a1fd2d398d 100644 --- a/svc/pkg/mm/ops/player-get/Cargo.toml +++ b/svc/pkg/mm/ops/player-get/Cargo.toml @@ -11,7 +11,7 @@ chirp-client = { path = "../../../../../lib/chirp/client" } prost = "0.10" [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/mm/ops/player-get/Service.toml b/svc/pkg/mm/ops/player-get/Service.toml index d375284c0a..d16a61245e 100644 --- a/svc/pkg/mm/ops/player-get/Service.toml +++ b/svc/pkg/mm/ops/player-get/Service.toml @@ -5,3 +5,6 @@ name = "mm-player-get" kind = "rust" [operation] + +[databases] +db-mm-state = {} diff --git a/svc/pkg/mm/ops/player-get/tests/integration.rs b/svc/pkg/mm/ops/player-get/tests/integration.rs index a64c74e0f6..2d72f9747e 100644 --- a/svc/pkg/mm/ops/player-get/tests/integration.rs +++ b/svc/pkg/mm/ops/player-get/tests/integration.rs @@ -27,6 +27,7 @@ async fn basic(ctx: TestCtx) { query: Some(mm::msg::lobby_find::message::Query::Direct(backend::matchmaker::query::Direct { lobby_id: Some(lobby_id.into()), })), + ..Default::default() }).await.unwrap().unwrap(); let res = op!([ctx] mm_player_get { diff --git a/svc/pkg/mm/standalone/gc-full/Cargo.toml b/svc/pkg/mm/standalone/gc-full/Cargo.toml index ac86d49b84..93a3203e02 100644 --- a/svc/pkg/mm/standalone/gc-full/Cargo.toml +++ b/svc/pkg/mm/standalone/gc-full/Cargo.toml @@ -19,14 +19,13 @@ tracing-subscriber = { version = "0.3", default-features = false, features = ["f util-mm = { package = "rivet-util-mm", path = "../../util" } [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false features = [ - "runtime-tokio-native-tls", + "runtime-tokio", "postgres", "uuid", "json", - "tls", "macros", ] diff --git a/svc/pkg/mm/standalone/gc-full/Service.toml b/svc/pkg/mm/standalone/gc-full/Service.toml index 7af1566b13..6fd518ce49 100644 --- a/svc/pkg/mm/standalone/gc-full/Service.toml +++ b/svc/pkg/mm/standalone/gc-full/Service.toml @@ -8,3 +8,6 @@ kind = "rust" [periodic] cron = "0 0 * * *" +[databases] +db-mm-state = {} +redis-mm = {} diff --git a/svc/pkg/mm/standalone/gc/Cargo.toml b/svc/pkg/mm/standalone/gc/Cargo.toml index d52a2d8d81..173e6b71c5 100644 --- a/svc/pkg/mm/standalone/gc/Cargo.toml +++ b/svc/pkg/mm/standalone/gc/Cargo.toml @@ -17,7 +17,7 @@ rivet-health-checks = { path = "../../../../../lib/health-checks" } rivet-metrics = { path = "../../../../../lib/metrics" } rivet-pools = { path = "../../../../../lib/pools" } rivet-runtime = { path = "../../../../../lib/runtime" } -tokio = { version = "1.21", features = ["full"] } +tokio = { version = "1.29", features = ["full"] } tracing = "0.1" tracing-subscriber = { version = "0.3", default-features = false, features = ["fmt", "json", "ansi"] } util-mm = { package = "rivet-util-mm", path = "../../util" } @@ -25,14 +25,13 @@ util-mm = { package = "rivet-util-mm", path = "../../util" } region-list = { path = "../../../region/ops/list" } [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false features = [ - "runtime-tokio-native-tls", + "runtime-tokio", "postgres", "uuid", "json", - "tls", "macros", ] diff --git a/svc/pkg/mm/standalone/gc/Service.toml b/svc/pkg/mm/standalone/gc/Service.toml index 9eb466afa6..301270b597 100644 --- a/svc/pkg/mm/standalone/gc/Service.toml +++ b/svc/pkg/mm/standalone/gc/Service.toml @@ -8,3 +8,6 @@ kind = "rust" [headless] singleton = true +[databases] +db-mm-state = {} +redis-mm = {} diff --git a/svc/pkg/mm/standalone/gc/tests/integration.rs b/svc/pkg/mm/standalone/gc/tests/integration.rs index a8d5f7cf26..f239d20a17 100644 --- a/svc/pkg/mm/standalone/gc/tests/integration.rs +++ b/svc/pkg/mm/standalone/gc/tests/integration.rs @@ -108,6 +108,7 @@ async fn remove_unregistered_players(ctx: TestCtx, crdb: CrdbPool) { query: Some(mm::msg::lobby_find::message::Query::Direct(backend::matchmaker::query::Direct { lobby_id: Some(lobby_id.into()), })), + ..Default::default() }) .await .unwrap().unwrap(); diff --git a/svc/pkg/mm/types/lobby-list-for-user-id.proto b/svc/pkg/mm/types/lobby-list-for-user-id.proto new file mode 100644 index 0000000000..4aa7531210 --- /dev/null +++ b/svc/pkg/mm/types/lobby-list-for-user-id.proto @@ -0,0 +1,18 @@ +syntax = "proto3"; + +package rivet.backend.pkg.mm.lobby_list_for_user_id; + +import "proto/common.proto"; + +message Request { + repeated rivet.common.Uuid user_ids = 1; +} + +message Response { + message User { + rivet.common.Uuid user_id = 1; + repeated rivet.common.Uuid lobby_ids = 2; + } + + repeated User users = 1; +} diff --git a/svc/pkg/mm/types/lobby-state-get.proto b/svc/pkg/mm/types/lobby-state-get.proto new file mode 100644 index 0000000000..aa120f811f --- /dev/null +++ b/svc/pkg/mm/types/lobby-state-get.proto @@ -0,0 +1,18 @@ +syntax = "proto3"; + +package rivet.backend.pkg.mm.lobby_state_get; + +import "proto/common.proto"; + +message Request { + repeated rivet.common.Uuid lobby_ids = 1; +} + +message Response { + message Lobby { + rivet.common.Uuid lobby_id = 1; + optional string state_json = 2; + } + + repeated Lobby lobbies = 1; +} diff --git a/svc/pkg/mm/types/msg/lobby-create.proto b/svc/pkg/mm/types/msg/lobby-create.proto index d7baf93874..5b9365c5f6 100644 --- a/svc/pkg/mm/types/msg/lobby-create.proto +++ b/svc/pkg/mm/types/msg/lobby-create.proto @@ -3,6 +3,7 @@ syntax = "proto3"; package rivet.backend.pkg.mm.msg.lobby_create; import "proto/common.proto"; +import "proto/backend/matchmaker.proto"; /// name = "msg-mm-lobby-create" /// parameters = [ @@ -36,5 +37,16 @@ message Message { // If a lobby row was preemptively inserted for this lobby. bool preemptively_created = 7; + + // The user (if any) that triggered this lobby's creation (either by /find or /create). + optional rivet.common.Uuid creator_user_id = 8; + // If this is a custom lobby created by a user. + bool is_custom = 9; + // Publicity of the lobby. Private lobbies do not show up in /list. Defaults to + // public when not set. + optional rivet.backend.matchmaker.Lobby.Publicity publicity = 10; + + // Extra lobby config provided by the user in /create. Sent to the lobby as an env var. + optional string lobby_config_json = 11; } diff --git a/svc/pkg/mm/types/msg/lobby-find-fail.proto b/svc/pkg/mm/types/msg/lobby-find-fail.proto index 01eba4c06b..d4d48e69bf 100644 --- a/svc/pkg/mm/types/msg/lobby-find-fail.proto +++ b/svc/pkg/mm/types/msg/lobby-find-fail.proto @@ -10,7 +10,7 @@ enum ErrorCode { STALE_MESSAGE = 1; TOO_MANY_PLAYERS_FROM_SOURCE = 101; - + LOBBY_STOPPED = 201; LOBBY_CLOSED = 202; LOBBY_NOT_FOUND = 203; @@ -19,8 +19,15 @@ enum ErrorCode { LOBBY_COUNT_OVER_MAX = 206; REGION_NOT_ENABLED = 207; LOBBY_STOPPED_PREMATURELY = 208; - + DEV_TEAM_INVALID_STATUS = 301; + + FIND_DISABLED = 401; + JOIN_DISABLED = 402; + VERIFICATION_FAILED = 403; + VERIFICATION_REQUEST_FAILED = 404; + IDENTITY_REQUIRED = 405; + REGISTRATION_REQUIRED = 406; } /// name = "msg-mm-lobby-find-fail" diff --git a/svc/pkg/mm/types/msg/lobby-find.proto b/svc/pkg/mm/types/msg/lobby-find.proto index 3229dbd509..0321d8e658 100644 --- a/svc/pkg/mm/types/msg/lobby-find.proto +++ b/svc/pkg/mm/types/msg/lobby-find.proto @@ -35,5 +35,12 @@ message Message { rivet.backend.matchmaker.query.Direct direct = 101; rivet.backend.matchmaker.query.LobbyGroup lobby_group = 102; }; + + // The user ID of the game user creating this find request (if there is one). + optional rivet.common.Uuid user_id = 201; + // JSON verification data from the user. + optional string verification_data_json = 202; + // Bypasses user data verification (if the give lobby group has any). + bool bypass_verification = 203; } diff --git a/svc/pkg/mm/types/msg/lobby-state-set-complete.proto b/svc/pkg/mm/types/msg/lobby-state-set-complete.proto new file mode 100644 index 0000000000..5fcd27149a --- /dev/null +++ b/svc/pkg/mm/types/msg/lobby-state-set-complete.proto @@ -0,0 +1,13 @@ +syntax = "proto3"; + +package rivet.backend.pkg.mm.msg.lobby_state_set_complete; + +import "proto/common.proto"; + +/// name = "msg-mm-lobby-state-set-complete" +/// parameters = [ +/// { name = "lobby_id" }, +/// ] +message Message { + rivet.common.Uuid lobby_id = 1; +} diff --git a/svc/pkg/mm/types/msg/lobby-state-set.proto b/svc/pkg/mm/types/msg/lobby-state-set.proto new file mode 100644 index 0000000000..d1cff2a74a --- /dev/null +++ b/svc/pkg/mm/types/msg/lobby-state-set.proto @@ -0,0 +1,14 @@ +syntax = "proto3"; + +package rivet.backend.pkg.mm.msg.lobby_state_set; + +import "proto/common.proto"; + +/// name = "msg-mm-lobby-state-set" +/// parameters = [ +/// { name = "lobby_id" }, +/// ] +message Message { + rivet.common.Uuid lobby_id = 1; + optional string state_json = 2; +} diff --git a/svc/pkg/mm/util/Cargo.toml b/svc/pkg/mm/util/Cargo.toml index df5b724a59..4d7aa656b3 100644 --- a/svc/pkg/mm/util/Cargo.toml +++ b/svc/pkg/mm/util/Cargo.toml @@ -7,7 +7,15 @@ license = "Apache-2.0" [dependencies] bit-vec = "0.6" +chirp-client = { path = "../../../../lib/chirp/client" } +http = "0.2" +rivet-operation = { path = "../../../../lib/operation/core" } rivet-util = { path = "../../../../lib/util/core" } serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0" strum = { version = "0.24", features = ["derive"] } uuid = { version = "1", features = ["v4", "serde"] } + +mm-lobby-list-for-user-id = { path = "../ops/lobby-list-for-user-id" } +region-get = { path = "../../region/ops/get" } +user-identity-get = { path = "../../user-identity/ops/get" } \ No newline at end of file diff --git a/svc/pkg/mm/util/src/consts.rs b/svc/pkg/mm/util/src/consts.rs index c1cc3c6373..7b5f235385 100644 --- a/svc/pkg/mm/util/src/consts.rs +++ b/svc/pkg/mm/util/src/consts.rs @@ -1,6 +1,7 @@ use rivet_util as util; -pub const LOBBY_READY_TIMEOUT: i64 = util::duration::minutes(5); // Also see mm-gc.LOBBY_READY_TIMEOUT +// TODO: Lower this again +pub const LOBBY_READY_TIMEOUT: i64 = util::duration::minutes(10); // Also see mm-gc.LOBBY_READY_TIMEOUT pub const PLAYER_READY_TIMEOUT: i64 = util::duration::minutes(2); // Also see mm-gc.LOBBY_READY_TIMEOUT pub const MIN_HOST_PORT: u16 = 26000; diff --git a/svc/pkg/mm/util/src/key.rs b/svc/pkg/mm/util/src/key.rs index d93bba3970..7a8ea2a373 100644 --- a/svc/pkg/mm/util/src/key.rs +++ b/svc/pkg/mm/util/src/key.rs @@ -53,6 +53,10 @@ pub mod lobby_config { pub ready_ts: Option, #[serde(rename = "c")] pub is_closed: bool, + #[serde(rename = "cu")] + pub is_custom: bool, + #[serde(rename = "st", skip_serializing_if = "Option::is_none")] + pub state_json: Option, } pub const NAMESPACE_ID: &str = "ns"; @@ -64,6 +68,8 @@ pub mod lobby_config { pub const PREEMPTIVE: &str = "p"; pub const READY_TS: &str = "rt"; pub const IS_CLOSED: &str = "c"; + pub const IS_CUSTOM: &str = "cu"; + pub const STATE_JSON: &str = "st"; } /// HASH diff --git a/svc/pkg/mm/util/src/lib.rs b/svc/pkg/mm/util/src/lib.rs index 89cef1142d..2c55146a15 100644 --- a/svc/pkg/mm/util/src/lib.rs +++ b/svc/pkg/mm/util/src/lib.rs @@ -2,6 +2,7 @@ pub mod consts; pub mod defaults; pub mod key; pub mod test; +pub mod verification; pub mod version_migrations; pub enum JoinKind { diff --git a/svc/pkg/mm/util/src/verification.rs b/svc/pkg/mm/util/src/verification.rs new file mode 100644 index 0000000000..5d737a1866 --- /dev/null +++ b/svc/pkg/mm/util/src/verification.rs @@ -0,0 +1,288 @@ +use http::StatusCode; +use proto::backend::{self, pkg::*}; +use rivet_operation::prelude::*; +use serde::Serialize; +use uuid::Uuid; + +#[derive(Serialize)] +pub struct ExternalVerificationRequest { + pub verification_data: Option, + pub lobby: Lobby, + pub join_kind: JoinKind, + pub kind: ConnectionKind, +} + +#[derive(Serialize)] +pub struct Lobby { + pub namespace_id: Uuid, + pub game_mode_id: Uuid, + pub game_mode_name_id: String, + + pub info: Option, + pub state: Option, + pub config: Option, +} + +#[derive(Serialize)] +pub struct LobbyInfo { + pub lobby_id: Uuid, + pub region_id: Uuid, + pub region_name_id: String, + pub create_ts: String, + pub is_closed: bool, +} + +#[derive(Serialize)] +pub enum JoinKind { + Normal, + Party, +} + +#[derive(Copy, Clone, Serialize)] +pub enum ConnectionKind { + Find, + Join, + Create, +} + +pub struct VerifyConfigOpts<'a> { + pub kind: ConnectionKind, + pub namespace_id: Uuid, + pub user_id: Option, + + pub lobby_group: &'a backend::matchmaker::LobbyGroup, + pub lobby_group_meta: &'a backend::matchmaker::LobbyGroupMeta, + pub lobby_info: Option<&'a backend::matchmaker::Lobby>, + pub lobby_state_json: Option<&'a str>, + + pub verification_data_json: Option<&'a str>, + pub lobby_config_json: Option<&'a str>, + pub custom_lobby_publicity: Option, +} + +/// Verifies everything required to make a find request or create a custom lobby. +pub async fn verify_config( + ctx: &OperationContext<()>, + opts: &VerifyConfigOpts<'_>, +) -> GlobalResult<()> { + // Get required verifications + let (identity_requirement, external_request_config) = match ( + opts.kind, + opts.lobby_group.find_config.as_ref(), + opts.lobby_group.join_config.as_ref(), + opts.lobby_group.create_config.as_ref(), + ) { + (ConnectionKind::Find, Some(find_config), _, _) => { + if !find_config.enabled { + panic_with!(MATCHMAKER_FIND_DISABLED); + } + + ( + internal_unwrap_owned!( + backend::matchmaker::IdentityRequirement::from_i32( + find_config.identity_requirement + ), + "invalid identity requirement variant" + ), + find_config.verification_config.as_ref().map(|config| { + backend::net::ExternalRequestConfig { + url: config.url.clone(), + method: backend::net::HttpMethod::Post as i32, + headers: config.headers.clone(), + } + }), + ) + } + (ConnectionKind::Join, _, Some(join_config), _) => { + if !join_config.enabled { + panic_with!(MATCHMAKER_JOIN_DISABLED); + } + + ( + internal_unwrap_owned!( + backend::matchmaker::IdentityRequirement::from_i32( + join_config.identity_requirement + ), + "invalid identity requirement variant" + ), + join_config.verification_config.as_ref().map(|config| { + backend::net::ExternalRequestConfig { + url: config.url.clone(), + method: backend::net::HttpMethod::Post as i32, + headers: config.headers.clone(), + } + }), + ) + } + (ConnectionKind::Create, _, _, Some(create_config)) => { + let publicity = internal_unwrap_owned!(opts.custom_lobby_publicity); + + // Verify publicity + match ( + publicity, + create_config.enable_public, + create_config.enable_private, + ) { + (backend::matchmaker::lobby::Publicity::Public, true, _) => {} + (backend::matchmaker::lobby::Publicity::Private, _, true) => {} + _ => { + panic_with!( + MATCHMAKER_CUSTOM_LOBBY_CONFIG_INVALID, + reason = "given publicity not allowed" + ); + } + } + + // Verify lobby count + if let (Some(max_lobbies_per_identity), Some(user_id)) = + (create_config.max_lobbies_per_identity, opts.user_id) + { + let lobbies_res = op!([ctx] mm_lobby_list_for_user_id { + user_ids: vec![user_id.into()], + }) + .await?; + let user = internal_unwrap_owned!(lobbies_res.users.first()); + assert_with!( + (user.lobby_ids.len() as u64) < max_lobbies_per_identity, + MATCHMAKER_CUSTOM_LOBBY_LIMIT_REACHED + ); + } + + ( + internal_unwrap_owned!( + backend::matchmaker::IdentityRequirement::from_i32( + create_config.identity_requirement + ), + "invalid identity requirement variant" + ), + create_config.verification_config.as_ref().map(|config| { + backend::net::ExternalRequestConfig { + url: config.url.clone(), + method: backend::net::HttpMethod::Post as i32, + headers: config.headers.clone(), + } + }), + ) + } + (ConnectionKind::Create, _, _, None) => { + panic_with!(MATCHMAKER_CUSTOM_LOBBIES_DISABLED); + } + _ => (backend::matchmaker::IdentityRequirement::None, None), + }; + + // Verify identity requirement + match (identity_requirement, opts.user_id) { + (backend::matchmaker::IdentityRequirement::Registered, Some(user_id)) => { + let user_identities_res = op!([ctx] user_identity_get { + user_ids: vec![user_id.into()], + }) + .await?; + let user = internal_unwrap_owned!( + user_identities_res.users.first(), + "could not find user identities" + ); + let is_registered = !user.identities.is_empty(); + + if !is_registered { + panic_with!(MATCHMAKER_REGISTRATION_REQUIRED); + } + } + ( + backend::matchmaker::IdentityRequirement::Guest + | backend::matchmaker::IdentityRequirement::Registered, + None, + ) => { + panic_with!(MATCHMAKER_IDENTITY_REQUIRED); + } + _ => {} + } + + // Verify lobby config + if let Some(lobby_config_json) = opts.lobby_config_json { + assert_with!( + lobby_config_json.len() as u64 <= util::file_size::kibibytes(16), + MATCHMAKER_CUSTOM_LOBBY_CONFIG_INVALID, + reason = "too large (> 16KiB)" + ); + } + + // Verify user data externally + if external_request_config.is_some() { + // Build lobby info + let lobby_info = if let Some(l) = &opts.lobby_info { + // Fetch region data for readable name + let region_id = internal_unwrap_owned!(l.region_id); + let regions_res = op!([ctx] region_get { + region_ids: vec![region_id], + }) + .await?; + let region = internal_unwrap_owned!(regions_res.regions.first()); + + Some(LobbyInfo { + lobby_id: internal_unwrap!(l.lobby_id).as_uuid(), + region_id: region_id.as_uuid(), + region_name_id: region.name_id.clone(), + create_ts: util::timestamp::to_string(l.create_ts)?, + is_closed: l.is_closed, + }) + } else { + None + }; + + // Build body + let body = ExternalVerificationRequest { + verification_data: opts + .verification_data_json + .as_ref() + .map(|json| serde_json::from_str::(json)) + .transpose()?, + lobby: Lobby { + game_mode_id: internal_unwrap!(opts.lobby_group_meta.lobby_group_id).as_uuid(), + game_mode_name_id: opts.lobby_group.name_id.clone(), + namespace_id: opts.namespace_id, + + info: lobby_info, + state: opts + .lobby_state_json + .as_ref() + .map(|json| serde_json::from_str::(json)) + .transpose()?, + config: opts + .lobby_config_json + .as_ref() + .map(|json| serde_json::from_str::(json)) + .transpose()?, + }, + join_kind: JoinKind::Normal, + kind: opts.kind, + }; + + // Send request + let request_id = Uuid::new_v4(); + let external_res = msg!([ctx] external::msg::request_call(request_id) + -> Result + { + request_id: Some(request_id.into()), + config: external_request_config, + timeout: util::duration::seconds(10) as u64, + body: Some(serde_json::to_vec(&body)?), + ..Default::default() + }) + .await?; + + // Handle status code + if let Ok(res) = external_res { + let status = StatusCode::from_u16(res.status_code as u16)?; + + tracing::info!(?status, "user verification response"); + + if !status.is_success() { + panic_with!(MATCHMAKER_VERIFICATION_FAILED); + } + } else { + panic_with!(MATCHMAKER_VERIFICATION_REQUEST_FAILED); + } + } + + Ok(()) +} diff --git a/svc/pkg/mm/worker/Cargo.toml b/svc/pkg/mm/worker/Cargo.toml index b4c5541306..29a122bb81 100644 --- a/svc/pkg/mm/worker/Cargo.toml +++ b/svc/pkg/mm/worker/Cargo.toml @@ -23,6 +23,7 @@ serde = { version = "1.0", features = ["derive"] } util-job = { package = "rivet-util-job", path = "../../job/util" } util-mm = { package = "rivet-util-mm", path = "../../mm/util" } http = "0.2" +heck = "0.3" build-get = { path = "../../build/ops/get" } game-get = { path = "../../game/ops/get" } @@ -35,7 +36,9 @@ mm-config-version-get = { path = "../../mm-config/ops/version-get" } mm-lobby-find-fail = { path = "../ops/lobby-find-fail" } mm-lobby-find-lobby-query-list = { path = "../ops/lobby-find-lobby-query-list" } mm-lobby-find-try-complete = { path = "../ops/lobby-find-try-complete" } +mm-lobby-get = { path = "../ops/lobby-get" } mm-lobby-idle-update = { path = "../ops/lobby-idle-update" } +mm-lobby-state-get = { path = "../ops/lobby-state-get" } region-get = { path = "../../region/ops/get" } team-dev-get = { path = "../../team-dev/ops/get" } tier-list = { path = "../../tier/ops/list" } @@ -45,7 +48,7 @@ upload-get = { path = "../../upload/ops/get" } upload-prepare = { path = "../../upload/ops/prepare" } [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] @@ -56,8 +59,11 @@ faker-game = { path = "../../faker/ops/game" } faker-game-version = { path = "../../faker/ops/game-version" } faker-mm-lobby = { path = "../../faker/ops/mm-lobby" } faker-region = { path = "../../faker/ops/region" } +faker-user = { path = "../../faker/ops/user" } game-namespace-version-set = { path = "../../game/ops/namespace-version-set" } mm-config-namespace-config-set = { path = "../../mm-config/ops/namespace-config-set" } mm-config-version-get = { path = "../../mm-config/ops/version-get" } -mm-lobby-player-count = { path = "../ops/lobby-player-count" } mm-lobby-get = { path = "../ops/lobby-get" } +mm-lobby-player-count = { path = "../ops/lobby-player-count" } +region-list = { path = "../../region/ops/list" } +user-identity-create = { path = "../../user-identity/ops/create" } diff --git a/svc/pkg/mm/worker/Service.toml b/svc/pkg/mm/worker/Service.toml index 0ccd35dacd..a9d04db017 100644 --- a/svc/pkg/mm/worker/Service.toml +++ b/svc/pkg/mm/worker/Service.toml @@ -6,3 +6,7 @@ kind = "rust" [consumer] +[databases] +db-mm-state = {} +redis-mm = {} + diff --git a/svc/pkg/mm/worker/redis-scripts/lobby_create.lua b/svc/pkg/mm/worker/redis-scripts/lobby_create.lua index 16ee91a7e1..41635457d4 100644 --- a/svc/pkg/mm/worker/redis-scripts/lobby_create.lua +++ b/svc/pkg/mm/worker/redis-scripts/lobby_create.lua @@ -22,7 +22,8 @@ redis.call('ZADD', key_lobby_available_spots_party, lobby_config['mpp'] - player redis.call('ZADD', key_lobby_unready, tonumber(ready_expire_ts), lobby_id) -- Add to idle lobbies if needed -if player_count == 0 then +local is_custom = lobby_config['cu'] +if player_count == 0 and not is_custom then redis.call('ZADD', key_idle_lobby_ids, ts, lobby_id) redis.call('HSET', key_idle_lobby_lobby_group_ids, lobby_id, lobby_config['lg']) end diff --git a/svc/pkg/mm/worker/redis-scripts/lobby_find.lua b/svc/pkg/mm/worker/redis-scripts/lobby_find.lua index eca22568ba..555ab12300 100644 --- a/svc/pkg/mm/worker/redis-scripts/lobby_find.lua +++ b/svc/pkg/mm/worker/redis-scripts/lobby_find.lua @@ -22,14 +22,14 @@ if query.kind.direct ~= nil then -- Check lobby exists if redis.call('EXISTS', key_direct_lobby_config) == 0 then - return {'err', 'LOBBY_NOT_FOUND'} + return { 'err', 'LOBBY_NOT_FOUND' } end -- Check lobby is not closed - local is_closed = redis.call('HGET', key_direct_lobby_config, 'c') == '1' - if is_closed then - return {'err', 'LOBBY_CLOSED'} - end + -- local is_closed = redis.call('HGET', key_direct_lobby_config, 'c') == '1' + -- if is_closed then + -- return {'err', 'LOBBY_CLOSED'} + -- end -- Get max player count local max_player_count = nil @@ -44,7 +44,7 @@ if query.kind.direct ~= nil then -- Validate player count local player_count = redis.call('ZCARD', key_direct_lobby_player_ids) if player_count + table.getn(query.players) > max_player_count then - return {'err', 'LOBBY_FULL'} + return { 'err', 'LOBBY_FULL' } end lobby_id = query.kind.direct.lobby_id @@ -63,7 +63,8 @@ elseif query.kind.lobby_group ~= nil then -- instead of `max_players_party` because `max_players_party` is -- only relevant when joining a lobby with the exact lobby ID (i.e. -- where `max_players_direct` would normally be used). - local lobby = redis.call('ZRANGEBYSCORE', key_available_spots, table.getn(query.players), '+inf', 'WITHSCORES', 'LIMIT', '0', '1') + local lobby = redis.call('ZRANGEBYSCORE', key_available_spots, table.getn(query.players), '+inf', 'WITHSCORES', + 'LIMIT', '0', '1') if table.getn(lobby) > 0 then local lobby_id = lobby[1] local available_spots = tonumber(lobby[2]) @@ -93,8 +94,10 @@ elseif query.kind.lobby_group ~= nil then redis.call('HSET', key_auto_create_lobby_config, k, tostring(v)) end redis.call('ZADD', key_auto_create_ns_lobby_ids, ts, auto_create.lobby_id) - redis.call('ZADD', key_auto_create_lobby_available_spots_normal, auto_create.lobby_config['mpn'], auto_create.lobby_id) - redis.call('ZADD', key_auto_create_lobby_available_spots_party, auto_create.lobby_config['mpp'], auto_create.lobby_id) + redis.call('ZADD', key_auto_create_lobby_available_spots_normal, auto_create.lobby_config['mpn'], + auto_create.lobby_id) + redis.call('ZADD', key_auto_create_lobby_available_spots_party, auto_create.lobby_config['mpp'], + auto_create.lobby_id) redis.call('ZADD', key_lobby_unready, tonumber(auto_create.ready_expire_ts), auto_create.lobby_id) end @@ -104,7 +107,7 @@ elseif query.kind.lobby_group ~= nil then elseif auto_create ~= nil then lobby_id = auto_create.lobby_id else - return {'err', 'NO_AVAILABLE_LOBBIES'} + return { 'err', 'NO_AVAILABLE_LOBBIES' } end else return redis.error_reply('Invalid query kind') @@ -131,10 +134,14 @@ local max_players_party = tonumber(redis.call('HGET', key_lobby_config, 'mpp')) -- Build keys for the given lobby ID local key_lobby_find_queries = 'mm:lobby:' .. lobby_id .. ':find_queries' local key_lobby_player_ids = 'mm:lobby:' .. lobby_id .. ':player_ids' -local key_lobby_available_spots_normal = 'mm:ns:' .. namespace_id .. ':region:' .. region_id .. ':lg:' .. lobby_group_id .. ':lobby:available_spots:normal' -local key_lobby_available_spots_party = 'mm:ns:' .. namespace_id .. ':region:' .. region_id .. ':lg:' .. lobby_group_id .. ':lobby:available_spots:party' -local key_idle_lobby_ids = 'mm:ns:' .. namespace_id .. ':region:' .. region_id .. ':lg:' .. lobby_group_id .. ':idle_lobby_ids' -local key_idle_lobby_lobby_group_ids = 'mm:ns:' .. namespace_id .. ':region:' .. region_id .. ':lobby:idle:lobby_group_ids' +local key_lobby_available_spots_normal = 'mm:ns:' .. +namespace_id .. ':region:' .. region_id .. ':lg:' .. lobby_group_id .. ':lobby:available_spots:normal' +local key_lobby_available_spots_party = 'mm:ns:' .. +namespace_id .. ':region:' .. region_id .. ':lg:' .. lobby_group_id .. ':lobby:available_spots:party' +local key_idle_lobby_ids = 'mm:ns:' .. +namespace_id .. ':region:' .. region_id .. ':lg:' .. lobby_group_id .. ':idle_lobby_ids' +local key_idle_lobby_lobby_group_ids = 'mm:ns:' .. +namespace_id .. ':region:' .. region_id .. ':lobby:idle:lobby_group_ids' -- Assert lobby state if #lobby_id ~= 36 then @@ -201,5 +208,4 @@ for _, player in ipairs(query.players) do end -return {'ok', {lobby_id, region_id, lobby_group_id}} - +return { 'ok', { lobby_id, region_id, lobby_group_id } } diff --git a/svc/pkg/mm/worker/src/main.rs b/svc/pkg/mm/worker/src/main.rs index 3e30fad20a..fd07975155 100644 --- a/svc/pkg/mm/worker/src/main.rs +++ b/svc/pkg/mm/worker/src/main.rs @@ -11,14 +11,15 @@ fn main() -> Result<(), ManagerError> { lobby_cleanup, lobby_closed_set, lobby_create, - lobby_find, lobby_find_job_run_fail, lobby_find_lobby_cleanup, lobby_find_lobby_create_fail, lobby_find_lobby_ready, + lobby_find, lobby_history_export, lobby_job_run_cleanup, lobby_ready_set, + lobby_state_set, lobby_stop, player_register, player_remove, diff --git a/svc/pkg/mm/worker/src/workers/lobby_cleanup.rs b/svc/pkg/mm/worker/src/workers/lobby_cleanup.rs index 28766599e8..afc556c6e2 100644 --- a/svc/pkg/mm/worker/src/workers/lobby_cleanup.rs +++ b/svc/pkg/mm/worker/src/workers/lobby_cleanup.rs @@ -15,7 +15,7 @@ struct LobbyRow { } #[worker(name = "mm-lobby-cleanup")] -async fn worker(ctx: OperationContext) -> GlobalResult<()> { +async fn worker(ctx: &OperationContext) -> GlobalResult<()> { // NOTE: Idempotent let lobby_id = internal_unwrap!(ctx.lobby_id).as_uuid(); diff --git a/svc/pkg/mm/worker/src/workers/lobby_closed_set.rs b/svc/pkg/mm/worker/src/workers/lobby_closed_set.rs index 6d5a4b7f5a..7e5659c980 100644 --- a/svc/pkg/mm/worker/src/workers/lobby_closed_set.rs +++ b/svc/pkg/mm/worker/src/workers/lobby_closed_set.rs @@ -15,7 +15,7 @@ struct LobbyRow { } #[worker(name = "mm-lobby-closed-set")] -async fn worker(ctx: OperationContext) -> GlobalResult<()> { +async fn worker(ctx: &OperationContext) -> GlobalResult<()> { let crdb = ctx.crdb("db-mm-state").await?; let lobby_id = internal_unwrap!(ctx.lobby_id).as_uuid(); diff --git a/svc/pkg/mm/worker/src/workers/lobby_create/mod.rs b/svc/pkg/mm/worker/src/workers/lobby_create/mod.rs index 4a26ff9f5b..2e928ba6f3 100644 --- a/svc/pkg/mm/worker/src/workers/lobby_create/mod.rs +++ b/svc/pkg/mm/worker/src/workers/lobby_create/mod.rs @@ -6,13 +6,6 @@ use std::ops::Deref; mod nomad_job; -enum DeliveryMethod { - Ats, - S3Direct, -} - -const DELIVERY_METHOD: DeliveryMethod = DeliveryMethod::S3Direct; - lazy_static::lazy_static! { static ref NOMAD_CONFIG: nomad_client::apis::configuration::Configuration = nomad_util::config_from_env().unwrap(); @@ -52,7 +45,7 @@ async fn fail( } #[worker(name = "mm-lobby-create")] -async fn worker(ctx: OperationContext) -> GlobalResult<()> { +async fn worker(ctx: &OperationContext) -> GlobalResult<()> { let crdb = ctx.crdb("db-mm-state").await?; let lobby_id = internal_unwrap!(ctx.lobby_id).as_uuid(); @@ -60,6 +53,7 @@ async fn worker(ctx: OperationContext) -> Global let lobby_group_id = internal_unwrap!(ctx.lobby_group_id).as_uuid(); let region_id = internal_unwrap!(ctx.region_id).as_uuid(); let create_ray_id = ctx.region_id.as_ref().map(common::Uuid::as_uuid); + let creator_user_id = ctx.creator_user_id.as_ref().map(common::Uuid::as_uuid); // Check for stale message if ctx.req_dt() > util::duration::seconds(60) { @@ -73,13 +67,7 @@ async fn worker(ctx: OperationContext) -> Global .await; } - let ( - namespace, - mm_ns_config, - (lobby_group, lobby_group_meta, version_id), - (region, cdn_region), - tiers, - ) = tokio::try_join!( + let (namespace, mm_ns_config, (lobby_group, lobby_group_meta, version_id), region, tiers) = tokio::try_join!( fetch_namespace(ctx, namespace_id), fetch_mm_namespace_config(ctx, namespace_id), fetch_lobby_group_config(ctx, lobby_group_id), @@ -168,6 +156,11 @@ async fn worker(ctx: OperationContext) -> Global run_id, create_ray_id: ctx.ray_id(), lobby_group: lobby_group.clone(), + creator_user_id, + is_custom: ctx.is_custom, + publicity: ctx + .publicity + .and_then(backend::matchmaker::lobby::Publicity::from_i32), }; rivet_pools::utils::crdb::tx(&crdb, |tx| { Box::pin(update_db(ctx.ts(), tx, insert_opts.clone())) @@ -191,6 +184,8 @@ async fn worker(ctx: OperationContext) -> Global preemptive: false, is_closed: false, ready_ts: None, + is_custom: ctx.is_custom, + state_json: None, })?) .arg(ctx.ts() + util_mm::consts::LOBBY_READY_TIMEOUT) .key(key::lobby_config(lobby_id)) @@ -232,7 +227,6 @@ async fn worker(ctx: OperationContext) -> Global &lobby_group, &lobby_group_meta, ®ion, - &cdn_region, tier, run_id, lobby_id, @@ -280,22 +274,15 @@ async fn worker(ctx: OperationContext) -> Global async fn fetch_region( ctx: &OperationContext, region_id: Uuid, -) -> GlobalResult<(backend::region::Region, backend::region::Region)> { +) -> GlobalResult { tracing::info!(?region_id, "fetching primary region"); let primary_get_res = op!([ctx] region_get { region_ids: vec![region_id.into()], }) .await?; let region = internal_unwrap_owned!(primary_get_res.regions.first(), "region not found"); - let cdn_region_id = internal_unwrap!(region.cdn_region_id).as_uuid(); - tracing::info!(?region_id, "fetching cdn region"); - let cdn_get_res = op!([ctx] region_get { - region_ids: vec![cdn_region_id.into()], - }) - .await?; - let cdn_region = internal_unwrap_owned!(cdn_get_res.regions.first()); - Ok((region.deref().clone(), cdn_region.deref().clone())) + Ok(region.clone()) } #[tracing::instrument] @@ -322,9 +309,8 @@ async fn fetch_namespace( }) .await?; - let namespace = internal_unwrap!(get_res.namespaces.first(), "namespace not found") - .deref() - .clone(); + let namespace = + internal_unwrap_owned!(get_res.namespaces.first(), "namespace not found").clone(); Ok(namespace) } @@ -340,7 +326,7 @@ async fn fetch_mm_namespace_config( .await?; let namespace = internal_unwrap!( - internal_unwrap!(get_res.namespaces.first(), "namespace not found").config + internal_unwrap_owned!(get_res.namespaces.first(), "namespace not found").config ) .deref() .clone(); @@ -479,6 +465,9 @@ struct UpdateDbOpts { run_id: Uuid, create_ray_id: Uuid, lobby_group: backend::matchmaker::LobbyGroup, + creator_user_id: Option, + is_custom: bool, + publicity: Option, } #[tracing::instrument(skip_all)] @@ -497,7 +486,7 @@ async fn update_db( "SELECT stop_ts, preemptive_create_ts FROM lobbies WHERE lobby_id = $1 FOR UPDATE", ) .bind(opts.lobby_id) - .fetch_optional(&mut *tx) + .fetch_optional(&mut **tx) .await?; if let Some((stop_ts, preemptive_create_ts)) = lobby_row { if preemptive_create_ts.is_none() { @@ -528,9 +517,12 @@ async fn update_db( max_players_direct, max_players_party, - is_closed + is_closed, + creator_user_id, + is_custom, + publicity ) - VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, false) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, false, $12, $13, $14) " )) .bind(opts.lobby_id) @@ -544,7 +536,13 @@ async fn update_db( .bind(opts.lobby_group.max_players_normal as i64) .bind(opts.lobby_group.max_players_direct as i64) .bind(opts.lobby_group.max_players_party as i64) - .execute(&mut *tx) + .bind(opts.creator_user_id) + .bind(opts.is_custom) + .bind( + opts.publicity + .unwrap_or(backend::matchmaker::lobby::Publicity::Public) as i32 as i64, + ) + .execute(&mut **tx) .await?; Ok(()) @@ -560,7 +558,6 @@ async fn create_docker_job( lobby_group: &backend::matchmaker::LobbyGroup, lobby_group_meta: &backend::matchmaker::LobbyGroupMeta, region: &backend::region::Region, - cdn_region: &backend::region::Region, tier: &backend::region::Tier, run_id: Uuid, lobby_id: Uuid, @@ -573,7 +570,7 @@ async fn create_docker_job( let resolve_perf = ctx.perf().start("resolve-image-artifact-url").await; let build_id = internal_unwrap!(runtime.build_id).as_uuid(); - let image_artifact_url = resolve_image_artifact_url(ctx, build_id, cdn_region).await?; + let image_artifact_url = resolve_image_artifact_url(ctx, build_id, region).await?; resolve_perf.end(); // Validate build exists and belongs to this game @@ -585,7 +582,12 @@ async fn create_docker_job( let build = internal_unwrap_owned!(build_get.builds.first()); // Generate the Docker job - let job_spec = nomad_job::gen_lobby_docker_job(runtime, &build.image_tag, tier)?; + let job_spec = nomad_job::gen_lobby_docker_job( + runtime, + &build.image_tag, + tier, + ctx.lobby_config_json.as_ref(), + )?; let job_spec_json = serde_json::to_string(&job_spec)?; // Build proxied ports for each exposed port @@ -709,7 +711,7 @@ async fn create_docker_job( async fn resolve_image_artifact_url( ctx: &OperationContext, build_id: Uuid, - cdn_region: &backend::region::Region, + region: &backend::region::Region, ) -> GlobalResult { let build_res = op!([ctx] build_get { build_ids: vec![build_id.into()], @@ -725,23 +727,75 @@ async fn resolve_image_artifact_url( .await?; let upload = internal_unwrap_owned!(upload_res.uploads.first()); - match DELIVERY_METHOD { - DeliveryMethod::Ats => { - // TODO: Auto-generate password for this & encode in to infra/salt/salt/traffic_server/files/consul/traffic_server.hcl.j2 - // See tf/svc/traefik/main.tf - // let http_auth = "job_run_image:XXXX"; - let http_auth: String = todo!("need to auto-generate password"); - - // TODO: Unproxied storage endopint was removed. Replace with Nebula address. We can't - // use Consul to resolve this though, since Consul is not installed on the edge nodes. - // Pull the image from the CDN region instead of the default region for - // faster boot times. + // Get provider + let proto_provider = internal_unwrap_owned!( + backend::upload::Provider::from_i32(upload.provider), + "invalid upload provider" + ); + let provider = match proto_provider { + backend::upload::Provider::Minio => s3_util::Provider::Minio, + backend::upload::Provider::Backblaze => s3_util::Provider::Backblaze, + backend::upload::Provider::Aws => s3_util::Provider::Aws, + }; + + match internal_unwrap_owned!( + std::env::var("RIVET_MM_LOBBY_DELIVERY_METHOD").ok(), + "missing RIVET_MM_LOBBY_DELIVERY_METHOD" + ) + .as_str() + { + // "s3_direct" => { + // tracing::info!("using s3 direct delivery"); + + // let bucket = "bucket-build"; + // let bucket_screaming = bucket.to_uppercase().replace('-', "_"); + + // // Build client + // let s3_client = s3_util::Client::from_env_opt( + // bucket, + // provider, + // s3_util::EndpointKind::InternalResolved, + // ) + // .await?; + + // let upload_id = internal_unwrap!(upload.upload_id).as_uuid(); + // let presigned_req = s3_client + // .get_object() + // .bucket(s3_client.bucket()) + // .key(format!("{upload_id}/image.tar")) + // .presigned( + // s3_util::aws_sdk_s3::presigning::config::PresigningConfig::builder() + // .expires_in(std::time::Duration::from_secs(15 * 60)) + // .build()?, + // ) + // .await?; + + // let addr = presigned_req.uri().clone(); + + // let addr_str = addr.to_string(); + // tracing::info!(addr = %addr_str, "resolved artifact s3 presigned request"); + + // Ok(addr_str) + // } + "traffic_server" => { + tracing::info!("using traffic server delivery"); + + // HACK: Hardcode ATS IP since this will be replaced shortly + let ats_url = if region.name_id == "lnd-atl" { + "10.0.25.2" + } else if region.name_id == "lnd-fra" { + "10.0.50.2" + } else { + tracing::info!(?region.name_id); + internal_panic!("invalid region"); + }; + let upload_id = internal_unwrap!(upload.upload_id).as_uuid(); let addr = format!( - "https://{auth}@cdn.{cdn_region}.{domain}/build/{upload_id}/image.tar", - cdn_region = cdn_region.name_id, - auth = http_auth, - domain = util::env::domain_main(), + "http://{ats_url}:9300/s3-cache/{provider}/{namespace}-bucket-build/{upload_id}/image.tar", + ats_url = ats_url, + provider = heck::KebabCase::to_kebab_case(provider.to_string().as_str()), + namespace = util::env::namespace(), upload_id = upload_id, ); @@ -749,36 +803,8 @@ async fn resolve_image_artifact_url( Ok(addr) } - DeliveryMethod::S3Direct => { - let bucket = "bucket-build"; - let bucket_screaming = bucket.to_uppercase().replace('-', "_"); - - // Build client - let s3_client = s3_util::Client::from_env_opt( - &bucket, - s3_util::Provider::default()?, - s3_util::EndpointKind::InternalResolved, - ) - .await?; - - let upload_id = internal_unwrap!(upload.upload_id).as_uuid(); - let presigned_req = s3_client - .get_object() - .bucket(s3_client.bucket()) - .key(format!("{upload_id}/image.tar")) - .presigned( - s3_util::aws_sdk_s3::presigning::config::PresigningConfig::builder() - .expires_in(std::time::Duration::from_secs(15 * 60)) - .build()?, - ) - .await?; - - let addr = presigned_req.uri().clone(); - - let addr_str = addr.to_string(); - tracing::info!(addr = %addr_str, "resolved artifact s3 presigned request"); - - Ok(addr_str) + _ => { + internal_panic!("invalid RIVET_MM_LOBBY_DELIVERY_METHOD") } } } diff --git a/svc/pkg/mm/worker/src/workers/lobby_create/nomad_job.rs b/svc/pkg/mm/worker/src/workers/lobby_create/nomad_job.rs index 4452791ebb..1b80fadb22 100644 --- a/svc/pkg/mm/worker/src/workers/lobby_create/nomad_job.rs +++ b/svc/pkg/mm/worker/src/workers/lobby_create/nomad_job.rs @@ -44,6 +44,7 @@ pub fn gen_lobby_docker_job( runtime: &backend::matchmaker::lobby_runtime::Docker, image_tag: &str, tier: &backend::region::Tier, + lobby_config_json: Option<&String>, ) -> GlobalResult { // IMPORTANT: This job spec must be deterministic. Do not pass in parameters // that change with every run, such as the lobby ID. Ensure the @@ -115,6 +116,13 @@ pub fn gen_lobby_docker_job( v.value.replace('$', "$$"), ) }) + .chain(lobby_config_json.map(|config| { + ( + "RIVET_LOBBY_CONFIG".to_string(), + // Escape all interpolation + config.replace('$', "$$"), + ) + })) .chain( [ ("RIVET_CHAT_API_URL", "api-chat"), @@ -122,7 +130,6 @@ pub fn gen_lobby_docker_job( ("RIVET_IDENTITY_API_URL", "api-identity"), ("RIVET_KV_API_URL", "api-kv"), ("RIVET_MATCHMAKER_API_URL", "api-matchmaker"), - ("RIVET_PARTY_API_URL", "api-party"), ] .iter() .map(|(env, service)| (env.to_string(), util::env::svc_router_url(service))), diff --git a/svc/pkg/mm/worker/src/workers/lobby_find/find.rs b/svc/pkg/mm/worker/src/workers/lobby_find/find.rs index 9b137bbd93..7fedd7403e 100644 --- a/svc/pkg/mm/worker/src/workers/lobby_find/find.rs +++ b/svc/pkg/mm/worker/src/workers/lobby_find/find.rs @@ -1,6 +1,11 @@ use chirp_worker::prelude::*; use proto::backend::{ - self, matchmaker::query::JoinKind, pkg::mm::msg::lobby_find::message::Query, pkg::*, + self, + matchmaker::query::JoinKind, + pkg::{ + mm::{msg::lobby_find::message::Query, msg::lobby_find_fail::ErrorCode}, + *, + }, }; use rand::seq::SliceRandom; use redis_util::RedisResult; @@ -78,7 +83,7 @@ pub struct FindOpts<'a> { pub join_kind: JoinKind, pub players: &'a [super::Player], pub query: &'a Query, - pub lobby_group_config: Option<&'a LobbyGroupConfig>, + pub lobby_group_config: &'a LobbyGroupConfig, pub auto_create_lobby_id: Uuid, } @@ -148,9 +153,7 @@ pub async fn find( .collect::>(); // Update config for auto create lobbies - let auto_create = if let (Some(auto_create), Some(lobby_group_config)) = - (auto_create, lobby_group_config) - { + let auto_create = if let Some(auto_create) = auto_create { let region_id = internal_unwrap!(auto_create.region_id).as_uuid(); let lobby_group_id = internal_unwrap!(auto_create.lobby_group_id).as_uuid(); @@ -186,6 +189,8 @@ pub async fn find( preemptive: true, ready_ts: None, is_closed: false, + is_custom: false, + state_json: None, }, ready_expire_ts: ctx.ts() + util_mm::consts::LOBBY_READY_TIMEOUT, }) @@ -324,17 +329,17 @@ pub async fn find( .fetch_optional(crdb) .await? { - mm::msg::lobby_find_fail::ErrorCode::LobbyStopped + ErrorCode::LobbyStopped } else { - mm::msg::lobby_find_fail::ErrorCode::LobbyNotFound + ErrorCode::LobbyNotFound } } else { - mm::msg::lobby_find_fail::ErrorCode::LobbyNotFound + ErrorCode::LobbyNotFound } } - Err("LOBBY_CLOSED") => mm::msg::lobby_find_fail::ErrorCode::LobbyClosed, - Err("LOBBY_FULL") => mm::msg::lobby_find_fail::ErrorCode::LobbyFull, - Err("NO_AVAILABLE_LOBBIES") => mm::msg::lobby_find_fail::ErrorCode::NoAvailableLobbies, + Err("LOBBY_CLOSED") => ErrorCode::LobbyClosed, + Err("LOBBY_FULL") => ErrorCode::LobbyFull, + Err("NO_AVAILABLE_LOBBIES") => ErrorCode::NoAvailableLobbies, Err(_) => internal_panic!("unknown redis error"), }; diff --git a/svc/pkg/mm/worker/src/workers/lobby_find/limit.rs b/svc/pkg/mm/worker/src/workers/lobby_find/limit.rs index 07b447b8fd..dcee8a5f80 100644 --- a/svc/pkg/mm/worker/src/workers/lobby_find/limit.rs +++ b/svc/pkg/mm/worker/src/workers/lobby_find/limit.rs @@ -1,5 +1,5 @@ use chirp_worker::prelude::*; -use proto::backend::{self, pkg::*}; +use proto::backend::{self, pkg::mm::msg::lobby_find_fail::ErrorCode, pkg::*}; use serde_json::json; use super::fail; @@ -79,7 +79,7 @@ pub async fn check_remote_addresses( ctx, namespace_id, query_id, - mm::msg::lobby_find_fail::ErrorCode::TooManyPlayersFromSource, + ErrorCode::TooManyPlayersFromSource, true, ) .await diff --git a/svc/pkg/mm/worker/src/workers/lobby_find/mod.rs b/svc/pkg/mm/worker/src/workers/lobby_find/mod.rs index 4ca64b9ba0..9e5734ebe2 100644 --- a/svc/pkg/mm/worker/src/workers/lobby_find/mod.rs +++ b/svc/pkg/mm/worker/src/workers/lobby_find/mod.rs @@ -1,7 +1,10 @@ use chirp_worker::prelude::*; use proto::backend::{ self, - pkg::{mm::msg::lobby_find::message::Query, *}, + pkg::{ + mm::{msg::lobby_find::message::Query, msg::lobby_find_fail::ErrorCode}, + *, + }, }; use serde_json::json; use tracing::Instrument; @@ -23,7 +26,7 @@ async fn fail( ctx: &OperationContext, namespace_id: Uuid, query_id: Uuid, - error_code: mm::msg::lobby_find_fail::ErrorCode, + error_code: ErrorCode, force_fail: bool, ) -> GlobalResult<()> { tracing::warn!(%namespace_id, ?query_id, ?error_code, ?force_fail, "player create failed"); @@ -68,7 +71,7 @@ async fn complete_request( } #[worker(name = "mm-lobby-find")] -async fn worker(ctx: OperationContext) -> GlobalResult<()> { +async fn worker(ctx: &OperationContext) -> GlobalResult<()> { // TODO: Fetch all sessions for the current IP // TODO: Map to all players matching the given sessions @@ -88,34 +91,14 @@ async fn worker(ctx: OperationContext) -> GlobalRe // Check for stale message if ctx.req_dt() > util::duration::seconds(60) { tracing::warn!("discarding stale message"); - fail( - ctx, - namespace_id, - query_id, - mm::msg::lobby_find_fail::ErrorCode::StaleMessage, - true, - ) - .await?; + fail(ctx, namespace_id, query_id, ErrorCode::StaleMessage, true).await?; return complete_request(ctx.chirp(), analytics_events).await; } let ((_namespace, mm_ns_config, dev_team), lobby_group_config) = tokio::try_join!( // Namespace and dev team fetch_ns_config_and_dev_team(ctx.base(), namespace_id), - // Fetch lobby group config if auto-creating lobby - async { - if let Query::LobbyGroup(backend::matchmaker::query::LobbyGroup { - auto_create: Some(auto_create), - .. - }) = &query - { - let lobby_group_id = internal_unwrap!(auto_create.lobby_group_id).as_uuid(); - let config = fetch_lobby_group_config(ctx.base(), lobby_group_id).await?; - Ok(Some(config)) - } else { - Ok(None) - } - }, + fetch_lobby_group_config(ctx.base(), query), )?; // Verify dev team status @@ -124,10 +107,57 @@ async fn worker(ctx: OperationContext) -> GlobalRe ctx, namespace_id, query_id, - mm::msg::lobby_find_fail::ErrorCode::DevTeamInvalidStatus, + ErrorCode::DevTeamInvalidStatus, true, ) .await?; + return complete_request(ctx.chirp(), analytics_events).await; + } + + // Verify user data + let verification_res = util_mm::verification::verify_config( + &ctx.base(), + &util_mm::verification::VerifyConfigOpts { + kind: match query { + Query::LobbyGroup(_) => util_mm::verification::ConnectionKind::Find, + Query::Direct(_) => util_mm::verification::ConnectionKind::Join, + }, + namespace_id, + user_id: ctx.user_id.map(|id| id.as_uuid()), + lobby_group: &lobby_group_config.lobby_group, + lobby_group_meta: &lobby_group_config.lobby_group_meta, + lobby_info: lobby_group_config.lobby_info.as_ref(), + lobby_state_json: lobby_group_config.lobby_state_json.as_deref(), + verification_data_json: ctx.verification_data_json.as_deref(), + lobby_config_json: None, + custom_lobby_publicity: None, + }, + ) + .await; + if let Err(err) = verification_res { + // Reduces verbosity + let err_branch = |err_code| async move { + fail(ctx, namespace_id, query_id, err_code, true).await?; + complete_request(ctx.chirp(), analytics_events).await + }; + + let res = if err.is(formatted_error::code::MATCHMAKER_FIND_DISABLED) { + err_branch(ErrorCode::FindDisabled).await + } else if err.is(formatted_error::code::MATCHMAKER_JOIN_DISABLED) { + err_branch(ErrorCode::JoinDisabled).await + } else if err.is(formatted_error::code::MATCHMAKER_REGISTRATION_REQUIRED) { + err_branch(ErrorCode::RegistrationRequired).await + } else if err.is(formatted_error::code::MATCHMAKER_IDENTITY_REQUIRED) { + err_branch(ErrorCode::IdentityRequired).await + } else if err.is(formatted_error::code::MATCHMAKER_VERIFICATION_FAILED) { + err_branch(ErrorCode::VerificationFailed).await + } else if err.is(formatted_error::code::MATCHMAKER_VERIFICATION_REQUEST_FAILED) { + err_branch(ErrorCode::VerificationRequestFailed).await + } else { + Err(err) + }; + + return res; } // Create players @@ -192,7 +222,7 @@ async fn worker(ctx: OperationContext) -> GlobalRe join_kind, players: &players, query, - lobby_group_config: lobby_group_config.as_ref(), + lobby_group_config: &lobby_group_config, auto_create_lobby_id, }, ) @@ -281,6 +311,11 @@ async fn worker(ctx: OperationContext) -> GlobalRe region_id: Some(auto_create_region_id.into()), create_ray_id: Some(ctx.ray_id().into()), preemptively_created: true, + + creator_user_id: ctx.user_id, + is_custom: false, + publicity: None, + lobby_config_json: None, }) .await?; @@ -415,23 +450,59 @@ pub struct LobbyGroupConfig { pub lobby_group: backend::matchmaker::LobbyGroup, #[allow(unused)] pub lobby_group_meta: backend::matchmaker::LobbyGroupMeta, + pub lobby_info: Option, + pub lobby_state_json: Option, } -/// Fetches the lobby group config. Only used if auto-creating lobby. +/// Fetches the lobby group config (and lobby if direct). #[tracing::instrument] async fn fetch_lobby_group_config( ctx: OperationContext<()>, - lobby_group_id: Uuid, + query: &Query, ) -> GlobalResult { - let lobby_group_id_proto = Some(common::Uuid::from(lobby_group_id)); + // Get lobby group id from query + let (lobby_group_id, lobby_info, lobby_state_json) = match query { + Query::LobbyGroup(backend::matchmaker::query::LobbyGroup { auto_create, .. }) => { + let auto_create = internal_unwrap!(auto_create); + + ( + internal_unwrap_owned!(auto_create.lobby_group_id), + None, + None, + ) + } + Query::Direct(backend::matchmaker::query::Direct { lobby_id, .. }) => { + let lobby_id = internal_unwrap_owned!(*lobby_id); + + let (lobbies_res, lobby_states_res) = tokio::try_join!( + op!([ctx] mm_lobby_get { + lobby_ids: vec![lobby_id], + include_stopped: true, + }), + op!([ctx] mm_lobby_state_get { + lobby_ids: vec![lobby_id], + }), + )?; + let lobby = + internal_unwrap_owned!(lobbies_res.lobbies.into_iter().next(), "lobby not found"); + let lobby_state = internal_unwrap_owned!(lobby_states_res.lobbies.into_iter().next()); + + ( + internal_unwrap_owned!(lobby.lobby_group_id), + Some(lobby), + lobby_state.state_json, + ) + } + }; + let lobby_group_id_proto = Some(lobby_group_id); // Resolve the version ID let resolve_version_res = op!([ctx] mm_config_lobby_group_resolve_version { - lobby_group_ids: vec![lobby_group_id.into()], + lobby_group_ids: vec![lobby_group_id], }) .await?; let version_id = internal_unwrap!( - internal_unwrap!( + internal_unwrap_owned!( resolve_version_res.versions.first(), "lobby group not found" ) @@ -464,6 +535,8 @@ async fn fetch_lobby_group_config( version_id, lobby_group: (*lobby_group).clone(), lobby_group_meta: (*lobby_group_meta).clone(), + lobby_info, + lobby_state_json, }) } @@ -477,7 +550,7 @@ struct InsertCrdbOpts { lobby_id: Uuid, region_id: Uuid, lobby_group_id: Uuid, - lobby_group_config: Option, + lobby_group_config: LobbyGroupConfig, auto_create_lobby: bool, now_ts: i64, ray_id: Uuid, @@ -503,9 +576,6 @@ async fn insert_to_crdb( ) -> GlobalResult<()> { // Insert preemptive lobby row if needed if auto_create_lobby { - // Lobby group config will exist if the lobby was auto created - let lobby_group_config = internal_unwrap!(lobby_group_config); - // Insert lobby if needed sqlx::query(indoc!( " @@ -537,7 +607,7 @@ async fn insert_to_crdb( .bind(lobby_group_config.lobby_group.max_players_normal as i64) .bind(lobby_group_config.lobby_group.max_players_direct as i64) .bind(lobby_group_config.lobby_group.max_players_party as i64) - .execute(&mut *tx) + .execute(&mut **tx) .await?; } @@ -561,7 +631,7 @@ async fn insert_to_crdb( .bind(lobby_id) .bind(auto_create_lobby) .bind(util_mm::FindQueryStatus::Pending as i64) - .execute(&mut *tx) + .execute(&mut **tx) .await?; // Insert players @@ -592,7 +662,7 @@ async fn insert_to_crdb( ) .bind(now_ts) .bind(ray_id) - .execute(&mut *tx) + .execute(&mut **tx) .await?; } diff --git a/svc/pkg/mm/worker/src/workers/lobby_find_job_run_fail.rs b/svc/pkg/mm/worker/src/workers/lobby_find_job_run_fail.rs index 6aba8fec1c..580fab9e94 100644 --- a/svc/pkg/mm/worker/src/workers/lobby_find_job_run_fail.rs +++ b/svc/pkg/mm/worker/src/workers/lobby_find_job_run_fail.rs @@ -8,7 +8,7 @@ struct LobbyRow { } #[worker(name = "mm-lobby-find-job-run-fail")] -async fn worker(ctx: OperationContext) -> GlobalResult<()> { +async fn worker(ctx: &OperationContext) -> GlobalResult<()> { let crdb = ctx.crdb("db-mm-state").await?; let run_id = internal_unwrap!(ctx.run_id).as_uuid(); diff --git a/svc/pkg/mm/worker/src/workers/lobby_find_lobby_cleanup.rs b/svc/pkg/mm/worker/src/workers/lobby_find_lobby_cleanup.rs index ebef8b7c5c..ea74229937 100644 --- a/svc/pkg/mm/worker/src/workers/lobby_find_lobby_cleanup.rs +++ b/svc/pkg/mm/worker/src/workers/lobby_find_lobby_cleanup.rs @@ -1,8 +1,8 @@ use chirp_worker::prelude::*; -use proto::backend::pkg::*; +use proto::backend::pkg::{mm::msg::lobby_find_fail::ErrorCode, *}; #[worker(name = "mm-lobby-find-lobby-cleanup")] -async fn worker(ctx: OperationContext) -> GlobalResult<()> { +async fn worker(ctx: &OperationContext) -> GlobalResult<()> { let lobby_id = internal_unwrap!(ctx.lobby_id).as_uuid(); // TODO: Is there a race condition here for new queries? @@ -16,7 +16,7 @@ async fn worker(ctx: OperationContext) -> Globa .await?; op!([ctx] mm_lobby_find_fail { query_ids: query_list.query_ids.clone(), - error_code: mm::msg::lobby_find_fail::ErrorCode::LobbyStoppedPrematurely as i32, + error_code: ErrorCode::LobbyStoppedPrematurely as i32, ..Default::default() }) .await?; diff --git a/svc/pkg/mm/worker/src/workers/lobby_find_lobby_create_fail.rs b/svc/pkg/mm/worker/src/workers/lobby_find_lobby_create_fail.rs index af1ca69326..babebe6aaa 100644 --- a/svc/pkg/mm/worker/src/workers/lobby_find_lobby_create_fail.rs +++ b/svc/pkg/mm/worker/src/workers/lobby_find_lobby_create_fail.rs @@ -2,7 +2,7 @@ use chirp_worker::prelude::*; use proto::backend::pkg::*; #[worker(name = "mm-lobby-find-lobby-create-fail")] -async fn worker(ctx: OperationContext) -> GlobalResult<()> { +async fn worker(ctx: &OperationContext) -> GlobalResult<()> { let lobby_id = internal_unwrap!(ctx.lobby_id).as_uuid(); let error_code = match mm::msg::lobby_create_fail::ErrorCode::from_i32(ctx.error_code) { diff --git a/svc/pkg/mm/worker/src/workers/lobby_find_lobby_ready.rs b/svc/pkg/mm/worker/src/workers/lobby_find_lobby_ready.rs index e5d7446fe2..5d90529727 100644 --- a/svc/pkg/mm/worker/src/workers/lobby_find_lobby_ready.rs +++ b/svc/pkg/mm/worker/src/workers/lobby_find_lobby_ready.rs @@ -2,7 +2,9 @@ use chirp_worker::prelude::*; use proto::backend::pkg::*; #[worker(name = "mm-lobby-find-lobby-ready")] -async fn worker(ctx: OperationContext) -> GlobalResult<()> { +async fn worker( + ctx: &OperationContext, +) -> GlobalResult<()> { let lobby_id = internal_unwrap!(ctx.lobby_id).as_uuid(); // TODO: Is there a race condition here for new queries? diff --git a/svc/pkg/mm/worker/src/workers/lobby_history_export.rs b/svc/pkg/mm/worker/src/workers/lobby_history_export.rs index ec3d388e7c..811e170ea4 100644 --- a/svc/pkg/mm/worker/src/workers/lobby_history_export.rs +++ b/svc/pkg/mm/worker/src/workers/lobby_history_export.rs @@ -48,7 +48,9 @@ struct LobbyGroupCache { } #[worker(name = "mm-lobby-history-export")] -async fn worker(ctx: OperationContext) -> GlobalResult<()> { +async fn worker( + ctx: &OperationContext, +) -> GlobalResult<()> { let crdb = ctx.crdb("db-mm-state").await?; let request_id = internal_unwrap!(ctx.request_id).as_uuid(); diff --git a/svc/pkg/mm/worker/src/workers/lobby_job_run_cleanup.rs b/svc/pkg/mm/worker/src/workers/lobby_job_run_cleanup.rs index 7eb82d813b..adc375a3fb 100644 --- a/svc/pkg/mm/worker/src/workers/lobby_job_run_cleanup.rs +++ b/svc/pkg/mm/worker/src/workers/lobby_job_run_cleanup.rs @@ -2,7 +2,7 @@ use chirp_worker::prelude::*; use proto::backend::pkg::*; #[worker(name = "mm-lobby-job-run-cleanup")] -async fn worker(ctx: OperationContext) -> GlobalResult<()> { +async fn worker(ctx: &OperationContext) -> GlobalResult<()> { let crdb = ctx.crdb("db-mm-state").await?; let run_id = internal_unwrap!(ctx.run_id).as_uuid(); diff --git a/svc/pkg/mm/worker/src/workers/lobby_ready_set.rs b/svc/pkg/mm/worker/src/workers/lobby_ready_set.rs index c4bd051238..9f5f779e43 100644 --- a/svc/pkg/mm/worker/src/workers/lobby_ready_set.rs +++ b/svc/pkg/mm/worker/src/workers/lobby_ready_set.rs @@ -16,7 +16,7 @@ struct LobbyRow { } #[worker(name = "mm-lobby-ready-set")] -async fn worker(ctx: OperationContext) -> GlobalResult<()> { +async fn worker(ctx: &OperationContext) -> GlobalResult<()> { let crdb = ctx.crdb("db-mm-state").await?; let mut redis_mm = ctx.redis_mm().await?; diff --git a/svc/pkg/mm/worker/src/workers/lobby_state_set.rs b/svc/pkg/mm/worker/src/workers/lobby_state_set.rs new file mode 100644 index 0000000000..81f30cd244 --- /dev/null +++ b/svc/pkg/mm/worker/src/workers/lobby_state_set.rs @@ -0,0 +1,33 @@ +use chirp_worker::prelude::*; +use proto::backend::pkg::*; + +#[worker(name = "mm-lobby-state-set")] +async fn worker(ctx: &OperationContext) -> GlobalResult<()> { + let crdb = ctx.crdb("db-mm-state").await?; + + let lobby_id = internal_unwrap!(ctx.lobby_id).as_uuid(); + let mut pipe = redis::pipe(); + pipe.atomic(); + + if let Some(state_json) = &ctx.state_json { + pipe.hset( + util_mm::key::lobby_config(lobby_id), + util_mm::key::lobby_config::STATE_JSON, + &state_json, + ); + } else { + pipe.hdel( + util_mm::key::lobby_config(lobby_id), + util_mm::key::lobby_config::STATE_JSON, + ); + } + + pipe.query_async(&mut ctx.redis_mm().await?).await?; + + msg!([ctx] mm::msg::lobby_state_set_complete(lobby_id) { + lobby_id: Some(lobby_id.into()), + }) + .await?; + + Ok(()) +} diff --git a/svc/pkg/mm/worker/src/workers/lobby_stop.rs b/svc/pkg/mm/worker/src/workers/lobby_stop.rs index 06f3715064..ed777c4d3a 100644 --- a/svc/pkg/mm/worker/src/workers/lobby_stop.rs +++ b/svc/pkg/mm/worker/src/workers/lobby_stop.rs @@ -8,7 +8,7 @@ struct LobbyRow { } #[worker(name = "mm-lobby-stop")] -async fn worker(ctx: OperationContext) -> GlobalResult<()> { +async fn worker(ctx: &OperationContext) -> GlobalResult<()> { let lobby_id = internal_unwrap!(ctx.lobby_id).as_uuid(); let crdb = ctx.crdb("db-mm-state").await?; diff --git a/svc/pkg/mm/worker/src/workers/mod.rs b/svc/pkg/mm/worker/src/workers/mod.rs index ea2eec884d..4cdaf83fdc 100644 --- a/svc/pkg/mm/worker/src/workers/mod.rs +++ b/svc/pkg/mm/worker/src/workers/mod.rs @@ -9,6 +9,7 @@ pub mod lobby_find_lobby_ready; pub mod lobby_history_export; pub mod lobby_job_run_cleanup; pub mod lobby_ready_set; +pub mod lobby_state_set; pub mod lobby_stop; pub mod player_register; pub mod player_remove; diff --git a/svc/pkg/mm/worker/src/workers/player_register.rs b/svc/pkg/mm/worker/src/workers/player_register.rs index 675492de39..6902625486 100644 --- a/svc/pkg/mm/worker/src/workers/player_register.rs +++ b/svc/pkg/mm/worker/src/workers/player_register.rs @@ -12,7 +12,7 @@ struct PlayerRow { } #[worker(name = "mm-player-register")] -async fn worker(ctx: OperationContext) -> GlobalResult<()> { +async fn worker(ctx: &OperationContext) -> GlobalResult<()> { let crdb = ctx.crdb("db-mm-state").await?; let player_id = internal_unwrap!(ctx.player_id).as_uuid(); diff --git a/svc/pkg/mm/worker/src/workers/player_remove.rs b/svc/pkg/mm/worker/src/workers/player_remove.rs index a394400cd4..a4ff54cdde 100644 --- a/svc/pkg/mm/worker/src/workers/player_remove.rs +++ b/svc/pkg/mm/worker/src/workers/player_remove.rs @@ -29,7 +29,7 @@ struct PlayerRow { struct LobbyRow {} #[worker(name = "mm-player-remove")] -async fn worker(ctx: OperationContext) -> GlobalResult<()> { +async fn worker(ctx: &OperationContext) -> GlobalResult<()> { // NOTE: Idempotent let crdb = ctx.crdb("db-mm-state").await?; diff --git a/svc/pkg/mm/worker/tests/lobby_create.rs b/svc/pkg/mm/worker/tests/lobby_create.rs index c7a7435a66..25e9279532 100644 --- a/svc/pkg/mm/worker/tests/lobby_create.rs +++ b/svc/pkg/mm/worker/tests/lobby_create.rs @@ -34,11 +34,16 @@ async fn setup(ctx: &TestCtx) -> Setup { regions: vec![backend::matchmaker::lobby_group::Region { region_id: Some(region_id.into()), tier_name_id: util_mm::test::TIER_NAME_ID.to_owned(), - idle_lobbies: None, + idle_lobbies: Some(backend::matchmaker::lobby_group::IdleLobbies { + min_idle_lobbies: 0, + // Don't auto-destory lobbies from tests + max_idle_lobbies: 32, + }), }], max_players_normal: 8, max_players_direct: 10, max_players_party: 12, + listable: true, runtime: Some(backend::matchmaker::lobby_runtime::Docker { build_id: build_res.build_id, @@ -80,6 +85,10 @@ async fn setup(ctx: &TestCtx) -> Setup { ], }.into()), + + find_config: None, + join_config: None, + create_config: None, }, backend::matchmaker::LobbyGroup { name_id: "test-2".into(), @@ -87,11 +96,16 @@ async fn setup(ctx: &TestCtx) -> Setup { regions: vec![backend::matchmaker::lobby_group::Region { region_id: Some(region_id.into()), tier_name_id: util_mm::test::TIER_NAME_ID.to_owned(), - idle_lobbies: None, + idle_lobbies: Some(backend::matchmaker::lobby_group::IdleLobbies { + min_idle_lobbies: 0, + // See above + max_idle_lobbies: 32, + }), }], max_players_normal: 8, max_players_direct: 10, max_players_party: 12, + listable: true, runtime: Some(backend::matchmaker::lobby_runtime::Docker { build_id: build_res.build_id, @@ -122,6 +136,10 @@ async fn setup(ctx: &TestCtx) -> Setup { ], }.into()), + + find_config: None, + join_config: None, + create_config: None, }], }), ..Default::default() @@ -175,6 +193,11 @@ async fn lobby_create(ctx: TestCtx) { region_id: Some(setup.region_id.into()), create_ray_id: None, preemptively_created: false, + + creator_user_id: None, + is_custom: false, + publicity: None, + lobby_config_json: None, }) .await .unwrap(); @@ -195,6 +218,46 @@ async fn lobby_create(ctx: TestCtx) { assert_eq!(12, sql_mpp); } +#[worker_test] +async fn custom_private_lobby_create(ctx: TestCtx) { + let setup = setup(&ctx).await; + + let lobby_id = Uuid::new_v4(); + msg!([ctx] mm::msg::lobby_create(lobby_id) -> mm::msg::lobby_create_complete { + lobby_id: Some(lobby_id.into()), + namespace_id: Some(setup.namespace_id.into()), + lobby_group_id: Some(setup.lobby_group_id.into()), + region_id: Some(setup.region_id.into()), + create_ray_id: None, + preemptively_created: false, + + creator_user_id: None, + is_custom: true, + publicity: Some(backend::matchmaker::lobby::Publicity::Private as i32), + lobby_config_json: Some(r#"{ "foo": "bar" }"#.to_string()), + }) + .await + .unwrap(); + + let (is_custom, publicity) = sqlx::query_as::<_, (bool, i64)>(indoc!( + " + SELECT is_custom, publicity + FROM lobbies + WHERE lobby_id = $1 + " + )) + .bind(lobby_id) + .fetch_one(&ctx.crdb("db-mm-state").await.unwrap()) + .await + .unwrap(); + + assert!(is_custom); + assert_eq!( + backend::matchmaker::lobby::Publicity::Private as i32 as i64, + publicity + ); +} + #[worker_test] async fn lobby_create_max_lobby_count(ctx: TestCtx) { let setup = setup(&ctx).await; @@ -222,6 +285,11 @@ async fn lobby_create_max_lobby_count(ctx: TestCtx) { region_id: Some(setup.region_id.into()), create_ray_id: None, preemptively_created: false, + + creator_user_id: None, + is_custom: false, + publicity: None, + lobby_config_json: None, }) .await .unwrap(); @@ -236,6 +304,11 @@ async fn lobby_create_max_lobby_count(ctx: TestCtx) { region_id: Some(setup.region_id.into()), create_ray_id: None, preemptively_created: false, + + creator_user_id: None, + is_custom: false, + publicity: None, + lobby_config_json: None, }) .await .unwrap(); @@ -257,6 +330,11 @@ async fn lobby_create_reuse_job_id(ctx: TestCtx) { region_id: Some(setup.region_id.into()), create_ray_id: None, preemptively_created: false, + + creator_user_id: None, + is_custom: false, + publicity: None, + lobby_config_json: None, }) .await .unwrap(); @@ -269,6 +347,11 @@ async fn lobby_create_reuse_job_id(ctx: TestCtx) { region_id: Some(setup.region_id.into()), create_ray_id: None, preemptively_created: false, + + creator_user_id: None, + is_custom: false, + publicity: None, + lobby_config_json: None, }) .await .unwrap(); @@ -290,10 +373,24 @@ async fn lobby_create_reuse_job_id(ctx: TestCtx) { .await .unwrap(); - let Some(backend::job::RunMeta { kind: Some(backend::job::run_meta::Kind::Nomad(backend::job::run_meta::Nomad { dispatched_job_id: dispatch_a, .. }))}) = &runs.runs[0].run_meta else { + let Some(backend::job::RunMeta { + kind: + Some(backend::job::run_meta::Kind::Nomad(backend::job::run_meta::Nomad { + dispatched_job_id: dispatch_a, + .. + })), + }) = &runs.runs[0].run_meta + else { panic!() }; - let Some(backend::job::RunMeta { kind: Some(backend::job::run_meta::Kind::Nomad(backend::job::run_meta::Nomad { dispatched_job_id: dispatch_b, .. }))}) = &runs.runs[1].run_meta else { + let Some(backend::job::RunMeta { + kind: + Some(backend::job::run_meta::Kind::Nomad(backend::job::run_meta::Nomad { + dispatched_job_id: dispatch_b, + .. + })), + }) = &runs.runs[1].run_meta + else { panic!() }; @@ -303,6 +400,8 @@ async fn lobby_create_reuse_job_id(ctx: TestCtx) { assert_eq!(job_a, job_b, "these runs were dispatched from different jobs. this means the nomad job is not deterministic."); } +// TODO: Write test verifying that lobby config data shows up in lobby env + // #[worker_test] // async fn lobby_create_stress_test(ctx: TestCtx) { // let setup = setup(&ctx).await; @@ -316,6 +415,11 @@ async fn lobby_create_reuse_job_id(ctx: TestCtx) { // region_id: Some(setup.region_id.into()), // create_ray_id: None, // preemptively_created: false, + +// creator_user_id: None, +// is_custom: false, +// publicity: None, +// lobby_config_json: None, // }) // .await // .unwrap(); diff --git a/svc/pkg/mm/worker/tests/lobby_find.rs b/svc/pkg/mm/worker/tests/lobby_find.rs index 9d3afe7d4c..08c248cd01 100644 --- a/svc/pkg/mm/worker/tests/lobby_find.rs +++ b/svc/pkg/mm/worker/tests/lobby_find.rs @@ -1,3 +1,5 @@ +use std::collections::HashMap; + use chirp_worker::prelude::*; use proto::backend::{self, pkg::*}; @@ -44,6 +46,7 @@ async fn create_lobby_group(ctx: &TestCtx, image: Option) - max_players_normal: 8, max_players_direct: 10, max_players_party: 12, + listable: true, runtime: Some(backend::matchmaker::lobby_runtime::Docker { // We can't use `curlimages/curl` here because it doesn't allow for @@ -64,6 +67,10 @@ async fn create_lobby_group(ctx: &TestCtx, image: Option) - proxy_kind: backend::matchmaker::lobby_runtime::ProxyKind::GameGuard as i32, }], }.into()), + + find_config: None, + join_config: None, + create_config: None, }], }), ..Default::default() @@ -107,11 +114,18 @@ async fn direct(ctx: TestCtx) { let find_res = find( &ctx, - lobby_res.namespace_id.as_ref().unwrap().as_uuid(), - gen_players(1), - mm::msg::lobby_find::message::Query::Direct(backend::matchmaker::query::Direct { - lobby_id: lobby_res.lobby_id, - }), + FindRequest { + namespace_id: lobby_res.namespace_id.as_ref().unwrap().as_uuid(), + players: gen_players(1), + query: mm::msg::lobby_find::message::Query::Direct( + backend::matchmaker::query::Direct { + lobby_id: lobby_res.lobby_id, + }, + ), + user_id: None, + verification_data_json: None, + bypass_verification: false, + }, ) .await .unwrap(); @@ -129,16 +143,23 @@ async fn lobby_group_existing(ctx: TestCtx) { let find_res = find( &ctx, - lobby_res.namespace_id.as_ref().unwrap().as_uuid(), - gen_players(1), - mm::msg::lobby_find::message::Query::LobbyGroup(backend::matchmaker::query::LobbyGroup { - lobby_group_ids: vec![lobby_res.lobby_group_id.unwrap()], - region_ids: vec![lobby_res.region_id.unwrap()], - auto_create: Some(backend::matchmaker::query::AutoCreate { - lobby_group_id: lobby_res.lobby_group_id, - region_id: lobby_res.region_id, - }), - }), + FindRequest { + namespace_id: lobby_res.namespace_id.as_ref().unwrap().as_uuid(), + players: gen_players(1), + query: mm::msg::lobby_find::message::Query::LobbyGroup( + backend::matchmaker::query::LobbyGroup { + lobby_group_ids: vec![lobby_res.lobby_group_id.unwrap()], + region_ids: vec![lobby_res.region_id.unwrap()], + auto_create: Some(backend::matchmaker::query::AutoCreate { + lobby_group_id: lobby_res.lobby_group_id, + region_id: lobby_res.region_id, + }), + }, + ), + user_id: None, + verification_data_json: None, + bypass_verification: false, + }, ) .await .unwrap(); @@ -164,11 +185,18 @@ async fn direct_closed(ctx: TestCtx) { let err = find( &ctx, - lobby_res.namespace_id.as_ref().unwrap().as_uuid(), - gen_players(1), - mm::msg::lobby_find::message::Query::Direct(backend::matchmaker::query::Direct { - lobby_id: lobby_res.lobby_id, - }), + FindRequest { + namespace_id: lobby_res.namespace_id.as_ref().unwrap().as_uuid(), + players: gen_players(1), + query: mm::msg::lobby_find::message::Query::Direct( + backend::matchmaker::query::Direct { + lobby_id: lobby_res.lobby_id, + }, + ), + user_id: None, + verification_data_json: None, + bypass_verification: false, + }, ) .await .unwrap_err(); @@ -197,13 +225,20 @@ async fn lobby_group_closed(ctx: TestCtx) { let err = find( &ctx, - lobby_res.namespace_id.as_ref().unwrap().as_uuid(), - gen_players(1), - mm::msg::lobby_find::message::Query::LobbyGroup(backend::matchmaker::query::LobbyGroup { - lobby_group_ids: vec![lobby_res.lobby_group_id.unwrap()], - region_ids: vec![lobby_res.region_id.unwrap()], - auto_create: None, - }), + FindRequest { + namespace_id: lobby_res.namespace_id.as_ref().unwrap().as_uuid(), + players: gen_players(1), + query: mm::msg::lobby_find::message::Query::LobbyGroup( + backend::matchmaker::query::LobbyGroup { + lobby_group_ids: vec![lobby_res.lobby_group_id.unwrap()], + region_ids: vec![lobby_res.region_id.unwrap()], + auto_create: None, + }, + ), + user_id: None, + verification_data_json: None, + bypass_verification: false, + }, ) .await .unwrap_err(); @@ -220,16 +255,23 @@ async fn lobby_crash_immediate(ctx: TestCtx) { let err = find( &ctx, - lobby_group.namespace_id, - gen_players(1), - mm::msg::lobby_find::message::Query::LobbyGroup(backend::matchmaker::query::LobbyGroup { - lobby_group_ids: vec![lobby_group.lobby_group_id.into()], - region_ids: vec![lobby_group.region_id.into()], - auto_create: Some(backend::matchmaker::query::AutoCreate { - lobby_group_id: Some(lobby_group.lobby_group_id.into()), - region_id: Some(lobby_group.region_id.into()), - }), - }), + FindRequest { + namespace_id: lobby_group.namespace_id, + players: gen_players(1), + query: mm::msg::lobby_find::message::Query::LobbyGroup( + backend::matchmaker::query::LobbyGroup { + lobby_group_ids: vec![lobby_group.lobby_group_id.into()], + region_ids: vec![lobby_group.region_id.into()], + auto_create: Some(backend::matchmaker::query::AutoCreate { + lobby_group_id: Some(lobby_group.lobby_group_id.into()), + region_id: Some(lobby_group.region_id.into()), + }), + }, + ), + user_id: None, + verification_data_json: None, + bypass_verification: false, + }, ) .await .unwrap_err(); @@ -269,18 +311,25 @@ async fn max_players_per_client(ctx: TestCtx) { let res = find( &ctx, - lobby_res.namespace_id.as_ref().unwrap().as_uuid(), - vec![mm::msg::lobby_find::Player { - player_id: Some(Uuid::new_v4().into()), - token_session_id: Some(Uuid::new_v4().into()), - client_info: Some(backend::net::ClientInfo { - user_agent: Some("Test".into()), - remote_address: Some(fake_ip.to_string()), - }), - }], - mm::msg::lobby_find::message::Query::Direct(backend::matchmaker::query::Direct { - lobby_id: lobby_res.lobby_id, - }), + FindRequest { + namespace_id: lobby_res.namespace_id.as_ref().unwrap().as_uuid(), + players: vec![mm::msg::lobby_find::Player { + player_id: Some(Uuid::new_v4().into()), + token_session_id: Some(Uuid::new_v4().into()), + client_info: Some(backend::net::ClientInfo { + user_agent: Some("Test".into()), + remote_address: Some(fake_ip.to_string()), + }), + }], + query: mm::msg::lobby_find::message::Query::Direct( + backend::matchmaker::query::Direct { + lobby_id: lobby_res.lobby_id, + }, + ), + user_id: None, + verification_data_json: None, + bypass_verification: false, + }, ) .await; if i >= max_players_per_client { @@ -301,16 +350,23 @@ async fn lobby_group_auto_create(ctx: TestCtx) { find( &ctx, - lobby_group.namespace_id, - gen_players(1), - mm::msg::lobby_find::message::Query::LobbyGroup(backend::matchmaker::query::LobbyGroup { - lobby_group_ids: vec![lobby_group.lobby_group_id.into()], - region_ids: vec![lobby_group.region_id.into()], - auto_create: Some(backend::matchmaker::query::AutoCreate { - lobby_group_id: Some(lobby_group.lobby_group_id.into()), - region_id: Some(lobby_group.region_id.into()), - }), - }), + FindRequest { + namespace_id: lobby_group.namespace_id, + players: gen_players(1), + query: mm::msg::lobby_find::message::Query::LobbyGroup( + backend::matchmaker::query::LobbyGroup { + lobby_group_ids: vec![lobby_group.lobby_group_id.into()], + region_ids: vec![lobby_group.region_id.into()], + auto_create: Some(backend::matchmaker::query::AutoCreate { + lobby_group_id: Some(lobby_group.lobby_group_id.into()), + region_id: Some(lobby_group.region_id.into()), + }), + }, + ), + user_id: None, + verification_data_json: None, + bypass_verification: false, + }, ) .await .unwrap(); @@ -322,13 +378,20 @@ async fn lobby_group_no_auto_create(ctx: TestCtx) { let err = find( &ctx, - lobby_group.namespace_id, - gen_players(1), - mm::msg::lobby_find::message::Query::LobbyGroup(backend::matchmaker::query::LobbyGroup { - lobby_group_ids: vec![lobby_group.lobby_group_id.into()], - region_ids: vec![lobby_group.region_id.into()], - auto_create: None, - }), + FindRequest { + namespace_id: lobby_group.namespace_id, + players: gen_players(1), + query: mm::msg::lobby_find::message::Query::LobbyGroup( + backend::matchmaker::query::LobbyGroup { + lobby_group_ids: vec![lobby_group.lobby_group_id.into()], + region_ids: vec![lobby_group.region_id.into()], + auto_create: None, + }, + ), + user_id: None, + verification_data_json: None, + bypass_verification: false, + }, ) .await .unwrap_err(); @@ -339,6 +402,275 @@ async fn lobby_group_no_auto_create(ctx: TestCtx) { ); } +#[worker_test] +async fn join_disabled(ctx: TestCtx) { + let user_id = Uuid::new_v4(); + + let (namespace_id, lobby_id) = gen_disabled_lobby(&ctx).await; + + let err = find( + &ctx, + FindRequest { + namespace_id, + players: gen_players(1), + query: mm::msg::lobby_find::message::Query::Direct( + backend::matchmaker::query::Direct { + lobby_id: Some(lobby_id.into()), + }, + ), + user_id: None, + verification_data_json: None, + bypass_verification: false, + }, + ) + .await + .unwrap_err(); + + assert_eq!( + mm::msg::lobby_find_fail::ErrorCode::JoinDisabled as i32, + err.error_code + ); +} + +#[worker_test] +async fn guest_verification(ctx: TestCtx) { + let user_id = Uuid::new_v4(); + + let (namespace_id, lobby_id) = + gen_verification_lobby(&ctx, backend::matchmaker::IdentityRequirement::Guest, None).await; + + let err = find( + &ctx, + FindRequest { + namespace_id, + players: gen_players(1), + query: mm::msg::lobby_find::message::Query::Direct( + backend::matchmaker::query::Direct { + lobby_id: Some(lobby_id.into()), + }, + ), + user_id: None, + verification_data_json: None, + bypass_verification: false, + }, + ) + .await + .unwrap_err(); + + assert_eq!( + mm::msg::lobby_find_fail::ErrorCode::IdentityRequired as i32, + err.error_code + ); + + let _find_res = find( + &ctx, + FindRequest { + namespace_id, + players: gen_players(1), + query: mm::msg::lobby_find::message::Query::Direct( + backend::matchmaker::query::Direct { + lobby_id: Some(lobby_id.into()), + }, + ), + user_id: Some(user_id), + verification_data_json: None, + bypass_verification: false, + }, + ) + .await + .unwrap(); +} + +#[worker_test] +async fn registered_verification(ctx: TestCtx) { + let user_res = op!([ctx] faker_user {}).await.unwrap(); + let user_id = user_res.user_id.unwrap().as_uuid(); + + let (namespace_id, lobby_id) = gen_verification_lobby( + &ctx, + backend::matchmaker::IdentityRequirement::Registered, + None, + ) + .await; + + let err = find( + &ctx, + FindRequest { + namespace_id, + players: gen_players(1), + query: mm::msg::lobby_find::message::Query::Direct( + backend::matchmaker::query::Direct { + lobby_id: Some(lobby_id.into()), + }, + ), + user_id: None, + verification_data_json: None, + bypass_verification: false, + }, + ) + .await + .unwrap_err(); + + assert_eq!( + mm::msg::lobby_find_fail::ErrorCode::IdentityRequired as i32, + err.error_code + ); + + let err = find( + &ctx, + FindRequest { + namespace_id, + players: gen_players(1), + query: mm::msg::lobby_find::message::Query::Direct( + backend::matchmaker::query::Direct { + lobby_id: Some(lobby_id.into()), + }, + ), + user_id: Some(user_id), + verification_data_json: None, + bypass_verification: false, + }, + ) + .await + .unwrap_err(); + + assert_eq!( + mm::msg::lobby_find_fail::ErrorCode::RegistrationRequired as i32, + err.error_code + ); + + let email = util::faker::email(); + op!([ctx] user_identity_create { + user_id: user_res.user_id, + identity: Some(backend::user_identity::Identity { + kind: Some(backend::user_identity::identity::Kind::Email( + backend::user_identity::identity::Email { + email: email.clone(), + } + )), + }), + }) + .await + .unwrap(); + + let _find_res = find( + &ctx, + FindRequest { + namespace_id, + players: gen_players(1), + query: mm::msg::lobby_find::message::Query::Direct( + backend::matchmaker::query::Direct { + lobby_id: Some(lobby_id.into()), + }, + ), + user_id: Some(user_id), + verification_data_json: None, + bypass_verification: false, + }, + ) + .await + .unwrap(); +} + +#[worker_test] +async fn bypass_verification(ctx: TestCtx) { + let user_id = Uuid::new_v4(); + + let (namespace_id, lobby_id) = gen_verification_lobby( + &ctx, + backend::matchmaker::IdentityRequirement::Registered, + None, + ) + .await; + + let _find_res = find( + &ctx, + FindRequest { + namespace_id, + players: gen_players(1), + query: mm::msg::lobby_find::message::Query::Direct( + backend::matchmaker::query::Direct { + lobby_id: Some(lobby_id.into()), + }, + ), + user_id: None, + verification_data_json: None, + bypass_verification: true, + }, + ) + .await + .unwrap(); +} + +// TODO: Find way to actually verify user data +#[worker_test] +async fn external_verification(ctx: TestCtx) { + let user_id = Uuid::new_v4(); + + let (namespace_id, lobby_id) = gen_verification_lobby( + &ctx, + backend::matchmaker::IdentityRequirement::None, + Some(backend::matchmaker::VerificationConfig { + url: "https://httpstat.us/403".to_string(), + headers: IntoIterator::into_iter([("accept".to_string(), "text/plain".to_string())]) + .collect::>(), + }), + ) + .await; + + let err = find( + &ctx, + FindRequest { + namespace_id, + players: gen_players(1), + query: mm::msg::lobby_find::message::Query::Direct( + backend::matchmaker::query::Direct { + lobby_id: Some(lobby_id.into()), + }, + ), + user_id: None, + verification_data_json: None, + bypass_verification: false, + }, + ) + .await + .unwrap_err(); + + assert_eq!( + mm::msg::lobby_find_fail::ErrorCode::VerificationFailed as i32, + err.error_code + ); + + let (namespace_id, lobby_id) = gen_verification_lobby( + &ctx, + backend::matchmaker::IdentityRequirement::None, + Some(backend::matchmaker::VerificationConfig { + url: "https://httpstat.us/200".to_string(), + headers: IntoIterator::into_iter([("accept".to_string(), "text/plain".to_string())]) + .collect::>(), + }), + ) + .await; + + let _find_res = find( + &ctx, + FindRequest { + namespace_id, + players: gen_players(1), + query: mm::msg::lobby_find::message::Query::Direct( + backend::matchmaker::query::Direct { + lobby_id: Some(lobby_id.into()), + }, + ), + user_id: Some(user_id), + verification_data_json: None, + bypass_verification: false, + }, + ) + .await + .unwrap(); +} + fn gen_players(count: usize) -> Vec { let mut players = Vec::new(); for _ in 0..count { @@ -354,22 +686,211 @@ fn gen_players(count: usize) -> Vec { players } -async fn find( +async fn gen_verification_lobby( ctx: &TestCtx, + identity_requirement: backend::matchmaker::IdentityRequirement, + verification_config: Option, +) -> (Uuid, Uuid) { + let region_list_res = op!([ctx] region_list { + ..Default::default() + }) + .await + .unwrap(); + + let game_res = op!([ctx] faker_game { + ..Default::default() + }) + .await + .unwrap(); + let namespace_id = game_res.namespace_ids.first().unwrap(); + + let build_res = op!([ctx] faker_build { + game_id: game_res.game_id, + image: faker::build::Image::MmLobbyAutoReady as i32, + }) + .await + .unwrap(); + + let version_create_res = op!([ctx] faker_game_version { + game_id: game_res.game_id, + override_lobby_groups: Some(faker::game_version::request::OverrideLobbyGroups { + lobby_groups: vec![backend::matchmaker::LobbyGroup { + name_id: "test-1".into(), + + regions: region_list_res + .region_ids + .iter() + .cloned() + .map(|region_id| backend::matchmaker::lobby_group::Region { + region_id: Some(region_id), + tier_name_id: util_mm::test::TIER_NAME_ID.to_owned(), + idle_lobbies: None, + }) + .collect(), + + max_players_normal: 8, + max_players_direct: 10, + max_players_party: 12, + listable: true, + + runtime: Some( + backend::matchmaker::lobby_runtime::Docker { + build_id: build_res.build_id, + args: Vec::new(), + env_vars: Vec::new(), + network_mode: + backend::matchmaker::lobby_runtime::NetworkMode::Bridge + as i32, + ports: Vec::new(), + } + .into(), + ), + + find_config: Some(backend::matchmaker::FindConfig { + enabled: true, + identity_requirement: identity_requirement as i32, + verification_config: verification_config.clone(), + }), + join_config: Some(backend::matchmaker::JoinConfig { + enabled: true, + identity_requirement: identity_requirement as i32, + verification_config, + }), + create_config: None, + }], + }), + }) + .await + .unwrap(); + + let lobby_res = op!([ctx] faker_mm_lobby { + namespace_id: Some(*namespace_id), + version_id: version_create_res.version_id, + ..Default::default() + }) + .await + .unwrap(); + + ( + lobby_res.namespace_id.unwrap().as_uuid(), + lobby_res.lobby_id.unwrap().as_uuid(), + ) +} + +async fn gen_disabled_lobby(ctx: &TestCtx) -> (Uuid, Uuid) { + let region_list_res = op!([ctx] region_list { + ..Default::default() + }) + .await + .unwrap(); + + let game_res = op!([ctx] faker_game { + ..Default::default() + }) + .await + .unwrap(); + let namespace_id = game_res.namespace_ids.first().unwrap(); + + let build_res = op!([ctx] faker_build { + game_id: game_res.game_id, + image: faker::build::Image::MmLobbyAutoReady as i32, + }) + .await + .unwrap(); + + let version_create_res = op!([ctx] faker_game_version { + game_id: game_res.game_id, + override_lobby_groups: Some(faker::game_version::request::OverrideLobbyGroups { + lobby_groups: vec![backend::matchmaker::LobbyGroup { + name_id: "test-1".into(), + + regions: region_list_res + .region_ids + .iter() + .cloned() + .map(|region_id| backend::matchmaker::lobby_group::Region { + region_id: Some(region_id), + tier_name_id: util_mm::test::TIER_NAME_ID.to_owned(), + idle_lobbies: None, + }) + .collect(), + + max_players_normal: 8, + max_players_direct: 10, + max_players_party: 12, + listable: true, + + runtime: Some( + backend::matchmaker::lobby_runtime::Docker { + build_id: build_res.build_id, + args: Vec::new(), + env_vars: Vec::new(), + network_mode: + backend::matchmaker::lobby_runtime::NetworkMode::Bridge + as i32, + ports: Vec::new(), + } + .into(), + ), + + find_config: Some(backend::matchmaker::FindConfig { + enabled: false, + identity_requirement: backend::matchmaker::IdentityRequirement::None as i32, + verification_config: None, + }), + join_config: Some(backend::matchmaker::JoinConfig { + enabled: false, + identity_requirement: backend::matchmaker::IdentityRequirement::None as i32, + verification_config: None, + }), + create_config: None, + }], + }), + }) + .await + .unwrap(); + + let lobby_res = op!([ctx] faker_mm_lobby { + namespace_id: Some(*namespace_id), + version_id: version_create_res.version_id, + ..Default::default() + }) + .await + .unwrap(); + + ( + lobby_res.namespace_id.unwrap().as_uuid(), + lobby_res.lobby_id.unwrap().as_uuid(), + ) +} + +struct FindRequest { namespace_id: Uuid, players: Vec, query: mm::msg::lobby_find::message::Query, + user_id: Option, + verification_data_json: Option, + bypass_verification: bool, +} + +async fn find( + ctx: &TestCtx, + req: FindRequest, ) -> Result< chirp_client::message::ReceivedMessage, chirp_client::message::ReceivedMessage, > { let query_id = Uuid::new_v4(); - msg!([ctx] @notrace mm::msg::lobby_find(namespace_id, query_id) -> Result { - namespace_id: Some(namespace_id.into()), + msg!([ctx] @notrace mm::msg::lobby_find(req.namespace_id, query_id) -> Result { + namespace_id: Some(req.namespace_id.into()), query_id: Some(query_id.into()), join_kind: backend::matchmaker::query::JoinKind::Normal as i32, - players: players, - query: Some(query), + players: req.players, + query: Some(req.query), + + user_id: req.user_id.map(Into::into), + verification_data_json: req.verification_data_json, + bypass_verification: req.bypass_verification, }) .await .unwrap() diff --git a/svc/pkg/mm/worker/tests/lobby_state_set.rs b/svc/pkg/mm/worker/tests/lobby_state_set.rs new file mode 100644 index 0000000000..51ca1207b3 --- /dev/null +++ b/svc/pkg/mm/worker/tests/lobby_state_set.rs @@ -0,0 +1,29 @@ +use chirp_worker::prelude::*; +use proto::backend::pkg::*; + +#[worker_test] +async fn set_lobby_state(ctx: TestCtx) { + let lobby = op!([ctx] faker_mm_lobby { + ..Default::default() + }) + .await + .unwrap(); + let lobby_id = lobby.lobby_id.unwrap(); + + let json = Some(r#"{ "foo": "bar" }"#.to_string()); + msg!([ctx] mm::msg::lobby_state_set(lobby_id) -> mm::msg::lobby_state_set_complete { + lobby_id: Some(lobby_id), + state_json: json.clone(), + }) + .await + .unwrap(); + + let res = op!([ctx] mm_lobby_state_get { + lobby_ids: vec![lobby_id], + }) + .await + .unwrap(); + let lobby = res.lobbies.first().unwrap(); + + assert_eq!(json, lobby.state_json); +} diff --git a/svc/pkg/mm/worker/tests/player_register.rs b/svc/pkg/mm/worker/tests/player_register.rs index 9c539fc647..5ae27a108f 100644 --- a/svc/pkg/mm/worker/tests/player_register.rs +++ b/svc/pkg/mm/worker/tests/player_register.rs @@ -25,6 +25,7 @@ async fn empty(ctx: TestCtx) { query: Some(mm::msg::lobby_find::message::Query::Direct(backend::matchmaker::query::Direct { lobby_id: Some(lobby_id.into()), })), + ..Default::default() }) .await .unwrap().unwrap(); @@ -97,6 +98,7 @@ async fn wrong_lobby(ctx: TestCtx) { query: Some(mm::msg::lobby_find::message::Query::Direct(backend::matchmaker::query::Direct { lobby_id: Some(lobby_id.into()), })), + ..Default::default() }) .await .unwrap().unwrap(); diff --git a/svc/pkg/mm/worker/tests/player_remove.rs b/svc/pkg/mm/worker/tests/player_remove.rs index 983d920385..36f675aa57 100644 --- a/svc/pkg/mm/worker/tests/player_remove.rs +++ b/svc/pkg/mm/worker/tests/player_remove.rs @@ -34,6 +34,7 @@ async fn basic(ctx: TestCtx) { query: Some(mm::msg::lobby_find::message::Query::Direct(backend::matchmaker::query::Direct { lobby_id: Some(lobby_id.into()), })), + ..Default::default() }) .await .unwrap().unwrap(); diff --git a/svc/pkg/module/ops/game-version-get/Cargo.toml b/svc/pkg/module/ops/game-version-get/Cargo.toml index 75c4b96400..d34bcb0810 100644 --- a/svc/pkg/module/ops/game-version-get/Cargo.toml +++ b/svc/pkg/module/ops/game-version-get/Cargo.toml @@ -11,7 +11,7 @@ chirp-client = { path = "../../../../../lib/chirp/client" } prost = "0.10" [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/module/ops/game-version-get/Service.toml b/svc/pkg/module/ops/game-version-get/Service.toml index 1b1db62974..aa5bd904d7 100644 --- a/svc/pkg/module/ops/game-version-get/Service.toml +++ b/svc/pkg/module/ops/game-version-get/Service.toml @@ -5,3 +5,6 @@ name = "module-game-version-get" kind = "rust" [operation] + +[databases] +db-module = {} diff --git a/svc/pkg/module/ops/game-version-publish/Cargo.toml b/svc/pkg/module/ops/game-version-publish/Cargo.toml index f66c938c6f..6247971b6a 100644 --- a/svc/pkg/module/ops/game-version-publish/Cargo.toml +++ b/svc/pkg/module/ops/game-version-publish/Cargo.toml @@ -13,7 +13,7 @@ unzip-n = "0.1.2" itertools = "0.10.5" [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/module/ops/game-version-publish/Service.toml b/svc/pkg/module/ops/game-version-publish/Service.toml index 3ad0136598..c577438934 100644 --- a/svc/pkg/module/ops/game-version-publish/Service.toml +++ b/svc/pkg/module/ops/game-version-publish/Service.toml @@ -5,3 +5,6 @@ name = "module-game-version-publish" kind = "rust" [operation] + +[databases] +db-module = {} diff --git a/svc/pkg/module/ops/get/Cargo.toml b/svc/pkg/module/ops/get/Cargo.toml index a4b31a8bf2..411fc6a8cf 100644 --- a/svc/pkg/module/ops/get/Cargo.toml +++ b/svc/pkg/module/ops/get/Cargo.toml @@ -11,7 +11,7 @@ prost = "0.10" rivet-operation = { path = "../../../../../lib/operation/core" } [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/module/ops/get/Service.toml b/svc/pkg/module/ops/get/Service.toml index 82dfb79351..5c76b26208 100644 --- a/svc/pkg/module/ops/get/Service.toml +++ b/svc/pkg/module/ops/get/Service.toml @@ -5,3 +5,6 @@ name = "module-get" kind = "rust" [operation] + +[databases] +db-module = {} diff --git a/svc/pkg/module/ops/instance-call/Cargo.toml b/svc/pkg/module/ops/instance-call/Cargo.toml index edb84d378c..f517394032 100644 --- a/svc/pkg/module/ops/instance-call/Cargo.toml +++ b/svc/pkg/module/ops/instance-call/Cargo.toml @@ -16,7 +16,7 @@ serde = { version = "1.0", features = ["derive"] } reqwest = { version = "0.11", features = ["json"] } [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/module/ops/instance-get/Cargo.toml b/svc/pkg/module/ops/instance-get/Cargo.toml index 2ab74c9491..25cce92fb6 100644 --- a/svc/pkg/module/ops/instance-get/Cargo.toml +++ b/svc/pkg/module/ops/instance-get/Cargo.toml @@ -11,7 +11,7 @@ prost = "0.10" rivet-operation = { path = "../../../../../lib/operation/core" } [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/module/ops/instance-get/Service.toml b/svc/pkg/module/ops/instance-get/Service.toml index 7bf4727b5f..bb073073c4 100644 --- a/svc/pkg/module/ops/instance-get/Service.toml +++ b/svc/pkg/module/ops/instance-get/Service.toml @@ -5,3 +5,6 @@ name = "module-instance-get" kind = "rust" [operation] + +[databases] +db-module = {} diff --git a/svc/pkg/module/ops/ns-instance-get/Cargo.toml b/svc/pkg/module/ops/ns-instance-get/Cargo.toml index 0cb0e13fc0..8b08930c34 100644 --- a/svc/pkg/module/ops/ns-instance-get/Cargo.toml +++ b/svc/pkg/module/ops/ns-instance-get/Cargo.toml @@ -11,7 +11,7 @@ prost = "0.10" rivet-operation = { path = "../../../../../lib/operation/core" } [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/module/ops/ns-instance-get/Service.toml b/svc/pkg/module/ops/ns-instance-get/Service.toml index f42b4adb29..0e3ce2fd90 100644 --- a/svc/pkg/module/ops/ns-instance-get/Service.toml +++ b/svc/pkg/module/ops/ns-instance-get/Service.toml @@ -5,3 +5,6 @@ name = "module-ns-instance-get" kind = "rust" [operation] + +[databases] +db-module = {} diff --git a/svc/pkg/module/ops/version-get/Cargo.toml b/svc/pkg/module/ops/version-get/Cargo.toml index e1c9fc8613..3e208ee6d3 100644 --- a/svc/pkg/module/ops/version-get/Cargo.toml +++ b/svc/pkg/module/ops/version-get/Cargo.toml @@ -13,7 +13,7 @@ rivet-operation = { path = "../../../../../lib/operation/core" } module-get = { path = "../get" } [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/module/ops/version-get/Service.toml b/svc/pkg/module/ops/version-get/Service.toml index 40e08641de..f60ddc2cda 100644 --- a/svc/pkg/module/ops/version-get/Service.toml +++ b/svc/pkg/module/ops/version-get/Service.toml @@ -5,3 +5,6 @@ name = "module-version-get" kind = "rust" [operation] + +[databases] +db-module = {} diff --git a/svc/pkg/module/worker/Cargo.toml b/svc/pkg/module/worker/Cargo.toml index 500082973a..7838139ff7 100644 --- a/svc/pkg/module/worker/Cargo.toml +++ b/svc/pkg/module/worker/Cargo.toml @@ -22,15 +22,14 @@ module-instance-get = { path = "../ops/instance-get" } module-game-version-get = { path = "../ops/game-version-get" } [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false features = [ - "runtime-tokio-native-tls", + "runtime-tokio", "postgres", "macros", "uuid", "json", - "tls", ] [dev-dependencies] diff --git a/svc/pkg/module/worker/Service.toml b/svc/pkg/module/worker/Service.toml index 67e38c5305..a56f7a9b99 100644 --- a/svc/pkg/module/worker/Service.toml +++ b/svc/pkg/module/worker/Service.toml @@ -6,5 +6,8 @@ kind = "rust" [consumer] +[databases] +db-module = {} + [secrets] -"fly/auth_token" = {} +"fly/auth_token" = { optional = true } diff --git a/svc/pkg/module/worker/src/workers/create.rs b/svc/pkg/module/worker/src/workers/create.rs index a84120be3a..160b754413 100644 --- a/svc/pkg/module/worker/src/workers/create.rs +++ b/svc/pkg/module/worker/src/workers/create.rs @@ -3,7 +3,7 @@ use proto::backend::pkg::*; use serde_json::json; #[worker(name = "module-create")] -async fn worker(ctx: OperationContext) -> Result<(), GlobalError> { +async fn worker(ctx: &OperationContext) -> Result<(), GlobalError> { let crdb = ctx.crdb("db-module").await?; let module_id = internal_unwrap!(ctx.module_id).as_uuid(); diff --git a/svc/pkg/module/worker/src/workers/instance_create.rs b/svc/pkg/module/worker/src/workers/instance_create.rs index db3968a5f9..a5446f43f2 100644 --- a/svc/pkg/module/worker/src/workers/instance_create.rs +++ b/svc/pkg/module/worker/src/workers/instance_create.rs @@ -94,11 +94,14 @@ struct CheckStatus { #[worker(name = "module-instance-create")] async fn worker( - ctx: OperationContext, + ctx: &OperationContext, ) -> Result<(), GlobalError> { let crdb = ctx.crdb("db-module").await?; - let (Ok(fly_org), Ok(fly_region)) = (std::env::var("FLY_ORGANIZATION_ID"), std::env::var("FLY_REGION")) else { + let (Ok(fly_org), Ok(fly_region)) = ( + std::env::var("FLY_ORGANIZATION_ID"), + std::env::var("FLY_REGION"), + ) else { internal_panic!("fly not enabled") }; let fly_auth_token = util::env::read_secret(&["fly", "auth_token"]).await?; @@ -196,7 +199,7 @@ async fn insert_instance( .bind(instance_id) .bind(version_id) .bind(now) - .execute(&mut *tx) + .execute(&mut **tx) .await?; match internal_unwrap!(msg.driver) { @@ -208,7 +211,7 @@ async fn insert_instance( " )) .bind(instance_id) - .execute(&mut *tx) + .execute(&mut **tx) .await?; } module::msg::instance_create::message::Driver::Fly(_) => { @@ -219,7 +222,7 @@ async fn insert_instance( " )) .bind(instance_id) - .execute(&mut *tx) + .execute(&mut **tx) .await?; } } diff --git a/svc/pkg/module/worker/src/workers/instance_destroy.rs b/svc/pkg/module/worker/src/workers/instance_destroy.rs index b7c97969ee..e15eb9b15b 100644 --- a/svc/pkg/module/worker/src/workers/instance_destroy.rs +++ b/svc/pkg/module/worker/src/workers/instance_destroy.rs @@ -3,7 +3,7 @@ use proto::backend::{self, pkg::*}; #[worker(name = "module-instance-destroy")] async fn worker( - ctx: OperationContext, + ctx: &OperationContext, ) -> Result<(), GlobalError> { let crdb = ctx.crdb("db-module").await?; diff --git a/svc/pkg/module/worker/src/workers/instance_version_set.rs b/svc/pkg/module/worker/src/workers/instance_version_set.rs index e9f4cdda3a..b80f49cc39 100644 --- a/svc/pkg/module/worker/src/workers/instance_version_set.rs +++ b/svc/pkg/module/worker/src/workers/instance_version_set.rs @@ -5,7 +5,7 @@ use serde_json::json; #[worker(name = "module-instance-version-set")] async fn worker( - ctx: OperationContext, + ctx: &OperationContext, ) -> Result<(), GlobalError> { let crdb = ctx.crdb("db-module").await?; diff --git a/svc/pkg/module/worker/src/workers/ns_version_set.rs b/svc/pkg/module/worker/src/workers/ns_version_set.rs index 30f14c5e79..ee676eb34d 100644 --- a/svc/pkg/module/worker/src/workers/ns_version_set.rs +++ b/svc/pkg/module/worker/src/workers/ns_version_set.rs @@ -19,7 +19,7 @@ struct NamespaceInstances { #[worker(name = "module-ns-version-set")] async fn worker( - ctx: OperationContext, + ctx: &OperationContext, ) -> Result<(), GlobalError> { let crdb = ctx.crdb("db-module").await?; @@ -33,10 +33,14 @@ async fn worker( version_ids: vec![version_id.into()], }) .await?; - let game_version = internal_unwrap_owned!(game_versions + let Some(game_version) = game_versions .versions .first() - .and_then(|x| x.config.as_ref())); + .and_then(|x| x.config.as_ref()) + else { + tracing::info!("no game version found"); + return Ok(()); + }; let new_version_keys = game_version .dependencies diff --git a/svc/pkg/module/worker/src/workers/version_create.rs b/svc/pkg/module/worker/src/workers/version_create.rs index d6d2423cef..6d82e21fc6 100644 --- a/svc/pkg/module/worker/src/workers/version_create.rs +++ b/svc/pkg/module/worker/src/workers/version_create.rs @@ -5,7 +5,7 @@ use std::convert::TryInto; #[worker(name = "module-version-create")] async fn worker( - ctx: OperationContext, + ctx: &OperationContext, ) -> Result<(), GlobalError> { let crdb = ctx.crdb("db-module").await?; @@ -61,7 +61,7 @@ async fn update_db( .bind(TryInto::::try_into(msg.major)?) .bind(TryInto::::try_into(msg.minor)?) .bind(TryInto::::try_into(msg.patch)?) - .execute(&mut *tx) + .execute(&mut **tx) .await?; match internal_unwrap!(msg.image) { @@ -74,7 +74,7 @@ async fn update_db( )) .bind(version_id) .bind(&docker.image_tag) - .execute(&mut *tx) + .execute(&mut **tx) .await?; } } @@ -90,7 +90,7 @@ async fn update_db( .bind(&script.name) .bind(&script.request_schema) .bind(&script.response_schema) - .execute(&mut *tx) + .execute(&mut **tx) .await?; if script.callable.is_some() { @@ -102,7 +102,7 @@ async fn update_db( )) .bind(version_id) .bind(&script.name) - .execute(&mut *tx) + .execute(&mut **tx) .await?; } } diff --git a/svc/pkg/nomad-log/ops/read/Service.toml b/svc/pkg/nomad-log/ops/read/Service.toml index a284cf9b71..fbe9272893 100644 --- a/svc/pkg/nomad-log/ops/read/Service.toml +++ b/svc/pkg/nomad-log/ops/read/Service.toml @@ -8,3 +8,6 @@ kind = "rust" [secrets] "clickhouse/users/chirp/password" = {} + +[databases] +db-nomad-logs = {} diff --git a/svc/pkg/nomad-log/standalone/follower/Cargo.toml b/svc/pkg/nomad-log/standalone/follower/Cargo.toml index 8b1f47e06e..f5db65e106 100644 --- a/svc/pkg/nomad-log/standalone/follower/Cargo.toml +++ b/svc/pkg/nomad-log/standalone/follower/Cargo.toml @@ -22,7 +22,7 @@ rivet-pools = { path = "../../../../../lib/pools" } rivet-runtime = { path = "../../../../../lib/runtime" } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" -tokio = { version = "1.21", features = ["full"] } +tokio = { version = "1.29", features = ["full"] } tracing = "0.1" tracing-subscriber = { version = "0.3", default-features = false, features = ["fmt", "json", "ansi"] } util-job = { package = "rivet-util-job", path = "../../../job/util" } diff --git a/svc/pkg/nomad-log/worker/src/workers/export.rs b/svc/pkg/nomad-log/worker/src/workers/export.rs index 971b0b697d..a3cce0269d 100644 --- a/svc/pkg/nomad-log/worker/src/workers/export.rs +++ b/svc/pkg/nomad-log/worker/src/workers/export.rs @@ -8,7 +8,7 @@ struct LogEntry { } #[worker(name = "nomad-log-export")] -async fn worker(ctx: OperationContext) -> GlobalResult<()> { +async fn worker(ctx: &OperationContext) -> GlobalResult<()> { let clickhouse = clickhouse::Client::default() .with_url("http://http.clickhouse.service.consul:8123") .with_user("chirp") diff --git a/svc/pkg/nomad-log/worker/src/workers/write.rs b/svc/pkg/nomad-log/worker/src/workers/write.rs index 0b41ad9c0d..17ff1cddf7 100644 --- a/svc/pkg/nomad-log/worker/src/workers/write.rs +++ b/svc/pkg/nomad-log/worker/src/workers/write.rs @@ -12,7 +12,7 @@ struct LogEntry<'a> { } #[worker(name = "nomad-log-write")] -async fn worker(ctx: OperationContext) -> GlobalResult<()> { +async fn worker(ctx: &OperationContext) -> GlobalResult<()> { let client = clickhouse::Client::default() .with_url("http://http.clickhouse.service.consul:8123") .with_user("chirp") diff --git a/svc/pkg/push-notification/worker/Service.toml b/svc/pkg/push-notification/worker/Service.toml index b07bb06ff2..02c6fef752 100644 --- a/svc/pkg/push-notification/worker/Service.toml +++ b/svc/pkg/push-notification/worker/Service.toml @@ -5,3 +5,6 @@ name = "push-notification-worker" kind = "rust" [consumer] + +[databases] +db-user-notification-auth = {} diff --git a/svc/pkg/push-notification/worker/src/workers/send.rs b/svc/pkg/push-notification/worker/src/workers/send.rs index 29558df3fb..77314a251f 100644 --- a/svc/pkg/push-notification/worker/src/workers/send.rs +++ b/svc/pkg/push-notification/worker/src/workers/send.rs @@ -13,7 +13,7 @@ struct NotificationData { #[worker(name = "push-notification-send")] async fn worker( - ctx: OperationContext, + ctx: &OperationContext, ) -> GlobalResult<()> { let user_id = internal_unwrap!(ctx.user_id).as_uuid(); let thread_id = internal_unwrap!(ctx.thread_id).as_uuid(); @@ -22,7 +22,7 @@ async fn worker( )); match service { - // Send push notificaton through Firebase + // Send push notification through Firebase backend::notification::NotificationService::Firebase => { let row = sqlx::query_as::<_, (Option,)>(indoc!( " @@ -63,11 +63,7 @@ async fn worker( &text.body.chars().collect::>(), 1024, )?; - let icon = util::route::user_avatar( - &user.avatar_id, - user.profile_upload_id.as_ref().map(common::Uuid::as_uuid), - user.profile_file_name.as_ref(), - ); + let icon = util::route::user_avatar(&user); let click_url = format!("/threads/{}", thread_id); let mut notif_builder = NotificationBuilder::new(); diff --git a/svc/pkg/region/ops/get/Cargo.toml b/svc/pkg/region/ops/get/Cargo.toml index b49c30c467..40db38d8a9 100644 --- a/svc/pkg/region/ops/get/Cargo.toml +++ b/svc/pkg/region/ops/get/Cargo.toml @@ -12,7 +12,7 @@ prost = "0.10" util-region = { package = "rivet-util-region", path = "../../util" } [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/region/ops/list/Cargo.toml b/svc/pkg/region/ops/list/Cargo.toml index 7832a3cfc2..bced1f244c 100644 --- a/svc/pkg/region/ops/list/Cargo.toml +++ b/svc/pkg/region/ops/list/Cargo.toml @@ -12,7 +12,7 @@ prost = "0.10" util-region = { package = "rivet-util-region", path = "../../util" } [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/region/ops/recommend/Cargo.toml b/svc/pkg/region/ops/recommend/Cargo.toml index f5206d92d1..4e404562a4 100644 --- a/svc/pkg/region/ops/recommend/Cargo.toml +++ b/svc/pkg/region/ops/recommend/Cargo.toml @@ -15,7 +15,7 @@ ip-info = { path = "../../../ip/ops/info" } region-get = { path = "../get" } [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/region/ops/resolve/Cargo.toml b/svc/pkg/region/ops/resolve/Cargo.toml index 3a88e14d30..fd5ad3ed92 100644 --- a/svc/pkg/region/ops/resolve/Cargo.toml +++ b/svc/pkg/region/ops/resolve/Cargo.toml @@ -12,7 +12,7 @@ prost = "0.10" util-region = { package = "rivet-util-region", path = "../../util" } [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/region/util/Cargo.toml b/svc/pkg/region/util/Cargo.toml index e2e4ed07f7..fbf58d6e40 100644 --- a/svc/pkg/region/util/Cargo.toml +++ b/svc/pkg/region/util/Cargo.toml @@ -8,5 +8,5 @@ license = "Apache-2.0" [dependencies] serde = { version = "1.0", features = ["derive"] } uuid = { version = "1", features = ["v4", "serde"] } -tokio = { version = "1.21", features = ["sync"] } +tokio = { version = "1.29", features = ["sync"] } serde_json = "1.0" diff --git a/svc/pkg/team-dev/ops/game-list/Cargo.toml b/svc/pkg/team-dev/ops/game-list/Cargo.toml index 1cf6674d22..d7befcd43f 100644 --- a/svc/pkg/team-dev/ops/game-list/Cargo.toml +++ b/svc/pkg/team-dev/ops/game-list/Cargo.toml @@ -11,7 +11,7 @@ chirp-client = { path = "../../../../../lib/chirp/client" } prost = "0.10" [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/team-dev/ops/game-list/Service.toml b/svc/pkg/team-dev/ops/game-list/Service.toml index 605739ed1b..40b2710c20 100644 --- a/svc/pkg/team-dev/ops/game-list/Service.toml +++ b/svc/pkg/team-dev/ops/game-list/Service.toml @@ -5,3 +5,6 @@ name = "team-dev-game-list" kind = "rust" [operation] + +[databases] +db-game = {} diff --git a/svc/pkg/team-dev/ops/get/Cargo.toml b/svc/pkg/team-dev/ops/get/Cargo.toml index 7fb6fecc06..ab92b162b0 100644 --- a/svc/pkg/team-dev/ops/get/Cargo.toml +++ b/svc/pkg/team-dev/ops/get/Cargo.toml @@ -11,7 +11,7 @@ chirp-client = { path = "../../../../../lib/chirp/client" } prost = "0.10" [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/team-dev/ops/get/Service.toml b/svc/pkg/team-dev/ops/get/Service.toml index 54b8a867fa..9195bceda9 100644 --- a/svc/pkg/team-dev/ops/get/Service.toml +++ b/svc/pkg/team-dev/ops/get/Service.toml @@ -5,3 +5,6 @@ name = "team-dev-get" kind = "rust" [operation] + +[databases] +db-team-dev = {} diff --git a/svc/pkg/team-dev/ops/halt/Cargo.toml b/svc/pkg/team-dev/ops/halt/Cargo.toml index 96ab475820..cad1eefa2c 100644 --- a/svc/pkg/team-dev/ops/halt/Cargo.toml +++ b/svc/pkg/team-dev/ops/halt/Cargo.toml @@ -14,7 +14,7 @@ mm-lobby-list-for-namespace = { path = "../../../mm/ops/lobby-list-for-namespace game-namespace-list = { path = "../../../game/ops/namespace-list" } [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/team-dev/ops/halt/Service.toml b/svc/pkg/team-dev/ops/halt/Service.toml index 7ecda95010..8de984cb04 100644 --- a/svc/pkg/team-dev/ops/halt/Service.toml +++ b/svc/pkg/team-dev/ops/halt/Service.toml @@ -5,3 +5,6 @@ name = "team-dev-halt" kind = "rust" [operation] + +[databases] +db-game = {} diff --git a/svc/pkg/team-dev/standalone/halt-collect/Cargo.toml b/svc/pkg/team-dev/standalone/halt-collect/Cargo.toml index 413c74f026..6b69fac489 100644 --- a/svc/pkg/team-dev/standalone/halt-collect/Cargo.toml +++ b/svc/pkg/team-dev/standalone/halt-collect/Cargo.toml @@ -16,21 +16,19 @@ rivet-connection = { path = "../../../../../lib/connection" } chrono = "0.4" rivet-pools = { path = "../../../../../lib/pools" } rivet-runtime = { path = "../../../../../lib/runtime" } -tokio = { version = "1.21", features = ["full"] } +tokio = { version = "1.29", features = ["full"] } tracing = "0.1" tracing-subscriber = { version = "0.3", default-features = false, features = ["fmt", "json", "ansi"] } team-dev-halt = { path = "../../ops/halt" } [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false features = [ - "runtime-tokio-native-tls", "postgres", "uuid", "json", - "tls", "macros", ] diff --git a/svc/pkg/team-dev/standalone/halt-collect/Service.toml b/svc/pkg/team-dev/standalone/halt-collect/Service.toml index 9bb2935a5e..7370eb388e 100644 --- a/svc/pkg/team-dev/standalone/halt-collect/Service.toml +++ b/svc/pkg/team-dev/standalone/halt-collect/Service.toml @@ -7,3 +7,6 @@ kind = "rust" [periodic] cron = "0 0 * * *" + +[databases] +db-team-dev = {} diff --git a/svc/pkg/team-dev/worker/Service.toml b/svc/pkg/team-dev/worker/Service.toml index f49c34f80a..2e26694f16 100644 --- a/svc/pkg/team-dev/worker/Service.toml +++ b/svc/pkg/team-dev/worker/Service.toml @@ -6,3 +6,6 @@ kind = "rust" [consumer] + +[databases] +db-team-dev = {} diff --git a/svc/pkg/team-dev/worker/src/workers/create.rs b/svc/pkg/team-dev/worker/src/workers/create.rs index e7487ca13f..c423cf0a55 100644 --- a/svc/pkg/team-dev/worker/src/workers/create.rs +++ b/svc/pkg/team-dev/worker/src/workers/create.rs @@ -3,7 +3,7 @@ use proto::backend::{self, pkg::*}; use serde_json::json; #[worker(name = "team-dev-create")] -async fn worker(ctx: OperationContext) -> GlobalResult<()> { +async fn worker(ctx: &OperationContext) -> GlobalResult<()> { let team_id = internal_unwrap!(ctx.team_id).as_uuid(); // Get the team diff --git a/svc/pkg/team-dev/worker/src/workers/halt_team_dev_update.rs b/svc/pkg/team-dev/worker/src/workers/halt_team_dev_update.rs index c922306e32..8ec63a5d58 100644 --- a/svc/pkg/team-dev/worker/src/workers/halt_team_dev_update.rs +++ b/svc/pkg/team-dev/worker/src/workers/halt_team_dev_update.rs @@ -2,7 +2,7 @@ use chirp_worker::prelude::*; use proto::backend::{self, pkg::*}; #[worker(name = "team-dev-halt-team-dev-update")] -async fn worker(ctx: OperationContext) -> GlobalResult<()> { +async fn worker(ctx: &OperationContext) -> GlobalResult<()> { let team_id = internal_unwrap!(ctx.team_id).as_uuid(); let team_dev_res = op!([ctx] team_dev_get { diff --git a/svc/pkg/team-dev/worker/src/workers/status_update.rs b/svc/pkg/team-dev/worker/src/workers/status_update.rs index dc6053b950..be8e825db9 100644 --- a/svc/pkg/team-dev/worker/src/workers/status_update.rs +++ b/svc/pkg/team-dev/worker/src/workers/status_update.rs @@ -2,7 +2,7 @@ use chirp_worker::prelude::*; use proto::backend::pkg::*; #[worker(name = "team-dev-status-update")] -async fn worker(ctx: OperationContext) -> GlobalResult<()> { +async fn worker(ctx: &OperationContext) -> GlobalResult<()> { let team_id = if let Some(setup_complete) = ctx.setup_complete { let (team_id,) = sqlx::query_as::<_, (Uuid,)>(indoc!( " diff --git a/svc/pkg/team-invite/ops/get/Cargo.toml b/svc/pkg/team-invite/ops/get/Cargo.toml index 0db1fb3b23..447c6629b9 100644 --- a/svc/pkg/team-invite/ops/get/Cargo.toml +++ b/svc/pkg/team-invite/ops/get/Cargo.toml @@ -12,7 +12,7 @@ chrono = "0.4" prost = "0.10" [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/team-invite/ops/get/Service.toml b/svc/pkg/team-invite/ops/get/Service.toml index cc8c0e6c54..3b6ba2e65d 100644 --- a/svc/pkg/team-invite/ops/get/Service.toml +++ b/svc/pkg/team-invite/ops/get/Service.toml @@ -5,3 +5,6 @@ name = "team-invite-get" kind = "rust" [operation] + +[databases] +db-team-invite = {} diff --git a/svc/pkg/team-invite/worker/Cargo.toml b/svc/pkg/team-invite/worker/Cargo.toml index 948060affe..ef4ba13ffa 100644 --- a/svc/pkg/team-invite/worker/Cargo.toml +++ b/svc/pkg/team-invite/worker/Cargo.toml @@ -17,7 +17,7 @@ team-member-list = { path = "../../team/ops/member-list" } team-user-ban-get = { path = "../../team/ops/user-ban-get" } [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/team-invite/worker/Service.toml b/svc/pkg/team-invite/worker/Service.toml index 4099226ff5..03d142021c 100644 --- a/svc/pkg/team-invite/worker/Service.toml +++ b/svc/pkg/team-invite/worker/Service.toml @@ -5,3 +5,6 @@ name = "team-invite-worker" kind = "rust" [consumer] + +[databases] +db-team-invite = {} diff --git a/svc/pkg/team-invite/worker/src/workers/consume.rs b/svc/pkg/team-invite/worker/src/workers/consume.rs index 7c7acb5f9e..58fc4c10f5 100644 --- a/svc/pkg/team-invite/worker/src/workers/consume.rs +++ b/svc/pkg/team-invite/worker/src/workers/consume.rs @@ -12,7 +12,7 @@ struct InvitationRow { } #[worker(name = "team-invite-consume")] -async fn worker(ctx: OperationContext) -> GlobalResult<()> { +async fn worker(ctx: &OperationContext) -> GlobalResult<()> { let crdb = ctx.crdb("db-team-invite").await?; let user_id = internal_unwrap!(ctx.user_id).as_uuid(); @@ -111,7 +111,7 @@ async fn update_db( ", ) .bind(&code) - .fetch_optional(&mut *tx) + .fetch_optional(&mut **tx) .await?; let invitation_row = if let Some(invitation) = invitation_row { tracing::info!(?invitation, "found invitation"); @@ -188,13 +188,13 @@ async fn update_db( // Insert consumption sqlx::query("UPDATE invitations SET use_counter = use_counter + 1 WHERE code = $1") .bind(&code) - .execute(&mut *tx) + .execute(&mut **tx) .await?; sqlx::query("INSERT INTO invitation_uses (code, user_id, create_ts) VALUES ($1, $2, $3)") .bind(&code) .bind(user_id) .bind(now) - .execute(&mut *tx) + .execute(&mut **tx) .await?; Ok(DbOutput::Success { invitation_row }) diff --git a/svc/pkg/team-invite/worker/src/workers/create.rs b/svc/pkg/team-invite/worker/src/workers/create.rs index 9cefb94a54..9874e1ea7b 100644 --- a/svc/pkg/team-invite/worker/src/workers/create.rs +++ b/svc/pkg/team-invite/worker/src/workers/create.rs @@ -3,7 +3,7 @@ use proto::backend::pkg::*; use serde_json::json; #[worker(name = "team-invite-create")] -async fn worker(ctx: OperationContext) -> GlobalResult<()> { +async fn worker(ctx: &OperationContext) -> GlobalResult<()> { let crdb = ctx.crdb("db-team-invite").await?; let team_id = internal_unwrap!(ctx.team_id).as_uuid(); diff --git a/svc/pkg/team/ops/avatar-upload-complete/Cargo.toml b/svc/pkg/team/ops/avatar-upload-complete/Cargo.toml index 64f50d8359..e7f69ccbb7 100644 --- a/svc/pkg/team/ops/avatar-upload-complete/Cargo.toml +++ b/svc/pkg/team/ops/avatar-upload-complete/Cargo.toml @@ -13,7 +13,7 @@ prost = "0.10" upload-complete = { path = "../../../upload/ops/complete" } [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/team/ops/avatar-upload-complete/Service.toml b/svc/pkg/team/ops/avatar-upload-complete/Service.toml index b0b55f1cc3..5f2a9d8f96 100644 --- a/svc/pkg/team/ops/avatar-upload-complete/Service.toml +++ b/svc/pkg/team/ops/avatar-upload-complete/Service.toml @@ -5,3 +5,6 @@ name = "team-avatar-upload-complete" kind = "rust" [operation] + +[databases] +db-team = {} diff --git a/svc/pkg/team/ops/get/Cargo.toml b/svc/pkg/team/ops/get/Cargo.toml index a01438c969..6f297432cc 100644 --- a/svc/pkg/team/ops/get/Cargo.toml +++ b/svc/pkg/team/ops/get/Cargo.toml @@ -14,7 +14,7 @@ upload-file-list = { path = "../../../upload/ops/file-list" } upload-get = { path = "../../../upload/ops/get" } [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/team/ops/get/Service.toml b/svc/pkg/team/ops/get/Service.toml index df9ba8d042..f65efe0ef7 100644 --- a/svc/pkg/team/ops/get/Service.toml +++ b/svc/pkg/team/ops/get/Service.toml @@ -5,3 +5,6 @@ name = "team-get" kind = "rust" [operation] + +[databases] +db-team = {} diff --git a/svc/pkg/team/ops/get/src/lib.rs b/svc/pkg/team/ops/get/src/lib.rs index 44be3980a8..d200677cbb 100644 --- a/svc/pkg/team/ops/get/src/lib.rs +++ b/svc/pkg/team/ops/get/src/lib.rs @@ -61,7 +61,7 @@ async fn handle(ctx: OperationContext) -> GlobalResult::into); // Fetch all information relating to the profile image - let (profile_upload_complete_ts, profile_file_name) = { + let (profile_upload_complete_ts, profile_file_name, profile_provider) = { let upload = upload_res .uploads .iter() @@ -77,7 +77,7 @@ async fn handle(ctx: OperationContext) -> GlobalResult) -> GlobalResult) -> GlobalResult<()> { +async fn worker(ctx: &OperationContext) -> GlobalResult<()> { let team_id = internal_unwrap!(ctx.team_id).as_uuid(); // Validate team diff --git a/svc/pkg/team/worker/src/workers/create_complete_chat_message_create.rs b/svc/pkg/team/worker/src/workers/create_complete_chat_message_create.rs index 1762dee94b..7da040082c 100644 --- a/svc/pkg/team/worker/src/workers/create_complete_chat_message_create.rs +++ b/svc/pkg/team/worker/src/workers/create_complete_chat_message_create.rs @@ -2,7 +2,7 @@ use chirp_worker::prelude::*; use proto::backend::{self, pkg::*}; #[worker(name = "team-create-complete-chat-message-create")] -async fn worker(ctx: OperationContext) -> GlobalResult<()> { +async fn worker(ctx: &OperationContext) -> GlobalResult<()> { // Create new chat with team op!([ctx] chat_message_create_with_topic { chat_message_id: Some(Uuid::new_v4().into()), diff --git a/svc/pkg/team/worker/src/workers/join_request_create.rs b/svc/pkg/team/worker/src/workers/join_request_create.rs index 03432d65a1..9de8d70b5b 100644 --- a/svc/pkg/team/worker/src/workers/join_request_create.rs +++ b/svc/pkg/team/worker/src/workers/join_request_create.rs @@ -35,7 +35,7 @@ async fn fail( #[worker(name = "team-join-request-create")] async fn worker( - ctx: OperationContext, + ctx: &OperationContext, ) -> GlobalResult<()> { let crdb = ctx.crdb("db-team").await?; let team_id: Uuid = internal_unwrap!(ctx.team_id).as_uuid(); diff --git a/svc/pkg/team/worker/src/workers/join_request_resolve.rs b/svc/pkg/team/worker/src/workers/join_request_resolve.rs index 917d1d53e5..aa8c51e8a3 100644 --- a/svc/pkg/team/worker/src/workers/join_request_resolve.rs +++ b/svc/pkg/team/worker/src/workers/join_request_resolve.rs @@ -4,7 +4,7 @@ use serde_json::json; #[worker(name = "team-join-request-resolve")] async fn worker( - ctx: OperationContext, + ctx: &OperationContext, ) -> GlobalResult<()> { let team_id: Uuid = internal_unwrap!(ctx.team_id).as_uuid(); let user_id: Uuid = internal_unwrap!(ctx.user_id).as_uuid(); diff --git a/svc/pkg/team/worker/src/workers/member_create.rs b/svc/pkg/team/worker/src/workers/member_create.rs index b0fa627464..eb74ab09c2 100644 --- a/svc/pkg/team/worker/src/workers/member_create.rs +++ b/svc/pkg/team/worker/src/workers/member_create.rs @@ -5,7 +5,7 @@ use serde_json::json; const MAX_TEAM_SIZE: i64 = 256; #[worker(name = "team-member-create")] -async fn worker(ctx: OperationContext) -> GlobalResult<()> { +async fn worker(ctx: &OperationContext) -> GlobalResult<()> { // Idempotent let team_id: Uuid = internal_unwrap!(ctx.team_id).as_uuid(); diff --git a/svc/pkg/team/worker/src/workers/member_kick.rs b/svc/pkg/team/worker/src/workers/member_kick.rs index 6ab04e055f..bd49283a51 100644 --- a/svc/pkg/team/worker/src/workers/member_kick.rs +++ b/svc/pkg/team/worker/src/workers/member_kick.rs @@ -3,7 +3,7 @@ use proto::backend::{self, pkg::*}; use serde_json::json; #[worker(name = "team-member-kick")] -async fn worker(ctx: OperationContext) -> GlobalResult<()> { +async fn worker(ctx: &OperationContext) -> GlobalResult<()> { let team_id = internal_unwrap!(ctx.team_id).as_uuid(); let user_id = internal_unwrap!(ctx.user_id).as_uuid(); diff --git a/svc/pkg/team/worker/src/workers/member_remove.rs b/svc/pkg/team/worker/src/workers/member_remove.rs index 393cab500e..cf09153995 100644 --- a/svc/pkg/team/worker/src/workers/member_remove.rs +++ b/svc/pkg/team/worker/src/workers/member_remove.rs @@ -3,7 +3,7 @@ use proto::backend::{self, pkg::*}; use serde_json::json; #[worker(name = "team-member-remove")] -async fn worker(ctx: OperationContext) -> GlobalResult<()> { +async fn worker(ctx: &OperationContext) -> GlobalResult<()> { let team_id: Uuid = internal_unwrap!(ctx.team_id).as_uuid(); let user_id: Uuid = internal_unwrap!(ctx.user_id).as_uuid(); diff --git a/svc/pkg/team/worker/src/workers/owner_transfer.rs b/svc/pkg/team/worker/src/workers/owner_transfer.rs index cdae782249..e0617c20bd 100644 --- a/svc/pkg/team/worker/src/workers/owner_transfer.rs +++ b/svc/pkg/team/worker/src/workers/owner_transfer.rs @@ -3,7 +3,7 @@ use proto::backend::{self, pkg::*}; use serde_json::json; #[worker(name = "team-owner-transfer")] -async fn worker(ctx: OperationContext) -> GlobalResult<()> { +async fn worker(ctx: &OperationContext) -> GlobalResult<()> { let raw_team_id = internal_unwrap!(ctx.team_id); let team_id = raw_team_id.as_uuid(); let new_owner_user_id = internal_unwrap!(ctx.new_owner_user_id).as_uuid(); diff --git a/svc/pkg/team/worker/src/workers/profile_set.rs b/svc/pkg/team/worker/src/workers/profile_set.rs index 2c9720b664..fd51db1cc9 100644 --- a/svc/pkg/team/worker/src/workers/profile_set.rs +++ b/svc/pkg/team/worker/src/workers/profile_set.rs @@ -4,7 +4,7 @@ use proto::backend::{self, pkg::*}; use serde_json::json; #[worker(name = "team-profile-set")] -async fn worker(ctx: OperationContext) -> GlobalResult<()> { +async fn worker(ctx: &OperationContext) -> GlobalResult<()> { let team::msg::profile_set::Message { team_id, display_name, diff --git a/svc/pkg/team/worker/src/workers/user_ban.rs b/svc/pkg/team/worker/src/workers/user_ban.rs index 6c83fb6a63..430ac267ef 100644 --- a/svc/pkg/team/worker/src/workers/user_ban.rs +++ b/svc/pkg/team/worker/src/workers/user_ban.rs @@ -3,7 +3,7 @@ use proto::backend::{self, pkg::*}; use serde_json::json; #[worker(name = "team-user-ban")] -async fn worker(ctx: OperationContext) -> GlobalResult<()> { +async fn worker(ctx: &OperationContext) -> GlobalResult<()> { let team_id = internal_unwrap!(ctx.team_id).as_uuid(); let user_id = internal_unwrap!(ctx.user_id).as_uuid(); diff --git a/svc/pkg/team/worker/src/workers/user_unban.rs b/svc/pkg/team/worker/src/workers/user_unban.rs index 212df1383d..041b7a3f3a 100644 --- a/svc/pkg/team/worker/src/workers/user_unban.rs +++ b/svc/pkg/team/worker/src/workers/user_unban.rs @@ -3,7 +3,7 @@ use proto::backend::pkg::*; use serde_json::json; #[worker(name = "team-user-unban")] -async fn worker(ctx: OperationContext) -> GlobalResult<()> { +async fn worker(ctx: &OperationContext) -> GlobalResult<()> { let team_id = internal_unwrap!(ctx.team_id).as_uuid(); let user_id = internal_unwrap!(ctx.user_id).as_uuid(); diff --git a/svc/pkg/telemetry/standalone/beacon/Cargo.toml b/svc/pkg/telemetry/standalone/beacon/Cargo.toml index e76b60e0d8..0d68ffde62 100644 --- a/svc/pkg/telemetry/standalone/beacon/Cargo.toml +++ b/svc/pkg/telemetry/standalone/beacon/Cargo.toml @@ -16,7 +16,7 @@ rivet-connection = { path = "../../../../../lib/connection" } rivet-operation = { path = "../../../../../lib/operation/core" } rivet-pools = { path = "../../../../../lib/pools" } rivet-runtime = { path = "../../../../../lib/runtime" } -tokio = { version = "1.21", features = ["full"] } +tokio = { version = "1.29", features = ["full"] } tracing = "0.1" tracing-subscriber = { version = "0.3", default-features = false, features = ["fmt", "json", "ansi"] } @@ -29,7 +29,7 @@ team-get = { path = "../../../team/ops/get" } team-member-count = { path = "../../../team/ops/member-count" } [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/telemetry/standalone/beacon/Service.toml b/svc/pkg/telemetry/standalone/beacon/Service.toml index ef48074f37..ac2f3d17a0 100644 --- a/svc/pkg/telemetry/standalone/beacon/Service.toml +++ b/svc/pkg/telemetry/standalone/beacon/Service.toml @@ -8,3 +8,7 @@ kind = "rust" [periodic] cron = "0 0 * * *" +[databases] +db-team-dev = {} +db-game-user = {} +db-game = {} diff --git a/svc/pkg/token/ops/create/Cargo.toml b/svc/pkg/token/ops/create/Cargo.toml index 6946964b99..d4770d2872 100644 --- a/svc/pkg/token/ops/create/Cargo.toml +++ b/svc/pkg/token/ops/create/Cargo.toml @@ -16,7 +16,7 @@ jsonwebtoken = "8.2.0" lazy_static = "1.4" [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/token/ops/create/Service.toml b/svc/pkg/token/ops/create/Service.toml index 5ee46e2073..ad1fd13e80 100644 --- a/svc/pkg/token/ops/create/Service.toml +++ b/svc/pkg/token/ops/create/Service.toml @@ -6,3 +6,5 @@ kind = "rust" [operation] +[databases] +db-token = {} diff --git a/svc/pkg/token/ops/exchange/Cargo.toml b/svc/pkg/token/ops/exchange/Cargo.toml index fdea99362f..76c14c120e 100644 --- a/svc/pkg/token/ops/exchange/Cargo.toml +++ b/svc/pkg/token/ops/exchange/Cargo.toml @@ -12,7 +12,7 @@ chrono = "0.4" prost = "0.10" [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false diff --git a/svc/pkg/token/ops/exchange/Service.toml b/svc/pkg/token/ops/exchange/Service.toml index 9565e5ac42..9dc7a99065 100644 --- a/svc/pkg/token/ops/exchange/Service.toml +++ b/svc/pkg/token/ops/exchange/Service.toml @@ -5,3 +5,6 @@ name = "token-exchange" kind = "rust" [operation] + +[databases] +db-token = {} diff --git a/svc/pkg/token/ops/get/Cargo.toml b/svc/pkg/token/ops/get/Cargo.toml index ee285ffdf8..3bf9f18b04 100644 --- a/svc/pkg/token/ops/get/Cargo.toml +++ b/svc/pkg/token/ops/get/Cargo.toml @@ -12,7 +12,7 @@ chrono = "0.4" prost = "0.10" [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/token/ops/get/Service.toml b/svc/pkg/token/ops/get/Service.toml index a13dd586b9..c7e62a4d2f 100644 --- a/svc/pkg/token/ops/get/Service.toml +++ b/svc/pkg/token/ops/get/Service.toml @@ -5,3 +5,6 @@ name = "token-get" kind = "rust" [operation] + +[databases] +db-token = {} diff --git a/svc/pkg/token/ops/revoke/Cargo.toml b/svc/pkg/token/ops/revoke/Cargo.toml index ba2ff26780..e58f206ba7 100644 --- a/svc/pkg/token/ops/revoke/Cargo.toml +++ b/svc/pkg/token/ops/revoke/Cargo.toml @@ -12,7 +12,7 @@ chrono = "0.4" prost = "0.10" [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/token/ops/revoke/Service.toml b/svc/pkg/token/ops/revoke/Service.toml index 5f999aaa1d..38764e733c 100644 --- a/svc/pkg/token/ops/revoke/Service.toml +++ b/svc/pkg/token/ops/revoke/Service.toml @@ -5,3 +5,6 @@ name = "token-revoke" kind = "rust" [operation] + +[databases] +db-token = {} diff --git a/svc/pkg/upload/ops/complete/Cargo.toml b/svc/pkg/upload/ops/complete/Cargo.toml index 12f80d085d..ae42fe8886 100644 --- a/svc/pkg/upload/ops/complete/Cargo.toml +++ b/svc/pkg/upload/ops/complete/Cargo.toml @@ -16,7 +16,7 @@ url = "2.2" nsfw-image-score = { path = "../../../nsfw/ops/image-score" } [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/upload/ops/complete/Service.toml b/svc/pkg/upload/ops/complete/Service.toml index 7f86573c5a..f751a33c71 100644 --- a/svc/pkg/upload/ops/complete/Service.toml +++ b/svc/pkg/upload/ops/complete/Service.toml @@ -6,3 +6,5 @@ kind = "rust" [operation] +[databases] +db-upload = {} diff --git a/svc/pkg/upload/ops/file-list/Cargo.toml b/svc/pkg/upload/ops/file-list/Cargo.toml index 753e73fc5e..d3e82e24fe 100644 --- a/svc/pkg/upload/ops/file-list/Cargo.toml +++ b/svc/pkg/upload/ops/file-list/Cargo.toml @@ -12,7 +12,7 @@ prost = "0.10" rivet-operation = { path = "../../../../../lib/operation/core" } [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/upload/ops/file-list/Service.toml b/svc/pkg/upload/ops/file-list/Service.toml index 5a6660bdda..c0de551d61 100644 --- a/svc/pkg/upload/ops/file-list/Service.toml +++ b/svc/pkg/upload/ops/file-list/Service.toml @@ -5,3 +5,6 @@ name = "upload-file-list" kind = "rust" [operation] + +[databases] +db-upload = {} diff --git a/svc/pkg/upload/ops/get/Cargo.toml b/svc/pkg/upload/ops/get/Cargo.toml index 713509d86f..0214a08afc 100644 --- a/svc/pkg/upload/ops/get/Cargo.toml +++ b/svc/pkg/upload/ops/get/Cargo.toml @@ -12,7 +12,7 @@ chrono = "0.4" prost = "0.10" [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/upload/ops/get/Service.toml b/svc/pkg/upload/ops/get/Service.toml index d3c2dd9e2e..31e24267ef 100644 --- a/svc/pkg/upload/ops/get/Service.toml +++ b/svc/pkg/upload/ops/get/Service.toml @@ -5,3 +5,6 @@ name = "upload-get" kind = "rust" [operation] + +[databases] +db-upload = {} diff --git a/svc/pkg/upload/ops/list-for-user/Cargo.toml b/svc/pkg/upload/ops/list-for-user/Cargo.toml index a1dcb7ee7c..0776b37550 100644 --- a/svc/pkg/upload/ops/list-for-user/Cargo.toml +++ b/svc/pkg/upload/ops/list-for-user/Cargo.toml @@ -12,7 +12,7 @@ chrono = "0.4" prost = "0.10" [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/upload/ops/list-for-user/Service.toml b/svc/pkg/upload/ops/list-for-user/Service.toml index b4de0db029..c372e81aca 100644 --- a/svc/pkg/upload/ops/list-for-user/Service.toml +++ b/svc/pkg/upload/ops/list-for-user/Service.toml @@ -5,3 +5,6 @@ name = "upload-list-for-user" kind = "rust" [operation] + +[databases] +db-upload = {} diff --git a/svc/pkg/upload/ops/prepare/Cargo.toml b/svc/pkg/upload/ops/prepare/Cargo.toml index 3cc57144ba..f5579967c5 100644 --- a/svc/pkg/upload/ops/prepare/Cargo.toml +++ b/svc/pkg/upload/ops/prepare/Cargo.toml @@ -13,7 +13,7 @@ prost = "0.10" s3-util = { path = "../../../../../lib/s3-util" } [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/upload/ops/prepare/Service.toml b/svc/pkg/upload/ops/prepare/Service.toml index 7ec79558fb..008e5ee102 100644 --- a/svc/pkg/upload/ops/prepare/Service.toml +++ b/svc/pkg/upload/ops/prepare/Service.toml @@ -6,3 +6,5 @@ kind = "rust" [operation] +[databases] +db-upload = {} diff --git a/svc/pkg/upload/standalone/provider-fill/Cargo.toml b/svc/pkg/upload/standalone/provider-fill/Cargo.toml index 32be469eca..41497aac98 100644 --- a/svc/pkg/upload/standalone/provider-fill/Cargo.toml +++ b/svc/pkg/upload/standalone/provider-fill/Cargo.toml @@ -15,19 +15,18 @@ rivet-connection = { path = "../../../../../lib/connection" } rivet-operation = { path = "../../../../../lib/operation/core" } rivet-pools = { path = "../../../../../lib/pools" } s3-util = { path = "../../../../../lib/s3-util" } -tokio = { version = "1.21", features = ["full"] } +tokio = { version = "1.29", features = ["full"] } tracing = "0.1" tracing-subscriber = { version = "0.3", default-features = false, features = ["fmt", "json", "ansi"] } [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false features = [ - "runtime-tokio-native-tls", + "runtime-tokio", "postgres", "uuid", "json", - "tls", ] [dev-dependencies] diff --git a/svc/pkg/upload/standalone/provider-fill/Service.toml b/svc/pkg/upload/standalone/provider-fill/Service.toml index 32e9d8233a..f3b17a39fd 100644 --- a/svc/pkg/upload/standalone/provider-fill/Service.toml +++ b/svc/pkg/upload/standalone/provider-fill/Service.toml @@ -5,3 +5,6 @@ name = "upload-provider-fill" kind = "rust" [oneshot] + +[databases] +db-upload = {} diff --git a/svc/pkg/upload/worker/Cargo.toml b/svc/pkg/upload/worker/Cargo.toml index fba60abe1e..72426aab80 100644 --- a/svc/pkg/upload/worker/Cargo.toml +++ b/svc/pkg/upload/worker/Cargo.toml @@ -14,7 +14,7 @@ rivet-runtime = { path = "../../../../lib/runtime" } s3-util = { path = "../../../../lib/s3-util" } [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/upload/worker/Service.toml b/svc/pkg/upload/worker/Service.toml index 6bce7524eb..dc81605a8c 100644 --- a/svc/pkg/upload/worker/Service.toml +++ b/svc/pkg/upload/worker/Service.toml @@ -5,3 +5,6 @@ name = "upload-worker" kind = "rust" [consumer] + +[databases] +db-upload = {} diff --git a/svc/pkg/upload/worker/src/workers/delete.rs b/svc/pkg/upload/worker/src/workers/delete.rs index b767ba7a93..239567dca9 100644 --- a/svc/pkg/upload/worker/src/workers/delete.rs +++ b/svc/pkg/upload/worker/src/workers/delete.rs @@ -23,7 +23,7 @@ struct BucketDeletions { } #[worker(name = "upload-delete")] -async fn worker(ctx: OperationContext) -> GlobalResult<()> { +async fn worker(ctx: &OperationContext) -> GlobalResult<()> { let crdb = ctx.crdb("db-upload").await?; let request_id = internal_unwrap!(ctx.request_id).as_uuid(); diff --git a/svc/pkg/user-dev/worker/src/workers/game_update.rs b/svc/pkg/user-dev/worker/src/workers/game_update.rs index e3cdb7ed6b..45e30c0784 100644 --- a/svc/pkg/user-dev/worker/src/workers/game_update.rs +++ b/svc/pkg/user-dev/worker/src/workers/game_update.rs @@ -6,7 +6,7 @@ use futures_util::{ use proto::backend::pkg::*; #[worker(name = "user-dev-game-update")] -async fn worker(ctx: OperationContext) -> GlobalResult<()> { +async fn worker(ctx: &OperationContext) -> GlobalResult<()> { let game_id = internal_unwrap!(ctx.game_id).as_uuid(); let game_res = op!([ctx] game_get { diff --git a/svc/pkg/user-follow/ops/count/Cargo.toml b/svc/pkg/user-follow/ops/count/Cargo.toml index 42a26dd34a..b2ef3ca729 100644 --- a/svc/pkg/user-follow/ops/count/Cargo.toml +++ b/svc/pkg/user-follow/ops/count/Cargo.toml @@ -11,7 +11,7 @@ chirp-client = { path = "../../../../../lib/chirp/client" } prost = "0.10" [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/user-follow/ops/count/Service.toml b/svc/pkg/user-follow/ops/count/Service.toml index 031cc3c584..d86c0f2710 100644 --- a/svc/pkg/user-follow/ops/count/Service.toml +++ b/svc/pkg/user-follow/ops/count/Service.toml @@ -5,3 +5,6 @@ name = "user-follow-count" kind = "rust" [operation] + +[databases] +db-user-follow = {} diff --git a/svc/pkg/user-follow/ops/get/Cargo.toml b/svc/pkg/user-follow/ops/get/Cargo.toml index 487c68db13..9c7bae4970 100644 --- a/svc/pkg/user-follow/ops/get/Cargo.toml +++ b/svc/pkg/user-follow/ops/get/Cargo.toml @@ -11,7 +11,7 @@ chirp-client = { path = "../../../../../lib/chirp/client" } prost = "0.10" [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/user-follow/ops/get/Service.toml b/svc/pkg/user-follow/ops/get/Service.toml index e87534d233..1722a17e44 100644 --- a/svc/pkg/user-follow/ops/get/Service.toml +++ b/svc/pkg/user-follow/ops/get/Service.toml @@ -5,3 +5,6 @@ name = "user-follow-get" kind = "rust" [operation] + +[databases] +db-user-follow = {} diff --git a/svc/pkg/user-follow/ops/list/Cargo.toml b/svc/pkg/user-follow/ops/list/Cargo.toml index 3db4d51f8f..42fa219363 100644 --- a/svc/pkg/user-follow/ops/list/Cargo.toml +++ b/svc/pkg/user-follow/ops/list/Cargo.toml @@ -11,7 +11,7 @@ chirp-client = { path = "../../../../../lib/chirp/client" } prost = "0.10" [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/user-follow/ops/list/Service.toml b/svc/pkg/user-follow/ops/list/Service.toml index 973908acdd..6baaaa6c9d 100644 --- a/svc/pkg/user-follow/ops/list/Service.toml +++ b/svc/pkg/user-follow/ops/list/Service.toml @@ -5,3 +5,6 @@ name = "user-follow-list" kind = "rust" [operation] + +[databases] +db-user-follow = {} diff --git a/svc/pkg/user-follow/ops/relationship-get/Cargo.toml b/svc/pkg/user-follow/ops/relationship-get/Cargo.toml index f448945b02..d2b31b5986 100644 --- a/svc/pkg/user-follow/ops/relationship-get/Cargo.toml +++ b/svc/pkg/user-follow/ops/relationship-get/Cargo.toml @@ -11,7 +11,7 @@ chirp-client = { path = "../../../../../lib/chirp/client" } prost = "0.10" [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/user-follow/ops/relationship-get/Service.toml b/svc/pkg/user-follow/ops/relationship-get/Service.toml index ac4946675c..6e6e4f97de 100644 --- a/svc/pkg/user-follow/ops/relationship-get/Service.toml +++ b/svc/pkg/user-follow/ops/relationship-get/Service.toml @@ -5,3 +5,6 @@ name = "user-follow-relationship-get" kind = "rust" [operation] + +[databases] +db-user-follow = {} diff --git a/svc/pkg/user-follow/ops/request-list/Cargo.toml b/svc/pkg/user-follow/ops/request-list/Cargo.toml index 3258dc328f..5a4d372972 100644 --- a/svc/pkg/user-follow/ops/request-list/Cargo.toml +++ b/svc/pkg/user-follow/ops/request-list/Cargo.toml @@ -11,7 +11,7 @@ chirp-client = { path = "../../../../../lib/chirp/client" } prost = "0.10" [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/user-follow/ops/request-list/Service.toml b/svc/pkg/user-follow/ops/request-list/Service.toml index a09545ac34..6b65c08630 100644 --- a/svc/pkg/user-follow/ops/request-list/Service.toml +++ b/svc/pkg/user-follow/ops/request-list/Service.toml @@ -5,3 +5,6 @@ name = "user-follow-request-list" kind = "rust" [operation] + +[databases] +db-user-follow = {} diff --git a/svc/pkg/user-follow/ops/toggle/Cargo.toml b/svc/pkg/user-follow/ops/toggle/Cargo.toml index 3049ed814d..a82e08aab0 100644 --- a/svc/pkg/user-follow/ops/toggle/Cargo.toml +++ b/svc/pkg/user-follow/ops/toggle/Cargo.toml @@ -11,7 +11,7 @@ chirp-client = { path = "../../../../../lib/chirp/client" } prost = "0.10" [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/user-follow/ops/toggle/Service.toml b/svc/pkg/user-follow/ops/toggle/Service.toml index 53cdad75f9..f2549e7c51 100644 --- a/svc/pkg/user-follow/ops/toggle/Service.toml +++ b/svc/pkg/user-follow/ops/toggle/Service.toml @@ -5,3 +5,6 @@ name = "user-follow-toggle" kind = "rust" [operation] + +[databases] +db-user-follow = {} diff --git a/svc/pkg/user-follow/worker/Service.toml b/svc/pkg/user-follow/worker/Service.toml index dcbbc6bd44..bd7ab57828 100644 --- a/svc/pkg/user-follow/worker/Service.toml +++ b/svc/pkg/user-follow/worker/Service.toml @@ -5,3 +5,6 @@ name = "user-follow-worker" kind = "rust" [consumer] + +[databases] +db-user-follow = {} diff --git a/svc/pkg/user-follow/worker/src/workers/request_ignore.rs b/svc/pkg/user-follow/worker/src/workers/request_ignore.rs index 440c3c312f..491d4b62f4 100644 --- a/svc/pkg/user-follow/worker/src/workers/request_ignore.rs +++ b/svc/pkg/user-follow/worker/src/workers/request_ignore.rs @@ -3,7 +3,7 @@ use proto::backend::pkg::*; #[worker(name = "user-follow-request-ignore")] async fn worker( - ctx: OperationContext, + ctx: &OperationContext, ) -> GlobalResult<()> { let follower_user_id = internal_unwrap!(ctx.follower_user_id).as_uuid(); let following_user_id = internal_unwrap!(ctx.following_user_id).as_uuid(); diff --git a/svc/pkg/user-identity/ops/create/Service.toml b/svc/pkg/user-identity/ops/create/Service.toml index af006a33d0..3a1a11f1ff 100644 --- a/svc/pkg/user-identity/ops/create/Service.toml +++ b/svc/pkg/user-identity/ops/create/Service.toml @@ -5,3 +5,6 @@ name = "user-identity-create" kind = "rust" [operation] + +[databases] +db-user-identity = {} diff --git a/svc/pkg/user-identity/ops/create/tests/integration.rs b/svc/pkg/user-identity/ops/create/tests/integration.rs index 5b691c78c9..5609d5c0d5 100644 --- a/svc/pkg/user-identity/ops/create/tests/integration.rs +++ b/svc/pkg/user-identity/ops/create/tests/integration.rs @@ -15,7 +15,7 @@ async fn empty(ctx: TestCtx) { identity: Some(backend::user_identity::Identity { kind: Some(backend::user_identity::identity::Kind::Email( backend::user_identity::identity::Email { - email: email.clone() + email: email.clone(), } )), }), diff --git a/svc/pkg/user-identity/ops/delete/Cargo.toml b/svc/pkg/user-identity/ops/delete/Cargo.toml index 45efce3532..2abbb93fce 100644 --- a/svc/pkg/user-identity/ops/delete/Cargo.toml +++ b/svc/pkg/user-identity/ops/delete/Cargo.toml @@ -11,7 +11,7 @@ chirp-client = { path = "../../../../../lib/chirp/client" } prost = "0.10" [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/user-identity/ops/delete/Service.toml b/svc/pkg/user-identity/ops/delete/Service.toml index 340ec3bc32..ddb7a7c86d 100644 --- a/svc/pkg/user-identity/ops/delete/Service.toml +++ b/svc/pkg/user-identity/ops/delete/Service.toml @@ -5,3 +5,6 @@ name = "user-identity-delete" kind = "rust" [operation] + +[databases] +db-user-identity = {} diff --git a/svc/pkg/user-identity/ops/get/Cargo.toml b/svc/pkg/user-identity/ops/get/Cargo.toml index e131f3d9ce..70eb42b195 100644 --- a/svc/pkg/user-identity/ops/get/Cargo.toml +++ b/svc/pkg/user-identity/ops/get/Cargo.toml @@ -11,7 +11,7 @@ chirp-client = { path = "../../../../../lib/chirp/client" } prost = "0.10" [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/user-identity/ops/get/Service.toml b/svc/pkg/user-identity/ops/get/Service.toml index bd5d3209be..901c4d105e 100644 --- a/svc/pkg/user-identity/ops/get/Service.toml +++ b/svc/pkg/user-identity/ops/get/Service.toml @@ -5,3 +5,6 @@ name = "user-identity-get" kind = "rust" [operation] + +[databases] +db-user-identity = {} diff --git a/svc/pkg/user-notification-auth/ops/register/Cargo.toml b/svc/pkg/user-notification-auth/ops/register/Cargo.toml index a2ca68ddcf..1274b0313f 100644 --- a/svc/pkg/user-notification-auth/ops/register/Cargo.toml +++ b/svc/pkg/user-notification-auth/ops/register/Cargo.toml @@ -11,7 +11,7 @@ chirp-client = { path = "../../../../../lib/chirp/client" } prost = "0.10" [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/user-notification-auth/ops/register/Service.toml b/svc/pkg/user-notification-auth/ops/register/Service.toml index 5124cec173..e3ea6bd296 100644 --- a/svc/pkg/user-notification-auth/ops/register/Service.toml +++ b/svc/pkg/user-notification-auth/ops/register/Service.toml @@ -5,3 +5,6 @@ name = "user-notification-auth-register" kind = "rust" [operation] + +[databases] +db-user-notification-auth = {} diff --git a/svc/pkg/user-notification-auth/ops/unregister/Cargo.toml b/svc/pkg/user-notification-auth/ops/unregister/Cargo.toml index 856e25f424..8565a4b192 100644 --- a/svc/pkg/user-notification-auth/ops/unregister/Cargo.toml +++ b/svc/pkg/user-notification-auth/ops/unregister/Cargo.toml @@ -11,7 +11,7 @@ chirp-client = { path = "../../../../../lib/chirp/client" } prost = "0.10" [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/user-notification-auth/ops/unregister/Service.toml b/svc/pkg/user-notification-auth/ops/unregister/Service.toml index 16e331ea07..acdaaf6715 100644 --- a/svc/pkg/user-notification-auth/ops/unregister/Service.toml +++ b/svc/pkg/user-notification-auth/ops/unregister/Service.toml @@ -5,3 +5,6 @@ name = "user-notification-auth-unregister" kind = "rust" [operation] + +[databases] +db-user-notification-auth = {} diff --git a/svc/pkg/user-presence/db/redis-user-presence/Service.toml b/svc/pkg/user-presence/db/redis-user-presence/Service.toml index 9e1c930cb5..b8039e7266 100644 --- a/svc/pkg/user-presence/db/redis-user-presence/Service.toml +++ b/svc/pkg/user-presence/db/redis-user-presence/Service.toml @@ -3,7 +3,7 @@ name = "redis-user-presence" [runtime] kind = "redis" -index = 6 +index = 5 persistent = true [cache] diff --git a/svc/pkg/user-presence/ops/get/Service.toml b/svc/pkg/user-presence/ops/get/Service.toml index be03395475..90c81dbbfa 100644 --- a/svc/pkg/user-presence/ops/get/Service.toml +++ b/svc/pkg/user-presence/ops/get/Service.toml @@ -5,3 +5,6 @@ name = "user-presence-get" kind = "rust" [operation] + +[databases] +redis-user-presence = {} diff --git a/svc/pkg/user-presence/ops/touch/Service.toml b/svc/pkg/user-presence/ops/touch/Service.toml index fccc3468fd..9a86576f6b 100644 --- a/svc/pkg/user-presence/ops/touch/Service.toml +++ b/svc/pkg/user-presence/ops/touch/Service.toml @@ -5,3 +5,6 @@ name = "user-presence-touch" kind = "rust" [operation] + +[databases] +redis-user-presence = {} diff --git a/svc/pkg/user-presence/standalone/gc/Cargo.toml b/svc/pkg/user-presence/standalone/gc/Cargo.toml index 9454a09c61..30d7747f6c 100644 --- a/svc/pkg/user-presence/standalone/gc/Cargo.toml +++ b/svc/pkg/user-presence/standalone/gc/Cargo.toml @@ -17,7 +17,7 @@ rivet-metrics = { path = "../../../../../lib/metrics" } rivet-operation = { path = "../../../../../lib/operation/core" } rivet-pools = { path = "../../../../../lib/pools" } rivet-runtime = { path = "../../../../../lib/runtime" } -tokio = { version = "1.21", features = ["full"] } +tokio = { version = "1.29", features = ["full"] } tracing = "0.1" tracing-subscriber = { version = "0.3", default-features = false, features = ["fmt", "json", "ansi"] } util-user-presence = { package = "rivet-util-user-presence", path = "../../util" } diff --git a/svc/pkg/user-presence/standalone/gc/Service.toml b/svc/pkg/user-presence/standalone/gc/Service.toml index 62b3b302ad..5aca003427 100644 --- a/svc/pkg/user-presence/standalone/gc/Service.toml +++ b/svc/pkg/user-presence/standalone/gc/Service.toml @@ -8,3 +8,5 @@ kind = "rust" [headless] singleton = true +[databases] +redis-user-presence = {} diff --git a/svc/pkg/user-presence/worker/Cargo.toml b/svc/pkg/user-presence/worker/Cargo.toml index 0b08a6374f..ec920fa6d3 100644 --- a/svc/pkg/user-presence/worker/Cargo.toml +++ b/svc/pkg/user-presence/worker/Cargo.toml @@ -14,7 +14,7 @@ rivet-runtime = { path = "../../../../lib/runtime" } util-user-presence = { package = "rivet-util-user-presence", path = "../util" } [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/user-presence/worker/Service.toml b/svc/pkg/user-presence/worker/Service.toml index 24e0919ebf..99820feecd 100644 --- a/svc/pkg/user-presence/worker/Service.toml +++ b/svc/pkg/user-presence/worker/Service.toml @@ -6,3 +6,6 @@ kind = "rust" [consumer] +[databases] +db-user-presence = {} +redis-user-presence = {} diff --git a/svc/pkg/user-presence/worker/src/workers/arrive.rs b/svc/pkg/user-presence/worker/src/workers/arrive.rs index bbf18e54fd..e6ff4c76c3 100644 --- a/svc/pkg/user-presence/worker/src/workers/arrive.rs +++ b/svc/pkg/user-presence/worker/src/workers/arrive.rs @@ -4,7 +4,7 @@ use proto::backend::{self, pkg::*}; const DEFAULT_USER_SET_STATUS: i32 = backend::user::Status::Online as i32; #[worker(name = "user-presence-arrive")] -async fn worker(ctx: OperationContext) -> GlobalResult<()> { +async fn worker(ctx: &OperationContext) -> GlobalResult<()> { let crdb = ctx.crdb("db-user-presence").await?; let user_id = internal_unwrap!(ctx.user_id).as_uuid(); diff --git a/svc/pkg/user-presence/worker/src/workers/game_activity_set.rs b/svc/pkg/user-presence/worker/src/workers/game_activity_set.rs index f659849a48..01586c4184 100644 --- a/svc/pkg/user-presence/worker/src/workers/game_activity_set.rs +++ b/svc/pkg/user-presence/worker/src/workers/game_activity_set.rs @@ -4,7 +4,7 @@ use redis::AsyncCommands; #[worker(name = "user-presence-game-activity-set")] async fn worker( - ctx: OperationContext, + ctx: &OperationContext, ) -> GlobalResult<()> { let mut redis = ctx.redis_user_presence().await?; diff --git a/svc/pkg/user-presence/worker/src/workers/leave.rs b/svc/pkg/user-presence/worker/src/workers/leave.rs index b3605f48a2..cf92295f7d 100644 --- a/svc/pkg/user-presence/worker/src/workers/leave.rs +++ b/svc/pkg/user-presence/worker/src/workers/leave.rs @@ -5,20 +5,22 @@ use redis::AsyncCommands; const DEFAULT_USER_SET_STATUS: i32 = backend::user::Status::Online as i32; #[worker(name = "user-presence-leave")] -async fn worker(ctx: OperationContext) -> GlobalResult<()> { +async fn worker(ctx: &OperationContext) -> GlobalResult<()> { let crdb = ctx.crdb("db-user-presence").await?; let mut redis = ctx.redis_user_presence().await?; let user_id = internal_unwrap!(ctx.user_id).as_uuid(); - let user_set_status = - sqlx::query_as::<_, (Option,)>("SELECT user_set_status FROM user_presences") - .fetch_optional(&crdb) - .await? - .and_then(|x| x.0) - .map(|x| x as i32) - .unwrap_or(DEFAULT_USER_SET_STATUS); + let user_set_status = sqlx::query_as::<_, (Option,)>( + "SELECT user_set_status FROM user_presences WHERE user_id = $1", + ) + .bind(user_id) + .fetch_optional(&crdb) + .await? + .and_then(|x| x.0) + .map(|x| x as i32) + .unwrap_or(DEFAULT_USER_SET_STATUS); // Remove the user from Redis. // diff --git a/svc/pkg/user-presence/worker/src/workers/status_set.rs b/svc/pkg/user-presence/worker/src/workers/status_set.rs index 1eb6ab0e0c..1640a9c3c7 100644 --- a/svc/pkg/user-presence/worker/src/workers/status_set.rs +++ b/svc/pkg/user-presence/worker/src/workers/status_set.rs @@ -10,7 +10,7 @@ enum Error { #[worker(name = "user-presence-status-set")] async fn worker( - ctx: OperationContext, + ctx: &OperationContext, ) -> GlobalResult<()> { let crdb = ctx.crdb("db-user-presence").await?; diff --git a/svc/pkg/user-report/worker/Service.toml b/svc/pkg/user-report/worker/Service.toml index ab383cae71..3138023bc6 100644 --- a/svc/pkg/user-report/worker/Service.toml +++ b/svc/pkg/user-report/worker/Service.toml @@ -5,3 +5,6 @@ name = "user-report-worker" kind = "rust" [consumer] + +[databases] +db-user-report = {} diff --git a/svc/pkg/user-report/worker/src/workers/create.rs b/svc/pkg/user-report/worker/src/workers/create.rs index c0d9f5c6ca..9a87320c01 100644 --- a/svc/pkg/user-report/worker/src/workers/create.rs +++ b/svc/pkg/user-report/worker/src/workers/create.rs @@ -2,7 +2,7 @@ use chirp_worker::prelude::*; use proto::backend::pkg::*; #[worker(name = "user-report-create")] -async fn worker(ctx: OperationContext) -> GlobalResult<()> { +async fn worker(ctx: &OperationContext) -> GlobalResult<()> { let reporter_user_id = internal_unwrap!(ctx.reporter_user_id).as_uuid(); let subject_user_id = internal_unwrap!(ctx.subject_user_id).as_uuid(); let namespace_id = ctx.subject_user_id.as_ref().map(common::Uuid::as_uuid); diff --git a/svc/pkg/user/db/user/migrations/20230515194135_search.up.sql b/svc/pkg/user/db/user/migrations/20230515194135_search.up.sql index 2464a763f8..d7e05c69b5 100644 --- a/svc/pkg/user/db/user/migrations/20230515194135_search.up.sql +++ b/svc/pkg/user/db/user/migrations/20230515194135_search.up.sql @@ -1,3 +1,3 @@ ALTER TABLE users - ADD COLUMN is_searchable BOOLEAN NOT NULL DEFAULT TRUE, + ADD COLUMN is_searchable BOOLEAN NOT NULL DEFAULT FALSE, DROP COLUMN display_name_len; diff --git a/svc/pkg/user/ops/avatar-upload-complete/Cargo.toml b/svc/pkg/user/ops/avatar-upload-complete/Cargo.toml index 6273ec563d..89d7ec0201 100644 --- a/svc/pkg/user/ops/avatar-upload-complete/Cargo.toml +++ b/svc/pkg/user/ops/avatar-upload-complete/Cargo.toml @@ -13,7 +13,7 @@ prost = "0.10" upload-complete = { path = "../../../upload/ops/complete" } [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/user/ops/avatar-upload-complete/Service.toml b/svc/pkg/user/ops/avatar-upload-complete/Service.toml index d2c98c8a23..6da5ff0fae 100644 --- a/svc/pkg/user/ops/avatar-upload-complete/Service.toml +++ b/svc/pkg/user/ops/avatar-upload-complete/Service.toml @@ -5,3 +5,6 @@ name = "user-avatar-upload-complete" kind = "rust" [operation] + +[databases] +db-user = {} diff --git a/svc/pkg/user/ops/get/Cargo.toml b/svc/pkg/user/ops/get/Cargo.toml index 263fe0a09e..b5c9e0fad0 100644 --- a/svc/pkg/user/ops/get/Cargo.toml +++ b/svc/pkg/user/ops/get/Cargo.toml @@ -14,7 +14,7 @@ upload-file-list = { path = "../../../upload/ops/file-list" } upload-get = { path = "../../../upload/ops/get" } [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/user/ops/get/Service.toml b/svc/pkg/user/ops/get/Service.toml index 9981bb2ccf..bfe731d0cb 100644 --- a/svc/pkg/user/ops/get/Service.toml +++ b/svc/pkg/user/ops/get/Service.toml @@ -5,3 +5,6 @@ name = "user-get" kind = "rust" [operation] + +[databases] +db-user = {} diff --git a/svc/pkg/user/ops/get/src/lib.rs b/svc/pkg/user/ops/get/src/lib.rs index a7b63c829b..6f2cfef96a 100644 --- a/svc/pkg/user/ops/get/src/lib.rs +++ b/svc/pkg/user/ops/get/src/lib.rs @@ -51,15 +51,14 @@ pub async fn handle( .filter_map(|user| user.profile_id.map(Into::into)) .collect::>(); - let upload_res = op!([ctx] upload_get { - upload_ids: upload_ids.clone(), - }) - .await?; - - let files_res = op!([ctx] upload_file_list { - upload_ids: upload_ids.clone(), - }) - .await?; + let (upload_res, files_res) = tokio::try_join!( + op!([ctx] upload_get { + upload_ids: upload_ids.clone(), + }), + op!([ctx] upload_file_list { + upload_ids: upload_ids.clone(), + }) + )?; Ok(user::get::Response { users: users @@ -68,7 +67,7 @@ pub async fn handle( let profile_id = user.profile_id.map(Into::::into); // Fetch all information relating to the profile image - let (profile_upload_complete_ts, profile_file_name) = { + let (profile_upload_complete_ts, profile_file_name, profile_provider) = { let upload = upload_res .uploads .iter() @@ -84,7 +83,7 @@ pub async fn handle( .rsplit_once('/') .map(|(_, file_name)| file_name.to_owned()) .or(Some(file.path.clone())); - (upload.complete_ts, profile_file_name) + (upload.complete_ts, profile_file_name, Some(upload.provider)) } else { Default::default() } @@ -101,6 +100,7 @@ pub async fn handle( None }, profile_file_name, + profile_provider, join_ts: user.join_ts, bio: user.bio, is_admin: user.is_admin, diff --git a/svc/pkg/user/ops/mutual-friend-list/Cargo.toml b/svc/pkg/user/ops/mutual-friend-list/Cargo.toml index 07ace882f0..e3db3ec8b3 100644 --- a/svc/pkg/user/ops/mutual-friend-list/Cargo.toml +++ b/svc/pkg/user/ops/mutual-friend-list/Cargo.toml @@ -11,7 +11,7 @@ chirp-client = { path = "../../../../../lib/chirp/client" } prost = "0.10" [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/user/ops/mutual-friend-list/Service.toml b/svc/pkg/user/ops/mutual-friend-list/Service.toml index e04cbd820f..2e52aca966 100644 --- a/svc/pkg/user/ops/mutual-friend-list/Service.toml +++ b/svc/pkg/user/ops/mutual-friend-list/Service.toml @@ -5,3 +5,6 @@ name = "user-mutual-friend-list" kind = "rust" [operation] + +[databases] +db-user-follow = {} diff --git a/svc/pkg/user/ops/pending-delete-toggle/Cargo.toml b/svc/pkg/user/ops/pending-delete-toggle/Cargo.toml index 1b3c73b317..451299d5bb 100644 --- a/svc/pkg/user/ops/pending-delete-toggle/Cargo.toml +++ b/svc/pkg/user/ops/pending-delete-toggle/Cargo.toml @@ -13,7 +13,7 @@ prost = "0.10" user-identity-get = { path = "../../../user-identity/ops/get" } [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/user/ops/pending-delete-toggle/Service.toml b/svc/pkg/user/ops/pending-delete-toggle/Service.toml index 34262dfa35..089747badb 100644 --- a/svc/pkg/user/ops/pending-delete-toggle/Service.toml +++ b/svc/pkg/user/ops/pending-delete-toggle/Service.toml @@ -5,3 +5,6 @@ name = "user-pending-delete-toggle" kind = "rust" [operation] + +[databases] +db-user = {} diff --git a/svc/pkg/user/ops/profile-validate/Cargo.toml b/svc/pkg/user/ops/profile-validate/Cargo.toml index 7ae1fa55cd..9420a0015c 100644 --- a/svc/pkg/user/ops/profile-validate/Cargo.toml +++ b/svc/pkg/user/ops/profile-validate/Cargo.toml @@ -14,7 +14,7 @@ user-get = { path = "../get" } profanity-check = { path = "../../../profanity/ops/check" } [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/user/ops/profile-validate/Service.toml b/svc/pkg/user/ops/profile-validate/Service.toml index c1bd529344..28f95fa87f 100644 --- a/svc/pkg/user/ops/profile-validate/Service.toml +++ b/svc/pkg/user/ops/profile-validate/Service.toml @@ -5,3 +5,6 @@ name = "user-profile-validate" kind = "rust" [operation] + +[databases] +db-user = {} diff --git a/svc/pkg/user/ops/resolve-email/Cargo.toml b/svc/pkg/user/ops/resolve-email/Cargo.toml index ebef26efc1..f53b73a2f9 100644 --- a/svc/pkg/user/ops/resolve-email/Cargo.toml +++ b/svc/pkg/user/ops/resolve-email/Cargo.toml @@ -11,7 +11,7 @@ chirp-client = { path = "../../../../../lib/chirp/client" } prost = "0.10" [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/user/ops/resolve-email/Service.toml b/svc/pkg/user/ops/resolve-email/Service.toml index 1b35e33c06..9b5f4af767 100644 --- a/svc/pkg/user/ops/resolve-email/Service.toml +++ b/svc/pkg/user/ops/resolve-email/Service.toml @@ -5,3 +5,6 @@ name = "user-resolve-email" kind = "rust" [operation] + +[databases] +db-user-identity = {} diff --git a/svc/pkg/user/ops/search/Cargo.toml b/svc/pkg/user/ops/search/Cargo.toml index 7cdbd738a9..4b8f193d6a 100644 --- a/svc/pkg/user/ops/search/Cargo.toml +++ b/svc/pkg/user/ops/search/Cargo.toml @@ -13,7 +13,7 @@ prost = "0.10" regex = "1.4" [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/user/ops/team-list/Cargo.toml b/svc/pkg/user/ops/team-list/Cargo.toml index c26c74e4e0..23eb6cf9b6 100644 --- a/svc/pkg/user/ops/team-list/Cargo.toml +++ b/svc/pkg/user/ops/team-list/Cargo.toml @@ -11,7 +11,7 @@ chirp-client = { path = "../../../../../lib/chirp/client" } prost = "0.10" [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/user/ops/team-list/Service.toml b/svc/pkg/user/ops/team-list/Service.toml index 7610cc40fd..2c0b0a870a 100644 --- a/svc/pkg/user/ops/team-list/Service.toml +++ b/svc/pkg/user/ops/team-list/Service.toml @@ -5,3 +5,6 @@ name = "user-team-list" kind = "rust" [operation] + +[databases] +db-team = {} diff --git a/svc/pkg/user/ops/thread-typing-status-set/Cargo.toml b/svc/pkg/user/ops/thread-typing-status-set/Cargo.toml index 213e1555da..e852a2870c 100644 --- a/svc/pkg/user/ops/thread-typing-status-set/Cargo.toml +++ b/svc/pkg/user/ops/thread-typing-status-set/Cargo.toml @@ -13,7 +13,7 @@ prost = "0.10" util-chat = { package = "rivet-util-chat", path = "../../../chat/util" } [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/user/ops/token-create/Cargo.toml b/svc/pkg/user/ops/token-create/Cargo.toml index fb99538b82..9489b5c4d2 100644 --- a/svc/pkg/user/ops/token-create/Cargo.toml +++ b/svc/pkg/user/ops/token-create/Cargo.toml @@ -13,7 +13,7 @@ prost = "0.10" token-create = { path = "../../../token/ops/create" } [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false [dev-dependencies] diff --git a/svc/pkg/user/ops/token-create/Service.toml b/svc/pkg/user/ops/token-create/Service.toml index 4d5ca7d8f6..664ba57d29 100644 --- a/svc/pkg/user/ops/token-create/Service.toml +++ b/svc/pkg/user/ops/token-create/Service.toml @@ -5,3 +5,6 @@ name = "user-token-create" kind = "rust" [operation] + +[databases] +db-user = {} diff --git a/svc/pkg/user/standalone/delete-pending/Cargo.toml b/svc/pkg/user/standalone/delete-pending/Cargo.toml index 23bd8a7c8f..57486342fa 100644 --- a/svc/pkg/user/standalone/delete-pending/Cargo.toml +++ b/svc/pkg/user/standalone/delete-pending/Cargo.toml @@ -15,7 +15,7 @@ prost = "0.10" rivet-connection = { path = "../../../../../lib/connection" } rivet-pools = { path = "../../../../../lib/pools" } rivet-runtime = { path = "../../../../../lib/runtime" } -tokio = { version = "1.21", features = ["full"] } +tokio = { version = "1.29", features = ["full"] } tracing = "0.1" tracing-subscriber = { version = "0.3", default-features = false, features = ["fmt", "json", "ansi"] } diff --git a/svc/pkg/user/standalone/delete-pending/Service.toml b/svc/pkg/user/standalone/delete-pending/Service.toml index 0c4ce5f9ff..33a93a84d6 100644 --- a/svc/pkg/user/standalone/delete-pending/Service.toml +++ b/svc/pkg/user/standalone/delete-pending/Service.toml @@ -8,3 +8,5 @@ kind = "rust" [periodic] cron = "0 0 * * *" +[databases] +db-user = {} diff --git a/svc/pkg/user/standalone/search-user-gc/Cargo.toml b/svc/pkg/user/standalone/search-user-gc/Cargo.toml index 0a9253f34f..8ca7fd9dc8 100644 --- a/svc/pkg/user/standalone/search-user-gc/Cargo.toml +++ b/svc/pkg/user/standalone/search-user-gc/Cargo.toml @@ -14,7 +14,7 @@ indoc = "1.0" prost = "0.10" rivet-connection = { path = "../../../../../lib/connection" } rivet-runtime = { path = "../../../../../lib/runtime" } -tokio = { version = "1.21", features = ["full"] } +tokio = { version = "1.29", features = ["full"] } tracing = "0.1" tracing-subscriber = { version = "0.3", default-features = false, features = ["fmt", "json", "ansi"] } diff --git a/svc/pkg/user/standalone/search-user-gc/Service.toml b/svc/pkg/user/standalone/search-user-gc/Service.toml index 8548ff6bcc..4ea9ba699e 100644 --- a/svc/pkg/user/standalone/search-user-gc/Service.toml +++ b/svc/pkg/user/standalone/search-user-gc/Service.toml @@ -8,3 +8,5 @@ kind = "rust" [periodic] cron = "0 0 * * *" +[databases] +db-user = {} diff --git a/svc/pkg/user/worker/Service.toml b/svc/pkg/user/worker/Service.toml index aca5302ce9..7c6117ae19 100644 --- a/svc/pkg/user/worker/Service.toml +++ b/svc/pkg/user/worker/Service.toml @@ -6,3 +6,5 @@ kind = "rust" [consumer] +[databases] +db-user = {} diff --git a/svc/pkg/user/worker/adjectives.txt b/svc/pkg/user/worker/adjectives.txt index e86b5c3b9d..31d2b9b2dd 100644 --- a/svc/pkg/user/worker/adjectives.txt +++ b/svc/pkg/user/worker/adjectives.txt @@ -335,7 +335,6 @@ Plastic Plucky Poised Polite -Poor Premium Present Prickly diff --git a/svc/pkg/user/worker/src/workers/create.rs b/svc/pkg/user/worker/src/workers/create.rs index 2aef91217e..39e09d9db9 100644 --- a/svc/pkg/user/worker/src/workers/create.rs +++ b/svc/pkg/user/worker/src/workers/create.rs @@ -14,7 +14,7 @@ lazy_static! { } #[worker(name = "user-create")] -async fn worker(ctx: OperationContext) -> GlobalResult<()> { +async fn worker(ctx: &OperationContext) -> GlobalResult<()> { let user_id = internal_unwrap!(ctx.user_id).as_uuid(); let join_ts = ctx.ts(); diff --git a/svc/pkg/user/worker/src/workers/delete.rs b/svc/pkg/user/worker/src/workers/delete.rs index 5439d3dd90..b8bb869583 100644 --- a/svc/pkg/user/worker/src/workers/delete.rs +++ b/svc/pkg/user/worker/src/workers/delete.rs @@ -8,7 +8,7 @@ const MESSAGE_BATCH_SIZE: usize = 256; const UPLOAD_BATCH_SIZE: usize = 256; #[worker(name = "user-delete")] -async fn worker(ctx: OperationContext) -> GlobalResult<()> { +async fn worker(ctx: &OperationContext) -> GlobalResult<()> { let user_id = internal_unwrap!(ctx.user_id).as_uuid(); let crdb = ctx.crdb("db-user").await?; diff --git a/svc/pkg/user/worker/src/workers/event_chat_last_read_ts_update.rs b/svc/pkg/user/worker/src/workers/event_chat_last_read_ts_update.rs index 90ab71fa08..5633e0a69c 100644 --- a/svc/pkg/user/worker/src/workers/event_chat_last_read_ts_update.rs +++ b/svc/pkg/user/worker/src/workers/event_chat_last_read_ts_update.rs @@ -3,7 +3,7 @@ use proto::backend::{self, pkg::*}; #[worker(name = "user-event-chat-last-read-ts-update")] async fn worker( - ctx: OperationContext, + ctx: &OperationContext, ) -> GlobalResult<()> { let user_id = internal_unwrap!(ctx.user_id).as_uuid(); diff --git a/svc/pkg/user/worker/src/workers/event_chat_message_create_complete.rs b/svc/pkg/user/worker/src/workers/event_chat_message_create_complete.rs index 72b1e147e6..2d6ec1d8f8 100644 --- a/svc/pkg/user/worker/src/workers/event_chat_message_create_complete.rs +++ b/svc/pkg/user/worker/src/workers/event_chat_message_create_complete.rs @@ -3,7 +3,7 @@ use proto::backend::{self, pkg::*}; #[worker(name = "user-event-chat-message-create-complete")] async fn worker( - ctx: OperationContext, + ctx: &OperationContext, ) -> GlobalResult<()> { for user_id in &ctx.participant_user_ids { msg!([ctx] user::msg::event(user_id) { diff --git a/svc/pkg/user/worker/src/workers/event_party_member_update.rs b/svc/pkg/user/worker/src/workers/event_party_member_update.rs new file mode 100644 index 0000000000..5a2017bd81 --- /dev/null +++ b/svc/pkg/user/worker/src/workers/event_party_member_update.rs @@ -0,0 +1,17 @@ +use chirp_worker::prelude::*; +use proto::backend::{self, pkg::*}; + +#[worker(name = "user-event-party-member-update")] +async fn worker(ctx: &OperationContext) -> GlobalResult<()> { + let user_id = internal_unwrap!(ctx.user_id).as_uuid(); + + msg!([ctx] user::msg::event(user_id) { + user_id: Some(user_id.into()), + event: Some(backend::user::event::Event { + kind: Some(backend::user::event::event::Kind::PartyUpdate(backend::user::event::PartyUpdate {})), + }), + }) + .await?; + + Ok(()) +} diff --git a/svc/pkg/user/worker/src/workers/event_party_update.rs b/svc/pkg/user/worker/src/workers/event_party_update.rs new file mode 100644 index 0000000000..7b877e3bb9 --- /dev/null +++ b/svc/pkg/user/worker/src/workers/event_party_update.rs @@ -0,0 +1,25 @@ +use chirp_worker::prelude::*; +use proto::backend::{self, pkg::*}; + +#[worker(name = "user-event-party-update")] +async fn worker(ctx: &OperationContext) -> GlobalResult<()> { + let party_id = internal_unwrap!(ctx.party_id).as_uuid(); + + let member_list = op!([ctx] party_member_list { + party_ids: vec![party_id.into()], + }) + .await?; + let party = internal_unwrap_owned!(member_list.parties.first()); + + for user_id in &party.user_ids { + msg!([ctx] user::msg::event(user_id) { + user_id: Some(*user_id), + event: Some(backend::user::event::Event { + kind: Some(backend::user::event::event::Kind::PartyUpdate(backend::user::event::PartyUpdate {})), + }), + }) + .await?; + } + + Ok(()) +} diff --git a/svc/pkg/user/worker/src/workers/event_team_member_remove.rs b/svc/pkg/user/worker/src/workers/event_team_member_remove.rs index 365b9342f2..a73acc10d8 100644 --- a/svc/pkg/user/worker/src/workers/event_team_member_remove.rs +++ b/svc/pkg/user/worker/src/workers/event_team_member_remove.rs @@ -2,7 +2,7 @@ use chirp_worker::prelude::*; use proto::backend::{self, pkg::*}; #[worker(name = "user-event-team-member-remove")] -async fn worker(ctx: OperationContext) -> GlobalResult<()> { +async fn worker(ctx: &OperationContext) -> GlobalResult<()> { let user_id = internal_unwrap!(ctx.user_id); msg!([ctx] user::msg::event(user_id) { diff --git a/svc/pkg/user/worker/src/workers/event_user_mm_lobby_join.rs b/svc/pkg/user/worker/src/workers/event_user_mm_lobby_join.rs index 3af00a00fa..bd4b3bda04 100644 --- a/svc/pkg/user/worker/src/workers/event_user_mm_lobby_join.rs +++ b/svc/pkg/user/worker/src/workers/event_user_mm_lobby_join.rs @@ -2,7 +2,7 @@ use chirp_worker::prelude::*; use proto::backend::{self, pkg::*}; #[worker(name = "user-event-user-mm-lobby-join")] -async fn worker(ctx: OperationContext) -> GlobalResult<()> { +async fn worker(ctx: &OperationContext) -> GlobalResult<()> { let user_id = internal_unwrap!(ctx.user_id).as_uuid(); msg!([ctx] user::msg::event(user_id) { diff --git a/svc/pkg/user/worker/src/workers/event_user_presence_update.rs b/svc/pkg/user/worker/src/workers/event_user_presence_update.rs index d00a48f447..ff08ab9cf4 100644 --- a/svc/pkg/user/worker/src/workers/event_user_presence_update.rs +++ b/svc/pkg/user/worker/src/workers/event_user_presence_update.rs @@ -3,7 +3,7 @@ use proto::backend::{self, pkg::*}; use rivet_convert::ApiInto; #[worker(name = "user-event-user-presence-update")] -async fn worker(ctx: OperationContext) -> GlobalResult<()> { +async fn worker(ctx: &OperationContext) -> GlobalResult<()> { let user_id = internal_unwrap!(ctx.user_id); msg!([ctx] user::msg::event(user_id) { diff --git a/svc/pkg/user/worker/src/workers/event_user_update.rs b/svc/pkg/user/worker/src/workers/event_user_update.rs index 4aeb16384b..6741631464 100644 --- a/svc/pkg/user/worker/src/workers/event_user_update.rs +++ b/svc/pkg/user/worker/src/workers/event_user_update.rs @@ -2,7 +2,7 @@ use chirp_worker::prelude::*; use proto::backend::{self, pkg::*}; #[worker(name = "user-event-user-update")] -async fn worker(ctx: OperationContext) -> GlobalResult<()> { +async fn worker(ctx: &OperationContext) -> GlobalResult<()> { let user_id = internal_unwrap!(ctx.user_id); msg!([ctx] user::msg::event(user_id) { diff --git a/svc/pkg/user/worker/src/workers/profile_set.rs b/svc/pkg/user/worker/src/workers/profile_set.rs index 6eb380c3af..a1a0fc872d 100644 --- a/svc/pkg/user/worker/src/workers/profile_set.rs +++ b/svc/pkg/user/worker/src/workers/profile_set.rs @@ -2,7 +2,7 @@ use chirp_worker::prelude::*; use proto::backend::pkg::*; #[worker(name = "user-profile-set")] -async fn worker(ctx: OperationContext) -> GlobalResult<()> { +async fn worker(ctx: &OperationContext) -> GlobalResult<()> { let body = ctx.body(); let user::msg::profile_set::Message { user_id, diff --git a/svc/pkg/user/worker/src/workers/search_update.rs b/svc/pkg/user/worker/src/workers/search_update.rs index f129982519..5118f9c421 100644 --- a/svc/pkg/user/worker/src/workers/search_update.rs +++ b/svc/pkg/user/worker/src/workers/search_update.rs @@ -2,7 +2,7 @@ use chirp_worker::prelude::*; use proto::backend::pkg::*; #[worker(name = "user-search-update")] -async fn worker(ctx: OperationContext) -> GlobalResult<()> { +async fn worker(ctx: &OperationContext) -> GlobalResult<()> { let crdb = ctx.crdb("db-user").await?; let user_id = internal_unwrap_owned!(ctx.user_id).as_uuid(); diff --git a/svc/pkg/user/worker/src/workers/search_update_user_follow_create.rs b/svc/pkg/user/worker/src/workers/search_update_user_follow_create.rs index bcbd0b7cb3..d5b3de79ab 100644 --- a/svc/pkg/user/worker/src/workers/search_update_user_follow_create.rs +++ b/svc/pkg/user/worker/src/workers/search_update_user_follow_create.rs @@ -2,7 +2,7 @@ use chirp_worker::prelude::*; use proto::backend::pkg::*; #[worker(name = "user-search-update-user-follow-create")] -async fn worker(ctx: OperationContext) -> GlobalResult<()> { +async fn worker(ctx: &OperationContext) -> GlobalResult<()> { let user_id = internal_unwrap_owned!(ctx.following_user_id).as_uuid(); msg!([ctx] user::msg::search_update(user_id) { diff --git a/svc/pkg/user/worker/src/workers/search_update_user_update.rs b/svc/pkg/user/worker/src/workers/search_update_user_update.rs index dc3552a0f4..77f45fef87 100644 --- a/svc/pkg/user/worker/src/workers/search_update_user_update.rs +++ b/svc/pkg/user/worker/src/workers/search_update_user_update.rs @@ -2,7 +2,7 @@ use chirp_worker::prelude::*; use proto::backend::pkg::*; #[worker(name = "user-search-update-user-update")] -async fn worker(ctx: OperationContext) -> GlobalResult<()> { +async fn worker(ctx: &OperationContext) -> GlobalResult<()> { let user_id = internal_unwrap_owned!(ctx.user_id); msg!([ctx] user::msg::search_update(user_id) { diff --git a/svc/pkg/user/worker/src/workers/updated_party_update.rs b/svc/pkg/user/worker/src/workers/updated_party_update.rs new file mode 100644 index 0000000000..9d2eaa43ce --- /dev/null +++ b/svc/pkg/user/worker/src/workers/updated_party_update.rs @@ -0,0 +1,25 @@ +use chirp_worker::prelude::*; +use proto::backend::{self, pkg::*}; + +#[worker(name = "user-updated-party-update")] +async fn worker(ctx: &OperationContext) -> GlobalResult<()> { + let party_id = internal_unwrap!(ctx.party_id); + + let member_list = op!([ctx] party_member_list { + party_ids: vec![*party_id], + }) + .await?; + let party = internal_unwrap_owned!(member_list.parties.first()); + + for user_id in &party.user_ids { + msg!([ctx] user::msg::updated(user_id) { + user_id: Some(*user_id), + update: Some(backend::user::update::Update { + kind: Some(backend::user::update::update::Kind::PartyUpdate(backend::user::update::PartyUpdate {})), + }), + }) + .await?; + } + + Ok(()) +} diff --git a/svc/pkg/user/worker/src/workers/updated_user_follow_create.rs b/svc/pkg/user/worker/src/workers/updated_user_follow_create.rs index 8cf04d09d2..2a9171463f 100644 --- a/svc/pkg/user/worker/src/workers/updated_user_follow_create.rs +++ b/svc/pkg/user/worker/src/workers/updated_user_follow_create.rs @@ -2,7 +2,7 @@ use chirp_worker::prelude::*; use proto::backend::{self, pkg::*}; #[worker(name = "user-updated-user-follow-create")] -async fn worker(ctx: OperationContext) -> GlobalResult<()> { +async fn worker(ctx: &OperationContext) -> GlobalResult<()> { let follower_user_id = internal_unwrap!(ctx.follower_user_id); let following_user_id = internal_unwrap!(ctx.following_user_id); diff --git a/svc/pkg/user/worker/src/workers/updated_user_follow_delete.rs b/svc/pkg/user/worker/src/workers/updated_user_follow_delete.rs index cbee28c855..7756f3dc99 100644 --- a/svc/pkg/user/worker/src/workers/updated_user_follow_delete.rs +++ b/svc/pkg/user/worker/src/workers/updated_user_follow_delete.rs @@ -2,7 +2,7 @@ use chirp_worker::prelude::*; use proto::backend::{self, pkg::*}; #[worker(name = "user-updated-user-follow-delete")] -async fn worker(ctx: OperationContext) -> GlobalResult<()> { +async fn worker(ctx: &OperationContext) -> GlobalResult<()> { let follower_user_id = internal_unwrap!(ctx.follower_user_id); let following_user_id = internal_unwrap!(ctx.following_user_id); diff --git a/svc/pkg/user/worker/src/workers/updated_user_presence_update.rs b/svc/pkg/user/worker/src/workers/updated_user_presence_update.rs index b9b4ad5864..b13ce1986a 100644 --- a/svc/pkg/user/worker/src/workers/updated_user_presence_update.rs +++ b/svc/pkg/user/worker/src/workers/updated_user_presence_update.rs @@ -3,7 +3,7 @@ use proto::backend::{self, pkg::*}; use rivet_convert::ApiInto; #[worker(name = "user-updated-user-presence-update")] -async fn worker(ctx: OperationContext) -> GlobalResult<()> { +async fn worker(ctx: &OperationContext) -> GlobalResult<()> { let user_id = internal_unwrap!(ctx.user_id); msg!([ctx] user::msg::updated(user_id) { diff --git a/svc/pkg/user/worker/src/workers/updated_user_update.rs b/svc/pkg/user/worker/src/workers/updated_user_update.rs index 0f994808b7..bd6e01251c 100644 --- a/svc/pkg/user/worker/src/workers/updated_user_update.rs +++ b/svc/pkg/user/worker/src/workers/updated_user_update.rs @@ -2,7 +2,7 @@ use chirp_worker::prelude::*; use proto::backend::{self, pkg::*}; #[worker(name = "user-updated-user-update")] -async fn worker(ctx: OperationContext) -> GlobalResult<()> { +async fn worker(ctx: &OperationContext) -> GlobalResult<()> { let user_id = internal_unwrap!(ctx.user_id); msg!([ctx] user::msg::updated(user_id) { diff --git a/svc/templates/api/Cargo.toml b/svc/templates/api/Cargo.toml index 51af8a5e8e..849d857349 100644 --- a/svc/templates/api/Cargo.toml +++ b/svc/templates/api/Cargo.toml @@ -20,7 +20,7 @@ rivet-pools = { path = "../../../lib/pools" } s3-util = { path = "../../../lib/s3-util" } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" -tokio = { version = "1.21" } +tokio = { version = "1.29" } tracing = "0.1" tracing-futures = "0.2" tracing-subscriber = { version = "0.3", default-features = false, features = ["fmt", "json", "ansi"] } diff --git a/svc/templates/operation/Cargo.toml b/svc/templates/operation/Cargo.toml index e618941319..19049267c2 100644 --- a/svc/templates/operation/Cargo.toml +++ b/svc/templates/operation/Cargo.toml @@ -10,5 +10,5 @@ chirp-client = { path = "../../../../../lib/chirp/client" } rivet-operation = { path = "../../../../../lib/operation/core" } [dependencies.sqlx] -version = "0.6" +version = "0.7" default-features = false diff --git a/svc/templates/standalone/Cargo.toml b/svc/templates/standalone/Cargo.toml index 366e87d193..a791a00db1 100644 --- a/svc/templates/standalone/Cargo.toml +++ b/svc/templates/standalone/Cargo.toml @@ -10,7 +10,7 @@ chirp-client = { path = "../../../../../lib/chirp/client" } rivet-operation = { path = "../../../../../lib/operation/core" } rivet-connection = { path = "../../../../../lib/connection" } rivet-runtime = { path = "../../../../../lib/runtime" } -tokio = { version = "1.21", features = ["full"] } +tokio = { version = "1.29", features = ["full"] } tracing = "0.1" tracing-subscriber = { version = "0.3", default-features = false, features = ["fmt", "json", "ansi"] } diff --git a/svc/templates/worker/src/workers/{{ snake name }}.rs b/svc/templates/worker/src/workers/{{ snake name }}.rs index 855fde8b73..75ac2afe16 100644 --- a/svc/templates/worker/src/workers/{{ snake name }}.rs +++ b/svc/templates/worker/src/workers/{{ snake name }}.rs @@ -2,7 +2,7 @@ use chirp_worker::prelude::*; use proto::backend::pkg::*; #[worker(name = "{{pkg}}-{{name}}")] -async fn worker(ctx: OperationContext<{{snake pkg}}::msg::{{snake name}}::Message>) -> GlobalResult<()> { +async fn worker(ctx: &OperationContext<{{snake pkg}}::msg::{{snake name}}::Message>) -> GlobalResult<()> { todo!(); Ok(())