Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
64 commits
Select commit Hold shift + click to select a range
172bc47
Add kubectl helper command
geisbruch Apr 16, 2026
5704885
Add kubectl logs
geisbruch Apr 16, 2026
40a5226
Skip ALB capacity validations in scheduled_task workflows
javi-null Apr 17, 2026
55b88a8
Merge pull request #178 from nullplatform/fix/avoid-alb-validation-sc…
gdrojas Apr 20, 2026
64c146b
Add --no-params flag to skip parameter fetching for actions that don'…
bjornaer Apr 16, 2026
4edd9d7
Merge pull request #176 from nullplatform/features/kubectl_read_comma…
geisbruch Apr 22, 2026
ddfa38e
fix: support ELB hostnames for external-dns DNSEndpoint on AWS
Apr 30, 2026
fe21304
fix(deployment): create DNSEndpoint for external_dns DNS type
May 4, 2026
5953855
fix(wait_on_balancer): use DNSEndpoint observedGeneration instead of …
May 4, 2026
4b2813f
fix(manage_route): resolve ALB hostname via Ingress when gateway retu…
May 4, 2026
b30faab
refactor(manage_route): try ALB Ingress first, fall back to gateway a…
May 4, 2026
e7b783b
revert(wait_on_balancer): restore nslookup check for external_dns to …
May 4, 2026
ae40e10
fix(wait_on_balancer): fix nslookup IP parsing to skip server address…
May 4, 2026
fb8ff48
fix(dns): add dns/zone-type label to DNSEndpoints to prevent cross-zo…
May 4, 2026
6710a7d
fix(wait_on_balancer): use observedGeneration for private scopes inst…
May 4, 2026
d2a7eef
refactor(wait_on_balancer): use observedGeneration for all external_d…
May 5, 2026
83405dd
fix(dns): address PR review - remove DNS management from deployment v…
May 6, 2026
354b47c
chore(changelog): add 1.12.0 entry for external-dns DNSEndpoint support
May 8, 2026
d6c24ad
chore(changelog): condense 1.11.1 entry into single functional descri…
May 11, 2026
fa6b7ba
chore(changelog): reframe 1.11.1 entry around user benefit
May 11, 2026
90288ca
Merge pull request #182 from nullplatform/fix/dnsendpoint
sebastiancorrea81 May 11, 2026
c0df99c
feat(k8s): configurable main_http_port and HTTP support for additiona…
fedemaleh May 5, 2026
7bd2a57
Additional port default is http
fedemaleh May 6, 2026
420c39c
fix(k8s/templates): use root context for k8s_modifiers in HTTP additi…
fedemaleh May 6, 2026
080827f
fix(k8s/templates): remove HTTP sidecar; HTTP additional ports are ap…
fedemaleh May 6, 2026
492841a
fix(k8s/templates): restore HTTP additional-port sidecar with UPSTREA…
fedemaleh May 6, 2026
39d4856
fix(k8s/templates): HTTP sidecar binds port+10000 so app can bind por…
fedemaleh May 8, 2026
9e6b43d
fix(k8s/verify_ingress): dedupe weights for multi-ingress listeners +…
fedemaleh May 8, 2026
1a52f3c
feat(k8s/templates): HTTP additional ports listen on dedicated HTTPS …
fedemaleh May 8, 2026
604a1fe
Fix tests
fedemaleh May 8, 2026
1e13f95
docs: document ALB listener lifecycle and 50-listener capacity limit
fedemaleh May 11, 2026
296c410
Review changes
fedemaleh May 11, 2026
ca00d3c
Merge pull request #183 from nullplatform/feature/clien-739-configura…
fedemaleh May 12, 2026
849f97c
Surface user-friendly failure reasons on deployment timeout (#184)
ignacioboud May 20, 2026
7c5bb64
docs: add design spec for CLIEN-781 memory & CPU limits
fedemaleh May 21, 2026
feb746a
docs: add implementation plan for CLIEN-781 memory & CPU limits
fedemaleh May 21, 2026
3916ce8
feat: add cpu_millicores_limit and ram_memory_limit properties to k8s…
fedemaleh May 21, 2026
957debc
feat: rename Processor tab to Resources and surface CPU/RAM limit con…
fedemaleh May 21, 2026
8bc5dac
feat: normalize cpu/ram limit capabilities to request value when unset
fedemaleh May 21, 2026
f50b59c
feat: render application container limits from normalized capability …
fedemaleh May 21, 2026
a40f54a
refactor: tighten normalize_capability_limits jq + bats here-string i…
fedemaleh May 21, 2026
3eff675
fix: mark cpu_millicores_limit and ram_memory_limit as required for U…
fedemaleh May 21, 2026
6856c9c
refactor: make cpu_millicores_limit a dropdown with 'Same as request'…
fedemaleh May 21, 2026
fcf31d7
Structured evidence + log embedding in k8s/diagnose (#181)
ignacioboud May 22, 2026
d08ca79
docs: align ram_memory_limit description with cpu_millicores_limit ph…
fedemaleh May 22, 2026
88f65ee
chore: move design spec and plan to .claude (untracked working notes)
fedemaleh May 22, 2026
26aae22
docs: add changelog entry for configurable CPU and memory limits
fedemaleh May 22, 2026
d9cf93f
Merge branch 'beta' into feature/clien-781-memory-cpu-limits
fedemaleh May 22, 2026
81726e1
refactor: drop ticket id and noise from normalize_capability_limits c…
fedemaleh May 22, 2026
0a3ab0f
test: exercise normalize via full build_context instead of private fu…
fedemaleh May 22, 2026
811b607
test: remove deployment template shape tests in favor of integration …
fedemaleh May 22, 2026
44776c7
feat: clamp limit to request when below it as defense-in-depth
fedemaleh May 22, 2026
e9505e4
Merge pull request #185 from nullplatform/feature/clien-781-memory-cp…
fedemaleh May 26, 2026
fd39127
fix(k8s,scheduled_task): file-type parameter no longer leaks binary a…
fedemaleh May 27, 2026
f6118ce
docs(changelog): tighten file-parameter fix entry
fedemaleh May 27, 2026
4c57d1e
fix(k8s,scheduled_task): isolate file binary in a dedicated Secret
fedemaleh May 27, 2026
8a093eb
refactor(k8s,scheduled_task): derive file-param identifiers from .name
fedemaleh May 27, 2026
dc679d2
fix(k8s,scheduled_task): omit env: block when no file params
fedemaleh May 27, 2026
cd89c5f
Revert "fix(k8s,scheduled_task): omit env: block when no file params"
fedemaleh May 27, 2026
b994dfa
fix(k8s,scheduled_task): quote destination_path in YAML to escape flo…
fedemaleh May 27, 2026
e43f0f3
test(scheduled_task): add build_deployment render test for file params
fedemaleh May 27, 2026
df0a510
Merge pull request #186 from nullplatform/fix/file-param-env-nul-byte
fedemaleh Jun 1, 2026
6c6284f
Update CHANGELOG.md
fedemaleh Jun 8, 2026
2836cfb
Merge pull request #188 from nullplatform/fedemaleh-patch-1
fedemaleh Jun 8, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -151,3 +151,6 @@ testing/docker/certs/

# Claude Code
.claude/

# Visual Studio Code
.vscode/
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,16 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

## [1.12.0] - 2026-06-08
- Fix: do not inject file parameter as env vars
- Public and private scopes now register DNS records in their correct Route53 hosted zone when using `DNS_TYPE=external_dns`, preventing cross-zone record leakage
- Add configurable main HTTP port for k8s scopes (default 8080) and HTTP support for additional ports
- Improve **wait deployment active** failure logging: consolidate repeated `Unhealthy` probe events per pod into a single human-readable line, emit a progress heartbeat every 10% of timeout, and surface a targeted suggested fix based on the probe failure mode (port not open / HTTP non-2xx / probe timeout)
- Add configurable memory and CPU limits, independent from requests, for k8s scope containers
- Improve **k8s/diagnose** evidence: every check now emits structured evidence following a documented schema (`summary`, `severity`, `affected`, `details`, `suggested_actions`), failure findings embed the relevant pod log slice (current or previous depending on the failure mode), and a new **Application Logs** category surfaces the user-owned `application` container's log tail directly in the UI

## [1.11.0] - 2026-04-16
- Add unit testing support
- Add scope configuration
Expand Down
36 changes: 35 additions & 1 deletion k8s/deployment/build_context
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,20 @@ MIN_REPLICAS=$(echo "$MIN_REPLICAS" | awk '{printf "%d", ($1 == int($1) ? $1 : i

DEPLOYMENT_STATUS=$(echo "$CONTEXT" | jq -r ".deployment.status")

# Fill in *_limit capability fields with the corresponding request value when
# the limit is missing or explicitly null, then clamp any limit below its
# request up to the request value. The schema rejects limit < request at save
# time; this is defense-in-depth so the script can never produce an invalid
# resources block, regardless of how the context was built.
normalize_capability_limits() {
echo "$1" | jq '
.scope.capabilities.cpu_millicores_limit //= .scope.capabilities.cpu_millicores
| .scope.capabilities.ram_memory_limit //= .scope.capabilities.ram_memory
| .scope.capabilities.cpu_millicores_limit = ([.scope.capabilities.cpu_millicores, .scope.capabilities.cpu_millicores_limit] | max)
| .scope.capabilities.ram_memory_limit = ([.scope.capabilities.ram_memory, .scope.capabilities.ram_memory_limit] | max)
'
}

validate_status() {
local action="$1"
local status="$2"
Expand Down Expand Up @@ -245,6 +259,22 @@ if [[ -n "$TRAFFIC_MANAGER_CONFIG_MAP" ]]; then
log info "✨ ConfigMap '$TRAFFIC_MANAGER_CONFIG_MAP' validation successful"
fi

MAIN_HTTP_PORT=$(echo "$CONTEXT" | jq -r '.scope.capabilities.main_http_port // 8080')
log debug "🔍 main_http_port resolved to ${MAIN_HTTP_PORT}"

# Enrich each additional_ports entry with traffic_manager_port = port + 10000.
# Convention: the traffic-manager sidecar that fronts an additional port binds
# <port>+10000 inside the pod so the application can bind <port> directly. The
# fixed +10000 offset makes it trivial to identify which sidecar belongs to
# which application port at a glance (e.g. app 8081 -> sidecar 18081). Keeping
# the math here (instead of in every template) means consumers just read
# .traffic_manager_port and never re-derive it.
CONTEXT=$(echo "$CONTEXT" | jq '
if (.scope.capabilities.additional_ports | type) == "array" then
.scope.capabilities.additional_ports |= map(. + {traffic_manager_port: (.port + 10000)})
else . end
')

# Check if blue deployment has K8s services for additional ports
BLUE_ADDITIONAL_PORT_SERVICES="{}"
if [ -n "$BLUE_DEPLOYMENT_ID" ] && [ "$BLUE_DEPLOYMENT_ID" != "null" ]; then
Expand Down Expand Up @@ -280,6 +310,7 @@ CONTEXT=$(echo "$CONTEXT" | jq \
--arg container_memory_in_memory "$CONTAINER_MEMORY_IN_MEMORY" \
--arg container_cpu_in_millicores "$CONTAINER_CPU_IN_MILLICORES" \
--argjson blue_additional_port_services "$BLUE_ADDITIONAL_PORT_SERVICES" \
--arg main_http_port "$MAIN_HTTP_PORT" \
'. + {blue_deployment_id: $blue_deployment_id,
blue_replicas: $blue_replicas,
green_replicas: $green_replicas,
Expand All @@ -292,9 +323,12 @@ CONTEXT=$(echo "$CONTEXT" | jq \
traffic_manager_config_map: $traffic_manager_config_map,
container_memory_in_memory: $container_memory_in_memory,
container_cpu_in_millicores: $container_cpu_in_millicores,
blue_additional_port_services: $blue_additional_port_services
blue_additional_port_services: $blue_additional_port_services,
main_http_port: ($main_http_port | tonumber)
}')

CONTEXT=$(normalize_capability_limits "$CONTEXT")

DEPLOYMENT_ID=$(echo "$CONTEXT" | jq -r '.deployment.id')

OUTPUT_DIR="$SERVICE_PATH/output/$SCOPE_ID-$DEPLOYMENT_ID"
Expand Down
13 changes: 13 additions & 0 deletions k8s/deployment/build_deployment
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

DEPLOYMENT_PATH="$OUTPUT_DIR/deployment-$SCOPE_ID-$DEPLOYMENT_ID.yaml"
SECRET_PATH="$OUTPUT_DIR/secret-$SCOPE_ID-$DEPLOYMENT_ID.yaml"
SECRET_FILES_PATH="$OUTPUT_DIR/secret-files-$SCOPE_ID-$DEPLOYMENT_ID.yaml"
SCALING_PATH="$OUTPUT_DIR/scaling-$SCOPE_ID-$DEPLOYMENT_ID.yaml"
SERVICE_TEMPLATE_PATH="$OUTPUT_DIR/service-$SCOPE_ID-$DEPLOYMENT_ID.yaml"
PDB_PATH="$OUTPUT_DIR/pdb-$SCOPE_ID-$DEPLOYMENT_ID.yaml"
Expand Down Expand Up @@ -38,6 +39,18 @@ if [[ $TEMPLATE_GENERATION_STATUS -ne 0 ]]; then
fi
log info " ✅ Secret template: $SECRET_PATH"

gomplate -c .="$CONTEXT_PATH" \
--file "$SECRET_FILES_TEMPLATE" \
--out "$SECRET_FILES_PATH"

TEMPLATE_GENERATION_STATUS=$?

if [[ $TEMPLATE_GENERATION_STATUS -ne 0 ]]; then
log error " ❌ Failed to build secret-files template"
exit 1
fi
log info " ✅ Secret-files template: $SECRET_FILES_PATH"

gomplate -c .="$CONTEXT_PATH" \
--file "$SCALING_TEMPLATE" \
--out "$SCALING_PATH"
Expand Down
Loading
Loading