Use symbolized keys in all workspace reconciliation logic
Issue: Refactorings to workspace container/script logic (#511503 - closed)
What does this MR do and why?
Converts all handling of "config_to_apply" kubernetes resources in Workspaces Rails domain logic to use symbolized keys instead of stringified keys.
It is only converted to a YAML file immediately before it is returned to the agent in the rails_info payload of the reconciliation loop response.
Benefits of symbolized keys:
- Data structures with symbolized keys can be used with rightward assignment and pattern matching
- Code is generally more concise and readable with symbol keys (no quotes, no fat-arrow hash syntax required
- Avoids confusion due to inconsistency (all other Workspaces domain code uses stringified keys wherever possible)
- Allows new domain logic which works with the config_to_apply to be written using symbols (see Refactorings to workspace container/script logic (#511503 - closed))
Summary of changes
- Symbolizes all keys related to
config_to_apply - Converts several usages of
findanddigto use pattern matching, now that it is available - Introduces documentation and examples of array-based pattern matching, and uses it in several places.
- Other minor rename/cleanup refactors
References
Please include cross links to any resources that are relevant to this MR. This will give reviewers and future readers helpful context to give an efficient review of the changes introduced.
- Refactorings to workspace container/script logic (#511503 - closed)
- Startup scripts for Remote Development workspac... (&15602)
MR acceptance checklist
Please evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.
Screenshots or screen recordings
Tested and verified in local development:
Agent can still successfully process the reconciliation rails_infos payload
{"time":"2025-02-07T20:23:48.53231-08:00","level":"INFO","msg":"starting partial reconciliation","mod_name":"remote_development","agent_id":4}
{"time":"2025-02-07T20:23:48.532362-08:00","level":"DEBUG","msg":"Running reconciliation loop","mod_name":"remote_development","agent_id":4}
{"time":"2025-02-07T20:23:48.532427-08:00","level":"DEBUG","msg":"Making GitLab request","mod_name":"remote_development","agent_id":4}
{"time":"2025-02-07T20:24:15.522096-08:00","level":"DEBUG","msg":"Made request to the Rails API","mod_name":"remote_development","agent_id":4,"status_code":201,"request_id":"01JKHWSY6M3E2P9FVSZC28KMV8","duration_in_ms":26989}
{"time":"2025-02-07T20:24:15.536792-08:00","level":"DEBUG","msg":"Read body from the Rails API","mod_name":"remote_development","agent_id":4,"payload_size_in_bytes":40328,"workspace_data_count":3}
{"time":"2025-02-07T20:24:15.550277-08:00","level":"DEBUG","msg":"Applying work to cluster","mod_name":"remote_development","agent_id":4,"inventory_name":"workspace-4-1-hesumv-secrets-inventory","inventory_namespace":"gl-rd-ns-4-1-hesumv"}
{"time":"2025-02-07T20:24:15.552368-08:00","level":"DEBUG","msg":"Applied work to cluster","mod_name":"remote_development","agent_id":4,"inventory_name":"workspace-4-1-hesumv-secrets-inventory","inventory_namespace":"gl-rd-ns-4-1-hesumv"}
{"time":"2025-02-07T20:24:15.55239-08:00","level":"DEBUG","msg":"Applying work to cluster","mod_name":"remote_development","agent_id":4,"inventory_name":"workspace-4-1-hesumv-workspace-inventory","inventory_namespace":"gl-rd-ns-4-1-hesumv"}
{"time":"2025-02-07T20:24:15.552404-08:00","level":"DEBUG","msg":"Applied work to cluster","mod_name":"remote_development","agent_id":4,"inventory_name":"workspace-4-1-hesumv-workspace-inventory","inventory_namespace":"gl-rd-ns-4-1-hesumv"}
{"time":"2025-02-07T20:24:15.566214-08:00","level":"DEBUG","msg":"Applied event","mod_name":"remote_development","agent_id":4,"apply_event":"InitEvent{ ActionGroups: [ [ ActionGroup{ Name: \"inventory-add-0\", Action: \"Inventory\", Identifiers: [gl-rd-ns-4-1-hesumv_workspace-4-1-hesumv-env-var__Secret gl-rd-ns-4-1-hesumv_workspace-4-1-hesumv-file__Secret] } ], [ ActionGroup{ Name: \"apply-0\", Action: \"Apply\", Identifiers: [gl-rd-ns-4-1-hesumv_workspace-4-1-hesumv-env-var__Secret gl-rd-ns-4-1-hesumv_workspace-4-1-hesumv-file__Secret] } ], [ ActionGroup{ Name: \"wait-0\", Action: \"Wait\", Identifiers: [gl-rd-ns-4-1-hesumv_workspace-4-1-hesumv-env-var__Secret gl-rd-ns-4-1-hesumv_workspace-4-1-hesumv-file__Secret] } ], [ ActionGroup{ Name: \"inventory-set-0\", Action: \"Inventory\", Identifiers: [] } ] ] }"}
{"time":"2025-02-07T20:24:15.569254-08:00","level":"DEBUG","msg":"Applied event","mod_name":"remote_development","agent_id":4,"apply_event":"StatusEvent{ Status: \"Current\", Generation: 0, Identifier: \"gl-rd-ns-4-1-hesumv_workspace-4-1-hesumv-env-var__Secret\" }"}
{"time":"2025-02-07T20:24:15.569296-08:00","level":"DEBUG","msg":"Applied event","mod_name":"remote_development","agent_id":4,"apply_event":"StatusEvent{ Status: \"Current\", Generation: 0, Identifier: \"gl-rd-ns-4-1-hesumv_workspace-4-1-hesumv-file__Secret\" }"}
{"time":"2025-02-07T20:24:15.578171-08:00","level":"DEBUG","msg":"Applied event","mod_name":"remote_development","agent_id":4,"apply_event":"InitEvent{ ActionGroups: [ [ ActionGroup{ Name: \"inventory-add-0\", Action: \"Inventory\", Identifiers: [gl-rd-ns-4-1-hesumv_workspace-4-1-hesumv_apps_Deployment gl-rd-ns-4-1-hesumv_workspace-4-1-hesumv__Service gl-rd-ns-4-1-hesumv_workspace-4-1-hesumv-gl-workspace-data__PersistentVolumeClaim gl-rd-ns-4-1-hesumv_workspace-4-1-hesumv__ServiceAccount gl-rd-ns-4-1-hesumv_workspace-4-1-hesumv_networking.k8s.io_NetworkPolicy] } ], [ ActionGroup{ Name: \"apply-0\", Action: \"Apply\", Identifiers: [gl-rd-ns-4-1-hesumv_workspace-4-1-hesumv__ServiceAccount gl-rd-ns-4-1-hesumv_workspace-4-1-hesumv__Service gl-rd-ns-4-1-hesumv_workspace-4-1-hesumv_apps_Deployment gl-rd-ns-4-1-hesumv_workspace-4-1-hesumv-gl-workspace-data__PersistentVolumeClaim gl-rd-ns-4-1-hesumv_workspace-4-1-hesumv_networking.k8s.io_NetworkPolicy] } ], [ ActionGroup{ Name: \"wait-0\", Action: \"Wait\", Identifiers: [gl-rd-ns-4-1-hesumv_workspace-4-1-hesumv__ServiceAccount gl-rd-ns-4-1-hesumv_workspace-4-1-hesumv__Service gl-rd-ns-4-1-hesumv_workspace-4-1-hesumv_apps_Deployment gl-rd-ns-4-1-hesumv_workspace-4-1-hesumv-gl-workspace-data__PersistentVolumeClaim gl-rd-ns-4-1-hesumv_workspace-4-1-hesumv_networking.k8s.io_NetworkPolicy] } ], [ ActionGroup{ Name: \"inventory-set-0\", Action: \"Inventory\", Identifiers: [] } ] ] }"}
{"time":"2025-02-07T20:24:15.58165-08:00","level":"DEBUG","msg":"Applying work to cluster","mod_name":"remote_development","agent_id":4,"inventory_name":"workspace-4-1-mf7wb6-workspace-inventory","inventory_namespace":"gl-rd-ns-4-1-mf7wb6"}
{"time":"2025-02-07T20:24:15.581673-08:00","level":"DEBUG","msg":"Applied work to cluster","mod_name":"remote_development","agent_id":4,"inventory_name":"workspace-4-1-mf7wb6-workspace-inventory","inventory_namespace":"gl-rd-ns-4-1-mf7wb6"}
{"time":"2025-02-07T20:24:15.581675-08:00","level":"DEBUG","msg":"Applying work to cluster","mod_name":"remote_development","agent_id":4,"inventory_name":"workspace-4-1-mf7wb6-secrets-inventory","inventory_namespace":"gl-rd-ns-4-1-mf7wb6"}
{"time":"2025-02-07T20:24:15.581678-08:00","level":"DEBUG","msg":"Applied work to cluster","mod_name":"remote_development","agent_id":4,"inventory_name":"workspace-4-1-mf7wb6-secrets-inventory","inventory_namespace":"gl-rd-ns-4-1-mf7wb6"}
{"time":"2025-02-07T20:24:15.581685-08:00","level":"DEBUG","msg":"Reconciliation loop ended","mod_name":"remote_development","agent_id":4}
{"time":"2025-02-07T20:24:15.581688-08:00","level":"DEBUG","msg":"finishing partial reconciliation","mod_name":"remote_development","agent_id":4,"full_reconciliation_interval":3600000000000,"partial_reconciliation_interval":10000000000}
Workspace is functional, VS Code starts, variables are set, and SSH works
How to set up and validate locally
Create a workspace locally, verify that everything still works with workspace creation and reconciliation.
This is an involved local setup process, so I've included output of local testing above. I can pair and demonstrate on my machine if you want to see it working prior to merge.
