Reputation: 75
I have a task to configure the following Ansible playbook to ignore error code 422 (which should happen when it looks for a volume that is detached from the server).
Furthermore, I currently see that this situation can also display error code 400, so, I may also have to exclude this.
# ---
# # This script will print the received parameters only
- hosts: localhost
connection: local
# # Required parameters
# # for testing locally
vars:
server_id: xxx
backup_properties:
name: xxx
retention_period: x
volume_ids:
- xxx
gather_facts: no
tasks:
# Get moss_url variable
- include_tasks: ../vault_get_moss_environment.yml
# Request the backup from the endpoint
- name: Call MOS Windows Service Endpoint
uri:
url: "{{ moss_url }}/v1/service-instances/{{ server_id }}/backups"
method: POST
return_content: yes
status_code: 202
headers:
Content-Type: "application/json"
Authorization: "Bearer {{ getToken.json.access_token }}"
body_format: json
body: {
"name": "{{ backup_properties.name | default('Backup Before Update') }}",
"volumeIds": "{{ backup_properties.volume_ids | default(omit) }}",
"retentionPeriod": "{{ backup_properties.retention_period | default(14) }}"
}
register: trigger_backup_response
no_log: false
ignore_errors: yes
- fail:
msg: "Error code: {% if trigger_backup_response.msg %}{{ trigger_backup_response.msg }}{% else %}{{ trigger_backup_response }}{% endif %}"
when: trigger_backup_response.failed | default(false) and trigger_backup_response.json.status != "NOT_FOUND" # .failed is defined only when it fails
- name: Delete server's backup schedules if server is not found in Openstack
include_tasks: ../MOSS/call_moss_delete_backup_schedules.yml
vars:
id: "{{ server_id }}"
when: trigger_backup_response.status == 404 and trigger_backup_response.json.status == "NOT_FOUND"
- name: Get the id from the content
debug:
msg: "Started backup job with id: {{ trigger_backup_response.json.id }} for server with id: {{ server_id }}"
when: trigger_backup_response.status == 202
- name: Set backup_job_id as a fact
set_fact:
backup_job_id="{{ trigger_backup_response.json.id }}"
when: trigger_backup_response.status == 202
###### Please do not delete this debug as it is used by MOSS #####
- debug:
msg: "backup_job_id={{ backup_job_id }}"
when: trigger_backup_response.status == 202
I am aware that I probably have to use ignore_erros
in some context, but, am not able to locate any way to exclude errors specifically by their code.
So, overall the question is how can I make this playbook ignore specifically errors 422 and 400 without sending any alerts or performing any actions?
Upvotes: 2
Views: 5418
Reputation: 75
So two things turned out to be the issue here:
failed_when
had to be used before no_log: false
and ignore_errors: yes
(the no_log part probably didn't matter too much, but the ignore_errors mechanism was apparently taking effect as it was before the condition of when not to fail).Currently, the working code looks like this:
# ---
# # This script will print the received parameters only
# - hosts: localhost
# connection: local
# # Required parameters
# # for testing locally
# vars:
# server_id: xxx
# backup_properties:
# name: xxx
# retention_period: x
# volume_ids:
# - xxx
# # gather_facts: no
# tasks:
# Get moss_url variable
- include_tasks: ../vault_get_moss_environment.yml
# Request the backup from the endpoint
- name: Call MOS Windows Service Endpoint
uri:
url: "{{ moss_url }}/v1/service-instances/{{ server_id }}/backups"
method: POST
return_content: yes
status_code: 202
headers:
Content-Type: "application/json"
Authorization: "Bearer {{ getToken.json.access_token }}"
body_format: json
body: {
"name": "{{ backup_properties.name | default('Backup Before Update') }}",
"volumeIds": "{{ backup_properties.volume_ids | default(omit) }}",
"retentionPeriod": "{{ backup_properties.retention_period | default(14) }}"
}
register: trigger_backup_response
failed_when: trigger_backup_response.status not in [202, 422]
no_log: false
ignore_errors: yes
- fail:
msg: "Error code: {% if trigger_backup_response.msg %}{{ trigger_backup_response.msg }}{% else %}{{ trigger_backup_response }}{% endif %}"
when: trigger_backup_response.failed | default(false) and trigger_backup_response.json.status != "NOT_FOUND" # .failed is defined only when it fails
- name: Delete server's backup schedules if server is not found in Openstack
include_tasks: ../MOSS/call_moss_delete_backup_schedules.yml
vars:
id: "{{ server_id }}"
when: trigger_backup_response.status == 404 and trigger_backup_response.json.status == "NOT_FOUND"
- name: Get the id from the content
debug:
msg: "Started backup job with id: {{ trigger_backup_response.json.id }} for server with id: {{ server_id }}"
when: trigger_backup_response.status == 202
- name: Set backup_job_id as a fact
set_fact:
backup_job_id="{{ trigger_backup_response.json.id }}"
when: trigger_backup_response.status == 202
###### Please do not delete this debug as it is used by MOSS #####
- debug:
msg: "backup_job_id={{ backup_job_id }}"
when: trigger_backup_response.status == 202
With that said, the previous answer was completely valid, just needed some modifications in this specific case. So thanks a lot for the assistance! =)
Upvotes: 0
Reputation: 39355
You can use a better mechanism than ignore_errors
in this case, it is failed_when
.
With it, you can fine grain the failure of a task to exactly what you want.
In your case it would be something like:
- name: Call MOS Windows Service Endpoint
uri:
url: https://example.org/api
## reduced the uri for brevity
register: trigger_backup_response
failed_when: trigger_backup_response.status not in [202, 400, 422]
This will cause the codes 202
, 400
and 422
to have a successful task, all other status code would, then, fail.
Next to this, in order to handle the tasks based on the return of that API call, you can either use a block
:
- block:
- debug:
msg: First task upon receiving a return form the API
- debug:
msg: Second task upon receiving a return form the API
- debug:
msg: Third task upon receiving a return form the API
when: trigger_backup_response.status == 202
Or, stop the execution totally, with the help of the meta
module.
The task here under will stop the play, on an host basis, if the the return code of the API is either 400
or 422
.
- meta: end_host
when: trigger_backup_response.status in [400, 422]
So, having a scenario like:
- name: Call API
uri:
url: https://example.org/api
register: trigger_backup_response
failed_when: trigger_backup_response.status not in [202, 400, 422]
- name: End play for hosts with detached volumes
meta: end_host
when: trigger_backup_response.status in [400, 422]
## From now on, it is safe to assume
## we are only dealing with API answer status being 202
- name: Display volume IDs
debug:
var: backup_properties.volume_ids
Upvotes: 4