fix(semaphore/configure): build POST bodies via Jinja dict literals
The 'uri' module with body_format=json was sending integer fields as
strings when they came from quoted Jinja expressions in inline YAML
(e.g. ssh_key_id: "{{ ... | int }}"), because YAML loads the quoted
form as a string and Ansible doesn't coerce back. Semaphore rejects
that with HTTP 400.
Build each body as a Jinja dict literal in a folded scalar so types
survive: integers stay integers, strings stay strings.
Also restores no_log: true on key creation now that we're past the
debug round.
This commit is contained in:
@@ -103,8 +103,7 @@
|
|||||||
loop_control:
|
loop_control:
|
||||||
label: "{{ item.name }}"
|
label: "{{ item.name }}"
|
||||||
when: item.name not in (_semaphore_keys.json | map(attribute='name') | list)
|
when: item.name not in (_semaphore_keys.json | map(attribute='name') | list)
|
||||||
# no_log temporarily disabled for debugging
|
no_log: true
|
||||||
no_log: false
|
|
||||||
|
|
||||||
- name: Re-list keys with assigned ids
|
- name: Re-list keys with assigned ids
|
||||||
ansible.builtin.uri:
|
ansible.builtin.uri:
|
||||||
@@ -140,12 +139,20 @@
|
|||||||
headers: "{{ _semaphore_headers }}"
|
headers: "{{ _semaphore_headers }}"
|
||||||
validate_certs: "{{ semaphore_api_validate_certs }}"
|
validate_certs: "{{ semaphore_api_validate_certs }}"
|
||||||
body_format: json
|
body_format: json
|
||||||
body:
|
# Build the body via Jinja so integer fields stay integers (the uri
|
||||||
name: "{{ item.name }}"
|
# module preserves dict value types from a Jinja expression but
|
||||||
project_id: "{{ _semaphore_project_id | int }}"
|
# coerces quoted "{{ ... }}" tokens in inline YAML to strings,
|
||||||
git_url: "{{ item.git_url }}"
|
# which Semaphore rejects with a 400).
|
||||||
git_branch: "{{ item.git_branch | default('main') }}"
|
body: >-
|
||||||
ssh_key_id: "{{ _semaphore_key_ids[item.ssh_key] | int }}"
|
{{
|
||||||
|
{
|
||||||
|
'name': item.name,
|
||||||
|
'project_id': _semaphore_project_id | int,
|
||||||
|
'git_url': item.git_url,
|
||||||
|
'git_branch': item.git_branch | default('main'),
|
||||||
|
'ssh_key_id': _semaphore_key_ids[item.ssh_key] | int
|
||||||
|
}
|
||||||
|
}}
|
||||||
status_code: [201, 204]
|
status_code: [201, 204]
|
||||||
loop: "{{ semaphore_config.repositories }}"
|
loop: "{{ semaphore_config.repositories }}"
|
||||||
loop_control:
|
loop_control:
|
||||||
@@ -185,14 +192,18 @@
|
|||||||
headers: "{{ _semaphore_headers }}"
|
headers: "{{ _semaphore_headers }}"
|
||||||
validate_certs: "{{ semaphore_api_validate_certs }}"
|
validate_certs: "{{ semaphore_api_validate_certs }}"
|
||||||
body_format: json
|
body_format: json
|
||||||
body:
|
body: >-
|
||||||
name: "{{ item.name }}"
|
{{
|
||||||
project_id: "{{ _semaphore_project_id | int }}"
|
{
|
||||||
type: "{{ item.type | default('file') }}"
|
'name': item.name,
|
||||||
inventory: "{{ item.inventory_file }}"
|
'project_id': _semaphore_project_id | int,
|
||||||
repository_id: "{{ _semaphore_repo_ids[item.repository] | int }}"
|
'type': item.type | default('file'),
|
||||||
ssh_key_id: "{{ _semaphore_key_ids[item.ssh_key] | int }}"
|
'inventory': item.inventory_file,
|
||||||
become_key_id: "{{ _semaphore_key_ids[item.become_key | default(item.ssh_key)] | int }}"
|
'repository_id': _semaphore_repo_ids[item.repository] | int,
|
||||||
|
'ssh_key_id': _semaphore_key_ids[item.ssh_key] | int,
|
||||||
|
'become_key_id': _semaphore_key_ids[item.become_key | default(item.ssh_key)] | int
|
||||||
|
}
|
||||||
|
}}
|
||||||
status_code: [201, 204]
|
status_code: [201, 204]
|
||||||
loop: "{{ semaphore_config.inventories }}"
|
loop: "{{ semaphore_config.inventories }}"
|
||||||
loop_control:
|
loop_control:
|
||||||
@@ -231,14 +242,15 @@
|
|||||||
headers: "{{ _semaphore_headers }}"
|
headers: "{{ _semaphore_headers }}"
|
||||||
validate_certs: "{{ semaphore_api_validate_certs }}"
|
validate_certs: "{{ semaphore_api_validate_certs }}"
|
||||||
body_format: json
|
body_format: json
|
||||||
body:
|
body: >-
|
||||||
name: "{{ item.name }}"
|
{{
|
||||||
project_id: "{{ _semaphore_project_id | int }}"
|
{
|
||||||
# Semaphore stores both env (process env vars) and json (extra
|
'name': item.name,
|
||||||
# variables). Pass an empty object for json unless someone
|
'project_id': _semaphore_project_id | int,
|
||||||
# extends the schema later.
|
'env': (item.env | default({}) | to_json),
|
||||||
env: "{{ item.env | default({}) | to_json }}"
|
'json': (item.extra_vars | default({}) | to_json)
|
||||||
json: "{{ item.extra_vars | default({}) | to_json }}"
|
}
|
||||||
|
}}
|
||||||
status_code: [201, 204]
|
status_code: [201, 204]
|
||||||
loop: "{{ semaphore_config.environments }}"
|
loop: "{{ semaphore_config.environments }}"
|
||||||
loop_control:
|
loop_control:
|
||||||
@@ -277,19 +289,26 @@
|
|||||||
headers: "{{ _semaphore_headers }}"
|
headers: "{{ _semaphore_headers }}"
|
||||||
validate_certs: "{{ semaphore_api_validate_certs }}"
|
validate_certs: "{{ semaphore_api_validate_certs }}"
|
||||||
body_format: json
|
body_format: json
|
||||||
body:
|
body: >-
|
||||||
project_id: "{{ _semaphore_project_id | int }}"
|
{{
|
||||||
name: "{{ item.name }}"
|
{
|
||||||
description: "{{ item.description | default('') }}"
|
'project_id': _semaphore_project_id | int,
|
||||||
app: "{{ item.app | default('ansible') }}"
|
'name': item.name,
|
||||||
playbook: "{{ item.playbook }}"
|
'description': item.description | default(''),
|
||||||
arguments: "{{ item.arguments | default('[]') }}"
|
'app': item.app | default('ansible'),
|
||||||
allow_override_args_in_task: "{{ item.allow_override_args | default(false) }}"
|
'playbook': item.playbook,
|
||||||
inventory_id: "{{ _semaphore_inv_ids[item.inventory] | int }}"
|
'arguments': item.arguments | default('[]'),
|
||||||
repository_id: "{{ _semaphore_repo_ids[item.repository] | int }}"
|
'allow_override_args_in_task': item.allow_override_args | default(false),
|
||||||
environment_id: "{{ _semaphore_env_ids[item.environment] | int }}"
|
'inventory_id': _semaphore_inv_ids[item.inventory] | int,
|
||||||
vault_key_id: "{{ _semaphore_key_ids[item.vault_password] | int if item.vault_password is defined else omit }}"
|
'repository_id': _semaphore_repo_ids[item.repository] | int,
|
||||||
survey_vars: "{{ item.survey_vars | default([]) }}"
|
'environment_id': _semaphore_env_ids[item.environment] | int,
|
||||||
|
'survey_vars': item.survey_vars | default([])
|
||||||
|
}
|
||||||
|
| combine(
|
||||||
|
{'vault_key_id': _semaphore_key_ids[item.vault_password] | int}
|
||||||
|
if item.vault_password is defined else {}
|
||||||
|
)
|
||||||
|
}}
|
||||||
status_code: [201, 204]
|
status_code: [201, 204]
|
||||||
loop: "{{ semaphore_config.templates }}"
|
loop: "{{ semaphore_config.templates }}"
|
||||||
loop_control:
|
loop_control:
|
||||||
|
|||||||
Reference in New Issue
Block a user