Skip to content

Commit b912820

Browse files
committed
add dry_run var, improve HANA file regex and wildcard support
1 parent 86e2602 commit b912820

11 files changed

Lines changed: 193 additions & 149 deletions

File tree

plugins/module_utils/software_center/search.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -358,9 +358,9 @@ def _prepare_search_filename(filename, search_upgrades=False):
358358

359359
# Revision version will be kept to ensure correct component versions.
360360
# Example: IMDB_SERVER20_067_4-80002046.SAR returns (IMDB_SERVER20_067, None, None)
361-
# With search_upgrades: (IMDB_SERVER20_067, IMDB_SERVER20_068, IMDB_SERVER20_)
361+
# With search_upgrades: (IMDB_SERVER20_067, IMDB_SERVER20_06, IMDB_SERVER20_)
362362
# Example: IMDB_AFL20_077_0-80002045.SAR returns (IMDB_AFL20_077, None, None)
363-
# With search_upgrades: (IMDB_AFL20_077, IMDB_AFL20_078, IMDB_AFL20_)
363+
# With search_upgrades: (IMDB_AFL20_077, IMDB_AFL20_07, IMDB_AFL20_)
364364
elif filename_base.startswith(('IMDB_SERVER', 'IMDB_AFL', 'IMDB_LCAPPS_1', 'IMDB_LCAPPS_2')):
365365
# Remove P from the 3rd element (index 2) to improve fuzzy search.
366366
if len(filename_parts) > 2:
@@ -370,7 +370,12 @@ def _prepare_search_filename(filename, search_upgrades=False):
370370
if search_upgrades:
371371
# Extract base prefix (e.g., IMDB_SERVER20_)
372372
suggested_base = "_".join(filename_parts[:2]) + '_'
373-
return suggested, _increment_last_digits(suggested), suggested_base
373+
# For 3-digit revisions, return prefix without last digit to find closest revision
374+
# Example: IMDB_SERVER20_077 → IMDB_SERVER20_07 catches 070-079 within same SPS 07.
375+
suggested_next = _increment_last_digits(suggested)
376+
if len(filename_parts) > 2 and len(filename_parts[2]) >= 3:
377+
suggested_next = "_".join(filename_parts[:2]) + '_' + filename_parts[2][:2]
378+
return suggested, suggested_next, suggested_base
374379
return suggested, None, None
375380

376381
# Example: IMDB_CLIENT20_021_31-80002082.SAR returns (IMDB_CLIENT20_021, IMDB_CLIENT20_022, None)

roles/sap_software_download/README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,12 @@ If multiple files with the same name are found, this setting determines which on
397397
Enables checksum validation of existing files present in `sap_software_download_directory`.<br>
398398
This does not affect automatic checksum validation of downloaded files.<br>
399399

400+
### sap_software_download_dry_run
401+
- _Type:_ `bool`<br>
402+
- _Default:_ `false`<br>
403+
404+
Enables `dry_run` mode in download tasks instead of actual download.<br>
405+
400406

401407
### sap_software_download_use_venv
402408
- _Type:_ `boolean`<br>

roles/sap_software_download/defaults/main.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,9 @@ sap_software_download_deduplicate: last
9191
# This does not affect automatic checksum validation of downloaded files.
9292
sap_software_download_validate_checksum: false
9393

94+
# Enables 'dry_run' mode in download tasks instead of actual download (Boolean).
95+
sap_software_download_dry_run: false
96+
9497

9598
### Python environment variables
9699

roles/sap_software_download/tasks/download_files.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
search_upgrades: "{{ sap_software_download_find_upgrades | d(false) }}"
2020
deduplicate: "{{ sap_software_download_deduplicate }}"
2121
validate_checksum: "{{ sap_software_download_validate_checksum | d(false) }}"
22+
dry_run: "{{ sap_software_download_dry_run | d(false) }}"
2223
# Loop condition acts as when conditional
2324
loop: "{{ __sap_software_download_files | d([]) }}"
2425
loop_control:

roles/sap_software_download/tasks/download_plan.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
download_filename: "{{ item.Filename }}"
1818
dest: "{{ sap_software_download_directory }}"
1919
validate_checksum: "{{ sap_software_download_validate_checksum | d(false) }}"
20+
dry_run: "{{ sap_software_download_dry_run | d(false) }}"
2021
# Loop condition acts as when conditional
2122
loop: "{{ __sap_software_download_register_mp_files.download_basket | d([]) }}"
2223
loop_control:

roles/sap_software_download/tasks/pre_steps/relationships/imdb_afl.yml

Lines changed: 45 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@
1212
# - IMDB_AFL20 - HANA 2.0 identifier
1313
# - 089 - Revision 89 (contains SPS level, e.g. SPS08)
1414
# - 300 - Patch level 3
15-
15+
#
16+
# NOTE: IMDB_AFL does not share FILE_ID between HANA 1.0 and 2.0 so upgrade search is not possible!
17+
#
1618
### Relationship validation workflow for IMDB_AFL:
1719
# 1. Parse file name to extract version details.
1820
# 2. Attempt search in dry_run mode if 'sap_software_download_find_alternatives' is true and fail if file is not found.
@@ -23,6 +25,36 @@
2325
# 7. Show summary message and inform about validation result.
2426

2527

28+
# Validate wildcard format if wildcard is present in filename.
29+
# This is validated inside of module, but we do it here to fail faster and avoid unnecessary API calls.
30+
- name: SAP Software Download - Relationship Validation - Validate wildcard format in IMDB_AFL filename
31+
ansible.builtin.fail:
32+
msg: |
33+
FAIL: Invalid wildcard format in IMDB_AFL filename.
34+
35+
Filename: {{ __sap_software_download_fact_hana_component_names['afl'] }}
36+
37+
Wildcard queries must follow specific format:
38+
Format: "PREFIX*-ID.EXT" where:
39+
- PREFIX must have at least one character before wildcard
40+
- Wildcard (*) must be in PREFIX position only
41+
- Single dash (-) separates prefix and ID
42+
- ID must be exactly 8 digits
43+
- Extension must be letters only
44+
45+
Valid examples:
46+
- "IMDB_AFL20*-80001894.SAR"
47+
- "IMDB_AFL100*-10012328.SAR"
48+
49+
Invalid examples:
50+
- "*-80001894.SAR" (no prefix - too broad)
51+
- "IMDB_AFL20-*.SAR" (wildcard in ID position)
52+
- "IMDB_AFL20*X-80001894.SAR" (extra characters after wildcard)
53+
- "IMDB_AFL20*-7000.SAR" (ID must be 8 digits, not 4)
54+
when:
55+
- "'*' in __sap_software_download_fact_hana_component_names['afl']"
56+
- __sap_software_download_fact_hana_component_names['afl'] is not match('^[^-]+\\*-\\d{8}\\.[a-zA-Z]+$')
57+
2658
# Update existing fact dictionary with component details appending to 'server' details.
2759
# '__sap_software_download_fact_hana_afl_original' is set for later reuse, when we update this dictionary.
2860
- name: SAP Software Download - Relationship Validation - Set fact with parsed IMDB_AFL file version details
@@ -55,37 +87,6 @@
5587
# Defines search type. Updated if alternative or update search is successful.
5688
source: exact
5789

58-
# Validate wildcard format if wildcard is present in filename.
59-
# This is validated inside of module, but we do it here to fail faster and avoid unnecessary API calls.
60-
- name: SAP Software Download - Relationship Validation - Validate wildcard format in IMDB_AFL filename
61-
ansible.builtin.fail:
62-
msg: |
63-
FAIL: Invalid wildcard format in IMDB_AFL filename.
64-
65-
Filename: {{ __sap_software_download_fact_hana_component_names['afl'] }}
66-
67-
Wildcard queries must follow specific format:
68-
Format: "PREFIX*-ID.EXT" where:
69-
- PREFIX must have at least one character before wildcard
70-
- Wildcard (*) must be in PREFIX position only
71-
- Single dash (-) separates prefix and ID
72-
- ID must be exactly 8 digits
73-
- Extension must be letters only
74-
75-
Valid examples:
76-
- "IMDB_AFL20*-80001894.SAR"
77-
- "IMDB_AFL100*-10012328.SAR"
78-
79-
Invalid examples:
80-
- "*-80001894.SAR" (no prefix - too broad)
81-
- "IMDB_AFL20-*.SAR" (wildcard in ID position)
82-
- "IMDB_AFL20*X-80001894.SAR" (extra characters after wildcard)
83-
- "IMDB_AFL20*-7000.SAR" (ID must be 8 digits, not 4)
84-
when:
85-
- "'*' in __sap_software_download_fact_hana_component_names['afl']"
86-
- __sap_software_download_fact_hana_component_names['afl'] is not match('^[^-]+\\*-\\d{8}\\.[a-zA-Z]+$')
87-
88-
# NOTE: IMDB_AFL does not share FILE_ID between HANA 1.0 and 2.0 so upgrade search is not possible!
8990
- name: SAP Software Download - Relationship Validation - Fail if IMDB_AFL is for wrong HANA version
9091
ansible.builtin.fail:
9192
msg: |
@@ -98,8 +99,19 @@
9899
Version: {{ __sap_software_download_fact_hana_components['afl']['version'] }}
99100
100101
Please provide correct IMDB_AFL file for the detected IMDB_SERVER version.
102+
{% if '*' in __sap_software_download_fact_hana_component_names['afl'] %}
103+
Wildcard prefixes must contain identifier for HANA version to avoid mismatch. Examples:
104+
- HANA 1.0: 'IMDB_AFL1*-{{ __file_id_ext }}', 'IMDB_AFL100*-{{ __file_id_ext }}', 'IMDB_AFL100_*-{{ __file_id_ext }}'
105+
- HANA 2.0: 'IMDB_AFL2*-{{ __file_id_ext }}', 'IMDB_AFL20*-{{ __file_id_ext }}', 'IMDB_AFL20_*-{{ __file_id_ext }}'
106+
{% else %}
107+
Expected prefixes:
108+
- HANA 1.0: 'IMDB_AFL100_'
109+
- HANA 2.0: 'IMDB_AFL20_'
110+
{% endif %}
111+
vars:
112+
__file_id_ext: "{{ __sap_software_download_fact_hana_components['afl']['file_id'] ~ '.SAR' }}"
101113
when: __sap_software_download_fact_hana_components['server']['version']
102-
!= __sap_software_download_fact_hana_components['afl']['version']
114+
!= __sap_software_download_fact_hana_components['afl']['version']
103115

104116

105117
- name: SAP Software Download - Relationship Validation - Check availability of IMDB_AFL file using dry run

roles/sap_software_download/tasks/pre_steps/relationships/imdb_lcapps.yml

Lines changed: 47 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@
1212
# - IMDB_LCAPPS2 - HANA 2.0 identifier
1313
# - 2089 - Revision 89 (contains SPS level, e.g. SPS08)
1414
# - 300 - Patch level 3
15-
15+
#
16+
# NOTE: IMDB_LCAPPS does share FILE_ID between HANA 1.0 and 2.0 so upgrade search is possible!
17+
#
1618
### Relationship validation workflow for IMDB_LCAPPS:
1719
# 1. Parse file name to extract version details.
1820
# 2. Attempt search in dry_run mode if 'sap_software_download_find_alternatives' is true and fail if file is not found.
@@ -23,6 +25,36 @@
2325
# 7. Show summary message and inform about validation result.
2426

2527

28+
# Validate wildcard format if wildcard is present in filename.
29+
# This is validated inside of module, but we do it here to fail faster and avoid unnecessary API calls.
30+
- name: SAP Software Download - Relationship Validation - Validate wildcard format in IMDB_LCAPPS filename
31+
ansible.builtin.fail:
32+
msg: |
33+
FAIL: Invalid wildcard format in IMDB_LCAPPS filename.
34+
35+
Filename: {{ __sap_software_download_fact_hana_component_names['lcapps'] }}
36+
37+
Wildcard queries must follow specific format:
38+
Format: "PREFIX*-ID.EXT" where:
39+
- PREFIX must have at least one character before wildcard
40+
- Wildcard (*) must be in PREFIX position only
41+
- Single dash (-) separates prefix and ID
42+
- ID must be exactly 8 digits
43+
- Extension must be letters only
44+
45+
Valid examples:
46+
- "IMDB_LCAPPS*-20010426.SAR"
47+
- "IMDB_LCAPPS_2*-20010426.SAR"
48+
49+
Invalid examples:
50+
- "*-20010426.SAR" (no prefix - too broad)
51+
- "IMDB_LCAPPS-*.SAR" (wildcard in ID position)
52+
- "IMDB_LCAPPS*X-20010426.SAR" (extra characters after wildcard)
53+
- "IMDB_LCAPPS*-7000.SAR" (ID must be 8 digits, not 4)
54+
when:
55+
- "'*' in __sap_software_download_fact_hana_component_names['lcapps']"
56+
- __sap_software_download_fact_hana_component_names['lcapps'] is not match('^[^-]+\\*-\\d{8}\\.[a-zA-Z]+$')
57+
2658
# Update existing fact dictionary with component details appending to 'server' details.
2759
# '__sap_software_download_fact_hana_lcapps_original' is set for later reuse, when we update this dictionary.
2860
- name: SAP Software Download - Relationship Validation - Set fact with parsed IMDB_LCAPPS file version details
@@ -55,37 +87,6 @@
5587
# Defines search type. Updated if alternative or update search is successful.
5688
source: exact
5789

58-
# Validate wildcard format if wildcard is present in filename.
59-
# This is validated inside of module, but we do it here to fail faster and avoid unnecessary API calls.
60-
- name: SAP Software Download - Relationship Validation - Validate wildcard format in IMDB_LCAPPS filename
61-
ansible.builtin.fail:
62-
msg: |
63-
FAIL: Invalid wildcard format in IMDB_LCAPPS filename.
64-
65-
Filename: {{ __sap_software_download_fact_hana_component_names['lcapps'] }}
66-
67-
Wildcard queries must follow specific format:
68-
Format: "PREFIX*-ID.EXT" where:
69-
- PREFIX must have at least one character before wildcard
70-
- Wildcard (*) must be in PREFIX position only
71-
- Single dash (-) separates prefix and ID
72-
- ID must be exactly 8 digits
73-
- Extension must be letters only
74-
75-
Valid examples:
76-
- "IMDB_LCAPPS*-20010426.SAR"
77-
- "IMDB_LCAPPS_2*-20010426.SAR"
78-
79-
Invalid examples:
80-
- "*-20010426.SAR" (no prefix - too broad)
81-
- "IMDB_LCAPPS-*.SAR" (wildcard in ID position)
82-
- "IMDB_LCAPPS*X-20010426.SAR" (extra characters after wildcard)
83-
- "IMDB_LCAPPS*-7000.SAR" (ID must be 8 digits, not 4)
84-
when:
85-
- "'*' in __sap_software_download_fact_hana_component_names['lcapps']"
86-
- __sap_software_download_fact_hana_component_names['lcapps'] is not match('^[^-]+\\*-\\d{8}\\.[a-zA-Z]+$')
87-
88-
# NOTE: IMDB_LCAPPS does share FILE_ID between HANA 1.0 and 2.0 so upgrade search is possible!
8990
- name: SAP Software Download - Relationship Validation - Fail if IMDB_LCAPPS is for wrong HANA version
9091
ansible.builtin.fail:
9192
msg: |
@@ -97,12 +98,20 @@
9798
{{ __sap_software_download_fact_hana_component_names['lcapps'] }} details:
9899
Version: {{ __sap_software_download_fact_hana_components['lcapps']['version'] }}
99100
100-
Please provide correct IMDB_LCAPPS file for the detected IMDB_SERVER version,
101-
or set the variable 'sap_software_download_upgrade_relationships' to 'true' to allow searching for upgrade candidate.
102-
when:
103-
- __sap_software_download_fact_hana_components['server']['version']
104-
!= __sap_software_download_fact_hana_components['lcapps']['version']
105-
- not sap_software_download_upgrade_relationships | d(false)
101+
Please provide correct IMDB_LCAPPS file for the detected IMDB_SERVER version.
102+
{% if '*' in __sap_software_download_fact_hana_component_names['lcapps'] %}
103+
Wildcard prefixes must contain identifier for HANA version to avoid mismatch. Examples:
104+
- HANA 1.0: 'IMDB_LCAPPS_1*-{{ __file_id_ext }}', 'IMDB_LCAPPS_122*-{{ __file_id_ext }}'
105+
- HANA 2.0: 'IMDB_LCAPPS_2*-{{ __file_id_ext }}', 'IMDB_LCAPPS_2089*-{{ __file_id_ext }}'
106+
{% else %}
107+
Expected prefixes:
108+
- HANA 1.0: 'IMDB_LCAPPS_1'
109+
- HANA 2.0: 'IMDB_LCAPPS_2'
110+
{% endif %}
111+
vars:
112+
__file_id_ext: "{{ __sap_software_download_fact_hana_components['lcapps']['file_id'] ~ '.SAR' }}"
113+
when: __sap_software_download_fact_hana_components['server']['version']
114+
!= __sap_software_download_fact_hana_components['lcapps']['version']
106115

107116

108117
- name: SAP Software Download - Relationship Validation - Check availability of IMDB_LCAPPS file using dry run

roles/sap_software_download/tasks/pre_steps/relationships/imdb_server.yml

Lines changed: 29 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
# - IMDB_SERVER20 - HANA 2.0 identifier
1515
# - 089 - Revision 89 (contains SPS level, e.g. SPS08)
1616
# - 3 - Patch level 3
17-
17+
#
1818
### Relationship validation workflow for IMDB_SERVER:
1919
# 1. Ensure that there are not multiple files for same component.
2020
# 2. Parse file name to extract version details.
@@ -74,34 +74,6 @@
7474
lcapps: "{{ __sap_software_download_files | select('match', '^IMDB_LCAPPS.*') | list | first | d('') }}"
7575
client: "{{ __sap_software_download_files | select('match', '^IMDB_CLIENT.*') | list | first | d('') }}"
7676

77-
78-
# Extract component details based on file name structure and enter into dictionary.
79-
- name: SAP Software Download - Relationship Validation - Set fact with parsed IMDB_SERVER file version details
80-
ansible.builtin.set_fact:
81-
__sap_software_download_fact_hana_components:
82-
server:
83-
filename: "{{ __sap_software_download_fact_hana_component_names['server'] }}"
84-
85-
# Extract HANA version from file name based on prefix, e.g. 1 or 2
86-
version:
87-
"{{ '1' if __sap_software_download_fact_hana_component_names['server'].startswith('IMDB_SERVER1')
88-
else ('2' if __sap_software_download_fact_hana_component_names['server'].startswith('IMDB_SERVER2') else '') }}"
89-
90-
# Extract revision from file name, e.g. IMDB_SERVER20_089_3-80002031.SAR -> 089
91-
revision: "{{ __sap_software_download_fact_hana_component_names['server'].split('_')[2] | d('') }}"
92-
93-
# Extract patch level from file name, e.g. IMDB_SERVER20_089_3-80002031.SAR -> 3
94-
patch: "{{ __sap_software_download_fact_hana_component_names['server'].split('_')[3].split('-')[0] | d('') }}"
95-
96-
# Extract File ID from file name, e.g. IMDB_SERVER20_089_3-80002031.SAR -> 80002031
97-
file_id: "{{ __sap_software_download_fact_hana_component_names['server'].split('-')[1].split('.')[0] | d('') }}"
98-
99-
# Defines search type. Updated if alternative or update search is successful.
100-
source: exact
101-
102-
# Save original file name to use when replacing in the list.
103-
__sap_software_download_fact_hana_server_original: "{{ __sap_software_download_fact_hana_component_names['server'] }}"
104-
10577
# Validate wildcard format if wildcard is present in filename
10678
# This is validated inside of module, but we do it here to fail faster and avoid unnecessary API calls.
10779
- name: SAP Software Download - Relationship Validation - Validate wildcard format in IMDB_SERVER filename
@@ -132,6 +104,33 @@
132104
- "'*' in __sap_software_download_fact_hana_component_names['server']"
133105
- __sap_software_download_fact_hana_component_names['server'] is not match('^[^-]+\\*-\\d{8}\\.[a-zA-Z]+$')
134106

107+
# Extract component details based on file name structure and enter into dictionary.
108+
- name: SAP Software Download - Relationship Validation - Set fact with parsed IMDB_SERVER file version details
109+
ansible.builtin.set_fact:
110+
__sap_software_download_fact_hana_components:
111+
server:
112+
filename: "{{ __sap_software_download_fact_hana_component_names['server'] }}"
113+
114+
# Extract HANA version from file name based on prefix, e.g. 1 or 2
115+
version:
116+
"{{ '1' if __sap_software_download_fact_hana_component_names['server'].startswith('IMDB_SERVER1')
117+
else ('2' if __sap_software_download_fact_hana_component_names['server'].startswith('IMDB_SERVER2') else '') }}"
118+
119+
# Extract revision from file name, e.g. IMDB_SERVER20_089_3-80002031.SAR -> 089
120+
revision: "{{ __sap_software_download_fact_hana_component_names['server'].split('_')[2] | d('') }}"
121+
122+
# Extract patch level from file name, e.g. IMDB_SERVER20_089_3-80002031.SAR -> 3
123+
patch: "{{ __sap_software_download_fact_hana_component_names['server'].split('_')[3].split('-')[0] | d('') }}"
124+
125+
# Extract File ID from file name, e.g. IMDB_SERVER20_089_3-80002031.SAR -> 80002031
126+
file_id: "{{ __sap_software_download_fact_hana_component_names['server'].split('-')[1].split('.')[0] | d('') }}"
127+
128+
# Defines search type. Updated if alternative or update search is successful.
129+
source: exact
130+
131+
# Save original file name to use when replacing in the list.
132+
__sap_software_download_fact_hana_server_original: "{{ __sap_software_download_fact_hana_component_names['server'] }}"
133+
135134

136135
# Combines both Python venv and default Python using environment variable.
137136
# Alternative search without 'search_upgrades' results in very strict search.
@@ -304,8 +303,7 @@
304303
Validation of IMDB_CLIENT file will be executed against this version.
305304
{% endif %}
306305
307-
NOTE: This validation does not ensure that same operating system version is used between components,
308-
it only checks HANA version based on file name structure!
306+
NOTE: See README.md for scope and limitations of relationship validation.
309307
310308
311309
# Execute component validations only when corresponding component file is found in the input list.

0 commit comments

Comments
 (0)