mirror of
https://github.com/block/buzz.git
synced 2026-10-27 04:30:52 +00:00
fix(mobile-infra): render push grant lifetimes as decimal in chart 0.3.2 (#7820)
A valid 30-day push gateway grant lifetime could render in scientific notation (e.g. `2.592e+06`) in the chart, which the gateway binary does not accept. Always ormat the integer as decimal text, preserving the strict gateway parser. ### Testing Added regression coverage that feeds actual Helm-rendered environment values into the production config parser. Covers defaults, values files, command-line overrides, exact lifetime boundaries, and invalid input rejection. The default case failed before the fix and passes afterward. Signed-off-by: Tom Brow <tomb@block.xyz>
This commit is contained in:
@@ -3,6 +3,6 @@ apiVersion: v2
|
||||
# branches (see docs/push-gateway-deployment.md, "Gateway chart release").
|
||||
name: buzz-push-gateway
|
||||
description: Public capability-gated APNs last-hop gateway for Buzz
|
||||
version: 0.3.1
|
||||
version: 0.3.2
|
||||
appVersion: "0.1.0"
|
||||
type: application
|
||||
|
||||
@@ -33,7 +33,8 @@ spec:
|
||||
- { name: BUZZ_PUSH_BIND_ADDR, value: "0.0.0.0:8080" }
|
||||
- { name: BUZZ_PUSH_HEALTH_ADDR, value: "0.0.0.0:8081" }
|
||||
- { name: BUZZ_PUSH_GATEWAY_ORIGIN, value: {{ required "gatewayOrigin is required" .Values.gatewayOrigin | quote }} }
|
||||
- { name: BUZZ_PUSH_MAX_GRANT_LIFETIME_SECONDS, value: {{ .Values.maxGrantLifetimeSeconds | quote }} }
|
||||
{{/* Schema bounds this integer; normalize YAML numbers before quote can emit scientific notation. */}}
|
||||
- { name: BUZZ_PUSH_MAX_GRANT_LIFETIME_SECONDS, value: {{ .Values.maxGrantLifetimeSeconds | int64 | quote }} }
|
||||
- { name: BUZZ_PUSH_APP_ATTEST_ROOT_CERT_PATH, value: /run/buzz/app-attest/root.pem }
|
||||
- { name: BUZZ_PUSH_DOGFOOD_APP_ATTEST_APP_ID, value: {{ .Values.profiles.dogfood.appAttestAppId | quote }} }
|
||||
- { name: BUZZ_PUSH_DOGFOOD_APNS_TOPIC, value: {{ .Values.profiles.dogfood.apnsTopic | quote }} }
|
||||
|
||||
46
deploy/charts/buzz-push-gateway/tests/grant-lifetime.sh
Executable file
46
deploy/charts/buzz-push-gateway/tests/grant-lifetime.sh
Executable file
@@ -0,0 +1,46 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
fixture=$(mktemp)
|
||||
trap 'rm -f "$fixture"' EXIT
|
||||
|
||||
# Use real Helm renders, including YAML values (not just --set, which can
|
||||
# preserve a different numeric type). No deployment or real secrets are needed.
|
||||
env -u GEM_HOME -u GEM_PATH -u RUBYLIB -u RUBYOPT ruby -rjson -ryaml -ropen3 \
|
||||
- "$fixture" <<'RUBY'
|
||||
chart = 'deploy/charts/buzz-push-gateway'
|
||||
command = ['helm', 'template', 'push', chart, '--set', 'gatewayOrigin=https://push.example']
|
||||
cases = []
|
||||
render = lambda do |label, expected, args, values|
|
||||
output, error, status = Open3.capture3(*command, *args, stdin_data: values)
|
||||
raise "#{label}: Helm failed: #{error}" unless status.success?
|
||||
deployment = YAML.load_stream(output).compact.find { |x| x['kind'] == 'Deployment' }
|
||||
entries = deployment.fetch('spec').fetch('template').fetch('spec').fetch('containers')[0].fetch('env')
|
||||
# Secret references are intentionally excluded; Config's fixture supplies
|
||||
# synthetic keyrings and database configuration in memory.
|
||||
literal_env = entries.select { |entry| entry.key?('value') }.to_h do |entry|
|
||||
value = entry.fetch('value')
|
||||
raise "#{label}: #{entry['name']} is not a string" unless value.is_a?(String)
|
||||
[entry.fetch('name'), value]
|
||||
end
|
||||
raise "#{label}: lifetime missing" unless literal_env.key?('BUZZ_PUSH_MAX_GRANT_LIFETIME_SECONDS')
|
||||
cases << [label, expected, literal_env]
|
||||
end
|
||||
render.call('default', 2592000, [], '')
|
||||
[1, 2592000, 2592001, 31536000].each do |seconds|
|
||||
render.call("values #{seconds}", seconds, ['-f', '-'], "maxGrantLifetimeSeconds: #{seconds}\n")
|
||||
render.call("set #{seconds}", seconds, ['--set', "maxGrantLifetimeSeconds=#{seconds}"], '')
|
||||
end
|
||||
|
||||
# Integer conversion must never hide invalid inputs. Helm's schema remains
|
||||
# authoritative, including rejecting strings that merely look numeric.
|
||||
['0', '-1', '31536001', '2592000.5', '"2592000"', 'true'].each do |value|
|
||||
_, error, status = Open3.capture3(*command, '-f', '-', stdin_data: "maxGrantLifetimeSeconds: #{value}\n")
|
||||
unless !status.success? && error.include?('maxGrantLifetimeSeconds')
|
||||
raise "expected schema rejection for #{value}: #{error}"
|
||||
end
|
||||
end
|
||||
File.write(ARGV.fetch(0), JSON.generate(cases))
|
||||
RUBY
|
||||
|
||||
BUZZ_TEST_HELM_ENV_FILE="$fixture" cargo test -p buzz-push-gateway --lib \
|
||||
config::tests::helm_rendered_grant_lifetimes -- --ignored --exact
|
||||
@@ -1,5 +1,6 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
bash deploy/charts/buzz-push-gateway/tests/grant-lifetime.sh
|
||||
out=$(mktemp); production_out=$(mktemp); route_out=$(mktemp); datadog_out=$(mktemp)
|
||||
trap 'rm -f "$out" "$production_out" "$route_out" "$datadog_out" "${monitoring_out:-}"' EXIT
|
||||
gateway_origin_arg=(--set 'gatewayOrigin=https://push.example')
|
||||
|
||||
Reference in New Issue
Block a user