diff --git a/config/global.yml b/config/global.yml index 9bf7bb4..28c584e 100644 --- a/config/global.yml +++ b/config/global.yml @@ -27,7 +27,7 @@ GLOBAL: recoveryPolicy: 1 # 1/automatic, 2/manual syncSpeed: 2 # 1/low, 2/medium, 3/high, 4/highest syncType: 3 # 1/manual, 2/wait after last sync begin, 3/wait after last sync ends - interval: 60 # synchronize interval in seconds (10 ~ 86400) + interval: 30 # synchronize interval in seconds (10 ~ 86400) compress: False # enable compress for async replication: true, false timeout: 10 # synchronize remote I/O timeout threshold in seconds, default: 10, options: 10~30, or set to 255 to disable timeout syncRetries: 3600 # 5 hours @@ -83,19 +83,13 @@ DMDATASERVICE: # DeviceManager Data service configuratio DEFAULT: noneName: "NONE" noneValue: "__NONE__" - suffixDigits: 3 + suffixDigits: 4 LOGGING: - format: '[%(asctime)s] %(levelname)-5s - %(message)s' + format: '%(asctime)s - %(levelname)s - %(filename)s[:%(lineno)d] - %(message)s' datefmt: '%Y-%m-%d %H:%M:%S' level: 'DEBUG' - levelno: - CRITICAL: 50 - ERROR: 40 - WARNING: 30 - INFO: 20 - DEBUG: 10 - NOTSET: 0 + path: "/var/lib/rundeck/logs/data_service" DJSERVICE: API: diff --git a/playbook/storage/oceanstor/get_lgs_by_host.yml b/playbook/storage/oceanstor/get_lgs_by_host.yml new file mode 100644 index 0000000..b848de1 --- /dev/null +++ b/playbook/storage/oceanstor/get_lgs_by_host.yml @@ -0,0 +1,9 @@ +- name: Delete LUN Group + hosts: localhost + vars_files: + - ../../../config/global.yml + gather_facts: no + become: no + tasks: + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/login_storage.yml" + - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/get_lgs_by_host.yml" diff --git a/playbook/storage/oceanstor/get_luns_by_pg.yml b/playbook/storage/oceanstor/get_luns_by_pg.yml new file mode 100644 index 0000000..5bdbbe8 --- /dev/null +++ b/playbook/storage/oceanstor/get_luns_by_pg.yml @@ -0,0 +1,9 @@ +- name: Delete LUN Group + hosts: localhost + vars_files: + - ../../../config/global.yml + gather_facts: no + become: no + tasks: + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/login_storage.yml" + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/get_luns_by_pg.yml" \ No newline at end of file diff --git a/playbook/storage/oceanstor/get_snapshots_by_cg.yml b/playbook/storage/oceanstor/get_snapshots_by_cg.yml new file mode 100644 index 0000000..b9ae486 --- /dev/null +++ b/playbook/storage/oceanstor/get_snapshots_by_cg.yml @@ -0,0 +1,9 @@ +- name: Delete LUN Group + hosts: localhost + vars_files: + - ../../../config/global.yml + gather_facts: no + become: no + tasks: + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/login_storage.yml" + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/get_snapshots_by_cg.yml" \ No newline at end of file diff --git a/rundeck/jobs/project001/01_create_host.yaml b/rundeck/jobs/project001/01_create_host.yaml index 95a9dd2..5cb1900 100644 --- a/rundeck/jobs/project001/01_create_host.yaml +++ b/rundeck/jobs/project001/01_create_host.yaml @@ -69,7 +69,7 @@ valuesUrl: http://localhost:26336/rest/data/v1/echo?host=1.%20Create%20host:%20"${option.Country.value}_${option.OS_Type.value}_${option.Host_Name.value}_1"%20on%20storage:%20"${option.Storage.value}"&wwn=2.%20Add%20WWNs%20"${option.Host_WWN.value}"%20to%20host:%20"${option.Country.value}_${option.OS_Type.value}_${option.Host_Name.value}_1"&cluster=3.%20Add%20host%20"${option.Country.value}_${option.OS_Type.value}_${option.Host_Name.value}_1"%20to%20cluster:%20"${option.Cluster_Name.value}" description: Select to confirm primary host result

Protection Settings

- name: Session_Name - description: Input Session Name used for CGs (optional, max 16 chars, '_' not permitted, default is Primary Host Name) + description: Input Session Name used for CGs (optional, max 13 chars, '_' not permitted, default is Primary Host Name) - enforced: true name: Enable_HyperMetro value: 'N' diff --git a/rundeck/jobs/project001/03_modify_host_info.yaml b/rundeck/jobs/project001/03_modify_host_info.yaml index d1465b5..71eb3b8 100644 --- a/rundeck/jobs/project001/03_modify_host_info.yaml +++ b/rundeck/jobs/project001/03_modify_host_info.yaml @@ -67,7 +67,7 @@ name: Session_Name valuesUrl: http://localhost:26337/deviceManager/rest/${option.Storage.value}/data/v1/search/lungroup?range=[0-100]&nameAttr=DESCRIPTION:1&nameSplit=_&valueAttr=DESCRIPTION:1&valueSplit=_&filter=NAME::${option.LUN_Group.value} - name: Modify_Session_Name - description: Input New Session Name (start with {Country}0, max 19 chars, '_' not permitted)

Performance Class

+ description: Input New Session Name (start with {Country}0, max 16 chars, '_' not permitted)

Performance Class

- enforced: true name: Class_1 valuesUrl: http://localhost:26337/deviceManager/rest/${option.Storage.value}/data/v1/search/lungroup?range=[0-100]&nameAttr=DESCRIPTION:0:2:3&valueAttr=DESCRIPTION:0:2:3&filter=NAME::${option.LUN_Group.value} diff --git a/rundeck/jobs/project001/05_create_cluster.yaml b/rundeck/jobs/project001/05_create_cluster.yaml index c142ca9..1438712 100644 --- a/rundeck/jobs/project001/05_create_cluster.yaml +++ b/rundeck/jobs/project001/05_create_cluster.yaml @@ -62,7 +62,7 @@ valuesUrl: http://localhost:26336/rest/data/v1/echo?cluster=1.%20Create%20cluster:%20"${option.Country.value}_${option.OS_Type.value}_${option.Cluster_Name.value}_1"%20on%20storage:%20"${option.Storage.value}"&hosts=2.%20Add%20hosts%20"${option.Hosts.value}"%20to%20cluster:%20"${option.Country.value}_${option.OS_Type.value}_${option.Cluster_Name.value}_1" description: Select to confirm primary cluster result

Protection Settings

- name: Session_Name - description: Input Session Name used for grouping (optional, max 16 chars, '_' not permitted, default is Primary Cluster Name) + description: Input Session Name used for grouping (optional, max 13 chars, '_' not permitted, default is Primary Cluster Name) - enforced: true name: Enable_HyperMetro value: 'N' diff --git a/rundeck/jobs/project001/07_modify_cluster_info.yaml b/rundeck/jobs/project001/07_modify_cluster_info.yaml index 20156b6..4f17229 100644 --- a/rundeck/jobs/project001/07_modify_cluster_info.yaml +++ b/rundeck/jobs/project001/07_modify_cluster_info.yaml @@ -70,7 +70,7 @@ name: Session_Name valuesUrl: http://localhost:26337/deviceManager/rest/${option.Storage.value}/data/v1/search/lungroup?range=[0-100]&nameAttr=DESCRIPTION:1&nameSplit=_&valueAttr=DESCRIPTION:1&valueSplit=_&filter=NAME::${option.LUN_Group.value} - name: Modify_Session_Name - description: Input New Session Name (start with {Country}0, max 19 chars, '_' not permitted)

Performance Class

+ description: Input New Session Name (start with {Country}0, max 16 chars, '_' not permitted)

Performance Class

- enforced: true name: Class_1 valuesUrl: http://localhost:26337/deviceManager/rest/${option.Storage.value}/data/v1/search/lungroup?range=[0-100]&nameAttr=DESCRIPTION:0:2:3&valueAttr=DESCRIPTION:0:2:3&filter=NAME::${option.LUN_Group.value} @@ -225,12 +225,12 @@ Modify_DR_Cluster_Description: ${option.Modify_DR_Cluster_Description} Class_2: ${option.Class_2} Modify_Class_2: ${option.Modify_Class_2} - Check_Result_3: ${option.Check_Result_2} + Check_Result_3: ${option.Check_Result_3} DR_Test_Cluster: ${option.DR_Test_Cluster} Class_3: ${option.Class_3} Modify_Class_3: ${option.Modify_Class_3} - Check_Result_4: ${option.Check_Result_3} + Check_Result_4: ${option.Check_Result_4} Protection_Group: ${option.Protection_Group} Metro_CG: ${option.Metro_CG} diff --git a/rundeck/jobs/project001/09_create_luns_for_host.yaml b/rundeck/jobs/project001/09_create_luns_for_host.yaml index 7384826..4d40732 100644 --- a/rundeck/jobs/project001/09_create_luns_for_host.yaml +++ b/rundeck/jobs/project001/09_create_luns_for_host.yaml @@ -55,7 +55,7 @@ - delimiter: '|' multivalued: true name: LUN_Description - description: Add LUN Description (optional, max 200 chars for all items, '|' and '_' not permitted) + description: Add LUN Description (optional, max 255 chars for all items, '|' and '_' not permitted) - enforced: true name: Pool valuesUrl: http://localhost:26337/deviceManager/rest/${option.Storage.value}/data/v1/search/storagepool?nameAttr=NAME&valueAttr=ID @@ -221,6 +221,8 @@ WBE_CODE: ${option.WBE_CODE} TICKET_NUMBER: ${option.TICKET_NUMBER} Country: ${option.Country} + Job_User: ${job.user.name} + Host: ${option.Host} Storage: ${option.Storage} Storage_Room: ${option.Storage_Room} diff --git a/rundeck/jobs/project001/10_map_luns_to_host.yaml b/rundeck/jobs/project001/10_map_luns_to_host.yaml index 111d3a6..c233a2a 100644 --- a/rundeck/jobs/project001/10_map_luns_to_host.yaml +++ b/rundeck/jobs/project001/10_map_luns_to_host.yaml @@ -220,6 +220,8 @@ WBE_CODE: ${option.WBE_CODE} TICKET_NUMBER: ${option.TICKET_NUMBER} Country: ${option.Country} + Job_User: ${job.user.name} + Host: ${option.Host} Storage: ${option.Storage} Storage_Room: ${option.Storage_Room} diff --git a/rundeck/jobs/project001/11_unmap_luns_from_host.yaml b/rundeck/jobs/project001/11_unmap_luns_from_host.yaml index e9327f5..8e70352 100644 --- a/rundeck/jobs/project001/11_unmap_luns_from_host.yaml +++ b/rundeck/jobs/project001/11_unmap_luns_from_host.yaml @@ -182,6 +182,9 @@ WBE_CODE: ${option.WBE_CODE} TICKET_NUMBER: ${option.TICKET_NUMBER} + Country: ${option.Country} + Job_User: ${job.user.name} + Host: ${option.Host} Storage: ${option.Storage} Storage_Room: ${option.Storage_Room} diff --git a/rundeck/jobs/project001/13_create_luns_for_cluster.yaml b/rundeck/jobs/project001/13_create_luns_for_cluster.yaml index 9d3487e..a371505 100644 --- a/rundeck/jobs/project001/13_create_luns_for_cluster.yaml +++ b/rundeck/jobs/project001/13_create_luns_for_cluster.yaml @@ -58,7 +58,7 @@ - delimiter: '|' multivalued: true name: LUN_Description - description: Add LUN Description (optional, max 200 chars for all items, '|' and '_' not permitted) + description: Add LUN Description (optional, max 255 chars for all items, '|' and '_' not permitted) - enforced: true name: Pool valuesUrl: http://localhost:26337/deviceManager/rest/${option.Storage.value}/data/v1/search/storagepool?nameAttr=NAME&valueAttr=ID @@ -224,6 +224,8 @@ WBE_CODE: ${option.WBE_CODE} TICKET_NUMBER: ${option.TICKET_NUMBER} Country: ${option.Country} + Job_User: ${job.user.name} + Cluster: ${option.Cluster} Storage: ${option.Storage} Storage_Room: ${option.Storage_Room} diff --git a/rundeck/jobs/project001/14_map_luns_to_cluster.yaml b/rundeck/jobs/project001/14_map_luns_to_cluster.yaml index a029385..5b97054 100644 --- a/rundeck/jobs/project001/14_map_luns_to_cluster.yaml +++ b/rundeck/jobs/project001/14_map_luns_to_cluster.yaml @@ -223,6 +223,8 @@ WBE_CODE: ${option.WBE_CODE} TICKET_NUMBER: ${option.TICKET_NUMBER} Country: ${option.Country} + Job_User: ${job.user.name} + Cluster: ${option.Cluster} Storage: ${option.Storage} Storage_Room: ${option.Storage_Room} diff --git a/rundeck/jobs/project001/15_unmap_luns_from_cluster.yaml b/rundeck/jobs/project001/15_unmap_luns_from_cluster.yaml index 9a0ce92..e3f50b7 100644 --- a/rundeck/jobs/project001/15_unmap_luns_from_cluster.yaml +++ b/rundeck/jobs/project001/15_unmap_luns_from_cluster.yaml @@ -185,6 +185,9 @@ WBE_CODE: ${option.WBE_CODE} TICKET_NUMBER: ${option.TICKET_NUMBER} + Country: ${option.Country} + Job_User: ${job.user.name} + Cluster: ${option.Cluster} Storage: ${option.Storage} Storage_Room: ${option.Storage_Room} diff --git a/rundeck/jobs/project001/16_delete_lun.yaml b/rundeck/jobs/project001/16_delete_lun.yaml index cf7a80a..bd2d640 100644 --- a/rundeck/jobs/project001/16_delete_lun.yaml +++ b/rundeck/jobs/project001/16_delete_lun.yaml @@ -62,6 +62,9 @@ WBE_CODE: ${option.WBE_CODE} TICKET_NUMBER: ${option.TICKET_NUMBER} + Country: ${option.Country} + Job_User: ${job.user.name} + Select_LUN: ${option.Select_LUN} Upload_LUN: ${file.Upload_LUN} Delimiter: "${option.Delimiter}" diff --git a/rundeck/jobs/project001/17_change_class.yaml b/rundeck/jobs/project001/17_change_class.yaml index 464c087..8e595c3 100644 --- a/rundeck/jobs/project001/17_change_class.yaml +++ b/rundeck/jobs/project001/17_change_class.yaml @@ -55,6 +55,9 @@ ansible-extra-vars: |- WBE_CODE: ${option.WBE_CODE} TICKET_NUMBER: ${option.TICKET_NUMBER} + Country: ${option.Country} + Job_User: ${job.user.name} + Select_LUN: ${option.Select_LUN} Upload_LUN: ${file.Upload_LUN} Delimiter: "${option.Delimiter}" diff --git a/rundeck/jobs/project001/18_remove_class.yaml b/rundeck/jobs/project001/18_remove_class.yaml index 0c06519..78138ab 100644 --- a/rundeck/jobs/project001/18_remove_class.yaml +++ b/rundeck/jobs/project001/18_remove_class.yaml @@ -57,6 +57,9 @@ ansible-extra-vars: |- WBE_CODE: ${option.WBE_CODE} TICKET_NUMBER: ${option.TICKET_NUMBER} + Country: ${option.Country} + Job_User: ${job.user.name} + Select_LUN: ${option.Select_LUN} Upload_LUN: ${file.Upload_LUN} Delimiter: "${option.Delimiter}" diff --git a/rundeck/jobs/project001/21_create_luns.yaml b/rundeck/jobs/project001/21_create_luns.yaml index 214f6d4..239f822 100644 --- a/rundeck/jobs/project001/21_create_luns.yaml +++ b/rundeck/jobs/project001/21_create_luns.yaml @@ -49,7 +49,7 @@ type: file - name: Delimiter value: ',' - - description: Maximum 28 characters, LUN naming convension is {COUNTRY:2} _ {OS:3} _ {HOST:16} _ {CHAIN:1} _ {PROTECT:1}{TYPE:1}{Suffix:3} + - description: Maximum 28 characters, LUN naming convension is {COUNTRY:2} _ {OS:3} _ {HOST:16} _ {CHAIN:1} _ {PROTECT:1}{TYPE:1}{Suffix:4} name: LUN_Prefix - name: Start_Suffix value: 0 @@ -60,7 +60,7 @@ - delimiter: '|' multivalued: true name: LUN_Description - description: Add LUN Description (optional, max 200 chars for all items, '|' and '_' not permitted) + description: Add LUN Description (optional, max 255 chars for all items, '|' and '_' not permitted) scheduleEnabled: true sequence: commands: @@ -73,6 +73,8 @@ WBE_CODE: ${option.WBE_CODE} TICKET_NUMBER: ${option.TICKET_NUMBER} + Job_User: ${job.user.name} + Site: ${option.Site} Room: ${option.Room} Storage: ${option.Storage} diff --git a/rundeck/jobs/project001/23_resize_luns_for_host.yaml b/rundeck/jobs/project001/23_resize_luns_for_host.yaml index e14b274..5095809 100644 --- a/rundeck/jobs/project001/23_resize_luns_for_host.yaml +++ b/rundeck/jobs/project001/23_resize_luns_for_host.yaml @@ -173,6 +173,9 @@ WBE_CODE: ${option.WBE_CODE} TICKET_NUMBER: ${option.TICKET_NUMBER} + Country: ${option.Country} + Job_User: ${job.user.name} + Host: ${option.Host} Storage: ${option.Storage} Storage_Room: ${option.Storage_Room} diff --git a/rundeck/jobs/project001/24_resize_luns_for_cluster.yaml b/rundeck/jobs/project001/24_resize_luns_for_cluster.yaml index 4f562e1..0d0435b 100644 --- a/rundeck/jobs/project001/24_resize_luns_for_cluster.yaml +++ b/rundeck/jobs/project001/24_resize_luns_for_cluster.yaml @@ -176,6 +176,9 @@ WBE_CODE: ${option.WBE_CODE} TICKET_NUMBER: ${option.TICKET_NUMBER} + Country: ${option.Country} + Job_User: ${job.user.name} + Cluster: ${option.Cluster} Storage: ${option.Storage} Storage_Room: ${option.Storage_Room} diff --git a/rundeck/jobs/project001/25_create_snapshots_for_host.yaml b/rundeck/jobs/project001/25_create_snapshots_for_host.yaml index 8cf3224..842f11f 100644 --- a/rundeck/jobs/project001/25_create_snapshots_for_host.yaml +++ b/rundeck/jobs/project001/25_create_snapshots_for_host.yaml @@ -70,7 +70,7 @@ - delimiter: '|' multivalued: true name: Snapshot_Description - description: Add Snapshot Description (optional, max 200 chars for all items, '|' and '_' not permitted) + description: Add Snapshot Description (optional, max 255 chars for all items, '|' and '_' not permitted) - enforced: true name: Class_1 valuesUrl: http://localhost:26337/deviceManager/rest/${option.Storage.value}/data/v1/search/lungroup?range=[0-100]&nameAttr=DESCRIPTION:0:2:3&valueAttr=DESCRIPTION:0:2:3&filter=NAME::${option.Target_LUN_Group.value} @@ -106,6 +106,8 @@ WBE_CODE: ${option.WBE_CODE} TICKET_NUMBER: ${option.TICKET_NUMBER} Country: ${option.Country} + Job_User: ${job.user.name} + Target_Host: ${option.Target_Host} Target_LUN_Group: ${option.Target_LUN_Group} Target_HyperMetro: ${option.Target_HyperMetro} diff --git a/rundeck/jobs/project001/26_change_snapshots_for_host.yaml b/rundeck/jobs/project001/26_change_snapshots_for_host.yaml index 43cea67..9761ac0 100644 --- a/rundeck/jobs/project001/26_change_snapshots_for_host.yaml +++ b/rundeck/jobs/project001/26_change_snapshots_for_host.yaml @@ -107,6 +107,8 @@ WBE_CODE: ${option.WBE_CODE} TICKET_NUMBER: ${option.TICKET_NUMBER} Country: ${option.Country} + Job_User: ${job.user.name} + Target_Host: ${option.Target_Host} Target_LUN_Group: ${option.Target_LUN_Group} Storage: ${option.Storage} diff --git a/rundeck/jobs/project001/27_create_snapshots_for_cluster.yaml b/rundeck/jobs/project001/27_create_snapshots_for_cluster.yaml index 1a40c4f..34e6f0a 100644 --- a/rundeck/jobs/project001/27_create_snapshots_for_cluster.yaml +++ b/rundeck/jobs/project001/27_create_snapshots_for_cluster.yaml @@ -76,7 +76,7 @@ - delimiter: '|' multivalued: true name: Snapshot_Description - description: Add Snapshot Description (optional, max 200 chars for all items, '|' and '_' not permitted) + description: Add Snapshot Description (optional, max 255 chars for all items, '|' and '_' not permitted) - enforced: true name: Class_1 valuesUrl: http://localhost:26337/deviceManager/rest/${option.Storage.value}/data/v1/search/lungroup?range=[0-100]&nameAttr=DESCRIPTION:0:2:3&valueAttr=DESCRIPTION:0:2:3&filter=NAME::${option.Target_LUN_Group.value} @@ -112,6 +112,8 @@ WBE_CODE: ${option.WBE_CODE} TICKET_NUMBER: ${option.TICKET_NUMBER} Country: ${option.Country} + Job_User: ${job.user.name} + Target_Cluster: ${option.Target_Cluster} Target_LUN_Group: ${option.Target_LUN_Group} Target_HyperMetro: ${option.Target_HyperMetro} diff --git a/rundeck/jobs/project001/28_change_snapshots_for_cluster.yaml b/rundeck/jobs/project001/28_change_snapshots_for_cluster.yaml index c2e094c..7d5e8a2 100644 --- a/rundeck/jobs/project001/28_change_snapshots_for_cluster.yaml +++ b/rundeck/jobs/project001/28_change_snapshots_for_cluster.yaml @@ -110,6 +110,8 @@ WBE_CODE: ${option.WBE_CODE} TICKET_NUMBER: ${option.TICKET_NUMBER} Country: ${option.Country} + Job_User: ${job.user.name} + Target_Cluster: ${option.Target_Cluster} Target_LUN_Group: ${option.Target_LUN_Group} Storage: ${option.Storage} diff --git a/rundeck/jobs/project001/29_dr_test_for_host.yaml b/rundeck/jobs/project001/29_dr_test_for_host.yaml index 9fa8795..a9c8494 100644 --- a/rundeck/jobs/project001/29_dr_test_for_host.yaml +++ b/rundeck/jobs/project001/29_dr_test_for_host.yaml @@ -85,7 +85,7 @@ valuesUrl: http://localhost:26337/deviceManager/rest/${option.DR_Storage.value}/data/v1/search/protectgroup?nameAttr=protectGroupName&valueAttr=protectGroupName&range=[0-100]&filter=lunGroupId::${option.DR_LUN_Group_ID.value} - enforced: true name: DR_CG - valuesUrl: http://localhost:26337/deviceManager/rest/${option.DR_Storage.value}/data/v1/search/CONSISTENTGROUP?nameAttr=NAME&valueAttr=NAME&range=[0-100]&filter=localPgName::${option.DR_Protection_Group.value}%20and%20RUNNINGSTATUS::1 + valuesUrl: http://localhost:26337/deviceManager/rest/${option.DR_Storage.value}/data/v1/search/CONSISTENTGROUP?nameAttr=NAME&valueAttr=NAME&range=[0-100]&filter=localPgName::${option.DR_Protection_Group.value} - enforced: true name: DR_Test_CG_ID valuesUrl: http://localhost:26337/deviceManager/rest/${option.DR_Storage.value}/data/v1/search/snapshot_consistency_group?nameAttr=ID&valueAttr=ID&filter=NAME::${option.DR_Test_CG.value} @@ -104,6 +104,9 @@ WBE_CODE: ${option.WBE_CODE} TICKET_NUMBER: ${option.TICKET_NUMBER} + Country: ${option.Country} + Job_User: ${job.user.name} + DR_Host: ${option.DR_Host} DR_Test_Host: ${option.DR_Test_Host} DR_Storage: ${option.DR_Storage} diff --git a/rundeck/jobs/project001/30_dr_test_clean_for_host.yaml b/rundeck/jobs/project001/30_dr_test_clean_for_host.yaml index 6fd4131..6a243b6 100644 --- a/rundeck/jobs/project001/30_dr_test_clean_for_host.yaml +++ b/rundeck/jobs/project001/30_dr_test_clean_for_host.yaml @@ -80,7 +80,7 @@ valuesUrl: http://localhost:26337/deviceManager/rest/${option.DR_Storage.value}/data/v1/search/protectgroup?nameAttr=protectGroupName&valueAttr=protectGroupName&range=[0-100]&filter=lunGroupId::${option.DR_LUN_Group_ID.value} - enforced: true name: DR_CG - valuesUrl: http://localhost:26337/deviceManager/rest/${option.DR_Storage.value}/data/v1/search/CONSISTENTGROUP?nameAttr=NAME&valueAttr=NAME&range=[0-100]&filter=localPgName::${option.DR_Protection_Group.value}%20and%20RUNNINGSTATUS::1 + valuesUrl: http://localhost:26337/deviceManager/rest/${option.DR_Storage.value}/data/v1/search/CONSISTENTGROUP?nameAttr=NAME&valueAttr=NAME&range=[0-100]&filter=localPgName::${option.DR_Protection_Group.value} - enforced: true name: DR_Test_CG_ID valuesUrl: http://localhost:26337/deviceManager/rest/${option.DR_Storage.value}/data/v1/search/snapshot_consistency_group?nameAttr=ID&valueAttr=ID&filter=NAME::${option.DR_Test_CG.value} @@ -102,6 +102,9 @@ WBE_CODE: ${option.WBE_CODE} TICKET_NUMBER: ${option.TICKET_NUMBER} + Country: ${option.Country} + Job_User: ${job.user.name} + DR_Host: ${option.DR_Host} DR_Test_Host: ${option.DR_Test_Host} DR_Storage: ${option.DR_Storage} diff --git a/rundeck/jobs/project001/31_dr_test_for_cluster.yaml b/rundeck/jobs/project001/31_dr_test_for_cluster.yaml index 7ef9bfd..c81b366 100644 --- a/rundeck/jobs/project001/31_dr_test_for_cluster.yaml +++ b/rundeck/jobs/project001/31_dr_test_for_cluster.yaml @@ -88,7 +88,7 @@ valuesUrl: http://localhost:26337/deviceManager/rest/${option.DR_Storage.value}/data/v1/search/protectgroup?nameAttr=protectGroupName&valueAttr=protectGroupName&range=[0-100]&filter=lunGroupId::${option.DR_LUN_Group_ID.value} - enforced: true name: DR_CG - valuesUrl: http://localhost:26337/deviceManager/rest/${option.DR_Storage.value}/data/v1/search/CONSISTENTGROUP?nameAttr=NAME&valueAttr=NAME&range=[0-100]&filter=localPgName::${option.DR_Protection_Group.value}%20and%20RUNNINGSTATUS::1 + valuesUrl: http://localhost:26337/deviceManager/rest/${option.DR_Storage.value}/data/v1/search/CONSISTENTGROUP?nameAttr=NAME&valueAttr=NAME&range=[0-100]&filter=localPgName::${option.DR_Protection_Group.value} - enforced: true name: DR_Test_CG_ID valuesUrl: http://localhost:26337/deviceManager/rest/${option.DR_Storage.value}/data/v1/search/snapshot_consistency_group?nameAttr=ID&valueAttr=ID&filter=NAME::${option.DR_Test_CG.value} @@ -107,6 +107,9 @@ WBE_CODE: ${option.WBE_CODE} TICKET_NUMBER: ${option.TICKET_NUMBER} + Country: ${option.Country} + Job_User: ${job.user.name} + DR_Cluster: ${option.DR_Cluster} DR_Test_Cluster: ${option.DR_Test_Cluster} DR_Storage: ${option.DR_Storage} diff --git a/rundeck/jobs/project001/32_dr_test_clean_for_cluster.yaml b/rundeck/jobs/project001/32_dr_test_clean_for_cluster.yaml index 07979ae..be8e312 100644 --- a/rundeck/jobs/project001/32_dr_test_clean_for_cluster.yaml +++ b/rundeck/jobs/project001/32_dr_test_clean_for_cluster.yaml @@ -83,7 +83,7 @@ valuesUrl: http://localhost:26337/deviceManager/rest/${option.DR_Storage.value}/data/v1/search/protectgroup?nameAttr=protectGroupName&valueAttr=protectGroupName&range=[0-100]&filter=lunGroupId::${option.DR_LUN_Group_ID.value} - enforced: true name: DR_CG - valuesUrl: http://localhost:26337/deviceManager/rest/${option.DR_Storage.value}/data/v1/search/CONSISTENTGROUP?nameAttr=NAME&valueAttr=NAME&range=[0-100]&filter=localPgName::${option.DR_Protection_Group.value}%20and%20RUNNINGSTATUS::1 + valuesUrl: http://localhost:26337/deviceManager/rest/${option.DR_Storage.value}/data/v1/search/CONSISTENTGROUP?nameAttr=NAME&valueAttr=NAME&range=[0-100]&filter=localPgName::${option.DR_Protection_Group.value} - enforced: true name: DR_Test_CG_ID valuesUrl: http://localhost:26337/deviceManager/rest/${option.DR_Storage.value}/data/v1/search/snapshot_consistency_group?nameAttr=ID&valueAttr=ID&filter=NAME::${option.DR_Test_CG.value} @@ -105,6 +105,9 @@ WBE_CODE: ${option.WBE_CODE} TICKET_NUMBER: ${option.TICKET_NUMBER} + Country: ${option.Country} + Job_User: ${job.user.name} + DR_Cluster: ${option.DR_Cluster} DR_Test_Cluster: ${option.DR_Test_Cluster} DR_Storage: ${option.DR_Storage} diff --git a/rundeck/jobs/project001/33_add_lun_group_to_host.yaml b/rundeck/jobs/project001/33_add_lun_group_to_host.yaml index c5559fe..60b10c1 100644 --- a/rundeck/jobs/project001/33_add_lun_group_to_host.yaml +++ b/rundeck/jobs/project001/33_add_lun_group_to_host.yaml @@ -42,7 +42,7 @@ valuesUrl: http://localhost:26336/rest/data/v1/search/tier?valueAttr=name - name: Session_Name required: true - description: Input Session Name used for CGs (max 16 chars, '_' not permitted) + description: Input Session Name used for CGs (max 13 chars, '_' not permitted) - enforced: true name: Enable_HyperMetro value: 'N' diff --git a/rundeck/jobs/project001/35_add_lun_group_to_cluster.yaml b/rundeck/jobs/project001/35_add_lun_group_to_cluster.yaml index b8e6da4..9c67dcd 100644 --- a/rundeck/jobs/project001/35_add_lun_group_to_cluster.yaml +++ b/rundeck/jobs/project001/35_add_lun_group_to_cluster.yaml @@ -43,7 +43,7 @@ name: Class_1 required: true valuesUrl: http://localhost:26336/rest/data/v1/search/tier?valueAttr=name - - description: Input Session Name used for CGs (max 16 chars, '_' not permitted) + - description: Input Session Name used for CGs (max 13 chars, '_' not permitted) name: Session_Name required: true - enforced: true diff --git a/rundeck/jobs/project001/37_add_replica_host.yaml b/rundeck/jobs/project001/37_add_replica_host.yaml index f5c99f4..c07b11c 100644 --- a/rundeck/jobs/project001/37_add_replica_host.yaml +++ b/rundeck/jobs/project001/37_add_replica_host.yaml @@ -175,6 +175,8 @@ WBE_CODE: ${option.WBE_CODE} TICKET_NUMBER: ${option.TICKET_NUMBER} Country: ${option.Country} + Job_User: ${job.user.name} + OS_Type: ${option.OS_Type} Host: ${option.Host} Storage: ${option.Storage} diff --git a/rundeck/jobs/project001/38_add_drtest_host.yaml b/rundeck/jobs/project001/38_add_drtest_host.yaml index 5b2f2ec..0048bba 100644 --- a/rundeck/jobs/project001/38_add_drtest_host.yaml +++ b/rundeck/jobs/project001/38_add_drtest_host.yaml @@ -151,6 +151,8 @@ WBE_CODE: ${option.WBE_CODE} TICKET_NUMBER: ${option.TICKET_NUMBER} Country: ${option.Country} + Job_User: ${job.user.name} + OS_Type: ${option.OS_Type} Host: ${option.Host} Storage: ${option.Storage} diff --git a/rundeck/jobs/project001/39_add_metro_host.yaml b/rundeck/jobs/project001/39_add_metro_host.yaml index 25b4f57..31df750 100644 --- a/rundeck/jobs/project001/39_add_metro_host.yaml +++ b/rundeck/jobs/project001/39_add_metro_host.yaml @@ -151,6 +151,8 @@ WBE_CODE: ${option.WBE_CODE} TICKET_NUMBER: ${option.TICKET_NUMBER} Country: ${option.Country} + Job_User: ${job.user.name} + OS_Type: ${option.OS_Type} Host: ${option.Host} Storage: ${option.Storage} diff --git a/rundeck/jobs/project001/40_remove_replica_host.yaml b/rundeck/jobs/project001/40_remove_replica_host.yaml index 056f8f6..68fcb87 100644 --- a/rundeck/jobs/project001/40_remove_replica_host.yaml +++ b/rundeck/jobs/project001/40_remove_replica_host.yaml @@ -190,6 +190,8 @@ WBE_CODE: ${option.WBE_CODE} TICKET_NUMBER: ${option.TICKET_NUMBER} Country: ${option.Country} + Job_User: ${job.user.name} + OS_Type: ${option.OS_Type} Host: ${option.Host} Storage: ${option.Storage} diff --git a/rundeck/jobs/project001/41_add_replica_cluster.yaml b/rundeck/jobs/project001/41_add_replica_cluster.yaml index b19d8b3..b70516c 100644 --- a/rundeck/jobs/project001/41_add_replica_cluster.yaml +++ b/rundeck/jobs/project001/41_add_replica_cluster.yaml @@ -177,6 +177,8 @@ WBE_CODE: ${option.WBE_CODE} TICKET_NUMBER: ${option.TICKET_NUMBER} Country: ${option.Country} + Job_User: ${job.user.name} + OS_Type: ${option.OS_Type} Cluster: ${option.Cluster} Storage: ${option.Storage} diff --git a/rundeck/jobs/project001/42_add_drtest_cluster.yaml b/rundeck/jobs/project001/42_add_drtest_cluster.yaml index 56b9aa1..fc869af 100644 --- a/rundeck/jobs/project001/42_add_drtest_cluster.yaml +++ b/rundeck/jobs/project001/42_add_drtest_cluster.yaml @@ -156,6 +156,8 @@ WBE_CODE: ${option.WBE_CODE} TICKET_NUMBER: ${option.TICKET_NUMBER} Country: ${option.Country} + Job_User: ${job.user.name} + OS_Type: ${option.OS_Type} Cluster: ${option.Cluster} Storage: ${option.Storage} diff --git a/rundeck/jobs/project001/43_add_metro_cluster.yaml b/rundeck/jobs/project001/43_add_metro_cluster.yaml index d92baa4..a095adc 100644 --- a/rundeck/jobs/project001/43_add_metro_cluster.yaml +++ b/rundeck/jobs/project001/43_add_metro_cluster.yaml @@ -156,6 +156,8 @@ WBE_CODE: ${option.WBE_CODE} TICKET_NUMBER: ${option.TICKET_NUMBER} Country: ${option.Country} + Job_User: ${job.user.name} + OS_Type: ${option.OS_Type} Cluster: ${option.Cluster} Storage: ${option.Storage} diff --git a/rundeck/jobs/project001/44_remove_replica_cluster.yaml b/rundeck/jobs/project001/44_remove_replica_cluster.yaml index 42902ff..e15174e 100644 --- a/rundeck/jobs/project001/44_remove_replica_cluster.yaml +++ b/rundeck/jobs/project001/44_remove_replica_cluster.yaml @@ -193,6 +193,8 @@ WBE_CODE: ${option.WBE_CODE} TICKET_NUMBER: ${option.TICKET_NUMBER} Country: ${option.Country} + Job_User: ${job.user.name} + OS_Type: ${option.OS_Type} Cluster: ${option.Cluster} Storage: ${option.Storage} diff --git a/rundeck/jobs/project001/45_migrate_host.yaml b/rundeck/jobs/project001/45_migrate_host.yaml index 2cd47ff..d189312 100644 --- a/rundeck/jobs/project001/45_migrate_host.yaml +++ b/rundeck/jobs/project001/45_migrate_host.yaml @@ -83,6 +83,8 @@ WBE_CODE: ${option.WBE_CODE} TICKET_NUMBER: ${option.TICKET_NUMBER} Country: ${option.Country} + Job_User: ${job.user.name} + OS_Type: ${option.OS_Type} Host: ${option.Host} Storage: ${option.Storage} diff --git a/rundeck/jobs/project001/46_migrate_cluster.yaml b/rundeck/jobs/project001/46_migrate_cluster.yaml index 63bff61..9dc7a0f 100644 --- a/rundeck/jobs/project001/46_migrate_cluster.yaml +++ b/rundeck/jobs/project001/46_migrate_cluster.yaml @@ -88,6 +88,8 @@ WBE_CODE: ${option.WBE_CODE} TICKET_NUMBER: ${option.TICKET_NUMBER} Country: ${option.Country} + Job_User: ${job.user.name} + OS_Type: ${option.OS_Type} Cluster: ${option.Cluster} Storage: ${option.Storage} diff --git a/rundeck/jobs/project001/49_create_pg.yaml b/rundeck/jobs/project001/49_create_pg.yaml new file mode 100644 index 0000000..b79bf12 --- /dev/null +++ b/rundeck/jobs/project001/49_create_pg.yaml @@ -0,0 +1,157 @@ +- defaultTab: monitor + description: Create Protection Group with Replication CG, and HyperMetro CG + executionEnabled: true + id: 34533a0b-9a0b-4229-852e-4c5f57971024 + loglevel: INFO + name: 49_create_pg + nodeFilterEditable: false + options: + - name: Job_Description + value: Create Protection Group with Replication CG, and HyperMetro CG + description: Create Protection Group + - name: Username + valuesUrl: http://localhost:26336/rest/data/v1/echo?${job.user.name}=${job.user.name} + description: (Optional) Alternative username/password to login all storage + - name: Password + secure: true + valueExposed: true + description:

Country, OS Type and Location

+ - enforced: true + name: Country + required: true + valuesUrl: http://localhost:26336/rest/data/v1/search/project?pageNo=1&pageSize=100&valueAttr=name + - enforced: true + name: OS_Type + required: true + valuesUrl: http://localhost:26336/rest/data/v1/enum/OSTYPE?nameAttr=desc&valueAttr=key&filter={"enable":1} + - enforced: true + name: Site + required: true + valuesUrl: http://localhost:26336/rest/data/v1/enum/DC?nameAttr=desc&valueAttr=key + description:

Protection Settings

+ - name: Session_Name + description: Input Session Name used for CGs (optional, max 13 chars, '_' not permitted) + required: true + - enforced: true + name: Enable_HyperMetro + value: 'N' + required: true + values: + - 'N' + - 'Y' + - enforced: true + name: Protection_Level + value: '1' + required: true + values: + - '1' + - '2' + - '3' + - enforced: true + name: DR_Sync_Mode + required: true + valuesUrl: http://localhost:26336/rest/data/v1/enum/REPMODE?nameAttr=desc&valueAttr=enum + description:

Primary Protection Group

+ - enforced: true + name: Primary_Storage_Room + required: true + valuesUrl: http://localhost:26336/rest/data/v1/enum/AZ?nameAttr=desc&valueAttr=key&filter={"dc":"${option.Site.value}"} + - enforced: true + name: Primary_Storage + required: true + valuesUrl: http://localhost:26336/rest/data/v1/join/storage?pageNo=1&pageSize=100&nameAttr=deviceName&valueAttr=sn&condition={"constraint":[{"logOp":"and","simple":{"name":"dataStatus","operator":"equal","value":"normal"}}]}&relations=[{"obj":"az","condition":{"constraint":[{"logOp":"and","simple":{"name":"name","operator":"equal","value":"${option.Primary_Storage_Room.value}"}}]}}] + - delimiter: ',' + enforced: true + multivalued: true + name: Check_Result_1 + required: true + valuesUrl: http://localhost:26336/rest/data/v1/echo?pg=1.%20Create%20primary%20protect%20group:%20"${option.Country.value}0${option.Session_Name.value}_1"%20on%20storage:%20"${option.Primary_Storage.value}" + description: Select to confirm primary Protection group result

Metro Protection Group

+ - name: Metro_Storage + valuesUrl: http://localhost:26337/deviceManager/rest/${option.Primary_Storage.value}/data/v1/search/HyperMetroDomain?range=[0-100]&nameAttr=REMOTEDEVICES:11&nameSplit=%22&valueAttr=REMOTEDEVICES:7&valueSplit=%22 + - enforced: true + name: Metro_Storage_Room + valuesUrl: http://localhost:26336/rest/data/v1/join/az?pageNo=1&pageSize=100&nameAttr=name&valueAttr=name&relations=[{"obj":"storage","condition":{"constraint":[{"logOp":"and","simple":{"name":"sn","operator":"equal","value":"${option.Metro_Storage.value}"}}]}}] + - delimiter: ',' + enforced: true + multivalued: true + name: Check_Result_2 + valuesUrl: http://localhost:26336/rest/data/v1/echo?pg=1.%20Create%20Metro%20protect%20group:%20"${option.Country.value}0${option.Session_Name.value}_1"%20on%20storage:%20"${option.Metro_Storage.value}" + description: Select to confirm metro Protection group result

DR Protection Group

+ - name: DR_Storage + valuesUrl: http://localhost:26337/deviceManager/rest/${option.Primary_Storage.value}/data/v1/search/remote_device?nameAttr=NAME&valueAttr=SN&filter=ARRAYTYPE!!2 + - enforced: true + name: DR_Storage_Room + valuesUrl: http://localhost:26336/rest/data/v1/join/az?pageNo=1&pageSize=100&nameAttr=name&valueAttr=name&relations=[{"obj":"storage","condition":{"constraint":[{"logOp":"and","simple":{"name":"sn","operator":"equal","value":"${option.DR_Storage.value}"}}]}}] + - delimiter: ',' + enforced: true + multivalued: true + name: Check_Result_3 + valuesUrl: http://localhost:26336/rest/data/v1/echo?pg=1.%20Create%20DR%20protect%20group:%20"${option.Country.value}0${option.Session_Name.value}_2"%20on%20storage:%20"${option.DR_Storage.value}" + description: Select to confirm the DR Protection group result + scheduleEnabled: true + sequence: + commands: + - configuration: + ansible-become: 'false' + ansible-disable-limit: 'false' + ansible-extra-vars: |- + username: ${option.Username} + password: ${option.Password} + + Country: ${option.Country} + OS_Type: ${option.OS_Type} + Site: ${option.Site} + + + Session_Name: ${option.Session_Name} + Enable_HyperMetro: ${option.Enable_HyperMetro} + Protection_Level: ${option.Protection_Level} + DR_Sync_Mode: ${option.DR_Sync_Mode} + + Primary_Storage_Room: ${option.Primary_Storage_Room} + Primary_Storage: ${option.Primary_Storage} + + Metro_Storage: ${option.Metro_Storage} + Metro_Storage_Room: ${option.Metro_Storage_Room} + + DR_Storage: ${option.DR_Storage} + DR_Storage_Room: ${option.DR_Storage_Room} + Check_Result_1: ${option.Check_Result_1} + Check_Result_2: ${option.Check_Result_2} + Check_Result_3: ${option.Check_Result_3} + ansible-playbook: /var/lib/rundeck/ansible/rundeck/workflow/project001/49_create_pg.yml + description: Create Host + nodeStep: false + type: com.batix.rundeck.plugins.AnsiblePlaybookWorkflowStep + keepgoing: false + pluginConfig: + LogFilter: + - config: + bgcolor: green + regex: TASK.*Step_.* + type: highlight-output + - config: + bgcolor: red + regex: TASK.*Rollback_.* + type: highlight-output + - config: + bgcolor: blue + regex: TASK.*Precheck_.* + type: highlight-output + - config: + bgcolor: cyan + regex: TASK.*Result_.* + type: highlight-output + - config: + fgcolor: green + mode: bold + regex: ok=[1-9][0-9]* + type: highlight-output + - config: + fgcolor: red + mode: bold + regex: failed=[1-9][0-9]* + type: highlight-output + strategy: node-first + uuid: 34533a0b-9a0b-4229-852e-4c5f57971024 diff --git a/rundeck/jobs/project001/50_add_luns_to_pg.yaml b/rundeck/jobs/project001/50_add_luns_to_pg.yaml new file mode 100644 index 0000000..9d47d2c --- /dev/null +++ b/rundeck/jobs/project001/50_add_luns_to_pg.yaml @@ -0,0 +1,347 @@ +- defaultTab: monitor + description: Create LUNs or select LUNs and add them to Protection Groups + executionEnabled: true + id: 22916134-7113-4969-8d11-786574075a11 + loglevel: INFO + name: 50_add_luns_to_pg + nodeFilterEditable: false + options: + - name: Job_Description + value: Create LUNs or select LUNs and add them to Protection Groups + - name: Username + valuesUrl: http://localhost:26336/rest/data/v1/echo?${job.user.name}=${job.user.name} + description: (Optional) Alternative username/password to login all storage + - name: Password + secure: true + valueExposed: true + description:

Ticket

+ - required: true + name: WBE_CODE + valuesUrl: http://localhost:26336/rest/data/v1/echo?${DATE:YYYYMMddHHmmss}=timestamp + - required: true + name: TICKET_NUMBER + valuesUrl: http://localhost:26336/rest/data/v1/echo?${DATE:YYYYMMddHHmmss}=timestamp + description:

Select Primary Host

+ - enforced: true + name: Country + required: true + valuesUrl: http://localhost:26336/rest/data/v1/search/project?pageNo=1&pageSize=100&valueAttr=name + - name: OS_Type + valuesUrl: http://localhost:26336/rest/data/v1/enum/OSTYPE?nameAttr=desc&valueAttr=key&filter={"enable":1} + - label: Search Host Name + name: Host_Search + - enforced: true + name: Host + required: true + valuesUrl: http://localhost:26336/rest/data/v1/search/storagehost?pageNo=1&pageSize=100&nameAttr=name&valueAttr=name&valueUnique=true&condition={"constraint":[{"simple":{"name":"name","operator":"begin%20with","value":"${option.Country.value}_${option.OS_Type.value}"}},{"logOp":"and","simple":{"name":"name","operator":"contain","value":"${option.Host_Search.value}"}},{"logOp":"and","simple":{"name":"name","operator":"end%20with","value":"_1"}},{"logOp":"and","simple":{"name":"dataStatus","operator":"equal","value":"normal"}}]} + - enforced: true + name: Storage + valuesUrl: http://localhost:26336/rest/data/v1/join/storage?pageNo=1&pageSize=100&nameAttr=deviceName&valueAttr=sn&condition={"constraint":[{"logOp":"and","simple":{"name":"dataStatus","operator":"equal","value":"normal"}}]}&relations=[{"obj":"storagehost","condition":{"constraint":[{"logOp":"and","simple":{"name":"name","operator":"equal","value":"${option.Host.value}"}}]}},{"obj":"az","condition":{"constraint":[{"logOp":"and","simple":{"name":"name","operator":"equal","value":"${option.Storage_Room.value}"}}]}}] + - enforced: true + name: Storage_Room + valuesUrl: http://localhost:26336/rest/data/v1/join/az?pageNo=1&pageSize=100&nameAttr=name&valueAttr=name&relations=[{"obj":"host","condition":{"constraint":[{"logOp":"and","simple":{"name":"name","operator":"equal","value":"${option.Host.value}"}}]}}] + description:

Create New LUNs

+ - label: LUN Size (GB) + name: LUN_Size + - label: Number of LUNs + name: LUN_Num + - delimiter: '|' + multivalued: true + name: LUN_Description + description: Add LUN Description (optional, max 255 chars for all items, '|' and '_' not permitted) + - enforced: true + name: Pool + valuesUrl: http://localhost:26337/deviceManager/rest/${option.Storage.value}/data/v1/search/storagepool?nameAttr=NAME&valueAttr=ID + - enforced: true + name: Workload + valuesUrl: http://localhost:26337/deviceManager/rest/${option.Storage.value}/data/v1/search/workload_type?nameAttr=NAME&valueAttr=ID + description:

Select Un-mapped LUNs

+ - label: Search LUN on Storage + name: Search_LUN + - delimiter: ',' + enforced: true + multivalued: true + name: Select_LUN + valuesUrl: http://localhost:26337/deviceManager/rest/${option.Storage.value}/data/v1/search/lun?range=[0-100]&nameAttr=NAME&valueAttr=NAME&filter=NAME:${option.Search_LUN.value}%20and%20mapped::false + description:

Set LUN Info

+ - enforced: true + name: LUN_Group + valuesUrl: http://localhost:26337/deviceManager/rest/${option.Storage.value}/data/v1/associate/mapping?nameAttr=lunGroupName&valueAttr=lunGroupName&matchAttr=mappingType&match=1&range=[0-100]&obj=host&filter=NAME::${option.Host.value} + description: Select LUN Group to find protection chain + - name: Start_SCSI_ID + - enforced: true + name: Class_1 + valuesUrl: http://localhost:26337/deviceManager/rest/${option.Storage.value}/data/v1/search/lungroup?range=[0-100]&nameAttr=DESCRIPTION:0:2:3&valueAttr=DESCRIPTION:0:2:3&filter=NAME::${option.LUN_Group.value} + - name: Designate_Class_1 + valuesUrl: http://localhost:26336/rest/data/v1/search/tier?valueAttr=name + - delimiter: ',' + enforced: true + multivalued: true + name: Check_Result_1 + required: true + valuesUrl: http://localhost:26336/rest/data/v1/echo?lun=1.%20Create%20${option.LUN_Num.value}%20x%20${option.LUN_Size.value}GB%20LUNs%20for%20host:%20"${option.Host.value}&select_lun=2.%20Select%20LUNs%20"${option.Select_LUN.value}"%20for%20host:%20"${option.Host.value}" + description: Select to confirm the primary host result

Protection Info

+ - label: Search Protection Group + name: Protection_Group_Search + - enforced: true + name: Protection_Group + valuesUrl: http://localhost:26337/deviceManager/rest/${option.Storage.value}/data/v1/search/protectgroup?nameAttr=protectGroupName&valueAttr=protectGroupName&range=[0-100]&filter=NAME:${option.Country.value}0${option.Protection_Group_Search.value}%20and%20description::${option.Enable_HyperMetro.value}${option.Protection_Level.value} + - enforced: true + name: Enable_HyperMetro + valuesUrl: http://localhost:26337/deviceManager/rest/${option.Storage.value}/data/v1/search/lungroup?range=[0-100]&nameAttr=DESCRIPTION:0:0:1&valueAttr=DESCRIPTION:0:0:1&filter=NAME::${option.LUN_Group.value} + - enforced: true + name: Protection_Level + valuesUrl: http://localhost:26337/deviceManager/rest/${option.Storage.value}/data/v1/search/lungroup?range=[0-100]&nameAttr=DESCRIPTION:0:1:2&valueAttr=DESCRIPTION:0:1:2&filter=NAME::${option.LUN_Group.value} + - enforced: true + name: Session_Name + valuesUrl: http://localhost:26337/deviceManager/rest/${option.Storage.value}/data/v1/search/protectgroup?range=[0-100]&nameAttr=protectGroupName:0&nameSplit=_&valueAttr=protectGroupName:0&valueSplit=_&filter=NAME::${option.Protection_Group.value} + description:

Metro Host

+ - enforced: true + name: Metro_Host + valuesUrl: http://localhost:26337/deviceManager/rest/${option.Metro_Storage.value}/data/v1/search/host?nameAttr=NAME&valueAttr=NAME&range=[0-100]&filter=NAME::${option.Host.value} + - enforced: true + name: Metro_Storage + valuesUrl: http://localhost:26337/deviceManager/rest/${option.Storage.value}/data/v1/detail/HyperMetroDomain?ID=${option.Metro_Domain.value}&nameAttr=REMOTEDEVICES:11&nameSplit="&valueAttr=REMOTEDEVICES:7&valueSplit=" + - enforced: true + name: Metro_Storage_Room + valuesUrl: http://localhost:26336/rest/data/v1/join/az?pageNo=1&pageSize=100&nameAttr=name&valueAttr=name&relations=[{"obj":"storage","condition":{"constraint":[{"logOp":"and","simple":{"name":"sn","operator":"equal","value":"${option.Metro_Storage.value}"}}]}}] + - enforced: true + name: Metro_Pool + valuesUrl: http://localhost:26337/deviceManager/rest/${option.Metro_Storage.value}/data/v1/search/storagepool?nameAttr=NAME&valueAttr=ID + - enforced: true + name: Metro_Workload + valuesUrl: http://localhost:26337/deviceManager/rest/${option.Metro_Storage.value}/data/v1/search/workload_type?nameAttr=NAME&valueAttr=ID + - delimiter: ',' + enforced: true + multivalued: true + name: Check_Result_2 + valuesUrl: http://localhost:26336/rest/data/v1/echo?lun=Create%20metro%20LUNs%20for%20host%20"${option.Metro_Host.value}" + description: Select to confirm the metro host result

DR Host

+ - enforced: true + name: DR_Host + valuesUrl: http://localhost:26337/deviceManager/rest/${option.DR_Storage.value}/data/v1/associate/mapping?nameAttr=hostName&valueAttr=hostName&range=[0-100]&obj=lungroup&filter=NAME::${option.DR_LUN_Group.value} + - enforced: true + name: DR_Storage + valuesUrl: http://localhost:26337/deviceManager/rest/${option.Storage.value}/data/v1/search/remote_device?nameAttr=NAME&valueAttr=SN&range=[0-100]&filter=ID::${option.DR_Storage_ID.value} + - enforced: true + name: DR_Storage_Room + valuesUrl: http://localhost:26336/rest/data/v1/join/az?pageNo=1&pageSize=100&nameAttr=name&valueAttr=name&relations=[{"obj":"storage","condition":{"constraint":[{"logOp":"and","simple":{"name":"sn","operator":"equal","value":"${option.DR_Storage.value}"}}]}}] + - enforced: true + name: DR_Pool + valuesUrl: http://localhost:26337/deviceManager/rest/${option.DR_Storage.value}/data/v1/search/storagepool?nameAttr=NAME&valueAttr=ID + - enforced: true + name: DR_Workload + valuesUrl: http://localhost:26337/deviceManager/rest/${option.DR_Storage.value}/data/v1/search/workload_type?nameAttr=NAME&valueAttr=ID + - enforced: true + name: Class_2 + valuesUrl: http://localhost:26337/deviceManager/rest/${option.Storage.value}/data/v1/search/lungroup?range=[0-100]&nameAttr=DESCRIPTION:0:3:4&valueAttr=DESCRIPTION:0:3:4&filter=NAME::${option.LUN_Group.value} + - name: Designate_Class_2 + valuesUrl: http://localhost:26336/rest/data/v1/search/tier?valueAttr=name + - delimiter: ',' + enforced: true + multivalued: true + name: Check_Result_3 + valuesUrl: http://localhost:26336/rest/data/v1/echo?lun=Create%20DR%20LUNs%20for%20host%20"${option.DR_Host.value}" + description: Select to confirm the DR host result

DR Test Host

+ - enforced: true + name: DR_Test_Host + valuesUrl: http://localhost:26337/deviceManager/rest/${option.DR_Storage.value}/data/v1/search/host?range=[0-100]&nameAttr=NAME&valueAttr=NAME&filter=NAME:${option.DR_Host_Name.value}_3 + - enforced: true + name: Class_3 + valuesUrl: http://localhost:26337/deviceManager/rest/${option.Storage.value}/data/v1/search/lungroup?range=[0-100]&nameAttr=DESCRIPTION:0:4:5&valueAttr=DESCRIPTION:0:4:5&filter=NAME::${option.LUN_Group.value} + - name: Designate_Class_3 + valuesUrl: http://localhost:26336/rest/data/v1/search/tier?valueAttr=name + - delimiter: ',' + enforced: true + multivalued: true + name: Check_Result_4 + valuesUrl: http://localhost:26336/rest/data/v1/echo?lun=Create%20DR%20Test%20LUNs%20for%20host%20"${option.DR_Test_Host.value}" + description: Select to confirm the DR test host result

Additional Info

+ - enforced: true + name: LUN_Group_ID + valuesUrl: http://localhost:26337/deviceManager/rest/${option.Storage.value}/data/v1/search/lungroup?nameAttr=ID&valueAttr=ID&range=[0-100]&filter=NAME::${option.LUN_Group.value} + - enforced: true + name: LUN_Group_NO + valuesUrl: http://localhost:26337/deviceManager/rest/${option.Storage.value}/data/v1/search/lungroup?nameAttr=NAME:4:2&nameSplit=_&valueAttr=NAME:4:2&valueSplit=_&range=[0-100]&filter=NAME::${option.LUN_Group.value} + - enforced: true + name: LG_Protection_Group + valuesUrl: http://localhost:26337/deviceManager/rest/${option.Storage.value}/data/v1/search/protectgroup?nameAttr=protectGroupName&valueAttr=protectGroupName&range=[0-100]&filter=lunGroupId::${option.LUN_Group_ID.value} + - enforced: true + name: Metro_CG + valuesUrl: http://localhost:26337/deviceManager/rest/${option.Storage.value}/data/v1/search/hypermetro_consistentgroup?nameAttr=NAME&valueAttr=NAME&range=[0-100]&filter=localPgName::${option.Protection_Group.value} + - enforced: true + name: Metro_CG_ID + valuesUrl: http://localhost:26337/deviceManager/rest/${option.Storage.value}/data/v1/search/hypermetro_consistentgroup?nameAttr=ID&valueAttr=ID&range=[0-100]&filter=localPgName::${option.Protection_Group.value} + - enforced: true + name: Metro_Domain + valuesUrl: http://localhost:26337/deviceManager/rest/${option.Storage.value}/data/v1/search/hypermetro_consistentgroup?nameAttr=DOMAINNAME&valueAttr=DOMAINID&range=[0-100]&filter=localPgName::${option.Protection_Group.value} + - enforced: true + name: DR_CG + valuesUrl: http://localhost:26337/deviceManager/rest/${option.Storage.value}/data/v1/search/CONSISTENTGROUP?nameAttr=NAME&valueAttr=NAME&range=[0-100]&filter=localPgName::${option.Protection_Group.value} + - enforced: true + name: DR_LG_CG + valuesUrl: http://localhost:26337/deviceManager/rest/${option.Storage.value}/data/v1/search/CONSISTENTGROUP?nameAttr=NAME&valueAttr=NAME&range=[0-100]&filter=localPgName::${option.LG_Protection_Group.value} + - enforced: true + name: DR_Mode_Enum + valuesUrl: http://localhost:26337/deviceManager/rest/${option.Storage.value}/data/v1/search/CONSISTENTGROUP?nameAttr=REPLICATIONMODEL&valueAttr=REPLICATIONMODEL&range=[0-100]&filter=NAME::${option.DR_CG.value} + - enforced: true + name: DR_Mode + valuesUrl: http://localhost:26336/rest/data/v1/enum/REPMODE?nameAttr=desc&valueAttr=key&filter={"enum":${option.DR_Mode_Enum.value}} + - enforced: true + name: DR_Storage_ID + valuesUrl: http://localhost:26337/deviceManager/rest/${option.Storage.value}/data/v1/search/CONSISTENTGROUP?nameAttr=remoteArrayID&valueAttr=remoteArrayID&range=[0-100]&filter=NAME::${option.DR_CG.value} + - enforced: true + name: DR_Protection_Group + valuesUrl: http://localhost:26337/deviceManager/rest/${option.Storage.value}/data/v1/search/CONSISTENTGROUP?nameAttr=rmtPgName&valueAttr=rmtPgName&range=[0-100]&filter=NAME::${option.DR_CG.value} + - enforced: true + name: DR_LG_Protection_Group + valuesUrl: http://localhost:26337/deviceManager/rest/${option.Storage.value}/data/v1/search/CONSISTENTGROUP?nameAttr=rmtPgName&valueAttr=rmtPgName&range=[0-100]&filter=NAME::${option.DR_LG_CG.value} + - enforced: true + name: DR_LUN_Group + valuesUrl: http://localhost:26337/deviceManager/rest/${option.DR_Storage.value}/data/v1/search/protectgroup?nameAttr=lunGroupName&valueAttr=lunGroupName&range=[0-100]&filter=protectGroupName::${option.DR_LG_Protection_Group.value} + - enforced: true + name: DR_Host_Name + valuesUrl: http://localhost:26337/deviceManager/rest/${option.DR_Storage.value}/data/v1/search/host?range=[0-100]&nameAttr=NAME:2&nameSplit=_&valueAttr=NAME:2&valueSplit=_&filter=NAME::${option.DR_Host.value} + - enforced: true + name: DR_Test_LUN_Group + valuesUrl: http://localhost:26337/deviceManager/rest/${option.DR_Storage.value}/data/v1/search/lungroup?range=[0-100]&nameAttr=NAME&valueAttr=NAME&filter=NAME::${option.DR_Test_Host.value}_LG${option.LUN_Group_NO.value} + - enforced: true + name: DR_Test_CG + valuesUrl: http://localhost:26337/deviceManager/rest/${option.DR_Storage.value}/data/v1/associate/snapshot_consistency_group?nameAttr=NAME&valueAttr=NAME&matchAttr=NAME&match=${option.Session_Name.value}&range=[0-4096]&obj=protectgroup&objIdAttr=protectGroupId&filter=protectGroupName::${option.DR_Protection_Group.value} + - enforced: true + name: DR_Test_CG_ID + valuesUrl: http://localhost:26337/deviceManager/rest/${option.DR_Storage.value}/data/v1/search/snapshot_consistency_group?nameAttr=ID&valueAttr=ID&filter=NAME::${option.DR_Test_CG.value} + - enforced: true + name: DR_Test_CG_Status + valuesUrl: http://localhost:26336/rest/data/v1/enum/SNAPCG?nameAttr=desc&valueAttr=enum&filter={"enum":${option.DR_Test_CG_Status_Enum.value}} + - enforced: true + name: DR_Test_CG_Status_Enum + valuesUrl: http://localhost:26337/deviceManager/rest/${option.DR_Storage.value}/data/v1/search/snapshot_consistency_group?nameAttr=RUNNINGSTATUS&valueAttr=RUNNINGSTATUS&filter=NAME::${option.DR_Test_CG.value} + - enforced: true + name: DR_Star + valuesUrl: http://localhost:26337/deviceManager/rest/${option.Storage.value}/data/v1/search/dr_star?nameAttr=NAME&valueAttr=NAME&range=[0-100]&filter=memberType::2%20and%20localResource::${option.Protection_Group.value} + - enforced: true + name: Standby_CG + valuesUrl: http://localhost:26337/deviceManager/rest/${option.Metro_Storage.value}/data/v1/search/CONSISTENTGROUP?nameAttr=NAME&valueAttr=NAME&range=[0-100]&filter=localPgName::${option.Protection_Group.value} + - enforced: true + name: Standby_CG_ID + valuesUrl: http://localhost:26337/deviceManager/rest/${option.Metro_Storage.value}/data/v1/search/CONSISTENTGROUP?nameAttr=ID&valueAttr=ID&range=[0-100]&filter=localPgName::${option.Protection_Group.value} + scheduleEnabled: true + sequence: + commands: + - configuration: + ansible-become: 'false' + ansible-disable-limit: 'false' + ansible-extra-vars: |- + username: ${option.Username} + password: ${option.Password} + + WBE_CODE: ${option.WBE_CODE} + TICKET_NUMBER: ${option.TICKET_NUMBER} + Country: ${option.Country} + Job_User: ${job.user.name} + + Host: ${option.Host} + Storage: ${option.Storage} + Storage_Room: ${option.Storage_Room} + LUN_Size: ${option.LUN_Size} + LUN_Num: ${option.LUN_Num} + Start_SCSI_ID: ${option.Start_SCSI_ID} + LUN_Description: ${option.LUN_Description} + Pool: ${option.Pool} + Workload: ${option.Workload} + Select_LUN: ${option.Select_LUN} + Check_Result_1: ${option.Check_Result_1} + + Metro_Host: ${option.Metro_Host} + Metro_Storage: ${option.Metro_Storage} + Metro_Storage_Room: ${option.Metro_Storage_Room} + Metro_Pool: ${option.Metro_Pool} + Metro_Workload: ${option.Metro_Workload} + Check_Result_2: ${option.Check_Result_2} + + DR_Host: ${option.DR_Host} + DR_Storage: ${option.DR_Storage} + DR_Storage_Room: ${option.DR_Storage_Room} + DR_Pool: ${option.DR_Pool} + DR_Workload: ${option.DR_Workload} + Check_Result_3: ${option.Check_Result_3} + + DR_Test_Host: ${option.DR_Test_Host} + Check_Result_4: ${option.Check_Result_4} + + Enable_HyperMetro: ${option.Enable_HyperMetro} + Metro_CG: ${option.Metro_CG} + Metro_CG_ID: ${option.Metro_CG_ID} + Session_Name: ${option.Session_Name} + Protection_Level: ${option.Protection_Level} + Class_1: ${option.Class_1} + Class_2: ${option.Class_2} + Class_3: ${option.Class_3} + Designate_Class_1: ${option.Designate_Class_1} + Designate_Class_2: ${option.Designate_Class_2} + Designate_Class_3: ${option.Designate_Class_3} + LUN_Group: ${option.LUN_Group} + Protection_Group: ${option.Protection_Group} + DR_CG: ${option.DR_CG} + DR_Mode: ${option.DR_Mode} + DR_Mode_Enum: ${option.DR_Mode_Enum} + DR_Storage_ID: ${option.DR_Storage_ID} + DR_Protection_Group: ${option.DR_Protection_Group} + DR_LUN_Group: ${option.DR_LUN_Group} + DR_Test_LUN_Group: ${option.DR_Test_LUN_Group} + DR_Test_CG: ${option.DR_Test_CG} + DR_Test_CG_ID: ${option.DR_Test_CG_ID} + DR_Test_CG_Status: ${option.DR_Test_CG_Status} + DR_Star: ${option.DR_Star} + Standby_CG: ${option.Standby_CG} + Standby_CG_ID: ${option.Standby_CG_ID} + ansible-playbook: /var/lib/rundeck/ansible/rundeck/workflow/project001/50_add_luns_to_pg.yml + nodeStep: false + type: com.batix.rundeck.plugins.AnsiblePlaybookWorkflowStep + - configuration: + command: /bin/psql automation -c "\copy (select * from activity where WBE_CODE = '${option.WBE_CODE}' and TICKET_NUMBER = '${option.TICKET_NUMBER}') TO '/var/lib/rundeck/exp/webapp/project001/export/${job.name}-${job.execid}-${job.user.name}-${option.TICKET_NUMBER}.csv' CSV HEADER" + description: Export Changes + nodeStep: true + type: localexec + - configuration: + command: echo "${job.name}-${job.execid}-${job.user.name}-${option.TICKET_NUMBER}.csv" + description: Download Link + nodeStep: true + plugins: + LogFilter: + - config: + datatype: text/html + type: render-datatype + type: localexec + keepgoing: false + pluginConfig: + LogFilter: + - config: + bgcolor: green + regex: TASK.*Step_.* + type: highlight-output + - config: + bgcolor: red + regex: TASK.*Rollback_.* + type: highlight-output + - config: + bgcolor: blue + regex: TASK.*Precheck_.* + type: highlight-output + - config: + bgcolor: cyan + regex: TASK.*Result_.* + type: highlight-output + - config: + fgcolor: green + mode: bold + regex: ok=[1-9][0-9]* + type: highlight-output + - config: + fgcolor: red + mode: bold + regex: failed=[1-9][0-9]* + type: highlight-output + strategy: node-first + uuid: 22916134-7113-4969-8d11-786574075a11 diff --git a/rundeck/jobs/project001/51_remove_luns_from_pg.yaml b/rundeck/jobs/project001/51_remove_luns_from_pg.yaml new file mode 100644 index 0000000..ca66267 --- /dev/null +++ b/rundeck/jobs/project001/51_remove_luns_from_pg.yaml @@ -0,0 +1,236 @@ +- defaultTab: monitor + description: Remove LUNs from LUN Group, Protect Group, Replication CGs, HyperMetro CG of a Protection Group, and delete replicas + executionEnabled: true + id: 85eef634-f4c3-4848-b621-5d92a348ee7e + loglevel: INFO + name: 51_remove_luns_from_pg + nodeFilterEditable: false + options: + - name: Job_Description + value: Remove LUNs from LUN Group, Protect Group, Replication CGs, HyperMetro CG, and delete replicas + - name: Username + valuesUrl: http://localhost:26336/rest/data/v1/echo?${job.user.name}=${job.user.name} + description: (Optional) Alternative username/password to login all storage + - name: Password + secure: true + valueExposed: true + description:

Ticket

+ - required: true + name: WBE_CODE + valuesUrl: http://localhost:26336/rest/data/v1/echo?${DATE:YYYYMMddHHmmss}=timestamp + - required: true + name: TICKET_NUMBER + valuesUrl: http://localhost:26336/rest/data/v1/echo?${DATE:YYYYMMddHHmmss}=timestamp + description:

Country, OS Type and Location

+ - enforced: true + name: Country + required: true + valuesUrl: http://localhost:26336/rest/data/v1/search/project?pageNo=1&pageSize=100&valueAttr=name + - name: OS_Type + valuesUrl: http://localhost:26336/rest/data/v1/enum/OSTYPE?nameAttr=desc&valueAttr=key&filter={"enable":1} + - enforced: true + name: Site + required: true + valuesUrl: http://localhost:26336/rest/data/v1/enum/DC?nameAttr=desc&valueAttr=key + - enforced: true + name: Storage_Room + valuesUrl: http://localhost:26336/rest/data/v1/enum/AZ?nameAttr=desc&valueAttr=key&filter={"dc":"${option.Site.value}"} + - enforced: true + name: Storage + valuesUrl: http://localhost:26336/rest/data/v1/join/storage?pageNo=1&pageSize=100&nameAttr=deviceName&valueAttr=sn&condition={"constraint":[{"logOp":"and","simple":{"name":"dataStatus","operator":"equal","value":"normal"}}]}&relations=[{"obj":"az","condition":{"constraint":[{"logOp":"and","simple":{"name":"name","operator":"equal","value":"${option.Storage_Room.value}"}}]}}] + description:

Select Primary Protection Group & LUNs

+ - label: Search Protection Group Name + name: Protection_Group_Search + - enforced: true + name: Protection_Group + required: true + valuesUrl: http://localhost:26337/deviceManager/rest/${option.Storage.value}/data/v1/search/protectgroup?nameAttr=protectGroupName&valueAttr=protectGroupName&range=[0-100]&filter=NAME:${option.Country.value}0${option.Protection_Group_Search.value} + description:

Select Primary LUNs

+ - delimiter: ',' + enforced: true + multivalued: true + required: true + name: Remove_LUN + valuesUrl: http://localhost:26337/deviceManager/rest/${option.Storage.value}/data/v1/associate/lun?nameAttr=NAME&valueAttr=NAME&range=[0-4096]&obj=protectgroup&objIdAttr=protectGroupId&filter=protectGroupName::${option.Protection_Group.value} + - delimiter: ',' + enforced: true + multivalued: true + name: Check_Result_1 + required: true + valuesUrl: http://localhost:26336/rest/data/v1/echo?lun=Remove%20luns%20"${option.Remove_LUN.value}"%20from%20protection%20group:%20"${option.Protection_Group.value}" + description: Select to confirm the primary host result

Protection Info

+ - enforced: true + name: Enable_HyperMetro + valuesUrl: http://localhost:26337/deviceManager/rest/${option.Storage.value}/data/v1/search/protectgroup?range=[0-100]&nameAttr=description:0:0:1&valueAttr=description:0:0:1&filter=NAME::${option.Protection_Group.value} + - enforced: true + name: Protection_Level + valuesUrl: http://localhost:26337/deviceManager/rest/${option.Storage.value}/data/v1/search/protectgroup?range=[0-100]&nameAttr=description:0:1:2&valueAttr=description:0:1:2&filter=NAME::${option.Protection_Group.value} + - enforced: true + name: Session_Name + valuesUrl: http://localhost:26337/deviceManager/rest/${option.Storage.value}/data/v1/search/protectgroup?range=[0-100]&nameAttr=protectGroupName:0&nameSplit=_&valueAttr=protectGroupName:0&valueSplit=_&filter=NAME::${option.Protection_Group.value} + description:

Metro Protection Group

+ - enforced: true + name: Metro_Storage_Room + valuesUrl: http://localhost:26336/rest/data/v1/join/az?pageNo=1&pageSize=100&nameAttr=name&valueAttr=name&relations=[{"obj":"storage","condition":{"constraint":[{"logOp":"and","simple":{"name":"sn","operator":"equal","value":"${option.Metro_Storage.value}"}}]}}] + - enforced: true + name: Metro_Storage + valuesUrl: http://localhost:26337/deviceManager/rest/${option.Storage.value}/data/v1/detail/HyperMetroDomain?ID=${option.Metro_Domain.value}&nameAttr=REMOTEDEVICES:11&nameSplit="&valueAttr=REMOTEDEVICES:7&valueSplit=" + - enforced: true + name: Metro_Protection_Group + valuesUrl: http://localhost:26337/deviceManager/rest/${option.Metro_Storage.value}/data/v1/search/protectgroup?range=[0-100]&nameAttr=protectGroupName&valueAttr=protectGroupName&filter=NAME::${option.Protection_Group.value} + - delimiter: ',' + enforced: true + multivalued: true + name: Check_Result_2 + valuesUrl: http://localhost:26336/rest/data/v1/echo?lun=Remove%20and%20delete%20metro%20LUNs%20from%20Protection%20Group:%20"${option.Metro_Protection_Group.value}" + description: Select to confirm the metro protection group result

DR Protection Group

+ - enforced: true + name: DR_Storage_Room + valuesUrl: http://localhost:26336/rest/data/v1/join/az?pageNo=1&pageSize=100&nameAttr=name&valueAttr=name&relations=[{"obj":"storage","condition":{"constraint":[{"logOp":"and","simple":{"name":"sn","operator":"equal","value":"${option.DR_Storage.value}"}}]}}] + - enforced: true + name: DR_Storage_ID + valuesUrl: http://localhost:26337/deviceManager/rest/${option.Storage.value}/data/v1/search/CONSISTENTGROUP?nameAttr=remoteArrayID&valueAttr=remoteArrayID&range=[0-100]&filter=NAME::${option.DR_CG.value} + - enforced: true + name: DR_Storage + valuesUrl: http://localhost:26337/deviceManager/rest/${option.Storage.value}/data/v1/search/remote_device?nameAttr=NAME&valueAttr=SN&range=[0-100]&filter=ID::${option.DR_Storage_ID.value} + - enforced: true + name: DR_Protection_Group + valuesUrl: http://localhost:26337/deviceManager/rest/${option.Storage.value}/data/v1/search/CONSISTENTGROUP?nameAttr=rmtPgName&valueAttr=rmtPgName&range=[0-100]&filter=NAME::${option.DR_CG.value} + - delimiter: ',' + enforced: true + multivalued: true + name: Check_Result_3 + valuesUrl: http://localhost:26336/rest/data/v1/echo?lun=Remove%20and%20delete%20DR%20LUNs%20from%20protection%20group:%20"${option.DR_Protection_Group.value}" + description: Select to confirm the DR host result

Additional Info

+ - enforced: true + name: Metro_Domain + valuesUrl: http://localhost:26337/deviceManager/rest/${option.Storage.value}/data/v1/search/hypermetro_consistentgroup?nameAttr=DOMAINNAME&valueAttr=DOMAINID&range=[0-100]&filter=localPgName::${option.Protection_Group.value} + - enforced: true + name: Metro_CG + valuesUrl: http://localhost:26337/deviceManager/rest/${option.Storage.value}/data/v1/search/hypermetro_consistentgroup?nameAttr=NAME&valueAttr=NAME&range=[0-100]&filter=localPgName::${option.Protection_Group.value} + - enforced: true + name: DR_CG + valuesUrl: http://localhost:26337/deviceManager/rest/${option.Storage.value}/data/v1/search/CONSISTENTGROUP?nameAttr=NAME&valueAttr=NAME&range=[0-100]&filter=localPgName::${option.Protection_Group.value} + - enforced: true + name: DR_Mode_Enum + valuesUrl: http://localhost:26337/deviceManager/rest/${option.Storage.value}/data/v1/search/CONSISTENTGROUP?nameAttr=REPLICATIONMODEL&valueAttr=REPLICATIONMODEL&range=[0-100]&filter=NAME::${option.DR_CG.value} + - enforced: true + name: DR_Mode + valuesUrl: http://localhost:26336/rest/data/v1/enum/REPMODE?nameAttr=desc&valueAttr=key&filter={"enum":${option.DR_Mode_Enum.value}} + - enforced: true + name: DR_Test_CG + valuesUrl: http://localhost:26337/deviceManager/rest/${option.DR_Storage.value}/data/v1/associate/snapshot_consistency_group?nameAttr=NAME&valueAttr=NAME&matchAttr=NAME&match=${option.Session_Name.value}&range=[0-4096]&obj=protectgroup&objIdAttr=protectGroupId&filter=protectGroupName::${option.DR_Protection_Group.value} + - enforced: true + name: DR_Test_CG_ID + valuesUrl: http://localhost:26337/deviceManager/rest/${option.DR_Storage.value}/data/v1/search/snapshot_consistency_group?nameAttr=ID&valueAttr=ID&filter=NAME::${option.DR_Test_CG.value} + - enforced: true + name: DR_Test_CG_Status + valuesUrl: http://localhost:26336/rest/data/v1/enum/SNAPCG?nameAttr=desc&valueAttr=enum&filter={"enum":${option.DR_Test_CG_Status_Enum.value}} + - enforced: true + name: DR_Test_CG_Status_Enum + valuesUrl: http://localhost:26337/deviceManager/rest/${option.DR_Storage.value}/data/v1/search/snapshot_consistency_group?nameAttr=RUNNINGSTATUS&valueAttr=RUNNINGSTATUS&filter=NAME::${option.DR_Test_CG.value} + - enforced: true + name: DR_Star + valuesUrl: http://localhost:26337/deviceManager/rest/${option.Storage.value}/data/v1/search/dr_star?nameAttr=NAME&valueAttr=NAME&range=[0-100]&filter=memberType::2%20and%20localResource::${option.Protection_Group.value} + - enforced: true + name: Standby_CG + valuesUrl: http://localhost:26337/deviceManager/rest/${option.Metro_Storage.value}/data/v1/search/CONSISTENTGROUP?nameAttr=NAME&valueAttr=NAME&range=[0-100]&filter=localPgName::${option.Protection_Group.value} + - enforced: true + name: Standby_CG_ID + valuesUrl: http://localhost:26337/deviceManager/rest/${option.Metro_Storage.value}/data/v1/search/CONSISTENTGROUP?nameAttr=ID&valueAttr=ID&range=[0-100]&filter=localPgName::${option.Protection_Group.value} + scheduleEnabled: true + sequence: + commands: + - configuration: + ansible-become: 'false' + ansible-disable-limit: 'false' + ansible-extra-vars: |- + username: ${option.Username} + password: ${option.Password} + + WBE_CODE: ${option.WBE_CODE} + TICKET_NUMBER: ${option.TICKET_NUMBER} + Country: ${option.Country} + Job_User: ${job.user.name} + + Protection_Group: ${option.Protection_Group} + Storage: ${option.Storage} + Storage_Room: ${option.Storage_Room} + Remove_LUN: ${option.Remove_LUN} + Check_Result_1: ${option.Check_Result_1} + + Metro_Protection_Group: ${option.Metro_Protection_Group} + Metro_Storage: ${option.Metro_Storage} + Metro_Storage_Room: ${option.Metro_Storage_Room} + Check_Result_2: ${option.Check_Result_2} + + DR_Protection_Group: ${option.DR_Protection_Group} + DR_Storage: ${option.DR_Storage} + DR_Storage_Room: ${option.DR_Storage_Room} + Check_Result_3: ${option.Check_Result_3} + + Session_Name: ${option.Session_Name} + Enable_HyperMetro: ${option.Enable_HyperMetro} + Metro_CG: ${option.Metro_CG} + Metro_CG_ID: ${option.Metro_CG_ID} + Protection_Level: ${option.Protection_Level} + Protection_Group: ${option.Protection_Group} + DR_CG: ${option.DR_CG} + DR_Mode: ${option.DR_Mode} + DR_Mode_Enum: ${option.DR_Mode_Enum} + DR_Storage_ID: ${option.DR_Storage_ID} + DR_Test_CG: ${option.DR_Test_CG} + DR_Test_CG_ID: ${option.DR_Test_CG_ID} + DR_Test_CG_Status: ${option.DR_Test_CG_Status} + DR_Star: ${option.DR_Star} + Standby_CG: ${option.Standby_CG} + Standby_CG_ID: ${option.Standby_CG_ID} + ansible-playbook: /var/lib/rundeck/ansible/rundeck/workflow/project001/51_remove_luns_from_pg.yml + nodeStep: false + type: com.batix.rundeck.plugins.AnsiblePlaybookWorkflowStep + - configuration: + command: /bin/psql automation -c "\copy (select * from activity where WBE_CODE = '${option.WBE_CODE}' and TICKET_NUMBER = '${option.TICKET_NUMBER}') TO '/var/lib/rundeck/exp/webapp/project001/export/${job.name}-${job.execid}-${job.user.name}-${option.TICKET_NUMBER}.csv' CSV HEADER" + description: Export Changes + nodeStep: true + type: localexec + - configuration: + command: echo "${job.name}-${job.execid}-${job.user.name}-${option.TICKET_NUMBER}.csv" + description: Download Link + nodeStep: true + plugins: + LogFilter: + - config: + datatype: text/html + type: render-datatype + type: localexec + keepgoing: false + pluginConfig: + LogFilter: + - config: + bgcolor: green + regex: TASK.*Step_.* + type: highlight-output + - config: + bgcolor: red + regex: TASK.*Rollback_.* + type: highlight-output + - config: + bgcolor: blue + regex: TASK.*Precheck_.* + type: highlight-output + - config: + bgcolor: cyan + regex: TASK.*Result_.* + type: highlight-output + - config: + fgcolor: green + mode: bold + regex: ok=[1-9][0-9]* + type: highlight-output + - config: + fgcolor: red + mode: bold + regex: failed=[1-9][0-9]* + type: highlight-output + strategy: node-first + uuid: 85eef634-f4c3-4848-b621-5d92a348ee7e diff --git a/rundeck/jobs/project001/52_delete_pg.yaml b/rundeck/jobs/project001/52_delete_pg.yaml new file mode 100644 index 0000000..c21dbfd --- /dev/null +++ b/rundeck/jobs/project001/52_delete_pg.yaml @@ -0,0 +1,158 @@ +- defaultTab: monitor + description: 'Delete Protection Group, Replication CG, HyperMetro CG' + executionEnabled: true + id: 5d57bbca-2442-4868-90e1-1372bc24bed0 + loglevel: INFO + name: 52_delete_pg + nodeFilterEditable: false + options: + - name: Job_Description + value: Delete Protection Group, Replication CG, HyperMetro CG + description: Requires no LUNs in Protection Group + - name: Username + valuesUrl: http://localhost:26336/rest/data/v1/echo?${job.user.name}=${job.user.name} + description: (Optional) Alternative username/password to login all storage + - name: Password + secure: true + valueExposed: true + description:

Select Primary Protection Group

+ - enforced: true + name: Country + required: true + valuesUrl: http://localhost:26336/rest/data/v1/search/project?pageNo=1&pageSize=100&valueAttr=name + - enforced: true + name: Site + required: true + valuesUrl: http://localhost:26336/rest/data/v1/enum/DC?nameAttr=desc&valueAttr=key + description: Select to confirm the primary host result

Protection Info

+ - enforced: true + name: Storage_Room + valuesUrl: http://localhost:26336/rest/data/v1/enum/AZ?nameAttr=desc&valueAttr=key&filter={"dc":"${option.Site.value}"} + - enforced: true + name: Storage + valuesUrl: http://localhost:26336/rest/data/v1/join/storage?pageNo=1&pageSize=100&nameAttr=deviceName&valueAttr=sn&condition={"constraint":[{"logOp":"and","simple":{"name":"dataStatus","operator":"equal","value":"normal"}}]}&relations=[{"obj":"az","condition":{"constraint":[{"logOp":"and","simple":{"name":"name","operator":"equal","value":"${option.Storage_Room.value}"}}]}}] + - label: Search Protection Group Name + name: Protection_Group_Search + - enforced: true + name: Protection_Group + valuesUrl: http://localhost:26337/deviceManager/rest/${option.Storage.value}/data/v1/search/protectgroup?nameAttr=protectGroupName&valueAttr=protectGroupName&range=[0-100]&filter=NAME:${option.Country.value}0${option.Protection_Group_Search.value} + - enforced: true + name: Enable_HyperMetro + valuesUrl: http://localhost:26337/deviceManager/rest/${option.Storage.value}/data/v1/search/protectgroup?range=[0-100]&nameAttr=description:0:0:1&valueAttr=description:0:0:1&filter=NAME::${option.Protection_Group.value} + - enforced: true + name: Protection_Level + valuesUrl: http://localhost:26337/deviceManager/rest/${option.Storage.value}/data/v1/search/protectgroup?range=[0-100]&nameAttr=description:0:1:2&valueAttr=description:0:1:2&filter=NAME::${option.Protection_Group.value} + - enforced: true + name: Session_Name + valuesUrl: http://localhost:26337/deviceManager/rest/${option.Storage.value}/data/v1/search/protectgroup?range=[0-100]&nameAttr=protectGroupName:0&nameSplit=_&valueAttr=protectGroupName:0&valueSplit=_&filter=NAME::${option.Protection_Group.value} + - delimiter: ',' + enforced: true + multivalued: true + name: Check_Result_1 + required: true + valuesUrl: http://localhost:26336/rest/data/v1/echo?pg=Delete%20protection%20group:%20"${option.Protection_Group.value}"%20and%20correlated%20CGs + description:

Metro Protection Group

+ + - enforced: true + name: Metro_Storage_Room + valuesUrl: http://localhost:26336/rest/data/v1/join/az?pageNo=1&pageSize=100&nameAttr=name&valueAttr=name&relations=[{"obj":"storage","condition":{"constraint":[{"logOp":"and","simple":{"name":"sn","operator":"equal","value":"${option.Metro_Storage.value}"}}]}}] + - enforced: true + name: Metro_Storage + valuesUrl: http://localhost:26337/deviceManager/rest/${option.Storage.value}/data/v1/detail/HyperMetroDomain?ID=${option.Metro_Domain.value}&nameAttr=REMOTEDEVICES:11&nameSplit="&valueAttr=REMOTEDEVICES:7&valueSplit=" + - enforced: true + name: Metro_Protection_Group + valuesUrl: http://localhost:26337/deviceManager/rest/${option.Metro_Storage.value}/data/v1/search/protectgroup?range=[0-100]&nameAttr=protectGroupName&valueAttr=protectGroupName&filter=NAME::${option.Protection_Group.value} + - enforced: true + name: Metro_Domain + valuesUrl: http://localhost:26337/deviceManager/rest/${option.Storage.value}/data/v1/search/hypermetro_consistentgroup?nameAttr=DOMAINNAME&valueAttr=DOMAINID&range=[0-100]&filter=localPgName::${option.Protection_Group.value} + - enforced: true + name: Metro_CG + valuesUrl: http://localhost:26337/deviceManager/rest/${option.Storage.value}/data/v1/search/hypermetro_consistentgroup?nameAttr=NAME&valueAttr=NAME&range=[0-100]&filter=localPgName::${option.Protection_Group.value} + - delimiter: ',' + enforced: true + multivalued: true + name: Check_Result_2 + valuesUrl: http://localhost:26336/rest/data/v1/echo?pg=Delete%20protection%20group:%20"${option.Metro_Protection_Group.value}"%20and%20correlated%20CGs + description: Select to confirm the metro protection group result

DR Protection Group

+ - enforced: true + name: DR_Storage_Room + valuesUrl: http://localhost:26336/rest/data/v1/join/az?pageNo=1&pageSize=100&nameAttr=name&valueAttr=name&relations=[{"obj":"storage","condition":{"constraint":[{"logOp":"and","simple":{"name":"sn","operator":"equal","value":"${option.DR_Storage.value}"}}]}}] + - enforced: true + name: DR_Storage_ID + valuesUrl: http://localhost:26337/deviceManager/rest/${option.Storage.value}/data/v1/search/CONSISTENTGROUP?nameAttr=remoteArrayID&valueAttr=remoteArrayID&range=[0-100]&filter=NAME::${option.DR_CG.value} + - enforced: true + name: DR_Storage + valuesUrl: http://localhost:26337/deviceManager/rest/${option.Storage.value}/data/v1/search/remote_device?nameAttr=NAME&valueAttr=SN&range=[0-100]&filter=ID::${option.DR_Storage_ID.value} + - enforced: true + name: DR_Protection_Group + valuesUrl: http://localhost:26337/deviceManager/rest/${option.Storage.value}/data/v1/search/CONSISTENTGROUP?nameAttr=rmtPgName&valueAttr=rmtPgName&range=[0-100]&filter=NAME::${option.DR_CG.value} + - enforced: true + name: DR_CG + valuesUrl: http://localhost:26337/deviceManager/rest/${option.Storage.value}/data/v1/search/CONSISTENTGROUP?nameAttr=NAME&valueAttr=NAME&range=[0-100]&filter=localPgName::${option.Protection_Group.value} + - delimiter: ',' + enforced: true + multivalued: true + name: Check_Result_3 + valuesUrl: http://localhost:26336/rest/data/v1/echo?pg=Delete%20DR%20protection%20group:%20"${option.DR_Protection_Group.value}"%20and%20correlated%20CGs + scheduleEnabled: true + sequence: + commands: + - configuration: + ansible-become: 'false' + ansible-disable-limit: 'false' + ansible-extra-vars: |- + username: ${option.Username} + password: ${option.Password} + + Storage: ${option.Storage} + Protection_Group: ${option.Protection_Group} + Enable_HyperMetro: ${option.Enable_HyperMetro} + Protection_Level: ${option.Protection_Level} + Session_Name: ${option.Session_Name} + Check_Result_1: ${option.Check_Result_1} + + Metro_Storage_Room: ${option.Metro_Storage_Room} + Metro_Storage: ${option.Metro_Storage} + Metro_Protection_Group: ${option.Metro_Protection_Group} + Metro_CG: ${option.Metro_CG} + Check_Result_2: ${option.Check_Result_2} + + DR_Storage: ${option.DR_Storage} + DR_Protection_Group: ${option.DR_Protection_Group} + DR_CG: ${option.DR_CG} + Check_Result_3: ${option.Check_Result_3} + + ansible-playbook: /var/lib/rundeck/ansible/rundeck/workflow/project001/52_delete_pg.yml + nodeStep: false + type: com.batix.rundeck.plugins.AnsiblePlaybookWorkflowStep + keepgoing: false + pluginConfig: + LogFilter: + - config: + bgcolor: green + regex: TASK.*Step_.* + type: highlight-output + - config: + bgcolor: red + regex: TASK.*Rollback_.* + type: highlight-output + - config: + bgcolor: blue + regex: TASK.*Precheck_.* + type: highlight-output + - config: + bgcolor: cyan + regex: TASK.*Result_.* + type: highlight-output + - config: + fgcolor: green + mode: bold + regex: ok=[1-9][0-9]* + type: highlight-output + - config: + fgcolor: red + mode: bold + regex: failed=[1-9][0-9]* + type: highlight-output + strategy: node-first + uuid: 5d57bbca-2442-4868-90e1-1372bc24bed0 diff --git a/rundeck/jobs/project001/53_dr_test_for_pg.yaml b/rundeck/jobs/project001/53_dr_test_for_pg.yaml new file mode 100644 index 0000000..67584ee --- /dev/null +++ b/rundeck/jobs/project001/53_dr_test_for_pg.yaml @@ -0,0 +1,150 @@ +- defaultTab: monitor + description: Move WWNs from DR Host to DR Test Host, Activate Snapshot CG + executionEnabled: true + id: bf3196d6-5602-49eb-8158-39e69a875d01 + loglevel: INFO + name: 53_dr_test_for_pg + nodeFilterEditable: false + options: + - name: Job_Description + value: Move WWNs from DR Host to DR Test Host, Activate Snapshot CG + - name: Username + valuesUrl: http://localhost:26336/rest/data/v1/echo?${job.user.name}=${job.user.name} + description: (Optional) Alternative username/password to login all storage + - name: Password + secure: true + valueExposed: true + description:

Ticket

+ - required: true + name: WBE_CODE + valuesUrl: http://localhost:26336/rest/data/v1/echo?${DATE:YYYYMMddHHmmss}=timestamp + - required: true + name: TICKET_NUMBER + valuesUrl: http://localhost:26336/rest/data/v1/echo?${DATE:YYYYMMddHHmmss}=timestamp + description:

Country, OS Type and Location

+ - enforced: true + name: Country + required: true + valuesUrl: http://localhost:26336/rest/data/v1/search/project?pageNo=1&pageSize=100&valueAttr=name + - name: OS_Type + valuesUrl: http://localhost:26336/rest/data/v1/enum/OSTYPE?nameAttr=desc&valueAttr=key&filter={"enable":1} + - enforced: true + name: Site + required: true + valuesUrl: http://localhost:26336/rest/data/v1/enum/DC?nameAttr=desc&valueAttr=key + - enforced: true + name: DR_Storage_Room + valuesUrl: http://localhost:26336/rest/data/v1/enum/AZ?nameAttr=desc&valueAttr=key&filter={"dc":"${option.Site.value}"} + - enforced: true + name: DR_Storage + valuesUrl: http://localhost:26336/rest/data/v1/join/storage?pageNo=1&pageSize=100&nameAttr=deviceName&valueAttr=sn&condition={"constraint":[{"logOp":"and","simple":{"name":"dataStatus","operator":"equal","value":"normal"}}]}&relations=[{"obj":"az","condition":{"constraint":[{"logOp":"and","simple":{"name":"name","operator":"equal","value":"${option.DR_Storage_Room.value}"}}]}}] + description:

Select DR Protection Group

+ - label: Search DR Protection Group Name + name: DR_Protection_Group_Search + - enforced: true + name: DR_Protection_Group + required: true + valuesUrl: http://localhost:26337/deviceManager/rest/${option.DR_Storage.value}/data/v1/search/protectgroup?nameAttr=protectGroupName&valueAttr=protectGroupName&range=[0-100]&filter=NAME:${option.Country.value}0${option.DR_Protection_Group_Search.value} + description:

DR Test Snapshot Consistency Group

+ - enforced: true + name: DR_Test_CG + valuesUrl: http://localhost:26337/deviceManager/rest/${option.DR_Storage.value}/data/v1/associate/snapshot_consistency_group?nameAttr=NAME&valueAttr=NAME&matchAttr=NAME&match=${option.Session_Name.value}&range=[0-4096]&obj=protectgroup&objIdAttr=protectGroupId&filter=protectGroupName::${option.DR_Protection_Group.value} + - enforced: true + name: DR_Test_CG_Status + valuesUrl: http://localhost:26336/rest/data/v1/enum/SNAPCG?nameAttr=desc&valueAttr=enum&filter={"enum":${option.DR_Test_CG_Status_Enum.value}} + - enforced: true + name: Designate_Class_3 + valuesUrl: http://localhost:26336/rest/data/v1/search/tier?valueAttr=name + - delimiter: ',' + enforced: true + multivalued: true + name: Check_Result_1 + required: true + valuesUrl: http://localhost:26336/rest/data/v1/echo?snap=Activate%20DR%20Test%20Snapshot%20CG%20"${option.DR_Test_CG.value}" + description: Select to confirm the result

Additional Info

+ - enforced: true + name: Session_Name + valuesUrl: http://localhost:26337/deviceManager/rest/${option.DR_Storage.value}/data/v1/search/protectgroup?range=[0-100]&nameAttr=protectGroupName:0&nameSplit=_&valueAttr=protectGroupName:0&valueSplit=_&filter=NAME::${option.DR_Protection_Group.value} + - enforced: true + name: DR_CG + valuesUrl: http://localhost:26337/deviceManager/rest/${option.DR_Storage.value}/data/v1/search/CONSISTENTGROUP?nameAttr=NAME&valueAttr=NAME&range=[0-100]&filter=localPgName::${option.DR_Protection_Group.value}%20and%20RUNNINGSTATUS::1 + - enforced: true + name: DR_Test_CG_ID + valuesUrl: http://localhost:26337/deviceManager/rest/${option.DR_Storage.value}/data/v1/search/snapshot_consistency_group?nameAttr=ID&valueAttr=ID&filter=NAME::${option.DR_Test_CG.value} + - enforced: true + name: DR_Test_CG_Status_Enum + valuesUrl: http://localhost:26337/deviceManager/rest/${option.DR_Storage.value}/data/v1/search/snapshot_consistency_group?nameAttr=RUNNINGSTATUS&valueAttr=RUNNINGSTATUS&filter=NAME::${option.DR_Test_CG.value} + scheduleEnabled: true + sequence: + commands: + - configuration: + ansible-become: 'false' + ansible-disable-limit: 'false' + ansible-extra-vars: |- + username: ${option.Username} + password: ${option.Password} + + WBE_CODE: ${option.WBE_CODE} + TICKET_NUMBER: ${option.TICKET_NUMBER} + Country: ${option.Country} + Job_User: ${job.user.name} + + OS_Type: ${option.OS_Type} + DR_Storage: ${option.DR_Storage} + DR_Storage_Room: ${option.DR_Storage_Room} + DR_Protection_Group: ${option.DR_Protection_Group} + DR_CG: ${option.DR_CG} + DR_Test_CG: ${option.DR_Test_CG} + DR_Test_CG_ID: ${option.DR_Test_CG_ID} + DR_Test_CG_Status: ${option.DR_Test_CG_Status} + Designate_Class_3: ${option.Designate_Class_3} + Check_Result_1: ${option.Check_Result_1} + ansible-playbook: /var/lib/rundeck/ansible/rundeck/workflow/project001/53_dr_test_for_pg.yml + nodeStep: false + type: com.batix.rundeck.plugins.AnsiblePlaybookWorkflowStep + - configuration: + command: /bin/psql automation -c "\copy (select * from activity where WBE_CODE = '${option.WBE_CODE}' and TICKET_NUMBER = '${option.TICKET_NUMBER}') TO '/var/lib/rundeck/exp/webapp/project001/export/${job.name}-${job.execid}-${job.user.name}-${option.TICKET_NUMBER}.csv' CSV HEADER" + description: Export Changes + nodeStep: true + type: localexec + - configuration: + command: echo "${job.name}-${job.execid}-${job.user.name}-${option.TICKET_NUMBER}.csv" + description: Download Link + nodeStep: true + plugins: + LogFilter: + - config: + datatype: text/html + type: render-datatype + type: localexec + keepgoing: false + pluginConfig: + LogFilter: + - config: + bgcolor: green + regex: TASK.*Step_.* + type: highlight-output + - config: + bgcolor: red + regex: TASK.*Rollback_.* + type: highlight-output + - config: + bgcolor: blue + regex: TASK.*Precheck_.* + type: highlight-output + - config: + bgcolor: cyan + regex: TASK.*Result_.* + type: highlight-output + - config: + fgcolor: green + mode: bold + regex: ok=[1-9][0-9]* + type: highlight-output + - config: + fgcolor: red + mode: bold + regex: failed=[1-9][0-9]* + type: highlight-output + strategy: node-first + uuid: bf3196d6-5602-49eb-8158-39e69a875d01 diff --git a/rundeck/jobs/project001/54_dr_test_clean_for_pg.yaml b/rundeck/jobs/project001/54_dr_test_clean_for_pg.yaml new file mode 100644 index 0000000..1dd8455 --- /dev/null +++ b/rundeck/jobs/project001/54_dr_test_clean_for_pg.yaml @@ -0,0 +1,150 @@ +- defaultTab: monitor + description: Move WWNs from DR Test Host to DR Host, Re-Create Snapshot CG + executionEnabled: true + id: bbd5a12a-87e9-4ad1-9e45-49e5a7d10148 + loglevel: INFO + name: 54_dr_test_clean_for_pg + nodeFilterEditable: false + options: + - name: Job_Description + value: Move WWNs from DR Test Host to DR Host, Re-Create Snapshot CG + - name: Username + valuesUrl: http://localhost:26336/rest/data/v1/echo?${job.user.name}=${job.user.name} + description: (Optional) Alternative username/password to login all storage + - name: Password + secure: true + valueExposed: true + description:

Ticket

+ - required: true + name: WBE_CODE + valuesUrl: http://localhost:26336/rest/data/v1/echo?${DATE:YYYYMMddHHmmss}=timestamp + - required: true + name: TICKET_NUMBER + valuesUrl: http://localhost:26336/rest/data/v1/echo?${DATE:YYYYMMddHHmmss}=timestamp + description:

Select DR Host

+ - enforced: true + name: Country + required: true + valuesUrl: http://localhost:26336/rest/data/v1/search/project?pageNo=1&pageSize=100&valueAttr=name + - name: OS_Type + valuesUrl: http://localhost:26336/rest/data/v1/enum/OSTYPE?nameAttr=desc&valueAttr=key&filter={"enable":1} + - enforced: true + name: Site + required: true + valuesUrl: http://localhost:26336/rest/data/v1/enum/DC?nameAttr=desc&valueAttr=key + - enforced: true + name: DR_Storage_Room + valuesUrl: http://localhost:26336/rest/data/v1/enum/AZ?nameAttr=desc&valueAttr=key&filter={"dc":"${option.Site.value}"} + - enforced: true + name: DR_Storage + valuesUrl: http://localhost:26336/rest/data/v1/join/storage?pageNo=1&pageSize=100&nameAttr=deviceName&valueAttr=sn&condition={"constraint":[{"logOp":"and","simple":{"name":"dataStatus","operator":"equal","value":"normal"}}]}&relations=[{"obj":"az","condition":{"constraint":[{"logOp":"and","simple":{"name":"name","operator":"equal","value":"${option.DR_Storage_Room.value}"}}]}}] + description:

Select Primary Protection Group & LUNs

+ - label: Search DR Protection Group Name + name: DR_Protection_Group_Search + - enforced: true + name: DR_Protection_Group + required: true + valuesUrl: http://localhost:26337/deviceManager/rest/${option.DR_Storage.value}/data/v1/search/protectgroup?nameAttr=protectGroupName&valueAttr=protectGroupName&range=[0-100]&filter=NAME:${option.Country.value}0${option.DR_Protection_Group_Search.value} + description:

DR Test Snapshot Consistency Group

+ - enforced: true + name: DR_Test_CG + valuesUrl: http://localhost:26337/deviceManager/rest/${option.DR_Storage.value}/data/v1/associate/snapshot_consistency_group?nameAttr=NAME&valueAttr=NAME&matchAttr=NAME&match=${option.Session_Name.value}&range=[0-4096]&obj=protectgroup&objIdAttr=protectGroupId&filter=protectGroupName::${option.DR_Protection_Group.value} + - enforced: true + name: DR_Test_CG_Status + valuesUrl: http://localhost:26336/rest/data/v1/enum/SNAPCG?nameAttr=desc&valueAttr=enum&filter={"enum":${option.DR_Test_CG_Status_Enum.value}} + - enforced: true + name: Designate_Class_3 + valuesUrl: http://localhost:26336/rest/data/v1/search/tier?valueAttr=name + - delimiter: ',' + enforced: true + multivalued: true + name: Check_Result_1 + required: true + valuesUrl: http://localhost:26336/rest/data/v1/echo?snap=Activate%20DR%20Test%20Snapshot%20CG%20"${option.DR_Test_CG.value}" + description: Select to confirm the result

Additional Info

+ - enforced: true + name: Session_Name + valuesUrl: http://localhost:26337/deviceManager/rest/${option.DR_Storage.value}/data/v1/search/protectgroup?range=[0-100]&nameAttr=protectGroupName:0&nameSplit=_&valueAttr=protectGroupName:0&valueSplit=_&filter=NAME::${option.DR_Protection_Group.value} + - enforced: true + name: DR_CG + valuesUrl: http://localhost:26337/deviceManager/rest/${option.DR_Storage.value}/data/v1/search/CONSISTENTGROUP?nameAttr=NAME&valueAttr=NAME&range=[0-100]&filter=localPgName::${option.DR_Protection_Group.value}%20and%20RUNNINGSTATUS::1 + - enforced: true + name: DR_Test_CG_ID + valuesUrl: http://localhost:26337/deviceManager/rest/${option.DR_Storage.value}/data/v1/search/snapshot_consistency_group?nameAttr=ID&valueAttr=ID&filter=NAME::${option.DR_Test_CG.value} + - enforced: true + name: DR_Test_CG_Status_Enum + valuesUrl: http://localhost:26337/deviceManager/rest/${option.DR_Storage.value}/data/v1/search/snapshot_consistency_group?nameAttr=RUNNINGSTATUS&valueAttr=RUNNINGSTATUS&filter=NAME::${option.DR_Test_CG.value} + scheduleEnabled: true + sequence: + commands: + - configuration: + ansible-become: 'false' + ansible-disable-limit: 'false' + ansible-extra-vars: |- + username: ${option.Username} + password: ${option.Password} + + WBE_CODE: ${option.WBE_CODE} + TICKET_NUMBER: ${option.TICKET_NUMBER} + Country: ${option.Country} + Job_User: ${job.user.name} + + OS_Type: ${option.OS_Type} + DR_Storage: ${option.DR_Storage} + DR_Storage_Room: ${option.DR_Storage_Room} + DR_Protection_Group: ${option.DR_Protection_Group} + DR_CG: ${option.DR_CG} + DR_Test_CG: ${option.DR_Test_CG} + DR_Test_CG_ID: ${option.DR_Test_CG_ID} + DR_Test_CG_Status: ${option.DR_Test_CG_Status} + Designate_Class_3: ${option.Designate_Class_3} + Check_Result_1: ${option.Check_Result_1} + ansible-playbook: /var/lib/rundeck/ansible/rundeck/workflow/project001/54_dr_test_clean_for_pg.yml + nodeStep: false + type: com.batix.rundeck.plugins.AnsiblePlaybookWorkflowStep + - configuration: + command: /bin/psql automation -c "\copy (select * from activity where WBE_CODE = '${option.WBE_CODE}' and TICKET_NUMBER = '${option.TICKET_NUMBER}') TO '/var/lib/rundeck/exp/webapp/project001/export/${job.name}-${job.execid}-${job.user.name}-${option.TICKET_NUMBER}.csv' CSV HEADER" + description: Export Changes + nodeStep: true + type: localexec + - configuration: + command: echo "${job.name}-${job.execid}-${job.user.name}-${option.TICKET_NUMBER}.csv" + description: Download Link + nodeStep: true + plugins: + LogFilter: + - config: + datatype: text/html + type: render-datatype + type: localexec + keepgoing: false + pluginConfig: + LogFilter: + - config: + bgcolor: green + regex: TASK.*Step_.* + type: highlight-output + - config: + bgcolor: red + regex: TASK.*Rollback_.* + type: highlight-output + - config: + bgcolor: blue + regex: TASK.*Precheck_.* + type: highlight-output + - config: + bgcolor: cyan + regex: TASK.*Result_.* + type: highlight-output + - config: + fgcolor: green + mode: bold + regex: ok=[1-9][0-9]* + type: highlight-output + - config: + fgcolor: red + mode: bold + regex: failed=[1-9][0-9]* + type: highlight-output + strategy: node-first + uuid: bbd5a12a-87e9-4ad1-9e45-49e5a7d10148 diff --git a/rundeck/jobs/project001/55_dr_test_for_multi_host.yaml b/rundeck/jobs/project001/55_dr_test_for_multi_host.yaml new file mode 100644 index 0000000..fbcb255 --- /dev/null +++ b/rundeck/jobs/project001/55_dr_test_for_multi_host.yaml @@ -0,0 +1,121 @@ +- defaultTab: monitor + description: Move WWNs from DR Hosts to DR Test Hosts, Activate Snapshot CG + executionEnabled: true + id: 30173e49-6fc7-4079-80c0-39a5dd4820d9 + loglevel: INFO + name: 55_dr_test_for_multi_host + nodeFilterEditable: false + options: + - name: Job_Description + value: Move WWNs from DR Hosts to DR Test Hosts, Activate Snapshot CG + - name: Username + valuesUrl: http://localhost:26336/rest/data/v1/echo?${job.user.name}=${job.user.name} + description: (Optional) Alternative username/password to login all storage + - name: Password + secure: true + valueExposed: true + description:

Ticket

+ - required: true + name: WBE_CODE + valuesUrl: http://localhost:26336/rest/data/v1/echo?${DATE:YYYYMMddHHmmss}=timestamp + - required: true + name: TICKET_NUMBER + valuesUrl: http://localhost:26336/rest/data/v1/echo?${DATE:YYYYMMddHHmmss}=timestamp + description:

Select DR Host

+ - enforced: true + name: Country + required: true + valuesUrl: http://localhost:26336/rest/data/v1/search/project?pageNo=1&pageSize=100&valueAttr=name + - name: OS_Type + valuesUrl: http://localhost:26336/rest/data/v1/enum/OSTYPE?nameAttr=desc&valueAttr=key&filter={"enable":1} + - enforced: true + name: DR_Storage_Room + valuesUrl: http://localhost:26336/rest/data/v1/join/az?pageNo=1&pageSize=100&nameAttr=name&valueAttr=name + - enforced: true + name: DR_Storage + valuesUrl: http://localhost:26336/rest/data/v1/join/storage?pageNo=1&pageSize=100&nameAttr=deviceName&valueAttr=sn&condition={"constraint":[{"logOp":"and","simple":{"name":"dataStatus","operator":"equal","value":"normal"}}]}&relations=[{"obj":"az","condition":{"constraint":[{"logOp":"and","simple":{"name":"name","operator":"equal","value":"${option.DR_Storage_Room.value}"}}]}}] + - label: Search Host Name + name: Host_Search + - delimiter: ',' + enforced: true + label: DR Hosts + multivalued: true + name: Select_DR_Host + valuesUrl: http://localhost:26336/rest/data/v1/search/storagehost?pageNo=1&pageSize=100&nameAttr=name&valueAttr=name&valueUnique=true&condition={"constraint":[{"simple":{"name":"name","operator":"begin%20with","value":"${option.Country.value}_${option.OS_Type.value}"}},{"logOp":"and","simple":{"name":"name","operator":"contain","value":"${option.Host_Search.value}"}},{"logOp":"and","simple":{"name":"name","operator":"end%20with","value":"_2"}},{"logOp":"and","simple":{"name":"dataStatus","operator":"equal","value":"normal"}}]} + - name: Designate_Class_3 + valuesUrl: http://localhost:26336/rest/data/v1/search/tier?valueAttr=name + - delimiter: ',' + enforced: true + multivalued: true + name: Check_Result_1 + required: true + valuesUrl: http://localhost:26336/rest/data/v1/echo?host=Move%20WWNs%20from%20DR%20Hosts%20"${option.Select_DR_Host.value}"%20to%20DR%20Test%20Hosts%20"${option.Select_DR_Host.value}" + scheduleEnabled: true + sequence: + commands: + - configuration: + ansible-become: 'false' + ansible-disable-limit: 'false' + ansible-extra-vars: |- + username: ${option.Username} + password: ${option.Password} + + WBE_CODE: ${option.WBE_CODE} + TICKET_NUMBER: ${option.TICKET_NUMBER} + Country: ${option.Country} + Job_User: ${job.user.name} + + OS_Type: ${option.OS_Type} + DR_Storage: ${option.DR_Storage} + DR_Storage_Room: ${option.DR_Storage_Room} + Select_DR_Host: ${option.Select_DR_Host} + Check_Result_1: ${option.Check_Result_1} + ansible-playbook: /var/lib/rundeck/ansible/rundeck/workflow/project001/55_dr_test_for_multi_host.yml + nodeStep: false + type: com.batix.rundeck.plugins.AnsiblePlaybookWorkflowStep + - configuration: + command: /bin/psql automation -c "\copy (select * from activity where WBE_CODE = '${option.WBE_CODE}' and TICKET_NUMBER = '${option.TICKET_NUMBER}') TO '/var/lib/rundeck/exp/webapp/project001/export/${job.name}-${job.execid}-${job.user.name}-${option.TICKET_NUMBER}.csv' CSV HEADER" + description: Export Changes + nodeStep: true + type: localexec + - configuration: + command: echo "${job.name}-${job.execid}-${job.user.name}-${option.TICKET_NUMBER}.csv" + description: Download Link + nodeStep: true + plugins: + LogFilter: + - config: + datatype: text/html + type: render-datatype + type: localexec + keepgoing: false + pluginConfig: + LogFilter: + - config: + bgcolor: green + regex: TASK.*Step_.* + type: highlight-output + - config: + bgcolor: red + regex: TASK.*Rollback_.* + type: highlight-output + - config: + bgcolor: blue + regex: TASK.*Precheck_.* + type: highlight-output + - config: + bgcolor: cyan + regex: TASK.*Result_.* + type: highlight-output + - config: + fgcolor: green + mode: bold + regex: ok=[1-9][0-9]* + type: highlight-output + - config: + fgcolor: red + mode: bold + regex: failed=[1-9][0-9]* + type: highlight-output + strategy: node-first + uuid: 30173e49-6fc7-4079-80c0-39a5dd4820d9 diff --git a/rundeck/jobs/project001/56_dr_test_clean_for_multi_host.yaml b/rundeck/jobs/project001/56_dr_test_clean_for_multi_host.yaml new file mode 100644 index 0000000..5eb6a06 --- /dev/null +++ b/rundeck/jobs/project001/56_dr_test_clean_for_multi_host.yaml @@ -0,0 +1,119 @@ +- defaultTab: monitor + description: Move WWNs from DR Test Hosts to DR Hosts, Re-Create Snapshot CG + executionEnabled: true + id: 3d843ddc-6c18-4f73-ad9a-e67cda198aab + loglevel: INFO + name: 56_dr_test_clean_for_multi_host + nodeFilterEditable: false + options: + - name: Job_Description + value: Move WWNs from DR Test Hosts to DR Hosts, Re-Create Snapshot CG + - name: Username + valuesUrl: http://localhost:26336/rest/data/v1/echo?${job.user.name}=${job.user.name} + description: (Optional) Alternative username/password to login all storage + - name: Password + secure: true + valueExposed: true + description:

Ticket

+ - required: true + name: WBE_CODE + valuesUrl: http://localhost:26336/rest/data/v1/echo?${DATE:YYYYMMddHHmmss}=timestamp + - required: true + name: TICKET_NUMBER + valuesUrl: http://localhost:26336/rest/data/v1/echo?${DATE:YYYYMMddHHmmss}=timestamp + description:

Select DR Host

+ - enforced: true + name: Country + required: true + valuesUrl: http://localhost:26336/rest/data/v1/search/project?pageNo=1&pageSize=100&valueAttr=name + - name: OS_Type + valuesUrl: http://localhost:26336/rest/data/v1/enum/OSTYPE?nameAttr=desc&valueAttr=key&filter={"enable":1} + - enforced: true + name: DR_Storage_Room + valuesUrl: http://localhost:26336/rest/data/v1/join/az?pageNo=1&pageSize=100&nameAttr=name&valueAttr=name + - enforced: true + name: DR_Storage + valuesUrl: http://localhost:26336/rest/data/v1/join/storage?pageNo=1&pageSize=100&nameAttr=deviceName&valueAttr=sn&condition={"constraint":[{"logOp":"and","simple":{"name":"dataStatus","operator":"equal","value":"normal"}}]}&relations=[{"obj":"az","condition":{"constraint":[{"logOp":"and","simple":{"name":"name","operator":"equal","value":"${option.DR_Storage_Room.value}"}}]}}] + - label: Search Host Name + name: Host_Search + - delimiter: ',' + enforced: true + label: DR Hosts + multivalued: true + name: Select_DR_Host + valuesUrl: http://localhost:26336/rest/data/v1/search/storagehost?pageNo=1&pageSize=100&nameAttr=name&valueAttr=name&valueUnique=true&condition={"constraint":[{"simple":{"name":"name","operator":"begin%20with","value":"${option.Country.value}_${option.OS_Type.value}"}},{"logOp":"and","simple":{"name":"name","operator":"contain","value":"${option.Host_Search.value}"}},{"logOp":"and","simple":{"name":"name","operator":"end%20with","value":"_2"}},{"logOp":"and","simple":{"name":"dataStatus","operator":"equal","value":"normal"}}]} + - delimiter: ',' + enforced: true + multivalued: true + name: Check_Result_1 + required: true + valuesUrl: http://localhost:26336/rest/data/v1/echo?host=Move%20WWNs%20from%20DR%20Hosts%20"${option.Select_DR_Host.value}"%20to%20DR%20Test%20Hosts%20"${option.Select_DR_Host.value}" + scheduleEnabled: true + sequence: + commands: + - configuration: + ansible-become: 'false' + ansible-disable-limit: 'false' + ansible-extra-vars: |- + username: ${option.Username} + password: ${option.Password} + + WBE_CODE: ${option.WBE_CODE} + TICKET_NUMBER: ${option.TICKET_NUMBER} + Country: ${option.Country} + Job_User: ${job.user.name} + + OS_Type: ${option.OS_Type} + DR_Storage: ${option.DR_Storage} + DR_Storage_Room: ${option.DR_Storage_Room} + Select_DR_Host: ${option.Select_DR_Host} + Check_Result_1: ${option.Check_Result_1} + ansible-playbook: /var/lib/rundeck/ansible/rundeck/workflow/project001/56_dr_test_clean_for_multi_host.yml + nodeStep: false + type: com.batix.rundeck.plugins.AnsiblePlaybookWorkflowStep + - configuration: + command: /bin/psql automation -c "\copy (select * from activity where WBE_CODE = '${option.WBE_CODE}' and TICKET_NUMBER = '${option.TICKET_NUMBER}') TO '/var/lib/rundeck/exp/webapp/project001/export/${job.name}-${job.execid}-${job.user.name}-${option.TICKET_NUMBER}.csv' CSV HEADER" + description: Export Changes + nodeStep: true + type: localexec + - configuration: + command: echo "${job.name}-${job.execid}-${job.user.name}-${option.TICKET_NUMBER}.csv" + description: Download Link + nodeStep: true + plugins: + LogFilter: + - config: + datatype: text/html + type: render-datatype + type: localexec + keepgoing: false + pluginConfig: + LogFilter: + - config: + bgcolor: green + regex: TASK.*Step_.* + type: highlight-output + - config: + bgcolor: red + regex: TASK.*Rollback_.* + type: highlight-output + - config: + bgcolor: blue + regex: TASK.*Precheck_.* + type: highlight-output + - config: + bgcolor: cyan + regex: TASK.*Result_.* + type: highlight-output + - config: + fgcolor: green + mode: bold + regex: ok=[1-9][0-9]* + type: highlight-output + - config: + fgcolor: red + mode: bold + regex: failed=[1-9][0-9]* + type: highlight-output + strategy: node-first + uuid: 3d843ddc-6c18-4f73-ad9a-e67cda198aab diff --git a/rundeck/jobs/project001/57_dr_test_for_multi_cluster.yaml b/rundeck/jobs/project001/57_dr_test_for_multi_cluster.yaml new file mode 100644 index 0000000..6802d5e --- /dev/null +++ b/rundeck/jobs/project001/57_dr_test_for_multi_cluster.yaml @@ -0,0 +1,124 @@ +- defaultTab: monitor + description: Move WWNs from DR Hosts to DR Test Hosts, Activate Snapshot CG + executionEnabled: true + id: bbd23f67-65f8-432b-8d5c-2c31d40fd383 + loglevel: INFO + name: 57_dr_test_for_multi_cluster + nodeFilterEditable: false + options: + - name: Job_Description + value: Move WWNs from DR Hosts to DR Test Hosts, Activate Snapshot CG + - name: Username + valuesUrl: http://localhost:26336/rest/data/v1/echo?${job.user.name}=${job.user.name} + description: (Optional) Alternative username/password to login all storage + - name: Password + secure: true + valueExposed: true + description:

Ticket

+ - required: true + name: WBE_CODE + valuesUrl: http://localhost:26336/rest/data/v1/echo?${DATE:YYYYMMddHHmmss}=timestamp + - required: true + name: TICKET_NUMBER + valuesUrl: http://localhost:26336/rest/data/v1/echo?${DATE:YYYYMMddHHmmss}=timestamp + description:

Select DR Cluster

+ - enforced: true + name: Country + required: true + valuesUrl: http://localhost:26336/rest/data/v1/search/project?pageNo=1&pageSize=100&valueAttr=name + - name: OS_Type + valuesUrl: http://localhost:26336/rest/data/v1/enum/OSTYPE?nameAttr=desc&valueAttr=key&filter={"enable":1} + - enforced: true + name: DR_Storage_Room + valuesUrl: http://localhost:26336/rest/data/v1/join/az?pageNo=1&pageSize=100&nameAttr=name&valueAttr=name + - enforced: true + name: DR_Storage + valuesUrl: http://localhost:26336/rest/data/v1/join/storage?pageNo=1&pageSize=100&nameAttr=deviceName&valueAttr=sn&condition={"constraint":[{"logOp":"and","simple":{"name":"dataStatus","operator":"equal","value":"normal"}}]}&relations=[{"obj":"az","condition":{"constraint":[{"logOp":"and","simple":{"name":"name","operator":"equal","value":"${option.DR_Storage_Room.value}"}}]}}] + - label: Search Cluster Name + name: Cluster_Search + - delimiter: ',' + enforced: true + label: DR Hosts + multivalued: true + name: Select_DR_Cluster + valuesUrl: http://localhost:26337/deviceManager/rest/${option.DR_Storage.value}/data/v1/search/hostgroup?range=[0-100]&nameAttr=NAME&valueAttr=NAME&filter=NAME:${option.Country.value}_${option.OS_Type.value}_${option.Cluster_Search.value} + - name: Designate_Class_3 + valuesUrl: http://localhost:26336/rest/data/v1/search/tier?valueAttr=name + - delimiter: ',' + enforced: true + multivalued: true + name: Check_Result_1 + required: true + valuesUrl: http://localhost:26336/rest/data/v1/echo?cluster=Move%20WWNs%20from%20DR%20Hosts%20in%20Cluster%20"${option.Select_DR_Cluster.value}"%20to%20DR%20Test%20Hosts%20in%20Cluster%20" + description: Select to confirm the result + scheduleEnabled: true + sequence: + commands: + - configuration: + ansible-become: 'false' + ansible-disable-limit: 'false' + ansible-extra-vars: |- + username: ${option.Username} + password: ${option.Password} + + WBE_CODE: ${option.WBE_CODE} + TICKET_NUMBER: ${option.TICKET_NUMBER} + Country: ${option.Country} + Job_User: ${job.user.name} + + OS_Type: ${option.OS_Type} + DR_Storage_Room: ${option.DR_Storage_Room} + DR_Storage: ${option.DR_Storage} + Select_DR_Cluster: ${option.Select_DR_Cluster} + Class_3: ${option.Class_3} + Designate_Class_3: ${option.Designate_Class_3} + Check_Result_1: ${option.Check_Result_1} + ansible-playbook: /var/lib/rundeck/ansible/rundeck/workflow/project001/57_dr_test_for_multi_cluster.yml + nodeStep: false + type: com.batix.rundeck.plugins.AnsiblePlaybookWorkflowStep + - configuration: + command: /bin/psql automation -c "\copy (select * from activity where WBE_CODE = '${option.WBE_CODE}' and TICKET_NUMBER = '${option.TICKET_NUMBER}') TO '/var/lib/rundeck/exp/webapp/project001/export/${job.name}-${job.execid}-${job.user.name}-${option.TICKET_NUMBER}.csv' CSV HEADER" + description: Export Changes + nodeStep: true + type: localexec + - configuration: + command: echo "${job.name}-${job.execid}-${job.user.name}-${option.TICKET_NUMBER}.csv" + description: Download Link + nodeStep: true + plugins: + LogFilter: + - config: + datatype: text/html + type: render-datatype + type: localexec + keepgoing: false + pluginConfig: + LogFilter: + - config: + bgcolor: green + regex: TASK.*Step_.* + type: highlight-output + - config: + bgcolor: red + regex: TASK.*Rollback_.* + type: highlight-output + - config: + bgcolor: blue + regex: TASK.*Precheck_.* + type: highlight-output + - config: + bgcolor: cyan + regex: TASK.*Result_.* + type: highlight-output + - config: + fgcolor: green + mode: bold + regex: ok=[1-9][0-9]* + type: highlight-output + - config: + fgcolor: red + mode: bold + regex: failed=[1-9][0-9]* + type: highlight-output + strategy: node-first + uuid: bbd23f67-65f8-432b-8d5c-2c31d40fd383 diff --git a/rundeck/jobs/project001/58_dr_test_clean_for_multi_cluster.yaml b/rundeck/jobs/project001/58_dr_test_clean_for_multi_cluster.yaml new file mode 100644 index 0000000..db60997 --- /dev/null +++ b/rundeck/jobs/project001/58_dr_test_clean_for_multi_cluster.yaml @@ -0,0 +1,120 @@ +- defaultTab: monitor + description: Move WWNs from DR Test Hosts to DR Hosts, Re-Create Snapshot CG + executionEnabled: true + id: 9654a965-0129-497e-b386-408c9cc2fdcf + loglevel: INFO + name: 58_dr_test_clean_for_multi_cluster + nodeFilterEditable: false + options: + - name: Job_Description + value: Move WWNs from DR Test Hosts to DR Hosts, Re-Create Snapshot CG + - name: Username + valuesUrl: http://localhost:26336/rest/data/v1/echo?${job.user.name}=${job.user.name} + description: (Optional) Alternative username/password to login all storage + - name: Password + secure: true + valueExposed: true + description:

Ticket

+ - required: true + name: WBE_CODE + valuesUrl: http://localhost:26336/rest/data/v1/echo?${DATE:YYYYMMddHHmmss}=timestamp + - required: true + name: TICKET_NUMBER + valuesUrl: http://localhost:26336/rest/data/v1/echo?${DATE:YYYYMMddHHmmss}=timestamp + description:

Select DR Cluster

+ - enforced: true + name: Country + required: true + valuesUrl: http://localhost:26336/rest/data/v1/search/project?pageNo=1&pageSize=100&valueAttr=name + - name: OS_Type + valuesUrl: http://localhost:26336/rest/data/v1/enum/OSTYPE?nameAttr=desc&valueAttr=key&filter={"enable":1} + - enforced: true + name: DR_Storage_Room + valuesUrl: http://localhost:26336/rest/data/v1/join/az?pageNo=1&pageSize=100&nameAttr=name&valueAttr=name + - enforced: true + name: DR_Storage + valuesUrl: http://localhost:26336/rest/data/v1/join/storage?pageNo=1&pageSize=100&nameAttr=deviceName&valueAttr=sn&condition={"constraint":[{"logOp":"and","simple":{"name":"dataStatus","operator":"equal","value":"normal"}}]}&relations=[{"obj":"az","condition":{"constraint":[{"logOp":"and","simple":{"name":"name","operator":"equal","value":"${option.DR_Storage_Room.value}"}}]}}] + - label: Search Cluster Name + name: Cluster_Search + - delimiter: ',' + enforced: true + label: DR Hosts + multivalued: true + name: Select_DR_Test_Cluster + valuesUrl: http://localhost:26337/deviceManager/rest/${option.DR_Storage.value}/data/v1/search/hostgroup?range=[0-100]&nameAttr=NAME&valueAttr=NAME&filter=NAME:${option.Country.value}_${option.OS_Type.value}_${option.Cluster_Search.value} + - delimiter: ',' + enforced: true + multivalued: true + name: Check_Result_1 + required: true + valuesUrl: http://localhost:26336/rest/data/v1/echo?cluster=Move%20WWNs%20from%20DR%20Hosts%20in%20Cluster%20"${option.Select_DR_Cluster.value}"%20to%20DR%20Test%20Hosts%20in%20Cluster%20" + description: Select to confirm the result + scheduleEnabled: true + sequence: + commands: + - configuration: + ansible-become: 'false' + ansible-disable-limit: 'false' + ansible-extra-vars: |- + username: ${option.Username} + password: ${option.Password} + + WBE_CODE: ${option.WBE_CODE} + TICKET_NUMBER: ${option.TICKET_NUMBER} + Country: ${option.Country} + Job_User: ${job.user.name} + + OS_Type: ${option.OS_Type} + DR_Storage_Room: ${option.DR_Storage_Room} + DR_Storage: ${option.DR_Storage} + Select_DR_Test_Cluster: ${option.Select_DR_Test_Cluster} + Check_Result_1: ${option.Check_Result_1} + ansible-playbook: /var/lib/rundeck/ansible/rundeck/workflow/project001/58_dr_test_clean_for_multi_cluster.yml + nodeStep: false + type: com.batix.rundeck.plugins.AnsiblePlaybookWorkflowStep + - configuration: + command: /bin/psql automation -c "\copy (select * from activity where WBE_CODE = '${option.WBE_CODE}' and TICKET_NUMBER = '${option.TICKET_NUMBER}') TO '/var/lib/rundeck/exp/webapp/project001/export/${job.name}-${job.execid}-${job.user.name}-${option.TICKET_NUMBER}.csv' CSV HEADER" + description: Export Changes + nodeStep: true + type: localexec + - configuration: + command: echo "${job.name}-${job.execid}-${job.user.name}-${option.TICKET_NUMBER}.csv" + description: Download Link + nodeStep: true + plugins: + LogFilter: + - config: + datatype: text/html + type: render-datatype + type: localexec + keepgoing: false + pluginConfig: + LogFilter: + - config: + bgcolor: green + regex: TASK.*Step_.* + type: highlight-output + - config: + bgcolor: red + regex: TASK.*Rollback_.* + type: highlight-output + - config: + bgcolor: blue + regex: TASK.*Precheck_.* + type: highlight-output + - config: + bgcolor: cyan + regex: TASK.*Result_.* + type: highlight-output + - config: + fgcolor: green + mode: bold + regex: ok=[1-9][0-9]* + type: highlight-output + - config: + fgcolor: red + mode: bold + regex: failed=[1-9][0-9]* + type: highlight-output + strategy: node-first + uuid: 9654a965-0129-497e-b386-408c9cc2fdcf diff --git a/rundeck/projects/project001/readme.md b/rundeck/projects/project001/readme.md index 616e613..2ecb715 100644 --- a/rundeck/projects/project001/readme.md +++ b/rundeck/projects/project001/readme.md @@ -315,4 +315,75 @@ + + +### Protection Group + + + + + + + + + + + + + + + + +
49 - Create PG50 - Add LUNs to PG51 - Remove LUNs from PG52 - Delete PG
+ + + + + + + +
+ + + + + + + + + + + + +
53 - DR Test for PG54 - DR Test Clean for PG
+ + + +
+ +### Multi Host DR Test + + + + + + + + + + + + + + + +
55 - Multi Host DR Test56 - Multi Host DR Test Clean57 - Multi Cluster DR Test58 - Multi Cluster DR Test Clean
+ + + + + + + +
\ No newline at end of file diff --git a/rundeck/webapp/project001/images/49_create_pg.png b/rundeck/webapp/project001/images/49_create_pg.png new file mode 100644 index 0000000..6a91d6d Binary files /dev/null and b/rundeck/webapp/project001/images/49_create_pg.png differ diff --git a/rundeck/webapp/project001/images/50_add_luns_to_pg.png b/rundeck/webapp/project001/images/50_add_luns_to_pg.png new file mode 100644 index 0000000..f0bb824 Binary files /dev/null and b/rundeck/webapp/project001/images/50_add_luns_to_pg.png differ diff --git a/rundeck/webapp/project001/images/51_remove_luns_from_pg.png b/rundeck/webapp/project001/images/51_remove_luns_from_pg.png new file mode 100644 index 0000000..2978869 Binary files /dev/null and b/rundeck/webapp/project001/images/51_remove_luns_from_pg.png differ diff --git a/rundeck/webapp/project001/images/52_delete_pg.png b/rundeck/webapp/project001/images/52_delete_pg.png new file mode 100644 index 0000000..0747bc1 Binary files /dev/null and b/rundeck/webapp/project001/images/52_delete_pg.png differ diff --git a/rundeck/webapp/project001/images/53_dr_test_for_pg.png b/rundeck/webapp/project001/images/53_dr_test_for_pg.png new file mode 100644 index 0000000..e8ac595 Binary files /dev/null and b/rundeck/webapp/project001/images/53_dr_test_for_pg.png differ diff --git a/rundeck/webapp/project001/images/54_dr_test_clean_for_pg.png b/rundeck/webapp/project001/images/54_dr_test_clean_for_pg.png new file mode 100644 index 0000000..e79cfa3 Binary files /dev/null and b/rundeck/webapp/project001/images/54_dr_test_clean_for_pg.png differ diff --git a/rundeck/webapp/project001/images/55_dr_test_for_multi_host.png b/rundeck/webapp/project001/images/55_dr_test_for_multi_host.png new file mode 100644 index 0000000..4a57123 Binary files /dev/null and b/rundeck/webapp/project001/images/55_dr_test_for_multi_host.png differ diff --git a/rundeck/webapp/project001/images/56_dr_test_clean_for_multi_host.png b/rundeck/webapp/project001/images/56_dr_test_clean_for_multi_host.png new file mode 100644 index 0000000..7fc0ec5 Binary files /dev/null and b/rundeck/webapp/project001/images/56_dr_test_clean_for_multi_host.png differ diff --git a/rundeck/webapp/project001/images/57_dr_test_for_multi_cluster.png b/rundeck/webapp/project001/images/57_dr_test_for_multi_cluster.png new file mode 100644 index 0000000..e2d240b Binary files /dev/null and b/rundeck/webapp/project001/images/57_dr_test_for_multi_cluster.png differ diff --git a/rundeck/webapp/project001/images/58_dr_test_clean_for_multi_cluster.png b/rundeck/webapp/project001/images/58_dr_test_clean_for_multi_cluster.png new file mode 100644 index 0000000..e4c14f1 Binary files /dev/null and b/rundeck/webapp/project001/images/58_dr_test_clean_for_multi_cluster.png differ diff --git a/rundeck/workflow/project001/01_create_host.yml b/rundeck/workflow/project001/01_create_host.yml index 4e60743..9960b18 100644 --- a/rundeck/workflow/project001/01_create_host.yml +++ b/rundeck/workflow/project001/01_create_host.yml @@ -30,7 +30,7 @@ Host_WWN: "{{ checked_host_wwns|unique == [True] }}" Class_1: "{{ Class_1 in ['A','B','C','D'] }}" Cluster_Name: "{{ (Cluster_Name is none) or (Cluster_Name[0:2] == Country and Cluster_Name[3:6] == OS_Type and Cluster_Name[-1:] == '1' ) }}" - Session_Name: "{{ (Session_Name is none) or (Session_Name|length <= 16 and '_' not in Session_Name) }}" + Session_Name: "{{ (Session_Name is none) or (Session_Name|length <= 13 and '_' not in Session_Name) }}" Enable_HyperMetro: "{{ Enable_HyperMetro in ['Y','N'] }}" Protection_Level: "{{ Protection_Level|int in [1,2,3] }}" Check_Result_1: "{{ ('host' in Check_Result_1) and ('wwn' in Check_Result_1) and ('cluster' in Check_Result_1 if Cluster_Name is not none else True) }}" diff --git a/rundeck/workflow/project001/03_modify_host_info.yml b/rundeck/workflow/project001/03_modify_host_info.yml index ed87ec5..6391759 100644 --- a/rundeck/workflow/project001/03_modify_host_info.yml +++ b/rundeck/workflow/project001/03_modify_host_info.yml @@ -16,7 +16,7 @@ Modify_Host_Name: "{{ (Modify_Host_Name is none) or (Modify_Host_Name|length <= 16 and '_' not in Modify_Host_Name) }}" Modify_Host_Description: "{{ (Modify_Host_Description is none) or (Modify_Host_Description|length <= 64) }}" Modify_Class_1: "{{ (Modify_Class_1 is none) or (Modify_Class_1 in ['A','B','C','D']) }}" - Modify_Session_Name: "{{ (Modify_Session_Name is none) or (Modify_Session_Name[0:3] == Country + '0' and Modify_Session_Name|length <= 19 and '_' not in Modify_Session_Name) }}" + Modify_Session_Name: "{{ (Modify_Session_Name is none) or (Modify_Session_Name[0:3] == Country + '0' and Modify_Session_Name|length <= 16 and '_' not in Modify_Session_Name) }}" Check_Result_1: "{{ 'host' in Check_Result_1 }}" - name: Precheck_0_1 - Check Host Params @@ -143,24 +143,17 @@ - set_fact: primaryLunIds: [] primaryLunNames: [] - primaryLunDesc: [] primaryLunNamesNew: [] - primaryLunDescNew: [] metroLunIds: [] metroLunNames: [] - metroLunDesc: [] metroLunNamesNew: [] - metroLunDescNew: [] drLunIds: [] drLunNames: [] - drLunDesc: [] drLunNamesNew: [] - drLunDescNew: [] drTestLunIds: [] drTestLunNames: [] - drTestLunDesc: [] drTestLunNamesNew: [] - drTestLunDescNew: [] + lunNameTemplate: "%s_%s_%s_%s_%s_%s_%s_%s" # Example: IT_AIX_HOST1MV_1, TS0000, A, 00, H3, MV, IT0DJGSS01, T1 - set_fact: Precheck_0_Execute: True @@ -223,12 +216,12 @@ primaryLgId: "{{ lgIds[0] }}" primaryLunIds: "{{ checkedLuns[primaryLgName] | json_query('[*].ID') }}" primaryLunNames: "{{ checkedLuns[primaryLgName] | json_query('[*].NAME') }}" - primaryLunDesc: "{{ checkedLuns[primaryLgName] | json_query('[*].DESCRIPTION') }}" - set_fact: - primaryLunNamesNew: "{{ primaryLunNamesNew + [ primaryHostNameNew + primaryLunNames[item.0][-6:] ] }}" - primaryLunDescNew: "{{ primaryLunDescNew + [ class1New + primaryLunDesc[item.0][1:] | replace(sessionName, sessionNameNew) ] }}" - with_indexed_items: "{{ primaryLunIds }}" + primaryLunNamesNew: "{{ primaryLunNamesNew + [ lunNameTemplate | format(primaryHostNameNew, old[4], class1New, old[6], old[7], old[8], sessionNameNew, old[10]) ] }}" + vars: + old: "{{ item.split('_') }}" + with_items: "{{ primaryLunNames }}" when: primaryLunIds|length > 0 - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_pgs.yml" @@ -272,12 +265,12 @@ metroLgId: "{{ lgIds[0] }}" metroLunIds: "{{ checkedLuns[primaryLgName] | json_query('[*].ID') }}" metroLunNames: "{{ checkedLuns[primaryLgName] | json_query('[*].NAME') }}" - metroLunDesc: "{{ checkedLuns[primaryLgName] | json_query('[*].DESCRIPTION') }}" - set_fact: - metroLunNamesNew: "{{ metroLunNamesNew + [ primaryHostNameNew + metroLunNames[item.0][-6:] ] }}" - metroLunDescNew: "{{ metroLunDescNew + [ class1New + metroLunDesc[item.0][1:] | replace(sessionName, sessionNameNew)] }}" - with_indexed_items: "{{ metroLunIds }}" + metroLunNamesNew: "{{ metroLunNamesNew + [ lunNameTemplate | format(primaryHostNameNew, old[4], class1New, old[6], old[7], old[8], sessionNameNew, old[10]) ] }}" + vars: + old: "{{ item.split('_') }}" + with_items: "{{ metroLunNames }}" when: metroLunIds|length > 0 - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_pgs.yml" @@ -322,12 +315,12 @@ drLgId: "{{ lgIds[0] }}" drLunIds: "{{ checkedLuns[drLgName] | json_query('[*].ID') }}" drLunNames: "{{ checkedLuns[drLgName] | json_query('[*].NAME') }}" - drLunDesc: "{{ checkedLuns[drLgName] | json_query('[*].DESCRIPTION') }}" - set_fact: - drLunNamesNew: "{{ drLunNamesNew + [ drHostNameNew + drLunNames[item.0][-6:] ] }}" - drLunDescNew: "{{ drLunDescNew + [ class1New + drLunDesc[item.0][1:] | replace(sessionName, sessionNameNew)] }}" - with_indexed_items: "{{ drLunIds }}" + drLunNamesNew: "{{ drLunNamesNew + [ lunNameTemplate | format(drHostNameNew, old[4], class2New, old[6], old[7], old[8], sessionNameNew, old[10]) ] }}" + vars: + old: "{{ item.split('_') }}" + with_items: "{{ drLunNames }}" when: drLunIds|length > 0 - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_pgs.yml" @@ -359,12 +352,12 @@ drTestLgId: "{{ lgIds[0] }}" drTestLunIds: "{{ checkedLuns[drTestLgName] | json_query('[*].ID') }}" drTestLunNames: "{{ checkedLuns[drTestLgName] | json_query('[*].NAME') }}" - drTestLunDesc: "{{ checkedLuns[drTestLgName] | json_query('[*].DESCRIPTION') }}" - set_fact: - drTestLunNamesNew: "{{ drTestLunNamesNew + [ drTestHostNameNew + drTestLunNames[item.0][-6:] ] }}" - drTestLunDescNew: "{{ drTestLunDescNew + [ class1New + drTestLunDesc[item.0][1:] | replace(sessionName, sessionNameNew)] }}" - with_indexed_items: "{{ drTestLunIds }}" + drTestLunNamesNew: "{{ drTestLunNamesNew + [ lunNameTemplate | format(drTestHostNameNew, old[4], class3New, old[6], old[7], old[8], sessionNameNew, old[10]) ] }}" + vars: + old: "{{ item.split('_') }}" + with_items: "{{ drTestLunNames }}" when: drTestLunIds|length > 0 - name: Query Snapshot CG by Name @@ -422,7 +415,7 @@ Step_1_1_Rollbacked: False # Modify Primary LUNs - Step_1_2_Execute: "{{ (primaryLunIds|length > 0) and ((primaryLunNames|sort != primaryLunNamesNew|sort) or (primaryLunDesc|sort != primaryLunDescNew|sort) ) }}" + Step_1_2_Execute: "{{ (primaryLunIds|length > 0) and (primaryLunNames|sort != primaryLunNamesNew|sort) }}" Step_1_2_Completed: False Step_1_2_Rollbacked: False @@ -457,7 +450,7 @@ Step_2_1_Rollbacked: False # Modify Metro LUNs - Step_2_2_Execute: "{{ (metroEnable == 'Y') and (metroLunIds|length > 0) and ((metroLunNames|sort != metroLunNamesNew|sort) or (metroLunDesc|sort != metroLunDescNew|sort) ) and (metroEnable == 'Y') }}" + Step_2_2_Execute: "{{ (metroEnable == 'Y') and (metroLunIds|length > 0) and (metroLunNames|sort != metroLunNamesNew|sort) and (metroEnable == 'Y') }}" Step_2_2_Completed: False Step_2_2_Rollbacked: False @@ -482,7 +475,7 @@ Step_3_1_Rollbacked: False # Modify DR LUNs - Step_3_2_Execute: "{{ (protectLevel|int >= 2) and (drLunIds|length > 0) and ((drLunNames|sort != drLunNamesNew|sort) or (drLunDesc|sort != drLunDescNew|sort) ) }}" + Step_3_2_Execute: "{{ (protectLevel|int >= 2) and (drLunIds|length > 0) and (drLunNames|sort != drLunNamesNew|sort) }}" Step_3_2_Completed: False Step_3_2_Rollbacked: False @@ -502,7 +495,7 @@ Step_4_1_Rollbacked: False # Modify DR Test LUNs - Step_4_2_Execute: "{{ (protectLevel|int == 3) and (drTestLunIds|length > 0) and ((drTestLunNames|sort != drTestLunNamesNew|sort) or (drTestLunDesc|sort != drTestLunDescNew|sort) ) }}" + Step_4_2_Execute: "{{ (protectLevel|int == 3) and (drTestLunIds|length > 0) and (drTestLunNames|sort != drTestLunNamesNew|sort) }}" Step_4_2_Completed: False Step_4_2_Rollbacked: False @@ -597,7 +590,11 @@ new: "{{ class1New }}" old: "{{ class1 }}" - - import_tasks: "{{GLOBAL.baseDir}}/task/volume/change_volumes_to_tier.yml" + - import_tasks: "{{GLOBAL.baseDir}}/task/volume/remove_volumes_from_tier.yml" + vars: + volumeNames: "{{ primaryLunNames }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/volume/add_volumes_to_tier.yml" vars: volumeNames: "{{ primaryLunNames }}" tierName: "{{ class1New }}" @@ -617,7 +614,11 @@ new: "{{ class1New }}" old: "{{ class1 }}" - - import_tasks: "{{GLOBAL.baseDir}}/task/volume/change_volumes_to_tier.yml" + - import_tasks: "{{GLOBAL.baseDir}}/task/volume/remove_volumes_from_tier.yml" + vars: + volumeNames: "{{ metroLunNames }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/volume/add_volumes_to_tier.yml" vars: volumeNames: "{{ metroLunNames }}" tierName: "{{ class1New }}" @@ -637,7 +638,11 @@ new: "{{ class2New }}" old: "{{ class2 }}" - - import_tasks: "{{GLOBAL.baseDir}}/task/volume/change_volumes_to_tier.yml" + - import_tasks: "{{GLOBAL.baseDir}}/task/volume/remove_volumes_from_tier.yml" + vars: + volumeNames: "{{ drLunNames }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/volume/add_volumes_to_tier.yml" vars: volumeNames: "{{ drLunNames }}" tierName: "{{ class2New }}" @@ -688,9 +693,6 @@ name: old: "{{ primaryLunNames }}" new: "{{ primaryLunNamesNew }}" - desc: - old: "{{ primaryLunDesc }}" - new: "{{ primaryLunDescNew }}" device: "{{ primaryDeviceName }}" - include_tasks: "{{GLOBAL.baseDir}}/task/volume/rename_volumes.yml" @@ -698,21 +700,6 @@ volumeNames: "{{ primaryLunNames }}" newVolumeNames: "{{ primaryLunNamesNew }}" - - set_fact: - deviceHost: "{{ primaryDeviceHost }}" - devicePort: "{{ primaryDevicePort }}" - deviceSn: "{{ primaryDeviceSn }}" - deviceToken: "{{ primaryDeviceToken }}" - deviceSession: "{{ primaryDeviceSession }}" - - - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/modify_lun.yml" - vars: - modifyLunId: "{{ primaryLunIds[i] }}" - desc: "{{ primaryLunDescNew[i] }}" - loop: "{{ range(0, primaryLunIds|length) | list }}" - loop_control: - loop_var: i - - set_fact: Step_1_2_Completed: True @@ -907,9 +894,6 @@ name: old: "{{ metroLunNames }}" new: "{{ metroLunNamesNew }}" - desc: - old: "{{ metroLunDesc }}" - new: "{{ metroLunDescNew }}" device: "{{ metroDeviceName }}" - include_tasks: "{{GLOBAL.baseDir}}/task/volume/rename_volumes.yml" @@ -917,21 +901,6 @@ volumeNames: "{{ metroLunNames }}" newVolumeNames: "{{ metroLunNamesNew }}" - - set_fact: - deviceHost: "{{ metroDeviceHost }}" - devicePort: "{{ metroDevicePort }}" - deviceSn: "{{ metroDeviceSn }}" - deviceToken: "{{ metroDeviceToken }}" - deviceSession: "{{ metroDeviceSession }}" - - - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/modify_lun.yml" - vars: - modifyLunId: "{{ metroLunIds[i] }}" - desc: "{{ metroLunDescNew[i] }}" - loop: "{{ range(0, metroLunIds|length) | list }}" - loop_control: - loop_var: i - - set_fact: Step_2_2_Completed: True @@ -1070,9 +1039,6 @@ name: old: "{{ drLunNames }}" new: "{{ drLunNamesNew }}" - desc: - old: "{{ drLunDesc }}" - new: "{{ drLunDescNew }}" device: "{{ drDeviceName }}" - include_tasks: "{{GLOBAL.baseDir}}/task/volume/rename_volumes.yml" @@ -1080,21 +1046,6 @@ volumeNames: "{{ drLunNames }}" newVolumeNames: "{{ drLunNamesNew }}" - - set_fact: - deviceHost: "{{ drDeviceHost }}" - devicePort: "{{ drDevicePort }}" - deviceSn: "{{ drDeviceSn }}" - deviceToken: "{{ drDeviceToken }}" - deviceSession: "{{ drDeviceSession }}" - - - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/modify_lun.yml" - vars: - modifyLunId: "{{ drLunIds[i] }}" - desc: "{{ drLunDescNew[i] }}" - loop: "{{ range(0, drLunIds|length) | list }}" - loop_control: - loop_var: i - - set_fact: Step_3_2_Completed: True @@ -1206,9 +1157,6 @@ name: old: "{{ drTestLunNames }}" new: "{{ drTestLunNamesNew }}" - desc: - old: "{{ drTestLunDesc }}" - new: "{{ drTestLunDescNew }}" device: "{{ drDeviceName }}" - include_tasks: "{{GLOBAL.baseDir}}/task/volume/rename_volumes.yml" @@ -1216,21 +1164,6 @@ volumeNames: "{{ drTestLunNames }}" newVolumeNames: "{{ drTestLunNamesNew }}" - - set_fact: - deviceHost: "{{ drDeviceHost }}" - devicePort: "{{ drDevicePort }}" - deviceSn: "{{ drDeviceSn }}" - deviceToken: "{{ drDeviceToken }}" - deviceSession: "{{ drDeviceSession }}" - - - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/modify_lun.yml" - vars: - modifyLunId: "{{ drTestLunIds[i] }}" - desc: "{{ drTestLunDescNew[i] }}" - loop: "{{ range(0, drTestLunIds|length) | list }}" - loop_control: - loop_var: i - - set_fact: Step_4_2_Completed: True @@ -1369,9 +1302,6 @@ name: old: "{{ drTestLunNamesNew }}" new: "{{ drTestLunNames }}" - desc: - old: "{{ drTestLunDescNew }}" - new: "{{ drTestLunDesc }}" device: "{{ drDeviceName }}" - include_tasks: "{{GLOBAL.baseDir}}/task/volume/rename_volumes.yml" @@ -1379,21 +1309,6 @@ volumeNames: "{{ drTestLunNamesNew }}" newVolumeNames: "{{ drTestLunNames }}" - - set_fact: - deviceHost: "{{ drDeviceHost }}" - devicePort: "{{ drDevicePort }}" - deviceSn: "{{ drDeviceSn }}" - deviceToken: "{{ drDeviceToken }}" - deviceSession: "{{ drDeviceSession }}" - - - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/modify_lun.yml" - vars: - modifyLunId: "{{ drTestLunIds[i] }}" - desc: "{{ drTestLunDesc[i] }}" - loop: "{{ range(0, drTestLunIds|length) | list }}" - loop_control: - loop_var: i - - set_fact: Step_4_2_Rollbacked: True @@ -1504,9 +1419,6 @@ name: old: "{{ drLunNamesNew }}" new: "{{ drLunNames }}" - desc: - old: "{{ drLunDescNew }}" - new: "{{ drLunDesc }}" device: "{{ drDeviceName }}" - include_tasks: "{{GLOBAL.baseDir}}/task/volume/rename_volumes.yml" @@ -1514,21 +1426,6 @@ volumeNames: "{{ drLunNamesNew }}" newVolumeNames: "{{ drLunNames }}" - - set_fact: - deviceHost: "{{ drDeviceHost }}" - devicePort: "{{ drDevicePort }}" - deviceSn: "{{ drDeviceSn }}" - deviceToken: "{{ drDeviceToken }}" - deviceSession: "{{ drDeviceSession }}" - - - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/modify_lun.yml" - vars: - modifyLunId: "{{ drLunIds[i] }}" - desc: "{{ drLunDesc[i] }}" - loop: "{{ range(0, drLunIds|length) | list }}" - loop_control: - loop_var: i - - set_fact: Step_3_2_Rollbacked: True @@ -1667,9 +1564,6 @@ name: old: "{{ metroLunNamesNew }}" new: "{{ metroLunNames }}" - desc: - old: "{{ metroLunDescNew }}" - new: "{{ metroLunDesc }}" device: "{{ metroDeviceName }}" - include_tasks: "{{GLOBAL.baseDir}}/task/volume/rename_volumes.yml" @@ -1684,14 +1578,6 @@ deviceToken: "{{ metroDeviceToken }}" deviceSession: "{{ metroDeviceSession }}" - - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/modify_lun.yml" - vars: - modifyLunId: "{{ metroLunIds[i] }}" - desc: "{{ metroLunDesc[i] }}" - loop: "{{ range(0, metroLunIds|length) | list }}" - loop_control: - loop_var: i - - set_fact: Step_2_2_Rollbacked: True @@ -1886,9 +1772,6 @@ name: old: "{{ primaryLunNamesNew }}" new: "{{ primaryLunNames }}" - desc: - old: "{{ primaryLunDescNew }}" - new: "{{ primaryLunDesc }}" device: "{{ primaryDeviceName }}" - include_tasks: "{{GLOBAL.baseDir}}/task/volume/rename_volumes.yml" @@ -1896,21 +1779,6 @@ volumeNames: "{{ primaryLunNamesNew }}" newVolumeNames: "{{ primaryLunNames }}" - - set_fact: - deviceHost: "{{ primaryDeviceHost }}" - devicePort: "{{ primaryDevicePort }}" - deviceSn: "{{ primaryDeviceSn }}" - deviceToken: "{{ primaryDeviceToken }}" - deviceSession: "{{ primaryDeviceSession }}" - - - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/modify_lun.yml" - vars: - modifyLunId: "{{ primaryLunIds[i] }}" - desc: "{{ primaryLunDesc[i] }}" - loop: "{{ range(0, primaryLunIds|length) | list }}" - loop_control: - loop_var: i - - set_fact: Step_1_2_Rollbacked: True @@ -1958,7 +1826,11 @@ new: "{{ class2 }}" old: "{{ class2New }}" - - import_tasks: "{{GLOBAL.baseDir}}/task/volume/change_volumes_to_tier.yml" + - import_tasks: "{{GLOBAL.baseDir}}/task/volume/remove_volumes_from_tier.yml" + vars: + volumeNames: "{{ drLunNames }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/volume/add_volumes_to_tier.yml" vars: volumeNames: "{{ drLunNames }}" tierName: "{{ class2 }}" @@ -1978,7 +1850,11 @@ new: "{{ class1 }}" old: "{{ class1New }}" - - import_tasks: "{{GLOBAL.baseDir}}/task/volume/change_volumes_to_tier.yml" + - import_tasks: "{{GLOBAL.baseDir}}/task/volume/remove_volumes_from_tier.yml" + vars: + volumeNames: "{{ metroLunNames }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/volume/add_volumes_to_tier.yml" vars: volumeNames: "{{ metroLunNames }}" tierName: "{{ class1 }}" @@ -1998,7 +1874,11 @@ new: "{{ class1 }}" old: "{{ class1New }}" - - import_tasks: "{{GLOBAL.baseDir}}/task/volume/change_volumes_to_tier.yml" + - import_tasks: "{{GLOBAL.baseDir}}/task/volume/remove_volumes_from_tier.yml" + vars: + volumeNames: "{{ primaryLunNames }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/volume/add_volumes_to_tier.yml" vars: volumeNames: "{{ primaryLunNames }}" tierName: "{{ class1 }}" @@ -2228,9 +2108,6 @@ name: old: "{{ primaryLunNames }}" new: "{{ primaryLunNamesNew }}" - desc: - old: "{{ primaryLunDesc }}" - new: "{{ primaryLunDescNew }}" device: "{{ primaryDeviceName }}" result: succeeded: "{{ Step_1_2_Completed }}" @@ -2345,9 +2222,6 @@ name: old: "{{ metroLunNames }}" new: "{{ metroLunNamesNew }}" - desc: - old: "{{ metroLunDesc }}" - new: "{{ metroLunDescNew }}" device: "{{ metroDeviceName }}" result: succeeded: "{{ Step_2_2_Completed }}" @@ -2432,9 +2306,6 @@ name: old: "{{ drLunNames }}" new: "{{ drLunNamesNew }}" - desc: - old: "{{ drLunDesc }}" - new: "{{ drLunDescNew }}" device: "{{ drDeviceName }}" result: succeeded: "{{ Step_3_2_Completed }}" @@ -2504,9 +2375,6 @@ name: old: "{{ drTestLunNames }}" new: "{{ drTestLunNamesNew }}" - desc: - old: "{{ drTestLunDesc }}" - new: "{{ drTestLunDescNew }}" device: "{{ drDeviceName }}" result: succeeded: "{{ Step_4_2_Completed }}" diff --git a/rundeck/workflow/project001/05_create_cluster.yml b/rundeck/workflow/project001/05_create_cluster.yml index 7bf07bf..6816343 100644 --- a/rundeck/workflow/project001/05_create_cluster.yml +++ b/rundeck/workflow/project001/05_create_cluster.yml @@ -29,7 +29,7 @@ Cluster_Description: "{{ (Cluster_Description is none) or (Cluster_Description|length <= 64) }}" Hosts: "{{ (checked_cluster_hosts|unique == [True]) }}" Class_1: "{{ Class_1 in ['A','B','C','D'] }}" - Session_Name: "{{ (Session_Name is none) or (Session_Name|length <= 16 and '_' not in Session_Name) }}" + Session_Name: "{{ (Session_Name is none) or (Session_Name|length <= 13 and '_' not in Session_Name) }}" Enable_HyperMetro: "{{ Enable_HyperMetro in ['Y','N'] }}" Protection_Level: "{{ Protection_Level|int in [1,2,3] }}" Check_Result_1: "{{ ('cluster' in Check_Result_1) and (Hosts is none or 'hosts' in Check_Result_1) }}" diff --git a/rundeck/workflow/project001/07_modify_cluster_info.yml b/rundeck/workflow/project001/07_modify_cluster_info.yml index 7adcc69..d6543d2 100644 --- a/rundeck/workflow/project001/07_modify_cluster_info.yml +++ b/rundeck/workflow/project001/07_modify_cluster_info.yml @@ -15,7 +15,7 @@ Modify_Cluster_Name: "{{ (Modify_Cluster_Name is none) or (Modify_Cluster_Name|length <= 16 and '_' not in Modify_Cluster_Name) }}" Modify_Cluster_Description: "{{ (Modify_Cluster_Description is none) or (Modify_Cluster_Description|length <= 64) }}" Modify_Class_1: "{{ (Modify_Class_1 is none) or (Modify_Class_1 in ['A','B','C','D']) }}" - Modify_Session_Name: "{{ (Modify_Session_Name is none) or (Modify_Session_Name[0:3] == Country + '0' and Modify_Session_Name|length <= 19 and '_' not in Modify_Session_Name) }}" + Modify_Session_Name: "{{ (Modify_Session_Name is none) or (Modify_Session_Name[0:3] == Country + '0' and Modify_Session_Name|length <= 16 and '_' not in Modify_Session_Name) }}" Check_Result_1: "{{ ('cluster' in Check_Result_1) }}" - name: Precheck_0_1 - Check Params @@ -142,24 +142,17 @@ - set_fact: primaryLunIds: [] primaryLunNames: [] - primaryLunDesc: [] primaryLunNamesNew: [] - primaryLunDescNew: [] metroLunIds: [] metroLunNames: [] - metroLunDesc: [] metroLunNamesNew: [] - metroLunDescNew: [] drLunIds: [] drLunNames: [] - drLunDesc: [] drLunNamesNew: [] - drLunDescNew: [] drTestLunIds: [] drTestLunNames: [] - drTestLunDesc: [] drTestLunNamesNew: [] - drTestLunDescNew: [] + lunNameTemplate: "%s_%s_%s_%s_%s_%s_%s_%s" # Example: IT_AIX_HOST1MV_1, TS0000, A, 00, H3, MV, IT0DJGSS01, T1 - set_fact: Precheck_1_Execute: True @@ -201,12 +194,12 @@ primaryLgId: "{{ lgIds[0] }}" primaryLunIds: "{{ checkedLuns[primaryLgName] | json_query('[*].ID') }}" primaryLunNames: "{{ checkedLuns[primaryLgName] | json_query('[*].NAME') }}" - primaryLunDesc: "{{ checkedLuns[primaryLgName] | json_query('[*].DESCRIPTION') }}" - set_fact: - primaryLunNamesNew: "{{ primaryLunNamesNew + [ primaryClusterNameNew + primaryLunNames[item.0][-6:] ] }}" - primaryLunDescNew: "{{ primaryLunDescNew + [ class1New + primaryLunDesc[item.0][1:] | replace(sessionName, sessionNameNew) ] }}" - with_indexed_items: "{{ primaryLunIds }}" + primaryLunNamesNew: "{{ primaryLunNamesNew + [ lunNameTemplate | format(primaryClusterNameNew, old[4], class1New, old[6], old[7], old[8], sessionNameNew, old[10]) ] }}" + vars: + old: "{{ item.split('_') }}" + with_items: "{{ primaryLunNames }}" when: primaryLunIds|length > 0 - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_pgs.yml" @@ -250,12 +243,12 @@ metroLgId: "{{ lgIds[0] }}" metroLunIds: "{{ checkedLuns[primaryLgName] | json_query('[*].ID') }}" metroLunNames: "{{ checkedLuns[primaryLgName] | json_query('[*].NAME') }}" - metroLunDesc: "{{ checkedLuns[primaryLgName] | json_query('[*].DESCRIPTION') }}" - set_fact: - metroLunNamesNew: "{{ metroLunNamesNew + [ primaryClusterNameNew + metroLunNames[item.0][-6:] ] }}" - metroLunDescNew: "{{ metroLunDescNew + [ class1New + metroLunDesc[item.0][1:] | replace(sessionName, sessionNameNew)] }}" - with_indexed_items: "{{ metroLunIds }}" + metroLunNamesNew: "{{ metroLunNamesNew + [ lunNameTemplate | format(primaryClusterNameNew, old[4], class1New, old[6], old[7], old[8], sessionNameNew, old[10]) ] }}" + vars: + old: "{{ item.split('_') }}" + with_items: "{{ metroLunNames }}" when: metroLunIds|length > 0 - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_pgs.yml" @@ -300,12 +293,12 @@ drLgId: "{{ lgIds[0] }}" drLunIds: "{{ checkedLuns[drLgName] | json_query('[*].ID') }}" drLunNames: "{{ checkedLuns[drLgName] | json_query('[*].NAME') }}" - drLunDesc: "{{ checkedLuns[drLgName] | json_query('[*].DESCRIPTION') }}" - set_fact: - drLunNamesNew: "{{ drLunNamesNew + [ drClusterNameNew + drLunNames[item.0][-6:] ] }}" - drLunDescNew: "{{ drLunDescNew + [ class1New + drLunDesc[item.0][1:] | replace(sessionName, sessionNameNew)] }}" - with_indexed_items: "{{ drLunIds }}" + drLunNamesNew: "{{ drLunNamesNew + [ lunNameTemplate | format(drClusterNameNew, old[4], class2New, old[6], old[7], old[8], sessionNameNew, old[10]) ] }}" + vars: + old: "{{ item.split('_') }}" + with_items: "{{ drLunNames }}" when: drLunIds|length > 0 - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_pgs.yml" @@ -337,12 +330,12 @@ drTestLgId: "{{ lgIds[0] }}" drTestLunIds: "{{ checkedLuns[drTestLgName] | json_query('[*].ID') }}" drTestLunNames: "{{ checkedLuns[drTestLgName] | json_query('[*].NAME') }}" - drTestLunDesc: "{{ checkedLuns[drTestLgName] | json_query('[*].DESCRIPTION') }}" - set_fact: - drTestLunNamesNew: "{{ drTestLunNamesNew + [ drTestClusterNameNew + drTestLunNames[item.0][-6:] ] }}" - drTestLunDescNew: "{{ drTestLunDescNew + [ class1New + drTestLunDesc[item.0][1:] | replace(sessionName, sessionNameNew)] }}" - with_indexed_items: "{{ drTestLunIds }}" + drTestLunNamesNew: "{{ drTestLunNamesNew + [ lunNameTemplate | format(drTestClusterNameNew, old[4], class3New, old[6], old[7], old[8], sessionNameNew, old[10]) ] }}" + vars: + old: "{{ item.split('_') }}" + with_items: "{{ drTestLunNames }}" when: drTestLunIds|length > 0 - name: Query Snapshot CG by Name @@ -391,7 +384,7 @@ Step_1_1_Rollbacked: False # Modify Primary LUNs - Step_1_2_Execute: "{{ (primaryLunIds|length > 0) and ((primaryLunNames|sort != primaryLunNamesNew|sort) or (primaryLunDesc|sort != primaryLunDescNew|sort) ) }}" + Step_1_2_Execute: "{{ (primaryLunIds|length > 0) and (primaryLunNames|sort != primaryLunNamesNew|sort) }}" Step_1_2_Completed: False Step_1_2_Rollbacked: False @@ -426,7 +419,7 @@ Step_2_1_Rollbacked: False # Modify Metro LUNs - Step_2_2_Execute: "{{ (metroEnable == 'Y') and (metroLunIds|length > 0) and ((metroLunNames|sort != metroLunNamesNew|sort) or (metroLunDesc|sort != metroLunDescNew|sort) ) }}" + Step_2_2_Execute: "{{ (metroEnable == 'Y') and (metroLunIds|length > 0) and (metroLunNames|sort != metroLunNamesNew|sort) }}" Step_2_2_Completed: False Step_2_2_Rollbacked: False @@ -451,7 +444,7 @@ Step_3_1_Rollbacked: False # Modify DR LUNs - Step_3_2_Execute: "{{ (protectLevel|int >= 2) and (drLunIds|length > 0) and ((drLunNames|sort != drLunNamesNew|sort) or (drLunDesc|sort != drLunDescNew|sort) ) }}" + Step_3_2_Execute: "{{ (protectLevel|int >= 2) and (drLunIds|length > 0) and (drLunNames|sort != drLunNamesNew|sort) }}" Step_3_2_Completed: False Step_3_2_Rollbacked: False @@ -471,7 +464,7 @@ Step_4_1_Rollbacked: False # Modify DR Test LUNs - Step_4_2_Execute: "{{ (protectLevel|int == 3) and (drTestLunIds|length > 0) and ((drTestLunNames|sort != drTestLunNamesNew|sort) or (drTestLunDesc|sort != drTestLunDescNew|sort) ) }}" + Step_4_2_Execute: "{{ (protectLevel|int == 3) and (drTestLunIds|length > 0) and (drTestLunNames|sort != drTestLunNamesNew|sort) }}" Step_4_2_Completed: False Step_4_2_Rollbacked: False @@ -523,7 +516,11 @@ new: "{{ class1New }}" old: "{{ class1 }}" - - import_tasks: "{{GLOBAL.baseDir}}/task/volume/change_volumes_to_tier.yml" + - import_tasks: "{{GLOBAL.baseDir}}/task/volume/remove_volumes_from_tier.yml" + vars: + volumeNames: "{{ primaryLunNames }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/volume/add_volumes_to_tier.yml" vars: volumeNames: "{{ primaryLunNames }}" tierName: "{{ class1New }}" @@ -543,7 +540,11 @@ new: "{{ class1New }}" old: "{{ class1 }}" - - import_tasks: "{{GLOBAL.baseDir}}/task/volume/change_volumes_to_tier.yml" + - import_tasks: "{{GLOBAL.baseDir}}/task/volume/remove_volumes_from_tier.yml" + vars: + volumeNames: "{{ metroLunNames }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/volume/add_volumes_to_tier.yml" vars: volumeNames: "{{ metroLunNames }}" tierName: "{{ class1New }}" @@ -563,7 +564,11 @@ new: "{{ class2New }}" old: "{{ class2 }}" - - import_tasks: "{{GLOBAL.baseDir}}/task/volume/change_volumes_to_tier.yml" + - import_tasks: "{{GLOBAL.baseDir}}/task/volume/remove_volumes_from_tier.yml" + vars: + volumeNames: "{{ drLunNames }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/volume/add_volumes_to_tier.yml" vars: volumeNames: "{{ drLunNames }}" tierName: "{{ class2New }}" @@ -614,9 +619,6 @@ name: old: "{{ primaryLunNames }}" new: "{{ primaryLunNamesNew }}" - desc: - old: "{{ primaryLunDesc }}" - new: "{{ primaryLunDescNew }}" device: "{{ primaryDeviceName }}" - include_tasks: "{{GLOBAL.baseDir}}/task/volume/rename_volumes.yml" @@ -624,21 +626,6 @@ volumeNames: "{{ primaryLunNames }}" newVolumeNames: "{{ primaryLunNamesNew }}" - - set_fact: - deviceHost: "{{ primaryDeviceHost }}" - devicePort: "{{ primaryDevicePort }}" - deviceSn: "{{ primaryDeviceSn }}" - deviceToken: "{{ primaryDeviceToken }}" - deviceSession: "{{ primaryDeviceSession }}" - - - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/modify_lun.yml" - vars: - modifyLunId: "{{ primaryLunIds[i] }}" - desc: "{{ primaryLunDescNew[i] }}" - loop: "{{ range(0, primaryLunIds|length) | list }}" - loop_control: - loop_var: i - - set_fact: Step_1_2_Completed: True @@ -833,9 +820,6 @@ name: old: "{{ metroLunNames }}" new: "{{ metroLunNamesNew }}" - desc: - old: "{{ metroLunDesc }}" - new: "{{ metroLunDescNew }}" device: "{{ metroDeviceName }}" - include_tasks: "{{GLOBAL.baseDir}}/task/volume/rename_volumes.yml" @@ -843,21 +827,6 @@ volumeNames: "{{ metroLunNames }}" newVolumeNames: "{{ metroLunNamesNew }}" - - set_fact: - deviceHost: "{{ metroDeviceHost }}" - devicePort: "{{ metroDevicePort }}" - deviceSn: "{{ metroDeviceSn }}" - deviceToken: "{{ metroDeviceToken }}" - deviceSession: "{{ metroDeviceSession }}" - - - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/modify_lun.yml" - vars: - modifyLunId: "{{ metroLunIds[i] }}" - desc: "{{ metroLunDescNew[i] }}" - loop: "{{ range(0, metroLunIds|length) | list }}" - loop_control: - loop_var: i - - set_fact: Step_2_2_Completed: True @@ -996,9 +965,6 @@ name: old: "{{ drLunNames }}" new: "{{ drLunNamesNew }}" - desc: - old: "{{ drLunDesc }}" - new: "{{ drLunDescNew }}" device: "{{ drDeviceName }}" - include_tasks: "{{GLOBAL.baseDir}}/task/volume/rename_volumes.yml" @@ -1006,21 +972,6 @@ volumeNames: "{{ drLunNames }}" newVolumeNames: "{{ drLunNamesNew }}" - - set_fact: - deviceHost: "{{ drDeviceHost }}" - devicePort: "{{ drDevicePort }}" - deviceSn: "{{ drDeviceSn }}" - deviceToken: "{{ drDeviceToken }}" - deviceSession: "{{ drDeviceSession }}" - - - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/modify_lun.yml" - vars: - modifyLunId: "{{ drLunIds[i] }}" - desc: "{{ drLunDescNew[i] }}" - loop: "{{ range(0, drLunIds|length) | list }}" - loop_control: - loop_var: i - - set_fact: Step_3_2_Completed: True @@ -1132,9 +1083,6 @@ name: old: "{{ drTestLunNames }}" new: "{{ drTestLunNamesNew }}" - desc: - old: "{{ drTestLunDesc }}" - new: "{{ drTestLunDescNew }}" device: "{{ drDeviceName }}" - include_tasks: "{{GLOBAL.baseDir}}/task/volume/rename_volumes.yml" @@ -1142,21 +1090,6 @@ volumeNames: "{{ drTestLunNames }}" newVolumeNames: "{{ drTestLunNamesNew }}" - - set_fact: - deviceHost: "{{ drDeviceHost }}" - devicePort: "{{ drDevicePort }}" - deviceSn: "{{ drDeviceSn }}" - deviceToken: "{{ drDeviceToken }}" - deviceSession: "{{ drDeviceSession }}" - - - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/modify_lun.yml" - vars: - modifyLunId: "{{ drTestLunIds[i] }}" - desc: "{{ drTestLunDescNew[i] }}" - loop: "{{ range(0, drTestLunIds|length) | list }}" - loop_control: - loop_var: i - - set_fact: Step_4_2_Completed: True @@ -1224,7 +1157,7 @@ # End Steps rescue: - # Begin Rollback + # Begin Rollback - block: - name: Rollback_4_4 - Modify DR Test CG Name @@ -1295,9 +1228,6 @@ name: old: "{{ drTestLunNamesNew }}" new: "{{ drTestLunNames }}" - desc: - old: "{{ drTestLunDescNew }}" - new: "{{ drTestLunDesc }}" device: "{{ drDeviceName }}" - include_tasks: "{{GLOBAL.baseDir}}/task/volume/rename_volumes.yml" @@ -1305,21 +1235,6 @@ volumeNames: "{{ drTestLunNamesNew }}" newVolumeNames: "{{ drTestLunNames }}" - - set_fact: - deviceHost: "{{ drDeviceHost }}" - devicePort: "{{ drDevicePort }}" - deviceSn: "{{ drDeviceSn }}" - deviceToken: "{{ drDeviceToken }}" - deviceSession: "{{ drDeviceSession }}" - - - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/modify_lun.yml" - vars: - modifyLunId: "{{ drTestLunIds[i] }}" - desc: "{{ drTestLunDesc[i] }}" - loop: "{{ range(0, drTestLunIds|length) | list }}" - loop_control: - loop_var: i - - set_fact: Step_4_2_Rollbacked: True @@ -1430,9 +1345,6 @@ name: old: "{{ drLunNamesNew }}" new: "{{ drLunNames }}" - desc: - old: "{{ drLunDescNew }}" - new: "{{ drLunDesc }}" device: "{{ drDeviceName }}" - include_tasks: "{{GLOBAL.baseDir}}/task/volume/rename_volumes.yml" @@ -1440,21 +1352,6 @@ volumeNames: "{{ drLunNamesNew }}" newVolumeNames: "{{ drLunNames }}" - - set_fact: - deviceHost: "{{ drDeviceHost }}" - devicePort: "{{ drDevicePort }}" - deviceSn: "{{ drDeviceSn }}" - deviceToken: "{{ drDeviceToken }}" - deviceSession: "{{ drDeviceSession }}" - - - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/modify_lun.yml" - vars: - modifyLunId: "{{ drLunIds[i] }}" - desc: "{{ drLunDesc[i] }}" - loop: "{{ range(0, drLunIds|length) | list }}" - loop_control: - loop_var: i - - set_fact: Step_3_2_Rollbacked: True @@ -1593,9 +1490,6 @@ name: old: "{{ metroLunNamesNew }}" new: "{{ metroLunNames }}" - desc: - old: "{{ metroLunDescNew }}" - new: "{{ metroLunDesc }}" device: "{{ metroDeviceName }}" - include_tasks: "{{GLOBAL.baseDir}}/task/volume/rename_volumes.yml" @@ -1603,21 +1497,6 @@ volumeNames: "{{ metroLunNamesNew }}" newVolumeNames: "{{ metroLunNames }}" - - set_fact: - deviceHost: "{{ metroDeviceHost }}" - devicePort: "{{ metroDevicePort }}" - deviceSn: "{{ metroDeviceSn }}" - deviceToken: "{{ metroDeviceToken }}" - deviceSession: "{{ metroDeviceSession }}" - - - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/modify_lun.yml" - vars: - modifyLunId: "{{ metroLunIds[i] }}" - desc: "{{ metroLunDesc[i] }}" - loop: "{{ range(0, metroLunIds|length) | list }}" - loop_control: - loop_var: i - - set_fact: Step_2_2_Rollbacked: True @@ -1812,9 +1691,6 @@ name: old: "{{ primaryLunNamesNew }}" new: "{{ primaryLunNames }}" - desc: - old: "{{ primaryLunDescNew }}" - new: "{{ primaryLunDesc }}" device: "{{ primaryDeviceName }}" - include_tasks: "{{GLOBAL.baseDir}}/task/volume/rename_volumes.yml" @@ -1822,21 +1698,6 @@ volumeNames: "{{ primaryLunNamesNew }}" newVolumeNames: "{{ primaryLunNames }}" - - set_fact: - deviceHost: "{{ primaryDeviceHost }}" - devicePort: "{{ primaryDevicePort }}" - deviceSn: "{{ primaryDeviceSn }}" - deviceToken: "{{ primaryDeviceToken }}" - deviceSession: "{{ primaryDeviceSession }}" - - - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/modify_lun.yml" - vars: - modifyLunId: "{{ primaryLunIds[i] }}" - desc: "{{ primaryLunDesc[i] }}" - loop: "{{ range(0, primaryLunIds|length) | list }}" - loop_control: - loop_var: i - - set_fact: Step_1_2_Rollbacked: True @@ -1884,7 +1745,11 @@ new: "{{ class2 }}" old: "{{ class2New }}" - - import_tasks: "{{GLOBAL.baseDir}}/task/volume/change_volumes_to_tier.yml" + - import_tasks: "{{GLOBAL.baseDir}}/task/volume/remove_volumes_from_tier.yml" + vars: + volumeNames: "{{ drLunNames }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/volume/add_volumes_to_tier.yml" vars: volumeNames: "{{ drLunNames }}" tierName: "{{ class2 }}" @@ -1904,7 +1769,11 @@ new: "{{ class1 }}" old: "{{ class1New }}" - - import_tasks: "{{GLOBAL.baseDir}}/task/volume/change_volumes_to_tier.yml" + - import_tasks: "{{GLOBAL.baseDir}}/task/volume/remove_volumes_from_tier.yml" + vars: + volumeNames: "{{ metroLunNames }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/volume/add_volumes_to_tier.yml" vars: volumeNames: "{{ metroLunNames }}" tierName: "{{ class1 }}" @@ -1924,7 +1793,11 @@ new: "{{ class1 }}" old: "{{ class1New }}" - - import_tasks: "{{GLOBAL.baseDir}}/task/volume/change_volumes_to_tier.yml" + - import_tasks: "{{GLOBAL.baseDir}}/task/volume/remove_volumes_from_tier.yml" + vars: + volumeNames: "{{ primaryLunNames }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/volume/add_volumes_to_tier.yml" vars: volumeNames: "{{ primaryLunNames }}" tierName: "{{ class1 }}" @@ -1936,7 +1809,7 @@ # End Rollbacks always: - # Begin Final steps + # Begin Final steps - name: Final_Step_1 - Sync Devices set_fact: @@ -2085,9 +1958,6 @@ name: old: "{{ primaryLunNames }}" new: "{{ primaryLunNamesNew }}" - desc: - old: "{{ primaryLunDesc }}" - new: "{{ primaryLunDescNew }}" device: "{{ primaryDeviceName }}" result: succeeded: "{{ Step_1_2_Completed }}" @@ -2202,9 +2072,6 @@ name: old: "{{ metroLunNames }}" new: "{{ metroLunNamesNew }}" - desc: - old: "{{ metroLunDesc }}" - new: "{{ metroLunDescNew }}" device: "{{ metroDeviceName }}" result: succeeded: "{{ Step_2_2_Completed }}" @@ -2289,9 +2156,6 @@ name: old: "{{ drLunNames }}" new: "{{ drLunNamesNew }}" - desc: - old: "{{ drLunDesc }}" - new: "{{ drLunDescNew }}" device: "{{ drDeviceName }}" result: succeeded: "{{ Step_3_2_Completed }}" @@ -2361,9 +2225,6 @@ name: old: "{{ drTestLunNames }}" new: "{{ drTestLunNamesNew }}" - desc: - old: "{{ drTestLunDesc }}" - new: "{{ drTestLunDescNew }}" device: "{{ drDeviceName }}" result: succeeded: "{{ Step_4_2_Completed }}" diff --git a/rundeck/workflow/project001/09_create_luns_for_host.yml b/rundeck/workflow/project001/09_create_luns_for_host.yml index e4f795d..79c333c 100644 --- a/rundeck/workflow/project001/09_create_luns_for_host.yml +++ b/rundeck/workflow/project001/09_create_luns_for_host.yml @@ -14,7 +14,7 @@ Storage: "{{ (Storage is not none and Storage != DEFAULT.noneValue) and (Storage|string|length == 20) }}" LUN_Size: "{{ (LUN_Size is not none) and (LUN_Size|int >= 1) }}" LUN_Num: "{{ (LUN_Num is not none) and (LUN_Num|int >= 1) }}" - LUN_Description: "{{ (LUN_Description is none) or (LUN_Description|string|length <= 200) }}" + LUN_Description: "{{ (LUN_Description is none) or (LUN_Description|string|length <= 255) }}" Class_1: "{{ Class_1 in ['A','B','C','D'] }}" Designate_Class_1: "{{ (Designate_Class_1 is none) or (Designate_Class_1 in ['A','B','C','D']) }}" Check_Result_1: "{{ ('lun' in Check_Result_1) }}" @@ -125,14 +125,14 @@ replicaType: "{{ REPTYPE[metroEnable+protectLevel|string]['type'] }}" # See ../../config/project001.yml - set_fact: - lunNameTemplate: "%s%0{{DEFAULT.suffixDigits}}d" + lunNameTemplate: "%s%0{{DEFAULT.suffixDigits}}d_%s" primaryLunPrefix: "{{primaryHostName}}_{{protectType}}{{'S' if metroEnable == 'Y' else 'N'}}" - primaryLunDesc: "{{ class1 }}_00_{{replicaType}}_{{'00' if replicaType == '00' else primaryRoom}}_{{'0000000000000000' if replicaType == '00' else sessionName}}_{{'0' if replicaType == '00' else protectType}}1|{{lunRemarks}}" + primaryLunSuffix: "{{ class1 }}_00_{{replicaType}}_{{'00' if replicaType == '00' else primaryRoom}}_{{'0000000000000000' if replicaType == '00' else sessionName}}_{{'0' if replicaType == '00' else protectType}}1" metroLunPrefix: "{{metroHostName}}_{{protectType}}M" drLunPrefix: "{{drHostName}}_{{protectType}}N" - drLunDesc: "{{ class2 }}_00_{{replicaType}}_{{primaryRoom}}_{{sessionName}}_{{protectType}}2|{{lunRemarks}}" + drLunSuffix: "{{ class2 }}_00_{{replicaType}}_{{primaryRoom}}_{{sessionName}}_{{protectType}}2" drTestLunPrefix: "{{drTestHostName}}_{{protectType}}N" - drTestLunDesc: "{{ class3 }}_00_00_{{primaryRoom}}_{{sessionName}}_{{protectType}}3|{{lunRemarks}}" + drTestLunSuffix: "{{ class3 }}_00_00_{{primaryRoom}}_{{sessionName}}_{{protectType}}3" drTestCgNameDefault: "{{ replicaType }}_{{ primaryRoom }}_{{ sessionName }}_{{ protectType }}3" drStarCgNameDefault: "{{ replicaType }}_{{ primaryRoom }}_{{ sessionName }}_{{ protectType }}0" @@ -214,7 +214,7 @@ primaryLunNames: [] - set_fact: - primaryLunNames: "{{ primaryLunNames + [ lunNameTemplate | format(primaryLunPrefix, nextScsiId|int + item|int) ] }}" + primaryLunNames: "{{ primaryLunNames + [ lunNameTemplate | format(primaryLunPrefix, (nextScsiId|int + item|int), primaryLunSuffix) ] }}" with_sequence: start=0 count="{{lunNum}}" - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_luns.yml" @@ -264,7 +264,7 @@ metroLunNames: [] - set_fact: - metroLunNames: "{{ metroLunNames + [ lunNameTemplate | format(metroLunPrefix, nextScsiId|int + item|int) ] }}" + metroLunNames: "{{ metroLunNames + [ lunNameTemplate | format(metroLunPrefix, (nextScsiId|int + item|int), primaryLunSuffix) ] }}" with_sequence: start=0 count="{{lunNum}}" - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_luns.yml" @@ -317,7 +317,7 @@ drLunNames: [] - set_fact: - drLunNames: "{{ drLunNames + [ lunNameTemplate | format(drLunPrefix, nextScsiId|int + item|int) ] }}" + drLunNames: "{{ drLunNames + [ lunNameTemplate | format(drLunPrefix, (nextScsiId|int + item|int), drLunSuffix) ] }}" with_sequence: start=0 count="{{lunNum}}" - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_luns.yml" @@ -358,8 +358,8 @@ drTestLunDescs: [] - set_fact: - drTestLunNames: "{{ drTestLunNames + [ lunNameTemplate | format(drTestLunPrefix, nextScsiId|int + item|int) ] }}" - drTestLunDescs: "{{ drTestLunDescs + [drTestLunDesc] }}" + drTestLunNames: "{{ drTestLunNames + [ lunNameTemplate | format(drTestLunPrefix, (nextScsiId|int + item|int), drTestLunSuffix) ] }}" + drTestLunDescs: "{{ drTestLunDescs + [lunRemarks] }}" with_sequence: start=0 count="{{lunNum}}" - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_luns.yml" @@ -557,12 +557,11 @@ msg: params: luns: - lunNamePrefix: "{{ primaryLunPrefix }}" - startSuffix: "{{ nextScsiId }}" + newLunNames: "{{ primaryLunNames }}" startScsiId: "{{ nextScsiId }}" poolId: "{{ primaryPoolId }}" workload: "{{ primaryWorkload }}" - desc: "{{ primaryLunDesc }}" + desc: "{{ lunRemarks }}" addLgName: "{{ primaryLgName }}" device: "{{ primaryDeviceName }}" @@ -575,17 +574,15 @@ - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/create_luns.yml" vars: - lunNamePrefix: "{{ primaryLunPrefix }}" - startSuffix: "{{ nextScsiId }}" + newLunNames: "{{ primaryLunNames }}" startScsiId: "{{ nextScsiId }}" poolId: "{{ primaryPoolId }}" workload: "{{ primaryWorkload }}" - desc: "{{ primaryLunDesc }}" + desc: "{{ lunRemarks }}" addLgName: "{{ primaryLgName }}" - set_fact: primaryLunIds: "{{ newLunIds }}" - primaryLunNames: "{{ newLunNames }}" Step_1_1_Completed: True # End Step_1_1 @@ -626,11 +623,10 @@ msg: params: luns: - lunNamePrefix: "{{ metroLunPrefix }}" - startSuffix: "{{ nextScsiId }}" + newLunNames: "{{ metroLunNames }}" poolId: "{{ metroPoolId }}" workload: "{{ metroWorkload }}" - desc: "{{ primaryLunDesc }}" + desc: "{{ lunRemarks }}" device: "{{ metroDeviceName }}" - set_fact: @@ -642,15 +638,13 @@ - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/create_luns.yml" vars: - lunNamePrefix: "{{ metroLunPrefix }}" - startSuffix: "{{ nextScsiId }}" + newLunNames: "{{ metroLunNames }}" poolId: "{{ metroPoolId }}" workload: "{{ metroWorkload }}" - desc: "{{ primaryLunDesc }}" + desc: "{{ lunRemarks }}" - set_fact: metroLunIds: "{{ newLunIds }}" - metroLunNames: "{{ newLunNames }}" Step_2_1_Completed: True # End Step_2_1 @@ -761,11 +755,10 @@ msg: params: luns: - lunNamePrefix: "{{ drLunPrefix }}" - startSuffix: "{{ nextScsiId }}" + newLunNames: "{{ drLunNames }}" poolId: "{{ drPoolId }}" workload: "{{ drWorkload }}" - desc: "{{ drLunDesc }}" + desc: "{{ lunRemarks }}" device: "{{ drDeviceName }}" - set_fact: @@ -777,15 +770,13 @@ - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/create_luns.yml" vars: - lunNamePrefix: "{{ drLunPrefix }}" - startSuffix: "{{ nextScsiId }}" + newLunNames: "{{ drLunNames }}" poolId: "{{ drPoolId }}" workload: "{{ drWorkload }}" - desc: "{{ drLunDesc }}" + desc: "{{ lunRemarks }}" - set_fact: drLunIds: "{{ newLunIds }}" - drLunNames: "{{ newLunNames }}" Step_3_1_Completed: True # End Step_3_1 @@ -1101,11 +1092,6 @@ deviceToken: "{{ drDeviceToken }}" deviceSession: "{{ drDeviceSession }}" - - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/sync_replication_cg.yml" - vars: - cgName: "{{ drCgName }}" - waitSync: True - - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/create_snapshot_cg.yml" vars: pgName: "{{ drPgName }}" @@ -2113,11 +2099,6 @@ deviceToken: "{{ drDeviceToken }}" deviceSession: "{{ drDeviceSession }}" - - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/sync_replication_cg.yml" - vars: - cgName: "{{ drCgName }}" - waitSync: True - - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/create_snapshot_cg.yml" vars: pgName: "{{ drPgName }}" @@ -2191,12 +2172,11 @@ msg: params: luns: - lunNamePrefix: "{{ primaryLunPrefix }}" - startSuffix: "{{ nextScsiId }}" + newLunNames: "{{ primaryLunNames }}" startScsiId: "{{ nextScsiId }}" poolId: "{{ primaryPoolId }}" workload: "{{ primaryWorkload }}" - desc: "{{ primaryLunDesc }}" + desc: "{{ lunRemarks }}" addLgName: "{{ primaryLgName }}" device: "{{ primaryDeviceName }}" result: @@ -2222,11 +2202,10 @@ msg: params: luns: - lunNamePrefix: "{{ metroLunPrefix }}" - startSuffix: "{{ nextScsiId }}" + newLunNames: "{{ metroLunNames }}" poolId: "{{ metroPoolId }}" workload: "{{ metroWorkload }}" - desc: "{{ primaryLunDesc }}" + desc: "{{ lunRemarks }}" device: "{{ metroDeviceName }}" result: succeeded: "{{ Step_2_1_Completed }}" @@ -2283,11 +2262,10 @@ msg: params: luns: - lunNamePrefix: "{{ drLunPrefix }}" - startSuffix: "{{ nextScsiId }}" + newLunNames: "{{ drLunNames }}" poolId: "{{ drPoolId }}" workload: "{{ drWorkload }}" - desc: "{{ drLunDesc }}" + desc: "{{ lunRemarks }}" device: "{{ drDeviceName }}" result: succeeded: "{{ Step_3_1_Completed }}" diff --git a/rundeck/workflow/project001/10_map_luns_to_host.yml b/rundeck/workflow/project001/10_map_luns_to_host.yml index 243e2c5..adbc6f2 100644 --- a/rundeck/workflow/project001/10_map_luns_to_host.yml +++ b/rundeck/workflow/project001/10_map_luns_to_host.yml @@ -119,15 +119,15 @@ replicaType: "{{ REPTYPE[metroEnable+protectLevel|string]['type'] }}" # See ../../config/project001.yml - set_fact: - lunNameTemplate: "%s%0{{DEFAULT.suffixDigits}}d" + lunNameTemplate: "%s%0{{DEFAULT.suffixDigits}}d_%s" primaryLunPrefix: "{{primaryHostName}}_{{protectType}}{{'S' if metroEnable == 'Y' else 'N'}}" - primaryLunDesc1New: "{{ class1 }}_00_{{replicaType}}_{{'00' if replicaType == '00' else primaryRoom}}_{{'0000000000000000' if replicaType == '00' else sessionName}}_{{'0' if replicaType == '00' else protectType}}1" + primaryLunSuffix: "{{ class1 }}_00_{{replicaType}}_{{'00' if replicaType == '00' else primaryRoom}}_{{'0000000000000000' if replicaType == '00' else sessionName}}_{{'0' if replicaType == '00' else protectType}}1" metroLunPrefix: "{{metroHostName}}_{{protectType}}M" - metroLunDesc1: "{{ class1 }}_00_{{replicaType}}_{{primaryRoom}}_{{sessionName}}_{{protectType}}1" + metroLunSuffix: "{{ class1 }}_00_{{replicaType}}_{{primaryRoom}}_{{sessionName}}_{{protectType}}1" drLunPrefix: "{{drHostName}}_{{protectType}}N" - drLunDesc1: "{{ class2 }}_00_{{replicaType}}_{{primaryRoom}}_{{sessionName}}_{{protectType}}2" + drLunSuffix: "{{ class2 }}_00_{{replicaType}}_{{primaryRoom}}_{{sessionName}}_{{protectType}}2" drTestLunPrefix: "{{drTestHostName}}_{{protectType}}N" - drTestLunDesc1: "{{ class3 }}_00_00_{{primaryRoom}}_{{sessionName}}_{{protectType}}3" + drTestLunSuffix: "{{ class3 }}_00_00_{{primaryRoom}}_{{sessionName}}_{{protectType}}3" drTestCgNameDefault: "{{ replicaType }}_{{ primaryRoom }}_{{ sessionName }}_{{ protectType }}3" drStarCgNameDefault: "{{ replicaType }}_{{ primaryRoom }}_{{ sessionName }}_{{ protectType }}0" @@ -214,13 +214,9 @@ primaryLunDescs: "{{ checkedLuns | json_query('[*].DESCRIPTION') }}" primaryLunsSector: "{{ checkedLuns | json_query('[*].CAPACITY') }}" primaryLunNamesNew: [] - primaryLunDescsNew: [] - set_fact: - primaryLunNamesNew: "{{ primaryLunNamesNew + [ lunNameTemplate | format(primaryLunPrefix, nextScsiId|int + item.0) ] }}" - primaryLunDescsNew: "{{ primaryLunDescsNew + [ primaryLunDescs[item.0] | replace(primaryLunDesc1, primaryLunDesc1New) ] }}" - vars: - primaryLunDesc1: "{{ primaryLunDescs[item.0].split('|')[0] }}" + primaryLunNamesNew: "{{ primaryLunNamesNew + [ lunNameTemplate | format(primaryLunPrefix, (nextScsiId|int + item.0), primaryLunSuffix) ] }}" with_indexed_items: "{{ primaryLunNames }}" - import_tasks: "{{GLOBAL.baseDir}}/task/volume/check_volumes.yml" @@ -236,9 +232,11 @@ - set_fact: primaryLunsInTier: "{{ checkedVolumes | json_query(queryVolumesInTier) }}" + primaryLunsInTierClass: "{{ checkedVolumes | json_query(queryVolumesInTierClass) }}" primaryLunsNotInTier: "{{ checkedVolumes | json_query(queryVolumesNotInTier) }}" vars: - queryVolumesInTier: "[? service_level_name != '' && service_level_name != '{{class1}}' && service_level_name != null ].name" + queryVolumesInTier: "[? service_level_name != '' && service_level_name != null ].name" + queryVolumesInTierClass: "[? service_level_name != '' && service_level_name != null ].service_level_name" queryVolumesNotInTier: "[? service_level_name == '' || service_level_name == null ].name" # End Precheck_1 @@ -281,13 +279,9 @@ - set_fact: metroLunNames: [] - metroLunDescs: [] - set_fact: - metroLunNames: "{{ metroLunNames + [ lunNameTemplate | format(metroLunPrefix, nextScsiId|int + item.0) ] }}" - metroLunDescs: "{{ metroLunDescs + [ primaryLunDescs[item.0] | replace(primaryLunDesc1, metroLunDesc1) ] }}" - vars: - primaryLunDesc1: "{{ primaryLunDescs[item.0].split('|')[0] }}" + metroLunNames: "{{ metroLunNames + [ lunNameTemplate | format(metroLunPrefix, (nextScsiId|int + item.0), metroLunSuffix) ] }}" with_indexed_items: "{{ primaryLunNames }}" - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_luns.yml" @@ -339,13 +333,9 @@ - set_fact: drLunNames: [] - drLunDescs: [] - set_fact: - drLunNames: "{{ drLunNames + [ lunNameTemplate | format(drLunPrefix, nextScsiId|int + item.0) ] }}" - drLunDescs: "{{ drLunDescs + [ primaryLunDescs[item.0] | replace(primaryLunDesc1, drLunDesc1) ] }}" - vars: - primaryLunDesc1: "{{ primaryLunDescs[item.0].split('|')[0] }}" + drLunNames: "{{ drLunNames + [ lunNameTemplate | format(drLunPrefix, (nextScsiId|int + item.0), drLunSuffix) ] }}" with_indexed_items: "{{ primaryLunNames }}" - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_luns.yml" @@ -383,13 +373,9 @@ existDrTestLuns: "{{ checkedLuns[drTestLgName] | json_query('[*].lunName') }}" existDrTestLunsDesc: [] drTestLunNames: [] - drTestLunDescs: [] - set_fact: - drTestLunNames: "{{ drTestLunNames + [ lunNameTemplate | format(drTestLunPrefix, nextScsiId|int + item.0) ] }}" - drTestLunDescs: "{{ drTestLunDescs + [ primaryLunDescs[item.0] | replace(primaryLunDesc1, drTestLunDesc1) ] }}" - vars: - primaryLunDesc1: "{{ primaryLunDescs[item.0].split('|')[0] }}" + drTestLunNames: "{{ drTestLunNames + [ lunNameTemplate | format(drTestLunPrefix, (nextScsiId|int + item.0), drTestLunSuffix) ] }}" with_indexed_items: "{{ primaryLunNames }}" - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_luns.yml" @@ -591,7 +577,7 @@ params: luns: lunNames: "{{ metroLunNames }}" - lunDescs: "{{ metroLunDescs }}" + lunDescs: "{{ primaryLunDescs }}" poolId: "{{ metroPoolId }}" workload: "{{ metroWorkload }}" device: "{{ metroDeviceName }}" @@ -609,7 +595,7 @@ lunSector: "{{ primaryLunsSector[i] }}" poolId: "{{ metroPoolId }}" workload: "{{ metroWorkload }}" - desc: "{{ metroLunDescs[i] }}" + desc: "{{ primaryLunDescs[i] }}" loop: "{{ range(0, metroLunNames|length) | list }}" loop_control: loop_var: i @@ -634,7 +620,7 @@ params: luns: lunNames: "{{ drLunNames }}" - lunDescs: "{{ drLunDescs }}" + lunDescs: "{{ primaryLunDescs }}" poolId: "{{ drPoolId }}" workload: "{{ drWorkload }}" device: "{{ drDeviceName }}" @@ -652,7 +638,7 @@ lunSector: "{{ primaryLunsSector[i] }}" poolId: "{{ drPoolId }}" workload: "{{ drWorkload }}" - desc: "{{ drLunDescs[i] }}" + desc: "{{ primaryLunDescs[i] }}" loop: "{{ range(0, drLunNames|length) | list }}" loop_control: loop_var: i @@ -1043,7 +1029,7 @@ cgName: "{{ drTestCgName }}" snapNames: "{{ existDrTestLuns + drTestLunNames }}" activate: False - snapDescs: "{{ existDrTestLunsDesc + drTestLunDescs }}" + snapDescs: "{{ existDrTestLunsDesc + primaryLunDescs }}" device: "{{ drDeviceName }}" - set_fact: @@ -1053,18 +1039,13 @@ deviceToken: "{{ drDeviceToken }}" deviceSession: "{{ drDeviceSession }}" - - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/sync_replication_cg.yml" - vars: - cgName: "{{ drCgName }}" - waitSync: True - - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/create_snapshot_cg.yml" vars: pgName: "{{ drPgName }}" cgName: "{{ drTestCgName }}" snapNames: "{{ existDrTestLuns + drTestLunNames }}" activate: False - snapDescs: "{{ existDrTestLunsDesc + drTestLunDescs }}" + snapDescs: "{{ existDrTestLunsDesc + primaryLunDescs }}" - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_luns.yml" vars: @@ -1156,14 +1137,14 @@ volumeNames: "{{ primaryLunNames }}" tierName: "{{ class1 }}" - - import_tasks: "{{GLOBAL.baseDir}}/task/volume/add_volumes_to_tier.yml" + - import_tasks: "{{GLOBAL.baseDir}}/task/volume/remove_volumes_from_tier.yml" vars: - volumeNames: "{{ primaryLunsNotInTier }}" - tierName: "{{ class1 }}" + volumeNames: "{{ primaryLunsInTier }}" + when: primaryLunsInTier|length > 0 - - import_tasks: "{{GLOBAL.baseDir}}/task/volume/change_volumes_to_tier.yml" + - import_tasks: "{{GLOBAL.baseDir}}/task/volume/add_volumes_to_tier.yml" vars: - volumeNames: "{{ primaryLunsInTier }}" + volumeNames: "{{ primaryLunNames }}" tierName: "{{ class1 }}" - set_fact: @@ -1180,9 +1161,6 @@ name: old: "{{ primaryLunNames }}" new: "{{ primaryLunNamesNew }}" - desc: - old: "{{ primaryLunDescs }}" - new: "{{ primaryLunDescsNew }}" device: "{{ primaryDeviceName }}" - include_tasks: "{{GLOBAL.baseDir}}/task/volume/rename_volumes.yml" @@ -1190,21 +1168,6 @@ volumeNames: "{{ primaryLunNames }}" newVolumeNames: "{{ primaryLunNamesNew }}" - - set_fact: - deviceHost: "{{ primaryDeviceHost }}" - devicePort: "{{ primaryDevicePort }}" - deviceSn: "{{ primaryDeviceSn }}" - deviceToken: "{{ primaryDeviceToken }}" - deviceSession: "{{ primaryDeviceSession }}" - - - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/modify_lun.yml" - vars: - modifyLunId: "{{ primaryLunIds[i] }}" - desc: "{{ primaryLunDescsNew[i] }}" - loop: "{{ range(0, primaryLunIds|length) | list }}" - loop_control: - loop_var: i - - set_fact: Step_3_7_Completed: True @@ -1562,9 +1525,6 @@ name: old: "{{ primaryLunNamesNew }}" new: "{{ primaryLunNames }}" - desc: - old: "{{ primaryLunDescsNew }}" - new: "{{ primaryLunDescs }}" device: "{{ primaryDeviceName }}" - include_tasks: "{{GLOBAL.baseDir}}/task/volume/rename_volumes.yml" @@ -1572,21 +1532,6 @@ volumeNames: "{{ primaryLunNamesNew }}" newVolumeNames: "{{ primaryLunNames }}" - - set_fact: - deviceHost: "{{ primaryDeviceHost }}" - devicePort: "{{ primaryDevicePort }}" - deviceSn: "{{ primaryDeviceSn }}" - deviceToken: "{{ primaryDeviceToken }}" - deviceSession: "{{ primaryDeviceSession }}" - - - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/modify_lun.yml" - vars: - modifyLunId: "{{ primaryLunIds[i] }}" - desc: "{{ primaryLunDescs[i] }}" - loop: "{{ range(0, primaryLunIds|length) | list }}" - loop_control: - loop_var: i - - set_fact: Step_3_7_Rollbacked: True @@ -1969,11 +1914,6 @@ deviceToken: "{{ drDeviceToken }}" deviceSession: "{{ drDeviceSession }}" - - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/sync_replication_cg.yml" - vars: - cgName: "{{ drCgName }}" - waitSync: True - - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/create_snapshot_cg.yml" vars: pgName: "{{ drPgName }}" @@ -2105,6 +2045,15 @@ vars: volumeNames: "{{ primaryLunNames }}" + - include_tasks: "{{GLOBAL.baseDir}}/task/volume/add_volumes_to_tier.yml" + vars: + volumeNames: ["{{ item.0 }}"] + tierName: "{{ item.1 }}" + with_together: + - "{{ primaryLunsInTier }}" + - "{{ primaryLunsInTierClass }}" + when: primaryLunsInTier|length > 0 + - set_fact: Step_3_6_Rollbacked: True @@ -2124,7 +2073,7 @@ params: luns: lunNames: "{{ metroLunNames }}" - lunDescs: "{{ metroLunDescs }}" + lunDescs: "{{ primaryLunDescs }}" poolId: "{{ metroPoolId }}" workload: "{{ metroWorkload }}" device: "{{ metroDeviceName }}" @@ -2140,7 +2089,7 @@ params: luns: lunNames: "{{ drLunNames }}" - lunDescs: "{{ drLunDescs }}" + lunDescs: "{{ primaryLunDescs }}" poolId: "{{ drPoolId }}" workload: "{{ drWorkload }}" device: "{{ drDeviceName }}" @@ -2311,7 +2260,7 @@ cgName: "{{ drTestCgName }}" snapNames: "{{ existDrTestLuns + drTestLunNames }}" activate: False - snapDescs: "{{ existDrTestLunsDesc + drTestLunDescs }}" + snapDescs: "{{ existDrTestLunsDesc + primaryLunDescs }}" device: "{{ drDeviceName }}" result: succeeded: "{{ Step_3_3_Completed }}" @@ -2367,9 +2316,6 @@ name: old: "{{ primaryLunNames }}" new: "{{ primaryLunNamesNew }}" - desc: - old: "{{ primaryLunDescs }}" - new: "{{ primaryLunDescsNew }}" device: "{{ primaryDeviceName }}" result: succeeded: "{{ Step_3_7_Completed }}" diff --git a/rundeck/workflow/project001/11_unmap_luns_from_host.yml b/rundeck/workflow/project001/11_unmap_luns_from_host.yml index 0cf631f..da77a64 100644 --- a/rundeck/workflow/project001/11_unmap_luns_from_host.yml +++ b/rundeck/workflow/project001/11_unmap_luns_from_host.yml @@ -1068,11 +1068,6 @@ deviceToken: "{{ drDeviceToken }}" deviceSession: "{{ drDeviceSession }}" - - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/sync_replication_cg.yml" - vars: - cgName: "{{ drCgName }}" - waitSync: True - - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/create_snapshot_cg.yml" vars: pgName: "{{ drPgName }}" @@ -1932,11 +1927,6 @@ deviceToken: "{{ drDeviceToken }}" deviceSession: "{{ drDeviceSession }}" - - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/sync_replication_cg.yml" - vars: - cgName: "{{ drCgName }}" - waitSync: True - - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/create_snapshot_cg.yml" vars: pgName: "{{ drPgName }}" diff --git a/rundeck/workflow/project001/13_create_luns_for_cluster.yml b/rundeck/workflow/project001/13_create_luns_for_cluster.yml index 4b3a12b..467a8b3 100644 --- a/rundeck/workflow/project001/13_create_luns_for_cluster.yml +++ b/rundeck/workflow/project001/13_create_luns_for_cluster.yml @@ -14,7 +14,7 @@ Storage: "{{ (Storage is not none and Storage != DEFAULT.noneValue) and (Storage|string|length == 20) }}" LUN_Size: "{{ (LUN_Size is not none) and (LUN_Size|int >= 1) }}" LUN_Num: "{{ (LUN_Num is not none) and (LUN_Num|int >= 1) }}" - LUN_Description: "{{ (LUN_Description is none) or (LUN_Description|string|length <= 200) }}" + LUN_Description: "{{ (LUN_Description is none) or (LUN_Description|string|length <= 255) }}" Class_1: "{{ Class_1 in ['A','B','C','D'] }}" Designate_Class_1: "{{ (Designate_Class_1 is none) or (Designate_Class_1 in ['A','B','C','D']) }}" Check_Result_1: "{{ ('lun' in Check_Result_1) }}" @@ -125,14 +125,14 @@ replicaType: "{{ REPTYPE[metroEnable+protectLevel|string]['type'] }}" # See ../../config/project001.yml - set_fact: - lunNameTemplate: "%s%0{{DEFAULT.suffixDigits}}d" + lunNameTemplate: "%s%0{{DEFAULT.suffixDigits}}d_%s" primaryLunPrefix: "{{primaryClusterName}}_{{protectType}}{{'S' if metroEnable == 'Y' else 'N'}}" - primaryLunDesc: "{{ class1 }}_00_{{replicaType}}_{{'00' if replicaType == '00' else primaryRoom}}_{{'0000000000000000' if replicaType == '00' else sessionName}}_{{'0' if replicaType == '00' else protectType}}1|{{lunRemarks}}" + primaryLunSuffix: "{{ class1 }}_00_{{replicaType}}_{{'00' if replicaType == '00' else primaryRoom}}_{{'0000000000000000' if replicaType == '00' else sessionName}}_{{'0' if replicaType == '00' else protectType}}1" metroLunPrefix: "{{metroClusterName}}_{{protectType}}M" drLunPrefix: "{{drClusterName}}_{{protectType}}N" - drLunDesc: "{{ class2 }}_00_{{replicaType}}_{{primaryRoom}}_{{sessionName}}_{{protectType}}2|{{lunRemarks}}" + drLunSuffix: "{{ class2 }}_00_{{replicaType}}_{{primaryRoom}}_{{sessionName}}_{{protectType}}2" drTestLunPrefix: "{{drTestClusterName}}_{{protectType}}N" - drTestLunDesc: "{{ class3 }}_00_00_{{primaryRoom}}_{{sessionName}}_{{protectType}}3|{{lunRemarks}}" + drTestLunSuffix: "{{ class3 }}_00_00_{{primaryRoom}}_{{sessionName}}_{{protectType}}3" drTestCgNameDefault: "{{ replicaType }}_{{ primaryRoom }}_{{ sessionName }}_{{ protectType }}3" drStarCgNameDefault: "{{ replicaType }}_{{ primaryRoom }}_{{ sessionName }}_{{ protectType }}0" @@ -208,12 +208,12 @@ when: Start_SCSI_ID|default(none) is not none - set_fact: - nextSuffix: "{{ (maxScsiId|int - nextScsiId|int + 1) }}" + nextLunNo: "{{ (maxScsiId|int - nextScsiId|int + 1) }}" primaryLunNames: [] lunScsiIds: [] - set_fact: - primaryLunNames: "{{ primaryLunNames + [ lunNameTemplate | format(primaryLunPrefix, ( nextSuffix|int + item|int ) ) ] }}" + primaryLunNames: "{{ primaryLunNames + [ lunNameTemplate | format(primaryLunPrefix, (nextLunNo|int + item|int), primaryLunSuffix ) ] }}" lunScsiIds: "{{ lunScsiIds + [nextScsiId|int - item|int] }}" with_sequence: start=0 count="{{lunNum}}" @@ -264,7 +264,7 @@ metroLunNames: [] - set_fact: - metroLunNames: "{{ metroLunNames + [ lunNameTemplate | format(metroLunPrefix, ( nextSuffix|int + item|int ) ) ] }}" + metroLunNames: "{{ metroLunNames + [ lunNameTemplate | format(metroLunPrefix, (nextLunNo|int + item|int), primaryLunSuffix ) ] }}" with_sequence: start=0 count="{{lunNum}}" - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_luns.yml" @@ -316,7 +316,7 @@ drLunNames: [] - set_fact: - drLunNames: "{{ drLunNames + [ lunNameTemplate | format(drLunPrefix, ( nextSuffix|int + item|int ) ) ] }}" + drLunNames: "{{ drLunNames + [ lunNameTemplate | format(drLunPrefix, (nextLunNo|int + item|int), drLunSuffix ) ] }}" with_sequence: start=0 count="{{lunNum}}" - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_luns.yml" @@ -357,8 +357,8 @@ drTestLunDescs: [] - set_fact: - drTestLunNames: "{{ drTestLunNames + [ lunNameTemplate | format(drTestLunPrefix, ( nextSuffix|int + item|int ) ) ] }}" - drTestLunDescs: "{{ drTestLunDescs + [drTestLunDesc] }}" + drTestLunNames: "{{ drTestLunNames + [ lunNameTemplate | format(drTestLunPrefix, (nextLunNo|int + item|int), drTestLunSuffix ) ] }}" + drTestLunDescs: "{{ drTestLunDescs + [lunRemarks] }}" with_sequence: start=0 count="{{lunNum}}" - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_luns.yml" @@ -556,12 +556,11 @@ msg: params: luns: - lunNamePrefix: "{{ primaryLunPrefix }}" - startSuffix: "{{ nextSuffix }}" + newLunNames: "{{ primaryLunNames }}" addLunScsiIds: "{{ lunScsiIds }}" poolId: "{{ primaryPoolId }}" workload: "{{ primaryWorkload }}" - desc: "{{ primaryLunDesc }}" + desc: "{{ lunRemarks }}" addLgName: "{{ primaryLgName }}" device: "{{ primaryDeviceName }}" @@ -574,17 +573,15 @@ - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/create_luns.yml" vars: - lunNamePrefix: "{{ primaryLunPrefix }}" - startSuffix: "{{ nextSuffix }}" + newLunNames: "{{ primaryLunNames }}" addLunScsiIds: "{{ lunScsiIds }}" poolId: "{{ primaryPoolId }}" workload: "{{ primaryWorkload }}" - desc: "{{ primaryLunDesc }}" + desc: "{{ lunRemarks }}" addLgName: "{{ primaryLgName }}" - set_fact: primaryLunIds: "{{ newLunIds }}" - primaryLunNames: "{{ newLunNames }}" Step_1_1_Completed: True # End Step_1_1 @@ -625,11 +622,10 @@ msg: params: luns: - lunNamePrefix: "{{ metroLunPrefix }}" - startSuffix: "{{ nextSuffix }}" + newLunNames: "{{ metroLunNames }}" poolId: "{{ metroPoolId }}" workload: "{{ metroWorkload }}" - desc: "{{ primaryLunDesc }}" + desc: "{{ lunRemarks }}" device: "{{ metroDeviceName }}" - set_fact: @@ -641,15 +637,13 @@ - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/create_luns.yml" vars: - lunNamePrefix: "{{ metroLunPrefix }}" - startSuffix: "{{ nextSuffix }}" + newLunNames: "{{ metroLunNames }}" poolId: "{{ metroPoolId }}" workload: "{{ metroWorkload }}" - desc: "{{ primaryLunDesc }}" + desc: "{{ lunRemarks }}" - set_fact: metroLunIds: "{{ newLunIds }}" - metroLunNames: "{{ newLunNames }}" Step_2_1_Completed: True # End Step_2_1 @@ -759,11 +753,10 @@ msg: params: luns: - lunNamePrefix: "{{ drLunPrefix }}" - startSuffix: "{{ nextSuffix }}" + newLunNames: "{{ drLunNames }}" poolId: "{{ drPoolId }}" workload: "{{ drWorkload }}" - desc: "{{ drLunDesc }}" + desc: "{{ lunRemarks }}" device: "{{ drDeviceName }}" - set_fact: @@ -775,15 +768,13 @@ - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/create_luns.yml" vars: - lunNamePrefix: "{{ drLunPrefix }}" - startSuffix: "{{ nextSuffix }}" + newLunNames: "{{ drLunNames }}" poolId: "{{ drPoolId }}" workload: "{{ drWorkload }}" - desc: "{{ drLunDesc }}" + desc: "{{ lunRemarks }}" - set_fact: drLunIds: "{{ newLunIds }}" - drLunNames: "{{ newLunNames }}" Step_3_1_Completed: True # End Step_3_1 @@ -1098,11 +1089,6 @@ deviceToken: "{{ drDeviceToken }}" deviceSession: "{{ drDeviceSession }}" - - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/sync_replication_cg.yml" - vars: - cgName: "{{ drCgName }}" - waitSync: True - - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/create_snapshot_cg.yml" vars: pgName: "{{ drPgName }}" @@ -2111,11 +2097,6 @@ deviceToken: "{{ drDeviceToken }}" deviceSession: "{{ drDeviceSession }}" - - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/sync_replication_cg.yml" - vars: - cgName: "{{ drCgName }}" - waitSync: True - - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/create_snapshot_cg.yml" vars: pgName: "{{ drPgName }}" @@ -2189,12 +2170,11 @@ msg: params: luns: - lunNamePrefix: "{{ primaryLunPrefix }}" - startSuffix: "{{ nextSuffix }}" + newLunNames: "{{ primaryLunNames }}" addLunScsiIds: "{{ lunScsiIds }}" poolId: "{{ primaryPoolId }}" workload: "{{ primaryWorkload }}" - desc: "{{ primaryLunDesc }}" + desc: "{{ lunRemarks }}" addLgName: "{{ primaryLgName }}" device: "{{ primaryDeviceName }}" result: @@ -2220,11 +2200,10 @@ msg: params: luns: - lunNamePrefix: "{{ metroLunPrefix }}" - startSuffix: "{{ nextSuffix }}" + newLunNames: "{{ metroLunNames }}" poolId: "{{ metroPoolId }}" workload: "{{ metroWorkload }}" - desc: "{{ primaryLunDesc }}" + desc: "{{ lunRemarks }}" device: "{{ metroDeviceName }}" result: succeeded: "{{ Step_2_1_Completed }}" @@ -2281,11 +2260,10 @@ msg: params: luns: - lunNamePrefix: "{{ drLunPrefix }}" - startSuffix: "{{ nextSuffix }}" + newLunNames: "{{ drLunNames }}" poolId: "{{ drPoolId }}" workload: "{{ drWorkload }}" - desc: "{{ drLunDesc }}" + desc: "{{ lunRemarks }}" device: "{{ drDeviceName }}" result: succeeded: "{{ Step_3_1_Completed }}" diff --git a/rundeck/workflow/project001/14_map_luns_to_cluster.yml b/rundeck/workflow/project001/14_map_luns_to_cluster.yml index 721a285..e7b6f7c 100644 --- a/rundeck/workflow/project001/14_map_luns_to_cluster.yml +++ b/rundeck/workflow/project001/14_map_luns_to_cluster.yml @@ -120,15 +120,15 @@ replicaType: "{{ REPTYPE[metroEnable+protectLevel|string]['type'] }}" # See ../../config/project001.yml - set_fact: - lunNameTemplate: "%s%0{{DEFAULT.suffixDigits}}d" + lunNameTemplate: "%s%0{{DEFAULT.suffixDigits}}d_%s" primaryLunPrefix: "{{primaryClusterName}}_{{protectType}}{{'S' if metroEnable == 'Y' else 'N'}}" - primaryLunDesc1New: "{{ class1 }}_00_{{replicaType}}_{{'00' if replicaType == '00' else primaryRoom}}_{{'0000000000000000' if replicaType == '00' else sessionName}}_{{'0' if replicaType == '00' else protectType}}1" + primaryLunSuffix: "{{ class1 }}_00_{{replicaType}}_{{'00' if replicaType == '00' else primaryRoom}}_{{'0000000000000000' if replicaType == '00' else sessionName}}_{{'0' if replicaType == '00' else protectType}}1" metroLunPrefix: "{{metroClusterName}}_{{protectType}}M" - metroLunDesc1: "{{ class1 }}_00_{{replicaType}}_{{primaryRoom}}_{{sessionName}}_{{protectType}}1" + metroLunSuffix: "{{ class1 }}_00_{{replicaType}}_{{primaryRoom}}_{{sessionName}}_{{protectType}}1" drLunPrefix: "{{drClusterName}}_{{protectType}}N" - drLunDesc1: "{{ class2 }}_00_{{replicaType}}_{{primaryRoom}}_{{sessionName}}_{{protectType}}2" + drLunSuffix: "{{ class2 }}_00_{{replicaType}}_{{primaryRoom}}_{{sessionName}}_{{protectType}}2" drTestLunPrefix: "{{drTestClusterName}}_{{protectType}}N" - drTestLunDesc1: "{{ class3 }}_00_00_{{primaryRoom}}_{{sessionName}}_{{protectType}}3" + drTestLunSuffix: "{{ class3 }}_00_00_{{primaryRoom}}_{{sessionName}}_{{protectType}}3" drTestCgNameDefault: "{{ replicaType }}_{{ primaryRoom }}_{{ sessionName }}_{{ protectType }}3" drStarCgNameDefault: "{{ replicaType }}_{{ primaryRoom }}_{{ sessionName }}_{{ protectType }}0" @@ -203,7 +203,7 @@ when: Start_SCSI_ID|default(none) is not none - set_fact: - nextSuffix: "{{ (maxScsiId|int - nextScsiId|int + 1) }}" + nextLunNo: "{{ (maxScsiId|int - nextScsiId|int + 1) }}" lunScsiIds: [] - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_luns.yml" @@ -215,14 +215,10 @@ primaryLunDescs: "{{ checkedLuns | json_query('[*].DESCRIPTION') }}" primaryLunsSector: "{{ checkedLuns | json_query('[*].CAPACITY') }}" primaryLunNamesNew: [] - primaryLunDescsNew: [] - set_fact: - primaryLunNamesNew: "{{ primaryLunNamesNew + [ lunNameTemplate | format(primaryLunPrefix, ( nextSuffix|int + item|int ) ) ] }}" + primaryLunNamesNew: "{{ primaryLunNamesNew + [ lunNameTemplate | format(primaryLunPrefix, (nextLunNo|int + item|int), primaryLunSuffix ) ] }}" lunScsiIds: "{{ lunScsiIds + [nextScsiId|int - item|int] }}" - primaryLunDescsNew: "{{ primaryLunDescsNew + [ primaryLunDescs[item|int] | replace(primaryLunDesc1, primaryLunDesc1New) ] }}" - vars: - primaryLunDesc1: "{{ primaryLunDescs[item|int].split('|')[0] }}" with_sequence: start=0 count="{{lunNum}}" - import_tasks: "{{GLOBAL.baseDir}}/task/volume/check_volumes.yml" @@ -238,9 +234,11 @@ - set_fact: primaryLunsInTier: "{{ checkedVolumes | json_query(queryVolumesInTier) }}" + primaryLunsInTierClass: "{{ checkedVolumes | json_query(queryVolumesInTierClass) }}" primaryLunsNotInTier: "{{ checkedVolumes | json_query(queryVolumesNotInTier) }}" vars: - queryVolumesInTier: "[? service_level_name != '' && service_level_name != '{{class1}}' && service_level_name != null ].name" + queryVolumesInTier: "[? service_level_name != '' && service_level_name != null ].name" + queryVolumesInTierClass: "[? service_level_name != '' && service_level_name != null ].service_level_name" queryVolumesNotInTier: "[? service_level_name == '' || service_level_name == null ].name" # End Precheck_1 @@ -283,13 +281,9 @@ - set_fact: metroLunNames: [] - metroLunDescs: [] - set_fact: - metroLunNames: "{{ metroLunNames + [ lunNameTemplate | format(metroLunPrefix, ( nextSuffix|int + item|int ) ) ] }}" - metroLunDescs: "{{ metroLunDescs + [ primaryLunDescs[item|int] | replace(primaryLunDesc1, metroLunDesc1) ] }}" - vars: - primaryLunDesc1: "{{ primaryLunDescs[item|int].split('|')[0] }}" + metroLunNames: "{{ metroLunNames + [ lunNameTemplate | format(metroLunPrefix, (nextLunNo|int + item|int), metroLunSuffix ) ] }}" with_sequence: start=0 count="{{lunNum}}" - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_luns.yml" @@ -337,13 +331,9 @@ - set_fact: drLunNames: [] - drLunDescs: [] - set_fact: - drLunNames: "{{ drLunNames + [ lunNameTemplate | format(drLunPrefix, ( nextSuffix|int + item|int ) ) ] }}" - drLunDescs: "{{ drLunDescs + [ primaryLunDescs[item|int] | replace(primaryLunDesc1, drLunDesc1) ] }}" - vars: - primaryLunDesc1: "{{ primaryLunDescs[item|int].split('|')[0] }}" + drLunNames: "{{ drLunNames + [ lunNameTemplate | format(drLunPrefix, (nextLunNo|int + item|int), drLunSuffix ) ] }}" with_sequence: start=0 count="{{lunNum}}" - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_luns.yml" @@ -381,13 +371,9 @@ existDrTestLuns: "{{ checkedLuns[drTestLgName] | json_query('[*].lunName') }}" existDrTestLunsDesc: [] drTestLunNames: [] - drTestLunDescs: [] - set_fact: - drTestLunNames: "{{ drTestLunNames + [ lunNameTemplate | format(drTestLunPrefix, ( nextSuffix|int + item|int ) ) ] }}" - drTestLunDescs: "{{ drTestLunDescs + [ primaryLunDescs[item|int] | replace(primaryLunDesc1, drTestLunDesc1) ] }}" - vars: - primaryLunDesc1: "{{ primaryLunDescs[item|int].split('|')[0] }}" + drTestLunNames: "{{ drTestLunNames + [ lunNameTemplate | format(drTestLunPrefix, (nextLunNo|int + item|int), drTestLunSuffix ) ] }}" with_sequence: start=0 count="{{lunNum}}" - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_luns.yml" @@ -589,7 +575,7 @@ params: luns: lunNames: "{{ metroLunNames }}" - lunDescs: "{{ metroLunDescs }}" + lunDescs: "{{ primaryLunDescs }}" poolId: "{{ metroPoolId }}" workload: "{{ metroWorkload }}" device: "{{ metroDeviceName }}" @@ -607,7 +593,7 @@ lunSector: "{{ primaryLunsSector[i] }}" poolId: "{{ metroPoolId }}" workload: "{{ metroWorkload }}" - desc: "{{ metroLunDescs[i] }}" + desc: "{{ primaryLunDescs[i] }}" loop: "{{ range(0, metroLunNames|length) | list }}" loop_control: loop_var: i @@ -632,7 +618,7 @@ params: luns: lunNames: "{{ drLunNames }}" - lunDescs: "{{ drLunDescs }}" + lunDescs: "{{ primaryLunDescs }}" poolId: "{{ drPoolId }}" workload: "{{ drWorkload }}" device: "{{ drDeviceName }}" @@ -650,7 +636,7 @@ lunSector: "{{ primaryLunsSector[i] }}" poolId: "{{ drPoolId }}" workload: "{{ drWorkload }}" - desc: "{{ drLunDescs[i] }}" + desc: "{{ primaryLunDescs[i] }}" loop: "{{ range(0, drLunNames|length) | list }}" loop_control: loop_var: i @@ -1045,7 +1031,7 @@ cgName: "{{ drTestCgName }}" snapNames: "{{ existDrTestLuns + drTestLunNames }}" activate: False - snapDescs: "{{ existDrTestLunsDesc + drTestLunDescs }}" + snapDescs: "{{ existDrTestLunsDesc + primaryLunDescs }}" device: "{{ drDeviceName }}" - set_fact: @@ -1055,18 +1041,13 @@ deviceToken: "{{ drDeviceToken }}" deviceSession: "{{ drDeviceSession }}" - - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/sync_replication_cg.yml" - vars: - cgName: "{{ drCgName }}" - waitSync: True - - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/create_snapshot_cg.yml" vars: pgName: "{{ drPgName }}" cgName: "{{ drTestCgName }}" snapNames: "{{ existDrTestLuns + drTestLunNames }}" activate: False - snapDescs: "{{ existDrTestLunsDesc + drTestLunDescs }}" + snapDescs: "{{ existDrTestLunsDesc + primaryLunDescs }}" - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_luns.yml" vars: @@ -1158,14 +1139,14 @@ volumeNames: "{{ primaryLunNames }}" tierName: "{{ class1 }}" - - import_tasks: "{{GLOBAL.baseDir}}/task/volume/add_volumes_to_tier.yml" + - import_tasks: "{{GLOBAL.baseDir}}/task/volume/remove_volumes_from_tier.yml" vars: - volumeNames: "{{ primaryLunsNotInTier }}" - tierName: "{{ class1 }}" + volumeNames: "{{ primaryLunsInTier }}" + when: primaryLunsInTier|length > 0 - - import_tasks: "{{GLOBAL.baseDir}}/task/volume/change_volumes_to_tier.yml" + - import_tasks: "{{GLOBAL.baseDir}}/task/volume/add_volumes_to_tier.yml" vars: - volumeNames: "{{ primaryLunsInTier }}" + volumeNames: "{{ primaryLunNames }}" tierName: "{{ class1 }}" - set_fact: @@ -1182,9 +1163,6 @@ name: old: "{{ primaryLunNames }}" new: "{{ primaryLunNamesNew }}" - desc: - old: "{{ primaryLunDescs }}" - new: "{{ primaryLunDescsNew }}" device: "{{ primaryDeviceName }}" - include_tasks: "{{GLOBAL.baseDir}}/task/volume/rename_volumes.yml" @@ -1192,21 +1170,6 @@ volumeNames: "{{ primaryLunNames }}" newVolumeNames: "{{ primaryLunNamesNew }}" - - set_fact: - deviceHost: "{{ primaryDeviceHost }}" - devicePort: "{{ primaryDevicePort }}" - deviceSn: "{{ primaryDeviceSn }}" - deviceToken: "{{ primaryDeviceToken }}" - deviceSession: "{{ primaryDeviceSession }}" - - - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/modify_lun.yml" - vars: - modifyLunId: "{{ primaryLunIds[i] }}" - desc: "{{ primaryLunDescsNew[i] }}" - loop: "{{ range(0, primaryLunIds|length) | list }}" - loop_control: - loop_var: i - - set_fact: Step_3_7_Completed: True @@ -1564,9 +1527,6 @@ name: old: "{{ primaryLunNamesNew }}" new: "{{ primaryLunNames }}" - desc: - old: "{{ primaryLunDescsNew }}" - new: "{{ primaryLunDescs }}" device: "{{ primaryDeviceName }}" - include_tasks: "{{GLOBAL.baseDir}}/task/volume/rename_volumes.yml" @@ -1574,21 +1534,6 @@ volumeNames: "{{ primaryLunNamesNew }}" newVolumeNames: "{{ primaryLunNames }}" - - set_fact: - deviceHost: "{{ primaryDeviceHost }}" - devicePort: "{{ primaryDevicePort }}" - deviceSn: "{{ primaryDeviceSn }}" - deviceToken: "{{ primaryDeviceToken }}" - deviceSession: "{{ primaryDeviceSession }}" - - - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/modify_lun.yml" - vars: - modifyLunId: "{{ primaryLunIds[i] }}" - desc: "{{ primaryLunDescs[i] }}" - loop: "{{ range(0, primaryLunIds|length) | list }}" - loop_control: - loop_var: i - - set_fact: Step_3_7_Rollbacked: True @@ -1971,11 +1916,6 @@ deviceToken: "{{ drDeviceToken }}" deviceSession: "{{ drDeviceSession }}" - - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/sync_replication_cg.yml" - vars: - cgName: "{{ drCgName }}" - waitSync: True - - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/create_snapshot_cg.yml" vars: pgName: "{{ drPgName }}" @@ -2107,6 +2047,15 @@ vars: volumeNames: "{{ primaryLunNames }}" + - include_tasks: "{{GLOBAL.baseDir}}/task/volume/add_volumes_to_tier.yml" + vars: + volumeNames: ["{{ item.0 }}"] + tierName: "{{ item.1 }}" + with_together: + - "{{ primaryLunsInTier }}" + - "{{ primaryLunsInTierClass }}" + when: primaryLunsInTier|length > 0 + - set_fact: Step_3_6_Rollbacked: True @@ -2126,7 +2075,7 @@ params: luns: lunNames: "{{ metroLunNames }}" - lunDescs: "{{ metroLunDescs }}" + lunDescs: "{{ primaryLunDescs }}" poolId: "{{ metroPoolId }}" workload: "{{ metroWorkload }}" device: "{{ metroDeviceName }}" @@ -2142,7 +2091,7 @@ params: luns: lunNames: "{{ drLunNames }}" - lunDescs: "{{ drLunDescs }}" + lunDescs: "{{ primaryLunDescs }}" poolId: "{{ drPoolId }}" workload: "{{ drWorkload }}" device: "{{ drDeviceName }}" @@ -2313,7 +2262,7 @@ cgName: "{{ drTestCgName }}" snapNames: "{{ existDrTestLuns + drTestLunNames }}" activate: False - snapDescs: "{{ existDrTestLunsDesc + drTestLunDescs }}" + snapDescs: "{{ existDrTestLunsDesc + primaryLunDescs }}" device: "{{ drDeviceName }}" result: succeeded: "{{ Step_3_3_Completed }}" @@ -2369,9 +2318,6 @@ name: old: "{{ primaryLunNames }}" new: "{{ primaryLunNamesNew }}" - desc: - old: "{{ primaryLunDescs }}" - new: "{{ primaryLunDescsNew }}" device: "{{ primaryDeviceName }}" result: succeeded: "{{ Step_3_7_Completed }}" diff --git a/rundeck/workflow/project001/15_unmap_luns_from_cluster.yml b/rundeck/workflow/project001/15_unmap_luns_from_cluster.yml index 101385e..ace0c9d 100644 --- a/rundeck/workflow/project001/15_unmap_luns_from_cluster.yml +++ b/rundeck/workflow/project001/15_unmap_luns_from_cluster.yml @@ -1059,11 +1059,6 @@ deviceToken: "{{ drDeviceToken }}" deviceSession: "{{ drDeviceSession }}" - - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/sync_replication_cg.yml" - vars: - cgName: "{{ drCgName }}" - waitSync: True - - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/create_snapshot_cg.yml" vars: pgName: "{{ drPgName }}" @@ -1923,11 +1918,6 @@ deviceToken: "{{ drDeviceToken }}" deviceSession: "{{ drDeviceSession }}" - - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/sync_replication_cg.yml" - vars: - cgName: "{{ drCgName }}" - waitSync: True - - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/create_snapshot_cg.yml" vars: pgName: "{{ drPgName }}" diff --git a/rundeck/workflow/project001/21_create_luns.yml b/rundeck/workflow/project001/21_create_luns.yml index 3c850d1..1327ebe 100644 --- a/rundeck/workflow/project001/21_create_luns.yml +++ b/rundeck/workflow/project001/21_create_luns.yml @@ -33,7 +33,7 @@ checked_params: LUN_Size: "{{ (LUN_Size is not none) and (LUN_Size|int >= 1) }}" LUN_Num: "{{ (LUN_Num is not none) and (LUN_Num|int >= 1) }}" - LUN_Description: "{{ (LUN_Description is none) or (LUN_Description|string|length <= 200) }}" + LUN_Description: "{{ (LUN_Description is none) or (LUN_Description|string|length <= 255) }}" LUN_Prefix: "{{ (LUN_Prefix is not none) and (LUN_Prefix|string|length <= 28) }}" Start_Suffix: "{{ (Start_Suffix is none) or (Start_Suffix|int >= 0 and (Start_Suffix|int + LUN_Num|int) < 1000 ) }}" @@ -43,9 +43,9 @@ - set_fact: lunNum: "{{ LUN_Num|int if (LUN_Num is not none) else 0 }}" - lunDesc: "{{Class}}_00_00_00_0000000000000000_01|{{ LUN_Description|string if (LUN_Description is not none) else '' }}" + lunDesc: "{{ LUN_Description|string if (LUN_Description is not none) else '' }}" startSuffix: "{{ Start_Suffix if (Start_Suffix is not none) else 0 }}" - lunNameTemplate: "%s%0{{DEFAULT.suffixDigits}}d" + lunNameTemplate: "%s_NN%0{{DEFAULT.suffixDigits}}d_{{Class}}_00_00_00_0000000000000000_01" lunNames: [] lunDescs: [] lunSizes: [] diff --git a/rundeck/workflow/project001/25_create_snapshots_for_host.yml b/rundeck/workflow/project001/25_create_snapshots_for_host.yml index f1a1d23..4edc807 100644 --- a/rundeck/workflow/project001/25_create_snapshots_for_host.yml +++ b/rundeck/workflow/project001/25_create_snapshots_for_host.yml @@ -56,8 +56,8 @@ - set_fact: sourceCgName: "{{targetLgName}}_SNAP_{{timestamp}}" targetLunPrefix: "{{targetHostName}}_{{protectType}}{{'S' if metroEnable == 'Y' else 'N'}}" - targetLunDesc: "{{ class1 }}_00_{{replicaType}}_{{'00' if replicaType == '00' else site}}_{{'0000000000000000' if replicaType == '00' else sessionName}}_{{'0' if replicaType == '00' else protectType}}1|{{snapRemarks}}" - lunNameTemplate: "%s%0{{DEFAULT.suffixDigits}}d" + targetLunSuffix: "{{ class1 }}_00_{{replicaType}}_{{'00' if replicaType == '00' else site}}_{{'0000000000000000' if replicaType == '00' else sessionName}}_{{'0' if replicaType == '00' else protectType}}1" + lunNameTemplate: "%s%0{{DEFAULT.suffixDigits}}d_%s" - set_fact: Precheck_1_Execute: True @@ -131,7 +131,7 @@ targetLunNames: [] - set_fact: - targetLunNames: "{{ targetLunNames + [ lunNameTemplate | format(targetLunPrefix, nextScsiId|int + item|int) ] }}" + targetLunNames: "{{ targetLunNames + [ lunNameTemplate | format(targetLunPrefix, (nextScsiId|int + item|int), targetLunSuffix) ] }}" with_sequence: start=0 count="{{lunNum}}" - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_luns.yml" @@ -188,7 +188,7 @@ cgName: "{{ sourceCgName }}" snapNames: "{{ targetLunNames }}" activate: "{{ snapActivate }}" - snapDesc: "{{ targetLunDesc }}" + snapDesc: "{{ snapRemarks }}" device: "{{ deviceName }}" - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/create_snapshot_cg.yml" @@ -197,7 +197,7 @@ cgName: "{{ sourceCgName }}" snapNames: "{{ targetLunNames }}" activate: "{{ snapActivate }}" - snapDesc: "{{ targetLunDesc }}" + snapDesc: "{{ snapRemarks }}" - import_tasks: "{{GLOBAL.baseDir}}/task/storage/sync_storage.yml" @@ -396,7 +396,7 @@ cgName: "{{ sourceCgName }}" snapNames: "{{ targetLunNames }}" activate: True - snapDesc: "{{ targetLunDesc }}" + snapDesc: "{{ snapRemarks }}" result: succeeded: "{{ Step_1_1_Completed }}" rollbacked: "{{ Step_1_1_Rollbacked }}" diff --git a/rundeck/workflow/project001/27_create_snapshots_for_cluster.yml b/rundeck/workflow/project001/27_create_snapshots_for_cluster.yml index f41b3fe..0c4ec81 100644 --- a/rundeck/workflow/project001/27_create_snapshots_for_cluster.yml +++ b/rundeck/workflow/project001/27_create_snapshots_for_cluster.yml @@ -56,8 +56,8 @@ - set_fact: sourceCgName: "{{targetLgName}}_SNAP_{{timestamp}}" targetLunPrefix: "{{targetClusterName}}_{{protectType}}{{'S' if metroEnable == 'Y' else 'N'}}" - targetLunDesc: "{{ class1 }}_00_{{replicaType}}_{{'00' if replicaType == '00' else site}}_{{'0000000000000000' if replicaType == '00' else sessionName}}_{{'0' if replicaType == '00' else protectType}}1|{{snapRemarks}}" - lunNameTemplate: "%s%0{{DEFAULT.suffixDigits}}d" + targetLunSuffix: "{{ class1 }}_00_{{replicaType}}_{{'00' if replicaType == '00' else site}}_{{'0000000000000000' if replicaType == '00' else sessionName}}_{{'0' if replicaType == '00' else protectType}}1" + lunNameTemplate: "%s%0{{DEFAULT.suffixDigits}}d_%s" - set_fact: Precheck_1_Execute: True @@ -129,12 +129,12 @@ when: Start_SCSI_ID|default(none) is not none - set_fact: - nextSuffix: "{{ (maxScsiId|int - nextScsiId|int + 1) }}" + nextLunNo: "{{ (maxScsiId|int - nextScsiId|int + 1) }}" targetLunNames: [] lunScsiIds: [] - set_fact: - targetLunNames: "{{ targetLunNames + [ lunNameTemplate | format(targetLunPrefix, ( nextSuffix|int + item|int ) ) ] }}" + targetLunNames: "{{ targetLunNames + [ lunNameTemplate | format(targetLunPrefix, (nextLunNo|int + item|int), targetLunSuffix ) ] }}" lunScsiIds: "{{ lunScsiIds + [nextScsiId|int - item|int] }}" with_sequence: start=0 count="{{lunNum}}" @@ -192,7 +192,7 @@ cgName: "{{ sourceCgName }}" snapNames: "{{ targetLunNames }}" activate: "{{ snapActivate }}" - snapDesc: "{{ targetLunDesc }}" + snapDesc: "{{ snapRemarks }}" device: "{{ deviceName }}" - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/create_snapshot_cg.yml" @@ -201,7 +201,7 @@ cgName: "{{ sourceCgName }}" snapNames: "{{ targetLunNames }}" activate: "{{ snapActivate }}" - snapDesc: "{{ targetLunDesc }}" + snapDesc: "{{ snapRemarks }}" - import_tasks: "{{GLOBAL.baseDir}}/task/storage/sync_storage.yml" @@ -400,7 +400,7 @@ cgName: "{{ sourceCgName }}" snapNames: "{{ targetLunNames }}" activate: True - snapDesc: "{{ targetLunDesc }}" + snapDesc: "{{ snapRemarks }}" result: succeeded: "{{ Step_1_1_Completed }}" rollbacked: "{{ Step_1_1_Rollbacked }}" diff --git a/rundeck/workflow/project001/29_dr_test_for_host.yml b/rundeck/workflow/project001/29_dr_test_for_host.yml index 7702d51..60ec2f3 100644 --- a/rundeck/workflow/project001/29_dr_test_for_host.yml +++ b/rundeck/workflow/project001/29_dr_test_for_host.yml @@ -138,11 +138,6 @@ cgName: "{{ drTestCgName }}" device: "{{ deviceName }}" - - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/sync_replication_cg.yml" - vars: - cgName: "{{ drCgName }}" - waitSync: True - - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/activate_snapshot_cg.yml" vars: cgName: "{{ drTestCgName }}" diff --git a/rundeck/workflow/project001/30_dr_test_clean_for_host.yml b/rundeck/workflow/project001/30_dr_test_clean_for_host.yml index 1aa0097..cbefbd4 100644 --- a/rundeck/workflow/project001/30_dr_test_clean_for_host.yml +++ b/rundeck/workflow/project001/30_dr_test_clean_for_host.yml @@ -42,14 +42,7 @@ drTestCgName: "{{ DR_Test_CG }}" drTestCgId: "{{ DR_Test_CG_ID }}" class3: "{{ Class_3 }}" - - - set_fact: - protectType: "{{ REPTYPE['N3']['enum'] }}" # See ../../config/project001.yml - replicaType: "{{ REPTYPE['N3']['type'] }}" # See ../../config/project001.yml - - - set_fact: - targetLunPrefix: "{{drTestHostName}}_{{protectType}}N" - lunNameTemplate: "%s%0{{DEFAULT.suffixDigits}}d" + lunNameTemplate: "%s_%s_%s_%s_%s_%s_%s_%s" # Example: IT_AIX_HOST1MV_3, TN0000, A, 00, H3, MV, IT0DJGSS01, T1 - import_tasks: "{{GLOBAL.baseDir}}/task/user/login.yml" - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/login_storage.yml" @@ -118,14 +111,14 @@ - set_fact: existDrLunNames: "{{ checkedLuns[drLgName] | json_query('[*].NAME') }}" - existDrLunDescs: "{{ checkedLuns[drLgName] | json_query('[*].DESCRIPTION') }}" + targetLunDescs: "{{ checkedLuns[drLgName] | json_query('[*].DESCRIPTION') }}" targetLunNames: [] - targetLunDescs: [] - set_fact: - targetLunNames: "{{ targetLunNames + [ lunNameTemplate | format(targetLunPrefix, item.1[-3:]|int) ] }}" - targetLunDescs: "{{ targetLunDescs + [ class3 + existDrLunDescs[item.0][1:] ] }}" - with_indexed_items: "{{ existDrLunNames }}" + targetLunNames: "{{ targetLunNames + [ lunNameTemplate | format(drTestHostName, dr[4], class3, dr[6], dr[7], dr[8], dr[9], dr[10] ) ] }}" + vars: + dr: "{{ item.split('_') }}" + with_items: "{{ existDrLunNames }}" - name: Query Snapshots in CG uri: @@ -356,11 +349,6 @@ cgName: "{{ drTestCgName }}" device: "{{ deviceName }}" - - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/sync_replication_cg.yml" - vars: - cgName: "{{ drCgName }}" - waitSync: True - - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/create_snapshot_cg.yml" vars: pgName: "{{ drPgName }}" diff --git a/rundeck/workflow/project001/31_dr_test_for_cluster.yml b/rundeck/workflow/project001/31_dr_test_for_cluster.yml index 17c1441..0cc9e0d 100644 --- a/rundeck/workflow/project001/31_dr_test_for_cluster.yml +++ b/rundeck/workflow/project001/31_dr_test_for_cluster.yml @@ -179,11 +179,6 @@ cgName: "{{ drTestCgName }}" device: "{{ deviceName }}" - - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/sync_replication_cg.yml" - vars: - cgName: "{{ drCgName }}" - waitSync: True - - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/activate_snapshot_cg.yml" vars: cgName: "{{ drTestCgName }}" diff --git a/rundeck/workflow/project001/32_dr_test_clean_for_cluster.yml b/rundeck/workflow/project001/32_dr_test_clean_for_cluster.yml index 37bd246..7ea3c23 100644 --- a/rundeck/workflow/project001/32_dr_test_clean_for_cluster.yml +++ b/rundeck/workflow/project001/32_dr_test_clean_for_cluster.yml @@ -42,14 +42,7 @@ drTestCgName: "{{ DR_Test_CG }}" drTestCgId: "{{ DR_Test_CG_ID }}" class3: "{{ Class_3 }}" - - - set_fact: - protectType: "{{ REPTYPE['N3']['enum'] }}" # See ../../config/project001.yml - replicaType: "{{ REPTYPE['N3']['type'] }}" # See ../../config/project001.yml - - - set_fact: - targetLunPrefix: "{{drTestClusterName}}_{{protectType}}N" - lunNameTemplate: "%s%0{{DEFAULT.suffixDigits}}d" + lunNameTemplate: "%s_%s_%s_%s_%s_%s_%s_%s" # Example: IT_AIX_HOST1MV_3, TN0000, A, 00, H3, MV, IT0DJGSS01, T1 - import_tasks: "{{GLOBAL.baseDir}}/task/user/login.yml" - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/login_storage.yml" @@ -163,14 +156,14 @@ - set_fact: existDrLunNames: "{{ checkedLuns[drLgName] | json_query('[*].NAME') }}" - existDrLunDescs: "{{ checkedLuns[drLgName] | json_query('[*].DESCRIPTION') }}" + targetLunDescs: "{{ checkedLuns[drLgName] | json_query('[*].DESCRIPTION') }}" targetLunNames: [] - targetLunDescs: [] - set_fact: - targetLunNames: "{{ targetLunNames + [ lunNameTemplate | format(targetLunPrefix, item.1[-3:]|int) ] }}" - targetLunDescs: "{{ targetLunDescs + [ class3 + existDrLunDescs[item.0][1:] ] }}" - with_indexed_items: "{{ existDrLunNames }}" + targetLunNames: "{{ targetLunNames + [ lunNameTemplate | format(drTestClusterName, dr[4], class3, dr[6], dr[7], dr[8], dr[9], dr[10] ) ] }}" + vars: + dr: "{{ item.split('_') }}" + with_items: "{{ existDrLunNames }}" - name: Query Snapshots in CG uri: @@ -403,11 +396,6 @@ cgName: "{{ drTestCgName }}" device: "{{ deviceName }}" - - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/sync_replication_cg.yml" - vars: - cgName: "{{ drCgName }}" - waitSync: True - - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/create_snapshot_cg.yml" vars: pgName: "{{ drPgName }}" diff --git a/rundeck/workflow/project001/33_add_lun_group_to_host.yml b/rundeck/workflow/project001/33_add_lun_group_to_host.yml index a02024e..1297b8a 100644 --- a/rundeck/workflow/project001/33_add_lun_group_to_host.yml +++ b/rundeck/workflow/project001/33_add_lun_group_to_host.yml @@ -17,7 +17,7 @@ Storage_Room: "{{ (Storage_Room is not none and Storage_Room != DEFAULT.noneValue) and Storage_Room in AZ }}" Host: "{{ Host is not none and Host != DEFAULT.noneValue }}" Class_1: "{{ Class_1 in ['A','B','C','D'] }}" - Session_Name: "{{ (Session_Name is not none) and (Session_Name|length <= 16 and '_' not in Session_Name) }}" + Session_Name: "{{ (Session_Name is not none) and (Session_Name|length <= 13 and '_' not in Session_Name) }}" Enable_HyperMetro: "{{ Enable_HyperMetro in ['Y','N'] }}" Protection_Level: "{{ Protection_Level|int in [1,2,3] }}" Check_Result_1: "{{ ('lungroup' in Check_Result_1) }}" diff --git a/rundeck/workflow/project001/35_add_lun_group_to_cluster.yml b/rundeck/workflow/project001/35_add_lun_group_to_cluster.yml index a50861b..18ce081 100644 --- a/rundeck/workflow/project001/35_add_lun_group_to_cluster.yml +++ b/rundeck/workflow/project001/35_add_lun_group_to_cluster.yml @@ -16,7 +16,7 @@ Storage_Room: "{{ (Storage_Room is not none and Storage_Room != DEFAULT.noneValue) and Storage_Room in AZ }}" Cluster: "{{ Cluster is not none and Cluster != DEFAULT.noneValue }}" Class_1: "{{ Class_1 in ['A','B','C','D'] }}" - Session_Name: "{{ (Session_Name is not none) and (Session_Name|length <= 16 and '_' not in Session_Name) }}" + Session_Name: "{{ (Session_Name is not none) and (Session_Name|length <= 13 and '_' not in Session_Name) }}" Enable_HyperMetro: "{{ Enable_HyperMetro in ['Y','N'] }}" Protection_Level: "{{ Protection_Level|int in [1,2,3] }}" Check_Result_1: "{{ ('lungroup' in Check_Result_1) }}" diff --git a/rundeck/workflow/project001/37_add_replica_host.yml b/rundeck/workflow/project001/37_add_replica_host.yml index 14bfa50..ee9db06 100644 --- a/rundeck/workflow/project001/37_add_replica_host.yml +++ b/rundeck/workflow/project001/37_add_replica_host.yml @@ -107,12 +107,12 @@ - set_fact: lgSuffix: "{{ LUN_Group[-2:] }}" - lunNameTemplate: "%s%0{{DEFAULT.suffixDigits}}d" + lunNameTemplate: "%s%0{{DEFAULT.suffixDigits}}d_%s" primaryLgName: "{{ LUN_Group }}" primaryLgDescNew: "{{ metroEnable }}{{ protectLevel }}{{class1}}{{class2}}{{class3}}_{{ sessionName }}" primaryPgName: "{{ Protection_Group }}" primaryLunPrefixNew: "{{primaryHostName}}_{{protectType}}{{'S' if metroEnable == 'Y' else 'N'}}" - primaryLunDesc1New: "{{ class1 }}_00_{{replicaType}}_{{'00' if replicaType == '00' else primaryRoom}}_{{'0000000000000000' if replicaType == '00' else sessionName}}_{{'0' if replicaType == '00' else protectType}}1" + primaryLunSuffixNew: "{{ class1 }}_00_{{replicaType}}_{{'00' if replicaType == '00' else primaryRoom}}_{{'0000000000000000' if replicaType == '00' else sessionName}}_{{'0' if replicaType == '00' else protectType}}1" - set_fact: metroDeviceSn: "{{ Metro_Storage|string }}" @@ -145,7 +145,7 @@ drLgDesc: "N{{ protectLevel }}{{ class1 }}{{class2}}{{class3}}_{{ sessionName }}" drPgName: "{{ drHostName }}_PG{{ lgSuffix }}" drLunPrefix: "{{drHostName}}_{{protectType}}N" - drLunDesc1: "{{ class2 }}_00_{{replicaType}}_{{primaryRoom}}_{{sessionName}}_{{protectType}}2" + drLunSuffix: "{{ class2 }}_00_{{replicaType}}_{{primaryRoom}}_{{sessionName}}_{{protectType}}2" when: protectLevel|int >= 2 - set_fact: @@ -157,7 +157,7 @@ - set_fact: drTestLgName: "{{ drTestHostName }}_LG{{ lgSuffix }}" drTestLunPrefix: "{{drTestHostName}}_{{protectType}}N" - drTestLunDesc1: "{{ class3 }}_00_00_{{primaryRoom}}_{{sessionName}}_{{protectType}}3" + drTestLunSuffix: "{{ class3 }}_00_00_{{primaryRoom}}_{{sessionName}}_{{protectType}}3" when: protectLevel|int == 3 - set_fact: @@ -242,15 +242,12 @@ primaryLunSectors: "{{ checkedLuns[primaryLgName] | json_query('[*].CAPACITY') }}" primaryLunDescs: "{{ checkedLuns[primaryLgName] | json_query('[*].DESCRIPTION') }}" primaryLunNamesNew: [] - primaryLunDescsNew: [] - set_fact: - primaryLunNamesNew: "{{ primaryLunNamesNew + [ lunNameTemplate | format(primaryLunPrefixNew, suffix|int) ] }}" - primaryLunDescsNew: "{{ primaryLunDescsNew + [ primaryLunDesc1New + '|' + remark ] }}" + primaryLunNamesNew: "{{ primaryLunNamesNew + [ lunNameTemplate | format(primaryLunPrefixNew, lunNo|int, primaryLunSuffixNew) ] }}" vars: - suffix: "{{ item.1.split('_')[4][2:] }}" - remark: "{{ primaryLunDescs[item.0].split('|')[1] | default('') }}" - with_indexed_items: "{{ primaryLunNames }}" + lunNo: "{{ item.split('_')[4][2:] }}" + with_items: "{{ primaryLunNames }}" - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_pgs.yml" vars: @@ -303,9 +300,9 @@ metroLunNamesNew: [] - set_fact: - metroLunNamesNew: "{{ metroLunNamesNew + [ lunNameTemplate | format(metroLunPrefixNew, suffix|int) ] }}" + metroLunNamesNew: "{{ metroLunNamesNew + [ lunNameTemplate | format(metroLunPrefixNew, lunNo|int, primaryLunSuffixNew) ] }}" vars: - suffix: "{{ item.split('_')[4][2:] }}" + lunNo: "{{ item.split('_')[4][2:] }}" with_items: "{{ primaryLunNames }}" - block: @@ -445,15 +442,12 @@ - set_fact: drLunNames: [] - drLunDescs: [] - set_fact: - drLunNames: "{{ drLunNames + [ lunNameTemplate | format(drLunPrefix, suffix|int) ] }}" - drLunDescs: "{{ drLunDescs + [ drLunDesc1 + '|' + remark ] }}" + drLunNames: "{{ drLunNames + [ lunNameTemplate | format(drLunPrefix, lunNo|int, drLunSuffix) ] }}" vars: - suffix: "{{ item.1.split('_')[4][2:] }}" - remark: "{{ primaryLunDescs[item.0].split('|')[1] | default('') }}" - with_indexed_items: "{{ primaryLunNames }}" + lunNo: "{{ item.split('_')[4][2:] }}" + with_items: "{{ primaryLunNames }}" - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_luns.yml" vars: @@ -499,15 +493,12 @@ - set_fact: drTestLunNames: [] - drTestLunDescs: [] - set_fact: - drTestLunNames: "{{ drTestLunNames + [ lunNameTemplate | format(drTestLunPrefix, suffix|int) ] }}" - drTestLunDescs: "{{ drTestLunDescs + [ drTestLunDesc1 + '|' + remark ] }}" + drTestLunNames: "{{ drTestLunNames + [ lunNameTemplate | format(drTestLunPrefix, lunNo|int, drTestLunSuffix) ] }}" vars: - suffix: "{{ item.1.split('_')[4][2:] }}" - remark: "{{ primaryLunDescs[item.0].split('|')[1] | default('') }}" - with_indexed_items: "{{ primaryLunNames }}" + lunNo: "{{ item.split('_')[4][2:] }}" + with_items: "{{ primaryLunNames }}" - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_luns.yml" vars: @@ -1180,7 +1171,7 @@ params: luns: lunNames: "{{ metroLunNamesNew }}" - lunDescs: "{{ primaryLunDescsNew }}" + lunDescs: "{{ primaryLunDescs }}" poolId: "{{ metroPoolId }}" workload: "{{ metroWorkload }}" device: "{{ metroDeviceName }}" @@ -1198,7 +1189,7 @@ lunSector: "{{ primaryLunSectors[i] }}" poolId: "{{ metroPoolId }}" workload: "{{ metroWorkload }}" - desc: "{{ primaryLunDescsNew[i] }}" + desc: "{{ primaryLunDescs[i] }}" loop: "{{ range(0, metroLunNamesNew|length) | list }}" loop_control: loop_var: i @@ -1320,7 +1311,7 @@ params: luns: lunNames: "{{ drLunNames }}" - lunDescs: "{{ drLunDescs }}" + lunDescs: "{{ primaryLunDescs }}" poolId: "{{ drPoolId }}" workload: "{{ drWorkload }}" device: "{{ drDeviceName }}" @@ -1338,7 +1329,7 @@ lunSector: "{{ primaryLunSectors[i] }}" poolId: "{{ drPoolId }}" workload: "{{ drWorkload }}" - desc: "{{ drLunDescs[i] }}" + desc: "{{ primaryLunDescs[i] }}" loop: "{{ range(0, drLunNames|length) | list }}" loop_control: loop_var: i @@ -1572,7 +1563,7 @@ cgName: "{{ drTestCgName }}" snapNames: "{{ drTestLunNames }}" activate: False - snapDescs: "{{ drTestLunDescs }}" + snapDescs: "{{ primaryLunDescs }}" device: "{{ drDeviceName }}" - set_fact: @@ -1582,18 +1573,13 @@ deviceToken: "{{ drDeviceToken }}" deviceSession: "{{ drDeviceSession }}" - - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/sync_replication_cg.yml" - vars: - cgName: "{{ drCgName }}" - waitSync: True - - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/create_snapshot_cg.yml" vars: pgName: "{{ drPgName }}" cgName: "{{ drTestCgName }}" snapNames: "{{ drTestLunNames }}" activate: False - snapDescs: "{{ drTestLunDescs }}" + snapDescs: "{{ primaryLunDescs }}" - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_luns.yml" vars: @@ -1708,9 +1694,6 @@ name: old: "{{ primaryLunNames }}" new: "{{ primaryLunNamesNew }}" - desc: - old: "{{ primaryLunDescs }}" - new: "{{ primaryLunDescsNew }}" device: "{{ primaryDeviceName }}" - include_tasks: "{{GLOBAL.baseDir}}/task/volume/rename_volumes.yml" @@ -1718,21 +1701,6 @@ volumeNames: "{{ primaryLunNames }}" newVolumeNames: "{{ primaryLunNamesNew }}" - - set_fact: - deviceHost: "{{ primaryDeviceHost }}" - devicePort: "{{ primaryDevicePort }}" - deviceSn: "{{ primaryDeviceSn }}" - deviceToken: "{{ primaryDeviceToken }}" - deviceSession: "{{ primaryDeviceSession }}" - - - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/modify_lun.yml" - vars: - modifyLunId: "{{ primaryLunIds[i] }}" - desc: "{{ primaryLunDescsNew[i] }}" - loop: "{{ range(0, primaryLunIds|length) | list }}" - loop_control: - loop_var: i - - set_fact: Step_7_3_Completed: True @@ -1833,9 +1801,6 @@ name: old: "{{ metroLunNames }}" new: "{{ metroLunNamesNew }}" - desc: - old: "{{ primaryLunDescs }}" - new: "{{ primaryLunDescsNew }}" device: "{{ metroDeviceName }}" - include_tasks: "{{GLOBAL.baseDir}}/task/volume/rename_volumes.yml" @@ -1843,21 +1808,6 @@ volumeNames: "{{ metroLunNames }}" newVolumeNames: "{{ metroLunNamesNew }}" - - set_fact: - deviceHost: "{{ metroDeviceHost }}" - devicePort: "{{ metroDevicePort }}" - deviceSn: "{{ metroDeviceSn }}" - deviceToken: "{{ metroDeviceToken }}" - deviceSession: "{{ metroDeviceSession }}" - - - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/modify_lun.yml" - vars: - modifyLunId: "{{ metroLunIds[i] }}" - desc: "{{ primaryLunDescsNew[i] }}" - loop: "{{ range(0, metroLunIds|length) | list }}" - loop_control: - loop_var: i - - set_fact: Step_8_4_Completed: True @@ -2121,9 +2071,6 @@ name: old: "{{ metroLunNamesNew }}" new: "{{ metroLunNames }}" - desc: - old: "{{ primaryLunDescsNew }}" - new: "{{ primaryLunDescs }}" device: "{{ metroDeviceName }}" - include_tasks: "{{GLOBAL.baseDir}}/task/volume/rename_volumes.yml" @@ -2131,21 +2078,6 @@ volumeNames: "{{ metroLunNamesNew }}" newVolumeNames: "{{ metroLunNames }}" - - set_fact: - deviceHost: "{{ metroDeviceHost }}" - devicePort: "{{ metroDevicePort }}" - deviceSn: "{{ metroDeviceSn }}" - deviceToken: "{{ metroDeviceToken }}" - deviceSession: "{{ metroDeviceSession }}" - - - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/modify_lun.yml" - vars: - modifyLunId: "{{ metroLunIds[i] }}" - desc: "{{ primaryLunDescs[i] }}" - loop: "{{ range(0, metroLunIds|length) | list }}" - loop_control: - loop_var: i - - set_fact: Step_8_4_Rollbacked: True @@ -2246,9 +2178,6 @@ name: old: "{{ primaryLunNamesNew }}" new: "{{ primaryLunNames }}" - desc: - old: "{{ primaryLunDescsNew }}" - new: "{{ primaryLunDescs }}" device: "{{ primaryDeviceName }}" - include_tasks: "{{GLOBAL.baseDir}}/task/volume/rename_volumes.yml" @@ -2256,21 +2185,6 @@ volumeNames: "{{ primaryLunNamesNew }}" newVolumeNames: "{{ primaryLunNames }}" - - set_fact: - deviceHost: "{{ primaryDeviceHost }}" - devicePort: "{{ primaryDevicePort }}" - deviceSn: "{{ primaryDeviceSn }}" - deviceToken: "{{ primaryDeviceToken }}" - deviceSession: "{{ primaryDeviceSession }}" - - - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/modify_lun.yml" - vars: - modifyLunId: "{{ primaryLunIds[i] }}" - desc: "{{ primaryLunDescs[i] }}" - loop: "{{ range(0, primaryLunIds|length) | list }}" - loop_control: - loop_var: i - - set_fact: Step_7_3_Rollbacked: True @@ -3178,7 +3092,7 @@ params: luns: lunNames: "{{ metroLunNamesNew }}" - lunDescs: "{{ primaryLunDescsNew }}" + lunDescs: "{{ primaryLunDescs }}" poolId: "{{ metroPoolId }}" workload: "{{ metroWorkload }}" device: "{{ metroDeviceName }}" @@ -3238,7 +3152,7 @@ params: luns: lunNames: "{{ drLunNames }}" - lunDescs: "{{ drLunDescs }}" + lunDescs: "{{ primaryLunDescs }}" poolId: "{{ drPoolId }}" workload: "{{ drWorkload }}" device: "{{ drDeviceName }}" @@ -3352,7 +3266,7 @@ cgName: "{{ drTestCgName }}" snapNames: "{{ drTestLunNames }}" activate: False - snapDescs: "{{ drTestLunDescs }}" + snapDescs: "{{ primaryLunDescs }}" device: "{{ drDeviceName }}" result: succeeded: "{{ Step_6_1_Completed }}" @@ -3414,9 +3328,6 @@ name: old: "{{ primaryLunNames }}" new: "{{ primaryLunNamesNew }}" - desc: - old: "{{ primaryLunDescs }}" - new: "{{ primaryLunDescsNew }}" device: "{{ primaryDeviceName }}" result: succeeded: "{{ Step_7_3_Completed }}" @@ -3479,9 +3390,6 @@ name: old: "{{ metroLunNames }}" new: "{{ metroLunNamesNew }}" - desc: - old: "{{ primaryLunDescs }}" - new: "{{ primaryLunDescsNew }}" device: "{{ metroDeviceName }}" result: succeeded: "{{ Step_8_4_Completed }}" diff --git a/rundeck/workflow/project001/38_add_drtest_host.yml b/rundeck/workflow/project001/38_add_drtest_host.yml index bd65aa0..d3d07d0 100644 --- a/rundeck/workflow/project001/38_add_drtest_host.yml +++ b/rundeck/workflow/project001/38_add_drtest_host.yml @@ -105,7 +105,7 @@ class3: "{{ Class_3 if (protectLevel|int == 3) else '0' }}" enableAlua: "{{ 1 if (OS_Type == 'SOL') else 0 }}" # Enable ALUA for Solaris enableMetroAlua: "{{ 1 if (OS_Type == 'SOL') else 0 }}" - lunNameTemplate: "%s%0{{DEFAULT.suffixDigits}}d" + lunNameTemplate: "%s%0{{DEFAULT.suffixDigits}}d_%s" - set_fact: drTestHostName: "{{ drHostName[0:-1] }}3" @@ -119,27 +119,23 @@ primaryLunNames: [] primaryLunNamesNew: [] primaryLunPrefixNew: "{{primaryHostName}}_{{protectType}}{{'S' if metroEnable == 'Y' else 'N'}}" - primaryLunDescsNew: [] - primaryLunDesc1New: "{{ class1 }}_00_{{replicaType}}_{{'00' if replicaType == '00' else primaryRoom}}_{{'0000000000000000' if replicaType == '00' else sessionName}}_{{'0' if replicaType == '00' else protectType}}1" + primaryLunSuffixNew: "{{ class1 }}_00_{{replicaType}}_{{'00' if replicaType == '00' else primaryRoom}}_{{'0000000000000000' if replicaType == '00' else sessionName}}_{{'0' if replicaType == '00' else protectType}}1" metroCgNameNew: "{{ replicaType }}_{{ primaryRoom }}_{{ sessionName }}_{{ protectType }}1" metroLunIds: [] metroLunNames: [] metroLunNamesNew: [] metroLunPrefixNew: "{{primaryHostName}}_{{protectType}}M" - metroLunDescsNew: [] - metroLunDesc1New: "{{ class1 }}_00_{{replicaType}}_{{'00' if replicaType == '00' else primaryRoom}}_{{'0000000000000000' if replicaType == '00' else sessionName}}_{{'0' if replicaType == '00' else protectType}}1" + metroLunSuffixNew: "{{ class1 }}_00_{{replicaType}}_{{'00' if replicaType == '00' else primaryRoom}}_{{'0000000000000000' if replicaType == '00' else sessionName}}_{{'0' if replicaType == '00' else protectType}}1" drCgNameNew: "{{ replicaType }}_{{ primaryRoom }}_{{ sessionName }}_{{ protectType }}2" drLgDescNew: "N{{ protectLevel }}{{ class1 }}{{class2}}{{class3}}_{{ sessionName }}" drLunIds: [] drLunNames: [] drLunNamesNew: [] drLunPrefixNew: "{{drHostName}}_{{protectType}}N" - drLunDescsNew: [] - drLunDesc1New: "{{ class2 }}_00_{{replicaType}}_{{primaryRoom}}_{{sessionName}}_{{protectType}}2" + drLunSuffixNew: "{{ class2 }}_00_{{replicaType}}_{{primaryRoom}}_{{sessionName}}_{{protectType}}2" drTestLunNames: [] drTestLunPrefix: "{{drTestHostName}}_{{protectType}}N" - drTestLunDescs: [] - drTestLunDesc1: "{{ class3 }}_00_00_{{primaryRoom}}_{{sessionName}}_{{protectType}}3" + drTestLunSuffix: "{{ class3 }}_00_00_{{primaryRoom}}_{{sessionName}}_{{protectType}}3" drStarCgNameNew: "{{ replicaType }}_{{ primaryRoom }}_{{ sessionName }}_{{ protectType }}0" standbyCgNameNew: "{{ replicaType }}_{{ primaryRoom }}_{{ sessionName }}_{{ protectType }}4" @@ -188,15 +184,12 @@ primaryLgDesc: "{{ checkedLgs[0].DESCRIPTION }}" primaryLunNames: "{{ checkedLuns[primaryLgName] | json_query('[*].NAME') }}" primaryLunIds: "{{ checkedLuns[primaryLgName] | json_query('[*].ID') }}" - primaryLunDescs: "{{ checkedLuns[primaryLgName] | json_query('[*].DESCRIPTION') }}" - set_fact: - primaryLunNamesNew: "{{ primaryLunNamesNew + [ lunNameTemplate | format(primaryLunPrefixNew, suffix|int) ] }}" - primaryLunDescsNew: "{{ primaryLunDescsNew + [ primaryLunDesc1New + '|' + remark ] }}" + primaryLunNamesNew: "{{ primaryLunNamesNew + [ lunNameTemplate | format(primaryLunPrefixNew, lunNo|int, primaryLunSuffixNew) ] }}" vars: - suffix: "{{ item.1.split('_')[4][2:] }}" - remark: "{{ primaryLunDescs[item.0].split('|')[1] | default('') }}" - with_indexed_items: "{{ primaryLunNames }}" + lunNo: "{{ item.split('_')[4][2:] }}" + with_items: "{{ primaryLunNames }}" - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_pgs.yml" vars: @@ -243,15 +236,12 @@ metroLgDesc: "{{ checkedLgs[0].DESCRIPTION }}" metroLunNames: "{{ checkedLuns[primaryLgName] | json_query('[*].NAME') }}" metroLunIds: "{{ checkedLuns[primaryLgName] | json_query('[*].ID') }}" - metroLunDescs: "{{ checkedLuns[primaryLgName] | json_query('[*].DESCRIPTION') }}" - set_fact: - metroLunNamesNew: "{{ metroLunNamesNew + [ lunNameTemplate | format(metroLunPrefixNew, suffix|int) ] }}" - metroLunDescsNew: "{{ metroLunDescsNew + [ metroLunDesc1New + '|' + remark ] }}" + metroLunNamesNew: "{{ metroLunNamesNew + [ lunNameTemplate | format(metroLunPrefixNew, lunNo|int, metroLunSuffixNew) ] }}" vars: - suffix: "{{ item.1.split('_')[4][2:] }}" - remark: "{{ metroLunDescs[item.0].split('|')[1] | default('') }}" - with_indexed_items: "{{ metroLunNames }}" + lunNo: "{{ item.split('_')[4][2:] }}" + with_items: "{{ metroLunNames }}" # End Precheck_2 when: Precheck_2_Execute @@ -321,12 +311,10 @@ drLunSectors: "{{ checkedLuns[drLgName] | json_query('[*].CAPACITY') }}" - set_fact: - drLunNamesNew: "{{ drLunNamesNew + [ lunNameTemplate | format(drLunPrefixNew, suffix|int) ] }}" - drLunDescsNew: "{{ drLunDescsNew + [ drLunDesc1New + '|' + remark ] }}" + drLunNamesNew: "{{ drLunNamesNew + [ lunNameTemplate | format(drLunPrefixNew, lunNo|int, drLunSuffixNew) ] }}" vars: - suffix: "{{ item.1.split('_')[4][2:] }}" - remark: "{{ drLunDescs[item.0].split('|')[1] | default('') }}" - with_indexed_items: "{{ drLunNames }}" + lunNo: "{{ item.split('_')[4][2:] }}" + with_items: "{{ drLunNames }}" # End Precheck_3 when: Precheck_3_Execute @@ -350,12 +338,10 @@ checkExist: False - set_fact: - drTestLunNames: "{{ drTestLunNames + [ lunNameTemplate | format(drTestLunPrefix, suffix|int) ] }}" - drTestLunDescs: "{{ drTestLunDescs + [ drTestLunDesc1 + '|' + remark ] }}" + drTestLunNames: "{{ drTestLunNames + [ lunNameTemplate | format(drTestLunPrefix, lunNo|int, drTestLunSuffix) ] }}" vars: - suffix: "{{ item.1.split('_')[4][2:] }}" - remark: "{{ drLunDescs[item.0].split('|')[1] | default('') }}" - with_indexed_items: "{{ drLunNames }}" + lunNo: "{{ item.split('_')[4][2:] }}" + with_items: "{{ drLunNames }}" # End Precheck_4 when: Precheck_4_Execute @@ -579,7 +565,7 @@ cgName: "{{ drTestCgName }}" snapNames: "{{ drTestLunNames }}" activate: False - snapDescs: "{{ drTestLunDescs }}" + snapDescs: "{{ drLunDescs }}" device: "{{ drDeviceName }}" - set_fact: @@ -589,18 +575,13 @@ deviceToken: "{{ drDeviceToken }}" deviceSession: "{{ drDeviceSession }}" - - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/sync_replication_cg.yml" - vars: - cgName: "{{ drCgName }}" - waitSync: True - - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/create_snapshot_cg.yml" vars: pgName: "{{ drPgName }}" cgName: "{{ drTestCgName }}" snapNames: "{{ drTestLunNames }}" activate: False - snapDescs: "{{ drTestLunDescs }}" + snapDescs: "{{ drLunDescs }}" - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_luns.yml" vars: @@ -771,9 +752,6 @@ name: old: "{{ drLunNames }}" new: "{{ drLunNamesNew }}" - desc: - old: "{{ drLunDescs }}" - new: "{{ drLunDescsNew }}" device: "{{ drDeviceName }}" - include_tasks: "{{GLOBAL.baseDir}}/task/volume/rename_volumes.yml" @@ -781,21 +759,6 @@ volumeNames: "{{ drLunNames }}" newVolumeNames: "{{ drLunNamesNew }}" - - set_fact: - deviceHost: "{{ drDeviceHost }}" - devicePort: "{{ drDevicePort }}" - deviceSn: "{{ drDeviceSn }}" - deviceToken: "{{ drDeviceToken }}" - deviceSession: "{{ drDeviceSession }}" - - - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/modify_lun.yml" - vars: - modifyLunId: "{{ drLunIds[i] }}" - desc: "{{ drLunDescsNew[i] }}" - loop: "{{ range(0, drLunIds|length) | list }}" - loop_control: - loop_var: i - - set_fact: Step_3_5_Completed: True @@ -896,9 +859,6 @@ name: old: "{{ metroLunNames }}" new: "{{ metroLunNamesNew }}" - desc: - old: "{{ metroLunDescs }}" - new: "{{ metroLunDescsNew }}" device: "{{ metroDeviceName }}" - include_tasks: "{{GLOBAL.baseDir}}/task/volume/rename_volumes.yml" @@ -906,21 +866,6 @@ volumeNames: "{{ metroLunNames }}" newVolumeNames: "{{ metroLunNamesNew }}" - - set_fact: - deviceHost: "{{ metroDeviceHost }}" - devicePort: "{{ metroDevicePort }}" - deviceSn: "{{ metroDeviceSn }}" - deviceToken: "{{ metroDeviceToken }}" - deviceSession: "{{ metroDeviceSession }}" - - - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/modify_lun.yml" - vars: - modifyLunId: "{{ metroLunIds[i] }}" - desc: "{{ metroLunDescsNew[i] }}" - loop: "{{ range(0, metroLunIds|length) | list }}" - loop_control: - loop_var: i - - set_fact: Step_4_4_Completed: True @@ -993,9 +938,6 @@ name: old: "{{ primaryLunNames }}" new: "{{ primaryLunNamesNew }}" - desc: - old: "{{ primaryLunDescs }}" - new: "{{ primaryLunDescsNew }}" device: "{{ primaryDeviceName }}" - include_tasks: "{{GLOBAL.baseDir}}/task/volume/rename_volumes.yml" @@ -1003,21 +945,6 @@ volumeNames: "{{ primaryLunNames }}" newVolumeNames: "{{ primaryLunNamesNew }}" - - set_fact: - deviceHost: "{{ primaryDeviceHost }}" - devicePort: "{{ primaryDevicePort }}" - deviceSn: "{{ primaryDeviceSn }}" - deviceToken: "{{ primaryDeviceToken }}" - deviceSession: "{{ primaryDeviceSession }}" - - - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/modify_lun.yml" - vars: - modifyLunId: "{{ primaryLunIds[i] }}" - desc: "{{ primaryLunDescsNew[i] }}" - loop: "{{ range(0, primaryLunIds|length) | list }}" - loop_control: - loop_var: i - - set_fact: Step_5_3_Completed: True @@ -1091,9 +1018,6 @@ name: old: "{{ primaryLunNamesNew }}" new: "{{ primaryLunNames }}" - desc: - old: "{{ primaryLunDescsNew }}" - new: "{{ primaryLunDescs }}" device: "{{ primaryDeviceName }}" - include_tasks: "{{GLOBAL.baseDir}}/task/volume/rename_volumes.yml" @@ -1101,21 +1025,6 @@ volumeNames: "{{ primaryLunNamesNew }}" newVolumeNames: "{{ primaryLunNames }}" - - set_fact: - deviceHost: "{{ primaryDeviceHost }}" - devicePort: "{{ primaryDevicePort }}" - deviceSn: "{{ primaryDeviceSn }}" - deviceToken: "{{ primaryDeviceToken }}" - deviceSession: "{{ primaryDeviceSession }}" - - - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/modify_lun.yml" - vars: - modifyLunId: "{{ primaryLunIds[i] }}" - desc: "{{ primaryLunDescs[i] }}" - loop: "{{ range(0, primaryLunIds|length) | list }}" - loop_control: - loop_var: i - - set_fact: Step_5_3_Rollbacked: True @@ -1188,9 +1097,6 @@ name: old: "{{ metroLunNamesNew }}" new: "{{ metroLunNames }}" - desc: - old: "{{ metroLunDescsNew }}" - new: "{{ metroLunDescs }}" device: "{{ metroDeviceName }}" - include_tasks: "{{GLOBAL.baseDir}}/task/volume/rename_volumes.yml" @@ -1198,21 +1104,6 @@ volumeNames: "{{ metroLunNamesNew }}" newVolumeNames: "{{ metroLunNames }}" - - set_fact: - deviceHost: "{{ metroDeviceHost }}" - devicePort: "{{ metroDevicePort }}" - deviceSn: "{{ metroDeviceSn }}" - deviceToken: "{{ metroDeviceToken }}" - deviceSession: "{{ metroDeviceSession }}" - - - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/modify_lun.yml" - vars: - modifyLunId: "{{ metroLunIds[i] }}" - desc: "{{ metroLunDescs[i] }}" - loop: "{{ range(0, metroLunIds|length) | list }}" - loop_control: - loop_var: i - - set_fact: Step_4_4_Rollbacked: True @@ -1313,9 +1204,6 @@ name: old: "{{ drLunNamesNew }}" new: "{{ drLunNames }}" - desc: - old: "{{ drLunDescsNew }}" - new: "{{ drLunDescs }}" device: "{{ drDeviceName }}" - include_tasks: "{{GLOBAL.baseDir}}/task/volume/rename_volumes.yml" @@ -1323,21 +1211,6 @@ volumeNames: "{{ drLunNamesNew }}" newVolumeNames: "{{ drLunNames }}" - - set_fact: - deviceHost: "{{ drDeviceHost }}" - devicePort: "{{ drDevicePort }}" - deviceSn: "{{ drDeviceSn }}" - deviceToken: "{{ drDeviceToken }}" - deviceSession: "{{ drDeviceSession }}" - - - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/modify_lun.yml" - vars: - modifyLunId: "{{ drLunIds[i] }}" - desc: "{{ drLunDescs[i] }}" - loop: "{{ range(0, drLunIds|length) | list }}" - loop_control: - loop_var: i - - set_fact: Step_3_5_Rollbacked: True @@ -1663,7 +1536,7 @@ cgName: "{{ drTestCgName }}" snapNames: "{{ drTestLunNames }}" activate: False - snapDescs: "{{ drTestLunDescs }}" + snapDescs: "{{ drLunDescs }}" device: "{{ drDeviceName }}" result: succeeded: "{{ Step_2_1_Completed }}" @@ -1755,9 +1628,6 @@ name: old: "{{ drLunNames }}" new: "{{ drLunNamesNew }}" - desc: - old: "{{ drLunDescs }}" - new: "{{ drLunDescsNew }}" device: "{{ drDeviceName }}" result: succeeded: "{{ Step_3_5_Completed }}" @@ -1820,9 +1690,6 @@ name: old: "{{ metroLunNames }}" new: "{{ metroLunNamesNew }}" - desc: - old: "{{ metroLunDescs }}" - new: "{{ metroLunDescsNew }}" device: "{{ metroDeviceName }}" result: succeeded: "{{ Step_4_4_Completed }}" @@ -1870,9 +1737,6 @@ name: old: "{{ primaryLunNames }}" new: "{{ primaryLunNamesNew }}" - desc: - old: "{{ primaryLunDescs }}" - new: "{{ primaryLunDescsNew }}" device: "{{ primaryDeviceName }}" result: succeeded: "{{ Step_5_3_Completed }}" diff --git a/rundeck/workflow/project001/39_add_metro_host.yml b/rundeck/workflow/project001/39_add_metro_host.yml index bb03617..ec6bf0a 100644 --- a/rundeck/workflow/project001/39_add_metro_host.yml +++ b/rundeck/workflow/project001/39_add_metro_host.yml @@ -85,7 +85,7 @@ class3: "{{ Class_3 if (protectLevel|int == 3) else '0' }}" enableAlua: "{{ 1 if (OS_Type == 'SOL') else 0 }}" # Enable ALUA for Solaris enableMetroAlua: "{{ 1 if (OS_Type == 'SOL') else 0 }}" - lunNameTemplate: "%s%0{{DEFAULT.suffixDigits}}d" + lunNameTemplate: "%s%0{{DEFAULT.suffixDigits}}d_%s" - set_fact: metroClusterName: "{{ Metro_Cluster_Name }}" @@ -123,27 +123,23 @@ primaryLunNames: [] primaryLunNamesNew: [] primaryLunPrefixNew: "{{primaryHostName}}_{{protectType}}{{'S' if metroEnable == 'Y' else 'N'}}" - primaryLunDescsNew: [] - primaryLunDesc1New: "{{ class1 }}_00_{{replicaType}}_{{'00' if replicaType == '00' else primaryRoom}}_{{'0000000000000000' if replicaType == '00' else sessionName}}_{{'0' if replicaType == '00' else protectType}}1" + primaryLunSuffixNew: "{{ class1 }}_00_{{replicaType}}_{{'00' if replicaType == '00' else primaryRoom}}_{{'0000000000000000' if replicaType == '00' else sessionName}}_{{'0' if replicaType == '00' else protectType}}1" metroLunNames: [] metroLunPrefix: "{{primaryHostName}}_{{protectType}}M" - metroLunDescs: [] - metroLunDesc1: "{{ class1 }}_00_{{replicaType}}_{{'00' if replicaType == '00' else primaryRoom}}_{{'0000000000000000' if replicaType == '00' else sessionName}}_{{'0' if replicaType == '00' else protectType}}1" + metroLunSuffix: "{{ class1 }}_00_{{replicaType}}_{{'00' if replicaType == '00' else primaryRoom}}_{{'0000000000000000' if replicaType == '00' else sessionName}}_{{'0' if replicaType == '00' else protectType}}1" drCgNameNew: "{{ replicaType }}_{{ primaryRoom }}_{{ sessionName }}_{{ protectType }}2" drLgDescNew: "N{{ protectLevel }}{{ class1 }}{{class2}}{{class3}}_{{ sessionName }}" drLunIds: [] drLunNames: [] drLunNamesNew: [] drLunPrefixNew: "{{DR_Host}}_{{protectType}}N" - drLunDescsNew: [] - drLunDesc1New: "{{ class2 }}_00_{{replicaType}}_{{primaryRoom}}_{{sessionName}}_{{protectType}}2" + drLunSuffixNew: "{{ class2 }}_00_{{replicaType}}_{{primaryRoom}}_{{sessionName}}_{{protectType}}2" drTestCgNameNew: "{{ replicaType }}_{{ primaryRoom }}_{{ sessionName }}_{{ protectType }}3" drTestLunIds: [] drTestLunNames: [] drTestLunNamesNew: [] drTestLunPrefixNew: "{{DR_Test_Host}}_{{protectType}}N" - drTestLunDescsNew: [] - drTestLunDesc1New: "{{ class3 }}_00_00_{{primaryRoom}}_{{sessionName}}_{{protectType}}3" + drTestLunSuffixNew: "{{ class3 }}_00_00_{{primaryRoom}}_{{sessionName}}_{{protectType}}3" - set_fact: Precheck_1_Execute: True @@ -233,12 +229,10 @@ primaryLunDescs: "{{ checkedLuns[primaryLgName] | json_query('[*].DESCRIPTION') }}" - set_fact: - primaryLunNamesNew: "{{ primaryLunNamesNew + [ lunNameTemplate | format(primaryLunPrefixNew, suffix|int) ] }}" - primaryLunDescsNew: "{{ primaryLunDescsNew + [ primaryLunDesc1New + '|' + remark ] }}" + primaryLunNamesNew: "{{ primaryLunNamesNew + [ lunNameTemplate | format(primaryLunPrefixNew, lunNo|int, primaryLunSuffixNew) ] }}" vars: - suffix: "{{ item.1.split('_')[4][2:] }}" - remark: "{{ primaryLunDescs[item.0].split('|')[1] | default('') }}" - with_indexed_items: "{{ primaryLunNames }}" + lunNo: "{{ item.split('_')[4][2:] }}" + with_items: "{{ primaryLunNames }}" - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_pgs.yml" vars: @@ -280,9 +274,9 @@ metroDeviceSession: "{{ deviceSession }}" - set_fact: - metroLunNames: "{{ metroLunNames + [ lunNameTemplate | format(metroLunPrefix, suffix|int) ] }}" + metroLunNames: "{{ metroLunNames + [ lunNameTemplate | format(metroLunPrefix, lunNo|int, metroLunSuffix) ] }}" vars: - suffix: "{{ item.split('_')[4][2:] }}" + lunNo: "{{ item.split('_')[4][2:] }}" with_items: "{{ primaryLunNames }}" - set_fact: @@ -367,15 +361,12 @@ drLgDesc: "{{ checkedLgs[0].DESCRIPTION }}" drLunIds: "{{ checkedLuns[drLgName] | json_query('[*].ID') }}" drLunNames: "{{ checkedLuns[drLgName] | json_query('[*].NAME') }}" - drLunDescs: "{{ checkedLuns[drLgName] | json_query('[*].DESCRIPTION') }}" - set_fact: - drLunNamesNew: "{{ drLunNamesNew + [ lunNameTemplate | format(drLunPrefixNew, suffix|int) ] }}" - drLunDescsNew: "{{ drLunDescsNew + [ drLunDesc1New + '|' + remark ] }}" + drLunNamesNew: "{{ drLunNamesNew + [ lunNameTemplate | format(drLunPrefixNew, lunNo|int, drLunSuffixNew) ] }}" vars: - suffix: "{{ item.1.split('_')[4][2:] }}" - remark: "{{ drLunDescs[item.0].split('|')[1] | default('') }}" - with_indexed_items: "{{ drLunNames }}" + lunNo: "{{ item.split('_')[4][2:] }}" + with_items: "{{ drLunNames }}" - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_pgs.yml" vars: @@ -408,15 +399,12 @@ drTestLgDesc: "{{ checkedLgs[0].DESCRIPTION }}" drTestLunNames: "{{ checkedLuns[drTestLgName] | json_query('[*].NAME') }}" drTestLunIds: "{{ checkedLuns[drTestLgName] | json_query('[*].ID') }}" - drTestLunDescs: "{{ checkedLuns[drTestLgName] | json_query('[*].DESCRIPTION') }}" - set_fact: - drTestLunNamesNew: "{{ drTestLunNamesNew + [ lunNameTemplate | format(drTestLunPrefixNew, suffix|int) ] }}" - drTestLunDescsNew: "{{ drTestLunDescsNew + [ drTestLunDesc1New + '|' + remark ] }}" + drTestLunNamesNew: "{{ drTestLunNamesNew + [ lunNameTemplate | format(drTestLunPrefixNew, lunNo|int, drTestLunSuffixNew) ] }}" vars: - suffix: "{{ item.1.split('_')[4][2:] }}" - remark: "{{ drTestLunDescs[item.0].split('|')[1] | default('') }}" - with_indexed_items: "{{ drTestLunNames }}" + lunNo: "{{ item.split('_')[4][2:] }}" + with_items: "{{ drTestLunNames }}" # End Precheck_4 when: Precheck_4_Execute @@ -751,7 +739,7 @@ params: luns: lunNames: "{{ metroLunNames }}" - lunDescs: "{{ primaryLunDescsNew }}" + lunDescs: "{{ primaryLunDescs }}" poolId: "{{ metroPoolId }}" workload: "{{ metroWorkload }}" device: "{{ metroDeviceName }}" @@ -769,7 +757,7 @@ lunSector: "{{ primaryLunSectors[i] }}" poolId: "{{ metroPoolId }}" workload: "{{ metroWorkload }}" - desc: "{{ primaryLunDescsNew[i] }}" + desc: "{{ primaryLunDescs[i] }}" loop: "{{ range(0, metroLunNames|length) | list }}" loop_control: loop_var: i @@ -1109,9 +1097,6 @@ name: old: "{{ primaryLunNames }}" new: "{{ primaryLunNamesNew }}" - desc: - old: "{{ primaryLunDescs }}" - new: "{{ primaryLunDescsNew }}" device: "{{ primaryDeviceName }}" - include_tasks: "{{GLOBAL.baseDir}}/task/volume/rename_volumes.yml" @@ -1119,21 +1104,6 @@ volumeNames: "{{ primaryLunNames }}" newVolumeNames: "{{ primaryLunNamesNew }}" - - set_fact: - deviceHost: "{{ primaryDeviceHost }}" - devicePort: "{{ primaryDevicePort }}" - deviceSn: "{{ primaryDeviceSn }}" - deviceToken: "{{ primaryDeviceToken }}" - deviceSession: "{{ primaryDeviceSession }}" - - - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/modify_lun.yml" - vars: - modifyLunId: "{{ primaryLunIds[i] }}" - desc: "{{ primaryLunDescsNew[i] }}" - loop: "{{ range(0, primaryLunIds|length) | list }}" - loop_control: - loop_var: i - - set_fact: Step_4_3_Completed: True @@ -1234,9 +1204,6 @@ name: old: "{{ drLunNames }}" new: "{{ drLunNamesNew }}" - desc: - old: "{{ drLunDescs }}" - new: "{{ drLunDescsNew }}" device: "{{ drDeviceName }}" - include_tasks: "{{GLOBAL.baseDir}}/task/volume/rename_volumes.yml" @@ -1244,21 +1211,6 @@ volumeNames: "{{ drLunNames }}" newVolumeNames: "{{ drLunNamesNew }}" - - set_fact: - deviceHost: "{{ drDeviceHost }}" - devicePort: "{{ drDevicePort }}" - deviceSn: "{{ drDeviceSn }}" - deviceToken: "{{ drDeviceToken }}" - deviceSession: "{{ drDeviceSession }}" - - - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/modify_lun.yml" - vars: - modifyLunId: "{{ drLunIds[i] }}" - desc: "{{ drLunDescsNew[i] }}" - loop: "{{ range(0, drLunIds|length) | list }}" - loop_control: - loop_var: i - - set_fact: Step_5_4_Completed: True @@ -1303,9 +1255,6 @@ name: old: "{{ drTestLunNames }}" new: "{{ drTestLunNamesNew }}" - desc: - old: "{{ drTestLunDescs }}" - new: "{{ drTestLunDescsNew }}" device: "{{ drDeviceName }}" - include_tasks: "{{GLOBAL.baseDir}}/task/volume/rename_volumes.yml" @@ -1313,21 +1262,6 @@ volumeNames: "{{ drTestLunNames }}" newVolumeNames: "{{ drTestLunNamesNew }}" - - set_fact: - deviceHost: "{{ drDeviceHost }}" - devicePort: "{{ drDevicePort }}" - deviceSn: "{{ drDeviceSn }}" - deviceToken: "{{ drDeviceToken }}" - deviceSession: "{{ drDeviceSession }}" - - - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/modify_lun.yml" - vars: - modifyLunId: "{{ drTestLunIds[i] }}" - desc: "{{ drTestLunDescsNew[i] }}" - loop: "{{ range(0, drTestLunIds|length) | list }}" - loop_control: - loop_var: i - - set_fact: Step_6_2_Completed: True @@ -1506,9 +1440,6 @@ name: old: "{{ drTestLunNamesNew }}" new: "{{ drTestLunNames }}" - desc: - old: "{{ drTestLunDescsNew }}" - new: "{{ drTestLunDescs }}" device: "{{ drDeviceName }}" - include_tasks: "{{GLOBAL.baseDir}}/task/volume/rename_volumes.yml" @@ -1516,22 +1447,6 @@ volumeNames: "{{ drTestLunNamesNew }}" newVolumeNames: "{{ drTestLunNames }}" - - set_fact: - deviceHost: "{{ drDeviceHost }}" - devicePort: "{{ drDevicePort }}" - deviceSn: "{{ drDeviceSn }}" - deviceToken: "{{ drDeviceToken }}" - deviceSession: "{{ drDeviceSession }}" - - - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/modify_lun.yml" - vars: - modifyLunId: "{{ drTestLunIds[i] }}" - newLunName: "{{ drTestLunNames[i] }}" - desc: "{{ drTestLunDescs[i] }}" - loop: "{{ range(0, drTestLunIds|length) | list }}" - loop_control: - loop_var: i - - set_fact: Step_6_2_Rollbacked: True @@ -1573,9 +1488,6 @@ name: old: "{{ drLunNamesNew }}" new: "{{ drLunNames }}" - desc: - old: "{{ drLunDescsNew }}" - new: "{{ drLunDescs }}" device: "{{ drDeviceName }}" - include_tasks: "{{GLOBAL.baseDir}}/task/volume/rename_volumes.yml" @@ -1583,21 +1495,6 @@ volumeNames: "{{ drLunNamesNew }}" newVolumeNames: "{{ drLunNames }}" - - set_fact: - deviceHost: "{{ drDeviceHost }}" - devicePort: "{{ drDevicePort }}" - deviceSn: "{{ drDeviceSn }}" - deviceToken: "{{ drDeviceToken }}" - deviceSession: "{{ drDeviceSession }}" - - - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/modify_lun.yml" - vars: - modifyLunId: "{{ drLunIds[i] }}" - desc: "{{ drLunDescs[i] }}" - loop: "{{ range(0, drLunIds|length) | list }}" - loop_control: - loop_var: i - - set_fact: Step_5_4_Rollbacked: True @@ -1698,9 +1595,6 @@ name: old: "{{ primaryLunNamesNew }}" new: "{{ primaryLunNames }}" - desc: - old: "{{ primaryLunDescsNew }}" - new: "{{ primaryLunDescs }}" device: "{{ primaryDeviceName }}" - include_tasks: "{{GLOBAL.baseDir}}/task/volume/rename_volumes.yml" @@ -1708,21 +1602,6 @@ volumeNames: "{{ primaryLunNamesNew }}" newVolumeNames: "{{ primaryLunNames }}" - - set_fact: - deviceHost: "{{ primaryDeviceHost }}" - devicePort: "{{ primaryDevicePort }}" - deviceSn: "{{ primaryDeviceSn }}" - deviceToken: "{{ primaryDeviceToken }}" - deviceSession: "{{ primaryDeviceSession }}" - - - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/modify_lun.yml" - vars: - modifyLunId: "{{ primaryLunIds[i] }}" - desc: "{{ primaryLunDescs[i] }}" - loop: "{{ range(0, primaryLunIds|length) | list }}" - loop_control: - loop_var: i - - set_fact: Step_4_3_Rollbacked: True @@ -2175,7 +2054,7 @@ params: luns: lunNames: "{{ metroLunNames }}" - lunDescs: "{{ primaryLunDescsNew }}" + lunDescs: "{{ primaryLunDescs }}" poolId: "{{ metroPoolId }}" workload: "{{ metroWorkload }}" device: "{{ metroDeviceName }}" @@ -2319,9 +2198,6 @@ name: old: "{{ primaryLunNames }}" new: "{{ primaryLunNamesNew }}" - desc: - old: "{{ primaryLunDescs }}" - new: "{{ primaryLunDescsNew }}" device: "{{ primaryDeviceName }}" result: succeeded: "{{ Step_4_3_Completed }}" @@ -2384,9 +2260,6 @@ name: old: "{{ drLunNames }}" new: "{{ drLunNamesNew }}" - desc: - old: "{{ drLunDescs }}" - new: "{{ drLunDescsNew }}" device: "{{ drDeviceName }}" result: succeeded: "{{ Step_5_4_Completed }}" @@ -2416,9 +2289,6 @@ name: old: "{{ drTestLunNames }}" new: "{{ drTestLunNamesNew }}" - desc: - old: "{{ drTestLunDescs }}" - new: "{{ drTestLunDescsNew }}" device: "{{ drDeviceName }}" result: succeeded: "{{ Step_6_2_Completed }}" diff --git a/rundeck/workflow/project001/40_remove_replica_host.yml b/rundeck/workflow/project001/40_remove_replica_host.yml index e1c95fe..30bd997 100644 --- a/rundeck/workflow/project001/40_remove_replica_host.yml +++ b/rundeck/workflow/project001/40_remove_replica_host.yml @@ -118,7 +118,7 @@ class3: "{{ Class_3 if (protectLevel|int == 3) else '0' }}" enableAlua: "{{ 1 if (OS_Type == 'SOL') else 0 }}" # Enable ALUA for Solaris enableMetroAlua: "{{ 1 if (OS_Type == 'SOL') else 0 }}" - lunNameTemplate: "%s%0{{DEFAULT.suffixDigits}}d" + lunNameTemplate: "%s%0{{DEFAULT.suffixDigits}}d_%s" - set_fact: primaryLgDescNew: "{{ metroEnable }}{{ protectLevel }}{{class1}}{{class2}}{{class3}}_{{ sessionName }}" @@ -126,16 +126,14 @@ primaryLunNames: [] primaryLunNamesNew: [] primaryLunPrefixNew: "{{primaryHostName}}_{{protectType}}{{'S' if metroEnable == 'Y' else 'N'}}" - primaryLunDescsNew: [] - primaryLunDesc1New: "{{ class1 }}_00_{{replicaType}}_{{'00' if replicaType == '00' else primaryRoom}}_{{'0000000000000000' if replicaType == '00' else sessionName}}_{{'0' if replicaType == '00' else protectType}}1" + primaryLunSuffixNew: "{{ class1 }}_00_{{replicaType}}_{{'00' if replicaType == '00' else primaryRoom}}_{{'0000000000000000' if replicaType == '00' else sessionName}}_{{'0' if replicaType == '00' else protectType}}1" metroCgNameNew: "{{ replicaType }}_{{ primaryRoom }}_{{ sessionName }}_{{ protectType }}1" metroLunIds: [] metroLunNames: [] metroLunsInTier: [] metroLunNamesNew: [] metroLunPrefixNew: "{{primaryHostName}}_{{protectType}}M" - metroLunDescsNew: [] - metroLunDesc1New: "{{ class1 }}_00_{{replicaType}}_{{'00' if replicaType == '00' else primaryRoom}}_{{'0000000000000000' if replicaType == '00' else sessionName}}_{{'0' if replicaType == '00' else protectType}}1" + metroLunSuffixNew: "{{ class1 }}_00_{{replicaType}}_{{'00' if replicaType == '00' else primaryRoom}}_{{'0000000000000000' if replicaType == '00' else sessionName}}_{{'0' if replicaType == '00' else protectType}}1" drCgNameNew: "{{ replicaType }}_{{ primaryRoom }}_{{ sessionName }}_{{ protectType }}2" drLgDescNew: "N{{ protectLevel }}{{ class1 }}{{class2}}{{class3}}_{{ sessionName }}" drLunIds: [] @@ -143,15 +141,13 @@ drLunsInTier: [] drLunNamesNew: [] drLunPrefixNew: "{{drHostName}}_{{protectType}}N" - drLunDescsNew: [] - drLunDesc1New: "{{ class2 }}_00_{{replicaType}}_{{primaryRoom}}_{{sessionName}}_{{protectType}}2" + drLunSuffixNew: "{{ class2 }}_00_{{replicaType}}_{{primaryRoom}}_{{sessionName}}_{{protectType}}2" drTestCgNameNew: "{{ replicaType }}_{{ primaryRoom }}_{{ sessionName }}_{{ protectType }}3" drTestLunIds: [] drTestLunNames: [] drTestLunNamesNew: [] drTestLunPrefixNew: "{{drTestHostName}}_{{protectType}}N" - drTestLunDescsNew: [] - drTestLunDesc1New: "{{ class3 }}_00_00_{{primaryRoom}}_{{sessionName}}_{{protectType}}3" + drTestLunSuffixNew: "{{ class3 }}_00_00_{{primaryRoom}}_{{sessionName}}_{{protectType}}3" drStarCgNameNew: "{{ replicaType }}_{{ primaryRoom }}_{{ sessionName }}_{{ protectType }}0" standbyCgNameNew: "{{ replicaType }}_{{ primaryRoom }}_{{ sessionName }}_{{ protectType }}4" @@ -204,12 +200,10 @@ primaryLunDescs: "{{ checkedLuns[primaryLgName] | json_query('[*].DESCRIPTION') }}" - set_fact: - primaryLunNamesNew: "{{ primaryLunNamesNew + [ lunNameTemplate | format(primaryLunPrefixNew, suffix|int) ] }}" - primaryLunDescsNew: "{{ primaryLunDescsNew + [ primaryLunDesc1New + '|' + remark ] }}" + primaryLunNamesNew: "{{ primaryLunNamesNew + [ lunNameTemplate | format(primaryLunPrefixNew, lunNo|int, primaryLunSuffixNew) ] }}" vars: - suffix: "{{ item.1.split('_')[4][2:] }}" - remark: "{{ primaryLunDescs[item.0].split('|')[1] | default('') }}" - with_indexed_items: "{{ primaryLunNames }}" + lunNo: "{{ item.split('_')[4][2:] }}" + with_items: "{{ primaryLunNames }}" - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_pgs.yml" vars: @@ -295,12 +289,10 @@ metroLunsWorkload: "{{ checkedLuns[primaryLgName] | json_query('[*].WORKLOADTYPEID') }}" - set_fact: - metroLunNamesNew: "{{ metroLunNamesNew + [ lunNameTemplate | format(metroLunPrefixNew, suffix|int) ] }}" - metroLunDescsNew: "{{ metroLunDescsNew + [ metroLunDesc1New + '|' + remark ] }}" + metroLunNamesNew: "{{ metroLunNamesNew + [ lunNameTemplate | format(metroLunPrefixNew, lunNo|int, metroLunSuffixNew) ] }}" vars: - suffix: "{{ item.1.split('_')[4][2:] }}" - remark: "{{ metroLunDescs[item.0].split('|')[1] | default('') }}" - with_indexed_items: "{{ metroLunNames }}" + lunNo: "{{ item.split('_')[4][2:] }}" + with_items: "{{ metroLunNames }}" - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_pgs.yml" vars: @@ -406,12 +398,10 @@ drLunsWorkload: "{{ checkedLuns[drLgName] | json_query('[*].WORKLOADTYPEID') }}" - set_fact: - drLunNamesNew: "{{ drLunNamesNew + [ lunNameTemplate | format(drLunPrefixNew, suffix|int) ] }}" - drLunDescsNew: "{{ drLunDescsNew + [ drLunDesc1New + '|' + remark ] }}" + drLunNamesNew: "{{ drLunNamesNew + [ lunNameTemplate | format(drLunPrefixNew, lunNo|int, drLunSuffixNew) ] }}" vars: - suffix: "{{ item.1.split('_')[4][2:] }}" - remark: "{{ drLunDescs[item.0].split('|')[1] | default('') }}" - with_indexed_items: "{{ drLunNames }}" + lunNo: "{{ item.split('_')[4][2:] }}" + with_items: "{{ drLunNames }}" - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_pgs.yml" vars: @@ -485,12 +475,10 @@ drTestLunsWorkload: "{{ checkedLuns[drTestLgName] | json_query('[*].WORKLOADTYPEID') }}" - set_fact: - drTestLunNamesNew: "{{ drTestLunNamesNew + [ lunNameTemplate | format(drTestLunPrefixNew, suffix|int) ] }}" - drTestLunDescsNew: "{{ drTestLunDescsNew + [ drTestLunDesc1New + '|' + remark ] }}" + drTestLunNamesNew: "{{ drTestLunNamesNew + [ lunNameTemplate | format(drTestLunPrefixNew, lunNo|int, drTestLunSuffixNew) ] }}" vars: - suffix: "{{ item.1.split('_')[4][2:] }}" - remark: "{{ drTestLunDescs[item.0].split('|')[1] | default('') }}" - with_indexed_items: "{{ drTestLunNames }}" + lunNo: "{{ item.split('_')[4][2:] }}" + with_items: "{{ drTestLunNames }}" # End Precheck_4 when: Precheck_4_Execute @@ -1328,9 +1316,6 @@ name: old: "{{ drTestLunNames }}" new: "{{ drTestLunNamesNew }}" - desc: - old: "{{ drTestLunDescs }}" - new: "{{ drTestLunDescsNew }}" device: "{{ drDeviceName }}" - include_tasks: "{{GLOBAL.baseDir}}/task/volume/rename_volumes.yml" @@ -1338,21 +1323,6 @@ volumeNames: "{{ drTestLunNames }}" newVolumeNames: "{{ drTestLunNamesNew }}" - - set_fact: - deviceHost: "{{ drDeviceHost }}" - devicePort: "{{ drDevicePort }}" - deviceSn: "{{ drDeviceSn }}" - deviceToken: "{{ drDeviceToken }}" - deviceSession: "{{ drDeviceSession }}" - - - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/modify_lun.yml" - vars: - modifyLunId: "{{ drTestLunIds[i] }}" - desc: "{{ drTestLunDescsNew[i] }}" - loop: "{{ range(0, drTestLunIds|length) | list }}" - loop_control: - loop_var: i - - set_fact: Step_5_2_Completed: True @@ -1510,9 +1480,6 @@ name: old: "{{ drLunNames }}" new: "{{ drLunNamesNew }}" - desc: - old: "{{ drLunDescs }}" - new: "{{ drLunDescsNew }}" device: "{{ drDeviceName }}" - include_tasks: "{{GLOBAL.baseDir}}/task/volume/rename_volumes.yml" @@ -1520,21 +1487,6 @@ volumeNames: "{{ drLunNames }}" newVolumeNames: "{{ drLunNamesNew }}" - - set_fact: - deviceHost: "{{ drDeviceHost }}" - devicePort: "{{ drDevicePort }}" - deviceSn: "{{ drDeviceSn }}" - deviceToken: "{{ drDeviceToken }}" - deviceSession: "{{ drDeviceSession }}" - - - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/modify_lun.yml" - vars: - modifyLunId: "{{ drLunIds[i] }}" - desc: "{{ drLunDescsNew[i] }}" - loop: "{{ range(0, drLunIds|length) | list }}" - loop_control: - loop_var: i - - set_fact: Step_6_5_Completed: True @@ -1635,9 +1587,6 @@ name: old: "{{ metroLunNames }}" new: "{{ metroLunNamesNew }}" - desc: - old: "{{ metroLunDescs }}" - new: "{{ metroLunDescsNew }}" device: "{{ metroDeviceName }}" - include_tasks: "{{GLOBAL.baseDir}}/task/volume/rename_volumes.yml" @@ -1645,21 +1594,6 @@ volumeNames: "{{ metroLunNames }}" newVolumeNames: "{{ metroLunNamesNew }}" - - set_fact: - deviceHost: "{{ metroDeviceHost }}" - devicePort: "{{ metroDevicePort }}" - deviceSn: "{{ metroDeviceSn }}" - deviceToken: "{{ metroDeviceToken }}" - deviceSession: "{{ metroDeviceSession }}" - - - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/modify_lun.yml" - vars: - modifyLunId: "{{ metroLunIds[i] }}" - desc: "{{ metroLunDescsNew[i] }}" - loop: "{{ range(0, metroLunIds|length) | list }}" - loop_control: - loop_var: i - - set_fact: Step_7_4_Completed: True @@ -1732,9 +1666,6 @@ name: old: "{{ primaryLunNames }}" new: "{{ primaryLunNamesNew }}" - desc: - old: "{{ primaryLunDescs }}" - new: "{{ primaryLunDescsNew }}" device: "{{ primaryDeviceName }}" - include_tasks: "{{GLOBAL.baseDir}}/task/volume/rename_volumes.yml" @@ -1742,21 +1673,6 @@ volumeNames: "{{ primaryLunNames }}" newVolumeNames: "{{ primaryLunNamesNew }}" - - set_fact: - deviceHost: "{{ primaryDeviceHost }}" - devicePort: "{{ primaryDevicePort }}" - deviceSn: "{{ primaryDeviceSn }}" - deviceToken: "{{ primaryDeviceToken }}" - deviceSession: "{{ primaryDeviceSession }}" - - - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/modify_lun.yml" - vars: - modifyLunId: "{{ primaryLunIds[i] }}" - desc: "{{ primaryLunDescsNew[i] }}" - loop: "{{ range(0, primaryLunIds|length) | list }}" - loop_control: - loop_var: i - - set_fact: Step_8_3_Completed: True @@ -1940,9 +1856,6 @@ name: old: "{{ primaryLunNamesNew }}" new: "{{ primaryLunNames }}" - desc: - old: "{{ primaryLunDescsNew }}" - new: "{{ primaryLunDescs }}" device: "{{ primaryDeviceName }}" - include_tasks: "{{GLOBAL.baseDir}}/task/volume/rename_volumes.yml" @@ -1950,21 +1863,6 @@ volumeNames: "{{ primaryLunNamesNew }}" newVolumeNames: "{{ primaryLunNames }}" - - set_fact: - deviceHost: "{{ primaryDeviceHost }}" - devicePort: "{{ primaryDevicePort }}" - deviceSn: "{{ primaryDeviceSn }}" - deviceToken: "{{ primaryDeviceToken }}" - deviceSession: "{{ primaryDeviceSession }}" - - - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/modify_lun.yml" - vars: - modifyLunId: "{{ primaryLunIds[i] }}" - desc: "{{ primaryLunDescs[i] }}" - loop: "{{ range(0, primaryLunIds|length) | list }}" - loop_control: - loop_var: i - - set_fact: Step_8_3_Rollbacked: True @@ -2037,9 +1935,6 @@ name: old: "{{ metroLunNamesNew }}" new: "{{ metroLunNames }}" - desc: - old: "{{ metroLunDescsNew }}" - new: "{{ metroLunDescs }}" device: "{{ metroDeviceName }}" - include_tasks: "{{GLOBAL.baseDir}}/task/volume/rename_volumes.yml" @@ -2047,21 +1942,6 @@ volumeNames: "{{ metroLunNamesNew }}" newVolumeNames: "{{ metroLunNames }}" - - set_fact: - deviceHost: "{{ metroDeviceHost }}" - devicePort: "{{ metroDevicePort }}" - deviceSn: "{{ metroDeviceSn }}" - deviceToken: "{{ metroDeviceToken }}" - deviceSession: "{{ metroDeviceSession }}" - - - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/modify_lun.yml" - vars: - modifyLunId: "{{ metroLunIds[i] }}" - desc: "{{ metroLunDescs[i] }}" - loop: "{{ range(0, metroLunIds|length) | list }}" - loop_control: - loop_var: i - - set_fact: Step_7_4_Rollbacked: True @@ -2162,9 +2042,6 @@ name: old: "{{ drLunNamesNew }}" new: "{{ drLunNames }}" - desc: - old: "{{ drLunDescsNew }}" - new: "{{ drLunDescs }}" device: "{{ drDeviceName }}" - include_tasks: "{{GLOBAL.baseDir}}/task/volume/rename_volumes.yml" @@ -2172,21 +2049,6 @@ volumeNames: "{{ drLunNamesNew }}" newVolumeNames: "{{ drLunNames }}" - - set_fact: - deviceHost: "{{ drDeviceHost }}" - devicePort: "{{ drDevicePort }}" - deviceSn: "{{ drDeviceSn }}" - deviceToken: "{{ drDeviceToken }}" - deviceSession: "{{ drDeviceSession }}" - - - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/modify_lun.yml" - vars: - modifyLunId: "{{ drLunIds[i] }}" - desc: "{{ drLunDescs[i] }}" - loop: "{{ range(0, drLunIds|length) | list }}" - loop_control: - loop_var: i - - set_fact: Step_6_5_Rollbacked: True @@ -2344,9 +2206,6 @@ name: old: "{{ drTestLunNamesNew }}" new: "{{ drTestLunNames }}" - desc: - old: "{{ drTestLunDescsNew }}" - new: "{{ drTestLunDescs }}" device: "{{ drDeviceName }}" - include_tasks: "{{GLOBAL.baseDir}}/task/volume/rename_volumes.yml" @@ -2354,22 +2213,6 @@ volumeNames: "{{ drTestLunNamesNew }}" newVolumeNames: "{{ drTestLunNames }}" - - set_fact: - deviceHost: "{{ drDeviceHost }}" - devicePort: "{{ drDevicePort }}" - deviceSn: "{{ drDeviceSn }}" - deviceToken: "{{ drDeviceToken }}" - deviceSession: "{{ drDeviceSession }}" - - - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/modify_lun.yml" - vars: - modifyLunId: "{{ drTestLunIds[i] }}" - newLunName: "{{ drTestLunNames[i] }}" - desc: "{{ drTestLunDescs[i] }}" - loop: "{{ range(0, drTestLunIds|length) | list }}" - loop_control: - loop_var: i - - set_fact: Step_5_2_Rollbacked: True @@ -3073,11 +2916,6 @@ deviceToken: "{{ drDeviceToken }}" deviceSession: "{{ drDeviceSession }}" - - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/sync_replication_cg.yml" - vars: - cgName: "{{ drCgName }}" - waitSync: True - - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/create_snapshot_cg.yml" vars: pgName: "{{ drPgName }}" @@ -3478,9 +3316,6 @@ name: old: "{{ drTestLunNames }}" new: "{{ drTestLunNamesNew }}" - desc: - old: "{{ drTestLunDescs }}" - new: "{{ drTestLunDescsNew }}" device: "{{ drDeviceName }}" result: succeeded: "{{ Step_5_2_Completed }}" @@ -3574,9 +3409,6 @@ name: old: "{{ drLunNames }}" new: "{{ drLunNamesNew }}" - desc: - old: "{{ drLunDescs }}" - new: "{{ drLunDescsNew }}" device: "{{ drDeviceName }}" result: succeeded: "{{ Step_6_5_Completed }}" @@ -3639,9 +3471,6 @@ name: old: "{{ metroLunNames }}" new: "{{ metroLunNamesNew }}" - desc: - old: "{{ metroLunDescs }}" - new: "{{ metroLunDescsNew }}" device: "{{ metroDeviceName }}" result: succeeded: "{{ Step_7_4_Completed }}" @@ -3689,9 +3518,6 @@ name: old: "{{ primaryLunNames }}" new: "{{ primaryLunNamesNew }}" - desc: - old: "{{ primaryLunDescs }}" - new: "{{ primaryLunDescsNew }}" device: "{{ primaryDeviceName }}" result: succeeded: "{{ Step_8_3_Completed }}" diff --git a/rundeck/workflow/project001/41_add_replica_cluster.yml b/rundeck/workflow/project001/41_add_replica_cluster.yml index 9b6e3f6..b2f7ccf 100644 --- a/rundeck/workflow/project001/41_add_replica_cluster.yml +++ b/rundeck/workflow/project001/41_add_replica_cluster.yml @@ -129,12 +129,12 @@ - set_fact: lgSuffix: "{{ LUN_Group[-2:] }}" - lunNameTemplate: "%s%0{{DEFAULT.suffixDigits}}d" + lunNameTemplate: "%s%0{{DEFAULT.suffixDigits}}d_%s" primaryLgName: "{{ LUN_Group }}" primaryLgDescNew: "{{ metroEnable }}{{ protectLevel }}{{class1}}{{class2}}{{class3}}_{{ sessionName }}" primaryPgName: "{{ Protection_Group }}" primaryLunPrefixNew: "{{primaryClusterName}}_{{protectType}}{{'S' if metroEnable == 'Y' else 'N'}}" - primaryLunDesc1New: "{{ class1 }}_00_{{replicaType}}_{{'00' if replicaType == '00' else primaryRoom}}_{{'0000000000000000' if replicaType == '00' else sessionName}}_{{'0' if replicaType == '00' else protectType}}1" + primaryLunSuffixNew: "{{ class1 }}_00_{{replicaType}}_{{'00' if replicaType == '00' else primaryRoom}}_{{'0000000000000000' if replicaType == '00' else sessionName}}_{{'0' if replicaType == '00' else protectType}}1" - set_fact: metroDeviceSn: "{{ Metro_Storage|string }}" @@ -165,7 +165,7 @@ drLgDesc: "N{{ protectLevel }}{{ class1 }}{{class2}}{{class3}}_{{ sessionName }}" drPgName: "{{ drClusterName }}_PG{{ lgSuffix }}" drLunPrefix: "{{drClusterName}}_{{protectType}}N" - drLunDesc1: "{{ class2 }}_00_{{replicaType}}_{{primaryRoom}}_{{sessionName}}_{{protectType}}2" + drLunSuffix: "{{ class2 }}_00_{{replicaType}}_{{primaryRoom}}_{{sessionName}}_{{protectType}}2" when: protectLevel|int >= 2 - set_fact: @@ -177,7 +177,7 @@ - set_fact: drTestLgName: "{{ drTestClusterName }}_LG{{ lgSuffix }}" drTestLunPrefix: "{{drTestClusterName}}_{{protectType}}N" - drTestLunDesc1: "{{ class3 }}_00_00_{{primaryRoom}}_{{sessionName}}_{{protectType}}3" + drTestLunSuffix: "{{ class3 }}_00_00_{{primaryRoom}}_{{sessionName}}_{{protectType}}3" when: protectLevel|int == 3 - set_fact: @@ -240,15 +240,12 @@ primaryLunSectors: "{{ checkedLuns[primaryLgName] | json_query('[*].CAPACITY') }}" primaryLunDescs: "{{ checkedLuns[primaryLgName] | json_query('[*].DESCRIPTION') }}" primaryLunNamesNew: [] - primaryLunDescsNew: [] - set_fact: - primaryLunNamesNew: "{{ primaryLunNamesNew + [ lunNameTemplate | format(primaryLunPrefixNew, suffix|int) ] }}" - primaryLunDescsNew: "{{ primaryLunDescsNew + [ primaryLunDesc1New + '|' + remark ] }}" + primaryLunNamesNew: "{{ primaryLunNamesNew + [ lunNameTemplate | format(primaryLunPrefixNew, lunNo|int, primaryLunSuffixNew) ] }}" vars: - suffix: "{{ item.1.split('_')[4][2:] }}" - remark: "{{ primaryLunDescs[item.0].split('|')[1] | default('') }}" - with_indexed_items: "{{ primaryLunNames }}" + lunNo: "{{ item.split('_')[4][2:] }}" + with_items: "{{ primaryLunNames }}" - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_pgs.yml" vars: @@ -301,9 +298,9 @@ metroLunNamesNew: [] - set_fact: - metroLunNamesNew: "{{ metroLunNamesNew + [ lunNameTemplate | format(metroLunPrefixNew, suffix|int) ] }}" + metroLunNamesNew: "{{ metroLunNamesNew + [ lunNameTemplate | format(metroLunPrefixNew, lunNo|int, primaryLunSuffixNew) ] }}" vars: - suffix: "{{ item.split('_')[4][2:] }}" + lunNo: "{{ item.split('_')[4][2:] }}" with_items: "{{ primaryLunNames }}" - block: @@ -428,15 +425,12 @@ - set_fact: drLunNames: [] - drLunDescs: [] - set_fact: - drLunNames: "{{ drLunNames + [ lunNameTemplate | format(drLunPrefix, suffix|int) ] }}" - drLunDescs: "{{ drLunDescs + [ drLunDesc1 + '|' + remark ] }}" + drLunNames: "{{ drLunNames + [ lunNameTemplate | format(drLunPrefix, lunNo|int, drLunSuffix) ] }}" vars: - suffix: "{{ item.1.split('_')[4][2:] }}" - remark: "{{ primaryLunDescs[item.0].split('|')[1] | default('') }}" - with_indexed_items: "{{ primaryLunNames }}" + lunNo: "{{ item.split('_')[4][2:] }}" + with_items: "{{ primaryLunNames }}" - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_luns.yml" vars: @@ -474,15 +468,12 @@ - set_fact: drTestLunNames: [] - drTestLunDescs: [] - set_fact: - drTestLunNames: "{{ drTestLunNames + [ lunNameTemplate | format(drTestLunPrefix, suffix|int) ] }}" - drTestLunDescs: "{{ drTestLunDescs + [ drTestLunDesc1 + '|' + remark ] }}" + drTestLunNames: "{{ drTestLunNames + [ lunNameTemplate | format(drTestLunPrefix, lunNo|int, drTestLunSuffix) ] }}" vars: - suffix: "{{ item.1.split('_')[4][2:] }}" - remark: "{{ primaryLunDescs[item.0].split('|')[1] | default('') }}" - with_indexed_items: "{{ primaryLunNames }}" + lunNo: "{{ item.split('_')[4][2:] }}" + with_items: "{{ primaryLunNames }}" - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_luns.yml" vars: @@ -1125,7 +1116,7 @@ params: luns: lunNames: "{{ metroLunNamesNew }}" - lunDescs: "{{ primaryLunDescsNew }}" + lunDescs: "{{ primaryLunDescs }}" poolId: "{{ metroPoolId }}" workload: "{{ metroWorkload }}" device: "{{ metroDeviceName }}" @@ -1143,7 +1134,7 @@ lunSector: "{{ primaryLunSectors[i] }}" poolId: "{{ metroPoolId }}" workload: "{{ metroWorkload }}" - desc: "{{ primaryLunDescsNew[i] }}" + desc: "{{ primaryLunDescs[i] }}" loop: "{{ range(0, metroLunNamesNew|length) | list }}" loop_control: loop_var: i @@ -1265,7 +1256,7 @@ params: luns: lunNames: "{{ drLunNames }}" - lunDescs: "{{ drLunDescs }}" + lunDescs: "{{ primaryLunDescs }}" poolId: "{{ drPoolId }}" workload: "{{ drWorkload }}" device: "{{ drDeviceName }}" @@ -1283,7 +1274,7 @@ lunSector: "{{ primaryLunSectors[i] }}" poolId: "{{ drPoolId }}" workload: "{{ drWorkload }}" - desc: "{{ drLunDescs[i] }}" + desc: "{{ primaryLunDescs[i] }}" loop: "{{ range(0, drLunNames|length) | list }}" loop_control: loop_var: i @@ -1517,7 +1508,7 @@ cgName: "{{ drTestCgName }}" snapNames: "{{ drTestLunNames }}" activate: False - snapDescs: "{{ drTestLunDescs }}" + snapDescs: "{{ primaryLunDescs }}" device: "{{ drDeviceName }}" - set_fact: @@ -1527,18 +1518,13 @@ deviceToken: "{{ drDeviceToken }}" deviceSession: "{{ drDeviceSession }}" - - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/sync_replication_cg.yml" - vars: - cgName: "{{ drCgName }}" - waitSync: True - - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/create_snapshot_cg.yml" vars: pgName: "{{ drPgName }}" cgName: "{{ drTestCgName }}" snapNames: "{{ drTestLunNames }}" activate: False - snapDescs: "{{ drTestLunDescs }}" + snapDescs: "{{ primaryLunDescs }}" - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_luns.yml" vars: @@ -1653,9 +1639,6 @@ name: old: "{{ primaryLunNames }}" new: "{{ primaryLunNamesNew }}" - desc: - old: "{{ primaryLunDescs }}" - new: "{{ primaryLunDescsNew }}" device: "{{ primaryDeviceName }}" - include_tasks: "{{GLOBAL.baseDir}}/task/volume/rename_volumes.yml" @@ -1663,21 +1646,6 @@ volumeNames: "{{ primaryLunNames }}" newVolumeNames: "{{ primaryLunNamesNew }}" - - set_fact: - deviceHost: "{{ primaryDeviceHost }}" - devicePort: "{{ primaryDevicePort }}" - deviceSn: "{{ primaryDeviceSn }}" - deviceToken: "{{ primaryDeviceToken }}" - deviceSession: "{{ primaryDeviceSession }}" - - - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/modify_lun.yml" - vars: - modifyLunId: "{{ primaryLunIds[i] }}" - desc: "{{ primaryLunDescsNew[i] }}" - loop: "{{ range(0, primaryLunIds|length) | list }}" - loop_control: - loop_var: i - - set_fact: Step_7_3_Completed: True @@ -1778,9 +1746,6 @@ name: old: "{{ metroLunNames }}" new: "{{ metroLunNamesNew }}" - desc: - old: "{{ primaryLunDescs }}" - new: "{{ primaryLunDescsNew }}" device: "{{ metroDeviceName }}" - include_tasks: "{{GLOBAL.baseDir}}/task/volume/rename_volumes.yml" @@ -1788,21 +1753,6 @@ volumeNames: "{{ metroLunNames }}" newVolumeNames: "{{ metroLunNamesNew }}" - - set_fact: - deviceHost: "{{ metroDeviceHost }}" - devicePort: "{{ metroDevicePort }}" - deviceSn: "{{ metroDeviceSn }}" - deviceToken: "{{ metroDeviceToken }}" - deviceSession: "{{ metroDeviceSession }}" - - - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/modify_lun.yml" - vars: - modifyLunId: "{{ metroLunIds[i] }}" - desc: "{{ primaryLunDescsNew[i] }}" - loop: "{{ range(0, metroLunIds|length) | list }}" - loop_control: - loop_var: i - - set_fact: Step_8_4_Completed: True @@ -2066,9 +2016,6 @@ name: old: "{{ metroLunNamesNew }}" new: "{{ metroLunNames }}" - desc: - old: "{{ primaryLunDescsNew }}" - new: "{{ primaryLunDescs }}" device: "{{ metroDeviceName }}" - include_tasks: "{{GLOBAL.baseDir}}/task/volume/rename_volumes.yml" @@ -2076,21 +2023,6 @@ volumeNames: "{{ metroLunNamesNew }}" newVolumeNames: "{{ metroLunNames }}" - - set_fact: - deviceHost: "{{ metroDeviceHost }}" - devicePort: "{{ metroDevicePort }}" - deviceSn: "{{ metroDeviceSn }}" - deviceToken: "{{ metroDeviceToken }}" - deviceSession: "{{ metroDeviceSession }}" - - - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/modify_lun.yml" - vars: - modifyLunId: "{{ metroLunIds[i] }}" - desc: "{{ primaryLunDescs[i] }}" - loop: "{{ range(0, metroLunIds|length) | list }}" - loop_control: - loop_var: i - - set_fact: Step_8_4_Rollbacked: True @@ -2191,9 +2123,6 @@ name: old: "{{ primaryLunNamesNew }}" new: "{{ primaryLunNames }}" - desc: - old: "{{ primaryLunDescsNew }}" - new: "{{ primaryLunDescs }}" device: "{{ primaryDeviceName }}" - include_tasks: "{{GLOBAL.baseDir}}/task/volume/rename_volumes.yml" @@ -2201,21 +2130,6 @@ volumeNames: "{{ primaryLunNamesNew }}" newVolumeNames: "{{ primaryLunNames }}" - - set_fact: - deviceHost: "{{ primaryDeviceHost }}" - devicePort: "{{ primaryDevicePort }}" - deviceSn: "{{ primaryDeviceSn }}" - deviceToken: "{{ primaryDeviceToken }}" - deviceSession: "{{ primaryDeviceSession }}" - - - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/modify_lun.yml" - vars: - modifyLunId: "{{ primaryLunIds[i] }}" - desc: "{{ primaryLunDescs[i] }}" - loop: "{{ range(0, primaryLunIds|length) | list }}" - loop_control: - loop_var: i - - set_fact: Step_7_3_Rollbacked: True @@ -3110,7 +3024,7 @@ params: luns: lunNames: "{{ metroLunNamesNew }}" - lunDescs: "{{ primaryLunDescsNew }}" + lunDescs: "{{ primaryLunDescs }}" poolId: "{{ metroPoolId }}" workload: "{{ metroWorkload }}" device: "{{ metroDeviceName }}" @@ -3170,7 +3084,7 @@ params: luns: lunNames: "{{ drLunNames }}" - lunDescs: "{{ drLunDescs }}" + lunDescs: "{{ primaryLunDescs }}" poolId: "{{ drPoolId }}" workload: "{{ drWorkload }}" device: "{{ drDeviceName }}" @@ -3284,7 +3198,7 @@ cgName: "{{ drTestCgName }}" snapNames: "{{ drTestLunNames }}" activate: False - snapDescs: "{{ drTestLunDescs }}" + snapDescs: "{{ primaryLunDescs }}" device: "{{ drDeviceName }}" result: succeeded: "{{ Step_6_1_Completed }}" @@ -3346,9 +3260,6 @@ name: old: "{{ primaryLunNames }}" new: "{{ primaryLunNamesNew }}" - desc: - old: "{{ primaryLunDescs }}" - new: "{{ primaryLunDescsNew }}" device: "{{ primaryDeviceName }}" result: succeeded: "{{ Step_7_3_Completed }}" @@ -3411,9 +3322,6 @@ name: old: "{{ metroLunNames }}" new: "{{ metroLunNamesNew }}" - desc: - old: "{{ primaryLunDescs }}" - new: "{{ primaryLunDescsNew }}" device: "{{ metroDeviceName }}" result: succeeded: "{{ Step_8_4_Completed }}" diff --git a/rundeck/workflow/project001/42_add_drtest_cluster.yml b/rundeck/workflow/project001/42_add_drtest_cluster.yml index a37cc4f..b675a5d 100644 --- a/rundeck/workflow/project001/42_add_drtest_cluster.yml +++ b/rundeck/workflow/project001/42_add_drtest_cluster.yml @@ -114,7 +114,7 @@ class1: "{{ Class_1 }}" class2: "{{ Class_2 if (protectLevel|int >= 2) else '0' }}" class3: "{{ Class_3 if (protectLevel|int == 3) else '0' }}" - lunNameTemplate: "%s%0{{DEFAULT.suffixDigits}}d" + lunNameTemplate: "%s%0{{DEFAULT.suffixDigits}}d_%s" - set_fact: drTestClusterName: "{{ drClusterName[0:-1] }}3" @@ -128,27 +128,23 @@ primaryLunNames: [] primaryLunNamesNew: [] primaryLunPrefixNew: "{{primaryClusterName}}_{{protectType}}{{'S' if metroEnable == 'Y' else 'N'}}" - primaryLunDescsNew: [] - primaryLunDesc1New: "{{ class1 }}_00_{{replicaType}}_{{'00' if replicaType == '00' else primaryRoom}}_{{'0000000000000000' if replicaType == '00' else sessionName}}_{{'0' if replicaType == '00' else protectType}}1" + primaryLunSuffixNew: "{{ class1 }}_00_{{replicaType}}_{{'00' if replicaType == '00' else primaryRoom}}_{{'0000000000000000' if replicaType == '00' else sessionName}}_{{'0' if replicaType == '00' else protectType}}1" metroCgNameNew: "{{ replicaType }}_{{ primaryRoom }}_{{ sessionName }}_{{ protectType }}1" metroLunIds: [] metroLunNames: [] metroLunNamesNew: [] metroLunPrefixNew: "{{primaryClusterName}}_{{protectType}}M" - metroLunDescsNew: [] - metroLunDesc1New: "{{ class1 }}_00_{{replicaType}}_{{'00' if replicaType == '00' else primaryRoom}}_{{'0000000000000000' if replicaType == '00' else sessionName}}_{{'0' if replicaType == '00' else protectType}}1" + metroLunSuffixNew: "{{ class1 }}_00_{{replicaType}}_{{'00' if replicaType == '00' else primaryRoom}}_{{'0000000000000000' if replicaType == '00' else sessionName}}_{{'0' if replicaType == '00' else protectType}}1" drCgNameNew: "{{ replicaType }}_{{ primaryRoom }}_{{ sessionName }}_{{ protectType }}2" drLgDescNew: "N{{ protectLevel }}{{ class1 }}{{class2}}{{class3}}_{{ sessionName }}" drLunIds: [] drLunNames: [] drLunNamesNew: [] drLunPrefixNew: "{{drClusterName}}_{{protectType}}N" - drLunDescsNew: [] - drLunDesc1New: "{{ class2 }}_00_{{replicaType}}_{{primaryRoom}}_{{sessionName}}_{{protectType}}2" + drLunSuffixNew: "{{ class2 }}_00_{{replicaType}}_{{primaryRoom}}_{{sessionName}}_{{protectType}}2" drTestLunNames: [] drTestLunPrefix: "{{drTestClusterName}}_{{protectType}}N" - drTestLunDescs: [] - drTestLunDesc1: "{{ class3 }}_00_00_{{primaryRoom}}_{{sessionName}}_{{protectType}}3" + drTestLunSuffix: "{{ class3 }}_00_00_{{primaryRoom}}_{{sessionName}}_{{protectType}}3" drStarCgNameNew: "{{ replicaType }}_{{ primaryRoom }}_{{ sessionName }}_{{ protectType }}0" standbyCgNameNew: "{{ replicaType }}_{{ primaryRoom }}_{{ sessionName }}_{{ protectType }}4" @@ -193,15 +189,12 @@ primaryLgDesc: "{{ checkedLgs[0].DESCRIPTION }}" primaryLunNames: "{{ checkedLuns[primaryLgName] | json_query('[*].NAME') }}" primaryLunIds: "{{ checkedLuns[primaryLgName] | json_query('[*].ID') }}" - primaryLunDescs: "{{ checkedLuns[primaryLgName] | json_query('[*].DESCRIPTION') }}" - set_fact: - primaryLunNamesNew: "{{ primaryLunNamesNew + [ lunNameTemplate | format(primaryLunPrefixNew, suffix|int) ] }}" - primaryLunDescsNew: "{{ primaryLunDescsNew + [ primaryLunDesc1New + '|' + remark ] }}" + primaryLunNamesNew: "{{ primaryLunNamesNew + [ lunNameTemplate | format(primaryLunPrefixNew, lunNo|int, primaryLunSuffixNew) ] }}" vars: - suffix: "{{ item.1.split('_')[4][2:] }}" - remark: "{{ primaryLunDescs[item.0].split('|')[1] | default('') }}" - with_indexed_items: "{{ primaryLunNames }}" + lunNo: "{{ item.split('_')[4][2:] }}" + with_items: "{{ primaryLunNames }}" - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_pgs.yml" vars: @@ -248,15 +241,12 @@ metroLgDesc: "{{ checkedLgs[0].DESCRIPTION }}" metroLunNames: "{{ checkedLuns[primaryLgName] | json_query('[*].NAME') }}" metroLunIds: "{{ checkedLuns[primaryLgName] | json_query('[*].ID') }}" - metroLunDescs: "{{ checkedLuns[primaryLgName] | json_query('[*].DESCRIPTION') }}" - set_fact: - metroLunNamesNew: "{{ metroLunNamesNew + [ lunNameTemplate | format(metroLunPrefixNew, suffix|int) ] }}" - metroLunDescsNew: "{{ metroLunDescsNew + [ metroLunDesc1New + '|' + remark ] }}" + metroLunNamesNew: "{{ metroLunNamesNew + [ lunNameTemplate | format(metroLunPrefixNew, lunNo|int, metroLunSuffixNew) ] }}" vars: - suffix: "{{ item.1.split('_')[4][2:] }}" - remark: "{{ metroLunDescs[item.0].split('|')[1] | default('') }}" - with_indexed_items: "{{ metroLunNames }}" + lunNo: "{{ item.split('_')[4][2:] }}" + with_items: "{{ metroLunNames }}" # End Precheck_2 when: Precheck_2_Execute @@ -309,12 +299,10 @@ drLunSectors: "{{ checkedLuns[drLgName] | json_query('[*].CAPACITY') }}" - set_fact: - drLunNamesNew: "{{ drLunNamesNew + [ lunNameTemplate | format(drLunPrefixNew, suffix|int) ] }}" - drLunDescsNew: "{{ drLunDescsNew + [ drLunDesc1New + '|' + remark ] }}" + drLunNamesNew: "{{ drLunNamesNew + [ lunNameTemplate | format(drLunPrefixNew, lunNo|int, drLunSuffixNew) ] }}" vars: - suffix: "{{ item.1.split('_')[4][2:] }}" - remark: "{{ drLunDescs[item.0].split('|')[1] | default('') }}" - with_indexed_items: "{{ drLunNames }}" + lunNo: "{{ item.split('_')[4][2:] }}" + with_items: "{{ drLunNames }}" # End Precheck_3 when: Precheck_3_Execute @@ -338,12 +326,10 @@ checkExist: False - set_fact: - drTestLunNames: "{{ drTestLunNames + [ lunNameTemplate | format(drTestLunPrefix, suffix|int) ] }}" - drTestLunDescs: "{{ drTestLunDescs + [ drTestLunDesc1 + '|' + remark ] }}" + drTestLunNames: "{{ drTestLunNames + [ lunNameTemplate | format(drTestLunPrefix, lunNo|int, drTestLunSuffix) ] }}" vars: - suffix: "{{ item.1.split('_')[4][2:] }}" - remark: "{{ drLunDescs[item.0].split('|')[1] | default('') }}" - with_indexed_items: "{{ drLunNames }}" + lunNo: "{{ item.split('_')[4][2:] }}" + with_items: "{{ drLunNames }}" # End Precheck_4 when: Precheck_4_Execute @@ -559,7 +545,7 @@ cgName: "{{ drTestCgName }}" snapNames: "{{ drTestLunNames }}" activate: False - snapDescs: "{{ drTestLunDescs }}" + snapDescs: "{{ drLunDescs }}" device: "{{ drDeviceName }}" - set_fact: @@ -569,18 +555,13 @@ deviceToken: "{{ drDeviceToken }}" deviceSession: "{{ drDeviceSession }}" - - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/sync_replication_cg.yml" - vars: - cgName: "{{ drCgName }}" - waitSync: True - - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/create_snapshot_cg.yml" vars: pgName: "{{ drPgName }}" cgName: "{{ drTestCgName }}" snapNames: "{{ drTestLunNames }}" activate: False - snapDescs: "{{ drTestLunDescs }}" + snapDescs: "{{ drLunDescs }}" - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_luns.yml" vars: @@ -751,9 +732,6 @@ name: old: "{{ drLunNames }}" new: "{{ drLunNamesNew }}" - desc: - old: "{{ drLunDescs }}" - new: "{{ drLunDescsNew }}" device: "{{ drDeviceName }}" - include_tasks: "{{GLOBAL.baseDir}}/task/volume/rename_volumes.yml" @@ -761,21 +739,6 @@ volumeNames: "{{ drLunNames }}" newVolumeNames: "{{ drLunNamesNew }}" - - set_fact: - deviceHost: "{{ drDeviceHost }}" - devicePort: "{{ drDevicePort }}" - deviceSn: "{{ drDeviceSn }}" - deviceToken: "{{ drDeviceToken }}" - deviceSession: "{{ drDeviceSession }}" - - - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/modify_lun.yml" - vars: - modifyLunId: "{{ drLunIds[i] }}" - desc: "{{ drLunDescsNew[i] }}" - loop: "{{ range(0, drLunIds|length) | list }}" - loop_control: - loop_var: i - - set_fact: Step_3_5_Completed: True @@ -876,9 +839,6 @@ name: old: "{{ metroLunNames }}" new: "{{ metroLunNamesNew }}" - desc: - old: "{{ metroLunDescs }}" - new: "{{ metroLunDescsNew }}" device: "{{ metroDeviceName }}" - include_tasks: "{{GLOBAL.baseDir}}/task/volume/rename_volumes.yml" @@ -886,21 +846,6 @@ volumeNames: "{{ metroLunNames }}" newVolumeNames: "{{ metroLunNamesNew }}" - - set_fact: - deviceHost: "{{ metroDeviceHost }}" - devicePort: "{{ metroDevicePort }}" - deviceSn: "{{ metroDeviceSn }}" - deviceToken: "{{ metroDeviceToken }}" - deviceSession: "{{ metroDeviceSession }}" - - - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/modify_lun.yml" - vars: - modifyLunId: "{{ metroLunIds[i] }}" - desc: "{{ metroLunDescsNew[i] }}" - loop: "{{ range(0, metroLunIds|length) | list }}" - loop_control: - loop_var: i - - set_fact: Step_4_4_Completed: True @@ -973,9 +918,6 @@ name: old: "{{ primaryLunNames }}" new: "{{ primaryLunNamesNew }}" - desc: - old: "{{ primaryLunDescs }}" - new: "{{ primaryLunDescsNew }}" device: "{{ primaryDeviceName }}" - include_tasks: "{{GLOBAL.baseDir}}/task/volume/rename_volumes.yml" @@ -983,21 +925,6 @@ volumeNames: "{{ primaryLunNames }}" newVolumeNames: "{{ primaryLunNamesNew }}" - - set_fact: - deviceHost: "{{ primaryDeviceHost }}" - devicePort: "{{ primaryDevicePort }}" - deviceSn: "{{ primaryDeviceSn }}" - deviceToken: "{{ primaryDeviceToken }}" - deviceSession: "{{ primaryDeviceSession }}" - - - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/modify_lun.yml" - vars: - modifyLunId: "{{ primaryLunIds[i] }}" - desc: "{{ primaryLunDescsNew[i] }}" - loop: "{{ range(0, primaryLunIds|length) | list }}" - loop_control: - loop_var: i - - set_fact: Step_5_3_Completed: True @@ -1071,9 +998,6 @@ name: old: "{{ primaryLunNamesNew }}" new: "{{ primaryLunNames }}" - desc: - old: "{{ primaryLunDescsNew }}" - new: "{{ primaryLunDescs }}" device: "{{ primaryDeviceName }}" - include_tasks: "{{GLOBAL.baseDir}}/task/volume/rename_volumes.yml" @@ -1081,21 +1005,6 @@ volumeNames: "{{ primaryLunNamesNew }}" newVolumeNames: "{{ primaryLunNames }}" - - set_fact: - deviceHost: "{{ primaryDeviceHost }}" - devicePort: "{{ primaryDevicePort }}" - deviceSn: "{{ primaryDeviceSn }}" - deviceToken: "{{ primaryDeviceToken }}" - deviceSession: "{{ primaryDeviceSession }}" - - - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/modify_lun.yml" - vars: - modifyLunId: "{{ primaryLunIds[i] }}" - desc: "{{ primaryLunDescs[i] }}" - loop: "{{ range(0, primaryLunIds|length) | list }}" - loop_control: - loop_var: i - - set_fact: Step_5_3_Rollbacked: True @@ -1168,9 +1077,6 @@ name: old: "{{ metroLunNamesNew }}" new: "{{ metroLunNames }}" - desc: - old: "{{ metroLunDescsNew }}" - new: "{{ metroLunDescs }}" device: "{{ metroDeviceName }}" - include_tasks: "{{GLOBAL.baseDir}}/task/volume/rename_volumes.yml" @@ -1178,21 +1084,6 @@ volumeNames: "{{ metroLunNamesNew }}" newVolumeNames: "{{ metroLunNames }}" - - set_fact: - deviceHost: "{{ metroDeviceHost }}" - devicePort: "{{ metroDevicePort }}" - deviceSn: "{{ metroDeviceSn }}" - deviceToken: "{{ metroDeviceToken }}" - deviceSession: "{{ metroDeviceSession }}" - - - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/modify_lun.yml" - vars: - modifyLunId: "{{ metroLunIds[i] }}" - desc: "{{ metroLunDescs[i] }}" - loop: "{{ range(0, metroLunIds|length) | list }}" - loop_control: - loop_var: i - - set_fact: Step_4_4_Rollbacked: True @@ -1293,9 +1184,6 @@ name: old: "{{ drLunNamesNew }}" new: "{{ drLunNames }}" - desc: - old: "{{ drLunDescsNew }}" - new: "{{ drLunDescs }}" device: "{{ drDeviceName }}" - include_tasks: "{{GLOBAL.baseDir}}/task/volume/rename_volumes.yml" @@ -1303,21 +1191,6 @@ volumeNames: "{{ drLunNamesNew }}" newVolumeNames: "{{ drLunNames }}" - - set_fact: - deviceHost: "{{ drDeviceHost }}" - devicePort: "{{ drDevicePort }}" - deviceSn: "{{ drDeviceSn }}" - deviceToken: "{{ drDeviceToken }}" - deviceSession: "{{ drDeviceSession }}" - - - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/modify_lun.yml" - vars: - modifyLunId: "{{ drLunIds[i] }}" - desc: "{{ drLunDescs[i] }}" - loop: "{{ range(0, drLunIds|length) | list }}" - loop_control: - loop_var: i - - set_fact: Step_3_5_Rollbacked: True @@ -1639,7 +1512,7 @@ cgName: "{{ drTestCgName }}" snapNames: "{{ drTestLunNames }}" activate: False - snapDescs: "{{ drTestLunDescs }}" + snapDescs: "{{ drLunDescs }}" device: "{{ drDeviceName }}" result: succeeded: "{{ Step_2_1_Completed }}" @@ -1731,9 +1604,6 @@ name: old: "{{ drLunNames }}" new: "{{ drLunNamesNew }}" - desc: - old: "{{ drLunDescs }}" - new: "{{ drLunDescsNew }}" device: "{{ drDeviceName }}" result: succeeded: "{{ Step_3_5_Completed }}" @@ -1796,9 +1666,6 @@ name: old: "{{ metroLunNames }}" new: "{{ metroLunNamesNew }}" - desc: - old: "{{ metroLunDescs }}" - new: "{{ metroLunDescsNew }}" device: "{{ metroDeviceName }}" result: succeeded: "{{ Step_4_4_Completed }}" @@ -1846,9 +1713,6 @@ name: old: "{{ primaryLunNames }}" new: "{{ primaryLunNamesNew }}" - desc: - old: "{{ primaryLunDescs }}" - new: "{{ primaryLunDescsNew }}" device: "{{ primaryDeviceName }}" result: succeeded: "{{ Step_5_3_Completed }}" diff --git a/rundeck/workflow/project001/43_add_metro_cluster.yml b/rundeck/workflow/project001/43_add_metro_cluster.yml index 8f901ce..d4c4ebe 100644 --- a/rundeck/workflow/project001/43_add_metro_cluster.yml +++ b/rundeck/workflow/project001/43_add_metro_cluster.yml @@ -94,7 +94,7 @@ class1: "{{ Class_1 }}" class2: "{{ Class_2 if (protectLevel|int >= 2) else '0' }}" class3: "{{ Class_3 if (protectLevel|int == 3) else '0' }}" - lunNameTemplate: "%s%0{{DEFAULT.suffixDigits}}d" + lunNameTemplate: "%s%0{{DEFAULT.suffixDigits}}d_%s" - set_fact: metroHosts: "{{ Metro_Hosts.split(',') }}" @@ -132,27 +132,23 @@ primaryLunNames: [] primaryLunNamesNew: [] primaryLunPrefixNew: "{{primaryClusterName}}_{{protectType}}{{'S' if metroEnable == 'Y' else 'N'}}" - primaryLunDescsNew: [] - primaryLunDesc1New: "{{ class1 }}_00_{{replicaType}}_{{'00' if replicaType == '00' else primaryRoom}}_{{'0000000000000000' if replicaType == '00' else sessionName}}_{{'0' if replicaType == '00' else protectType}}1" + primaryLunSuffixNew: "{{ class1 }}_00_{{replicaType}}_{{'00' if replicaType == '00' else primaryRoom}}_{{'0000000000000000' if replicaType == '00' else sessionName}}_{{'0' if replicaType == '00' else protectType}}1" metroLunNames: [] metroLunPrefix: "{{primaryClusterName}}_{{protectType}}M" - metroLunDescs: [] - metroLunDesc1: "{{ class1 }}_00_{{replicaType}}_{{'00' if replicaType == '00' else primaryRoom}}_{{'0000000000000000' if replicaType == '00' else sessionName}}_{{'0' if replicaType == '00' else protectType}}1" + metroLunSuffix: "{{ class1 }}_00_{{replicaType}}_{{'00' if replicaType == '00' else primaryRoom}}_{{'0000000000000000' if replicaType == '00' else sessionName}}_{{'0' if replicaType == '00' else protectType}}1" drCgNameNew: "{{ replicaType }}_{{ primaryRoom }}_{{ sessionName }}_{{ protectType }}2" drLgDescNew: "N{{ protectLevel }}{{ class1 }}{{class2}}{{class3}}_{{ sessionName }}" drLunIds: [] drLunNames: [] drLunNamesNew: [] drLunPrefixNew: "{{DR_Cluster}}_{{protectType}}N" - drLunDescsNew: [] - drLunDesc1New: "{{ class2 }}_00_{{replicaType}}_{{primaryRoom}}_{{sessionName}}_{{protectType}}2" + drLunSuffixNew: "{{ class2 }}_00_{{replicaType}}_{{primaryRoom}}_{{sessionName}}_{{protectType}}2" drTestCgNameNew: "{{ replicaType }}_{{ primaryRoom }}_{{ sessionName }}_{{ protectType }}3" drTestLunIds: [] drTestLunNames: [] drTestLunNamesNew: [] drTestLunPrefixNew: "{{DR_Test_Cluster}}_{{protectType}}N" - drTestLunDescsNew: [] - drTestLunDesc1New: "{{ class3 }}_00_00_{{primaryRoom}}_{{sessionName}}_{{protectType}}3" + drTestLunSuffixNew: "{{ class3 }}_00_00_{{primaryRoom}}_{{sessionName}}_{{protectType}}3" - set_fact: Precheck_1_Execute: True @@ -209,12 +205,10 @@ primaryLunDescs: "{{ checkedLuns[primaryLgName] | json_query('[*].DESCRIPTION') }}" - set_fact: - primaryLunNamesNew: "{{ primaryLunNamesNew + [ lunNameTemplate | format(primaryLunPrefixNew, suffix|int) ] }}" - primaryLunDescsNew: "{{ primaryLunDescsNew + [ primaryLunDesc1New + '|' + remark ] }}" + primaryLunNamesNew: "{{ primaryLunNamesNew + [ lunNameTemplate | format(primaryLunPrefixNew, lunNo|int, primaryLunSuffixNew) ] }}" vars: - suffix: "{{ item.1.split('_')[4][2:] }}" - remark: "{{ primaryLunDescs[item.0].split('|')[1] | default('') }}" - with_indexed_items: "{{ primaryLunNames }}" + lunNo: "{{ item.split('_')[4][2:] }}" + with_items: "{{ primaryLunNames }}" - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_pgs.yml" vars: @@ -255,9 +249,9 @@ metroDeviceSession: "{{ deviceSession }}" - set_fact: - metroLunNames: "{{ metroLunNames + [ lunNameTemplate | format(metroLunPrefix, suffix|int) ] }}" + metroLunNames: "{{ metroLunNames + [ lunNameTemplate | format(metroLunPrefix, lunNo|int, metroLunSuffix) ] }}" vars: - suffix: "{{ item.split('_')[4][2:] }}" + lunNo: "{{ item.split('_')[4][2:] }}" with_items: "{{ primaryLunNames }}" - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_hostgroups.yml" @@ -327,15 +321,12 @@ drLgDesc: "{{ checkedLgs[0].DESCRIPTION }}" drLunIds: "{{ checkedLuns[drLgName] | json_query('[*].ID') }}" drLunNames: "{{ checkedLuns[drLgName] | json_query('[*].NAME') }}" - drLunDescs: "{{ checkedLuns[drLgName] | json_query('[*].DESCRIPTION') }}" - set_fact: - drLunNamesNew: "{{ drLunNamesNew + [ lunNameTemplate | format(drLunPrefixNew, suffix|int) ] }}" - drLunDescsNew: "{{ drLunDescsNew + [ drLunDesc1New + '|' + remark ] }}" + drLunNamesNew: "{{ drLunNamesNew + [ lunNameTemplate | format(drLunPrefixNew, lunNo|int, drLunSuffixNew) ] }}" vars: - suffix: "{{ item.1.split('_')[4][2:] }}" - remark: "{{ drLunDescs[item.0].split('|')[1] | default('') }}" - with_indexed_items: "{{ drLunNames }}" + lunNo: "{{ item.split('_')[4][2:] }}" + with_items: "{{ drLunNames }}" - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_pgs.yml" vars: @@ -368,15 +359,12 @@ drTestLgDesc: "{{ checkedLgs[0].DESCRIPTION }}" drTestLunNames: "{{ checkedLuns[drTestLgName] | json_query('[*].NAME') }}" drTestLunIds: "{{ checkedLuns[drTestLgName] | json_query('[*].ID') }}" - drTestLunDescs: "{{ checkedLuns[drTestLgName] | json_query('[*].DESCRIPTION') }}" - set_fact: - drTestLunNamesNew: "{{ drTestLunNamesNew + [ lunNameTemplate | format(drTestLunPrefixNew, suffix|int) ] }}" - drTestLunDescsNew: "{{ drTestLunDescsNew + [ drTestLunDesc1New + '|' + remark ] }}" + drTestLunNamesNew: "{{ drTestLunNamesNew + [ lunNameTemplate | format(drTestLunPrefixNew, lunNo|int, drTestLunSuffixNew) ] }}" vars: - suffix: "{{ item.1.split('_')[4][2:] }}" - remark: "{{ drTestLunDescs[item.0].split('|')[1] | default('') }}" - with_indexed_items: "{{ drTestLunNames }}" + lunNo: "{{ item.split('_')[4][2:] }}" + with_items: "{{ drTestLunNames }}" # End Precheck_4 when: Precheck_4_Execute @@ -701,7 +689,7 @@ params: luns: lunNames: "{{ metroLunNames }}" - lunDescs: "{{ primaryLunDescsNew }}" + lunDescs: "{{ primaryLunDescs }}" poolId: "{{ metroPoolId }}" workload: "{{ metroWorkload }}" device: "{{ metroDeviceName }}" @@ -719,7 +707,7 @@ lunSector: "{{ primaryLunSectors[i] }}" poolId: "{{ metroPoolId }}" workload: "{{ metroWorkload }}" - desc: "{{ primaryLunDescsNew[i] }}" + desc: "{{ primaryLunDescs[i] }}" loop: "{{ range(0, metroLunNames|length) | list }}" loop_control: loop_var: i @@ -1059,9 +1047,6 @@ name: old: "{{ primaryLunNames }}" new: "{{ primaryLunNamesNew }}" - desc: - old: "{{ primaryLunDescs }}" - new: "{{ primaryLunDescsNew }}" device: "{{ primaryDeviceName }}" - include_tasks: "{{GLOBAL.baseDir}}/task/volume/rename_volumes.yml" @@ -1069,21 +1054,6 @@ volumeNames: "{{ primaryLunNames }}" newVolumeNames: "{{ primaryLunNamesNew }}" - - set_fact: - deviceHost: "{{ primaryDeviceHost }}" - devicePort: "{{ primaryDevicePort }}" - deviceSn: "{{ primaryDeviceSn }}" - deviceToken: "{{ primaryDeviceToken }}" - deviceSession: "{{ primaryDeviceSession }}" - - - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/modify_lun.yml" - vars: - modifyLunId: "{{ primaryLunIds[i] }}" - desc: "{{ primaryLunDescsNew[i] }}" - loop: "{{ range(0, primaryLunIds|length) | list }}" - loop_control: - loop_var: i - - set_fact: Step_4_3_Completed: True @@ -1184,9 +1154,6 @@ name: old: "{{ drLunNames }}" new: "{{ drLunNamesNew }}" - desc: - old: "{{ drLunDescs }}" - new: "{{ drLunDescsNew }}" device: "{{ drDeviceName }}" - include_tasks: "{{GLOBAL.baseDir}}/task/volume/rename_volumes.yml" @@ -1194,21 +1161,6 @@ volumeNames: "{{ drLunNames }}" newVolumeNames: "{{ drLunNamesNew }}" - - set_fact: - deviceHost: "{{ drDeviceHost }}" - devicePort: "{{ drDevicePort }}" - deviceSn: "{{ drDeviceSn }}" - deviceToken: "{{ drDeviceToken }}" - deviceSession: "{{ drDeviceSession }}" - - - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/modify_lun.yml" - vars: - modifyLunId: "{{ drLunIds[i] }}" - desc: "{{ drLunDescsNew[i] }}" - loop: "{{ range(0, drLunIds|length) | list }}" - loop_control: - loop_var: i - - set_fact: Step_5_4_Completed: True @@ -1253,9 +1205,6 @@ name: old: "{{ drTestLunNames }}" new: "{{ drTestLunNamesNew }}" - desc: - old: "{{ drTestLunDescs }}" - new: "{{ drTestLunDescsNew }}" device: "{{ drDeviceName }}" - include_tasks: "{{GLOBAL.baseDir}}/task/volume/rename_volumes.yml" @@ -1263,21 +1212,6 @@ volumeNames: "{{ drTestLunNames }}" newVolumeNames: "{{ drTestLunNamesNew }}" - - set_fact: - deviceHost: "{{ drDeviceHost }}" - devicePort: "{{ drDevicePort }}" - deviceSn: "{{ drDeviceSn }}" - deviceToken: "{{ drDeviceToken }}" - deviceSession: "{{ drDeviceSession }}" - - - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/modify_lun.yml" - vars: - modifyLunId: "{{ drTestLunIds[i] }}" - desc: "{{ drTestLunDescsNew[i] }}" - loop: "{{ range(0, drTestLunIds|length) | list }}" - loop_control: - loop_var: i - - set_fact: Step_6_2_Completed: True @@ -1456,9 +1390,6 @@ name: old: "{{ drTestLunNamesNew }}" new: "{{ drTestLunNames }}" - desc: - old: "{{ drTestLunDescsNew }}" - new: "{{ drTestLunDescs }}" device: "{{ drDeviceName }}" - include_tasks: "{{GLOBAL.baseDir}}/task/volume/rename_volumes.yml" @@ -1466,22 +1397,6 @@ volumeNames: "{{ drTestLunNamesNew }}" newVolumeNames: "{{ drTestLunNames }}" - - set_fact: - deviceHost: "{{ drDeviceHost }}" - devicePort: "{{ drDevicePort }}" - deviceSn: "{{ drDeviceSn }}" - deviceToken: "{{ drDeviceToken }}" - deviceSession: "{{ drDeviceSession }}" - - - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/modify_lun.yml" - vars: - modifyLunId: "{{ drTestLunIds[i] }}" - newLunName: "{{ drTestLunNames[i] }}" - desc: "{{ drTestLunDescs[i] }}" - loop: "{{ range(0, drTestLunIds|length) | list }}" - loop_control: - loop_var: i - - set_fact: Step_6_2_Rollbacked: True @@ -1523,9 +1438,6 @@ name: old: "{{ drLunNamesNew }}" new: "{{ drLunNames }}" - desc: - old: "{{ drLunDescsNew }}" - new: "{{ drLunDescs }}" device: "{{ drDeviceName }}" - include_tasks: "{{GLOBAL.baseDir}}/task/volume/rename_volumes.yml" @@ -1533,21 +1445,6 @@ volumeNames: "{{ drLunNamesNew }}" newVolumeNames: "{{ drLunNames }}" - - set_fact: - deviceHost: "{{ drDeviceHost }}" - devicePort: "{{ drDevicePort }}" - deviceSn: "{{ drDeviceSn }}" - deviceToken: "{{ drDeviceToken }}" - deviceSession: "{{ drDeviceSession }}" - - - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/modify_lun.yml" - vars: - modifyLunId: "{{ drLunIds[i] }}" - desc: "{{ drLunDescs[i] }}" - loop: "{{ range(0, drLunIds|length) | list }}" - loop_control: - loop_var: i - - set_fact: Step_5_4_Rollbacked: True @@ -1648,9 +1545,6 @@ name: old: "{{ primaryLunNamesNew }}" new: "{{ primaryLunNames }}" - desc: - old: "{{ primaryLunDescsNew }}" - new: "{{ primaryLunDescs }}" device: "{{ primaryDeviceName }}" - include_tasks: "{{GLOBAL.baseDir}}/task/volume/rename_volumes.yml" @@ -1658,21 +1552,6 @@ volumeNames: "{{ primaryLunNamesNew }}" newVolumeNames: "{{ primaryLunNames }}" - - set_fact: - deviceHost: "{{ primaryDeviceHost }}" - devicePort: "{{ primaryDevicePort }}" - deviceSn: "{{ primaryDeviceSn }}" - deviceToken: "{{ primaryDeviceToken }}" - deviceSession: "{{ primaryDeviceSession }}" - - - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/modify_lun.yml" - vars: - modifyLunId: "{{ primaryLunIds[i] }}" - desc: "{{ primaryLunDescs[i] }}" - loop: "{{ range(0, primaryLunIds|length) | list }}" - loop_control: - loop_var: i - - set_fact: Step_4_3_Rollbacked: True @@ -2120,7 +1999,7 @@ params: luns: lunNames: "{{ metroLunNames }}" - lunDescs: "{{ primaryLunDescsNew }}" + lunDescs: "{{ primaryLunDescs }}" poolId: "{{ metroPoolId }}" workload: "{{ metroWorkload }}" device: "{{ metroDeviceName }}" @@ -2264,9 +2143,6 @@ name: old: "{{ primaryLunNames }}" new: "{{ primaryLunNamesNew }}" - desc: - old: "{{ primaryLunDescs }}" - new: "{{ primaryLunDescsNew }}" device: "{{ primaryDeviceName }}" result: succeeded: "{{ Step_4_3_Completed }}" @@ -2329,9 +2205,6 @@ name: old: "{{ drLunNames }}" new: "{{ drLunNamesNew }}" - desc: - old: "{{ drLunDescs }}" - new: "{{ drLunDescsNew }}" device: "{{ drDeviceName }}" result: succeeded: "{{ Step_5_4_Completed }}" @@ -2361,9 +2234,6 @@ name: old: "{{ drTestLunNames }}" new: "{{ drTestLunNamesNew }}" - desc: - old: "{{ drTestLunDescs }}" - new: "{{ drTestLunDescsNew }}" device: "{{ drDeviceName }}" result: succeeded: "{{ Step_6_2_Completed }}" diff --git a/rundeck/workflow/project001/44_remove_replica_cluster.yml b/rundeck/workflow/project001/44_remove_replica_cluster.yml index 706242a..4e88b0a 100644 --- a/rundeck/workflow/project001/44_remove_replica_cluster.yml +++ b/rundeck/workflow/project001/44_remove_replica_cluster.yml @@ -116,7 +116,7 @@ class1: "{{ Class_1 }}" class2: "{{ Class_2 if (protectLevel|int >= 2) else '0' }}" class3: "{{ Class_3 if (protectLevel|int == 3) else '0' }}" - lunNameTemplate: "%s%0{{DEFAULT.suffixDigits}}d" + lunNameTemplate: "%s%0{{DEFAULT.suffixDigits}}d_%s" - set_fact: primaryLgDescNew: "{{ metroEnable }}{{ protectLevel }}{{class1}}{{class2}}{{class3}}_{{ sessionName }}" @@ -124,16 +124,14 @@ primaryLunNames: [] primaryLunNamesNew: [] primaryLunPrefixNew: "{{primaryClusterName}}_{{protectType}}{{'S' if metroEnable == 'Y' else 'N'}}" - primaryLunDescsNew: [] - primaryLunDesc1New: "{{ class1 }}_00_{{replicaType}}_{{'00' if replicaType == '00' else primaryRoom}}_{{'0000000000000000' if replicaType == '00' else sessionName}}_{{'0' if replicaType == '00' else protectType}}1" + primaryLunSuffixNew: "{{ class1 }}_00_{{replicaType}}_{{'00' if replicaType == '00' else primaryRoom}}_{{'0000000000000000' if replicaType == '00' else sessionName}}_{{'0' if replicaType == '00' else protectType}}1" metroCgNameNew: "{{ replicaType }}_{{ primaryRoom }}_{{ sessionName }}_{{ protectType }}1" metroLunIds: [] metroLunNames: [] metroLunsInTier: [] metroLunNamesNew: [] metroLunPrefixNew: "{{primaryClusterName}}_{{protectType}}M" - metroLunDescsNew: [] - metroLunDesc1New: "{{ class1 }}_00_{{replicaType}}_{{'00' if replicaType == '00' else primaryRoom}}_{{'0000000000000000' if replicaType == '00' else sessionName}}_{{'0' if replicaType == '00' else protectType}}1" + metroLunSuffixNew: "{{ class1 }}_00_{{replicaType}}_{{'00' if replicaType == '00' else primaryRoom}}_{{'0000000000000000' if replicaType == '00' else sessionName}}_{{'0' if replicaType == '00' else protectType}}1" drCgNameNew: "{{ replicaType }}_{{ primaryRoom }}_{{ sessionName }}_{{ protectType }}2" drLgDescNew: "N{{ protectLevel }}{{ class1 }}{{class2}}{{class3}}_{{ sessionName }}" drLunIds: [] @@ -141,15 +139,13 @@ drLunsInTier: [] drLunNamesNew: [] drLunPrefixNew: "{{drClusterName}}_{{protectType}}N" - drLunDescsNew: [] - drLunDesc1New: "{{ class2 }}_00_{{replicaType}}_{{primaryRoom}}_{{sessionName}}_{{protectType}}2" + drLunSuffixNew: "{{ class2 }}_00_{{replicaType}}_{{primaryRoom}}_{{sessionName}}_{{protectType}}2" drTestCgNameNew: "{{ replicaType }}_{{ primaryRoom }}_{{ sessionName }}_{{ protectType }}3" drTestLunIds: [] drTestLunNames: [] drTestLunNamesNew: [] drTestLunPrefixNew: "{{drTestClusterName}}_{{protectType}}N" - drTestLunDescsNew: [] - drTestLunDesc1New: "{{ class3 }}_00_00_{{primaryRoom}}_{{sessionName}}_{{protectType}}3" + drTestLunSuffixNew: "{{ class3 }}_00_00_{{primaryRoom}}_{{sessionName}}_{{protectType}}3" drStarCgNameNew: "{{ replicaType }}_{{ primaryRoom }}_{{ sessionName }}_{{ protectType }}0" standbyCgNameNew: "{{ replicaType }}_{{ primaryRoom }}_{{ sessionName }}_{{ protectType }}4" @@ -198,12 +194,10 @@ primaryLunDescs: "{{ checkedLuns[primaryLgName] | json_query('[*].DESCRIPTION') }}" - set_fact: - primaryLunNamesNew: "{{ primaryLunNamesNew + [ lunNameTemplate | format(primaryLunPrefixNew, suffix|int) ] }}" - primaryLunDescsNew: "{{ primaryLunDescsNew + [ primaryLunDesc1New + '|' + remark ] }}" + primaryLunNamesNew: "{{ primaryLunNamesNew + [ lunNameTemplate | format(primaryLunPrefixNew, lunNo|int, primaryLunSuffixNew) ] }}" vars: - suffix: "{{ item.1.split('_')[4][2:] }}" - remark: "{{ primaryLunDescs[item.0].split('|')[1] | default('') }}" - with_indexed_items: "{{ primaryLunNames }}" + lunNo: "{{ item.split('_')[4][2:] }}" + with_items: "{{ primaryLunNames }}" - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_pgs.yml" vars: @@ -267,12 +261,10 @@ metroLunsWorkload: "{{ checkedLuns[primaryLgName] | json_query('[*].WORKLOADTYPEID') }}" - set_fact: - metroLunNamesNew: "{{ metroLunNamesNew + [ lunNameTemplate | format(metroLunPrefixNew, suffix|int) ] }}" - metroLunDescsNew: "{{ metroLunDescsNew + [ metroLunDesc1New + '|' + remark ] }}" + metroLunNamesNew: "{{ metroLunNamesNew + [ lunNameTemplate | format(metroLunPrefixNew, lunNo|int, metroLunSuffixNew) ] }}" vars: - suffix: "{{ item.1.split('_')[4][2:] }}" - remark: "{{ metroLunDescs[item.0].split('|')[1] | default('') }}" - with_indexed_items: "{{ metroLunNames }}" + lunNo: "{{ item.split('_')[4][2:] }}" + with_items: "{{ metroLunNames }}" - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_pgs.yml" vars: @@ -352,12 +344,10 @@ drLunsWorkload: "{{ checkedLuns[drLgName] | json_query('[*].WORKLOADTYPEID') }}" - set_fact: - drLunNamesNew: "{{ drLunNamesNew + [ lunNameTemplate | format(drLunPrefixNew, suffix|int) ] }}" - drLunDescsNew: "{{ drLunDescsNew + [ drLunDesc1New + '|' + remark ] }}" + drLunNamesNew: "{{ drLunNamesNew + [ lunNameTemplate | format(drLunPrefixNew, lunNo|int, drLunSuffixNew) ] }}" vars: - suffix: "{{ item.1.split('_')[4][2:] }}" - remark: "{{ drLunDescs[item.0].split('|')[1] | default('') }}" - with_indexed_items: "{{ drLunNames }}" + lunNo: "{{ item.split('_')[4][2:] }}" + with_items: "{{ drLunNames }}" - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_pgs.yml" vars: @@ -424,12 +414,10 @@ drTestLunsWorkload: "{{ checkedLuns[drTestLgName] | json_query('[*].WORKLOADTYPEID') }}" - set_fact: - drTestLunNamesNew: "{{ drTestLunNamesNew + [ lunNameTemplate | format(drTestLunPrefixNew, suffix|int) ] }}" - drTestLunDescsNew: "{{ drTestLunDescsNew + [ drTestLunDesc1New + '|' + remark ] }}" + drTestLunNamesNew: "{{ drTestLunNamesNew + [ lunNameTemplate | format(drTestLunPrefixNew, lunNo|int, drTestLunSuffixNew) ] }}" vars: - suffix: "{{ item.1.split('_')[4][2:] }}" - remark: "{{ drTestLunDescs[item.0].split('|')[1] | default('') }}" - with_indexed_items: "{{ drTestLunNames }}" + lunNo: "{{ item.split('_')[4][2:] }}" + with_items: "{{ drTestLunNames }}" # End Precheck_4 when: Precheck_4_Execute @@ -1176,9 +1164,6 @@ name: old: "{{ drTestLunNames }}" new: "{{ drTestLunNamesNew }}" - desc: - old: "{{ drTestLunDescs }}" - new: "{{ drTestLunDescsNew }}" device: "{{ drDeviceName }}" - include_tasks: "{{GLOBAL.baseDir}}/task/volume/rename_volumes.yml" @@ -1186,21 +1171,6 @@ volumeNames: "{{ drTestLunNames }}" newVolumeNames: "{{ drTestLunNamesNew }}" - - set_fact: - deviceHost: "{{ drDeviceHost }}" - devicePort: "{{ drDevicePort }}" - deviceSn: "{{ drDeviceSn }}" - deviceToken: "{{ drDeviceToken }}" - deviceSession: "{{ drDeviceSession }}" - - - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/modify_lun.yml" - vars: - modifyLunId: "{{ drTestLunIds[i] }}" - desc: "{{ drTestLunDescsNew[i] }}" - loop: "{{ range(0, drTestLunIds|length) | list }}" - loop_control: - loop_var: i - - set_fact: Step_5_2_Completed: True @@ -1358,9 +1328,6 @@ name: old: "{{ drLunNames }}" new: "{{ drLunNamesNew }}" - desc: - old: "{{ drLunDescs }}" - new: "{{ drLunDescsNew }}" device: "{{ drDeviceName }}" - include_tasks: "{{GLOBAL.baseDir}}/task/volume/rename_volumes.yml" @@ -1368,21 +1335,6 @@ volumeNames: "{{ drLunNames }}" newVolumeNames: "{{ drLunNamesNew }}" - - set_fact: - deviceHost: "{{ drDeviceHost }}" - devicePort: "{{ drDevicePort }}" - deviceSn: "{{ drDeviceSn }}" - deviceToken: "{{ drDeviceToken }}" - deviceSession: "{{ drDeviceSession }}" - - - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/modify_lun.yml" - vars: - modifyLunId: "{{ drLunIds[i] }}" - desc: "{{ drLunDescsNew[i] }}" - loop: "{{ range(0, drLunIds|length) | list }}" - loop_control: - loop_var: i - - set_fact: Step_6_5_Completed: True @@ -1483,9 +1435,6 @@ name: old: "{{ metroLunNames }}" new: "{{ metroLunNamesNew }}" - desc: - old: "{{ metroLunDescs }}" - new: "{{ metroLunDescsNew }}" device: "{{ metroDeviceName }}" - include_tasks: "{{GLOBAL.baseDir}}/task/volume/rename_volumes.yml" @@ -1493,21 +1442,6 @@ volumeNames: "{{ metroLunNames }}" newVolumeNames: "{{ metroLunNamesNew }}" - - set_fact: - deviceHost: "{{ metroDeviceHost }}" - devicePort: "{{ metroDevicePort }}" - deviceSn: "{{ metroDeviceSn }}" - deviceToken: "{{ metroDeviceToken }}" - deviceSession: "{{ metroDeviceSession }}" - - - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/modify_lun.yml" - vars: - modifyLunId: "{{ metroLunIds[i] }}" - desc: "{{ metroLunDescsNew[i] }}" - loop: "{{ range(0, metroLunIds|length) | list }}" - loop_control: - loop_var: i - - set_fact: Step_7_4_Completed: True @@ -1580,9 +1514,6 @@ name: old: "{{ primaryLunNames }}" new: "{{ primaryLunNamesNew }}" - desc: - old: "{{ primaryLunDescs }}" - new: "{{ primaryLunDescsNew }}" device: "{{ primaryDeviceName }}" - include_tasks: "{{GLOBAL.baseDir}}/task/volume/rename_volumes.yml" @@ -1590,21 +1521,6 @@ volumeNames: "{{ primaryLunNames }}" newVolumeNames: "{{ primaryLunNamesNew }}" - - set_fact: - deviceHost: "{{ primaryDeviceHost }}" - devicePort: "{{ primaryDevicePort }}" - deviceSn: "{{ primaryDeviceSn }}" - deviceToken: "{{ primaryDeviceToken }}" - deviceSession: "{{ primaryDeviceSession }}" - - - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/modify_lun.yml" - vars: - modifyLunId: "{{ primaryLunIds[i] }}" - desc: "{{ primaryLunDescsNew[i] }}" - loop: "{{ range(0, primaryLunIds|length) | list }}" - loop_control: - loop_var: i - - set_fact: Step_8_3_Completed: True @@ -1788,9 +1704,6 @@ name: old: "{{ primaryLunNamesNew }}" new: "{{ primaryLunNames }}" - desc: - old: "{{ primaryLunDescsNew }}" - new: "{{ primaryLunDescs }}" device: "{{ primaryDeviceName }}" - include_tasks: "{{GLOBAL.baseDir}}/task/volume/rename_volumes.yml" @@ -1798,21 +1711,6 @@ volumeNames: "{{ primaryLunNamesNew }}" newVolumeNames: "{{ primaryLunNames }}" - - set_fact: - deviceHost: "{{ primaryDeviceHost }}" - devicePort: "{{ primaryDevicePort }}" - deviceSn: "{{ primaryDeviceSn }}" - deviceToken: "{{ primaryDeviceToken }}" - deviceSession: "{{ primaryDeviceSession }}" - - - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/modify_lun.yml" - vars: - modifyLunId: "{{ primaryLunIds[i] }}" - desc: "{{ primaryLunDescs[i] }}" - loop: "{{ range(0, primaryLunIds|length) | list }}" - loop_control: - loop_var: i - - set_fact: Step_8_3_Rollbacked: True @@ -1885,9 +1783,6 @@ name: old: "{{ metroLunNamesNew }}" new: "{{ metroLunNames }}" - desc: - old: "{{ metroLunDescsNew }}" - new: "{{ metroLunDescs }}" device: "{{ metroDeviceName }}" - include_tasks: "{{GLOBAL.baseDir}}/task/volume/rename_volumes.yml" @@ -1895,21 +1790,6 @@ volumeNames: "{{ metroLunNamesNew }}" newVolumeNames: "{{ metroLunNames }}" - - set_fact: - deviceHost: "{{ metroDeviceHost }}" - devicePort: "{{ metroDevicePort }}" - deviceSn: "{{ metroDeviceSn }}" - deviceToken: "{{ metroDeviceToken }}" - deviceSession: "{{ metroDeviceSession }}" - - - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/modify_lun.yml" - vars: - modifyLunId: "{{ metroLunIds[i] }}" - desc: "{{ metroLunDescs[i] }}" - loop: "{{ range(0, metroLunIds|length) | list }}" - loop_control: - loop_var: i - - set_fact: Step_7_4_Rollbacked: True @@ -2010,9 +1890,6 @@ name: old: "{{ drLunNamesNew }}" new: "{{ drLunNames }}" - desc: - old: "{{ drLunDescsNew }}" - new: "{{ drLunDescs }}" device: "{{ drDeviceName }}" - include_tasks: "{{GLOBAL.baseDir}}/task/volume/rename_volumes.yml" @@ -2020,21 +1897,6 @@ volumeNames: "{{ drLunNamesNew }}" newVolumeNames: "{{ drLunNames }}" - - set_fact: - deviceHost: "{{ drDeviceHost }}" - devicePort: "{{ drDevicePort }}" - deviceSn: "{{ drDeviceSn }}" - deviceToken: "{{ drDeviceToken }}" - deviceSession: "{{ drDeviceSession }}" - - - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/modify_lun.yml" - vars: - modifyLunId: "{{ drLunIds[i] }}" - desc: "{{ drLunDescs[i] }}" - loop: "{{ range(0, drLunIds|length) | list }}" - loop_control: - loop_var: i - - set_fact: Step_6_5_Rollbacked: True @@ -2192,9 +2054,6 @@ name: old: "{{ drTestLunNamesNew }}" new: "{{ drTestLunNames }}" - desc: - old: "{{ drTestLunDescsNew }}" - new: "{{ drTestLunDescs }}" device: "{{ drDeviceName }}" - include_tasks: "{{GLOBAL.baseDir}}/task/volume/rename_volumes.yml" @@ -2202,22 +2061,6 @@ volumeNames: "{{ drTestLunNamesNew }}" newVolumeNames: "{{ drTestLunNames }}" - - set_fact: - deviceHost: "{{ drDeviceHost }}" - devicePort: "{{ drDevicePort }}" - deviceSn: "{{ drDeviceSn }}" - deviceToken: "{{ drDeviceToken }}" - deviceSession: "{{ drDeviceSession }}" - - - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/modify_lun.yml" - vars: - modifyLunId: "{{ drTestLunIds[i] }}" - newLunName: "{{ drTestLunNames[i] }}" - desc: "{{ drTestLunDescs[i] }}" - loop: "{{ range(0, drTestLunIds|length) | list }}" - loop_control: - loop_var: i - - set_fact: Step_5_2_Rollbacked: True @@ -2814,11 +2657,6 @@ deviceToken: "{{ drDeviceToken }}" deviceSession: "{{ drDeviceSession }}" - - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/sync_replication_cg.yml" - vars: - cgName: "{{ drCgName }}" - waitSync: True - - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/create_snapshot_cg.yml" vars: pgName: "{{ drPgName }}" @@ -3180,9 +3018,6 @@ name: old: "{{ drTestLunNames }}" new: "{{ drTestLunNamesNew }}" - desc: - old: "{{ drTestLunDescs }}" - new: "{{ drTestLunDescsNew }}" device: "{{ drDeviceName }}" result: succeeded: "{{ Step_5_2_Completed }}" @@ -3276,9 +3111,6 @@ name: old: "{{ drLunNames }}" new: "{{ drLunNamesNew }}" - desc: - old: "{{ drLunDescs }}" - new: "{{ drLunDescsNew }}" device: "{{ drDeviceName }}" result: succeeded: "{{ Step_6_5_Completed }}" @@ -3341,9 +3173,6 @@ name: old: "{{ metroLunNames }}" new: "{{ metroLunNamesNew }}" - desc: - old: "{{ metroLunDescs }}" - new: "{{ metroLunDescsNew }}" device: "{{ metroDeviceName }}" result: succeeded: "{{ Step_7_4_Completed }}" @@ -3391,9 +3220,6 @@ name: old: "{{ primaryLunNames }}" new: "{{ primaryLunNamesNew }}" - desc: - old: "{{ primaryLunDescs }}" - new: "{{ primaryLunDescsNew }}" device: "{{ primaryDeviceName }}" result: succeeded: "{{ Step_8_3_Completed }}" diff --git a/rundeck/workflow/project001/45_migrate_host.yml b/rundeck/workflow/project001/45_migrate_host.yml index 92b4116..df44c62 100644 --- a/rundeck/workflow/project001/45_migrate_host.yml +++ b/rundeck/workflow/project001/45_migrate_host.yml @@ -41,7 +41,7 @@ replicaType: "{{ REPTYPE['N1']['type'] }}" # See ../../config/project001.yml enableAlua: "{{ 1 if (OS_Type == 'SOL') else 0 }}" # Enable ALUA for Solaris enableMetroAlua: "{{ 1 if (OS_Type == 'SOL') else 0 }}" - lunNameTemplate: "%s%0{{DEFAULT.suffixDigits}}d" + lunNameTemplate: "%s%0{{DEFAULT.suffixDigits}}d_%s_%s_%s_%s" - set_fact: primaryLunNames: [] @@ -145,11 +145,11 @@ targetLuns: "{{ targetLuns + [targetLun] }}" vars: targetLun: - name: "{{ lunNameTemplate | format(targetLunPrefix, nextScsiId|int + item.0) }}" - desc: "{{ primaryLunDescs[item.0][0:1] }}_00_{{replicaType}}_00_0000000000000000_01|{{primaryLunDescs[item.0].split('|')[1] | default('') }}" + name: "{{ lunNameTemplate | format(targetLunPrefix, (nextScsiId|int + item.0), item.1.split('_')[5], '00', replicaType, '00_0000000000000000_01' ) }}" + desc: "{{ primaryLunDescs[item.0] }}" sector: "{{ primaryLunSectors[item.0] }}" lg: "{{ primaryLunLgs[item.0] }}" - class: "{{ primaryLunDescs[item.0][0:1] }}" + class: "{{ item.1.split('_')[5] }}" scsiId: "{{ nextScsiId|int + item.0 }}" with_indexed_items: "{{ primaryLunNames }}" diff --git a/rundeck/workflow/project001/46_migrate_cluster.yml b/rundeck/workflow/project001/46_migrate_cluster.yml index 1c6ec6a..e68c19c 100644 --- a/rundeck/workflow/project001/46_migrate_cluster.yml +++ b/rundeck/workflow/project001/46_migrate_cluster.yml @@ -51,7 +51,7 @@ protectType: "{{ REPTYPE['N1']['enum'] }}" # See ../../config/project001.yml replicaType: "{{ REPTYPE['N1']['type'] }}" # See ../../config/project001.yml maxScsiId: "{{ OSTYPE[OS_Type]['max_scsi_id'] }}" # See ../../config/project001.yml - lunNameTemplate: "%s%0{{DEFAULT.suffixDigits}}d" + lunNameTemplate: "%s%0{{DEFAULT.suffixDigits}}d_%s_%s_%s_%s" - set_fact: primaryLunNames: [] @@ -132,11 +132,11 @@ targetLuns: "{{ targetLuns + [targetLun] }}" vars: targetLun: - name: "{{ lunNameTemplate | format( targetLunPrefix, (maxScsiId|int - (nextScsiId|int - item.0) + 1) ) }}" - desc: "{{ primaryLunDescs[item.0][0:1] }}_00_{{replicaType}}_00_0000000000000000_01|{{ primaryLunDescs[item.0].split('|')[1] | default('') }}" + name: "{{ lunNameTemplate | format(targetLunPrefix, (maxScsiId|int - (nextScsiId|int - item.0) + 1), item.1.split('_')[5], '00', replicaType, '00_0000000000000000_01' ) }}" + desc: "{{ primaryLunDescs[item.0] }}" sector: "{{ primaryLunSectors[item.0] }}" lg: "{{ primaryLunLgs[item.0] }}" - class: "{{ primaryLunDescs[item.0][0:1] }}" + class: "{{ item.1.split('_')[5] }}" scsiId: "{{ nextScsiId|int - item.0 }}" with_indexed_items: "{{ primaryLunNames }}" diff --git a/rundeck/workflow/project001/49_create_pg.yml b/rundeck/workflow/project001/49_create_pg.yml new file mode 100644 index 0000000..eda379b --- /dev/null +++ b/rundeck/workflow/project001/49_create_pg.yml @@ -0,0 +1,814 @@ +- name: Create Protection Group + hosts: localhost + vars_files: + - ../../../config/global.yml + - ../../../config/project001.yml + gather_facts: no + become: no + tasks: + + # Check Protection Group Params + - block: + - set_fact: + checked_pg_params: + Country: "{{ (Country is not none and Country != DEFAULT.noneValue) and Country|length == 2 }}" + OS_Type: "{{ (OS_Type is not none and OS_Type != DEFAULT.noneValue) and OS_Type in OSTYPE }}" + Site: "{{ (Site is not none and Site != DEFAULT.noneValue) and Site in DC }}" + Primary_Storage_Room: "{{ (Primary_Storage_Room is not none and Primary_Storage_Room != DEFAULT.noneValue) and Primary_Storage_Room in AZ }}" + Primary_Storage: "{{ (Primary_Storage is not none and Primary_Storage != DEFAULT.noneValue) and (Primary_Storage|string|length == 20) }}" + Session_Name: "{{ Session_Name|length <= 13 and '_' not in Session_Name }}" + Enable_HyperMetro: "{{ Enable_HyperMetro in ['Y','N'] }}" + Protection_Level: "{{ Protection_Level|int in [1,2,3] }}" + Check_Result_1: "{{ ('pg' in Check_Result_1) }}" + + - name: Precheck_0_1 - Check Protection Group Params + debug: + msg: "{{checked_pg_params}}" + failed_when: checked_pg_params.values()|unique != [True] + + # Check Metro Protection Group Params + - block: + - set_fact: + checked_metro_pg_params: + Metro_Storage: "{{ (Metro_Storage is not none and Metro_Storage != DEFAULT.noneValue) and (Metro_Storage|string|length == 20) }}" + Metro_Storage_Room: "{{ (Metro_Storage_Room is not none and Metro_Storage_Room != DEFAULT.noneValue) and Metro_Storage_Room in AZ }}" + Check_Result_2: "{{ ('pg' in Check_Result_1) }}" + + - name: Precheck_0_2 - Check Metro Protection Group Params + debug: + msg: "{{checked_metro_pg_params}}" + failed_when: checked_metro_pg_params.values()|unique != [True] + + when: Enable_HyperMetro == 'Y' + + + # Check DR Protection Group Params + - block: + - set_fact: + checked_dr_pg_params: + DR_Storage: "{{ (DR_Storage is not none and DR_Storage != DEFAULT.noneValue) and (DR_Storage|string|length == 20) }}" + DR_Storage_Room: "{{ (DR_Storage_Room is not none and DR_Storage_Room != DEFAULT.noneValue) and DR_Storage_Room in AZ }}" + Check_Result_3: "{{ ('pg' in Check_Result_1) }}" + + - name: Precheck_0_3 - Check DR Protection Group Params + debug: + msg: "{{checked_dr_pg_params}}" + failed_when: checked_dr_pg_params.values()|unique != [True] + + when: Protection_Level|int >= 2 + + # Set Params + + - set_fact: + sessionName: "{{Country}}0{{ Session_Name}}" + protectType: "{{ REPTYPE[Enable_HyperMetro+Protection_Level|string]['enum'] }}" # See ../../config/project001.yml + replicaType: "{{ REPTYPE[Enable_HyperMetro+Protection_Level|string]['type'] }}" # See ../../config/project001.yml + + - set_fact: + primaryDeviceSn: "{{ Primary_Storage|string }}" + primaryPgName: "{{ sessionName }}_1" + primaryPgDesc: "{{ Enable_HyperMetro }}{{ Protection_Level }}" + + - set_fact: + metroDeviceSn: "{{ Metro_Storage|string if (Metro_Storage is not none) else none }}" + metroCgName: "{{ replicaType }}_{{ Site }}_{{ sessionName }}_{{ protectType }}1" + when: + - Enable_HyperMetro == 'Y' + + - set_fact: + drDeviceSn: "{{ DR_Storage|string if (DR_Storage is not none) else none }}" + drCgName: "{{ replicaType }}_{{ Site }}_{{ sessionName }}_{{ protectType }}2" + drSyncMode: "{{ DR_Sync_Mode }}" + when: + - Protection_Level|int >= 2 + + - set_fact: + drPgName: "{{ sessionName }}_2" + when: + - Protection_Level|int >= 2 + + - set_fact: + standbyCgName: "{{ replicaType }}_{{ Site }}_{{ sessionName }}_{{ protectType }}4" + when: + - Enable_HyperMetro == 'Y' + - Protection_Level|int >= 2 + + - set_fact: + drTestCgName: "{{ replicaType }}_{{ Site }}_{{ sessionName }}_{{ protectType }}3" + when: + - Protection_Level|int == 3 + + - import_tasks: "{{GLOBAL.baseDir}}/task/user/login.yml" + + - block: + - name: Precheck_1 - Check Primary Protection Group + debug: + msg: + protectGroup: "{{ primaryPgName }}" + device: "{{ primaryDeviceSn }}" + + - name: Login to Primary Device + set_fact: + deviceSn: "{{ primaryDeviceSn }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/login_storage.yml" + + - set_fact: + primaryDeviceName: "{{ deviceName }}" + primaryDeviceHost: "{{ deviceHost }}" + primaryDevicePort: "{{ devicePort }}" + primaryDeviceToken: "{{ deviceToken }}" + primaryDeviceSession: "{{ deviceSession }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_pgs.yml" + vars: + pgNames: ["{{ primaryPgName }}"] + checkExist: False + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_hypermetro_cgs.yml" + vars: + cgNames: ["{{ metroCgName }}"] + checkExist: False + when: + - Enable_HyperMetro == 'Y' + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_replication_cgs.yml" + vars: + cgNames: [ "{{ drCgName }}" ] + checkExist: False + when: + - Protection_Level|int>= 2 + + # End Precheck_1 + # End Block + + - block: + - name: Precheck_2 - Check Metro Protection Group + debug: + msg: + protectGroup: "{{ primaryPgName }}" + device: "{{ metroDeviceSn }}" + + - name: Login to Metro Device + set_fact: + deviceSn: "{{ metroDeviceSn }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/login_storage.yml" + + - set_fact: + metroDeviceName: "{{ deviceName }}" + metroDeviceHost: "{{ deviceHost }}" + metroDevicePort: "{{ devicePort }}" + metroDeviceToken: "{{ deviceToken }}" + metroDeviceSession: "{{ deviceSession }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_pgs.yml" + vars: + pgNames: ["{{ primaryPgName }}"] + checkExist: False + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_hypermetro_cgs.yml" + vars: + cgNames: ["{{ metroCgName }}"] + checkExist: False + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_replication_cgs.yml" + vars: + cgNames: [ "{{ standbyCgName }}" ] + checkExist: False + when: + - Protection_Level|int>= 2 + + # End Precheck_2 + + # End Block + when: + - Enable_HyperMetro == 'Y' + + - block: + - name: Precheck_3 - Check DR Protection Group + debug: + msg: + drProtectGroup: "{{ drPgName }}" + device: "{{ drDeviceSn }}" + + - name: Login to DR Device + set_fact: + deviceSn: "{{ drDeviceSn }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/login_storage.yml" + + - set_fact: + drDeviceName: "{{ deviceName }}" + drDeviceHost: "{{ deviceHost }}" + drDevicePort: "{{ devicePort }}" + drDeviceToken: "{{ deviceToken }}" + drDeviceSession: "{{ deviceSession }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_pgs.yml" + vars: + pgNames: ["{{ drPgName }}"] + checkExist: False + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_replication_cgs.yml" + vars: + cgNames: [ "{{ drCgName }}" ] + checkExist: False + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_replication_cgs.yml" + vars: + cgNames: [ "{{ standbyCgName }}" ] + checkExist: False + when: + - Enable_HyperMetro == 'Y' + + # End Precheck_3 + + # End Block + when: + - Protection_Level|int >= 2 + + - block: + - name: Precheck_4 - Check DR Test Cgs + debug: + msg: + drProtectGroup: "{{ drPgName }}" + device: "{{ drDeviceSn }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_snapshot_cgs.yml" + vars: + cgNames: ["{{ drTestCgName }}"] + checkExist: False + + # End Precheck_4 + + # End Block + when: + - Protection_Level|int == 3 + + + - block: + + # Begin Workflow Steps + + - set_fact: + # Create Primary Protection Group + Step_1_3_Execute: "{{ True }}" + Step_1_3_Completed: False + Step_1_3_Rollbacked: False + + # Create Metro Protection Group + Step_2_3_Execute: "{{ Enable_HyperMetro == 'Y' }}" + Step_2_3_Completed: False + Step_2_3_Rollbacked: False + + # Create HyperMetro CG + Step_2_4_Execute: "{{ Enable_HyperMetro == 'Y' }}" + Step_2_4_Completed: False + Step_2_4_Rollbacked: False + + # Create DR Protection Group + Step_3_3_Execute: "{{ Protection_Level|int >= 2 }}" + Step_3_3_Completed: False + Step_3_3_Rollbacked: False + + # Create Replication CG + Step_3_4_Execute: "{{ Protection_Level|int >= 2 }}" + Step_3_4_Completed: False + Step_3_4_Rollbacked: False + + # Create Standby Replication CG + Step_3_5_Execute: "{{ Protection_Level|int >= 2 and Enable_HyperMetro == 'Y' }}" + Step_3_5_Completed: False + Step_3_5_Rollbacked: False + + - name: Workflow - Create Protection Group + debug: + msg: + Step_1_3: "[{{Step_1_3_Execute}}] Create Primary Protection Group" + Step_2_3: "[{{Step_2_3_Execute}}] Create Metro Protection Group" + Step_2_4: "[{{Step_2_4_Execute}}] Create Metro CG" + Step_3_3: "[{{Step_3_3_Execute}}] Create DR Protection Group" + Step_3_4: "[{{Step_3_4_Execute}}] Create Replication CG" + Step_3_5: "[{{Step_3_5_Execute}}] Create Standby Replication CG" + + - block: + - name: Step_1_3 - Create Primary Protection Group + debug: + msg: + params: + pg: "{{ primaryPgName }}" + device: "{{ primaryDeviceName }}" + + - set_fact: + deviceHost: "{{ primaryDeviceHost }}" + devicePort: "{{ primaryDevicePort }}" + deviceSn: "{{ primaryDeviceSn }}" + deviceToken: "{{ primaryDeviceToken }}" + deviceSession: "{{ primaryDeviceSession }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/create_pg.yml" + vars: + pgName: "{{ primaryPgName }}" + desc: "{{ primaryPgDesc }}" + + - set_fact: + primaryPgId: "{{ newPgId }}" + Step_1_3_Completed: True + when: Step_1_3_Execute + + - block: + - name: Step_2_3 - Create Metro Protection Group + debug: + msg: + params: + pg: "{{ primaryPgName }}" + device: "{{ metroDeviceName }}" + + - set_fact: + deviceHost: "{{ metroDeviceHost }}" + devicePort: "{{ metroDevicePort }}" + deviceSn: "{{ metroDeviceSn }}" + deviceToken: "{{ metroDeviceToken }}" + deviceSession: "{{ metroDeviceSession }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/create_pg.yml" + vars: + pgName: "{{ primaryPgName }}" + desc: "{{ primaryPgDesc }}" + + - set_fact: + metroPgId: "{{ newPgId }}" + Step_2_3_Completed: True + when: Step_2_3_Execute + + - block: + - name: Step_2_4 - Create Metro CG + debug: + msg: + params: + device: "{{ primaryDeviceName }}" + remote: "{{ metroDeviceName }}" + cg: "{{ metroCgName }}" + pg: + local: + name: "{{ primaryPgName }}" + id: "{{ primaryPgId }}" + remote: + name: "{{ primaryPgName }}" + id: "{{ metroPgId }}" + + - set_fact: + deviceHost: "{{ primaryDeviceHost }}" + devicePort: "{{ primaryDevicePort }}" + deviceSn: "{{ primaryDeviceSn }}" + deviceToken: "{{ primaryDeviceToken }}" + deviceSession: "{{ primaryDeviceSession }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/create_hypermetro_cg.yml" + vars: + cgName: "{{ metroCgName }}" + remoteSn: "{{ metroDeviceSn }}" + localPgId: "{{ primaryPgId }}" + remotePgId: "{{ metroPgId }}" + + - set_fact: + Step_2_4_Completed: True + when: Step_2_4_Execute + + - block: + - name: Step_3_3 - Create DR Protection Group + debug: + msg: + params: + pg: "{{ drPgName }}" + device: "{{ drDeviceName }}" + + - set_fact: + deviceHost: "{{ drDeviceHost }}" + devicePort: "{{ drDevicePort }}" + deviceSn: "{{ drDeviceSn }}" + deviceToken: "{{ drDeviceToken }}" + deviceSession: "{{ drDeviceSession }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/create_pg.yml" + vars: + pgName: "{{ drPgName }}" + desc: "{{ primaryPgDesc }}" + + - set_fact: + drPgId: "{{ newPgId }}" + Step_3_3_Completed: True + when: Step_3_3_Execute + + - block: + - name: Step_3_4 - Create Replication CG + debug: + msg: + params: + device: "{{ primaryDeviceName }}" + remote: "{{ drDeviceName }}" + cg: "{{ drCgName }}" + pg: + local: + name: "{{ primaryPgName }}" + id: "{{ primaryPgId }}" + remote: + name: "{{ drPgName }}" + id: "{{ drPgId }}" + + - set_fact: + deviceHost: "{{ primaryDeviceHost }}" + devicePort: "{{ primaryDevicePort }}" + deviceSn: "{{ primaryDeviceSn }}" + deviceToken: "{{ primaryDeviceToken }}" + deviceSession: "{{ primaryDeviceSession }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/create_replication_cg.yml" + vars: + cgName: "{{ drCgName }}" + remoteSn: "{{ drDeviceSn }}" + mode: "{{ drSyncMode }}" + localPgId: "{{ primaryPgId }}" + remotePgId: "{{ drPgId }}" + + - set_fact: + Step_3_4_Completed: True + when: Step_3_4_Execute + + - block: + - name: Step_3_5 - Create Standby Replication CG + debug: + msg: + params: + device: "{{ metroDeviceName }}" + remote: "{{ drDeviceName }}" + cg: "{{ standbyCgName }}" + pg: + local: + name: "{{ primaryPgName }}" + id: "{{ metroPgId }}" + remote: + name: "{{ drPgName }}" + id: "{{ drPgId }}" + + - set_fact: + deviceHost: "{{ metroDeviceHost }}" + devicePort: "{{ metroDevicePort }}" + deviceSn: "{{ metroDeviceSn }}" + deviceToken: "{{ metroDeviceToken }}" + deviceSession: "{{ metroDeviceSession }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/create_replication_cg.yml" + vars: + cgName: "{{ standbyCgName }}" + remoteSn: "{{ drDeviceSn }}" + mode: "{{ GLOBAL.replication.syncMode.async }}" + localPgId: "{{ metroPgId }}" + remotePgId: "{{ drPgId }}" + + - set_fact: + Step_3_5_Completed: True + when: Step_3_5_Execute + + # End Workflow Steps + + # End Block + + rescue: + + # Begin Workflow Rollbacks + + - block: + - name: Rollback_3_5 - Delete Standby Replication CG + debug: + msg: + params: + device: "{{ metroDeviceName }}" + cg: "{{ standbyCgName }}" + + - set_fact: + deviceHost: "{{ metroDeviceHost }}" + devicePort: "{{ metroDevicePort }}" + deviceSn: "{{ metroDeviceSn }}" + deviceToken: "{{ metroDeviceToken }}" + deviceSession: "{{ metroDeviceSession }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/delete_replication_cg.yml" + vars: + cgName: "{{ standbyCgName }}" + + - set_fact: + Step_3_5_Rollbacked: True + when: Step_3_5_Completed + + - block: + - name: Rollback_3_4 - Delete Replication CG + debug: + msg: + params: + device: "{{ primaryDeviceName }}" + cg: "{{ drCgName }}" + + - set_fact: + deviceHost: "{{ primaryDeviceHost }}" + devicePort: "{{ primaryDevicePort }}" + deviceSn: "{{ primaryDeviceSn }}" + deviceToken: "{{ primaryDeviceToken }}" + deviceSession: "{{ primaryDeviceSession }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/delete_replication_cg.yml" + vars: + cgName: "{{ drCgName }}" + + - set_fact: + Step_3_4_Rollbacked: True + when: Step_3_4_Completed + + - block: + - name: Rollback_3_3 - Delete DR Protection Group + debug: + msg: + params: + pg: "{{ drPgName }}" + device: "{{ drDeviceName }}" + + - set_fact: + deviceHost: "{{ drDeviceHost }}" + devicePort: "{{ drDevicePort }}" + deviceSn: "{{ drDeviceSn }}" + deviceToken: "{{ drDeviceToken }}" + deviceSession: "{{ drDeviceSession }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/delete_pg.yml" + vars: + pgName: "{{ drPgName }}" + + - set_fact: + Step_3_3_Rollbacked: True + when: Step_3_3_Completed + + - block: + - name: Rollback_2_4 - Delete HyperMetro CG + debug: + msg: + params: + device: "{{ primaryDeviceName }}" + cg: "{{ metroCgName }}" + + - set_fact: + deviceHost: "{{ primaryDeviceHost }}" + devicePort: "{{ primaryDevicePort }}" + deviceSn: "{{ primaryDeviceSn }}" + deviceToken: "{{ primaryDeviceToken }}" + deviceSession: "{{ primaryDeviceSession }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/delete_hypermetro_cg.yml" + vars: + cgName: "{{ metroCgName }}" + + - set_fact: + Step_2_4_Rollbacked: True + when: Step_2_4_Completed + + - block: + - name: Rollback_2_3 - Delete for Metro Protection Group + debug: + msg: + params: + pgName: "{{ primaryPgName }}" + device: "{{ metroDeviceName }}" + + - set_fact: + deviceHost: "{{ metroDeviceHost }}" + devicePort: "{{ metroDevicePort }}" + deviceSn: "{{ metroDeviceSn }}" + deviceToken: "{{ metroDeviceToken }}" + deviceSession: "{{ metroDeviceSession }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/delete_pg.yml" + vars: + pgName: "{{ primaryPgName }}" + + - set_fact: + Step_2_3_Rollbacked: True + when: Step_2_3_Completed + + - block: + - name: Rollback_1_3 - Delete Primary Protection Group + debug: + msg: + params: + pgName: "{{ primaryPgName }}" + device: "{{ primaryDeviceName }}" + + - set_fact: + deviceHost: "{{ primaryDeviceHost }}" + devicePort: "{{ primaryDevicePort }}" + deviceSn: "{{ primaryDeviceSn }}" + deviceToken: "{{ primaryDeviceToken }}" + deviceSession: "{{ primaryDeviceSession }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/delete_pg.yml" + vars: + pgName: "{{ primaryPgName }}" + + - set_fact: + Step_1_3_Rollbacked: True + when: Step_1_3_Completed + + # End Workflow Rollbacks + + # End Rescure + always: + + # Begin Final Steps + + - name: Final_Step_1 - Sync Devices + set_fact: + deviceSynced: [] + primaryDeviceNeedSync: "{{ (Step_1_3_Completed|bool == True and Step_1_3_Rollbacked|bool == False) }}" + metroDeviceNeedSync: "{{ (Step_2_3_Completed|bool == True and Step_2_3_Rollbacked|bool == False) }}" + remoteDeviceNeedSync: "{{ (Step_3_3_Completed|bool == True and Step_3_3_Rollbacked|bool == False) }}" + + - name: Final_Step_1_1 - Sync Primary Device + debug: + msg: + device: "{{ primaryDeviceName }}" + when: primaryDeviceNeedSync + + - set_fact: + deviceName: "{{ primaryDeviceName }}" + when: primaryDeviceNeedSync + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/sync_storage.yml" + when: primaryDeviceNeedSync + + - set_fact: + deviceSynced: "{{ deviceSynced + [primaryDeviceName] }}" + when: primaryDeviceNeedSync + + - name: Final_Step_1_2 - Sync Metro Device + debug: + msg: + device: "{{ metroDeviceName }}" + when: + - metroDeviceNeedSync + + - set_fact: + deviceName: "{{ metroDeviceName }}" + when: + - metroDeviceNeedSync + - metroDeviceName not in deviceSynced + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/sync_storage.yml" + when: + - metroDeviceNeedSync + - metroDeviceName not in deviceSynced + + - set_fact: + deviceSynced: "{{ deviceSynced + [metroDeviceName] }}" + when: + - metroDeviceNeedSync + - metroDeviceName not in deviceSynced + + - name: Final_Step_1_3 - Sync DR Device + debug: + msg: + device: "{{ drDeviceName }}" + when: + - remoteDeviceNeedSync + + - set_fact: + deviceName: "{{ drDeviceName }}" + when: + - remoteDeviceNeedSync + - drDeviceName not in deviceSynced + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/sync_storage.yml" + when: + - remoteDeviceNeedSync + - drDeviceName not in deviceSynced + + - set_fact: + deviceSynced: "{{ deviceSynced + [drDeviceName] }}" + when: + - remoteDeviceNeedSync + - drDeviceName not in deviceSynced + + # End Final Steps + + # End Always Block + + # End Workflow + + - block: + + # Begin Validate Results + + - name: Result_1_3 - Create Primary Protection Group + debug: + msg: + params: + pg: "{{ primaryPgName }}" + device: "{{ primaryDeviceName }}" + result: + succeeded: "{{ Step_1_3_Completed }}" + rollbacked: "{{ Step_1_3_Rollbacked }}" + failed_when: Step_1_3_Completed|bool == False + when: Step_1_3_Execute + + - name: Result_2_3 - Create Metro Protection Group + debug: + msg: + params: + pg: "{{ primaryPgName }}" + device: "{{ metroDeviceName }}" + result: + succeeded: "{{ Step_2_3_Completed }}" + rollbacked: "{{ Step_2_3_Rollbacked }}" + failed_when: Step_2_3_Completed|bool == False + when: Step_2_3_Execute + + - name: Result_2_4 - Create HyperMetro CG + debug: + msg: + params: + device: "{{ primaryDeviceName }}" + remote: "{{ metroDeviceName }}" + cg: "{{ metroCgName }}" + pg: + local: + name: "{{ primaryPgName }}" + id: "{{ primaryPgId }}" + remote: + name: "{{ primaryPgName }}" + id: "{{ metroPgId }}" + result: + succeeded: "{{ Step_2_4_Completed }}" + rollbacked: "{{ Step_2_4_Rollbacked }}" + failed_when: Step_2_4_Completed|bool == False + when: Step_2_4_Execute + + - name: Result_3_3 - Create DR Protection Group + debug: + msg: + params: + pg: "{{ drPgName }}" + result: + succeeded: "{{ Step_3_3_Completed }}" + rollbacked: "{{ Step_3_3_Rollbacked }}" + failed_when: Step_3_3_Completed|bool == False + when: Step_3_3_Execute + + - name: Result_3_4 - Create Replication CG + debug: + msg: + params: + device: "{{ primaryDeviceName }}" + remote: "{{ drDeviceName }}" + cg: "{{ drCgName }}" + pg: + local: + name: "{{ primaryPgName }}" + id: "{{ primaryPgId }}" + remote: + name: "{{ drPgName }}" + id: "{{ drPgId }}" + result: + succeeded: "{{ Step_3_4_Completed }}" + rollbacked: "{{ Step_3_4_Rollbacked }}" + failed_when: Step_3_4_Completed|bool == False + when: Step_3_4_Execute + + - name: Result_3_5 - Create Standby Replication CG + debug: + msg: + params: + device: "{{ metroDeviceName }}" + remote: "{{ drDeviceName }}" + cg: "{{ standbyCgName }}" + pg: + local: + name: "{{ primaryPgName }}" + id: "{{ metroPgId }}" + remote: + name: "{{ drPgName }}" + id: "{{ drPgId }}" + result: + succeeded: "{{ Step_3_5_Completed }}" + rollbacked: "{{ Step_3_5_Rollbacked }}" + failed_when: Step_3_5_Completed|bool == False + when: Step_3_5_Execute + + - name: Synced Device + debug: + msg: + synced: "{{ deviceSynced }}" + # End Validate Results + + # End Block + + # End Tasks + +# End Playbook \ No newline at end of file diff --git a/rundeck/workflow/project001/50_add_luns_to_pg.yml b/rundeck/workflow/project001/50_add_luns_to_pg.yml new file mode 100644 index 0000000..be86dfd --- /dev/null +++ b/rundeck/workflow/project001/50_add_luns_to_pg.yml @@ -0,0 +1,3381 @@ +- name: Add LUNs For Protection Group + hosts: localhost + vars_files: + - ../../../config/global.yml + - ../../../config/project001.yml + gather_facts: no + become: no + tasks: + # Check Params + - block: + - set_fact: + create_lun_params_exists: "{{ (LUN_Size is not none) and (LUN_Num is not none) }}" + select_lun_params_exists: "{{ Select_LUN is not none }}" + + - set_fact: + checked_params: + Host: "{{ Host is not none and Host != DEFAULT.noneValue }}" + Storage: "{{ (Storage is not none and Storage != DEFAULT.noneValue) and (Storage|string|length == 20) }}" + Select_LUN: "{{ create_lun_params_exists or (select_lun_params_exists and (Select_LUN|string).split(',')|length >= 1) }}" + LUN_Size: "{{ select_lun_params_exists or ((LUN_Size is not none) and (LUN_Size|int >= 1)) }}" + LUN_Num: "{{ select_lun_params_exists or ((LUN_Num is not none) and (LUN_Num|int >= 1)) }}" + LUN_Description: "{{ select_lun_params_exists or ((LUN_Description is none) or (LUN_Description|string|length <= 255)) }}" + Class_1: "{{ Class_1 in ['A','B','C','D'] }}" + Designate_Class_1: "{{ (Designate_Class_1 is none) or (Designate_Class_1 in ['A','B','C','D']) }}" + Check_Result_1: "{{ ('lun' in Check_Result_1) or ('select_lun' in Check_Result_1)}}" + + - name: Precheck_0_1 - Check Params + debug: + msg: "{{checked_params}}" + failed_when: checked_params.values()|unique != [True] + + # Check Metro Params + - block: + - set_fact: + checked_metro_params: + Metro_Host: "{{ Metro_Host is not none and Metro_Host != DEFAULT.noneValue }}" + Metro_Storage: "{{ (Metro_Storage is not none and Metro_Storage != DEFAULT.noneValue) and (Metro_Storage|string|length == 20) }}" + Check_Result_2: "{{ ('lun' in Check_Result_2) }}" + + - name: Precheck_0_2 - Check Metro Params + debug: + msg: "{{checked_metro_params}}" + failed_when: checked_metro_params.values()|unique != [True] + + when: Enable_HyperMetro == 'Y' + + # Check DR Params + - block: + - set_fact: + checked_dr_params: + DR_Host: "{{ DR_Host is not none and DR_Host != DEFAULT.noneValue }}" + DR_Storage: "{{ (DR_Storage is not none and DR_Storage != DEFAULT.noneValue) and (DR_Storage|string|length == 20) }}" + Class_2: "{{ Class_2 in ['A','B','C','D'] }}" + Designate_Class_2: "{{ (Designate_Class_2 is none) or (Designate_Class_2 in ['A','B','C','D']) }}" + Check_Result_3: "{{ ('lun' in Check_Result_3) }}" + + - name: Precheck_0_3 - Check DR Params + debug: + msg: "{{checked_dr_params}}" + failed_when: checked_dr_params.values()|unique != [True] + + when: Protection_Level|int >= 2 + + # Check DR Test Params + - block: + - set_fact: + checked_drtest_params: + DR_Test_Host: "{{ DR_Test_Host is not none and DR_Test_Host != DEFAULT.noneValue }}" + Class_3: "{{ Class_3 in ['A','B','C','D'] }}" + Designate_Class_3: "{{ (Designate_Class_3 is none) or (Designate_Class_3 in ['A','B','C','D']) }}" + Check_Result_4: "{{ ('lun' in Check_Result_4) }}" + + - name: Precheck_0_4 - Check DR Test Params + debug: + msg: "{{checked_drtest_params}}" + failed_when: checked_drtest_params.values()|unique != [True] + + when: Protection_Level|int == 3 + + - set_fact: + WBE_CODE: "{{ WBE_CODE }}" + TICKET_NUMBER: "{{ TICKET_NUMBER }}" + osType: "{{ Host.split('_')[1] }}" + createLunSize: "{{ LUN_Size }}" + createLunNum: "{{ LUN_Num|default(0)|int }}" + createLunRemarks: "{{ LUN_Description|string if (LUN_Description is not none) else '' }}" + createPoolId: "{{ Pool }}" + createWorkload: "{{ Workload }}" + selectedLunNames: "{{ (Select_LUN|string).split(',') | sort if Select_LUN is not none else [] }}" + selectedLunNum: "{{ (Select_LUN|string).split(',')|length if Select_LUN is not none else 0 }}" + primaryDeviceSn: "{{ Storage|string }}" + primaryRoom: "{{ Storage_Room }}" + primarySite: "{{ AZ[Storage_Room]['dc'] }}" + primaryHostName: "{{ Host }}" + primaryLgName: "{{ LUN_Group }}" + primaryLg00Name: "{{ Host }}_LG00" + primaryLg00Desc: "{{ Enable_HyperMetro }}{{ Protection_Level }}{{ Class_1 }}{{ Class_2 if Protection_Level|int >= 2 else '0' }}{{Class_3 if Protection_Level|int >= 3 else '0'}}_{{ Session_Name }}" + primaryPgName: "{{ Protection_Group }}" + + - set_fact: + metroEnable: "{{ Enable_HyperMetro }}" + metroHostName: "{{ Metro_Host }}" + metroDeviceSn: "{{ Metro_Storage|string }}" + metroRoom: "{{ Metro_Storage_Room }}" + metroSite: "{{ AZ[Metro_Storage_Room]['dc'] }}" + metroPoolId: "{{ Metro_Pool }}" + metroWorkload: "{{ Metro_Workload }}" + metroCgName: "{{ Metro_CG }}" + metroCgId: "{{ Metro_CG_ID }}" + sessionName: "{{ Session_Name }}" + protectLevel: "{{ Protection_Level }}" + class1: "{{ Designate_Class_1 if (Designate_Class_1 is not none) else Class_1 }}" + class2: "{{ Designate_Class_2 if (Designate_Class_2 is not none) else Class_2 }}" + class3: "{{ Designate_Class_3 if (Designate_Class_3 is not none) else Class_3 }}" + drCgName: "{{ DR_CG }}" + drCgMode: "{{ DR_Mode }}" + drCgModeEnum: "{{ DR_Mode_Enum }}" + drDevId: "{{ DR_Storage_ID }}" + drDeviceSn: "{{ DR_Storage|string }}" + drRoom: "{{ DR_Storage_Room }}" + drSite: "{{ AZ[DR_Storage_Room]['dc'] }}" + drHostName: "{{ DR_Host }}" + drPoolId: "{{ DR_Pool }}" + drWorkload: "{{ DR_Workload }}" + drLgName: "{{ DR_LUN_Group }}" + drLg00Name: "{{ DR_Host }}_LG00" + drLg00Desc: "N{{ Protection_Level }}{{ Class_1 }}{{Class_2}}{{Class_3 if Protection_Level|int >= 3 else '0'}}_{{ Session_Name }}" + drPgName: "{{ DR_Protection_Group }}" + drTestHostName: "{{ DR_Test_Host }}" + drTestLgName: "{{ DR_Test_LUN_Group }}" + drTestLg00Name: "{{ DR_Test_Host }}_LG00" + drStarCgName: "{{ DR_Star if (DR_Star is not none and DR_Star != DEFAULT.noneValue) else '' }}" + standbyCgName: "{{ Standby_CG }}" + standbyCgId: "{{ Standby_CG_ID }}" + + - set_fact: + minScsiId: "{{ OSTYPE[osType]['min_scsi_id'] }}" # See ../../config/project001.yml + protectType: "{{ REPTYPE[metroEnable+protectLevel|string]['enum'] }}" # See ../../config/project001.yml + replicaType: "{{ REPTYPE[metroEnable+protectLevel|string]['type'] }}" # See ../../config/project001.yml + + - set_fact: + lunNameTemplate: "%s%0{{DEFAULT.suffixDigits}}d_%s" + primaryLunPrefix: "{{primaryHostName}}_{{protectType}}{{'S' if metroEnable == 'Y' else 'N'}}" + primaryLunSuffix: "{{ class1 }}_00_{{replicaType}}_{{'00' if replicaType == '00' else primaryRoom}}_{{'0000000000000000' if replicaType == '00' else sessionName}}_{{'0' if replicaType == '00' else protectType}}1" + metroLunPrefix: "{{metroHostName}}_{{protectType}}M" + metroLunSuffix: "{{ class1 }}_00_{{replicaType}}_{{primaryRoom}}_{{sessionName}}_{{protectType}}1" + drLunPrefix: "{{drHostName}}_{{protectType}}N" + drLunSuffix: "{{ class2 }}_00_{{replicaType}}_{{primaryRoom}}_{{sessionName}}_{{protectType}}2" + drTestLunPrefix: "{{drTestHostName}}_{{protectType}}N" + drTestLunSuffix: "{{ class3 }}_00_00_{{primaryRoom}}_{{sessionName}}_{{protectType}}3" + drTestCgNameDefault: "{{ replicaType }}_{{ primaryRoom }}_{{ sessionName }}_{{ protectType }}3" + drStarCgNameDefault: "{{ replicaType }}_{{ primaryRoom }}_{{ sessionName }}_{{ protectType }}0" + + - set_fact: + drTestCgName: "{{ DR_Test_CG if (DR_Test_CG is not none and DR_Test_CG != DEFAULT.noneValue) else drTestCgNameDefault }}" + drTestCgId: "{{ DR_Test_CG_ID }}" + drTestCgActivated: "{{ (DR_Test_CG_Status == SNAPCG.activated.enum) if (DR_Test_CG_Status is not none and DR_Test_CG_Status != DEFAULT.noneValue) else False }}" + drTestCgExists: "{{ True if (DR_Test_CG is not none and DR_Test_CG != DEFAULT.noneValue) else False }}" + + - set_fact: + Precheck_1_Execute: True + Precheck_2_Execute: "{{ (metroEnable == 'Y') }}" + Precheck_3_Execute: "{{ (protectLevel|int >= 2) }}" + Precheck_4_Execute: "{{ (protectLevel|int == 3) }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/user/login.yml" + + - block: + - name: Precheck_1 - Check Primary Host + debug: + msg: + host: "{{ primaryHostName }}" + device: "{{ primaryDeviceSn }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/host/check_hosts.yml" + vars: + hostNames: ["{{ primaryHostName }}"] + + - name: Login Device + set_fact: + deviceSn: "{{ primaryDeviceSn }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/login_storage.yml" + + - set_fact: + primaryDeviceName: "{{ deviceName }}" + primaryDeviceHost: "{{ deviceHost }}" + primaryDevicePort: "{{ devicePort }}" + primaryDeviceToken: "{{ deviceToken }}" + primaryDeviceSession: "{{ deviceSession }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_hosts.yml" + vars: + hostNames: ["{{ primaryHostName }}"] + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_host_lun_id.yml" + vars: + hostName: "{{ primaryHostName }}" + + - block: + - set_fact: + currentMaxScsiId: "{{ minScsiId|int - 1 }}" + placeholderScsiIds: "{{ OSTYPE[osType]['placeholder_scsi_id'] }}" + + - set_fact: + currentMaxScsiId: "{{ item|int }}" + when: + - currentMaxScsiId|int < item|int + - item|int not in placeholderScsiIds + with_items: "{{ checkedHostLunIds }}" + + - set_fact: + nextScsiId: "{{ currentMaxScsiId|int + 1 }}" + lastScsiId: "{{ currentMaxScsiId|int + createLunNum|int + selectedLunNum|int }}" + when: Start_SCSI_ID|default(none) is none + + - block: + - set_fact: + nextScsiId: "{{ Start_SCSI_ID|int }}" + lastScsiId: "{{ Start_SCSI_ID|int + createLunNum|int + selectedLunNum|int - 1 }}" + + - name: Check Host SCSI IDs Conflicts + fail: + msg: "SCSI ID {{ item|int }} is occupied" + when: item|int >= nextScsiId|int and item|int <= lastScsiId|int + with_items: "{{ checkedHostLunIds }}" + + when: Start_SCSI_ID|default(none) is not none + + - set_fact: + createLunNames: [] + createLunIds: [] + createLunDescs: [] + createLunsSector: [] + selectedLuns: [] + selectedLunIds: [] + selectedLunsClass: [] + selectedLunNamesNew: [] + selectedLunDescs: [] + selectedLunsSector: [] + primaryLunNames: [] + primaryLunIds: [] + primaryLunDescs: [] + primaryLunsSector: [] + primaryLunsInTier: [] + primaryLunsInTierClass: [] + primaryLunsNotInTier: [] + createNextScsiId: "{{ nextScsiId|int }}" + createLastScsiId: "{{ nextScsiId|int + createLunNum|int - 1 }}" + selectedNextScsiId: "{{ nextScsiId|int + createLunNum|int }}" + selectedLastScsiId: "{{ lastScsiId|int }}" + + - block: + - set_fact: + createLunNames: "{{ createLunNames + [ lunNameTemplate | format(primaryLunPrefix, (createNextScsiId|int + item|int), primaryLunSuffix) ] }}" + createLunDescs: "{{ createLunDescs + [ createLunRemarks ] }}" + createLunsSector: "{{ createLunsSector + [ createLunSize|int * 1024 * 1024 * 2 ] }}" + with_sequence: start=0 count="{{createLunNum}}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_luns.yml" + vars: + lunNames: "{{ createLunNames }}" + checkExist: False + + when: create_lun_params_exists + + - block: + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_luns.yml" + vars: + lunNames: "{{ selectedLunNames }}" + + - set_fact: + selectedLuns: "{{ checkedLuns }}" + selectedLunIds: "{{ lunIds }}" + selectedLunDescs: "{{ checkedLuns | json_query('[*].DESCRIPTION') }}" + selectedLunsSector: "{{ checkedLuns | json_query('[*].CAPACITY') }}" + + - set_fact: + selectedLunNamesNew: "{{ selectedLunNamesNew + [ lunNameTemplate | format(primaryLunPrefix, (selectedNextScsiId|int + item.0), primaryLunSuffix) ] }}" + with_indexed_items: "{{ selectedLunNames }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_luns.yml" + vars: + lunNames: "{{ selectedLunNamesNew }}" + checkExist: False + + - import_tasks: "{{GLOBAL.baseDir}}/task/volume/check_volumes.yml" + vars: + volumeNames: "{{ selectedLunNames }}" + + - set_fact: + selectedLunsClass: "{{ selectedLunsClass + [ checkedVolumes[item.0].service_level_name ] }}" + with_indexed_items: "{{ selectedLunNames }}" + + - set_fact: + primaryLunsInTier: "{{ checkedVolumes | json_query(queryVolumesInTier) }}" + primaryLunsInTierClass: "{{ checkedVolumes | json_query(queryVolumesInTierClass) }}" + primaryLunsNotInTier: "{{ checkedVolumes | json_query(queryVolumesNotInTier) }}" + vars: + queryVolumesInTier: "[? service_level_name != '' && service_level_name != null ].name" + queryVolumesInTierClass: "[? service_level_name != '' && service_level_name != null ].service_level_name" + queryVolumesNotInTier: "[? service_level_name == '' || service_level_name == null ].name" + + when: select_lun_params_exists + + - set_fact: + primaryLunIds: "{{ createLunIds + selectedLunIds }}" + primaryLunNames: "{{ createLunNames + selectedLunNamesNew }}" + primaryLunDescs: "{{ createLunDescs + selectedLunDescs }}" + primaryLunsSector: "{{ createLunsSector + selectedLunsSector }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_lgs.yml" + vars: + lgNames: ["{{ primaryLgName }}", "{{ primaryLg00Name }}"] + + # End Precheck_1 + when: Precheck_1_Execute + + + - block: + - name: Precheck_2 - Check Metro Host + debug: + msg: + host: "{{ metroHostName }}" + device: "{{ metroDeviceSn }}" + + - name: Login Metro Device + set_fact: + deviceSn: "{{ metroDeviceSn }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/login_storage.yml" + + - set_fact: + metroDeviceName: "{{ deviceName }}" + metroDeviceHost: "{{ deviceHost }}" + metroDevicePort: "{{ devicePort }}" + metroDeviceToken: "{{ deviceToken }}" + metroDeviceSession: "{{ deviceSession }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_hosts.yml" + vars: + hostNames: ["{{ metroHostName }}"] + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_host_lun_id.yml" + vars: + hostName: "{{ metroHostName }}" + + - name: Check Metro Host SCSI IDs Conflicts + fail: + msg: "SCSI ID {{ item|int }} is occupied" + when: item|int >= nextScsiId|int and item|int <= lastScsiId|int + with_items: "{{ checkedHostLunIds }}" + + - set_fact: + metroLunNames: [] + + - set_fact: + metroLunNames: "{{ metroLunNames + [ lunNameTemplate | format(metroLunPrefix, (nextScsiId|int + item.0), metroLunSuffix) ] }}" + with_indexed_items: "{{ primaryLunNames }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_luns.yml" + vars: + lunNames: "{{ metroLunNames }}" + checkExist: False + + - block: + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/get_lgs_by_host.yml" + vars: + hostName: "{{ primaryHostName }}" + + - set_fact: + metroLg00Exists: False + + - set_fact: + metroLg00Exists: True + when: item.lunGroupName|string == primaryLg00Name|string + with_items: "{{ checkedLgs }}" + + # End Precheck_2 + when: Precheck_2_Execute + + - block: + - name: Precheck_3 - Check DR Host + debug: + msg: + host: "{{ drHostName }}" + device: "{{ drDeviceSn }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/host/check_hosts.yml" + vars: + hostNames: ["{{ drHostName }}"] + + - name: Login DR Device + set_fact: + deviceSn: "{{ drDeviceSn }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/login_storage.yml" + + - set_fact: + drDeviceName: "{{ deviceName }}" + drDeviceHost: "{{ deviceHost }}" + drDevicePort: "{{ devicePort }}" + drDeviceToken: "{{ deviceToken }}" + drDeviceSession: "{{ deviceSession }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_hosts.yml" + vars: + hostNames: ["{{ drHostName }}"] + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_host_lun_id.yml" + vars: + hostName: "{{ drHostName }}" + + - name: Check DR Host SCSI IDs Conflicts + fail: + msg: "SCSI ID {{ item|int }} is occupied" + when: item|int >= nextScsiId|int and item|int <= lastScsiId|int + with_items: "{{ checkedHostLunIds }}" + + - set_fact: + drLunNames: [] + + - set_fact: + drLunNames: "{{ drLunNames + [ lunNameTemplate | format(drLunPrefix, (nextScsiId|int + item.0), drLunSuffix) ] }}" + with_indexed_items: "{{ primaryLunNames }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_luns.yml" + vars: + lunNames: "{{ drLunNames }}" + checkExist: False + + - block: + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/get_lgs_by_host.yml" + vars: + hostName: "{{ drHostName }}" + + - set_fact: + drLg00Exists: False + + - set_fact: + drLg00Exists: True + when: item.lunGroupName|string == drLg00Name|string + with_items: "{{ checkedLgs }}" + + # End Precheck_3 + when: Precheck_3_Execute + + + - block: + - name: Precheck_4 - Check DR Test Host + debug: + msg: + host: "{{ drTestHostName }}" + device: "{{ drDeviceSn }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_hosts.yml" + vars: + hostNames: ["{{ drTestHostName }}"] + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_host_lun_id.yml" + vars: + hostName: "{{ drTestHostName }}" + + - name: Check DR Test Host SCSI IDs Conflicts + fail: + msg: "SCSI ID {{ item|int }} is occupied" + when: item|int >= nextScsiId|int and item|int <= lastScsiId|int + with_items: "{{ checkedHostLunIds }}" + + - set_fact: + drTestLunNames: [] + drTestLg00Exists: "{{ True if (drTestLg00Name in checkedLuns) else False }}" + + - set_fact: + drTestLunNames: "{{ drTestLunNames + [ lunNameTemplate | format(drTestLunPrefix, (nextScsiId|int + item.0), drTestLunSuffix) ] }}" + with_indexed_items: "{{ primaryLunNames }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_luns.yml" + vars: + lunNames: "{{ drTestLunNames }}" + checkExist: False + + # Check other snapshots in SCGs + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/get_snapshots_by_cg.yml" + vars: + cgName: "{{ drTestCgName }}" + + - set_fact: + existDrTestLunNames: "{{ checkedSnapshots|json_query('[*].NAME') }}" + existDrTestLunsDescs: "{{ checkedSnapshots|json_query('[*].DESCRIPTION') }}" + existDrTestLunsId: "{{ checkedSnapshots|json_query('[*].ID') }}" + drTestHostNamesAll: [] + + - set_fact: + drTestHostNamesAll: "{{ drTestHostNamesAll + [ hostName ] }}" + vars: + hostName: "{% set field = item.split('_') %}{% set output = field[:4] %}{{'_'.join(output)}}" + with_items: + - "{{ existDrTestLunNames }}" + + - set_fact: + drTestHostNamesAll: "{{ drTestHostNamesAll | unique }}" + checkedHostLuns: [] + + - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_host_lun_id_loop_helper.yml" + vars: + hostName: "{{ name }}" + loop: "{{ drTestHostNamesAll }}" + loop_control: + loop_var: name + + - set_fact: + existDrTestLuns: [] + + - include_tasks: "{{GLOBAL.baseDir}}/rundeck/workflow/project001/loop_helper/50_exsit_dr_test_luns_loop_helper.yml" + vars: + drTestLun: "{{ checkedSnapshot }}" + loop: "{{ checkedSnapshots }}" + loop_control: + loop_var: checkedSnapshot + + # End Precheck_4 + when: Precheck_4_Execute + + + - block: + + # Begin Workflow Steps + + - set_fact: + + # Create Primary LUNs + Step_1_1_Execute: "{{ create_lun_params_exists }}" + Step_1_1_Completed: False + Step_1_1_Rollbacked: False + + # Modify Selected LUNs + Step_1_1_1_Execute: "{{ select_lun_params_exists }}" + Step_1_1_1_Completed: False + Step_1_1_1_Rollbacked: False + + # Add Primary LUNs to Protection Group + Step_1_1_2_Execute: "{{ True }}" + Step_1_1_2_Completed: False + Step_1_1_2_Rollbacked: False + + # Add Primary LUNs to LUN Group + Step_1_1_3_Execute: "{{ True }}" + Step_1_1_3_Completed: False + Step_1_1_3_Rollbacked: False + + # Disable DR Star + Step_1_2_Execute: "{{ (protectLevel|int >= 2) and (metroEnable == 'Y') and (drStarCgName != '') }}" + Step_1_2_Completed: False + Step_1_2_Rollbacked: False + + # Create Metro LUNs + Step_2_1_Execute: "{{ (metroEnable == 'Y') }}" + Step_2_1_Completed: False + Step_2_1_Rollbacked: False + + # Add Metro LUNs to Protection Group + Step_2_1_1_Execute: "{{ metroEnable == 'Y' }}" + Step_2_1_1_Completed: False + Step_2_1_1_Rollbacked: False + + # Create Metro Pairs + Step_2_2_Execute: "{{ (metroEnable == 'Y') }}" + Step_2_2_Completed: False + Step_2_2_Rollbacked: False + + # Create LUN Group for Metro Host + Step_2_3_0_Execute: "{{ (metroEnable == 'Y') and (metroLg00Exists|bool == False) }}" + Step_2_3_0_Completed: False + Step_2_3_0_Rollbacked: False + + # Add Metro LUNs to LUN Group + Step_2_3_Execute: "{{ (metroEnable == 'Y') }}" + Step_2_3_Completed: False + Step_2_3_Rollbacked: False + + # Add Metro Pairs to HyperMetro CG + Step_2_4_Execute: "{{ (metroEnable == 'Y') }}" + Step_2_4_Completed: False + Step_2_4_Rollbacked: False + + # Create DR LUNs + Step_3_1_Execute: "{{ (protectLevel|int >= 2) }}" + Step_3_1_Completed: False + Step_3_1_Rollbacked: False + + # Add DR LUNs to Protection Group + Step_3_1_1_Execute: "{{ (protectLevel|int >= 2) }}" + Step_3_1_1_Completed: False + Step_3_1_1_Rollbacked: False + + # Create DR Pairs + Step_3_2_Execute: "{{ (protectLevel|int >= 2) }}" + Step_3_2_Completed: False + Step_3_2_Rollbacked: False + + # Create Standby DR Pairs + Step_3_3_Execute: "{{ (protectLevel|int >= 2) and (metroEnable == 'Y') }}" + Step_3_3_Completed: False + Step_3_3_Rollbacked: False + + # Create LUN Group for DR Host + Step_3_3_1_Execute: "{{ (protectLevel|int >= 2) and (drLg00Exists|bool == False) }}" + Step_3_3_1_Completed: False + Step_3_3_1_Rollbacked: False + + # Add DR LUNs to LUN Group + Step_3_4_Execute: "{{ (protectLevel|int >= 2) }}" + Step_3_4_Completed: False + Step_3_4_Rollbacked: False + + # Add DR Pair to Replication CG + Step_3_5_Execute: "{{ (protectLevel|int >= 2) }}" + Step_3_5_Completed: False + Step_3_5_Rollbacked: False + + # Add Standby DR Pair to Standby Replication CG + Step_3_6_Execute: "{{ (protectLevel|int >= 2) and (metroEnable == 'Y') }}" + Step_3_6_Completed: False + Step_3_6_Rollbacked: False + + # Create DR Star + Step_3_7_Execute: "{{ (protectLevel|int >= 2) and (metroEnable == 'Y') and (drStarCgName == '') }}" + Step_3_7_Completed: False + Step_3_7_Rollbacked: False + + # Enable DR Star + Step_3_8_Execute: "{{ (protectLevel|int >= 2) and (metroEnable == 'Y') and (drStarCgName != '') }}" + Step_3_8_Completed: False + Step_3_8_Rollbacked: False + + # Create LUN Group for DR Test Host + Step_4_0_Execute: "{{ (protectLevel|int == 3) and (drTestLg00Exists|bool == False) }}" + Step_4_0_Completed: False + Step_4_0_Rollbacked: False + + # Remove Existing DR Test LUNs from LUN Group + Step_4_1_Execute: "{{ (protectLevel|int == 3) and (existDrTestLuns|length > 0) and (drTestCgActivated|bool == False) }}" + Step_4_1_Completed: False + Step_4_1_Rollbacked: False + + # Delete Existing DR Test Snapshot CG + Step_4_2_Execute: "{{ (protectLevel|int == 3) and (drTestCgExists|bool == True) and (drTestCgActivated|bool == False) }}" + Step_4_2_Completed: False + Step_4_2_Rollbacked: False + + # Create DR Test Snapshot CG + Step_4_3_Execute: "{{ (protectLevel|int == 3) and (drTestCgActivated|bool == False) }}" + Step_4_3_Completed: False + Step_4_3_Rollbacked: False + + # Add Existing DR Test LUNs to LUN Group + Step_4_4_Execute: "{{ (protectLevel|int == 3) and (existDrTestLuns|length > 0) and (drTestCgActivated|bool == False) }}" + Step_4_4_Completed: False + Step_4_4_Rollbacked: False + + # Add DR Test LUNs to LUN Group + Step_4_5_Execute: "{{ (protectLevel|int == 3) and (drTestCgActivated|bool == False) }}" + Step_4_5_Completed: False + Step_4_5_Rollbacked: False + + deviceSynced: [] + + # Set Class for Primary LUNs + Step_5_1_Execute: True + Step_5_1_Completed: False + Step_5_1_Rollbacked: False + + # Set Class for Metro LUNs + Step_5_2_Execute: "{{ (metroEnable == 'Y') }}" + Step_5_2_Completed: False + Step_5_2_Rollbacked: False + + # Set Class for DR LUNs + Step_5_3_Execute: "{{ (protectLevel|int >= 2) }}" + Step_5_3_Completed: False + Step_5_3_Rollbacked: False + + # Insert Primary LUNs to KPI table + Step_6_1_Execute: "{{ True }}" + Step_6_1_Completed: False + + # Insert Metro LUNs to KPI table + Step_6_2_Execute: "{{ (metroEnable == 'Y') }}" + Step_6_2_Completed: False + + # Insert DR LUNs to KPI table + Step_6_3_Execute: "{{ (protectLevel|int >= 2) }}" + Step_6_3_Completed: False + + # Insert DR Test LUNs to KPI table + Step_6_4_Execute: "{{ (protectLevel|int == 3) and (drTestCgActivated|bool == False) }}" + Step_6_4_Completed: False + + # Update Existing DR Test LUNs to KPI table + Step_6_5_Execute: "{{ (protectLevel|int == 3) and (existDrTestLuns|length > 0) and (drTestCgActivated|bool == False) }}" + Step_6_5_Completed: False + + - name: Workflow - Create LUNs for Host + debug: + msg: + Step_1_1: "[{{Step_1_1_Execute}}] Create Primary LUNs" + Step_1_1_1: "[{{Step_1_1_1_Execute}}] Modify Selected LUNs" + Step_1_1_2: "[{{Step_1_1_2_Execute}}] Add Primary LUNs to Protection Group" + Step_1_1_3: "[{{Step_1_1_3_Execute}}] Add Primary LUNs to LUN Group" + Step_1_2: "[{{Step_1_2_Execute}}] Disable DR Star" + Step_2_1: "[{{Step_2_1_Execute}}] Create Metro LUNs" + Step_2_1_1: "[{{Step_2_1_1_Execute}}] Add Metro LUNs to Protection Group" + Step_2_2: "[{{Step_2_2_Execute}}] Create Metro Pairs" + Step_2_3_0: "[{{Step_2_3_0_Execute}}] Create LUN Group for Metro Host" + Step_2_3: "[{{Step_2_3_Execute}}] Add Metro LUNs to LUN Group" + Step_2_4: "[{{Step_2_4_Execute}}] Add Metro Pairs to HyperMetro CG" + Step_3_1: "[{{Step_3_1_Execute}}] Create DR LUNs" + Step_3_1_1: "[{{Step_3_1_1_Execute}}] Add DR LUNs to Protection Group" + Step_3_2: "[{{Step_3_2_Execute}}] Create DR Pairs" + Step_3_3: "[{{Step_3_3_Execute}}] Create Standby DR Pairs" + Step_3_3_1: "[{{Step_3_3_1_Execute}}] Create LUN Group for DR Host" + Step_3_4: "[{{Step_3_4_Execute}}] Add DR LUNs to LUN Group" + Step_3_5: "[{{Step_3_5_Execute}}] Add DR Pair to Replication CG" + Step_3_6: "[{{Step_3_6_Execute}}] Add Standby DR Pair to Standby Replication CG" + Step_3_7: "[{{Step_3_7_Execute}}] Create DR Star" + Step_3_8: "[{{Step_3_8_Execute}}] Enable DR Star" + Step_4_0: "[{{Step_4_0_Execute}}] Create LUN Group for DR Test Host" + Step_4_1: "[{{Step_4_1_Execute}}] Remove Existing DR Test LUNs from LUN Group" + Step_4_2: "[{{Step_4_2_Execute}}] Delete Existing DR Test Snapshot CG" + Step_4_3: "[{{Step_4_3_Execute}}] Create DR Test Snapshot CG" + Step_4_4: "[{{Step_4_4_Execute}}] Add Existing DR Test LUNs to LUN Group" + Step_4_5: "[{{Step_4_5_Execute}}] Add DR Test LUNs to LUN Group" + Step_5_1: "[{{Step_5_1_Execute}}] Set Class for Primary LUNs" + Step_5_2: "[{{Step_5_2_Execute}}] Set Class for Metro LUNs" + Step_5_3: "[{{Step_5_3_Execute}}] Set Class for DR LUNs" + Step_6_1: "[{{Step_6_1_Execute}}] Insert Primary LUNs to KPI table" + Step_6_2: "[{{Step_6_2_Execute}}] Insert Metro LUNs to KPI table" + Step_6_3: "[{{Step_6_3_Execute}}] Insert DR LUNs to KPI table" + Step_6_4: "[{{Step_6_4_Execute}}] Insert DR Test LUNs to KPI table" + Step_6_5: "[{{Step_6_5_Execute}}] Update Existing DR Test LUNs to KPI table" + + - block: + - name: Step_1_1 - Create Primary LUNs + debug: + msg: + params: + luns: + lunSize: "{{ createLunSize }}" + newLunNames: "{{ createLunNames }}" + startScsiId: "{{ createNextScsiId }}" + poolId: "{{ createPoolId }}" + workload: "{{ createWorkload }}" + desc: "{{ createLunRemarks }}" + device: "{{ primaryDeviceName }}" + + - set_fact: + deviceHost: "{{ primaryDeviceHost }}" + devicePort: "{{ primaryDevicePort }}" + deviceSn: "{{ primaryDeviceSn }}" + deviceToken: "{{ primaryDeviceToken }}" + deviceSession: "{{ primaryDeviceSession }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/create_luns.yml" + vars: + lunSize: "{{ createLunSize }}" + newLunNames: "{{ createLunNames }}" + startScsiId: "{{ createNextScsiId }}" + poolId: "{{ createPoolId }}" + workload: "{{ createWorkload }}" + desc: "{{ createLunRemarks }}" + + - set_fact: + createLunIds: "{{ newLunIds }}" + primaryLunIds: "{{ newLunIds + selectedLunIds }}" + Step_1_1_Completed: True + + # End Step_1_1 + + # End block + when: Step_1_1_Execute + + - block: + - name: Step_1_1_1 - Modify Selected LUNs + debug: + msg: + params: + luns: + name: + old: "{{ selectedLunNames }}" + new: "{{ selectedLunNamesNew }}" + device: "{{ primaryDeviceName }}" + + - include_tasks: "{{GLOBAL.baseDir}}/task/volume/rename_volumes.yml" + vars: + volumeNames: "{{ selectedLunNames }}" + newVolumeNames: "{{ selectedLunNamesNew }}" + deviceSn: "{{ primaryDeviceSn }}" + + - set_fact: + Step_1_1_1_Completed: True + + # End Step_1_1_1 + + # End block + when: Step_1_1_1_Execute + + - block: + - name: Step_1_1_2 - Add Primary LUNs to Protection Group + debug: + msg: + params: + lun: + lunNames: "{{ primaryLunNames }}" + pgName: "{{ primaryPgName }}" + device: "{{ primaryDeviceName }}" + + - set_fact: + deviceHost: "{{ primaryDeviceHost }}" + devicePort: "{{ primaryDevicePort }}" + deviceSn: "{{ primaryDeviceSn }}" + deviceToken: "{{ primaryDeviceToken }}" + deviceSession: "{{ primaryDeviceSession }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/add_luns_to_pg.yml" + vars: + lunNames: "{{ primaryLunNames }}" + pgName: "{{ primaryPgName }}" + + - set_fact: + Step_1_1_2_Completed: True + + # End Step_1_1_2 + + # End block + when: Step_1_1_2_Execute + + - block: + - name: Step_1_1_3 - Add Primary LUNs to LUN Group + debug: + msg: + params: + lun: + lunNames: "{{ primaryLunNames }}" + lgName: "{{ primaryLg00Name }}" + startScsiId: "{{ nextScsiId }}" + device: "{{ primaryDeviceName }}" + + - set_fact: + deviceHost: "{{ primaryDeviceHost }}" + devicePort: "{{ primaryDevicePort }}" + deviceSn: "{{ primaryDeviceSn }}" + deviceToken: "{{ primaryDeviceToken }}" + deviceSession: "{{ primaryDeviceSession }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/add_luns_to_lg.yml" + vars: + lunNames: "{{ primaryLunNames }}" + lgName: "{{ primaryLg00Name }}" + startScsiId: "{{ nextScsiId }}" + + - set_fact: + Step_1_1_3_Completed: True + + # End Step_1_1_3 + + # End block + when: Step_1_1_3_Execute + + - block: + - name: Step_1_2 - Disable DR Star + debug: + msg: + params: + drStarName: "{{ drStarCgName }}" + device: "{{ primaryDeviceName }}" + + - set_fact: + deviceHost: "{{ primaryDeviceHost }}" + devicePort: "{{ primaryDevicePort }}" + deviceSn: "{{ primaryDeviceSn }}" + deviceToken: "{{ primaryDeviceToken }}" + deviceSession: "{{ primaryDeviceSession }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/disable_drstar.yml" + vars: + drStarName: "{{ drStarCgName }}" + + - set_fact: + Step_1_2_Completed: True + + # End Step_1_2 + + # End block + when: Step_1_2_Execute + + - block: + - name: Step_2_1 - Create Metro LUNs + debug: + msg: + params: + luns: + lunNames: "{{ metroLunNames }}" + lunDescs: "{{ primaryLunDescs }}" + poolId: "{{ metroPoolId }}" + workload: "{{ metroWorkload }}" + device: "{{ metroDeviceName }}" + + - set_fact: + deviceHost: "{{ metroDeviceHost }}" + devicePort: "{{ metroDevicePort }}" + deviceSn: "{{ metroDeviceSn }}" + deviceToken: "{{ metroDeviceToken }}" + deviceSession: "{{ metroDeviceSession }}" + + - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/create_lun.yml" + vars: + lunName: "{{ metroLunNames[i] }}" + lunSector: "{{ primaryLunsSector[i] }}" + poolId: "{{ metroPoolId }}" + workload: "{{ metroWorkload }}" + desc: "{{ primaryLunDescs[i] }}" + loop: "{{ range(0, metroLunNames|length) | list }}" + loop_control: + loop_var: i + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_luns.yml" + vars: + lunNames: "{{ metroLunNames }}" + + - set_fact: + metroLunIds: "{{ lunIds }}" + Step_2_1_Completed: True + + # End Step_2_1 + + # End block + when: Step_2_1_Execute + + - block: + - name: Step_2_1_1 - Add Metro LUNs to Protection Group + debug: + msg: + params: + lun: + lunNames: "{{ metroLunNames }}" + pgName: "{{ primaryPgName }}" + device: "{{ metroDeviceName }}" + + - set_fact: + deviceHost: "{{ metroDeviceHost }}" + devicePort: "{{ metroDevicePort }}" + deviceSn: "{{ metroDeviceSn }}" + deviceToken: "{{ metroDeviceToken }}" + deviceSession: "{{ metroDeviceSession }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/add_luns_to_pg.yml" + vars: + pgName: "{{ primaryPgName }}" + lunNames: "{{ metroLunNames }}" + + - set_fact: + Step_2_1_1_Completed: True + + # End Step_2_1_1 + + # End block + when: Step_2_1_1_Execute + + - block: + - name: Step_2_2 - Create Metro Pairs + debug: + msg: + params: + pairs: + localLunIds: "{{ primaryLunIds }}" + remoteLunIds: "{{ metroLunIds }}" + remoteSn: "{{ metroDeviceSn }}" + device: "{{ primaryDeviceName }}" + + - set_fact: + deviceHost: "{{ primaryDeviceHost }}" + devicePort: "{{ primaryDevicePort }}" + deviceSn: "{{ primaryDeviceSn }}" + deviceToken: "{{ primaryDeviceToken }}" + deviceSession: "{{ primaryDeviceSession }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/create_hypermetro_pairs.yml" + vars: + localLunIds: "{{ primaryLunIds }}" + remoteLunIds: "{{ metroLunIds }}" + remoteSn: "{{ metroDeviceSn }}" + + - set_fact: + Step_2_2_Completed: True + + # End Step_2_2 + + # End block + when: Step_2_2_Execute + + - block: + - name: Step_2_3_0 - Create LUN Group for Metro Host + debug: + msg: + params: + host: "{{ primaryHostName }}" + lg: "{{ primaryLg00Name }}" + desc: "{{ primaryLg00Desc }}" + device: "{{ metroDeviceName }}" + + - set_fact: + deviceHost: "{{ metroDeviceHost }}" + devicePort: "{{ metroDevicePort }}" + deviceSn: "{{ metroDeviceSn }}" + deviceToken: "{{ metroDeviceToken }}" + deviceSession: "{{ metroDeviceSession }}" + + # Set addLunIds to empty list for variable name duplicated issue. + - set_fact: + addLunIds: [] + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/create_lg.yml" + vars: + lgName: "{{ primaryLg00Name }}" + mapHostNames: ["{{ primaryHostName }}"] + desc: "{{ primaryLg00Desc }}" + + - set_fact: + metroLgId: "{{ newLgId }}" + Step_2_3_0_Completed: True + + # End Step_2_3_0 + + # End block + when: Step_2_3_0_Execute + + - block: + - name: Step_2_3 - Add Metro LUNs to LUN Group + debug: + msg: + params: + lunNames: "{{ metroLunNames }}" + lgName: "{{ primaryLg00Name }}" + startScsiId: "{{ nextScsiId }}" + device: "{{ metroDeviceName }}" + + - set_fact: + deviceHost: "{{ metroDeviceHost }}" + devicePort: "{{ metroDevicePort }}" + deviceSn: "{{ metroDeviceSn }}" + deviceToken: "{{ metroDeviceToken }}" + deviceSession: "{{ metroDeviceSession }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/add_luns_to_lg.yml" + vars: + lgName: "{{ primaryLg00Name }}" + lunNames: "{{ metroLunNames }}" + startScsiId: "{{ nextScsiId }}" + + - set_fact: + Step_2_3_Completed: True + + # End Step_2_3 + + # End block + when: Step_2_3_Execute + + - block: + - name: Step_2_4 - Add Metro Pairs to HyperMetro CG + debug: + msg: + params: + pairs: + localLunIds: "{{ primaryLunIds }}" + remoteLunIds: "{{ metroLunIds }}" + cgName: "{{ metroCgName }}" + device: "{{ primaryDeviceName }}" + + - set_fact: + deviceHost: "{{ primaryDeviceHost }}" + devicePort: "{{ primaryDevicePort }}" + deviceSn: "{{ primaryDeviceSn }}" + deviceToken: "{{ primaryDeviceToken }}" + deviceSession: "{{ primaryDeviceSession }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/add_luns_to_hypermetro_cg.yml" + vars: + cgName: "{{ metroCgName }}" + localLunIds: "{{ primaryLunIds }}" + remoteLunIds: "{{ metroLunIds }}" + waitSync: True + + - set_fact: + Step_2_4_Completed: True + + # End Step_2_4 + + # End block + when: Step_2_4_Execute + + - block: + - name: Step_3_1 - Create DR LUNs + debug: + msg: + params: + luns: + lunNames: "{{ drLunNames }}" + lunDescs: "{{ primaryLunDescs }}" + poolId: "{{ drPoolId }}" + workload: "{{ drWorkload }}" + device: "{{ drDeviceName }}" + + - set_fact: + deviceHost: "{{ drDeviceHost }}" + devicePort: "{{ drDevicePort }}" + deviceSn: "{{ drDeviceSn }}" + deviceToken: "{{ drDeviceToken }}" + deviceSession: "{{ drDeviceSession }}" + + - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/create_lun.yml" + vars: + lunName: "{{ drLunNames[i] }}" + lunSector: "{{ primaryLunsSector[i] }}" + poolId: "{{ drPoolId }}" + workload: "{{ drWorkload }}" + desc: "{{ primaryLunDescs[i] }}" + loop: "{{ range(0, drLunNames|length) | list }}" + loop_control: + loop_var: i + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_luns.yml" + vars: + lunNames: "{{ drLunNames }}" + + - set_fact: + drLunIds: "{{ lunIds }}" + Step_3_1_Completed: True + + # End Step_3_1 + + # End block + when: Step_3_1_Execute + + - block: + - name: Step_3_1_1 - Add DR LUNs to Protection Group + debug: + msg: + params: + lunNames: "{{ drLunNames }}" + lunIds: "{{ drLunIds }}" + pgName: "{{ drPgName }}" + device: "{{ drDeviceName }}" + + - set_fact: + deviceHost: "{{ drDeviceHost }}" + devicePort: "{{ drDevicePort }}" + deviceSn: "{{ drDeviceSn }}" + deviceToken: "{{ drDeviceToken }}" + deviceSession: "{{ drDeviceSession }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/add_luns_to_pg.yml" + vars: + pgName: "{{ drPgName }}" + lunNames: "{{ drLunNames }}" + + - set_fact: + Step_3_1_1_Completed: True + + # End Step_3_1_1 + + # End block + when: Step_3_1_1_Execute + + - block: + - name: Step_3_2 - Create DR Pairs + debug: + msg: + params: + pairs: + localLunIds: "{{ primaryLunIds }}" + remoteLunIds: "{{ drLunIds }}" + remoteSn: "{{ drDeviceSn }}" + mode: "{{ drCgModeEnum }}" + device: "{{ primaryDeviceName }}" + + - set_fact: + deviceHost: "{{ primaryDeviceHost }}" + devicePort: "{{ primaryDevicePort }}" + deviceSn: "{{ primaryDeviceSn }}" + deviceToken: "{{ primaryDeviceToken }}" + deviceSession: "{{ primaryDeviceSession }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/create_replication_pairs.yml" + vars: + localLunIds: "{{ primaryLunIds }}" + remoteLunIds: "{{ drLunIds }}" + remoteSn: "{{ drDeviceSn }}" + mode: "{{ drCgModeEnum }}" + + - set_fact: + Step_3_2_Completed: True + + # End Step_3_2 + + # End block + when: Step_3_2_Execute + + - block: + - name: Step_3_3 - Create Standby DR Pairs + debug: + msg: + params: + pairs: + localLunIds: "{{ metroLunIds }}" + remoteLunIds: "{{ drLunIds }}" + remoteSn: "{{ drDeviceSn }}" + mode: "{{ GLOBAL.replication.syncMode.async }}" + standby: True + device: "{{ metroDeviceName }}" + + - set_fact: + deviceHost: "{{ metroDeviceHost }}" + devicePort: "{{ metroDevicePort }}" + deviceSn: "{{ metroDeviceSn }}" + deviceToken: "{{ metroDeviceToken }}" + deviceSession: "{{ metroDeviceSession }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/create_replication_pairs.yml" + vars: + localLunIds: "{{ metroLunIds }}" + remoteLunIds: "{{ drLunIds }}" + remoteSn: "{{ drDeviceSn }}" + mode: "{{ GLOBAL.replication.syncMode.async }}" + standby: True + + - set_fact: + Step_3_3_Completed: True + + # End Step_3_3 + + # End block + when: Step_3_3_Execute + + - block: + - name: Step_3_3_1 - Create LUN Group for DR Host + debug: + msg: + params: + host: "{{ drHostName }}" + lg: "{{ drLg00Name }}" + desc: "{{ drLg00Desc }}" + device: "{{ drDeviceName }}" + + - set_fact: + deviceHost: "{{ drDeviceHost }}" + devicePort: "{{ drDevicePort }}" + deviceSn: "{{ drDeviceSn }}" + deviceToken: "{{ drDeviceToken }}" + deviceSession: "{{ drDeviceSession }}" + + # Set addLunIds to empty list for variable name duplicated issue. + - set_fact: + addLunIds: [] + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/create_lg.yml" + vars: + lgName: "{{ drLg00Name }}" + mapHostNames: ["{{ drHostName }}"] + desc: "{{ drLg00Desc }}" + + - set_fact: + drLgId: "{{ newLgId }}" + Step_3_3_1_Completed: True + + # End Step_3_3_1 + + # End block + when: Step_3_3_1_Execute + + - block: + - name: Step_3_4 - Add DR LUNs to LUN Group + debug: + msg: + params: + lunNames: "{{ drLunNames }}" + lgName: "{{ drLg00Name }}" + startScsiId: "{{ nextScsiId }}" + device: "{{ drDeviceName }}" + + - set_fact: + deviceHost: "{{ drDeviceHost }}" + devicePort: "{{ drDevicePort }}" + deviceSn: "{{ drDeviceSn }}" + deviceToken: "{{ drDeviceToken }}" + deviceSession: "{{ drDeviceSession }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/add_luns_to_lg.yml" + vars: + lgName: "{{ drLg00Name }}" + lunNames: "{{ drLunNames }}" + startScsiId: "{{ nextScsiId }}" + + - set_fact: + Step_3_4_Completed: True + + # End Step_3_4 + + # End block + when: Step_3_4_Execute + + - block: + - name: Step_3_5 - Add DR Pairs to Replication CG + debug: + msg: + params: + pairs: + localLunIds: "{{ primaryLunIds }}" + remoteLunIds: "{{ drLunIds }}" + cgName: "{{ drCgName }}" + device: "{{ primaryDeviceName }}" + + - set_fact: + deviceHost: "{{ primaryDeviceHost }}" + devicePort: "{{ primaryDevicePort }}" + deviceSn: "{{ primaryDeviceSn }}" + deviceToken: "{{ primaryDeviceToken }}" + deviceSession: "{{ primaryDeviceSession }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/add_luns_to_replication_cg.yml" + vars: + cgName: "{{ drCgName }}" + localLunIds: "{{ primaryLunIds }}" + remoteLunIds: "{{ drLunIds }}" + waitSync: True + + - set_fact: + Step_3_5_Completed: True + + # End Step_3_5 + + # End block + when: Step_3_5_Execute + + - block: + - name: Step_3_6 - Add Standby DR Pairs to Standby Replication CG + debug: + msg: + params: + pairs: + localLunIds: "{{ metroLunIds }}" + remoteLunIds: "{{ drLunIds }}" + standby: True + cgName: "{{ standbyCgName }}" + device: "{{ metroDeviceName }}" + + - set_fact: + deviceHost: "{{ metroDeviceHost }}" + devicePort: "{{ metroDevicePort }}" + deviceSn: "{{ metroDeviceSn }}" + deviceToken: "{{ metroDeviceToken }}" + deviceSession: "{{ metroDeviceSession }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/add_luns_to_replication_cg.yml" + vars: + cgName: "{{ standbyCgName }}" + localLunIds: "{{ metroLunIds }}" + remoteLunIds: "{{ drLunIds }}" + standby: True + + - set_fact: + Step_3_6_Completed: True + + # End Step_3_6 + + # End block + when: Step_3_6_Execute + + - block: + - name: Step_3_7 - Create DR Star + debug: + msg: + params: + drstar: + drStarName: "{{ drStarCgNameDefault }}" + mode: 1 # HyperMetro + Async Replication + memberType: 2 # CG + metroId: "{{ metroCgId }}" + asyncId: "{{ standbyCgId }}" + device: "{{ metroDeviceName }}" + + - set_fact: + deviceHost: "{{ metroDeviceHost }}" + devicePort: "{{ metroDevicePort }}" + deviceSn: "{{ metroDeviceSn }}" + deviceToken: "{{ metroDeviceToken }}" + deviceSession: "{{ metroDeviceSession }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/create_drstar.yml" + vars: + drStarName: "{{ drStarCgNameDefault }}" + mode: 1 # HyperMetro + Async Replication + memberType: 2 # CG + metroId: "{{ metroCgId }}" + asyncId: "{{ standbyCgId }}" + + - set_fact: + Step_3_7_Completed: True + + # End Step_3_7 + + # End block + when: Step_3_7_Execute + + - block: + - name: Step_3_8 - Enable DR Star + debug: + msg: + params: + drStarName: "{{ drStarCgName }}" + device: "{{ primaryDeviceName }}" + + - set_fact: + deviceHost: "{{ primaryDeviceHost }}" + devicePort: "{{ primaryDevicePort }}" + deviceSn: "{{ primaryDeviceSn }}" + deviceToken: "{{ primaryDeviceToken }}" + deviceSession: "{{ primaryDeviceSession }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/enable_drstar.yml" + vars: + drStarName: "{{ drStarCgName }}" + + - set_fact: + Step_3_8_Completed: True + + # End Step_3_8 + + # End block + when: Step_3_8_Execute + + - block: + - name: Step_4_0 - Create LUN Group for DR Test Host + debug: + msg: + params: + host: "{{ drTestHostName }}" + lg: "{{ drTestLg00Name }}" + desc: "{{ drLg00Desc }}" + device: "{{ drDeviceName }}" + + - set_fact: + deviceHost: "{{ drDeviceHost }}" + devicePort: "{{ drDevicePort }}" + deviceSn: "{{ drDeviceSn }}" + deviceToken: "{{ drDeviceToken }}" + deviceSession: "{{ drDeviceSession }}" + + # Set addLunIds to empty list for variable name duplicated issue. + - set_fact: + addLunIds: [] + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/create_lg.yml" + vars: + lgName: "{{ drTestLg00Name }}" + mapHostNames: ["{{ drTestHostName }}"] + desc: "{{ drLg00Desc }}" + + - set_fact: + drTestLgId: "{{ newLgId }}" + Step_4_0_Completed: True + + # End Step_4_0 + + # End block + when: Step_4_0_Execute + + - block: + - name: Step_4_1 - Remove Existing DR Test LUNs from LUN Group + debug: + msg: + params: + luns: "{{ existDrTestLuns }}" + device: "{{ drDeviceName }}" + + - set_fact: + deviceHost: "{{ drDeviceHost }}" + devicePort: "{{ drDevicePort }}" + deviceSn: "{{ drDeviceSn }}" + deviceToken: "{{ drDeviceToken }}" + deviceSession: "{{ drDeviceSession }}" + + - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/remove_luns_from_lg.yml" + vars: + lgName: "{{ existDrTestLun.lgName }}" + lunNames: ["{{ existDrTestLun.lunName }}"] + loop: "{{ existDrTestLuns }}" + loop_control: + loop_var: existDrTestLun + + - set_fact: + Step_4_1_Completed: True + + # End Step_4_1 + + # End block + when: Step_4_1_Execute + + - block: + - name: Step_4_2 - Delete Existing DR Test Snapshot CG + debug: + msg: + params: + cgName: "{{ drTestCgName }}" + device: "{{ drDeviceName }}" + + - set_fact: + deviceHost: "{{ drDeviceHost }}" + devicePort: "{{ drDevicePort }}" + deviceSn: "{{ drDeviceSn }}" + deviceToken: "{{ drDeviceToken }}" + deviceSession: "{{ drDeviceSession }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/delete_snapshot_cg.yml" + vars: + cgName: "{{ drTestCgName }}" + + - set_fact: + Step_4_2_Completed: True + + # End Step_4_2 + + # End block + when: Step_4_2_Execute + + - block: + - name: Step_4_3 - Create DR Test Snapshot CG + debug: + msg: + params: + snapCg: + pgName: "{{ drPgName }}" + cgName: "{{ drTestCgName }}" + snapNames: "{{ existDrTestLunNames + drTestLunNames }}" + activate: False + snapDescs: "{{ existDrTestLunsDescs + primaryLunDescs }}" + device: "{{ drDeviceName }}" + + - set_fact: + deviceHost: "{{ drDeviceHost }}" + devicePort: "{{ drDevicePort }}" + deviceSn: "{{ drDeviceSn }}" + deviceToken: "{{ drDeviceToken }}" + deviceSession: "{{ drDeviceSession }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/create_snapshot_cg.yml" + vars: + pgName: "{{ drPgName }}" + cgName: "{{ drTestCgName }}" + snapNames: "{{ existDrTestLunNames + drTestLunNames }}" + activate: False + snapDescs: "{{ existDrTestLunsDescs + primaryLunDescs }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_luns.yml" + vars: + lunNames: "{{ existDrTestLunNames }}" + checkExist: True + + - set_fact: + existDrTestLunsIdNew: "{{ lunIds }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_luns.yml" + vars: + lunNames: "{{ drTestLunNames }}" + checkExist: True + + - set_fact: + drTestLunIds: "{{ lunIds }}" + Step_4_3_Completed: True + + # End Step_4_3 + + # End block + when: Step_4_3_Execute + + - block: + - name: Step_4_4 - Add Existing DR Test LUNs to LUN Group + debug: + msg: + params: + luns: "{{ existDrTestLuns }}" + device: "{{ drDeviceName }}" + + - set_fact: + deviceHost: "{{ drDeviceHost }}" + devicePort: "{{ drDevicePort }}" + deviceSn: "{{ drDeviceSn }}" + deviceToken: "{{ drDeviceToken }}" + deviceSession: "{{ drDeviceSession }}" + + - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/add_luns_to_lg.yml" + vars: + lgName: "{{ existDrTestLun.lgName }}" + lunNames: ["{{ existDrTestLun.lunName }}"] + addLunScsiIds: ["{{ existDrTestLun.lunScsiId }}"] + loop: "{{ existDrTestLuns }}" + loop_control: + loop_var: existDrTestLun + + - set_fact: + Step_4_4_Completed: True + + # End Step_4_4 + + # End block + when: Step_4_4_Execute + + - block: + - name: Step_4_5 - Add DR Test LUNs to LUN Group + debug: + msg: + params: + lunNames: "{{ drTestLunNames }}" + lgName: "{{ drTestLg00Name }}" + startScsiId: "{{ nextScsiId }}" + device: "{{ drDeviceName }}" + + - set_fact: + deviceHost: "{{ drDeviceHost }}" + devicePort: "{{ drDevicePort }}" + deviceSn: "{{ drDeviceSn }}" + deviceToken: "{{ drDeviceToken }}" + deviceSession: "{{ drDeviceSession }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/add_luns_to_lg.yml" + vars: + lgName: "{{ drTestLg00Name }}" + lunNames: "{{ drTestLunNames }}" + startScsiId: "{{ nextScsiId }}" + + - set_fact: + Step_4_5_Completed: True + + # End Step_4_5 + + # End block + when: Step_4_5_Execute + + # End Device Steps + + # Begin DJ Steps + + - block: + - name: Step_5_1 - Set Class for Primary LUNs + debug: + msg: + params: + volumeNames: "{{ primaryLunNames }}" + tierName: "{{ class1 }}" + #projectName: "{{ Country }}" + + - set_fact: + deviceName: "{{ primaryDeviceName }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/sync_storage.yml" + + - set_fact: + deviceSynced: "{{ deviceSynced + [primaryDeviceName] }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/volume/check_volumes.yml" + vars: + volumeNames: "{{ primaryLunNames }}" + waitExist: True + + - import_tasks: "{{GLOBAL.baseDir}}/task/volume/remove_volumes_from_tier.yml" + vars: + volumeNames: "{{ primaryLunsInTier }}" + when: primaryLunsInTier|length > 0 + + - import_tasks: "{{GLOBAL.baseDir}}/task/volume/add_volumes_to_tier.yml" + vars: + volumeNames: "{{ primaryLunNames }}" + tierName: "{{ class1 }}" + + - set_fact: + Step_5_1_Completed: True + + # - import_tasks: "{{GLOBAL.baseDir}}/task/volume/add_volumes_to_project.yml" + # vars: + # volumeNames: "{{ primaryLunNames }}" + # projectName: "{{ Country }}" + + # End Step_5_1 + + # End block + when: Step_5_1_Execute + + - block: + - name: Step_5_2 - Set Class for Metro LUNs + debug: + msg: + params: + volumeNames: "{{ metroLunNames }}" + tierName: "{{ class1 }}" + #projectName: "{{ Country }}" + + - set_fact: + deviceName: "{{ metroDeviceName }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/sync_storage.yml" + when: + - metroDeviceName not in deviceSynced + + - set_fact: + deviceSynced: "{{ deviceSynced + [metroDeviceName] }}" + when: + - metroDeviceName not in deviceSynced + + - import_tasks: "{{GLOBAL.baseDir}}/task/volume/check_volumes.yml" + vars: + volumeNames: "{{ metroLunNames }}" + waitExist: True + + - import_tasks: "{{GLOBAL.baseDir}}/task/volume/add_volumes_to_tier.yml" + vars: + volumeNames: "{{ metroLunNames }}" + tierName: "{{ class1 }}" + + - set_fact: + Step_5_2_Completed: True + + # - import_tasks: "{{GLOBAL.baseDir}}/task/volume/add_volumes_to_project.yml" + # vars: + # volumeNames: "{{ metroLunNames }}" + # projectName: "{{ Country }}" + + # End Step_5_2 + + # End block + when: Step_5_2_Execute + + - block: + - name: Step_5_3 - Set Class for DR LUNs + debug: + msg: + params: + volumeNames: "{{ drLunNames }}" + tierName: "{{ class2 }}" + #projectName: "{{ Country }}" + + - set_fact: + deviceName: "{{ drDeviceName }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/sync_storage.yml" + when: + - drDeviceName not in deviceSynced + + - set_fact: + deviceSynced: "{{ deviceSynced + [drDeviceName] }}" + when: + - drDeviceName not in deviceSynced + + - import_tasks: "{{GLOBAL.baseDir}}/task/volume/check_volumes.yml" + vars: + volumeNames: "{{ drLunNames }}" + waitExist: True + + - import_tasks: "{{GLOBAL.baseDir}}/task/volume/add_volumes_to_tier.yml" + vars: + volumeNames: "{{ drLunNames }}" + tierName: "{{ class2 }}" + + - set_fact: + Step_5_3_Completed: True + + # - import_tasks: "{{GLOBAL.baseDir}}/task/volume/add_volumes_to_project.yml" + # vars: + # volumeNames: "{{ drLunNames }}" + # projectName: "{{ Country }}" + + # End Step_5_3 + + # End block + when: Step_5_3_Execute + + - block: + - name: Step_6_1 - Insert Primary LUNs to KPI table + debug: + msg: + params: + lunIds: "{{ primaryLunIds }}" + device: "{{ primaryDeviceName }}" + + # Minus orphan capacity + - include_tasks: update_lun_kpi_table.yml + vars: + TYPE_OF_OPERATION: "modify" + WBE_CODE: "{{ WBE_CODE }}" + TICKET_NUMBER: "{{ TICKET_NUMBER }}" + SYSTEM_NAME: "" + SITE: "{{ primarySite }}" + ENVIRONMENT: "" + STORAGE_CLASS: "{{ selectedLunsClass[item.0] }}" + CAPACITY_GB: "-{{ (selectedLunsSector[item.0]|int / 1024 / 1024 / 2)|int }}" + STORAGE: "{{ primaryDeviceName }}" + VDISK_UID: "{{ item.1 }}" + with_indexed_items: "{{ selectedLunIds }}" + + # Add capacity to primary host + - include_tasks: update_lun_kpi_table.yml + vars: + TYPE_OF_OPERATION: "modify" + WBE_CODE: "{{ WBE_CODE }}" + TICKET_NUMBER: "{{ TICKET_NUMBER }}" + SYSTEM_NAME: "{{ primaryHostName }}" + SITE: "{{ primarySite }}" + ENVIRONMENT: "{{ osType }}" + STORAGE_CLASS: "{{ class1 }}" + CAPACITY_GB: "{{ (selectedLunsSector[item.0]|int / 1024 / 1024 / 2)|int }}" + STORAGE: "{{ primaryDeviceName }}" + VDISK_UID: "{{ item.1 }}" + with_indexed_items: "{{ selectedLunsSector }}" + + - include_tasks: update_lun_kpi_table.yml + vars: + TYPE_OF_OPERATION: "create" + WBE_CODE: "{{ WBE_CODE }}" + TICKET_NUMBER: "{{ TICKET_NUMBER }}" + SYSTEM_NAME: "{{ primaryHostName }}" + SITE: "{{ primarySite }}" + ENVIRONMENT: "{{ osType }}" + STORAGE_CLASS: "{{ class1 }}" + CAPACITY_GB: "{{ createLunSize }}" + STORAGE: "{{ primaryDeviceName }}" + VDISK_UID: "{{ item }}" + with_items: "{{ createLunIds }}" + + - set_fact: + Step_6_1_Completed: True + + # End Step_6_1 + + # End block + when: Step_6_1_Execute + + - block: + - name: Step_6_2 - Insert Metro LUNs to KPI table + debug: + msg: + params: + lunIds: "{{ metroLunIds }}" + device: "{{ metroDeviceName }}" + + - include_tasks: update_lun_kpi_table.yml + vars: + TYPE_OF_OPERATION: "create" + WBE_CODE: "{{ WBE_CODE }}" + TICKET_NUMBER: "{{ TICKET_NUMBER }}" + SYSTEM_NAME: "{{ metroHostName }}" + SITE: "{{ metroSite }}" + ENVIRONMENT: "{{ osType }}" + STORAGE_CLASS: "{{ class1 }}" + CAPACITY_GB: "{{ (primaryLunsSector[item.0]|int / 1024 / 1024 / 2)|int }}" + STORAGE: "{{ metroDeviceName }}" + VDISK_UID: "{{ item.1 }}" + with_indexed_items: "{{ metroLunIds }}" + + - set_fact: + Step_6_2_Completed: True + + # End Step_6_2 + + # End block + when: Step_6_2_Execute + + - block: + - name: Step_6_3 - Insert DR LUNs to KPI table + debug: + msg: + params: + lunIds: "{{ drLunIds }}" + device: "{{ drDeviceName }}" + + - include_tasks: update_lun_kpi_table.yml + vars: + TYPE_OF_OPERATION: "create" + WBE_CODE: "{{ WBE_CODE }}" + TICKET_NUMBER: "{{ TICKET_NUMBER }}" + SYSTEM_NAME: "{{ drHostName }}" + SITE: "{{ drSite }}" + ENVIRONMENT: "{{ osType }}" + STORAGE_CLASS: "{{ class2 }}" + CAPACITY_GB: "{{ (primaryLunsSector[item.0]|int / 1024 / 1024 / 2)|int }}" + STORAGE: "{{ drDeviceName }}" + VDISK_UID: "{{ item.1 }}" + with_indexed_items: "{{ drLunIds }}" + + - set_fact: + Step_6_3_Completed: True + + # End Step_6_3 + + # End block + when: Step_6_3_Execute + + - block: + - name: Step_6_4 - Insert DR Test LUNs to KPI table + debug: + msg: + params: + lunIds: "{{ drTestLunIds }}" + device: "{{ drDeviceName }}" + + - include_tasks: update_lun_kpi_table.yml + vars: + TYPE_OF_OPERATION: "create" + WBE_CODE: "{{ WBE_CODE }}" + TICKET_NUMBER: "{{ TICKET_NUMBER }}" + SYSTEM_NAME: "{{ drTestHostName }}" + SITE: "{{ drSite }}" + ENVIRONMENT: "{{ osType }}" + STORAGE_CLASS: "" + CAPACITY_GB: "{{ (primaryLunsSector[item.0]|int / 1024 / 1024 / 2)|int }}" + STORAGE: "{{ drDeviceName }}" + VDISK_UID: "{{ item.1 }}" + with_indexed_items: "{{ drTestLunIds }}" + + - set_fact: + Step_6_4_Completed: True + + # End Step_6_4 + + # End block + when: Step_6_4_Execute + + - block: + - name: Step_6_5 - Update Existing DR Test LUNs to KPI table + debug: + msg: + params: + lunIds: + old: "{{ existDrTestLunsId }}" + new: "{{ existDrTestLunsIdNew }}" + device: "{{ drDeviceName }}" + + - include_tasks: update_lun_kpi_table.yml + vars: + TYPE_OF_OPERATION: "delete" + WBE_CODE: "{{ WBE_CODE }}" + TICKET_NUMBER: "{{ TICKET_NUMBER }}" + SYSTEM_NAME: "{{ drTestHostName }}" + SITE: "{{ drSite }}" + ENVIRONMENT: "{{ osType }}" + STORAGE_CLASS: "" + CAPACITY_GB: "-{{ (existDrTestLuns[item.0].lunSector|int / 1024 / 1024 / 2)|int }}" + STORAGE: "{{ drDeviceName }}" + VDISK_UID: "{{ item.1 }}" + with_indexed_items: "{{ existDrTestLunsId }}" + + - include_tasks: update_lun_kpi_table.yml + vars: + TYPE_OF_OPERATION: "create" + WBE_CODE: "{{ WBE_CODE }}" + TICKET_NUMBER: "{{ TICKET_NUMBER }}" + SYSTEM_NAME: "{{ drTestHostName }}" + SITE: "{{ drSite }}" + ENVIRONMENT: "{{ osType }}" + STORAGE_CLASS: "" + CAPACITY_GB: "{{ (existDrTestLuns[item.0].lunSector|int / 1024 / 1024 / 2)|int }}" + STORAGE: "{{ drDeviceName }}" + VDISK_UID: "{{ item.1 }}" + with_indexed_items: "{{ existDrTestLunsIdNew }}" + + - set_fact: + Step_6_5_Completed: True + + # End Step_6_5 + + # End block + when: Step_6_5_Execute + + # End Block + rescue: + # Begin Rollback + + - block: + - name: Rollback_5_3 - Remove Class for DR LUNs + debug: + msg: + params: + volumeNames: "{{ drLunNames }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/volume/remove_volumes_from_tier.yml" + vars: + volumeNames: "{{ drLunNames }}" + + - set_fact: + Step_5_3_Rollbacked: True + + # End Rollback_5_3 + + # End block + when: Step_5_3_Completed + + - block: + - name: Rollback_5_2 - Remove Class for Metro LUNs + debug: + msg: + params: + volumeNames: "{{ metroLunNames }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/volume/remove_volumes_from_tier.yml" + vars: + volumeNames: "{{ metroLunNames }}" + + - set_fact: + Step_5_2_Rollbacked: True + + # End Rollback_5_2 + + # End block + when: Step_5_2_Completed + + - block: + - name: Rollback_5_1 - Remove Class for Primary LUNs + debug: + msg: + params: + volumeNames: "{{ primaryLunNames }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/volume/check_volumes.yml" + vars: + volumeNames: "{{ primaryLunNames }}" + waitExist: True + + - import_tasks: "{{GLOBAL.baseDir}}/task/volume/remove_volumes_from_tier.yml" + vars: + volumeNames: "{{ primaryLunNames }}" + + - include_tasks: "{{GLOBAL.baseDir}}/task/volume/add_volumes_to_tier.yml" + vars: + volumeNames: ["{{ item.0 }}"] + tierName: "{{ item.1 }}" + with_together: + - "{{ primaryLunsInTier }}" + - "{{ primaryLunsInTierClass }}" + when: primaryLunsInTier|length > 0 + + - set_fact: + Step_5_1_Rollbacked: True + + # End Rollback_5_1 + + # End block + when: Step_5_1_Completed + + - block: + - name: Rollback_4_5 - Remove DR Test LUNs from LUN Group + debug: + msg: + params: + lunNames: "{{ drTestLunNames }}" + lgName: "{{ drTestLg00Name }}" + device: "{{ drDeviceName }}" + + - set_fact: + deviceHost: "{{ drDeviceHost }}" + devicePort: "{{ drDevicePort }}" + deviceSn: "{{ drDeviceSn }}" + deviceToken: "{{ drDeviceToken }}" + deviceSession: "{{ drDeviceSession }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/remove_luns_from_lg.yml" + vars: + lgName: "{{ drTestLg00Name }}" + lunNames: "{{ drTestLunNames }}" + + - set_fact: + Step_4_5_Rollbacked: True + + # End Rollback_4_5 + + # End block + when: Step_4_5_Completed + + - block: + - name: Rollback_4_4 - Remove Existing DR Test LUNs from LUN Group + debug: + msg: + params: + luns: "{{ existDrTestLuns }}" + device: "{{ drDeviceName }}" + + - set_fact: + deviceHost: "{{ drDeviceHost }}" + devicePort: "{{ drDevicePort }}" + deviceSn: "{{ drDeviceSn }}" + deviceToken: "{{ drDeviceToken }}" + deviceSession: "{{ drDeviceSession }}" + + - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/remove_luns_from_lg.yml" + vars: + lgName: "{{ existDrTestLun.lgName }}" + lunNames: ["{{ existDrTestLun.lunName }}"] + loop: "{{ existDrTestLuns }}" + loop_control: + loop_var: existDrTestLun + + - set_fact: + Step_4_4_Rollbacked: True + + # End Rollback_4_4 + + # End block + when: Step_4_4_Completed + + - block: + - name: Rollback_4_3 - Delete DR Test Snapshot CG + debug: + msg: + params: + cgName: "{{ drTestCgName }}" + device: "{{ drDeviceName }}" + + - set_fact: + deviceHost: "{{ drDeviceHost }}" + devicePort: "{{ drDevicePort }}" + deviceSn: "{{ drDeviceSn }}" + deviceToken: "{{ drDeviceToken }}" + deviceSession: "{{ drDeviceSession }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/delete_snapshot_cg.yml" + vars: + cgName: "{{ drTestCgName }}" + + - set_fact: + Step_4_3_Rollbacked: True + + # End Rollback_4_3 + + # End block + when: Step_4_3_Completed + + - block: + - name: Rollback_4_0 - Delete LUN Group for DR Test Host + debug: + msg: + params: + lg: "{{ drTestLg00Name }}" + device: "{{ drDeviceName }}" + + - set_fact: + deviceHost: "{{ drDeviceHost }}" + devicePort: "{{ drDevicePort }}" + deviceSn: "{{ drDeviceSn }}" + deviceToken: "{{ drDeviceToken }}" + deviceSession: "{{ drDeviceSession }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/delete_lg.yml" + vars: + lgName: "{{ drTestLg00Name }}" + unmap: True + + - set_fact: + Step_4_0_Rollbacked: True + + # End Rollback_4_0 + + # End block + when: Step_4_0_Completed + + - block: + - name: Rollback_3_8 - Disable DR Star + debug: + msg: + params: + drStarName: "{{ drStarCgName }}" + device: "{{ primaryDeviceName }}" + + - set_fact: + deviceHost: "{{ primaryDeviceHost }}" + devicePort: "{{ primaryDevicePort }}" + deviceSn: "{{ primaryDeviceSn }}" + deviceToken: "{{ primaryDeviceToken }}" + deviceSession: "{{ primaryDeviceSession }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/disable_drstar.yml" + vars: + drStarName: "{{ drStarCgName }}" + + - set_fact: + Step_3_8_Rollbacked: True + + # End Rollback_3_8 + + # End block + when: Step_3_8_Completed + + - block: + - name: Rollback_3_7 - Delete DR Star + debug: + msg: + params: + drStarName: "{{ drStarCgNameDefault }}" + device: "{{ metroDeviceName }}" + + - set_fact: + deviceHost: "{{ metroDeviceHost }}" + devicePort: "{{ metroDevicePort }}" + deviceSn: "{{ metroDeviceSn }}" + deviceToken: "{{ metroDeviceToken }}" + deviceSession: "{{ metroDeviceSession }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/delete_drstar.yml" + vars: + drStarName: "{{ drStarCgNameDefault }}" + + - set_fact: + Step_3_7_Rollbacked: True + + # End Rollback_3_7 + + # End block + when: Step_3_7_Completed + + + - block: + - name: Rollback_3_4 - Remove DR LUNs from LUN Group + debug: + msg: + params: + lunNames: "{{ drLunNames }}" + lgName: "{{ drLg00Name }}" + device: "{{ drDeviceName }}" + + - set_fact: + deviceHost: "{{ drDeviceHost }}" + devicePort: "{{ drDevicePort }}" + deviceSn: "{{ drDeviceSn }}" + deviceToken: "{{ drDeviceToken }}" + deviceSession: "{{ drDeviceSession }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/remove_luns_from_lg.yml" + vars: + lgName: "{{ drLg00Name }}" + lunNames: "{{ drLunNames }}" + + - set_fact: + Step_3_4_Rollbacked: True + + # End Rollback_3_4 + + # End block + when: Step_3_4_Completed + + - block: + - name: Rollback_3_3_1 - Delete LUN Group for DR Host + debug: + msg: + params: + lg: "{{ drLg00Name }}" + device: "{{ drDeviceName }}" + + - set_fact: + deviceHost: "{{ drDeviceHost }}" + devicePort: "{{ drDevicePort }}" + deviceSn: "{{ drDeviceSn }}" + deviceToken: "{{ drDeviceToken }}" + deviceSession: "{{ drDeviceSession }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/delete_lg.yml" + vars: + lgName: "{{ drLg00Name }}" + unmap: True + + - set_fact: + Step_3_3_1_Rollbacked: True + + # End Rollback_3_4 + + # End block + when: Step_3_3_1_Completed + + - block: + - name: Rollback_3_1_1 - Remove DR LUNs from Protection Group + debug: + msg: + params: + lunNames: "{{ drLunNames }}" + pgName: "{{ drPgName }}" + device: "{{ drDeviceName }}" + + - set_fact: + deviceHost: "{{ drDeviceHost }}" + devicePort: "{{ drDevicePort }}" + deviceSn: "{{ drDeviceSn }}" + deviceToken: "{{ drDeviceToken }}" + deviceSession: "{{ drDeviceSession }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/remove_luns_from_pg.yml" + vars: + pgName: "{{ drPgName }}" + lunNames: "{{ drLunNames }}" + + - set_fact: + Step_3_1_1_Rollbacked: True + + # End Rollback_3_1_1 + + # End block + when: Step_3_1_1_Completed + + - block: + - name: Rollback_2_3 - Remove Metro LUNs from LUN Group + debug: + msg: + params: + lunNames: "{{ metroLunNames }}" + lgName: "{{ primaryLg00Name }}" + device: "{{ metroDeviceName }}" + + - set_fact: + deviceHost: "{{ metroDeviceHost }}" + devicePort: "{{ metroDevicePort }}" + deviceSn: "{{ metroDeviceSn }}" + deviceToken: "{{ metroDeviceToken }}" + deviceSession: "{{ metroDeviceSession }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/remove_luns_from_lg.yml" + vars: + lgName: "{{ primaryLg00Name }}" + lunNames: "{{ metroLunNames }}" + + - set_fact: + Step_2_3_Rollbacked: True + + # End Rollback_2_3 + + # End block + when: Step_2_3_Completed + + - block: + - name: Rollback_2_3_0 - Delete LUN Group for Metro Host + debug: + msg: + params: + lg: "{{ primaryLg00Name }}" + device: "{{ metroDeviceName }}" + + - set_fact: + deviceHost: "{{ metroDeviceHost }}" + devicePort: "{{ metroDevicePort }}" + deviceSn: "{{ metroDeviceSn }}" + deviceToken: "{{ metroDeviceToken }}" + deviceSession: "{{ metroDeviceSession }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/delete_lg.yml" + vars: + lgName: "{{ primaryLg00Name }}" + unmap: True + + - set_fact: + Step_2_3_Rollbacked: True + + # End Rollback_2_3_0 + + # End block + when: Step_2_3_0_Completed + + + - block: + - name: Rollback_2_1_1 - Remove Metro LUNs from Protection Group + debug: + msg: + params: + lun: + lunNames: "{{ metroLunNames }}" + pgName: "{{ primaryPgName }}" + device: "{{ metroDeviceName }}" + + - set_fact: + deviceHost: "{{ metroDeviceHost }}" + devicePort: "{{ metroDevicePort }}" + deviceSn: "{{ metroDeviceSn }}" + deviceToken: "{{ metroDeviceToken }}" + deviceSession: "{{ metroDeviceSession }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/remove_luns_from_pg.yml" + vars: + pgName: "{{ primaryPgName }}" + lunNames: "{{ metroLunNames }}" + + - set_fact: + Step_2_1_1_Rollbacked: True + + # End Rollback_2_1_1 + + # End block + when: Step_2_1_1_Completed + + - block: + - name: Rollback_1_1_3 - Remove Primary LUNs from LUN Group + debug: + msg: + params: + luns: + lunNames: "{{ primaryLunNames }}" + lgName: "{{ primaryLg00Name }}" + startScsiId: "{{ nextScsiId }}" + device: "{{ primaryDeviceName }}" + + - set_fact: + deviceHost: "{{ primaryDeviceHost }}" + devicePort: "{{ primaryDevicePort }}" + deviceSn: "{{ primaryDeviceSn }}" + deviceToken: "{{ primaryDeviceToken }}" + deviceSession: "{{ primaryDeviceSession }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/remove_luns_from_lg.yml" + vars: + lgName: "{{ primaryLg00Name }}" + lunNames: "{{ primaryLunNames }}" + + # End Rollback_1_1_3 + + # End block + when: Step_1_1_3_Completed + + - block: + - name: Rollback_1_1_2 - Remove Primary LUNs from Protection Group + debug: + msg: + params: + lun: + lunNames: "{{ primaryLunNames }}" + pgName: "{{ primaryPgName }}" + device: "{{ primaryDeviceName }}" + - set_fact: + deviceHost: "{{ primaryDeviceHost }}" + devicePort: "{{ primaryDevicePort }}" + deviceSn: "{{ primaryDeviceSn }}" + deviceToken: "{{ primaryDeviceToken }}" + deviceSession: "{{ primaryDeviceSession }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/remove_luns_from_pg.yml" + vars: + pgName: "{{ primaryPgName }}" + lunNames: "{{ primaryLunNames }}" + + - set_fact: + Step_1_1_2_Rollbacked: True + + # End Rollback_1_1_2 + + # End block + when: Step_1_1_2_Completed + + - block: + - name: Rollback_1_1_1 - Modify Selected LUNs + debug: + msg: + params: + luns: + name: + new: "{{ selectedLunNames }}" + old: "{{ selectedLunNamesNew }}" + device: "{{ primaryDeviceName }}" + + - include_tasks: "{{GLOBAL.baseDir}}/task/volume/rename_volumes.yml" + vars: + volumeNames: "{{ selectedLunNamesNew }}" + newVolumeNames: "{{ selectedLunNames }}" + + - set_fact: + Step_1_1_1_Rollbacked: True + + # End Rollback_1_1_1 + + # End block + when: Step_1_1_1_Completed + + - block: + - name: Rollback_3_6 - Remove Standby DR Pairs from Standby Replication CG + debug: + msg: + params: + pairs: + localLunIds: "{{ metroLunIds }}" + remoteLunIds: "{{ drLunIds }}" + cgName: "{{ standbyCgName }}" + device: "{{ metroDeviceName }}" + + - set_fact: + deviceHost: "{{ metroDeviceHost }}" + devicePort: "{{ metroDevicePort }}" + deviceSn: "{{ metroDeviceSn }}" + deviceToken: "{{ metroDeviceToken }}" + deviceSession: "{{ metroDeviceSession }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/remove_luns_from_replication_cg.yml" + vars: + cgName: "{{ standbyCgName }}" + localLunIds: "{{ metroLunIds }}" + remoteLunIds: "{{ drLunIds }}" + + - set_fact: + Step_3_6_Rollbacked: True + Step_3_3_Rollbacked: True + + # End Rollback_3_6 + + # End block + when: Step_3_6_Completed + + - block: + - name: Rollback_3_5 - Remove DR Pairs from Replication CG + debug: + msg: + params: + pairs: + localLunIds: "{{ primaryLunIds }}" + remoteLunIds: "{{ drLunIds }}" + cgName: "{{ drCgName }}" + device: "{{ primaryDeviceName }}" + + - set_fact: + deviceHost: "{{ primaryDeviceHost }}" + devicePort: "{{ primaryDevicePort }}" + deviceSn: "{{ primaryDeviceSn }}" + deviceToken: "{{ primaryDeviceToken }}" + deviceSession: "{{ primaryDeviceSession }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/remove_luns_from_replication_cg.yml" + vars: + cgName: "{{ drCgName }}" + localLunIds: "{{ primaryLunIds }}" + remoteLunIds: "{{ drLunIds }}" + + - set_fact: + Step_3_5_Rollbacked: True + Step_3_2_Rollbacked: True + + + # End Rollback_3_5 + + # End block + when: Step_3_5_Completed + + - block: + - name: Rollback_3_3 - Delete Standby DR Pairs + debug: + msg: + params: + pairs: + localLunIds: "{{ metroLunIds }}" + remoteLunIds: "{{ drLunIds }}" + remoteSn: "{{ drDeviceSn }}" + device: "{{ metroDeviceName }}" + + - set_fact: + deviceHost: "{{ metroDeviceHost }}" + devicePort: "{{ metroDevicePort }}" + deviceSn: "{{ metroDeviceSn }}" + deviceToken: "{{ metroDeviceToken }}" + deviceSession: "{{ metroDeviceSession }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/delete_replication_pairs.yml" + vars: + localLunIds: "{{ metroLunIds }}" + remoteLunIds: "{{ drLunIds }}" + remoteSn: "{{ drDeviceSn }}" + + - set_fact: + Step_3_3_Rollbacked: True + + # End Rollback_3_3 + + # End block + when: + - Step_3_3_Completed + - Step_3_3_Rollbacked|bool == False + + - block: + - name: Rollback_3_2 - Delete DR Pairs + debug: + msg: + params: + pairs: + localLunIds: "{{ primaryLunIds }}" + remoteLunIds: "{{ drLunIds }}" + remoteSn: "{{ drDeviceSn }}" + device: "{{ primaryDeviceName }}" + + - set_fact: + deviceHost: "{{ primaryDeviceHost }}" + devicePort: "{{ primaryDevicePort }}" + deviceSn: "{{ primaryDeviceSn }}" + deviceToken: "{{ primaryDeviceToken }}" + deviceSession: "{{ primaryDeviceSession }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/delete_replication_pairs.yml" + vars: + localLunIds: "{{ primaryLunIds }}" + remoteLunIds: "{{ drLunIds }}" + remoteSn: "{{ drDeviceSn }}" + + - set_fact: + Step_3_2_Rollbacked: True + + # End Rollback_3_2 + + # End block + when: + - Step_3_2_Completed + - Step_3_2_Rollbacked|bool == False + + - block: + - name: Rollback_3_1 - Delete DR LUNs + debug: + msg: + params: + lunNames: "{{ drLunNames }}" + device: "{{ drDeviceName }}" + + - set_fact: + deviceHost: "{{ drDeviceHost }}" + devicePort: "{{ drDevicePort }}" + deviceSn: "{{ drDeviceSn }}" + deviceToken: "{{ drDeviceToken }}" + deviceSession: "{{ drDeviceSession }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/delete_luns.yml" + vars: + lunNames: "{{ drLunNames }}" + + - set_fact: + Step_3_1_Rollbacked: True + + # End Rollback_3_1 + + # End block + when: Step_3_1_Completed + + - block: + - name: Rollback_2_4 - Remove Metro Pairs from HyperMetro CG + debug: + msg: + params: + pairs: + localLunIds: "{{ primaryLunIds }}" + remoteLunIds: "{{ metroLunIds }}" + cgName: "{{ metroCgName }}" + device: "{{ primaryDeviceName }}" + + - set_fact: + deviceHost: "{{ primaryDeviceHost }}" + devicePort: "{{ primaryDevicePort }}" + deviceSn: "{{ primaryDeviceSn }}" + deviceToken: "{{ primaryDeviceToken }}" + deviceSession: "{{ primaryDeviceSession }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/remove_luns_from_hypermetro_cg.yml" + vars: + cgName: "{{ metroCgName }}" + localLunIds: "{{ primaryLunIds }}" + remoteLunIds: "{{ metroLunIds }}" + + - set_fact: + Step_2_4_Rollbacked: True + Step_2_2_Rollbacked: True + + # End Rollback_2_4 + + # End block + when: Step_2_4_Completed + + - block: + - name: Rollback_2_2 - Delete Metro Pairs + debug: + msg: + params: + pairs: + localLunIds: "{{ primaryLunIds }}" + remoteLunIds: "{{ metroLunIds }}" + remoteSn: "{{ metroDeviceSn }}" + device: "{{ primaryDeviceName }}" + + - set_fact: + deviceHost: "{{ primaryDeviceHost }}" + devicePort: "{{ primaryDevicePort }}" + deviceSn: "{{ primaryDeviceSn }}" + deviceToken: "{{ primaryDeviceToken }}" + deviceSession: "{{ primaryDeviceSession }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/delete_hypermetro_pairs.yml" + vars: + localLunIds: "{{ primaryLunIds }}" + remoteLunIds: "{{ metroLunIds }}" + remoteSn: "{{ metroDeviceSn }}" + + - set_fact: + Step_2_2_Rollbacked: True + + # End Rollback_2_2 + + # End block + when: + - Step_2_2_Completed + - Step_2_2_Rollbacked|bool == False + + - block: + - name: Rollback_2_1 - Delete Metro LUNs + debug: + msg: + params: + lunNames: "{{ metroLunNames }}" + device: "{{ metroDeviceName }}" + + - set_fact: + deviceHost: "{{ metroDeviceHost }}" + devicePort: "{{ metroDevicePort }}" + deviceSn: "{{ metroDeviceSn }}" + deviceToken: "{{ metroDeviceToken }}" + deviceSession: "{{ metroDeviceSession }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/delete_luns.yml" + vars: + lunNames: "{{ metroLunNames }}" + + - set_fact: + Step_2_1_Rollbacked: True + + # End Rollback_2_1 + + # End block + when: Step_2_1_Completed + + - block: + - name: Rollback_1_2 - Enable DR Star + debug: + msg: + params: + drStarName: "{{ drStarCgName }}" + device: "{{ primaryDeviceName }}" + + - set_fact: + deviceHost: "{{ primaryDeviceHost }}" + devicePort: "{{ primaryDevicePort }}" + deviceSn: "{{ primaryDeviceSn }}" + deviceToken: "{{ primaryDeviceToken }}" + deviceSession: "{{ primaryDeviceSession }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/enable_drstar.yml" + vars: + drStarName: "{{ drStarCgName }}" + + - set_fact: + Step_1_2_Rollbacked: True + + # End Rollback_1_2 + + # End block + when: Step_1_2_Completed + + - block: + - name: Rollback_1_1 - Delete Primary LUNs + debug: + msg: + params: + lunNames: "{{ primaryLunNames }}" + device: "{{ primaryDeviceName }}" + + - set_fact: + deviceHost: "{{ primaryDeviceHost }}" + devicePort: "{{ primaryDevicePort }}" + deviceSn: "{{ primaryDeviceSn }}" + deviceToken: "{{ primaryDeviceToken }}" + deviceSession: "{{ primaryDeviceSession }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/delete_luns.yml" + vars: + lunNames: "{{ primaryLunNames }}" + + - set_fact: + Step_1_1_Rollbacked: True + + # End Rollback_1_1 + + # End block + when: Step_1_1_Completed + + - block: + - name: Rollback_4_2 - Create DR Test Snapshot CG + debug: + msg: + params: + snapCg: + pgName: "{{ drPgName }}" + cgName: "{{ drTestCgName }}" + snapNames: "{{ existDrTestLunNames }}" + activate: False + snapDescs: "{{ existDrTestLunsDescs }}" + device: "{{ drDeviceName }}" + + - set_fact: + deviceHost: "{{ drDeviceHost }}" + devicePort: "{{ drDevicePort }}" + deviceSn: "{{ drDeviceSn }}" + deviceToken: "{{ drDeviceToken }}" + deviceSession: "{{ drDeviceSession }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/create_snapshot_cg.yml" + vars: + pgName: "{{ drPgName }}" + cgName: "{{ drTestCgName }}" + snapNames: "{{ existDrTestLunNames }}" + activate: False + snapDescs: "{{ existDrTestLunsDescs }}" + + - set_fact: + Step_4_2_Rollbacked: True + + # End Rollback_4_2 + + # End block + when: Step_4_2_Completed + + - block: + - name: Rollback_4_1 - Add Existing DR Test LUNs to LUN Group + debug: + msg: + params: + luns: "{{ existDrTestLuns }}" + device: "{{ drDeviceName }}" + + - set_fact: + deviceHost: "{{ drDeviceHost }}" + devicePort: "{{ drDevicePort }}" + deviceSn: "{{ drDeviceSn }}" + deviceToken: "{{ drDeviceToken }}" + deviceSession: "{{ drDeviceSession }}" + + - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/add_luns_to_lg.yml" + vars: + lgName: "{{ existDrTestLun.lgName }}" + lunNames: ["{{ existDrTestLun.lunName }}"] + addLunScsiIds: ["{{ existDrTestLun.lunScsiId }}"] + loop: "{{ existDrTestLuns }}" + loop_control: + loop_var: existDrTestLun + + - set_fact: + Step_4_1_Rollbacked: True + + # End Rollback_4_1 + + # End block + when: Step_4_1_Completed + + - block: + - name: Re-Sync Storage Devices + debug: + msg: + params: + devices: "{{ deviceSynced }}" + + - include_tasks: "{{GLOBAL.baseDir}}/task/storage/sync_storage.yml" + loop: "{{ deviceSynced }}" + loop_control: + loop_var: deviceName + + when: deviceSynced|length > 0 + + # End Rollbacks + + # End Workflow + + # Begin Validate Results + + - block: + - name: Result_1_1 - Create Primary LUNs + debug: + msg: + params: + luns: + lunSize: "{{ createLunSize }}" + newLunNames: "{{ createLunNames }}" + startScsiId: "{{ createNextScsiId }}" + poolId: "{{ createPoolId }}" + workload: "{{ createWorkload }}" + desc: "{{ createLunRemarks }}" + device: "{{ primaryDeviceName }}" + result: + succeeded: "{{ Step_1_1_Completed }}" + rollbacked: "{{ Step_1_1_Rollbacked }}" + failed_when: Step_1_1_Completed|bool == False + when: Step_1_1_Execute + + - name: Result_1_1_1 - Modify Selected LUNs + debug: + msg: + params: + luns: + name: + new: "{{ selectedLunNames }}" + old: "{{ selectedLunNamesNew }}" + device: "{{ primaryDeviceName }}" + result: + succeeded: "{{ Step_1_1_1_Completed }}" + rollbacked: "{{ Step_1_1_1_Rollbacked }}" + failed_when: Step_1_1_1_Completed|bool == False + when: Step_1_1_1_Execute + + - name: Result_1_1_2 - Add Primary LUNs to Protection Group + debug: + msg: + params: + lun: + lunNames: "{{ primaryLunNames }}" + pgName: "{{ primaryPgName }}" + device: "{{ primaryDeviceName }}" + result: + succeeded: "{{ Step_1_1_2_Completed }}" + rollbacked: "{{ Step_1_1_2_Rollbacked }}" + failed_when: Step_1_1_2_Completed|bool == False + when: Step_1_1_2_Execute + + - name: Result_1_1_3 - Add Primary LUNs to LUN Group + debug: + msg: + params: + lun: + primaryLunNames: "{{ primaryLunNames }}" + selectedLunNames: "{{ selectedLunNames }}" + primaryLunIds: "{{ primaryLunIds }}" + selectedLunIds: "{{ selectedLunIds }}" + lgName: "{{ primaryLg00Name }}" + startScsiId: "{{ nextScsiId }}" + device: "{{ primaryDeviceName }}" + result: + succeeded: "{{ Step_1_1_3_Completed }}" + rollbacked: "{{ Step_1_1_3_Rollbacked }}" + failed_when: Step_1_1_3_Completed|bool == False + when: Step_1_1_3_Execute + + - name: Result_1_3 - Disable DR Star + debug: + msg: + params: + drStarName: "{{ drStarCgName }}" + device: "{{ primaryDeviceName }}" + result: + succeeded: "{{ Step_1_2_Completed }}" + rollbacked: "{{ Step_1_2_Rollbacked }}" + failed_when: Step_1_2_Completed|bool == False + when: Step_1_2_Execute + + - name: Result_2_1 - Create Metro LUNs + debug: + msg: + params: + luns: + lunNames: "{{ metroLunNames }}" + lunDescs: "{{ primaryLunDescs }}" + poolId: "{{ metroPoolId }}" + workload: "{{ metroWorkload }}" + device: "{{ metroDeviceName }}" + result: + succeeded: "{{ Step_2_1_Completed }}" + rollbacked: "{{ Step_2_1_Rollbacked }}" + failed_when: Step_2_1_Completed|bool == False + when: Step_2_1_Execute + + - name: Result_2_1_1 - Add Metro LUNs to Protection Group + debug: + msg: + params: + lun: + lunNames: "{{ metroLunNames }}" + lunIds: "{{ metroLunIds }}" + pgName: "{{ primaryPgName }}" + device: "{{ metroDeviceName }}" + result: + succeeded: "{{ Step_2_1_1_Completed }}" + rollbacked: "{{ Step_2_1_1_Rollbacked }}" + failed_when: Step_2_1_1_Completed|bool == False + when: Step_2_1_1_Execute + + - name: Result_2_2 - Create Metro Pairs + debug: + msg: + params: + pairs: + localLunIds: "{{ primaryLunIds }}" + remoteLunIds: "{{ metroLunIds }}" + remoteSn: "{{ metroDeviceSn }}" + device: "{{ primaryDeviceName }}" + result: + succeeded: "{{ Step_2_2_Completed }}" + rollbacked: "{{ Step_2_2_Rollbacked }}" + failed_when: Step_2_2_Completed|bool == False + when: Step_2_2_Execute + + - name: Result_2_3_0 - Create LUN Group for Metro Host + debug: + msg: + params: + host: "{{ primaryHostName }}" + lg: "{{ primaryLg00Name }}" + desc: "{{ primaryLg00Desc }}" + device: "{{ metroDeviceName }}" + result: + succeeded: "{{ Step_2_3_0_Completed }}" + rollbacked: "{{ Step_2_3_0_Rollbacked }}" + failed_when: Step_2_3_0_Completed|bool == False + when: Step_2_3_0_Execute + + - name: Result_2_3 - Add Metro LUNs to LUN Group + debug: + msg: + params: + lunNames: "{{ metroLunNames }}" + lgName: "{{ primaryLg00Name }}" + startScsiId: "{{ nextScsiId }}" + device: "{{ metroDeviceName }}" + result: + succeeded: "{{ Step_2_3_Completed }}" + rollbacked: "{{ Step_2_3_Rollbacked }}" + failed_when: Step_2_3_Completed|bool == False + when: Step_2_3_Execute + + - name: Result_2_4 - Add Metro Pairs to HyperMetro CG + debug: + msg: + params: + pairs: + localLunIds: "{{ primaryLunIds }}" + remoteLunIds: "{{ metroLunIds }}" + cgName: "{{ metroCgName }}" + device: "{{ primaryDeviceName }}" + result: + succeeded: "{{ Step_2_4_Completed }}" + rollbacked: "{{ Step_2_4_Rollbacked }}" + failed_when: Step_2_4_Completed|bool == False + when: Step_2_4_Execute + + - name: Result_3_1 - Create DR LUNs + debug: + msg: + params: + luns: + lunNames: "{{ drLunNames }}" + lunDescs: "{{ primaryLunDescs }}" + poolId: "{{ drPoolId }}" + workload: "{{ drWorkload }}" + device: "{{ drDeviceName }}" + result: + succeeded: "{{ Step_3_1_Completed }}" + rollbacked: "{{ Step_3_1_Rollbacked }}" + failed_when: Step_3_1_Completed|bool == False + when: Step_3_1_Execute + + - name: Result_3_1_1 - Add DR LUNs to Protection Group + debug: + msg: + params: + lunNames: "{{ drLunNames }}" + lunIds: "{{ drLunIds }}" + pgName: "{{ drPgName }}" + device: "{{ drDeviceName }}" + result: + succeeded: "{{ Step_3_1_1_Completed }}" + rollbacked: "{{ Step_3_1_1_Rollbacked }}" + failed_when: Step_3_1_1_Completed|bool == False + when: Step_3_1_1_Execute + + - name: Result_3_2 - Create DR Pairs + debug: + msg: + params: + pairs: + localLunIds: "{{ primaryLunIds }}" + remoteLunIds: "{{ drLunIds }}" + remoteSn: "{{ drDeviceSn }}" + mode: "{{ drCgModeEnum }}" + device: "{{ primaryDeviceName }}" + result: + succeeded: "{{ Step_3_2_Completed }}" + rollbacked: "{{ Step_3_2_Rollbacked }}" + failed_when: Step_3_2_Completed|bool == False + when: Step_3_2_Execute + + - name: Result_3_3 - Create Standby DR Pairs + debug: + msg: + params: + pairs: + localLunIds: "{{ metroLunIds }}" + remoteLunIds: "{{ drLunIds }}" + remoteSn: "{{ drDeviceSn }}" + mode: "{{ GLOBAL.replication.syncMode.async }}" + standby: True + device: "{{ metroDeviceName }}" + result: + succeeded: "{{ Step_3_3_Completed }}" + rollbacked: "{{ Step_3_3_Rollbacked }}" + failed_when: Step_3_3_Completed|bool == False + when: Step_3_3_Execute + + + - name: Result_3_3_1 - Create LUN Group for DR Host + debug: + msg: + params: + host: "{{ drHostName }}" + lg: "{{ drLg00Name }}" + desc: "{{ drLg00Desc }}" + device: "{{ drDeviceName }}" + result: + succeeded: "{{ Step_3_3_1_Completed }}" + rollbacked: "{{ Step_3_3_1_Rollbacked }}" + failed_when: Step_3_3_1_Completed|bool == False + when: Step_3_3_1_Execute + + - name: Result_3_4 - Add DR LUNs to LUN Group + debug: + msg: + params: + lunNames: "{{ drLunNames }}" + lgName: "{{ drLg00Name }}" + startScsiId: "{{ nextScsiId }}" + device: "{{ drDeviceName }}" + result: + succeeded: "{{ Step_3_4_Completed }}" + rollbacked: "{{ Step_3_4_Rollbacked }}" + failed_when: Step_3_4_Completed|bool == False + when: Step_3_4_Execute + + - name: Result_3_5 - Add DR Pairs to Replication CG + debug: + msg: + params: + pairs: + localLunIds: "{{ primaryLunIds }}" + remoteLunIds: "{{ drLunIds }}" + cgName: "{{ drCgName }}" + device: "{{ primaryDeviceName }}" + result: + succeeded: "{{ Step_3_5_Completed }}" + rollbacked: "{{ Step_3_5_Rollbacked }}" + failed_when: Step_3_5_Completed|bool == False + when: Step_3_5_Execute + + - name: Result_3_6 - Add Standby DR Pairs to Standby Replication CG + debug: + msg: + params: + pairs: + localLunIds: "{{ metroLunIds }}" + remoteLunIds: "{{ drLunIds }}" + standby: True + cgName: "{{ standbyCgName }}" + device: "{{ metroDeviceName }}" + result: + succeeded: "{{ Step_3_6_Completed }}" + rollbacked: "{{ Step_3_6_Rollbacked }}" + failed_when: Step_3_6_Completed|bool == False + when: Step_3_6_Execute + + + - name: Result_3_7 - Create DR Star + debug: + msg: + params: + drstar: + drStarName: "{{ drStarCgNameDefault }}" + mode: 1 # HyperMetro + Async Replication + memberType: 2 # CG + metroId: "{{ metroCgId }}" + asyncId: "{{ standbyCgId }}" + device: "{{ metroDeviceName }}" + result: + succeeded: "{{ Step_3_7_Completed }}" + rollbacked: "{{ Step_3_7_Rollbacked }}" + failed_when: Step_3_7_Completed|bool == False + when: Step_3_7_Execute + + - name: Result_3_8 - Enable DR Star + debug: + msg: + params: + drStarName: "{{ drStarCgName }}" + device: "{{ primaryDeviceName }}" + result: + succeeded: "{{ Step_3_8_Completed }}" + rollbacked: "{{ Step_3_8_Rollbacked }}" + failed_when: Step_3_8_Completed|bool == False + when: Step_3_8_Execute + + - name: Result_4_0 - Create LUN Group for DR Test Host + debug: + msg: + params: + host: "{{ drTestHostName }}" + lg: "{{ drTestLg00Name }}" + desc: "{{ drLg00Desc }}" + device: "{{ drDeviceName }}" + result: + succeeded: "{{ Step_4_0_Completed }}" + rollbacked: "{{ Step_4_0_Rollbacked }}" + failed_when: Step_4_0_Completed|bool == False + when: Step_4_0_Execute + + - name: Result_4_1 - Remove Existing DR Test LUNs from LUN Group + debug: + msg: + params: + luns: "{{ existDrTestLuns }}" + device: "{{ drDeviceName }}" + result: + succeeded: "{{ Step_4_1_Completed }}" + rollbacked: "{{ Step_4_1_Rollbacked }}" + failed_when: Step_4_1_Completed|bool == False + when: Step_4_1_Execute + + - name: Result_4_2 - Delete Existing DR Test Snapshot CG + debug: + msg: + params: + cgName: "{{ drTestCgName }}" + device: "{{ drDeviceName }}" + result: + succeeded: "{{ Step_4_2_Completed }}" + rollbacked: "{{ Step_4_2_Rollbacked }}" + failed_when: Step_4_2_Completed|bool == False + when: Step_4_2_Execute + + - name: Result_4_3 - Create DR Test Snapshot CG + debug: + msg: + params: + snapCg: + pgName: "{{ drPgName }}" + cgName: "{{ drTestCgName }}" + snapNames: "{{ existDrTestLunNames + drTestLunNames }}" + activate: False + snapDescs: "{{ existDrTestLunsDescs + primaryLunDescs }}" + device: "{{ drDeviceName }}" + result: + succeeded: "{{ Step_4_3_Completed }}" + rollbacked: "{{ Step_4_3_Rollbacked }}" + failed_when: Step_4_3_Completed|bool == False + when: Step_4_3_Execute + + - name: Result_4_4 - Add Existing DR Test LUNs to LUN Group + debug: + msg: + params: + luns: "{{ existDrTestLuns }}" + device: "{{ drDeviceName }}" + result: + succeeded: "{{ Step_4_4_Completed }}" + rollbacked: "{{ Step_4_4_Rollbacked }}" + failed_when: Step_4_4_Completed|bool == False + when: Step_4_4_Execute + + - name: Result_4_5 - Add DR Test LUNs to LUN Group + debug: + msg: + params: + lunNames: "{{ drTestLunNames }}" + lgName: "{{ drTestLg00Name }}" + startScsiId: "{{ nextScsiId }}" + device: "{{ drDeviceName }}" + result: + succeeded: "{{ Step_4_5_Completed }}" + rollbacked: "{{ Step_4_5_Rollbacked }}" + failed_when: Step_4_5_Completed|bool == False + when: Step_4_5_Execute + + - name: Result_5_1 - Set Class for Primary LUNs + debug: + msg: + params: + volumeNames: "{{ primaryLunNames }}" + tierName: "{{ class1 }}" + #projectName: "{{ Country }}" + result: + succeeded: "{{ Step_5_1_Completed }}" + rollbacked: "{{ Step_5_1_Rollbacked }}" + failed_when: Step_5_1_Completed|bool == False + when: Step_5_1_Execute + + - name: Result_5_2 - Set Class for Metro LUNs + debug: + msg: + params: + volumeNames: "{{ metroLunNames }}" + tierName: "{{ class1 }}" + #projectName: "{{ Country }}" + result: + succeeded: "{{ Step_5_2_Completed }}" + rollbacked: "{{ Step_5_2_Rollbacked }}" + failed_when: Step_5_2_Completed|bool == False + when: Step_5_2_Execute + + - name: Result_5_3 - Set Class for DR LUNs + debug: + msg: + params: + volumeNames: "{{ drLunNames }}" + tierName: "{{ class2 }}" + #projectName: "{{ Country }}" + result: + succeeded: "{{ Step_5_3_Completed }}" + rollbacked: "{{ Step_5_3_Rollbacked }}" + failed_when: Step_5_3_Completed|bool == False + when: Step_5_3_Execute + + - name: Result_6_1 - Insert Primary LUNs to KPI table + debug: + msg: + params: + lunIds: "{{ primaryLunIds }}" + device: "{{ primaryDeviceName }}" + result: + succeeded: "{{ Step_6_1_Completed }}" + failed_when: Step_6_1_Completed|bool == False + when: Step_6_1_Execute + + - name: Result_6_2 - Insert Metro LUNs to KPI table + debug: + msg: + params: + lunIds: "{{ metroLunIds }}" + device: "{{ metroDeviceName }}" + result: + succeeded: "{{ Step_6_2_Completed }}" + failed_when: Step_6_2_Completed|bool == False + when: Step_6_2_Execute + + - name: Result_6_3 - Insert DR LUNs to KPI table + debug: + msg: + params: + lunIds: "{{ drLunIds }}" + device: "{{ drDeviceName }}" + result: + succeeded: "{{ Step_6_3_Completed }}" + failed_when: Step_6_3_Completed|bool == False + when: Step_6_3_Execute + + - name: Result_6_4 - Insert DR Test LUNs to KPI table + debug: + msg: + params: + lunIds: "{{ drTestLunIds }}" + device: "{{ drDeviceName }}" + result: + succeeded: "{{ Step_6_4_Completed }}" + failed_when: Step_6_4_Completed|bool == False + when: Step_6_4_Execute + + - name: Result_6_5 - Update Existing DR Test LUNs to KPI table + debug: + msg: + params: + lunIds: + old: "{{ existDrTestLunsId }}" + new: "{{ existDrTestLunsIdNew }}" + device: "{{ drDeviceName }}" + result: + succeeded: "{{ Step_6_5_Completed }}" + failed_when: Step_6_5_Completed|bool == False + when: Step_6_5_Execute + + # End Validate Results + + # End Tasks + +# End Playbook \ No newline at end of file diff --git a/rundeck/workflow/project001/51_remove_luns_from_pg.yml b/rundeck/workflow/project001/51_remove_luns_from_pg.yml new file mode 100644 index 0000000..8aacfa1 --- /dev/null +++ b/rundeck/workflow/project001/51_remove_luns_from_pg.yml @@ -0,0 +1,2997 @@ +- name: Remove LUNs From Protection Group + hosts: localhost + vars_files: + - ../../../config/global.yml + - ../../../config/project001.yml + gather_facts: no + become: no + tasks: + + # Check Params + - block: + - set_fact: + checked_params: + Protection_Group: "{{ Protection_Group is not none and Protection_Group != DEFAULT.noneValue }}" + Storage: "{{ (Storage is not none and Storage != DEFAULT.noneValue) and (Storage|string|length == 20) }}" + Remove_LUN: "{{ Remove_LUN is not none and Remove_LUN != DEFAULT.noneValue }}" + Check_Result_1: "{{ ('lun' in Check_Result_1) }}" + + - name: Precheck_0_1 - Check Params + debug: + msg: "{{checked_params}}" + failed_when: checked_params.values()|unique != [True] + + # Check Metro Params + - block: + - set_fact: + checked_metro_params: + Metro_Protection_Group: "{{ Metro_Protection_Group is not none and Metro_Protection_Group != DEFAULT.noneValue }}" + Metro_Storage: "{{ (Metro_Storage is not none and Metro_Storage != DEFAULT.noneValue) and (Metro_Storage|string|length == 20) }}" + Check_Result_2: "{{ ('lun' in Check_Result_2) }}" + + - name: Precheck_0_2 - Check Metro Params + debug: + msg: "{{checked_metro_params}}" + failed_when: checked_metro_params.values()|unique != [True] + + when: Enable_HyperMetro == 'Y' + + # Check DR Params + - block: + - set_fact: + checked_dr_params: + DR_Protection_Group: "{{ DR_Protection_Group is not none and DR_Protection_Group != DEFAULT.noneValue }}" + DR_Storage: "{{ (DR_Storage is not none and DR_Storage != DEFAULT.noneValue) and (DR_Storage|string|length == 20) }}" + Check_Result_3: "{{ ('lun' in Check_Result_3) }}" + + - name: Precheck_0_3 - Check DR Params + debug: + msg: "{{checked_dr_params}}" + failed_when: checked_dr_params.values()|unique != [True] + when: Protection_Level|int >= 2 + + - set_fact: + WBE_CODE: "{{ WBE_CODE }}" + TICKET_NUMBER: "{{ TICKET_NUMBER }}" + primaryLunNames: "{{ Remove_LUN.split(',')|sort }}" + primaryDeviceSn: "{{ Storage|string }}" + primaryRoom: "{{ Storage_Room }}" + primarySite: "{{ AZ[Storage_Room]['dc'] }}" + primaryPgName: "{{ Protection_Group }}" + sessionName: "{{ Session_Name }}" + metroEnable: "{{ Enable_HyperMetro }}" + metroDeviceSn: "{{ Metro_Storage|string }}" + metroRoom: "{{ Metro_Storage_Room }}" + metroSite: "{{ AZ[Metro_Storage_Room]['dc'] }}" + metroCgName: "{{ Metro_CG }}" + metroCgId: "{{ Metro_CG_ID }}" + protectLevel: "{{ Protection_Level }}" + drCgName: "{{ DR_CG }}" + drCgMode: "{{ DR_Mode }}" + drCgModeEnum: "{{ DR_Mode_Enum }}" + drDevId: "{{ DR_Storage_ID }}" + drDeviceSn: "{{ DR_Storage|string }}" + drRoom: "{{ DR_Storage_Room }}" + drSite: "{{ AZ[DR_Storage_Room]['dc'] }}" + drPgName: "{{ DR_Protection_Group }}" + drTestCgName: "{{ DR_Test_CG }}" + drTestCgId: "{{ DR_Test_CG_ID }}" + drTestCgActivated: "{{ (DR_Test_CG_Status == SNAPCG.activated.enum) if (DR_Test_CG_Status is not none and DR_Test_CG_Status != DEFAULT.noneValue) else False }}" + drStarCgName: "{{ DR_Star if (DR_Star is not none and DR_Star != DEFAULT.noneValue) else '' }}" + standbyCgName: "{{ Standby_CG }}" + standbyCgId: "{{ Standby_CG_ID }}" + hostNameTemplate: "%s_%s_%s_%s" + + - set_fact: + protectType: "{{ REPTYPE[metroEnable+protectLevel|string]['enum'] }}" # See ../../config/project001.yml + replicaType: "{{ REPTYPE[metroEnable+protectLevel|string]['type'] }}" # See ../../config/project001.yml + + - set_fact: + primaryLunIds: [] + primaryLunsInTier: [] + primaryLg00Names: [] + primaryHostNames: [] + metroLunIds: [] + metroLunNames: [] + metroLunsInTier: [] + metroLg00Names: [] + metroHostNames: [] + drLunIds: [] + drLg00Names: [] + drHostNames: [] + drLunNames: [] + drLunsInTier: [] + drTestLunIds: [] + drTestLg00Names: [] + drTestHostNames: [] + drTestLunNames: [] + existDrTestLuns: [] + + - set_fact: + Precheck_1_Execute: True + Precheck_2_Execute: "{{ (metroEnable == 'Y') }}" + Precheck_3_Execute: "{{ (protectLevel|int >= 2) }}" + Precheck_4_Execute: "{{ (protectLevel|int == 3) }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/user/login.yml" + + - block: + - name: Precheck_1 - Check Primary Protection Group + debug: + msg: + pg: "{{ primaryPgName }}" + device: "{{ primaryDeviceSn }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/volume/check_volumes.yml" + vars: + volumeNames: "{{ primaryLunNames }}" + + - set_fact: + primaryLunsInTier: "{{ checkedVolumes | json_query(queryLunsName) }}" + primaryLunsInTierClass: "{{ checkedVolumes | json_query(queryLunsInTierClass) }}" + primaryLunsSize: "{{ checkedVolumes | json_query('[*].capacity') }}" + primaryLunsClass: [] + vars: + queryLunsName: "[? service_level_name != '' && service_level_name != null ].name" + queryLunsInTierClass: "[? service_level_name != '' && service_level_name != null ].service_level_name" + + - set_fact: + primaryLunsClass: "{{ primaryLunsClass + [ checkedVolumes[item.0].service_level_name ] }}" + with_indexed_items: "{{ primaryLunNames }}" + + - set_fact: + primaryLg00Names: "{{ primaryLg00Names + [hostName + '_LG00'] }}" + primaryHostNames: "{{ primaryHostNames + [hostName] }}" + vars: + field: "{{ item.split('_') }}" + hostName: "{{ hostNameTemplate | format(field[0],field[1],field[2],field[3]) }}" + with_items: "{{ primaryLunNames }}" + + - set_fact: + primaryLg00UniqueNames: "{{ primaryLg00Names | unique }}" + primaryHostUniqueNames: "{{ primaryHostNames | unique }}" + + - name: Login Device + set_fact: + deviceSn: "{{ primaryDeviceSn }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/login_storage.yml" + + - set_fact: + primaryDeviceName: "{{ deviceName }}" + primaryDeviceHost: "{{ deviceHost }}" + primaryDevicePort: "{{ devicePort }}" + primaryDeviceToken: "{{ deviceToken }}" + primaryDeviceSession: "{{ deviceSession }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_pgs.yml" + vars: + pgNames: ["{{ primaryPgName }}"] + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_lgs.yml" + vars: + lgNames: "{{ primaryLg00UniqueNames }}" + + - set_fact: + checkedHostLuns: [] + + - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_host_lun_id_loop_helper.yml" + vars: + hostName: "{{ item }}" + with_items: "{{ primaryHostUniqueNames }}" + + - set_fact: + primaryHostLunsAll: [] + primaryHostLunIds: [] + + - set_fact: + primaryHostLunsAll: "{{ primaryHostLunsAll + checkedHostLuns[item.0][item.1] }}" + with_indexed_items: "{{ primaryLg00UniqueNames }}" + + - set_fact: + primaryHostLunIds: "{{ primaryHostLunIds + primaryHostLunsAll | json_query(queryScsiId) }}" + primaryLunIds: "{{ primaryLunIds + primaryHostLunsAll | json_query(queryLunId) }}" + vars: + queryScsiId: "[? lunName=='{{item}}'].hostLunId" + queryLunId: "[? lunName=='{{item}}'].lunId" + with_items: "{{ primaryLunNames }}" + + - name: Check Primary LUNs are Mapped to Host + debug: + msg: + primaryHostLunIds: "{{ primaryHostLunIds }}" + primaryLunNames: "{{ primaryLunNames }}" + failed_when: primaryLunNames|length != primaryHostLunIds|length + + - name: Get HyperMetro Pairs + uri: + url: "https://{{deviceHost}}:{{devicePort}}/deviceManager/rest/{{deviceSn}}/HyperMetroPair?filter=LOCALOBJNAME%3A%3A{{item}}" + method: GET + validate_certs: no + headers: + Accept: "application/json" + Content-Type: "application/json;charset=utf8" + iBaseToken: "{{ deviceToken }}" + Cookie: "session={{ deviceSession }}" + register: METRO_PAIRS + with_items: "{{ primaryLunNames }}" + when: metroEnable == 'Y' + + - name: Get Metro LUNs + vars: + queryMetroLunIds: "[*].REMOTEOBJID" + queryMetroLunNames: "[*].REMOTEOBJNAME" + set_fact: + metroLunIds: "{{ metroLunIds + METRO_PAIRS.results[item.0].json.data | default([]) | json_query(queryMetroLunIds) }}" + metroLunNames: "{{ metroLunNames + METRO_PAIRS.results[item.0].json.data | default([]) | json_query(queryMetroLunNames) }}" + with_indexed_items: "{{ primaryLunNames }}" + when: metroEnable == 'Y' + + - name: Check Exist Replication Pairs + uri: + url: "https://{{deviceHost}}:{{devicePort}}/deviceManager/rest/{{deviceSn}}/REPLICATIONPAIR?filter=LOCALRESNAME%3A%3A{{item}}" + method: GET + validate_certs: no + headers: + Accept: "application/json" + Content-Type: "application/json;charset=utf8" + iBaseToken: "{{ deviceToken }}" + Cookie: "session={{ deviceSession }}" + register: DR_PAIRS + with_items: "{{ primaryLunNames }}" + when: protectLevel|int >= 2 + + - name: Get DR LUNs + vars: + queryDrLunIds: "[? REMOTEDEVICEID=='{{drDevId}}'].REMOTERESID" + queryDrLunNames: "[? REMOTEDEVICEID=='{{drDevId}}'].REMOTERESNAME" + set_fact: + drLunIds: "{{ drLunIds + DR_PAIRS.results[item.0].json.data | default([]) | json_query(queryDrLunIds) }}" + drLunNames: "{{ drLunNames + DR_PAIRS.results[item.0].json.data | default([]) | json_query(queryDrLunNames) }}" + with_indexed_items: "{{ primaryLunNames }}" + when: protectLevel|int >= 2 + + # End Precheck_1 + when: Precheck_1_Execute + + + - block: + - name: Precheck_2 - Check Metro Protection Group + debug: + msg: + pg: "{{ primaryPgName }}" + device: "{{ metroDeviceSn }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/volume/check_volumes.yml" + vars: + volumeNames: "{{ metroLunNames }}" + + - set_fact: + metroLunsInTier: "{{ checkedVolumes | json_query(queryLunsInTier) }}" + metroLunsInTierClass: "{{ checkedVolumes | json_query(queryLunsInTierClass) }}" + metroLunsSize: "{{ checkedVolumes | json_query('[*].capacity') }}" + metroLunsClass: [] + vars: + queryLunsInTier: "[? service_level_name != '' && service_level_name != null ].name" + queryLunsInTierClass: "[? service_level_name != '' && service_level_name != null ].service_level_name" + + - set_fact: + metroLunsClass: "{{ metroLunsClass + [ checkedVolumes[item.0].service_level_name ] }}" + with_indexed_items: "{{ metroLunNames }}" + + - set_fact: + metroLg00Names: "{{ metroLg00Names + [hostName + '_LG00'] }}" + metroHostNames: "{{ metroHostNames + [hostName] }}" + vars: + field: "{{ item.split('_') }}" + hostName: "{{ hostNameTemplate | format(field[0],field[1],field[2],field[3]) }}" + with_items: "{{ metroLunNames }}" + + - set_fact: + metroLg00UniqueNames: "{{ metroLg00Names | unique }}" + metroHostUniqueNames: "{{ metroHostNames | unique }}" + + - name: Login Metro Device + set_fact: + deviceSn: "{{ metroDeviceSn }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/login_storage.yml" + + - set_fact: + metroDeviceName: "{{ deviceName }}" + metroDeviceHost: "{{ deviceHost }}" + metroDevicePort: "{{ devicePort }}" + metroDeviceToken: "{{ deviceToken }}" + metroDeviceSession: "{{ deviceSession }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_pgs.yml" + vars: + pgNames: ["{{ primaryPgName }}"] + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_lgs.yml" + vars: + lgNames: "{{ metroLg00UniqueNames }}" + + - set_fact: + checkedHostLuns: [] + + - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_host_lun_id_loop_helper.yml" + vars: + hostName: "{{ item }}" + with_items: "{{ metroHostNames }}" + + - set_fact: + metroHostLunsAll: [] + metroHostLunIds: [] + + - set_fact: + metroHostLunsAll: "{{ metroHostLunsAll + checkedHostLuns[item.0][item.1] }}" + with_indexed_items: "{{ metroLg00UniqueNames }}" + + - set_fact: + metroHostLunIds: "{{ metroHostLunIds + metroHostLunsAll | json_query(queryScsiId) }}" + vars: + queryScsiId: "[? lunName=='{{item}}'].hostLunId" + with_items: "{{ metroLunNames }}" + + - name: Check Metro LUNs are Mapped to Host + debug: + msg: + metroHostLunIds: "{{ metroHostLunIds }}" + metroLunNames: "{{ metroLunNames }}" + failed_when: (metroLunNames|length != metroHostLunIds|length) + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_luns.yml" + vars: + lunNames: "{{ metroLunNames }}" + + - set_fact: + metroLunsDesc: "{{ checkedLuns | json_query('[*].DESCRIPTION') }}" + metroLunsSector: "{{ checkedLuns | json_query('[*].CAPACITY') }}" + metroLunsPool: "{{ checkedLuns | json_query('[*].PARENTID') }}" + metroLunsWorkload: "{{ checkedLuns | json_query('[*].WORKLOADTYPEID') }}" + + # Need to Delete DR Star When remove the last LUNs + - set_fact: + deleteDrStar: "{{ True if (metroHostLunsAll|length == metroLunNames|length) else False}}" + when: protectLevel|int >= 2 + + # Need to Disable DR Star when remove LUNs from CG + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_drstars.yml" + vars: + drStarNames: [ "{{ drStarCgName }}" ] + checkExist: True + when: protectLevel|int >= 2 + + # End Precheck_2 + when: + - Precheck_2_Execute + - metroLunNames|length > 0 + + + - block: + - name: Precheck_3 - Check DR Protection Group + debug: + msg: + pg: "{{ drPgName }}" + device: "{{ drDeviceSn }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/volume/check_volumes.yml" + vars: + volumeNames: "{{ drLunNames }}" + + - set_fact: + drLunsInTier: "{{ checkedVolumes | json_query(queryLunsInTier) }}" + drLunsInTierClass: "{{ checkedVolumes | json_query(queryLunsInTierClass) }}" + drLunsSize: "{{ checkedVolumes | json_query('[*].capacity') }}" + drLunsClass: [] + vars: + queryLunsInTier: "[? service_level_name != '' && service_level_name != null ].name" + queryLunsInTierClass: "[? service_level_name != '' && service_level_name != null ].service_level_name" + + - set_fact: + drLunsClass: "{{ drLunsClass + [ checkedVolumes[item.0].service_level_name ] }}" + with_indexed_items: "{{ drLunNames }}" + + - set_fact: + drLg00Names: "{{ drLg00Names + [hostName + '_LG00'] }}" + drHostNames: "{{ drHostNames + [hostName] }}" + vars: + field: "{{ item.split('_') }}" + hostName: "{{ hostNameTemplate | format(field[0],field[1],field[2],field[3]) }}" + with_items: "{{ drLunNames }}" + + - set_fact: + drLg00UniqueNames: "{{ drLg00Names | unique }}" + drHostUniqueNames: "{{ drHostNames | unique }}" + + - name: Login DR Device + set_fact: + deviceSn: "{{ drDeviceSn }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/login_storage.yml" + + - set_fact: + drDeviceName: "{{ deviceName }}" + drDeviceHost: "{{ deviceHost }}" + drDevicePort: "{{ devicePort }}" + drDeviceToken: "{{ deviceToken }}" + drDeviceSession: "{{ deviceSession }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_pgs.yml" + vars: + pgNames: ["{{ drPgName }}"] + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_lgs.yml" + vars: + lgNames: "{{ drLg00UniqueNames }}" + + - set_fact: + checkedHostLuns: [] + + - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_host_lun_id_loop_helper.yml" + vars: + hostName: "{{ item }}" + with_items: "{{ drHostUniqueNames }}" + + - set_fact: + drHostLunsAll: [] + drHostLunIds: [] + + - set_fact: + drHostLunsAll: "{{ drHostLunsAll + checkedHostLuns[item.0][item.1] }}" + with_indexed_items: "{{ drLg00UniqueNames }}" + + - set_fact: + drHostLunIds: "{{ drHostLunIds + drHostLunsAll | json_query(queryScsiId) }}" + vars: + queryScsiId: "[? lunName=='{{item}}'].hostLunId" + with_items: "{{ drLunNames }}" + + - name: Check DR LUNs are Mapped to Host + debug: + msg: + drHostLunIds: "{{ drHostLunIds }}" + drLunNames: "{{ drLunNames }}" + failed_when: (drLunNames|length != drHostLunIds|length) + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_luns.yml" + vars: + lunNames: "{{ drLunNames }}" + + - set_fact: + drLunsDesc: "{{ checkedLuns | json_query('[*].DESCRIPTION') }}" + drLunsSector: "{{ checkedLuns | json_query('[*].CAPACITY') }}" + drLunsPool: "{{ checkedLuns | json_query('[*].PARENTID') }}" + drLunsWorkload: "{{ checkedLuns | json_query('[*].WORKLOADTYPEID') }}" + + - name: Query Snapshots in CG + uri: + url: "https://{{deviceHost}}:{{devicePort}}/deviceManager/rest/{{deviceSn}}/snapshot/associate?ASSOCIATEOBJTYPE=57646&ASSOCIATEOBJID={{drTestCgId}}" + method: GET + validate_certs: no + headers: + Accept: "application/json" + Content-Type: "application/json;charset=utf8" + iBaseToken: "{{ deviceToken }}" + Cookie: "session={{ deviceSession }}" + register: SNAPSHOTS + when: protectLevel|int == 3 + + - set_fact: + drTestLunNames: "{{ drTestLunNames + SNAPSHOTS.json.data | default([]) | json_query(querySnapName) }}" + vars: + querySnapName: "[? SOURCELUNNAME == '{{item}}'].NAME" + with_items: "{{ drLunNames }}" + when: protectLevel|int == 3 + + - set_fact: + drTestLunNamesAll: "{{ SNAPSHOTS.json.data | default([]) | json_query('[*].NAME') }}" + + # End Precheck_3 + when: + - Precheck_3_Execute + - drLunNames|length > 0 + + + - block: + - name: Precheck_4 - Check DR Test Protection Group + debug: + msg: + pg: "{{ drPgName }}" + device: "{{ drDeviceSn }}" + + - set_fact: + drTestLg00Names: "{{ drTestLg00Names + [hostName + '_LG00'] }}" + drTestHostNames: "{{ drTestHostNames + [hostName] }}" + vars: + field: "{{ item.split('_') }}" + hostName: "{{ hostNameTemplate | format(field[0],field[1],field[2],field[3]) }}" + with_items: "{{ drTestLunNamesAll }}" + + - set_fact: + drTestLg00UniqueNames: "{{ drTestLg00Names | unique }}" + drTestHostUniqueNames: "{{ drTestHostNames | unique }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_lgs.yml" + vars: + lgNames: "{{ drTestLg00UniqueNames }}" + + - set_fact: + checkedHostLuns: [] + + - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_host_lun_id_loop_helper.yml" + vars: + hostName: "{{ item }}" + with_items: "{{ drTestHostUniqueNames }}" + + - set_fact: + drTestHostLunsAll: [] + + - set_fact: + drTestHostLunsAll: "{{ drTestHostLunsAll + checkedHostLuns[item.0][item.1] }}" + with_indexed_items: "{{ drTestLg00UniqueNames }}" + + - set_fact: + drTestLunsAll: "{{ drTestHostLunsAll | json_query('[*].lunName') }}" + drTestLunsAllId: "{{ drTestHostLunsAll | json_query('[*].lunId') }}" + drTestLunsAllScsiId: "{{ drTestHostLunsAll | json_query('[*].hostLunId') }}" + drTestLunScsiIds: [] + + - set_fact: + drTestLunIds: "{{ drTestLunIds + drTestHostLunsAll | json_query(queryLunId) }}" + drTestLunScsiIds: "{{ drTestLunScsiIds + drTestHostLunsAll | json_query(queryScsiId) }}" + vars: + queryScsiId: "[? lunName=='{{item}}'].hostLunId" + queryLunId: "[? lunName=='{{item}}'].lunId" + with_items: "{{ drTestLunNames }}" + + - name: Check DR Test LUNs are Mapped to Host + debug: + msg: + drTestLunScsiIds: "{{ drTestLunScsiIds }}" + drTestLunNames: "{{ drTestLunNames }}" + failed_when: (drTestLunNames|length != drTestLunScsiIds|length) + + - set_fact: + existDrTestLuns: "{{ drTestLunsAll | difference(drTestLunNames) }}" + existDrTestLunsId: "{{ drTestLunsAllId | difference(drTestLunIds) }}" + existDrTestLunsScsiId: "{{ drTestLunsAllScsiId | difference(drTestLunScsiIds) }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_luns.yml" + vars: + lunNames: "{{ drTestLunsAll }}" + + - set_fact: + drTestLunsAllSector: "{{ checkedLuns | json_query('[*].CAPACITY') }}" + drTestLunsAllDesc: "{{ checkedLuns | json_query('[*].DESCRIPTION') }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_luns.yml" + vars: + lunNames: "{{ existDrTestLuns }}" + + - set_fact: + existDrTestLunsSector: "{{ checkedLuns | json_query('[*].CAPACITY') }}" + existDrTestLunsDesc: "{{ checkedLuns | json_query('[*].DESCRIPTION') }}" + + # End Precheck_4 + when: + - Precheck_4_Execute + - drTestLunNames|length > 0 + + - block: + + # Begin Workflow Steps + + - set_fact: + + # Remove DR LUNs Class on DJ + Step_0_1_Execute: "{{ (protectLevel|int >= 2 and drLunsInTier|length > 0) }}" + Step_0_1_Completed: False + Step_0_1_Rollbacked: False + + # Remove Metro LUNs Class on DJ + Step_0_2_Execute: "{{ (metroEnable == 'Y' and metroLunsInTier|length > 0) }}" + Step_0_2_Completed: False + Step_0_2_Rollbacked: False + + # Remove Primary LUNs Class on DJ + Step_0_3_Execute: "{{ primaryLunsInTier|length > 0 }}" + Step_0_3_Completed: False + Step_0_3_Rollbacked: False + + # Remove DR Test LUNs from LUN Group + Step_1_1_Execute: "{{ (protectLevel|int == 3 and drTestLunNames|length > 0) and (drTestCgActivated|bool == False) }}" + Step_1_1_Completed: False + Step_1_1_Rollbacked: False + + # Delete DR Test Snapshot CG + Step_1_2_Execute: "{{ (protectLevel|int == 3 and drTestLunNames|length > 0) and (drTestCgActivated|bool == False) }}" + Step_1_2_Completed: False + Step_1_2_Rollbacked: False + + # Remove DR LUNs from LUN Group + Step_1_3_Execute: "{{ (protectLevel|int >= 2 and drLunNames|length > 0) }}" + Step_1_3_Completed: False + Step_1_3_Rollbacked: False + + # Remove Metro LUNs from LUN Group + Step_1_4_Execute: "{{ (metroEnable == 'Y' and metroLunNames|length > 0) }}" + Step_1_4_Completed: False + Step_1_4_Rollbacked: False + + # Remove Primary LUNs from LUN Group + Step_1_5_Execute: True + Step_1_5_Completed: False + Step_1_5_Rollbacked: False + + # Delete DR Star + Step_2_0_Execute: "{{ (protectLevel|int >= 2 and drLunNames|length > 0) and (metroEnable == 'Y' and metroLunNames|length > 0) and (deleteDrStar|bool == True) }}" + Step_2_0_Completed: False + Step_2_0_Rollbacked: False + + # Disable DR Star + Step_2_1_Execute: "{{ (protectLevel|int >= 2 and drLunNames|length > 0) and (metroEnable == 'Y' and metroLunNames|length > 0) and (deleteDrStar|bool == False) }}" + Step_2_1_Completed: False + Step_2_1_Rollbacked: False + + # Remove DR LUNs from Protection Group + Step_3_0_1_Execute: "{{ (protectLevel|int >= 2 and drLunNames|length > 0) }}" + Step_3_0_1_Completed: False + Step_3_0_1_Rollbacked: False + + # Remove Metro LUNs from Protection Group + Step_3_0_2_Execute: "{{ (metroEnable == 'Y' and metroLunNames|length > 0) }}" + Step_3_0_2_Completed: False + Step_3_0_2_Rollbacked: False + + # Remove Primary LUNs from Protection Group + Step_3_0_3_Execute: True + Step_3_0_3_Completed: False + Step_3_0_3_Rollbacked: False + + # Remove Standby DR Pairs from Standby Replication CG + Step_2_2_Execute: "{{ (protectLevel|int >= 2 and drLunNames|length > 0) and (metroEnable == 'Y' and metroLunNames|length > 0) }}" + Step_2_2_Completed: False + Step_2_2_Rollbacked: False + + # Remove DR Pairs from Replication CG + Step_2_3_Execute: "{{ (protectLevel|int >= 2 and drLunNames|length > 0) }}" + Step_2_3_Completed: False + Step_2_3_Rollbacked: False + + # Remove Metro Pairs from HyperMetro CG + Step_2_4_Execute: "{{ (metroEnable == 'Y' and metroLunNames|length > 0) }}" + Step_2_4_Completed: False + Step_2_4_Rollbacked: False + + # Enable DR Star + Step_2_5_Execute: "{{ (protectLevel|int >= 2 and drLunNames|length > 0) and (metroEnable == 'Y' and metroLunNames|length > 0) and (deleteDrStar|bool == False) }}" + Step_2_5_Completed: False + Step_2_5_Rollbacked: False + + # Re-create DR Test Snapshot CG + Step_3_1_Execute: "{{ (protectLevel|int == 3 and existDrTestLuns|length > 0) and (drTestCgActivated|bool == False) }}" + Step_3_1_Completed: False + Step_3_1_Rollbacked: False + + # Add Existing DR Test LUNs to LUN Group + Step_3_2_Execute: "{{ (protectLevel|int == 3 and existDrTestLuns|length > 0) and (drTestCgActivated|bool == False) }}" + Step_3_2_Completed: False + Step_3_2_Rollbacked: False + + # Delete DR LUNs + Step_3_3_Execute: "{{ (protectLevel|int >= 2 and drLunNames|length > 0) and (drTestCgActivated|bool == False) }}" + Step_3_3_Completed: False + Step_3_3_Rollbacked: False + + # Delete Metro LUNs + Step_3_4_Execute: "{{ (metroEnable == 'Y' and metroLunNames|length > 0) }}" + Step_3_4_Completed: False + Step_3_4_Rollbacked: False + + # Delete Empty DR Test LUN Group + Step_3_5_Execute: "{{ (protectLevel|int == 3 and drTestLunNames|length > 0) and (drTestCgActivated|bool == False) }}" + Step_3_5_Completed: False + Step_3_5_Rollbacked: False + + # Delete Empty DR LUN Group + Step_3_6_Execute: "{{ (protectLevel|int >= 2 and drLunNames|length > 0) }}" + Step_3_6_Completed: False + Step_3_6_Rollbacked: False + + # Delete Empty Metro LUN Group + Step_3_7_Execute: "{{ (metroEnable == 'Y' and metroLunNames|length > 0) }}" + Step_3_7_Completed: False + Step_3_7_Rollbacked: False + + deviceSynced: [] + + # Sync Primary Device + Step_4_1_Execute: True + Step_4_1_Completed: False + + # Sync Metro Device + Step_4_2_Execute: "{{ (metroEnable == 'Y' and metroLunNames|length > 0) }}" + Step_4_2_Completed: False + + # Sync DR Device + Step_4_3_Execute: "{{ (protectLevel|int >= 2 and drLunNames|length > 0) }}" + Step_4_3_Completed: False + + # Insert Primary LUNs to KPI table + Step_5_1_Execute: True + Step_5_1_Completed: False + + # Insert Metro LUNs to KPI table + Step_5_2_Execute: "{{ (metroEnable == 'Y' and metroLunNames|length > 0) }}" + Step_5_2_Completed: False + + # Insert DR LUNs to KPI table + Step_5_3_Execute: "{{ (protectLevel|int >= 2 and drLunNames|length > 0) }}" + Step_5_3_Completed: False + + # Insert DR Test LUNs to KPI table + Step_5_4_Execute: "{{ (protectLevel|int == 3 and drTestLunNames|length > 0) and (drTestCgActivated|bool == False) }}" + Step_5_4_Completed: False + + # Update Existing DR Test LUNs to KPI table + Step_5_5_Execute: "{{ (protectLevel|int == 3 and existDrTestLuns|length > 0) and (drTestCgActivated|bool == False) }}" + Step_5_5_Completed: False + + - name: Workflow - Remove LUNs from Protection Group + debug: + msg: + Step_0_1: "[{{Step_0_1_Execute}}] Remove DR LUNs Class on DJ" + Step_0_2: "[{{Step_0_2_Execute}}] Remove Metro LUNs Class on DJ" + Step_0_3: "[{{Step_0_3_Execute}}] Remove Primary LUNs Class on DJ" + Step_1_1: "[{{Step_1_1_Execute}}] Remove DR Test LUNs from LUN Group" + Step_1_2: "[{{Step_1_2_Execute}}] Delete DR Test Snapshot CG" + Step_1_3: "[{{Step_1_3_Execute}}] Remove DR LUNs from LUN Group" + Step_1_4: "[{{Step_1_4_Execute}}] Remove Metro LUNs from LUN Group" + Step_1_5: "[{{Step_1_5_Execute}}] Remove Primary LUNs from LUN Group" + Step_2_0: "[{{Step_2_0_Execute}}] Delete DR Star" + Step_2_1: "[{{Step_2_1_Execute}}] Disable DR Star" + Step_3_0_1: "[{{Step_3_0_1_Execute}}] Remove DR LUNs from Protection Group" + Step_3_0_2: "[{{Step_3_0_2_Execute}}] Remove Metro LUNs from Protection Group" + Step_3_0_3: "[{{Step_3_0_3_Execute}}] Remove Primary LUNs from Protection Group" + Step_2_2: "[{{Step_2_2_Execute}}] Remove Standby DR Pairs from Standby Replication CG" + Step_2_3: "[{{Step_2_3_Execute}}] Remove DR Pairs from Replication CG" + Step_2_4: "[{{Step_2_4_Execute}}] Remove Metro Pairs from HyperMetro CG" + Step_2_5: "[{{Step_2_5_Execute}}] Enable DR Star" + Step_3_1: "[{{Step_3_1_Execute}}] Re-create DR Test Snapshot CG" + Step_3_2: "[{{Step_3_2_Execute}}] Add exist DR Test LUNs to LUN Group" + Step_3_3: "[{{Step_3_3_Execute}}] Delete DR LUNs" + Step_3_4: "[{{Step_3_4_Execute}}] Delete Metro LUNs" + Step_3_5: "[{{Step_3_5_Execute}}] Delete Empty DR Test LUN Group" + Step_3_6: "[{{Step_3_6_Execute}}] Delete Empty DR LUN Group" + Step_3_7: "[{{Step_3_7_Execute}}] Delete Empty Metro LUN Group" + Step_4_1: "[{{Step_4_1_Execute}}] Sync Primary Device" + Step_4_2: "[{{Step_4_2_Execute}}] Sync Metro Device" + Step_4_3: "[{{Step_4_3_Execute}}] Sync DR Device" + Step_5_1: "[{{Step_5_1_Execute}}] Insert Primary LUNs to KPI table" + Step_5_2: "[{{Step_5_2_Execute}}] Insert Metro LUNs to KPI table" + Step_5_3: "[{{Step_5_3_Execute}}] Insert DR LUNs to KPI table" + Step_5_4: "[{{Step_5_4_Execute}}] Insert DR Test LUNs to KPI table" + Step_5_5: "[{{Step_5_5_Execute}}] Update Existing DR Test LUNs to KPI table" + + + - block: + - name: Step_0_1 - Remove DR LUNs Class on DJ + debug: + msg: + params: + volumeNames: "{{ drLunsInTier }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/volume/remove_volumes_from_tier.yml" + vars: + volumeNames: "{{ drLunsInTier }}" + when: drLunsInTier|length > 0 + + - set_fact: + Step_0_1_Completed: True + + # End Step_0_1 + + # End block + when: Step_0_1_Execute + + - block: + - name: Step_0_2 - Remove Metro LUNs Class on DJ + debug: + msg: + params: + volumeNames: "{{ metroLunsInTier }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/volume/remove_volumes_from_tier.yml" + vars: + volumeNames: "{{ metroLunsInTier }}" + when: metroLunsInTier|length > 0 + + - set_fact: + Step_0_2_Completed: True + + # End Step_0_2 + + # End block + when: Step_0_2_Execute + + - block: + - name: Step_0_3 - Remove Primary LUNs Class on DJ + debug: + msg: + params: + volumeNames: "{{ primaryLunsInTier }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/volume/remove_volumes_from_tier.yml" + vars: + volumeNames: "{{ primaryLunsInTier }}" + when: primaryLunsInTier|length > 0 + + - set_fact: + Step_0_3_Completed: True + + # End Step_0_3 + + # End block + when: Step_0_3_Execute + + - block: + - name: Step_1_1 - Remove DR Test LUNs from LUN Group + debug: + msg: + params: + lg: "{{ drTestLg00Names }}" + lunNames: "{{ drTestLunsAll }}" + device: "{{ drDeviceName }}" + + - set_fact: + deviceHost: "{{ drDeviceHost }}" + devicePort: "{{ drDevicePort }}" + deviceSn: "{{ drDeviceSn }}" + deviceToken: "{{ drDeviceToken }}" + deviceSession: "{{ drDeviceSession }}" + + - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/remove_luns_from_lg.yml" + vars: + field: "{{ item.split('_') }}" + hostName: "{{ hostNameTemplate | format(field[0],field[1],field[2],field[3]) }}" + lgName: "{{ hostName + '_LG00' }}" + lunNames: [ "{{ item }}" ] + with_items: "{{ drTestLunsAll }}" + + - set_fact: + Step_1_1_Completed: True + + # End Step_1_1 + + # End block + when: Step_1_1_Execute + + - block: + - name: Step_1_2 - Delete DR Test Snapshot CG + debug: + msg: + params: + cgName: "{{ drTestCgName }}" + device: "{{ drDeviceName }}" + + - set_fact: + deviceHost: "{{ drDeviceHost }}" + devicePort: "{{ drDevicePort }}" + deviceSn: "{{ drDeviceSn }}" + deviceToken: "{{ drDeviceToken }}" + deviceSession: "{{ drDeviceSession }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/delete_snapshot_cg.yml" + vars: + cgName: "{{ drTestCgName }}" + + - set_fact: + Step_1_2_Completed: True + + # End Step_1_2 + + # End block + when: Step_1_2_Execute + + - block: + - name: Step_1_3 - Remove DR LUNs from LUN Group + debug: + msg: + params: + lg: "{{ drLg00Names }}" + lunNames: "{{ drLunNames }}" + device: "{{ drDeviceName }}" + + - set_fact: + deviceHost: "{{ drDeviceHost }}" + devicePort: "{{ drDevicePort }}" + deviceSn: "{{ drDeviceSn }}" + deviceToken: "{{ drDeviceToken }}" + deviceSession: "{{ drDeviceSession }}" + + - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/remove_luns_from_lg.yml" + vars: + lgName: "{{ item.0 }}" + lunNames: [ "{{ item.1 }}" ] + with_together: + - "{{ drLg00Names }}" + - "{{ drLunNames }}" + + - set_fact: + Step_1_3_Completed: True + + # End Step_1_3 + + # End block + when: Step_1_3_Execute + + - block: + - name: Step_1_4 - Remove Metro LUNs from LUN Group + debug: + msg: + params: + lg: "{{ metroLg00Names }}" + lunNames: "{{ metroLunNames }}" + device: "{{ metroDeviceName }}" + + - set_fact: + deviceHost: "{{ metroDeviceHost }}" + devicePort: "{{ metroDevicePort }}" + deviceSn: "{{ metroDeviceSn }}" + deviceToken: "{{ metroDeviceToken }}" + deviceSession: "{{ metroDeviceSession }}" + + - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/remove_luns_from_lg.yml" + vars: + lgName: "{{ item.0 }}" + lunNames: [ "{{ item.1 }}" ] + with_together: + - "{{ metroLg00Names }}" + - "{{ metroLunNames }}" + + - set_fact: + Step_1_4_Completed: True + + # End Step_1_4 + + # End block + when: Step_1_4_Execute + + - block: + - name: Step_1_5 - Remove Primary LUNs from LUN Group + debug: + msg: + params: + lg: "{{ primaryLg00Names }}" + lunNames: "{{ primaryLunNames }}" + device: "{{ primaryDeviceName }}" + + - set_fact: + deviceHost: "{{ primaryDeviceHost }}" + devicePort: "{{ primaryDevicePort }}" + deviceSn: "{{ primaryDeviceSn }}" + deviceToken: "{{ primaryDeviceToken }}" + deviceSession: "{{ primaryDeviceSession }}" + + - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/remove_luns_from_lg.yml" + vars: + lgName: "{{ item.0 }}" + lunNames: [ "{{ item.1 }}" ] + with_together: + - "{{ primaryLg00Names }}" + - "{{ primaryLunNames }}" + + - set_fact: + Step_1_5_Completed: True + + # End Step_1_5 + + # End block + when: Step_1_5_Execute + + - block: + - name: Step_2_0 - Delete DR Star + debug: + msg: + params: + drStarName: "{{ drStarCgName }}" + device: "{{ metroDeviceName }}" + + - set_fact: + deviceHost: "{{ metroDeviceHost }}" + devicePort: "{{ metroDevicePort }}" + deviceSn: "{{ metroDeviceSn }}" + deviceToken: "{{ metroDeviceToken }}" + deviceSession: "{{ metroDeviceSession }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/delete_drstar.yml" + vars: + drStarName: "{{ drStarCgName }}" + + - set_fact: + Step_2_0_Completed: True + + # End Step_2_0 + + # End block + when: Step_2_0_Execute + + - block: + - name: Step_2_1 - Disable DR Star + debug: + msg: + params: + drStarName: "{{ drStarCgName }}" + device: "{{ primaryDeviceName }}" + + - set_fact: + deviceHost: "{{ primaryDeviceHost }}" + devicePort: "{{ primaryDevicePort }}" + deviceSn: "{{ primaryDeviceSn }}" + deviceToken: "{{ primaryDeviceToken }}" + deviceSession: "{{ primaryDeviceSession }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/disable_drstar.yml" + vars: + drStarName: "{{ drStarCgName }}" + + - set_fact: + Step_2_1_Completed: True + + # End Step_2_1 + + # End block + when: Step_2_1_Execute + + - block: + - name: Step_3_0_1 - Remove DR LUNs from Protection Group + debug: + msg: + params: + pgName: "{{ drPgName }}" + lunNames: "{{ drLunNames }}" + device: "{{ drDeviceName }}" + + - set_fact: + deviceHost: "{{ drDeviceHost }}" + devicePort: "{{ drDevicePort }}" + deviceSn: "{{ drDeviceSn }}" + deviceToken: "{{ drDeviceToken }}" + deviceSession: "{{ drDeviceSession }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/remove_luns_from_pg.yml" + vars: + pgName: "{{ drPgName }}" + lunNames: "{{ drLunNames }}" + + - set_fact: + Step_3_0_1_Completed: True + + # End Step_3_0_1 + + # End block + when: Step_3_0_1_Execute + + - block: + - name: Step_3_0_2 - Remove Metro LUNs from Protection Group + debug: + msg: + params: + pgName: "{{ primaryPgName }}" + lunNames: "{{ metroLunNames }}" + device: "{{ metroDeviceName }}" + + - set_fact: + deviceHost: "{{ metroDeviceHost }}" + devicePort: "{{ metroDevicePort }}" + deviceSn: "{{ metroDeviceSn }}" + deviceToken: "{{ metroDeviceToken }}" + deviceSession: "{{ metroDeviceSession }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/remove_luns_from_pg.yml" + vars: + pgName: "{{ primaryPgName }}" + lunNames: "{{ metroLunNames }}" + + - set_fact: + Step_3_0_2_Completed: True + + # End Step_3_0_2 + + # End block + when: Step_3_0_2_Execute + + - block: + - name: Step_3_0_3 - Remove Primary LUNs from Protection Group + debug: + msg: + params: + pgName: "{{ primaryPgName }}" + lunNames: "{{ primaryLunNames }}" + device: "{{ primaryDeviceName }}" + + - set_fact: + deviceHost: "{{ primaryDeviceHost }}" + devicePort: "{{ primaryDevicePort }}" + deviceSn: "{{ primaryDeviceSn }}" + deviceToken: "{{ primaryDeviceToken }}" + deviceSession: "{{ primaryDeviceSession }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/remove_luns_from_pg.yml" + vars: + pgName: "{{ primaryPgName }}" + lunNames: "{{ primaryLunNames }}" + + - set_fact: + Step_3_0_3_Completed: True + + # End Step_3_0_3 + + # End block + when: Step_3_0_3_Execute + + - block: + - name: Step_2_2 - Remove Standby DR Pairs from Standby Replication CG + debug: + msg: + params: + pairs: + localLunIds: "{{ metroLunIds }}" + remoteLunIds: "{{ drLunIds }}" + cgName: "{{ standbyCgName }}" + deletePairs: True + device: "{{ metroDeviceName }}" + + - set_fact: + deviceHost: "{{ metroDeviceHost }}" + devicePort: "{{ metroDevicePort }}" + deviceSn: "{{ metroDeviceSn }}" + deviceToken: "{{ metroDeviceToken }}" + deviceSession: "{{ metroDeviceSession }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/remove_luns_from_replication_cg.yml" + vars: + cgName: "{{ standbyCgName }}" + localLunIds: "{{ metroLunIds }}" + remoteLunIds: "{{ drLunIds }}" + deletePairs: True + + - set_fact: + Step_2_2_Completed: True + + # End Step_2_2 + + # End block + when: Step_2_2_Execute + + - block: + - name: Step_2_3 - Remove DR Pairs from Replication CG + debug: + msg: + params: + pairs: + localLunIds: "{{ primaryLunIds }}" + remoteLunIds: "{{ drLunIds }}" + cgName: "{{ drCgName }}" + deletePairs: True + device: "{{ primaryDeviceName }}" + + - set_fact: + deviceHost: "{{ primaryDeviceHost }}" + devicePort: "{{ primaryDevicePort }}" + deviceSn: "{{ primaryDeviceSn }}" + deviceToken: "{{ primaryDeviceToken }}" + deviceSession: "{{ primaryDeviceSession }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/remove_luns_from_replication_cg.yml" + vars: + cgName: "{{ drCgName }}" + localLunIds: "{{ primaryLunIds }}" + remoteLunIds: "{{ drLunIds }}" + deletePairs: True + + - set_fact: + Step_2_3_Completed: True + + # End Step_2_3 + + # End block + when: Step_2_3_Execute + + - block: + - name: Step_2_4 - Remove Metro Pairs from HyperMetro CG + debug: + msg: + params: + pairs: + localLunIds: "{{ primaryLunIds }}" + remoteLunIds: "{{ metroLunIds }}" + cgName: "{{ metroCgName }}" + deletePairs: True + device: "{{ primaryDeviceName }}" + + - set_fact: + deviceHost: "{{ primaryDeviceHost }}" + devicePort: "{{ primaryDevicePort }}" + deviceSn: "{{ primaryDeviceSn }}" + deviceToken: "{{ primaryDeviceToken }}" + deviceSession: "{{ primaryDeviceSession }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/remove_luns_from_hypermetro_cg.yml" + vars: + cgName: "{{ metroCgName }}" + localLunIds: "{{ primaryLunIds }}" + remoteLunIds: "{{ metroLunIds }}" + deletePairs: True + + - set_fact: + Step_2_4_Completed: True + + # End Step_2_4 + + # End block + when: Step_2_4_Execute + + - block: + - name: Step_2_5 - Enable DR Star + debug: + msg: + params: + drStarName: "{{ drStarCgName }}" + device: "{{ primaryDeviceName }}" + + - set_fact: + deviceHost: "{{ primaryDeviceHost }}" + devicePort: "{{ primaryDevicePort }}" + deviceSn: "{{ primaryDeviceSn }}" + deviceToken: "{{ primaryDeviceToken }}" + deviceSession: "{{ primaryDeviceSession }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/enable_drstar.yml" + vars: + drStarName: "{{ drStarCgName }}" + + - set_fact: + Step_2_5_Completed: True + + # End Step_2_5 + + # End block + when: Step_2_5_Execute + + - block: + - name: Step_3_1 - Re-create DR Test Snapshot CG + debug: + msg: + params: + snapCg: + pgName: "{{ drPgName }}" + cgName: "{{ drTestCgName }}" + snapNames: "{{ existDrTestLuns }}" + activate: False + snapDescs: "{{ existDrTestLunsDesc }}" + device: "{{ drDeviceName }}" + + - set_fact: + deviceHost: "{{ drDeviceHost }}" + devicePort: "{{ drDevicePort }}" + deviceSn: "{{ drDeviceSn }}" + deviceToken: "{{ drDeviceToken }}" + deviceSession: "{{ drDeviceSession }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/create_snapshot_cg.yml" + vars: + pgName: "{{ drPgName }}" + cgName: "{{ drTestCgName }}" + snapNames: "{{ existDrTestLuns }}" + activate: False + snapDescs: "{{ existDrTestLunsDesc }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_luns.yml" + vars: + lunNames: "{{ existDrTestLuns }}" + checkExist: True + + - set_fact: + existDrTestLunsIdNew: "{{ lunIds }}" + Step_3_1_Completed: True + + # End Step_3_1 + + # End block + when: Step_3_1_Execute + + - block: + - name: Step_3_2 - Add Existing DR Test LUNs to LUN Group + debug: + msg: + params: + lunNames: "{{ existDrTestLuns }}" + addLunScsiIds: "{{ existDrTestLunsScsiId }}" + device: "{{ drDeviceName }}" + + - set_fact: + deviceHost: "{{ drDeviceHost }}" + devicePort: "{{ drDevicePort }}" + deviceSn: "{{ drDeviceSn }}" + deviceToken: "{{ drDeviceToken }}" + deviceSession: "{{ drDeviceSession }}" + + - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/add_luns_to_lg.yml" + vars: + field: "{{ item.0.split('_') }}" + hostName: "{{ hostNameTemplate | format(field[0],field[1],field[2],field[3]) }}" + lgName: "{{ hostName + '_LG00' }}" + lunNames: [ "{{ item.0 }}" ] + addLunScsiIds: [ "{{ item.1 }}" ] + with_together: + - "{{ existDrTestLuns }}" + - "{{ existDrTestLunsScsiId }}" + + - set_fact: + Step_3_2_Completed: True + + # End Step_3_2 + + # End block + when: Step_3_2_Execute + + - block: + - name: Step_3_3 - Delete DR LUNs + debug: + msg: + params: + lunNames: "{{ drLunNames }}" + device: "{{ drDeviceName }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/volume/disable_volumes_qos.yml" + vars: + volumeNames: "{{ drLunNames }}" + + - set_fact: + deviceHost: "{{ drDeviceHost }}" + devicePort: "{{ drDevicePort }}" + deviceSn: "{{ drDeviceSn }}" + deviceToken: "{{ drDeviceToken }}" + deviceSession: "{{ drDeviceSession }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/delete_luns.yml" + vars: + lunNames: "{{ drLunNames }}" + + - set_fact: + Step_3_3_Completed: True + + # End Step_3_3 + + # End block + when: Step_3_3_Execute + + - block: + - name: Step_3_4 - Delete Metro LUNs + debug: + msg: + params: + lunNames: "{{ metroLunNames }}" + device: "{{ metroDeviceName }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/volume/disable_volumes_qos.yml" + vars: + volumeNames: "{{ metroLunNames }}" + + - set_fact: + deviceHost: "{{ metroDeviceHost }}" + devicePort: "{{ metroDevicePort }}" + deviceSn: "{{ metroDeviceSn }}" + deviceToken: "{{ metroDeviceToken }}" + deviceSession: "{{ metroDeviceSession }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/delete_luns.yml" + vars: + lunNames: "{{ metroLunNames }}" + + - set_fact: + Step_3_4_Completed: True + + # End Step_3_4 + + # End block + when: Step_3_4_Execute + + - block: + - name: Step_3_5 - Delete Empty DR Test LUN Group + debug: + msg: + params: + lg: "{{ drTestLg00Names }}" + device: "{{ drDeviceName }}" + + - set_fact: + deviceHost: "{{ drDeviceHost }}" + devicePort: "{{ drDevicePort }}" + deviceSn: "{{ drDeviceSn }}" + deviceToken: "{{ drDeviceToken }}" + deviceSession: "{{ drDeviceSession }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_lgs.yml" + vars: + lgNames: "{{ drTestLg00UniqueNames }}" + + - set_fact: + drTestEmptyLg00Names: "{{ checkedLgs | json_query(queryName)}}" + drTestEmptyLg00Descs: "{{ checkedLgs | json_query(queryDesc)}}" + drTestEmptyLg00Hosts: [] + vars: + queryName: "[? lunNumber=='0'].NAME" + queryDesc: "[? lunNumber=='0'].NAME" + + - set_fact: + drTestEmptyLg00Hosts: "{{ drTestEmptyLg00Hosts + [ item[:-5] ]}}" + with_items: "{{ drTestEmptyLg00Names }}" + + - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/delete_lg.yml" + vars: + lgName: "{{ item }}" + unmap: True + with_items: "{{ drTestEmptyLg00Names }}" + + - set_fact: + Step_3_5_Completed: True + + # End Step_3_5 + + # End block + when: Step_3_5_Execute + + - block: + - name: Step_3_6 - Delete Empty DR LUN Group + debug: + msg: + params: + lg: "{{ drLg00Names }}" + device: "{{ drDeviceName }}" + + - set_fact: + deviceHost: "{{ drDeviceHost }}" + devicePort: "{{ drDevicePort }}" + deviceSn: "{{ drDeviceSn }}" + deviceToken: "{{ drDeviceToken }}" + deviceSession: "{{ drDeviceSession }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_lgs.yml" + vars: + lgNames: "{{ drLg00UniqueNames }}" + + - set_fact: + drEmptyLg00Names: "{{ checkedLgs | json_query(queryName)}}" + drEmptyLg00Descs: "{{ checkedLgs | json_query(queryDesc)}}" + drEmptyLg00Hosts: [] + vars: + queryName: "[? lunNumber=='0'].NAME" + queryDesc: "[? lunNumber=='0'].NAME" + + - set_fact: + drEmptyLg00Hosts: "{{ drEmptyLg00Hosts + [ item[:-5] ]}}" + with_items: "{{ drEmptyLg00Names }}" + + - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/delete_lg.yml" + vars: + lgName: "{{ item }}" + unmap: True + with_items: "{{ drEmptyLg00Names }}" + + - set_fact: + Step_3_6_Completed: True + + # End Step_3_6 + + # End block + when: Step_3_6_Execute + + - block: + - name: Step_3_7 - Delete Empty Metro LUN Group + debug: + msg: + params: + lg: "{{ metroLg00Names }}" + device: "{{ metroDeviceName }}" + + - set_fact: + deviceHost: "{{ metroDeviceHost }}" + devicePort: "{{ metroDevicePort }}" + deviceSn: "{{ metroDeviceSn }}" + deviceToken: "{{ metroDeviceToken }}" + deviceSession: "{{ metroDeviceSession }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_lgs.yml" + vars: + lgNames: "{{ metroLg00UniqueNames }}" + + - set_fact: + metroEmptyLg00Names: "{{ checkedLgs | json_query(queryName)}}" + metroEmptyLg00Descs: "{{ checkedLgs | json_query(queryDesc)}}" + metroEmptyLg00Hosts: [] + vars: + queryName: "[? lunNumber=='0'].NAME" + queryDesc: "[? lunNumber=='0'].NAME" + + - set_fact: + metroEmptyLg00Hosts: "{{ metroEmptyLg00Hosts + [ item[:-5] ]}}" + with_items: "{{ metroEmptyLg00Names }}" + + - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/delete_lg.yml" + vars: + lgName: "{{ item }}" + unmap: True + with_items: "{{ metroEmptyLg00Names }}" + + - set_fact: + Step_3_7_Completed: True + + # End Step_3_7 + + # End block + when: Step_3_7_Execute + + # End Device Steps + + # Begin DJ Steps + + - block: + - name: Step_4_1 - Sync Primary Device + debug: + msg: + params: + deviceName: "{{ primaryDeviceName }}" + + - set_fact: + deviceName: "{{ primaryDeviceName }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/sync_storage.yml" + + - set_fact: + deviceSynced: "{{ deviceSynced + [primaryDeviceName] }}" + + - set_fact: + Step_4_1_Completed: True + + # End Step_4_1 + + # End block + when: Step_4_1_Execute + + - block: + - name: Step_4_2 - Sync Metro Device + debug: + msg: + params: + deviceName: "{{ metroDeviceName }}" + + - set_fact: + deviceName: "{{ metroDeviceName }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/sync_storage.yml" + when: + - metroDeviceName not in deviceSynced + + - set_fact: + deviceSynced: "{{ deviceSynced + [metroDeviceName] }}" + when: + - metroDeviceName not in deviceSynced + + - set_fact: + Step_4_2_Completed: True + + # End Step_4_2 + + # End block + when: Step_4_2_Execute + + - block: + - name: Step_4_3 - Sync DR Device + debug: + msg: + params: + deviceName: "{{ drDeviceName }}" + + - set_fact: + deviceName: "{{ drDeviceName }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/sync_storage.yml" + when: + - drDeviceName not in deviceSynced + + - set_fact: + deviceSynced: "{{ deviceSynced + [drDeviceName] }}" + when: + - drDeviceName not in deviceSynced + + - set_fact: + Step_4_3_Completed: True + + # End Step_4_3 + + # End block + when: Step_4_3_Execute + + # End DJ Steps + + - block: + - name: Step_5_1 - Insert Primary LUNs to KPI table + debug: + msg: + params: + lunIds: "{{ primaryLunIds }}" + device: "{{ primaryDeviceName }}" + + # Minus capacity from primary host + - include_tasks: update_lun_kpi_table.yml + vars: + TYPE_OF_OPERATION: "modify" + WBE_CODE: "{{ WBE_CODE }}" + TICKET_NUMBER: "{{ TICKET_NUMBER }}" + SYSTEM_NAME: "" + SITE: "{{ primarySite }}" + ENVIRONMENT: "" + STORAGE_CLASS: "{{ primaryLunsClass[item.0] }}" + CAPACITY_GB: "-{{ primaryLunsSize[item.0] }}" + STORAGE: "{{ primaryDeviceName }}" + VDISK_UID: "{{ item.1 }}" + with_indexed_items: "{{ primaryLunIds }}" + + # Add orphan capacity + - include_tasks: update_lun_kpi_table.yml + vars: + TYPE_OF_OPERATION: "modify" + WBE_CODE: "{{ WBE_CODE }}" + TICKET_NUMBER: "{{ TICKET_NUMBER }}" + SYSTEM_NAME: "" + SITE: "{{ primarySite }}" + ENVIRONMENT: "" + STORAGE_CLASS: "" + CAPACITY_GB: "{{ primaryLunsSize[item.0] }}" + STORAGE: "{{ primaryDeviceName }}" + VDISK_UID: "{{ item.1 }}" + with_indexed_items: "{{ primaryLunIds }}" + + - set_fact: + Step_5_1_Completed: True + + # End Step_5_1 + + # End block + when: Step_5_1_Execute + + - block: + - name: Step_5_2 - Insert Metro LUNs to KPI table + debug: + msg: + params: + lunIds: "{{ metroLunIds }}" + device: "{{ metroDeviceName }}" + + - include_tasks: update_lun_kpi_table.yml + vars: + TYPE_OF_OPERATION: "delete" + WBE_CODE: "{{ WBE_CODE }}" + TICKET_NUMBER: "{{ TICKET_NUMBER }}" + SYSTEM_NAME: "" + SITE: "{{ metroSite }}" + ENVIRONMENT: "" + STORAGE_CLASS: "{{ metroLunsClass[item.0] }}" + CAPACITY_GB: "-{{ metroLunsSize[item.0] }}" + STORAGE: "{{ metroDeviceName }}" + VDISK_UID: "{{ item.1 }}" + with_indexed_items: "{{ metroLunIds }}" + + - set_fact: + Step_5_2_Completed: True + + # End Step_5_2 + + # End block + when: Step_5_2_Execute + + - block: + - name: Step_5_3 - Insert DR LUNs to KPI table + debug: + msg: + params: + lunIds: "{{ drLunIds }}" + device: "{{ drDeviceName }}" + + - include_tasks: update_lun_kpi_table.yml + vars: + TYPE_OF_OPERATION: "delete" + WBE_CODE: "{{ WBE_CODE }}" + TICKET_NUMBER: "{{ TICKET_NUMBER }}" + SYSTEM_NAME: "" + SITE: "{{ drSite }}" + ENVIRONMENT: "" + STORAGE_CLASS: "{{ drLunsClass[item.0] }}" + CAPACITY_GB: "-{{ drLunsSize[item.0] }}" + STORAGE: "{{ drDeviceName }}" + VDISK_UID: "{{ item.1 }}" + with_indexed_items: "{{ drLunIds }}" + when: drTestCgActivated|bool == False + + - include_tasks: update_lun_kpi_table.yml + vars: + TYPE_OF_OPERATION: "modify" + WBE_CODE: "{{ WBE_CODE }}" + TICKET_NUMBER: "{{ TICKET_NUMBER }}" + SYSTEM_NAME: "" + SITE: "{{ drSite }}" + ENVIRONMENT: "" + STORAGE_CLASS: "{{ drLunsClass[item.0] }}" + CAPACITY_GB: "-{{ drLunsSize[item.0] }}" + STORAGE: "{{ drDeviceName }}" + VDISK_UID: "{{ item.1 }}" + with_indexed_items: "{{ drLunIds }}" + when: drTestCgActivated|bool == True + + # Update orphan DR LUNs + - include_tasks: update_lun_kpi_table.yml + vars: + TYPE_OF_OPERATION: "modify" + WBE_CODE: "{{ WBE_CODE }}" + TICKET_NUMBER: "{{ TICKET_NUMBER }}" + SYSTEM_NAME: "" + SITE: "{{ drSite }}" + ENVIRONMENT: "" + STORAGE_CLASS: "" + CAPACITY_GB: "{{ drLunsSize[item.0] }}" + STORAGE: "{{ drDeviceName }}" + VDISK_UID: "{{ item.1 }}" + with_indexed_items: "{{ drLunIds }}" + when: drTestCgActivated|bool == True + + - set_fact: + Step_5_3_Completed: True + + # End Step_5_3 + + # End block + when: Step_5_3_Execute + + - block: + - name: Step_5_4 - Insert DR Test LUNs to KPI table + debug: + msg: + params: + lunIds: "{{ drTestLunsAllId }}" + device: "{{ drDeviceName }}" + + - include_tasks: update_lun_kpi_table.yml + vars: + TYPE_OF_OPERATION: "delete" + WBE_CODE: "{{ WBE_CODE }}" + TICKET_NUMBER: "{{ TICKET_NUMBER }}" + SYSTEM_NAME: "" + SITE: "{{ drSite }}" + ENVIRONMENT: "" + STORAGE_CLASS: "" + CAPACITY_GB: "-{{ (drTestLunsAllSector[item.0]|int / 1024 / 1024 / 2)|int }}" + STORAGE: "{{ drDeviceName }}" + VDISK_UID: "{{ item.1 }}" + with_indexed_items: "{{ drTestLunsAllId }}" + + - set_fact: + Step_5_4_Completed: True + + # End Step_5_4 + + # End block + when: Step_5_4_Execute + + - block: + - name: Step_5_5 - Update Existing DR Test LUNs to KPI table + debug: + msg: + params: + lunIds: + old: "{{ existDrTestLunsId }}" + new: "{{ existDrTestLunsIdNew }}" + device: "{{ drDeviceName }}" + + - include_tasks: update_lun_kpi_table.yml + vars: + TYPE_OF_OPERATION: "create" + WBE_CODE: "{{ WBE_CODE }}" + TICKET_NUMBER: "{{ TICKET_NUMBER }}" + SYSTEM_NAME: "" + SITE: "{{ drSite }}" + ENVIRONMENT: "" + STORAGE_CLASS: "" + CAPACITY_GB: "{{ (existDrTestLunsSector[item.0]|int / 1024 / 1024 / 2)|int }}" + STORAGE: "{{ drDeviceName }}" + VDISK_UID: "{{ item.1 }}" + with_indexed_items: "{{ existDrTestLunsIdNew }}" + + - set_fact: + Step_5_5_Completed: True + + # End Step_5_5 + + # End block + when: Step_5_5_Execute + + # End Block + rescue: + # Begin Rollback + + - block: + - name: Rollback_3_7 - Create Metro LUN Group + debug: + msg: + params: + lg: "{{ metroEmptyLg00Names }}" + device: "{{ metroDeviceName }}" + + - set_fact: + deviceHost: "{{ metroDeviceHost }}" + devicePort: "{{ metroDevicePort }}" + deviceSn: "{{ metroDeviceSn }}" + deviceToken: "{{ metroDeviceToken }}" + deviceSession: "{{ metroDeviceSession }}" + + - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/create_lg.yml" + vars: + lgName: "{{ item.0 }}" + mapHostNames: ["{{ item.1 }}"] + desc: "{{ item.2 }}" + with_together: + - "{{ metroEmptyLg00Names }}" + - "{{ metroEmptyLg00Hosts }}" + - "{{ metroEmptyLg00Descs }}" + + - set_fact: + Step_3_7_Rollbacked: True + + # End Rollback_3_7 + + # End block + when: Step_3_7_Completed + + - block: + - name: Rollback_3_6 - Create DR LUN Group + debug: + msg: + params: + lg: "{{ drEmptyLg00Names }}" + device: "{{ drDeviceName }}" + + - set_fact: + deviceHost: "{{ drDeviceHost }}" + devicePort: "{{ drDevicePort }}" + deviceSn: "{{ drDeviceSn }}" + deviceToken: "{{ drDeviceToken }}" + deviceSession: "{{ drDeviceSession }}" + + - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/create_lg.yml" + vars: + lgName: "{{ item.0 }}" + mapHostNames: ["{{ item.1 }}"] + desc: "{{ item.2 }}" + with_together: + - "{{ drEmptyLg00Names }}" + - "{{ drEmptyLg00Hosts }}" + - "{{ drEmptyLg00Descs }}" + + - set_fact: + Step_3_6_Rollbacked: True + + # End Rollback_3_6 + + # End block + when: Step_3_6_Completed + + - block: + - name: Rollback_3_5 - Create DR Test LUN Group + debug: + msg: + params: + lg: "{{ drTestEmptyLg00Names }}" + device: "{{ drDeviceName }}" + + - set_fact: + deviceHost: "{{ drDeviceHost }}" + devicePort: "{{ drDevicePort }}" + deviceSn: "{{ drDeviceSn }}" + deviceToken: "{{ drDeviceToken }}" + deviceSession: "{{ drDeviceSession }}" + + - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/create_lg.yml" + vars: + lgName: "{{ item.0 }}" + mapHostNames: ["{{ item.1 }}"] + desc: "{{ item.2 }}" + with_together: + - "{{ drTestEmptyLg00Names }}" + - "{{ drTestEmptyLg00Hosts }}" + - "{{ drTestEmptyLg00Descs }}" + + - set_fact: + Step_3_5_Rollbacked: True + + # End Rollback_3_5 + + # End block + when: Step_3_5_Completed + + - block: + - name: Rollback_3_4 - Create Metro LUNs + debug: + msg: + params: + lunNames: "{{ metroLunNames }}" + lunDescs: "{{ metroLunsDesc }}" + device: "{{ metroDeviceName }}" + + - set_fact: + deviceHost: "{{ metroDeviceHost }}" + devicePort: "{{ metroDevicePort }}" + deviceSn: "{{ metroDeviceSn }}" + deviceToken: "{{ metroDeviceToken }}" + deviceSession: "{{ metroDeviceSession }}" + + - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/create_lun.yml" + vars: + lunName: "{{ metroLunNames[i] }}" + lunSector: "{{ metroLunsSector[i] }}" + poolId: "{{ metroLunsPool[i] }}" + workload: "{{ metroLunsWorkload[i] }}" + desc: "{{ metroLunsDesc[i] }}" + loop: "{{ range(0, metroLunNames|length) | list }}" + loop_control: + loop_var: i + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_luns.yml" + vars: + lunNames: "{{ metroLunNames }}" + + - set_fact: + metroLunIds: "{{ lunIds }}" + Step_3_4_Rollbacked: True + + # End block + when: Step_3_4_Completed + + - block: + - name: Rollback_3_3 - Create DR LUNs + debug: + msg: + params: + lunNames: "{{ drLunNames }}" + lunDescs: "{{ drLunsDesc }}" + device: "{{ drDeviceName }}" + + - set_fact: + deviceHost: "{{ drDeviceHost }}" + devicePort: "{{ drDevicePort }}" + deviceSn: "{{ drDeviceSn }}" + deviceToken: "{{ drDeviceToken }}" + deviceSession: "{{ drDeviceSession }}" + + - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/create_lun.yml" + vars: + lunName: "{{ drLunNames[i] }}" + lunSector: "{{ drLunsSector[i] }}" + poolId: "{{ drLunsPool[i] }}" + workload: "{{ drLunsWorkload[i] }}" + desc: "{{ drLunsDesc[i] }}" + loop: "{{ range(0, drLunNames|length) | list }}" + loop_control: + loop_var: i + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_luns.yml" + vars: + lunNames: "{{ drLunNames }}" + + - set_fact: + drLunIds: "{{ lunIds }}" + Step_3_3_Rollbacked: True + + # End block + when: Step_3_3_Completed + + - block: + - name: Rollback_3_2 - Remove Existing DR Test LUNs from LUN Group + debug: + msg: + params: + lunNames: "{{ existDrTestLuns }}" + device: "{{ drDeviceName }}" + + - set_fact: + deviceHost: "{{ drDeviceHost }}" + devicePort: "{{ drDevicePort }}" + deviceSn: "{{ drDeviceSn }}" + deviceToken: "{{ drDeviceToken }}" + deviceSession: "{{ drDeviceSession }}" + + - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/remove_luns_from_lg.yml" + vars: + field: "{{ item.split('_') }}" + hostName: "{{ hostNameTemplate | format(field[0],field[1],field[2],field[3]) }}" + lgName: "{{ hostName + '_LG00' }}" + lunNames: [ "{{ item }}" ] + with_items: "{{ existDrTestLuns }}" + + - set_fact: + Step_3_2_Rollbacked: True + + # End block + when: Step_3_2_Completed + + - block: + - name: Rollback_3_1 - Delete DR Test Snapshot CG + debug: + msg: + params: + cgName: "{{ drTestCgName }}" + device: "{{ drDeviceName }}" + + - set_fact: + deviceHost: "{{ drDeviceHost }}" + devicePort: "{{ drDevicePort }}" + deviceSn: "{{ drDeviceSn }}" + deviceToken: "{{ drDeviceToken }}" + deviceSession: "{{ drDeviceSession }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/delete_snapshot_cg.yml" + vars: + cgName: "{{ drTestCgName }}" + + - set_fact: + Step_3_1_Rollbacked: True + + # End block + when: Step_3_1_Completed + + - block: + - name: Rollback_1_5 - Add Primary LUNs to LUN Group + debug: + msg: + params: + lg: "{{ primaryLg00Names }}" + lunNames: "{{ primaryLunNames }}" + addLunScsiIds: "{{ primaryHostLunIds }}" + device: "{{ primaryDeviceName }}" + + - set_fact: + deviceHost: "{{ primaryDeviceHost }}" + devicePort: "{{ primaryDevicePort }}" + deviceSn: "{{ primaryDeviceSn }}" + deviceToken: "{{ primaryDeviceToken }}" + deviceSession: "{{ primaryDeviceSession }}" + + - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/add_luns_to_lg.yml" + vars: + lgName: "{{ item.0 }}" + lunNames: [ "{{ item.1 }}" ] + addLunScsiIds: [ "{{ item.2 }}" ] + with_together: + - "{{ primaryLg00Names }}" + - "{{ primaryLunNames }}" + - "{{ primaryHostLunIds }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/create_hypermetro_pairs.yml" + vars: + localLunIds: "{{ primaryLunIds }}" + remoteLunIds: "{{ metroLunIds }}" + remoteSn: "{{ metroDeviceSn }}" + when: Step_2_4_Completed + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/create_replication_pairs.yml" + vars: + localLunIds: "{{ primaryLunIds }}" + remoteLunIds: "{{ drLunIds }}" + remoteSn: "{{ drDeviceSn }}" + mode: "{{ drCgModeEnum }}" + when: Step_2_3_Completed + + - set_fact: + Step_1_5_Rollbacked: True + + # End Step_1_5 + + # End block + when: Step_1_5_Completed + + - block: + - name: Rollback_1_4 - Add Metro LUNs to LUN Group + debug: + msg: + params: + lg: "{{ metroLg00Names }}" + lunNames: "{{ metroLunNames }}" + addLunScsiIds: "{{ metroHostLunIds }}" + device: "{{ metroDeviceName }}" + + - set_fact: + deviceHost: "{{ metroDeviceHost }}" + devicePort: "{{ metroDevicePort }}" + deviceSn: "{{ metroDeviceSn }}" + deviceToken: "{{ metroDeviceToken }}" + deviceSession: "{{ metroDeviceSession }}" + + - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/add_luns_to_lg.yml" + vars: + lgName: "{{ item.0 }}" + lunNames: [ "{{ item.1 }}" ] + addLunScsiIds: [ "{{ item.2 }}" ] + with_together: + - "{{ metroLg00Names }}" + - "{{ metroLunNames }}" + - "{{ metroHostLunIds }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/create_replication_pairs.yml" + vars: + localLunIds: "{{ metroLunIds }}" + remoteLunIds: "{{ drLunIds }}" + remoteSn: "{{ drDeviceSn }}" + mode: "{{ GLOBAL.replication.syncMode.async }}" + standby: True + when: Step_2_2_Completed + + - set_fact: + Step_1_4_Rollbacked: True + + # End Rollback_1_4 + + # End block + when: Step_1_4_Completed + + - block: + - name: Rollback_1_3 - Add DR LUNs to LUN Group + debug: + msg: + params: + lg: "{{ drLg00Names }}" + lunNames: "{{ drLunNames }}" + addLunScsiIds: "{{ drHostLunIds }}" + device: "{{ drDeviceName }}" + + - set_fact: + deviceHost: "{{ drDeviceHost }}" + devicePort: "{{ drDevicePort }}" + deviceSn: "{{ drDeviceSn }}" + deviceToken: "{{ drDeviceToken }}" + deviceSession: "{{ drDeviceSession }}" + + - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/add_luns_to_lg.yml" + vars: + lgName: "{{ item.0 }}" + lunNames: [ "{{ item.1 }}" ] + addLunScsiIds: [ "{{ item.2 }}" ] + with_together: + - "{{ drLg00Names }}" + - "{{ drLunNames }}" + - "{{ drHostLunIds }}" + + - set_fact: + Step_1_3_Rollbacked: True + + # End Rollback_1_3 + + # End block + when: Step_1_3_Completed + + - block: + - name: Rollback_2_5 - Disable DR Star + debug: + msg: + params: + drStarName: "{{ drStarCgName }}" + device: "{{ primaryDeviceName }}" + + - set_fact: + deviceHost: "{{ primaryDeviceHost }}" + devicePort: "{{ primaryDevicePort }}" + deviceSn: "{{ primaryDeviceSn }}" + deviceToken: "{{ primaryDeviceToken }}" + deviceSession: "{{ primaryDeviceSession }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/disable_drstar.yml" + vars: + drStarName: "{{ drStarCgName }}" + + - set_fact: + Step_2_5_Rollbacked: True + + # End Rollback_2_5 + + # End block + when: Step_2_5_Completed + + + - block: + - name: Rollback_2_4 - Add Metro Pairs to HyperMetro CG + debug: + msg: + params: + pairs: + localLunIds: "{{ primaryLunIds }}" + remoteLunIds: "{{ metroLunIds }}" + cgName: "{{ metroCgName }}" + device: "{{ primaryDeviceName }}" + + - set_fact: + deviceHost: "{{ primaryDeviceHost }}" + devicePort: "{{ primaryDevicePort }}" + deviceSn: "{{ primaryDeviceSn }}" + deviceToken: "{{ primaryDeviceToken }}" + deviceSession: "{{ primaryDeviceSession }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/add_luns_to_hypermetro_cg.yml" + vars: + cgName: "{{ metroCgName }}" + localLunIds: "{{ primaryLunIds }}" + remoteLunIds: "{{ metroLunIds }}" + waitSync: True + + - set_fact: + Step_2_4_Rollbacked: True + + # End Rollback_2_4 + + # End block + when: Step_2_4_Completed + + + - block: + - name: Rollback_2_3 - Add DR Pairs to Replication CG + debug: + msg: + params: + pairs: + localLunIds: "{{ primaryLunIds }}" + remoteLunIds: "{{ drLunIds }}" + cgName: "{{ drCgName }}" + device: "{{ primaryDeviceName }}" + + - set_fact: + deviceHost: "{{ primaryDeviceHost }}" + devicePort: "{{ primaryDevicePort }}" + deviceSn: "{{ primaryDeviceSn }}" + deviceToken: "{{ primaryDeviceToken }}" + deviceSession: "{{ primaryDeviceSession }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/add_luns_to_replication_cg.yml" + vars: + cgName: "{{ drCgName }}" + localLunIds: "{{ primaryLunIds }}" + remoteLunIds: "{{ drLunIds }}" + waitSync: True + + - set_fact: + Step_2_3_Rollbacked: True + + # End Rollback_2_3 + + # End block + when: Step_2_3_Completed + + - block: + - name: Rollback_2_2 - Add Standby DR Pairs to Standby Replication CG + debug: + msg: + params: + pairs: + localLunIds: "{{ metroLunIds }}" + remoteLunIds: "{{ drLunIds }}" + cgName: "{{ standbyCgName }}" + device: "{{ metroDeviceName }}" + + - set_fact: + deviceHost: "{{ metroDeviceHost }}" + devicePort: "{{ metroDevicePort }}" + deviceSn: "{{ metroDeviceSn }}" + deviceToken: "{{ metroDeviceToken }}" + deviceSession: "{{ metroDeviceSession }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/add_luns_to_replication_cg.yml" + vars: + cgName: "{{ standbyCgName }}" + localLunIds: "{{ metroLunIds }}" + remoteLunIds: "{{ drLunIds }}" + standby: True + + - set_fact: + Step_2_2_Rollbacked: True + + # End Rollback_2_2 + + # End block + when: Step_2_2_Completed + + - block: + - name: Rollback_3_0_3 - Add Primary LUNs to Protection Group + debug: + msg: + params: + lunNames: "{{ primaryLunNames }}" + pgName: "{{ primaryPgName }}" + addLunScsiIds: "{{ primaryHostLunIds }}" + device: "{{ primaryDeviceName }}" + + - set_fact: + deviceHost: "{{ primaryDeviceHost }}" + devicePort: "{{ primaryDevicePort }}" + deviceSn: "{{ primaryDeviceSn }}" + deviceToken: "{{ primaryDeviceToken }}" + deviceSession: "{{ primaryDeviceSession }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/add_luns_to_pg.yml" + vars: + pgName: "{{ primaryPgName }}" + lunNames: "{{ primaryLunNames }}" + addLunScsiIds: "{{ primaryHostLunIds }}" + + - set_fact: + Step_3_0_3_Rollbacked: True + + # End Step_3_0_3 + + # End block + when: Step_3_0_3_Completed + + - block: + - name: Rollback_3_0_2 - Add Metro LUNs to Protection Group + debug: + msg: + params: + lunNames: "{{ metroLunNames }}" + pgName: "{{ primaryPgName }}" + addLunScsiIds: "{{ metroHostLunIds }}" + device: "{{ metroDeviceName }}" + + - set_fact: + deviceHost: "{{ metroDeviceHost }}" + devicePort: "{{ metroDevicePort }}" + deviceSn: "{{ metroDeviceSn }}" + deviceToken: "{{ metroDeviceToken }}" + deviceSession: "{{ metroDeviceSession }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/add_luns_to_pg.yml" + vars: + pgName: "{{ primaryPgName }}" + lunNames: "{{ metroLunNames }}" + addLunScsiIds: "{{ metroHostLunIds }}" + + - set_fact: + Step_3_0_2_Rollbacked: True + + # End Rollback_3_0_2 + + # End block + when: Step_3_0_2_Completed + + - block: + - name: Rollback_3_0_1 - Add DR LUNs to Protection Group + debug: + msg: + params: + lunNames: "{{ drLunNames }}" + pgName: "{{ drPgName }}" + addLunScsiIds: "{{ drHostLunIds }}" + device: "{{ drDeviceName }}" + + - set_fact: + deviceHost: "{{ drDeviceHost }}" + devicePort: "{{ drDevicePort }}" + deviceSn: "{{ drDeviceSn }}" + deviceToken: "{{ drDeviceToken }}" + deviceSession: "{{ drDeviceSession }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/add_luns_to_pg.yml" + vars: + pgName: "{{ drPgName }}" + lunNames: "{{ drLunNames }}" + addLunScsiIds: "{{ drHostLunIds }}" + + - set_fact: + Step_3_0_1_Rollbacked: True + + # End Rollback_3_0_1 + + # End block + when: Step_3_0_1_Completed + + - block: + - name: Rollback_2_1 - Enable DR Star + debug: + msg: + params: + drStarName: "{{ drStarCgName }}" + device: "{{ primaryDeviceName }}" + + - set_fact: + deviceHost: "{{ primaryDeviceHost }}" + devicePort: "{{ primaryDevicePort }}" + deviceSn: "{{ primaryDeviceSn }}" + deviceToken: "{{ primaryDeviceToken }}" + deviceSession: "{{ primaryDeviceSession }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/enable_drstar.yml" + vars: + drStarName: "{{ drStarCgName }}" + + + - set_fact: + Step_2_1_Rollbacked: True + + # End Rollback_2_1 + + # End block + when: Step_2_1_Completed + + - block: + - name: Rollback_2_0 - Create DR Star + debug: + msg: + params: + drstar: + drStarName: "{{ drStarCgName }}" + mode: 1 # HyperMetro + Async Replication + memberType: 2 # CG + metroId: "{{ metroCgId }}" + asyncId: "{{ standbyCgId }}" + device: "{{ metroDeviceName }}" + + - set_fact: + deviceHost: "{{ metroDeviceHost }}" + devicePort: "{{ metroDevicePort }}" + deviceSn: "{{ metroDeviceSn }}" + deviceToken: "{{ metroDeviceToken }}" + deviceSession: "{{ metroDeviceSession }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/create_drstar.yml" + vars: + drStarName: "{{ drStarCgName }}" + mode: 1 # HyperMetro + Async Replication + memberType: 2 # CG + metroId: "{{ metroCgId }}" + asyncId: "{{ standbyCgId }}" + + - set_fact: + Step_2_0_Rollbacked: True + + # End Rollback_2_0 + + # End block + when: Step_2_0_Completed + + - block: + - name: Rollback_1_2 - Re-create DR Test Snapshot CG + debug: + msg: + params: + snapCg: + pgName: "{{ drPgName }}" + cgName: "{{ drTestCgName }}" + snapNames: "{{ drTestLunsAll }}" + activate: False + snapDescs: "{{ drTestLunsAllDesc }}" + device: "{{ drDeviceName }}" + + - set_fact: + deviceHost: "{{ drDeviceHost }}" + devicePort: "{{ drDevicePort }}" + deviceSn: "{{ drDeviceSn }}" + deviceToken: "{{ drDeviceToken }}" + deviceSession: "{{ drDeviceSession }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/create_snapshot_cg.yml" + vars: + pgName: "{{ drPgName }}" + cgName: "{{ drTestCgName }}" + snapNames: "{{ drTestLunsAll }}" + activate: False + snapDescs: "{{ drTestLunsAllDesc }}" + + - set_fact: + Step_1_2_Rollbacked: True + + # End block + when: Step_1_2_Completed + + - block: + - name: Rollback_1_1 - Add DR Test LUNs to LUN Group + debug: + msg: + params: + lg: "{{ drTestLg00Names }}" + lunNames: "{{ drTestLunsAll }}" + device: "{{ drDeviceName }}" + + - set_fact: + deviceHost: "{{ drDeviceHost }}" + devicePort: "{{ drDevicePort }}" + deviceSn: "{{ drDeviceSn }}" + deviceToken: "{{ drDeviceToken }}" + deviceSession: "{{ drDeviceSession }}" + + - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/add_luns_to_lg.yml" + vars: + field: "{{ item.split('_') }}" + hostName: "{{ hostNameTemplate | format(field[0],field[1],field[2],field[3]) }}" + lunNames: [ "{{ hostName + '_LG00' }}" ] + addLunScsiIds: [ "{{ item.2 }}" ] + with_together: + - "{{ drTestLunsAll }}" + - "{{ drTestLunsAllScsiId }}" + + - set_fact: + Step_1_1_Rollbacked: True + + # End Rollback_1_1 + + # End block + when: Step_1_1_Completed + + - block: + - name: Re-Sync Storage Devices + debug: + msg: + params: + devices: "{{ deviceSynced }}" + + - include_tasks: "{{GLOBAL.baseDir}}/task/storage/sync_storage.yml" + loop: "{{ deviceSynced }}" + loop_control: + loop_var: deviceName + + when: deviceSynced|length > 0 + + - block: + - name: Rollback_0_3 - Set Primary LUN Class on DJ + debug: + msg: + params: + volumeNames: "{{ primaryLunsInTier }}" + tierName: "{{ primaryLunsInTierClass }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/volume/check_volumes.yml" + vars: + volumeNames: "{{ primaryLunNames }}" + waitExist: True + + - include_tasks: "{{GLOBAL.baseDir}}/task/volume/add_volumes_to_tier.yml" + vars: + volumeNames: ["{{ primaryLunsInTier[i] }}"] + tierName: "{{ primaryLunsInTierClass[i] }}" + loop: "{{ range(0, primaryLunsInTier|length) | list }}" + loop_control: + loop_var: i + + - set_fact: + Step_0_3_Rollbacked: True + + # End block + when: Step_0_3_Completed + + - block: + - name: Rollback_0_2 - Set Metro LUN Class on DJ + debug: + msg: + params: + volumeNames: "{{ metroLunsInTier }}" + tierName: "{{ metroLunsInTierClass }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/volume/check_volumes.yml" + vars: + volumeNames: "{{ metroLunNames }}" + waitExist: True + + - include_tasks: "{{GLOBAL.baseDir}}/task/volume/add_volumes_to_tier.yml" + vars: + volumeNames: ["{{ metroLunsInTier[i] }}"] + tierName: "{{ metroLunsInTierClass[i] }}" + loop: "{{ range(0, metroLunsInTier|length) | list }}" + loop_control: + loop_var: i + + - set_fact: + Step_0_2_Rollbacked: True + + # End block + when: Step_0_2_Completed + + - block: + - name: Rollback_0_1 - Set DR LUN Class on DJ + debug: + msg: + params: + volumeNames: "{{ drLunsInTier }}" + tierName: "{{ drLunsInTierClass }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/volume/check_volumes.yml" + vars: + volumeNames: "{{ drLunNames }}" + waitExist: True + + - include_tasks: "{{GLOBAL.baseDir}}/task/volume/add_volumes_to_tier.yml" + vars: + volumeNames: ["{{ drLunsInTier[i] }}"] + tierName: "{{ drLunsInTierClass[i] }}" + loop: "{{ range(0, drLunsInTier|length) | list }}" + loop_control: + loop_var: i + + - set_fact: + Step_0_1_Rollbacked: True + + # End block + when: Step_0_1_Completed + + # End Rollbacks + + # End Workflow + + # Begin Validate Results + + - block: + + - name: Result_0_1 - Remove DR LUNs Class on DJ + debug: + msg: + params: + volumeNames: "{{ drLunsInTier }}" + result: + succeeded: "{{ Step_0_1_Completed }}" + rollbacked: "{{ Step_0_1_Rollbacked }}" + failed_when: Step_0_1_Completed|bool == False + when: Step_0_1_Execute + + - name: Result_0_2 - Remove Metro LUNs Class on DJ + debug: + msg: + params: + volumeNames: "{{ metroLunsInTier }}" + result: + succeeded: "{{ Step_0_2_Completed }}" + rollbacked: "{{ Step_0_2_Rollbacked }}" + failed_when: Step_0_2_Completed|bool == False + when: Step_0_2_Execute + + - name: Result_0_3 - Remove Primary LUNs Class on DJ + debug: + msg: + params: + volumeNames: "{{ primaryLunsInTier }}" + result: + succeeded: "{{ Step_0_3_Completed }}" + rollbacked: "{{ Step_0_3_Rollbacked }}" + failed_when: Step_0_3_Completed|bool == False + when: Step_0_3_Execute + + - name: Result_1_1 - Remove DR Test LUNs from LUN Group + debug: + msg: + params: + lunNames: "{{ drTestLunsAll }}" + device: "{{ drDeviceName }}" + result: + succeeded: "{{ Step_1_1_Completed }}" + rollbacked: "{{ Step_1_1_Rollbacked }}" + failed_when: Step_1_1_Completed|bool == False + when: Step_1_1_Execute + + - name: Result_1_2 - Delete DR Test Snapshot CG + debug: + msg: + params: + cgName: "{{ drTestCgName }}" + device: "{{ drDeviceName }}" + result: + succeeded: "{{ Step_1_2_Completed }}" + rollbacked: "{{ Step_1_2_Rollbacked }}" + failed_when: Step_1_2_Completed|bool == False + when: Step_1_2_Execute + + - name: Result_1_3 - Remove DR LUNs from LUN Group + debug: + msg: + params: + lunNames: "{{ drLunNames }}" + device: "{{ drDeviceName }}" + result: + succeeded: "{{ Step_1_3_Completed }}" + rollbacked: "{{ Step_1_3_Rollbacked }}" + failed_when: Step_1_3_Completed|bool == False + when: Step_1_3_Execute + + - name: Result_1_4 - Remove Metro LUNs from LUN Group + debug: + msg: + params: + lunNames: "{{ metroLunNames }}" + device: "{{ metroDeviceName }}" + result: + succeeded: "{{ Step_1_4_Completed }}" + rollbacked: "{{ Step_1_4_Rollbacked }}" + failed_when: Step_1_4_Completed|bool == False + when: Step_1_4_Execute + + + - name: Result_1_5 - Remove Primary LUNs from LUN Group + debug: + msg: + params: + lunNames: "{{ primaryLunNames }}" + device: "{{ primaryDeviceName }}" + result: + succeeded: "{{ Step_1_5_Completed }}" + rollbacked: "{{ Step_1_5_Rollbacked }}" + failed_when: Step_1_5_Completed|bool == False + when: Step_1_5_Execute + + - name: Result_2_0 - Delete DR Star + debug: + msg: + params: + drStarName: "{{ drStarCgName }}" + device: "{{ metroDeviceName }}" + result: + succeeded: "{{ Step_2_0_Completed }}" + rollbacked: "{{ Step_2_0_Rollbacked }}" + failed_when: Step_2_0_Completed|bool == False + when: Step_2_0_Execute + + - name: Result_2_1 - Disable DR Star + debug: + msg: + params: + drStarName: "{{ drStarCgName }}" + device: "{{ primaryDeviceName }}" + result: + succeeded: "{{ Step_2_1_Completed }}" + rollbacked: "{{ Step_2_1_Rollbacked }}" + failed_when: Step_2_1_Completed|bool == False + when: Step_2_1_Execute + + - name: Result_2_2 - Remove Standby DR Pairs from Standby Replication CG + debug: + msg: + params: + pairs: + localLunIds: "{{ metroLunIds }}" + remoteLunIds: "{{ drLunIds }}" + cgName: "{{ standbyCgName }}" + deletePairs: True + device: "{{ metroDeviceName }}" + result: + succeeded: "{{ Step_2_2_Completed }}" + rollbacked: "{{ Step_2_2_Rollbacked }}" + failed_when: Step_2_2_Completed|bool == False + when: Step_2_2_Execute + + - name: Result_2_3 - Remove DR Pairs from Replication CG + debug: + msg: + params: + pairs: + localLunIds: "{{ primaryLunIds }}" + remoteLunIds: "{{ drLunIds }}" + cgName: "{{ drCgName }}" + deletePairs: True + device: "{{ primaryDeviceName }}" + result: + succeeded: "{{ Step_2_3_Completed }}" + rollbacked: "{{ Step_2_3_Rollbacked }}" + failed_when: Step_2_3_Completed|bool == False + when: Step_2_3_Execute + + - name: Result_2_4 - Remove Metro Pairs from HyperMetro CG + debug: + msg: + params: + pairs: + localLunIds: "{{ primaryLunIds }}" + remoteLunIds: "{{ metroLunIds }}" + cgName: "{{ metroCgName }}" + deletePairs: True + device: "{{ primaryDeviceName }}" + result: + succeeded: "{{ Step_2_4_Completed }}" + rollbacked: "{{ Step_2_4_Rollbacked }}" + failed_when: Step_2_4_Completed|bool == False + when: Step_2_4_Execute + + - name: Result_2_5 - Enable DR Star + debug: + msg: + params: + drStarName: "{{ drStarCgName }}" + device: "{{ primaryDeviceName }}" + result: + succeeded: "{{ Step_2_5_Completed }}" + rollbacked: "{{ Step_2_5_Rollbacked }}" + failed_when: Step_2_5_Completed|bool == False + when: Step_2_5_Execute + + - name: Result_3_1 - Re-create DR Test Snapshot CG + debug: + msg: + params: + snapCg: + pgName: "{{ drPgName }}" + cgName: "{{ drTestCgName }}" + snapNames: "{{ existDrTestLuns }}" + activate: False + snapDescs: "{{ existDrTestLunsDesc }}" + result: + succeeded: "{{ Step_3_1_Completed }}" + rollbacked: "{{ Step_3_1_Rollbacked }}" + failed_when: Step_3_1_Completed|bool == False + when: Step_3_1_Execute + + - name: Result_3_2 - Add Existing DR Test LUNs to LUN Group + debug: + msg: + params: + lunNames: "{{ existDrTestLuns }}" + addLunScsiIds: "{{ existDrTestLunsScsiId }}" + device: "{{ drDeviceName }}" + result: + succeeded: "{{ Step_3_2_Completed }}" + rollbacked: "{{ Step_3_2_Rollbacked }}" + failed_when: Step_3_2_Completed|bool == False + when: Step_3_2_Execute + + - name: Result_3_3 - Delete DR LUNs + debug: + msg: + params: + lunNames: "{{ drLunNames }}" + device: "{{ drDeviceName }}" + result: + succeeded: "{{ Step_3_3_Completed }}" + rollbacked: "{{ Step_3_3_Rollbacked }}" + failed_when: Step_3_3_Completed|bool == False + when: Step_3_3_Execute + + - name: Result_3_4 - Delete Metro LUNs + debug: + msg: + params: + lunNames: "{{ metroLunNames }}" + device: "{{ metroDeviceName }}" + result: + succeeded: "{{ Step_3_4_Completed }}" + rollbacked: "{{ Step_3_4_Rollbacked }}" + failed_when: Step_3_4_Completed|bool == False + when: Step_3_4_Execute + + - name: Result_3_5 - Delete Empty DR Test Lun Group + debug: + msg: + params: + lg: "{{ drTestEmptyLg00Names }}" + device: "{{ drDeviceName }}" + result: + succeeded: "{{ Step_3_5_Completed }}" + rollbacked: "{{ Step_3_5_Rollbacked }}" + failed_when: Step_3_5_Completed|bool == False + when: Step_3_5_Execute + + - name: Result_3_6 - Delete Empty DR Lun Group + debug: + msg: + params: + lg: "{{ drEmptyLg00Names }}" + device: "{{ drDeviceName }}" + result: + succeeded: "{{ Step_3_6_Completed }}" + rollbacked: "{{ Step_3_6_Rollbacked }}" + failed_when: Step_3_6_Completed|bool == False + when: Step_3_6_Execute + + - name: Result_3_7 - Delete Empty Metro Lun Group + debug: + msg: + params: + lg: "{{ metroEmptyLg00Names }}" + device: "{{ metroDeviceName }}" + result: + succeeded: "{{ Step_3_7_Completed }}" + rollbacked: "{{ Step_3_7_Rollbacked }}" + failed_when: Step_3_7_Completed|bool == False + when: Step_3_7_Execute + + - name: Result_4_1 - Sync Primary Device + debug: + msg: + params: + deviceName: "{{ primaryDeviceName }}" + result: + succeeded: "{{ Step_4_1_Completed }}" + failed_when: Step_4_1_Completed|bool == False + when: Step_4_1_Execute + + - name: Result_4_2 - Sync Metro Device + debug: + msg: + params: + deviceName: "{{ metroDeviceName }}" + result: + succeeded: "{{ Step_4_2_Completed }}" + failed_when: Step_4_2_Completed|bool == False + when: Step_4_2_Execute + + - name: Result_4_3 - Sync DR Device + debug: + msg: + params: + deviceName: "{{ drDeviceName }}" + result: + succeeded: "{{ Step_4_3_Completed }}" + failed_when: Step_4_3_Completed|bool == False + when: Step_4_3_Execute + + - name: Result_5_1 - Insert Primary LUNs to KPI table + debug: + msg: + params: + lunIds: "{{ primaryLunIds }}" + device: "{{ primaryDeviceName }}" + result: + succeeded: "{{ Step_5_1_Completed }}" + failed_when: Step_5_1_Completed|bool == False + when: Step_5_1_Execute + + - name: Result_5_2 - Insert Metro LUNs to KPI table + debug: + msg: + params: + lunIds: "{{ metroLunIds }}" + device: "{{ metroDeviceName }}" + result: + succeeded: "{{ Step_5_2_Completed }}" + failed_when: Step_5_2_Completed|bool == False + when: Step_5_2_Execute + + - name: Result_5_3 - Insert DR LUNs to KPI table + debug: + msg: + params: + lunIds: "{{ drLunIds }}" + device: "{{ drDeviceName }}" + result: + succeeded: "{{ Step_5_3_Completed }}" + failed_when: Step_5_3_Completed|bool == False + when: Step_5_3_Execute + + - name: Result_5_4 - Insert DR Test LUNs to KPI table + debug: + msg: + params: + lunIds: "{{ drTestLunsAllId }}" + device: "{{ drDeviceName }}" + result: + succeeded: "{{ Step_5_4_Completed }}" + failed_when: Step_5_4_Completed|bool == False + when: Step_5_4_Execute + + - name: Result_5_5 - Update Existing DR Test LUNs to KPI table + debug: + msg: + params: + lunIds: + old: "{{ existDrTestLunsId }}" + new: "{{ existDrTestLunsIdNew }}" + device: "{{ drDeviceName }}" + result: + succeeded: "{{ Step_5_5_Completed }}" + failed_when: Step_5_5_Completed|bool == False + when: Step_5_5_Execute + + # End Validate Results + + # End Tasks + +# End Playbook \ No newline at end of file diff --git a/rundeck/workflow/project001/52_delete_pg.yml b/rundeck/workflow/project001/52_delete_pg.yml new file mode 100644 index 0000000..ce9e1a4 --- /dev/null +++ b/rundeck/workflow/project001/52_delete_pg.yml @@ -0,0 +1,915 @@ +- name: Delete Protection Group + hosts: localhost + vars_files: + - ../../../config/global.yml + - ../../../config/project001.yml + gather_facts: no + become: no + tasks: + # Check Protection Group Params + - block: + - set_fact: + checked_pg_params: + Storage: "{{ (Storage is not none and Storage != DEFAULT.noneValue) and (Storage|string|length == 20) }}" + Protection_Group: "{{ Protection_Group is not none and Protection_Group != DEFAULT.noneValue }}" + Enable_HyperMetro: "{{ Enable_HyperMetro in ['Y','N'] }}" + Protection_Level: "{{ Protection_Level|int in [1,2,3] }}" + Check_Result_1: "{{ ('pg' in Check_Result_1) }}" + + - name: Precheck_0_1 - Check Protection Group Params + debug: + msg: "{{checked_pg_params}}" + failed_when: checked_pg_params.values()|unique != [True] + + # Check Metro Protection Group Params + - block: + - set_fact: + checked_metro_pg_params: + Metro_Storage: "{{ (Metro_Storage is not none and Metro_Storage != DEFAULT.noneValue) and (Metro_Storage|string|length == 20) }}" + Metro_Protection_Group: "{{ Metro_Protection_Group is not none and Metro_Protection_Group != DEFAULT.noneValue }}" + Metro_CG: "{{ Metro_CG is not none and Metro_CG != DEFAULT.noneValue }}" + Check_Result_2: "{{ ('pg' in Check_Result_2) }}" + + - name: Precheck_0_2 - Check Metro Protection Group Params + debug: + msg: "{{checked_metro_pg_params}}" + failed_when: checked_metro_pg_params.values()|unique != [True] + when: Enable_HyperMetro == 'Y' + + # Check DR Protection Group Params + - block: + - set_fact: + checked_dr_pg_params: + DR_Storage: "{{ (DR_Storage is not none and DR_Storage != DEFAULT.noneValue) and (DR_Storage|string|length == 20) }}" + DR_Protection_Group: "{{ DR_Protection_Group is not none and DR_Protection_Group != DEFAULT.noneValue }}" + DR_CG: "{{ DR_CG is not none and DR_CG != DEFAULT.noneValue }}" + Check_Result_3: "{{ ('pg' in Check_Result_3) }}" + + - name: Precheck_0_3 - Check DR Protection Group Params + debug: + msg: "{{checked_dr_pg_params}}" + failed_when: checked_dr_pg_params.values()|unique != [True] + when: Protection_Level|int >= 2 + + - name: Set variables + set_fact: + primaryDeviceSn: "{{ Storage|string if (Storage is not none) else none }}" + primaryPgName: "{{ Protection_Group }}" + sessionName: "{{ Session_Name }}" + metroEnable: "{{ Enable_HyperMetro }}" + protectLevel: "{{ Protection_Level }}" + metroDeviceSn: "{{ Metro_Storage|string }}" + drDeviceSn: "{{ DR_Storage|string }}" + drPgName: "{{ DR_Protection_Group }}" + + + - set_fact: + Precheck_0_Execute: True + Precheck_1_Execute: True + Precheck_2_Execute: "{{ (metroEnable == 'Y') }}" + Precheck_3_Execute: "{{ (protectLevel|int >= 2) }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/user/login.yml" + + - block: + - name: Precheck_1 - Check Primary Protection Group + debug: + msg: + pg: "{{ primaryPgName }}" + device: "{{ primaryDeviceSn }}" + + - name: Login Device + set_fact: + deviceSn: "{{ primaryDeviceSn }}" + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/login_storage.yml" + + - set_fact: + primaryDeviceName: "{{ deviceName }}" + primaryDeviceHost: "{{ deviceHost }}" + primaryDevicePort: "{{ devicePort }}" + primaryDeviceToken: "{{ deviceToken }}" + primaryDeviceSession: "{{ deviceSession }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_pgs.yml" + vars: + pgNames: ["{{ primaryPgName }}"] + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/get_pg.yml" + vars: + pgName: "{{ primaryPgName }}" + + - set_fact: + primaryPg: "{{ checkedPg }}" + primaryRepCgNum: "{{ checkedPg['replicationGroupNum']|int }}" + primaryMetroCgNum: "{{ checkedPg['hyperMetroGroupNum']|int }}" + + - name: Check No Snapshot CG + vars: + snapCgNum: "{{ checkedPg['snapshotGroupNum']|int }}" + fail: + msg: "Snapshot CG exists: {{ checkedPg['snapshotGroupName'] }}" + when: snapCgNum|int > 0 + + - name: Check No Clone CG + vars: + cloneCgNum: "{{ checkedPg['cloneGroupNum']|int }}" + fail: + msg: "Clone CG exists: {{ checkedPg['cloneGroupName'] }}" + when: cloneCgNum|int > 0 + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_replication_cgs.yml" + vars: + cgNames: "{{ checkedPg['replicationGroupName'].split(',') }}" + when: primaryRepCgNum|int > 0 + + - set_fact: + primaryRepCgs: "{{ checkedRepCgs }}" + when: primaryRepCgNum|int > 0 + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_hypermetro_cgs.yml" + vars: + cgNames: ["{{ checkedPg['hyperMetroName'] }}"] + when: primaryMetroCgNum|int == 1 + + - set_fact: + primaryMetroCg: "{{ checkedMetroCgs[0] }}" + when: primaryMetroCgNum|int == 1 + + # End Precheck_1 + + when: Precheck_1_Execute + + - block: + - name: Precheck_2 - Check Metro Protection Group + debug: + msg: + pg: "{{ primaryPgName }}" + device: "{{ metroDeviceSn }}" + + - name: Login Metro Device + set_fact: + deviceSn: "{{ metroDeviceSn }}" + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/login_storage.yml" + + - set_fact: + metroDeviceName: "{{ deviceName }}" + metroDeviceHost: "{{ deviceHost }}" + metroDevicePort: "{{ devicePort }}" + metroDeviceToken: "{{ deviceToken }}" + metroDeviceSession: "{{ deviceSession }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_pgs.yml" + vars: + pgNames: ["{{ primaryPgName }}"] + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/get_pg.yml" + vars: + pgName: "{{ primaryPgName }}" + + - set_fact: + metroPg: "{{ checkedPg }}" + metroRepCgNum: "{{ checkedPg['replicationGroupNum']|int }}" + + - name: Check No Snapshot CG + vars: + snapCgNum: "{{ checkedPg['snapshotGroupNum']|int }}" + fail: + msg: "Snapshot CG exists: {{ checkedPg['snapshotGroupName'] }}" + when: snapCgNum|int > 0 + + - name: Check No Clone CG + vars: + cloneCgNum: "{{ checkedPg['cloneGroupNum']|int }}" + fail: + msg: "Clone CG exists: {{ checkedPg['cloneGroupName'] }}" + when: cloneCgNum|int > 0 + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_replication_cgs.yml" + vars: + cgNames: "{{ checkedPg['replicationGroupName'].split(',') }}" + when: metroRepCgNum|int > 0 + + - set_fact: + standbyRepCgs: "{{ checkedRepCgs }}" + when: metroRepCgNum|int > 0 + + # End Precheck_2 + when: Precheck_2_Execute + + - block: + - name: Precheck_3 - Check DR Protection Group + debug: + msg: + pg: "{{ drPgName }}" + device: "{{ drDeviceSn }}" + + - name: Login Device + set_fact: + deviceSn: "{{ drDeviceSn }}" + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/login_storage.yml" + + - set_fact: + drDeviceName: "{{ deviceName }}" + drDeviceHost: "{{ deviceHost }}" + drDevicePort: "{{ devicePort }}" + drDeviceToken: "{{ deviceToken }}" + drDeviceSession: "{{ deviceSession }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_pgs.yml" + vars: + pgNames: ["{{ drPgName }}"] + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/get_pg.yml" + vars: + pgName: "{{ drPgName }}" + + - set_fact: + drPg: "{{ checkedPg }}" + drRepCgNum: "{{ checkedPg['replicationGroupNum']|int }}" + + - name: Check No Snapshot CG + vars: + snapCgNum: "{{ checkedPg['snapshotGroupNum']|int }}" + fail: + msg: "Snapshot CG exists: {{ checkedPg['snapshotGroupName'] }}" + when: snapCgNum|int > 0 + + - name: Check No Clone CG + vars: + cloneCgNum: "{{ checkedPg['cloneGroupNum']|int }}" + fail: + msg: "Clone CG exists: {{ checkedPg['cloneGroupName'] }}" + when: cloneCgNum|int > 0 + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_replication_cgs.yml" + vars: + cgNames: "{{ checkedPg['replicationGroupName'].split(',') }}" + when: drRepCgNum|int > 0 + + - set_fact: + drRepCgs: "{{ checkedRepCgs }}" + when: drRepCgNum|int > 0 + + # End Precheck_3 + when: Precheck_3_Execute + + - block: + - set_fact: + + # To bypass the Replication CGs on the other side storage + deletedRepCgNames: [] + rollbackedRepCgNames: [] + + # Delete HyperMetro CG + Step_1_1_Execute: "{{ primaryMetroCgNum|int == 1 }}" + Step_1_1_Completed: False + Step_1_1_Rollbacked: False + + # Delete Replication CG + Step_1_2_Execute: "{{ primaryRepCgNum|int > 0 }}" + Step_1_2_Completed: False + Step_1_2_Rollbacked: False + + # Delete LUN Group + Step_1_3_Execute: True + Step_1_3_Completed: False + Step_1_3_Rollbacked: False + + # Delete Standby Replication CG + Step_2_1_Execute: "{{ (metroEnable == 'Y') and (metroRepCgNum|int > 0) }}" + Step_2_1_Completed: False + Step_2_1_Rollbacked: False + + # Delete Metro LUN Group + Step_2_2_Execute: "{{ (metroEnable == 'Y') }}" + Step_2_2_Completed: False + Step_2_2_Rollbacked: False + + # Delete DR Replication CG + Step_3_1_Execute: "{{ (protectLevel|int >= 2) and (drRepCgNum|int > 0) }}" + Step_3_1_Completed: False + Step_3_1_Rollbacked: False + + # Delete DR LUN Group + Step_3_2_Execute: "{{ (protectLevel|int >= 2) }}" + Step_3_2_Completed: False + Step_3_2_Rollbacked: False + + - name: Workflow - Delete Protection Group + debug: + msg: + Step_1_1: "[{{Step_1_1_Execute}}] Delete HyperMetro CG" + Step_1_2: "[{{Step_1_2_Execute}}] Delete Replication CG" + Step_1_3: "[{{Step_1_3_Execute}}] Delete Protection Group" + + Step_2_1: "[{{Step_2_1_Execute}}] Delete Standby Replication CG" + Step_2_2: "[{{Step_2_2_Execute}}] Delete Metro Protection Group" + + Step_3_1: "[{{Step_3_1_Execute}}] Delete DR Replication CG" + Step_3_2: "[{{Step_3_2_Execute}}] Delete DR Protection Group" + + - block: + - name: Step_1_1 - Delete HyperMetro CG + debug: + msg: + params: + pg: "{{ primaryPgName }}" + cgName: "{{ primaryMetroCg.NAME }}" + device: "{{ primaryDeviceName }}" + + - set_fact: + deviceHost: "{{ primaryDeviceHost }}" + devicePort: "{{ primaryDevicePort }}" + deviceSn: "{{ primaryDeviceSn }}" + deviceToken: "{{ primaryDeviceToken }}" + deviceSession: "{{ primaryDeviceSession }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/delete_hypermetro_cg.yml" + vars: + cgName: "{{ primaryMetroCg.NAME }}" + deletePairs: False + + - set_fact: + primaryRemovedMPairIds: "{{ removedPairIds }}" + Step_1_1_Completed: True + when: Step_1_1_Execute + + - block: + - name: Step_1_2 - Delete Replication CGs + debug: + msg: + params: + pg: "{{ primaryPgName }}" + cgNames: "{{ primaryRepCgs | json_query('[*].NAME') }}" + device: "{{ primaryDeviceName }}" + + - set_fact: + deviceHost: "{{ primaryDeviceHost }}" + devicePort: "{{ primaryDevicePort }}" + deviceSn: "{{ primaryDeviceSn }}" + deviceToken: "{{ primaryDeviceToken }}" + deviceSession: "{{ primaryDeviceSession }}" + rcgNames: "{{ primaryRepCgs | json_query('[*].NAME') | difference(deletedRepCgNames) }}" + outPairIds: {} + + - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/delete_replication_cg.yml" + vars: + deletePairs: False + loop: "{{ rcgNames }}" + loop_control: + loop_var: cgName + when: + - rcgNames|length > 0 + + - set_fact: + deletedRepCgNames: "{{ deletedRepCgNames + rcgNames }}" + primaryRemovedRPairIds: "{{ outPairIds }}" + Step_1_2_Completed: True + when: Step_1_2_Execute + + - block: + - name: Step_1_3 - Delete Protection Group + debug: + msg: + params: + pgName: "{{ primaryPgName }}" + device: "{{ primaryDeviceName }}" + + - set_fact: + deviceHost: "{{ primaryDeviceHost }}" + devicePort: "{{ primaryDevicePort }}" + deviceSn: "{{ primaryDeviceSn }}" + deviceToken: "{{ primaryDeviceToken }}" + deviceSession: "{{ primaryDeviceSession }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/delete_pg.yml" + vars: + pgName: "{{ primaryPgName }}" + unmap: True + + - set_fact: + primaryRemovedLunIds: "{{ removedLunIds }}" + primaryDeletedPg: "{{ deletedPg }}" + Step_1_3_Completed: True + when: Step_1_3_Execute + + + - block: + - name: Step_2_1 - Delete Standby Replication CGs + debug: + msg: + params: + pg: "{{ primaryPgName }}" + cgNames: "{{ standbyRepCgs | json_query('[*].NAME') }}" + device: "{{ metroDeviceName }}" + + - set_fact: + deviceHost: "{{ metroDeviceHost }}" + devicePort: "{{ metroDevicePort }}" + deviceSn: "{{ metroDeviceSn }}" + deviceToken: "{{ metroDeviceToken }}" + deviceSession: "{{ metroDeviceSession }}" + rcgNames: "{{ standbyRepCgs | json_query('[*].NAME') | difference(deletedRepCgNames) }}" + outPairIds: {} + + - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/delete_replication_cg.yml" + vars: + deletePairs: False + loop: "{{ rcgNames }}" + loop_control: + loop_var: cgName + when: + - rcgNames|length > 0 + + - set_fact: + deletedRepCgNames: "{{ deletedRepCgNames + rcgNames }}" + metroRemovedRPairIds: "{{ outPairIds }}" + Step_2_1_Completed: True + when: Step_2_1_Execute + + - block: + - name: Step_2_2 - Delete Metro Protection Group + debug: + msg: + params: + pgName: "{{ primaryPgName }}" + device: "{{ metroDeviceName }}" + + - set_fact: + deviceHost: "{{ metroDeviceHost }}" + devicePort: "{{ metroDevicePort }}" + deviceSn: "{{ metroDeviceSn }}" + deviceToken: "{{ metroDeviceToken }}" + deviceSession: "{{ metroDeviceSession }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/delete_pg.yml" + vars: + pgName: "{{ primaryPgName }}" + + - set_fact: + metroRemovedLunIds: "{{ removedLunIds }}" + metroDeletedPg: "{{ deletedPg }}" + Step_2_2_Completed: True + when: Step_2_2_Execute + + - block: + - name: Step_3_1 - Delete DR Replication CGs + debug: + msg: + params: + pg: "{{ drPgName }}" + cgNames: "{{ drRepCgs | json_query('[*].NAME') }}" + device: "{{ drDeviceName }}" + + - set_fact: + deviceHost: "{{ drDeviceHost }}" + devicePort: "{{ drDevicePort }}" + deviceSn: "{{ drDeviceSn }}" + deviceToken: "{{ drDeviceToken }}" + deviceSession: "{{ drDeviceSession }}" + rcgNames: "{{ drRepCgs | json_query('[*].NAME') | difference(deletedRepCgNames) }}" + outPairIds: {} + + - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/delete_replication_cg.yml" + vars: + deletePairs: False + loop: "{{ rcgNames }}" + loop_control: + loop_var: cgName + when: + - rcgNames|length > 0 + + - set_fact: + deletedRepCgNames: "{{ deletedRepCgNames + rcgNames }}" + drRemovedRPairIds: "{{ outPairIds }}" + Step_3_1_Completed: True + when: Step_3_1_Execute + + - block: + - name: Step_3_2 - Delete DR Protection Group + debug: + msg: + params: + pgName: "{{ drPgName }}" + device: "{{ drDeviceName }}" + + - set_fact: + deviceHost: "{{ drDeviceHost }}" + devicePort: "{{ drDevicePort }}" + deviceSn: "{{ drDeviceSn }}" + deviceToken: "{{ drDeviceToken }}" + deviceSession: "{{ drDeviceSession }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/delete_pg.yml" + vars: + pgName: "{{ drPgName }}" + + - set_fact: + drRemovedLunIds: "{{ removedLunIds }}" + drDeletedPg: "{{ deletedPg }}" + Step_3_2_Completed: True + when: Step_3_2_Execute + + # End Steps + rescue: + # Begin Rollback + + - block: + - name: Rollback_3_2 - Create DR Protection Group + debug: + msg: + params: + addLunIds: "{{ drRemovedLunIds }}" + pgName: "{{ drDeletedPg.protectGroupName }}" + desc: "{{ drDeletedPg.description }}" + + - set_fact: + deviceHost: "{{ drDeviceHost }}" + devicePort: "{{ drDevicePort }}" + deviceSn: "{{ drDeviceSn }}" + deviceToken: "{{ drDeviceToken }}" + deviceSession: "{{ drDeviceSession }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/create_pg.yml" + vars: + addLunIds: "{{ drRemovedLunIds }}" + pgName: "{{ drDeletedPg.protectGroupName }}" + desc: "{{ drDeletedPg.description }}" + + - set_fact: + Step_3_2_Rollbacked: True + when: Step_3_2_Completed + + - block: + - name: Rollback_2_2 - Create Metro Protection Group + debug: + msg: + params: + addLunIds: "{{ metroRemovedLunIds }}" + pgName: "{{ metroDeletedPg.protectGroupName }}" + desc: "{{ metroDeletedPg.description }}" + + - set_fact: + deviceHost: "{{ metroDeviceHost }}" + devicePort: "{{ metroDevicePort }}" + deviceSn: "{{ metroDeviceSn }}" + deviceToken: "{{ metroDeviceToken }}" + deviceSession: "{{ metroDeviceSession }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/create_pg.yml" + vars: + addLunIds: "{{ metroRemovedLunIds }}" + pgName: "{{ metroDeletedPg.protectGroupName }}" + desc: "{{ metroDeletedPg.description }}" + + - set_fact: + Step_2_2_Rollbacked: True + when: Step_2_2_Completed + + - block: + - name: Rollback_1_3 - Create Protection Group + debug: + msg: + params: + addLunIds: "{{ primaryRemovedLunIds }}" + pgName: "{{ primaryDeletedPg.protectGroupName }}" + desc: "{{ primaryDeletedPg.description }}" + + - set_fact: + deviceHost: "{{ primaryDeviceHost }}" + devicePort: "{{ primaryDevicePort }}" + deviceSn: "{{ primaryDeviceSn }}" + deviceToken: "{{ primaryDeviceToken }}" + deviceSession: "{{ primaryDeviceSession }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/create_pg.yml" + vars: + addLunIds: "{{ primaryRemovedLunIds }}" + pgName: "{{ primaryDeletedPg.protectGroupName }}" + desc: "{{ primaryDeletedPg.description }}" + + - set_fact: + Step_1_3_Rollbacked: True + when: Step_1_3_Completed + + - block: + - name: Rollback_1_2 - Create Replication CGs + debug: + msg: + params: + pg: "{{ primaryPgName }}" + cgNames: "{{ primaryRepCgs | json_query('[*].NAME') }}" + device: "{{ primaryDeviceName }}" + + - set_fact: + deviceHost: "{{ primaryDeviceHost }}" + devicePort: "{{ primaryDevicePort }}" + deviceSn: "{{ primaryDeviceSn }}" + deviceToken: "{{ primaryDeviceToken }}" + deviceSession: "{{ primaryDeviceSession }}" + rcgNames: "{{ primaryRepCgs | json_query('[*].NAME') | difference(rollbackedRepCgNames) }}" + + - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/create_replication_cg.yml" + vars: + query: "[? NAME=='{{cgName}}']" + cg: "{{ primaryRepCgs | json_query(query) | first }}" + remoteDevId: "{{ cg.remoteArrayID }}" + mode: "{{ cg.REPLICATIONMODEL }}" + localPgId: "{{ cg.localpgId }}" + remotePgId: "{{ cg.rmtpgId }}" + addPairIds: "{{ primaryRemovedRPairIds[cgName] }}" + loop: "{{ rcgNames }}" + loop_control: + loop_var: cgName + when: + - rcgNames|length > 0 + + - set_fact: + rollbackedRepCgNames: "{{ rollbackedRepCgNames + rcgNames }}" + Step_1_2_Rollbacked: True + when: Step_1_2_Completed + + - block: + - name: Rollback_1_1 - Create HyperMetro CG + debug: + msg: + params: + pg: "{{ primaryPgName }}" + cgName: "{{ primaryMetroCg.NAME }}" + localPgName: "{{ primaryMetroCg.localPgName }}" + rmtPgName: "{{ primaryMetroCg.rmtPgName }}" + device: "{{ primaryDeviceName }}" + + - set_fact: + deviceHost: "{{ primaryDeviceHost }}" + devicePort: "{{ primaryDevicePort }}" + deviceSn: "{{ primaryDeviceSn }}" + deviceToken: "{{ primaryDeviceToken }}" + deviceSession: "{{ primaryDeviceSession }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/create_hypermetro_cg.yml" + vars: + cgName: "{{ primaryMetroCg.NAME }}" + remoteSn: "{{ primaryMetroDeviceSn }}" + localPgId: "{{ primaryMetroCg.localPgId }}" + remotePgId: "{{ primaryMetroCg.remotePgId }}" + + - set_fact: + Step_1_1_Rollbacked: True + when: Step_1_1_Completed + + - block: + - name: Rollback_2_1 - Create Standby Replication CGs + debug: + msg: + params: + pg: "{{ primaryPgName }}" + cgNames: "{{ standbyRepCgs | json_query('[*].NAME') }}" + device: "{{ metroDeviceName }}" + + - set_fact: + deviceHost: "{{ metroDeviceHost }}" + devicePort: "{{ metroDevicePort }}" + deviceSn: "{{ metroDeviceSn }}" + deviceToken: "{{ metroDeviceToken }}" + deviceSession: "{{ metroDeviceSession }}" + rcgNames: "{{ standbyRepCgs | json_query('[*].NAME') | difference(rollbackedRepCgNames) }}" + + - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/create_replication_cg.yml" + vars: + query: "[? NAME=='{{cgName}}']" + cg: "{{ standbyRepCgs | json_query(query) | first }}" + remoteDevId: "{{ cg.remoteArrayID }}" + mode: "{{ cg.REPLICATIONMODEL }}" + localPgId: "{{ cg.localpgId }}" + remotePgId: "{{ cg.rmtpgId }}" + addPairIds: "{{ metroRemovedRPairIds[cgName] }}" + loop: "{{ rcgNames }}" + loop_control: + loop_var: cgName + when: + - rcgNames|length > 0 + + - set_fact: + rollbackedRepCgNames: "{{ rollbackedRepCgNames + rcgNames }}" + Step_2_1_Rollbacked: True + when: Step_2_1_Completed + + - block: + - name: Rollback_3_1 - Create DR Replication CGs + debug: + msg: + params: + pg: "{{ drPgName }}" + cgNames: "{{ drRepCgs | json_query('[*].NAME') }}" + device: "{{ drDeviceName }}" + + - set_fact: + deviceHost: "{{ drDeviceHost }}" + devicePort: "{{ drDevicePort }}" + deviceSn: "{{ drDeviceSn }}" + deviceToken: "{{ drDeviceToken }}" + deviceSession: "{{ drDeviceSession }}" + rcgNames: "{{ drRepCgs | json_query('[*].NAME') | difference(rollbackedRepCgNames) }}" + + - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/create_replication_cg.yml" + vars: + query: "[? NAME=='{{cgName}}']" + cg: "{{ drRepCgs | json_query(query) | first }}" + remoteDevId: "{{ cg.remoteArrayID }}" + mode: "{{ cg.REPLICATIONMODEL }}" + localPgId: "{{ cg.localpgId }}" + remotePgId: "{{ cg.rmtpgId }}" + addPairIds: "{{ drRemovedRPairIds[cgName] }}" + loop: "{{ rcgNames }}" + loop_control: + loop_var: cgName + when: + - rcgNames|length > 0 + + - set_fact: + rollbackedRepCgNames: "{{ rollbackedRepCgNames + rcgNames }}" + Step_3_1_Rollbacked: True + when: Step_3_1_Completed + + # End Rollbacks + always: + + - name: Final_Step_1 - Sync Devices + set_fact: + deviceSynced: [] + primaryDeviceNeedSync: "{{ (Step_1_3_Completed|bool == True and Step_1_3_Rollbacked|bool == False) }}" + metroDeviceNeedSync: "{{ (Step_2_2_Completed|bool == True and Step_2_2_Rollbacked|bool == False) }}" + drDeviceNeedSync: "{{ (Step_3_2_Completed|bool == True and Step_3_2_Rollbacked|bool == False) }}" + + - name: Final_Step_1_1 - Sync Primary Device + debug: + msg: + device: "{{ primaryDeviceName }}" + when: primaryDeviceNeedSync + + - set_fact: + deviceName: "{{ primaryDeviceName }}" + when: primaryDeviceNeedSync + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/sync_storage.yml" + when: primaryDeviceNeedSync + + - set_fact: + deviceSynced: "{{ deviceSynced + [primaryDeviceName] }}" + when: primaryDeviceNeedSync + + - name: Final_Step_1_2 - Sync Metro Device + debug: + msg: + device: "{{ metroDeviceName }}" + when: + - metroDeviceNeedSync + + - set_fact: + deviceName: "{{ metroDeviceName }}" + when: + - metroDeviceNeedSync + - metroDeviceName not in deviceSynced + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/sync_storage.yml" + when: + - metroDeviceNeedSync + - metroDeviceName not in deviceSynced + + - set_fact: + deviceSynced: "{{ deviceSynced + [metroDeviceName] }}" + when: + - metroDeviceNeedSync + - metroDeviceName not in deviceSynced + + - name: Final_Step_1_3 - Sync DR Device + debug: + msg: + device: "{{ drDeviceName }}" + when: + - drDeviceNeedSync + + - set_fact: + deviceName: "{{ drDeviceName }}" + when: + - drDeviceNeedSync + - drDeviceName not in deviceSynced + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/sync_storage.yml" + when: + - drDeviceNeedSync + - drDeviceName not in deviceSynced + + - set_fact: + deviceSynced: "{{ deviceSynced + [drDeviceName] }}" + when: + - drDeviceNeedSync + - drDeviceName not in deviceSynced + + # End Final Steps + + # End Workflow + + # Begin Validate Results + + - block: + + - name: Result_1_1 - Delete HyperMetro CG + debug: + msg: + params: + pg: "{{ primaryPgName }}" + cgName: "{{ primaryMetroCg.NAME }}" + device: "{{ primaryDeviceName }}" + result: + succeeded: "{{ Step_1_1_Completed }}" + rollbacked: "{{ Step_1_1_Rollbacked }}" + failed_when: Step_1_1_Completed|bool == False + when: Step_1_1_Execute + + - name: Result_1_2 - Delete Replication CGs + debug: + msg: + params: + pg: "{{ primaryPgName }}" + cgNames: "{{ primaryRepCgs | json_query('[*].NAME') }}" + device: "{{ primaryDeviceName }}" + result: + succeeded: "{{ Step_1_2_Completed }}" + rollbacked: "{{ Step_1_2_Rollbacked }}" + failed_when: Step_1_2_Completed|bool == False + when: Step_1_2_Execute + + - name: Result_1_3 - Delete Protection Group + debug: + msg: + params: + pg: "{{ primaryPgName }}" + device: "{{ primaryDeviceName }}" + result: + succeeded: "{{ Step_1_3_Completed }}" + rollbacked: "{{ Step_1_3_Rollbacked }}" + failed_when: Step_1_3_Completed|bool == False + when: Step_1_3_Execute + + - name: Result_2_1 - Delete Standby Replication CGs + debug: + msg: + params: + pg: "{{ primaryPgName }}" + cgNames: "{{ standbyRepCgs | json_query('[*].NAME') }}" + device: "{{ metroDeviceName }}" + result: + succeeded: "{{ Step_2_1_Completed }}" + rollbacked: "{{ Step_2_1_Rollbacked }}" + failed_when: Step_2_1_Completed|bool == False + when: Step_2_1_Execute + + - name: Result_2_2 - Delete Metro Protection Group + debug: + msg: + params: + pg: "{{ primaryPgName }}" + device: "{{ metroDeviceName }}" + result: + succeeded: "{{ Step_2_2_Completed }}" + rollbacked: "{{ Step_2_2_Rollbacked }}" + failed_when: Step_2_2_Completed|bool == False + when: Step_2_2_Execute + + - name: Result_3_1 - Delete DR Replication CGs + debug: + msg: + params: + pg: "{{ drPgName }}" + cgNames: "{{ drRepCgs | json_query('[*].NAME') }}" + device: "{{ drDeviceName }}" + result: + succeeded: "{{ Step_3_1_Completed }}" + rollbacked: "{{ Step_3_1_Rollbacked }}" + failed_when: Step_3_1_Completed|bool == False + when: Step_3_1_Execute + + - name: Result_3_2 - Delete DR Protection Group + debug: + msg: + params: + pg: "{{ drPgName }}" + device: "{{ drDeviceName }}" + result: + succeeded: "{{ Step_3_2_Completed }}" + rollbacked: "{{ Step_3_2_Rollbacked }}" + failed_when: Step_3_2_Completed|bool == False + when: Step_3_2_Execute + + - name: Synced Device + debug: + msg: + synced: "{{ deviceSynced }}" + + # End Validates + + # End Tasks + +# End Playbook \ No newline at end of file diff --git a/rundeck/workflow/project001/53_dr_test_for_pg.yml b/rundeck/workflow/project001/53_dr_test_for_pg.yml new file mode 100644 index 0000000..0ec8fa4 --- /dev/null +++ b/rundeck/workflow/project001/53_dr_test_for_pg.yml @@ -0,0 +1,456 @@ +- name: DR Test for Protection Group + hosts: localhost + vars_files: + - ../../../config/global.yml + - ../../../config/project001.yml + gather_facts: no + become: no + tasks: + + # Check Params + - block: + - set_fact: + checked_params: + DR_Storage: "{{ (DR_Storage is not none and DR_Storage != DEFAULT.noneValue) and (DR_Storage|string|length == 20) }}" + DR_Protection_Group: "{{ DR_Protection_Group is not none and DR_Protection_Group != DEFAULT.noneValue }}" + DR_CG: "{{ DR_CG is not none and DR_CG != DEFAULT.noneValue }}" + DR_Test_CG: "{{ DR_Test_CG is not none and DR_Test_CG != DEFAULT.noneValue }}" + DR_Test_CG_Status: "{{ DR_Test_CG_Status is not none and DR_Test_CG_Status != DEFAULT.noneValue and DR_Test_CG_Status != SNAPCG.activated.enum }}" + Check_Result_1: "{{ 'snap' in Check_Result_1 }}" + + - name: Precheck_0_1 - Check Params + debug: + msg: "{{checked_params}}" + failed_when: checked_params.values()|unique != [True] + + - set_fact: + WBE_CODE: "{{ WBE_CODE }}" + TICKET_NUMBER: "{{ TICKET_NUMBER }}" + osType: "{{ OS_Type }}" + deviceSn: "{{ DR_Storage|string }}" + room: "{{ DR_Storage_Room }}" + site: "{{ AZ[DR_Storage_Room]['dc'] }}" + drPgName: "{{ DR_Protection_Group }}" + drCgName: "{{ DR_CG }}" + drTestCgId: "{{ DR_Test_CG_ID }}" + drTestCgName: "{{ DR_Test_CG }}" + class3: "{{ Designate_Class_3 }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/user/login.yml" + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/login_storage.yml" + + - name: Precheck_1 - Check Protection Group, Hosts, WWNs + debug: + msg: + pgName: "{{ drPgName }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_pgs.yml" + vars: + pgNames: ["{{drPgName}}"] + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/get_luns_by_pg.yml" + vars: + pgName: "{{drPgName}}" + + - set_fact: + drLunNames: "{{ checkedLuns | json_query('[*].NAME') }}" + drHostNames: [] + drTestHostNames: [] + + - set_fact: + drHostNames: "{{ drHostNames + [item[:-6]] }}" + drTestHostNames: "{{ drTestHostNames + [item[:-7] + '3'] }}" + with_items: "{{ drLunNames }}" + + - set_fact: + drHostNames: "{{ drHostNames | unique }}" + drTestHostNames: "{{ drTestHostNames | unique}}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_host_wwns.yml" + vars: + hostNames: "{{ drTestHostNames }}" + checkExist: False + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_host_wwns.yml" + vars: + hostNames: "{{ drHostNames }}" + + - set_fact: + drHostWwns: "{{ checkedWwns }}" + drTestHostWwns: {} + + - set_fact: + drTestHostWwns: "{{ drTestHostWwns | combine( { item.0: drHostWwns[item.1] } ) }}" + with_together: + - "{{ drTestHostNames }}" + - "{{ drHostNames }}" + + - name: Query Snapshots in CG + uri: + url: "https://{{deviceHost}}:{{devicePort}}/deviceManager/rest/{{deviceSn}}/snapshot/associate?ASSOCIATEOBJTYPE=57646&ASSOCIATEOBJID={{drTestCgId}}" + method: GET + validate_certs: no + headers: + Accept: "application/json" + Content-Type: "application/json;charset=utf8" + iBaseToken: "{{ deviceToken }}" + Cookie: "session={{ deviceSession }}" + register: SNAPSHOTS + + - set_fact: + drTestLunNames: "{{ SNAPSHOTS.json.data | default([]) | json_query('[*].NAME') }}" + drTestLunIds: "{{ SNAPSHOTS.json.data | default([]) | json_query('[*].ID') }}" + drTestLunSectors: "{{ SNAPSHOTS.json.data | default([]) | json_query('[*].USERCAPACITY') }}" + + - debug: + msg: + drHostWwns: "{{ drHostWwns }}" + drCgName: "{{ drCgName }}" + drTestLunNames: "{{ drTestLunNames }}" + drTestCgName: "{{ drTestCgName }}" + failed_when: drHostWwns|length == 0 or drTestLunNames|length == 0 + + - block: + + # Begin Workflow Steps + + - set_fact: + + # Activate DR Test Snapshot CG + Step_1_1_Execute: True + Step_1_1_Completed: False + Step_1_1_Rollbacked: False + + # Set Class for DR Test LUNs + Step_1_2_Execute: True + Step_1_2_Completed: False + Step_1_2_Rollbacked: False + + # Remove WWNs from DR Hosts + Step_2_1_Execute: True + Step_2_1_Completed: False + Step_2_1_Rollbacked: False + + # Add WWNs to DR Test Hosts + Step_2_2_Execute: True + Step_2_2_Completed: False + Step_2_2_Rollbacked: False + + # Update DR Test LUNs to KPI table + Step_3_1_Execute: True + Step_3_1_Completed: False + + - name: Workflow - DR Test for Host + debug: + msg: + Step_1_1: "[{{Step_1_1_Execute}}] Activate DR Test Snapshot CG" + Step_1_2: "[{{Step_1_2_Execute}}] Set Class for DR Test LUNs" + Step_2_1: "[{{Step_2_1_Execute}}] Remove WWNs from DR Hosts" + Step_2_2: "[{{Step_2_2_Execute}}] Add WWNs to DR Test Hosts" + Step_3_1: "[{{Step_3_1_Execute}}] Update DR Test LUNs to KPI table" + + - block: + - name: Step_1_1 - Activate DR Test Snapshot CG + debug: + msg: + params: + cgName: "{{ drTestCgName }}" + device: "{{ deviceName }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/activate_snapshot_cg.yml" + vars: + cgName: "{{ drTestCgName }}" + + - set_fact: + Step_1_1_Completed: True + + # End Step_1_1 + + # End block + when: Step_1_1_Execute + + - block: + - name: Step_1_2 - Set Class for DR Test LUNs + debug: + msg: + params: + volumeNames: "{{ drTestLunNames }}" + tierName: "{{ class3 }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/volume/add_volumes_to_tier.yml" + vars: + volumeNames: "{{ drTestLunNames }}" + tierName: "{{ class3 }}" + + - set_fact: + Step_1_2_Completed: True + + # End Step_1_2 + + # End block + when: Step_1_2_Execute + + - block: + - name: Step_2_1 - Remove WWNs from DR Hosts + debug: + msg: + params: + wwns: "{{ drHostWwns }}" + device: "{{ deviceName }}" + + - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/remove_ports_from_host.yml" + vars: + wwns: "{{ host2wwn.value }}" + hostName: "{{ host2wwn.key }}" + loop: "{{ lookup('dict', drHostWwns, wantlist=True) }}" + loop_control: + loop_var: host2wwn + + + - set_fact: + Step_2_1_Completed: True + + # End Step_2_1 + + # End block + when: Step_2_1_Execute + + - block: + - name: Step_2_2 - Add WWNs to DR Test Hosts + debug: + msg: + params: + wwns: "{{ drTestHostWwns }}" + device: "{{ deviceName }}" + + - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/add_ports_to_host.yml" + vars: + wwns: "{{ host2wwn.value }}" + hostName: "{{ host2wwn.key }}" + loop: "{{ lookup('dict', drTestHostWwns, wantlist=True) }}" + loop_control: + loop_var: host2wwn + + - set_fact: + Step_2_2_Completed: True + + # End Step_2_2 + + # End block + when: Step_2_2_Execute + + - block: + - name: Step_3_1 - Update DR Test LUNs to KPI table + debug: + msg: + params: + lunIds: "{{ drTestLunIds }}" + class: "{{ class3 }}" + + # Minus Non-Class capacity + - include_tasks: update_lun_kpi_table.yml + vars: + TYPE_OF_OPERATION: "modify" + WBE_CODE: "{{ WBE_CODE }}" + TICKET_NUMBER: "{{ TICKET_NUMBER }}" + SYSTEM_NAME: "{{ drPgName }}" + SITE: "{{ site }}" + ENVIRONMENT: "{{ osType }}" + STORAGE_CLASS: "" + CAPACITY_GB: "-{{ (drTestLunSectors[item.0]|int / 1024 / 1024 / 2)|int }}" + STORAGE: "{{ deviceName }}" + VDISK_UID: "{{ item.1 }}" + with_indexed_items: "{{ drTestLunIds }}" + + # Add capacity to Class + - include_tasks: update_lun_kpi_table.yml + vars: + TYPE_OF_OPERATION: "modify" + WBE_CODE: "{{ WBE_CODE }}" + TICKET_NUMBER: "{{ TICKET_NUMBER }}" + SYSTEM_NAME: "{{ drPgName }}" + SITE: "{{ site }}" + ENVIRONMENT: "{{ osType }}" + STORAGE_CLASS: "{{ class3 }}" + CAPACITY_GB: "{{ (drTestLunSectors[item.0]|int / 1024 / 1024 / 2)|int }}" + STORAGE: "{{ deviceName }}" + VDISK_UID: "{{ item.1 }}" + with_indexed_items: "{{ drTestLunIds }}" + + - set_fact: + Step_3_1_Completed: True + + # End Step_3_1 + + # End block + when: Step_3_1_Execute + + # End Steps + rescue: + + - block: + - name: Rollback_2_2 - Remove WWNs from DR Test Hosts + debug: + msg: + params: + wwns: "{{ drTestHostWwns }}" + device: "{{ deviceName }}" + + - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/remove_ports_from_host.yml" + vars: + wwns: "{{ host2wwn.value }}" + hostName: "{{ host2wwn.key }}" + loop: "{{ lookup('dict', drTestHostWwns, wantlist=True) }}" + loop_control: + loop_var: host2wwn + + - set_fact: + Step_2_2_Rollbacked: True + + # End Rollback_2_2 + + # End block + when: Step_2_2_Completed + + - block: + - name: Rollback_2_1 - Add WWNs to DR Hosts + debug: + msg: + params: + wwns: "{{ drHostWwns }}" + device: "{{ deviceName }}" + + - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/add_ports_to_host.yml" + vars: + wwns: "{{ host2wwn.value }}" + hostName: "{{ host2wwn.key }}" + loop: "{{ lookup('dict', drHostWwns, wantlist=True) }}" + loop_control: + loop_var: host2wwn + + - set_fact: + Step_2_1_Rollbacked: True + + # End Rollback_2_1 + + # End block + when: Step_2_1_Completed + + - block: + - name: Rollback_1_2 - Remove Class for DR Test LUNs + debug: + msg: + params: + volumeNames: "{{ drTestLunNames }}" + tierName: "{{ class3 }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/volume/remove_volumes_from_tier.yml" + vars: + volumeNames: "{{ drTestLunNames }}" + tierName: "{{ class3 }}" + + - set_fact: + Step_1_2_Rollbacked: True + + # End Rollback_1_2 + + # End block + when: Step_1_2_Completed + + - block: + - name: Rollback_1_1 - Deactivate DR Test Snapshot CG + debug: + msg: + params: + cgName: "{{ drTestCgName }}" + device: "{{ deviceName }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/deactivate_snapshot_cg.yml" + vars: + cgName: "{{ drTestCgName }}" + + - set_fact: + Step_1_1_Rollbacked: True + + # End Rollback_1_1 + + # End block + when: Step_1_1_Completed + + # End Rollbacks + always: + + - name: Final_Step_1 - Sync DR Device + debug: + msg: + device: "{{ deviceName }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/sync_storage.yml" + + # End Final Steps + + # End Workflow + + + - block: + + # Begin Validate Results + + - name: Result_1_1 - Activate DR Test Snapshot CG + debug: + msg: + params: + cgName: "{{ drTestCgName }}" + device: "{{ deviceName }}" + result: + succeeded: "{{ Step_1_1_Completed }}" + rollbacked: "{{ Step_1_1_Rollbacked }}" + failed_when: Step_1_1_Completed|bool == False + when: Step_1_1_Execute + + - name: Result_1_2 - Set Class for DR Test LUNs + debug: + msg: + params: + volumeNames: "{{ drTestLunNames }}" + tierName: "{{ class3 }}" + result: + succeeded: "{{ Step_1_2_Completed }}" + rollbacked: "{{ Step_1_2_Rollbacked }}" + failed_when: Step_1_2_Completed|bool == False + when: Step_1_2_Execute + + - name: Result_2_1 - Remove WWNs from DR Hosts + debug: + msg: + params: + wwns: "{{ drHostWwns }}" + device: "{{ deviceName }}" + result: + succeeded: "{{ Step_2_1_Completed }}" + rollbacked: "{{ Step_2_1_Rollbacked }}" + failed_when: Step_2_1_Completed|bool == False + when: Step_2_1_Execute + + - name: Result_2_2 - Add WWNs to DR Test Hosts + debug: + msg: + params: + wwns: "{{ drHostWwns }}" + device: "{{ deviceName }}" + result: + succeeded: "{{ Step_2_2_Completed }}" + rollbacked: "{{ Step_2_2_Rollbacked }}" + failed_when: Step_2_2_Completed|bool == False + when: Step_2_2_Execute + + - name: Result_3_1 - Update DR Test LUNs to KPI table + debug: + msg: + params: + lunIds: "{{ drTestLunIds }}" + class: "{{ class3 }}" + result: + succeeded: "{{ Step_3_1_Completed }}" + failed_when: Step_3_1_Completed|bool == False + when: Step_3_1_Execute \ No newline at end of file diff --git a/rundeck/workflow/project001/54_dr_test_clean_for_pg.yml b/rundeck/workflow/project001/54_dr_test_clean_for_pg.yml new file mode 100644 index 0000000..913c60d --- /dev/null +++ b/rundeck/workflow/project001/54_dr_test_clean_for_pg.yml @@ -0,0 +1,737 @@ +- name: DR Test Clean for Hosts + hosts: localhost + vars_files: + - ../../../config/global.yml + - ../../../config/project001.yml + gather_facts: no + become: no + tasks: + + # Check Params + - block: + - set_fact: + checked_params: + DR_Storage: "{{ (DR_Storage is not none and DR_Storage != DEFAULT.noneValue) and (DR_Storage|string|length == 20) }}" + DR_Protection_Group: "{{ DR_Protection_Group is not none and DR_Protection_Group != DEFAULT.noneValue }}" + DR_CG: "{{ DR_CG is not none and DR_CG != DEFAULT.noneValue }}" + DR_Test_CG: "{{ DR_Test_CG is not none and DR_Test_CG != DEFAULT.noneValue }}" + DR_Test_CG_Status: "{{ DR_Test_CG_Status is not none and DR_Test_CG_Status != DEFAULT.noneValue and DR_Test_CG_Status == SNAPCG.activated.enum }}" + Check_Result_1: "{{ 'snap' in Check_Result_1 }}" + + - name: Precheck_0_1 - Check Params + debug: + msg: "{{checked_params}}" + failed_when: checked_params.values()|unique != [True] + + - set_fact: + WBE_CODE: "{{ WBE_CODE }}" + TICKET_NUMBER: "{{ TICKET_NUMBER }}" + osType: "{{ OS_Type }}" + deviceSn: "{{ DR_Storage|string }}" + room: "{{ DR_Storage_Room }}" + site: "{{ AZ[DR_Storage_Room]['dc'] }}" + drPgName: "{{ DR_Protection_Group }}" + drCgName: "{{ DR_CG }}" + drTestCgName: "{{ DR_Test_CG }}" + drTestCgId: "{{ DR_Test_CG_ID }}" + class3: "{{ Designate_Class_3 }}" + + - set_fact: + protectType: "{{ REPTYPE['N3']['enum'] }}" # See ../../config/project001.yml + replicaType: "{{ REPTYPE['N3']['type'] }}" # See ../../config/project001.yml + + - import_tasks: "{{GLOBAL.baseDir}}/task/user/login.yml" + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/login_storage.yml" + + - name: Precheck_1 - Check Protection Group,Hosts, WWNs + debug: + msg: + pgName: "{{ drPgName }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_pgs.yml" + vars: + pgNames: ["{{drPgName}}"] + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/get_luns_by_pg.yml" + vars: + pgName: "{{drPgName}}" + + - set_fact: + drLunNames: "{{ checkedLuns | json_query('[*].NAME') }}" + drHostNames: [] + drTestHostNames: [] + drTestLg00Names: [] + + - set_fact: + drHostNames: "{{ drHostNames + [item[:-6]] }}" + drTestHostNames: "{{ drTestHostNames + [item[:-7] + '3'] }}" + drTestLg00Names: "{{ drTestLg00Names + [item[:-7] + '3_LG00'] }}" + with_items: "{{ drLunNames }}" + + - set_fact: + drHostNames: "{{ drHostNames | unique }}" + drTestHostNames: "{{ drTestHostNames | unique}}" + drTestLg00Names: "{{ drTestLg00Names | unique}}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_host_wwns.yml" + vars: + hostNames: "{{ drHostNames }}" + checkExist: False + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_host_wwns.yml" + vars: + hostNames: "{{ drTestHostNames }}" + + - set_fact: + drTestHostWwns: "{{ checkedWwns }}" + drHostWwns: {} + + - set_fact: + drHostWwns: "{{ drHostWwns | combine( { item.0: drTestHostWwns[item.1] } ) }}" + with_together: + - "{{ drHostNames }}" + - "{{ drTestHostNames }}" + + - name: Query Snapshots in CG + uri: + url: "https://{{deviceHost}}:{{devicePort}}/deviceManager/rest/{{deviceSn}}/snapshot/associate?ASSOCIATEOBJTYPE=57646&ASSOCIATEOBJID={{drTestCgId}}" + method: GET + validate_certs: no + headers: + Accept: "application/json" + Content-Type: "application/json;charset=utf8" + iBaseToken: "{{ deviceToken }}" + Cookie: "session={{ deviceSession }}" + register: SNAPSHOTS + + - set_fact: + drTestLunNames: "{{ SNAPSHOTS.json.data | default([]) | json_query('[*].NAME') }}" + drTestLunIds: "{{ SNAPSHOTS.json.data | default([]) | json_query('[*].ID') }}" + drTestLunSectors: "{{ SNAPSHOTS.json.data | default([]) | json_query('[*].USERCAPACITY') }}" + sourceDrLunNames: "{{ SNAPSHOTS.json.data | default([]) | json_query('[*].SOURCELUNNAME') }}" + + - debug: + msg: + drTestHostWwns: "{{ drTestHostWwns }}" + drCgName: "{{ drCgName }}" + drTestLunNames: "{{ drTestLunNames }}" + drTestCgName: "{{ drTestCgName }}" + failed_when: drTestHostWwns|length == 0 or drTestLunNames|length == 0 + + - import_tasks: "{{GLOBAL.baseDir}}/task/volume/check_volumes.yml" + vars: + volumeNames: "{{ drTestLunNames }}" + + - set_fact: + drTestLunClass: [] + drTestLunsInTier: {} + tierNames: "{{ checkedVolumes | json_query('[*].service_level_name') | unique }}" + + - set_fact: + drTestLunClass: "{{ drTestLunClass + [ checkedVolumes[item.0].service_level_name ] }}" + with_indexed_items: "{{ drTestLunNames }}" + + - set_fact: + drTestLunsInTier: "{{ drTestLunsInTier | combine( { item: checkedVolumes | json_query(queryVolumesInTier) } ) }}" + vars: + queryVolumesInTier: "[? service_level_name == '{{ item }}' ].id" + with_items: "{{ tierNames }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_luns.yml" + vars: + lunNames: "{{ drLunNames }}" + + - set_fact: + existDrLunNames: "{{ checkedLuns | json_query('[*].NAME') }}" + existDrLunDescs: "{{ checkedLuns | json_query('[*].DESCRIPTION') }}" + targetLunNames: [] + targetLunDescs: [] + + - set_fact: + targetLunNames: "{{ targetLunNames + [ item.0[:-7] + '3' + item.0[-6:] ] }}" + targetLunDescs: "{{ targetLunDescs + [ class3 + item.1[1:] ] }}" + with_together: + - "{{ existDrLunNames }}" + - "{{ existDrLunDescs }}" + + - set_fact: + orphanDrLunNames: "{{ sourceDrLunNames | difference(existDrLunNames) }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_luns.yml" + vars: + lunNames: "{{ orphanDrLunNames }}" + when: orphanDrLunNames|length > 0 + + - set_fact: + orphanDrLunIds: "{{ checkedLuns | json_query('[*].ID') }}" + orphanDrLunSectors: "{{ checkedLuns | json_query('[*].CAPACITY') }}" + when: orphanDrLunNames|length > 0 + + - set_fact: + checkedHostLuns: [] + + - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_host_lun_id_loop_helper.yml" + vars: + hostName: "{{ name }}" + loop: "{{ drTestHostNames | flatten(levels=1) }}" + loop_control: + loop_var: name + + - set_fact: + drTestHostLunsAll: [] + targetLunLunScsiIds: [] + + - set_fact: + drTestHostLunsAll: "{{ drTestHostLunsAll + checkedHostLuns[item.0][item.1] }}" + with_indexed_items: "{{ drTestLg00Names }}" + + - set_fact: + targetLunLunScsiIds: "{{ targetLunLunScsiIds + drTestHostLunsAll | json_query(queryScsiId) }}" + vars: + queryScsiId: "[? lunName=='{{item}}'].hostLunId" + with_items: "{{ targetLunNames }}" + + - block: + + # Begin Workflow Steps + + - set_fact: + + # Remove WWNs from DR Test Hosts + Step_1_1_Execute: True + Step_1_1_Completed: False + Step_1_1_Rollbacked: False + + # Add WWNs to DR Hosts + Step_1_2_Execute: True + Step_1_2_Completed: False + Step_1_2_Rollbacked: False + + # Remove DR Test LUNs from Class + Step_2_1_Execute: True + Step_2_1_Completed: False + Step_2_1_Rollbacked: False + + # Remove DR Test LUNs from LUN Group + Step_2_2_Execute: True + Step_2_2_Completed: False + Step_2_2_Rollbacked: False + + # Delete DR Test Snapshot CG + Step_2_3_Execute: True + Step_2_3_Completed: False + Step_2_3_Rollbacked: False + + # Re-Create DR Test Snapshot CG + Step_2_4_Execute: "{{ targetLunNames|length > 0 }}" + Step_2_4_Completed: False + Step_2_4_Rollbacked: False + + # Add DR Test LUNs to LUN Group + Step_2_5_Execute: "{{ targetLunNames|length > 0 }}" + Step_2_5_Completed: False + Step_2_5_Rollbacked: False + + # Delete Orphan DR LUNs + Step_2_6_Execute: "{{ orphanDrLunNames|length > 0 }}" + Step_2_6_Completed: False + Step_2_6_Rollbacked: False + + # Update DR Test LUNs to KPI table + Step_3_1_Execute: True + Step_3_1_Completed: False + Step_3_1_Rollbacked: False + + # Update Orphan DR LUNs to KPI table + Step_3_2_Execute: "{{ orphanDrLunNames|length > 0 }}" + Step_3_2_Completed: False + Step_3_2_Rollbacked: False + + - name: Workflow - DR Test Clean for Hosts + debug: + msg: + Step_1_1: "[{{Step_1_1_Execute}}] Remove WWNs from DR Test Hosts" + Step_1_2: "[{{Step_1_2_Execute}}] Add WWNs to DR Hosts" + Step_2_1: "[{{Step_2_1_Execute}}] Remove DR Test LUNs from Class" + Step_2_2: "[{{Step_2_2_Execute}}] Remove DR Test LUNs from LUN Group" + Step_2_3: "[{{Step_2_3_Execute}}] Delete DR Test Snapshot CG" + Step_2_4: "[{{Step_2_4_Execute}}] Re-Create DR Test Snapshot CG" + Step_2_5: "[{{Step_2_5_Execute}}] Add DR Test LUNs to LUN Group" + Step_2_6: "[{{Step_2_6_Execute}}] Delete Orphan DR LUNs" + Step_3_1: "[{{Step_3_1_Execute}}] Update DR Test LUNs to KPI table" + Step_3_2: "[{{Step_3_2_Execute}}] Update Orphan DR LUNs to KPI table" + + - block: + - name: Step_1_1 - Remove WWNs from DR Test Hosts + debug: + msg: + params: + wwns: "{{ drTestHostWwns }}" + device: "{{ deviceName }}" + + - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/remove_ports_from_host.yml" + vars: + wwns: "{{ host2wwn.value }}" + hostName: "{{ host2wwn.key }}" + loop: "{{ lookup('dict', drTestHostWwns, wantlist=True) }}" + loop_control: + loop_var: host2wwn + + - set_fact: + Step_1_1_Completed: True + + # End Step_1_1 + + # End block + when: Step_1_1_Execute + + - block: + - name: Step_1_2 - Add WWNs to DR Hosts + debug: + msg: + params: + wwns: "{{ drHostWwns }}" + device: "{{ deviceName }}" + + - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/add_ports_to_host.yml" + vars: + wwns: "{{ host2wwn.value }}" + hostName: "{{ host2wwn.key }}" + loop: "{{ lookup('dict', drHostWwns, wantlist=True) }}" + loop_control: + loop_var: host2wwn + + - set_fact: + Step_1_2_Completed: True + + # End Step_1_2 + + # End block + when: Step_1_2_Execute + + - block: + - name: Step_2_1 - Remove DR Test LUNs from Class + debug: + msg: + params: + drTestLunsInTier: "{{ drTestLunsInTier }}" + + - include_tasks: "{{GLOBAL.baseDir}}/task/volume/remove_volumes_from_tier.yml" + vars: + volumeIds: "{{ drTestLunsInTier[tierName] }}" + loop: "{{ tierNames }}" + loop_control: + loop_var: tierName + + - set_fact: + Step_2_1_Completed: True + + # End Step_2_1 + + # End block + when: Step_2_1_Execute + + - block: + - name: Step_2_2 - Remove DR Test LUNs from LUN Group + debug: + msg: + params: + lunNames: "{{ drTestLunNames }}" + device: "{{ deviceName }}" + + - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/remove_luns_from_lg.yml" + vars: + lgName: "{{ name[:-5] + 'LG00' }}" + lunNames: [ "{{ name }}" ] + loop: "{{ drTestLunNames | flatten(levels=1) }}" + loop_control: + loop_var: name + + - set_fact: + Step_2_2_Completed: True + + # End Step_2_2 + + # End block + when: Step_2_2_Execute + + - block: + - name: Step_2_3 - Delete DR Test Snapshot CG + debug: + msg: + params: + cgName: "{{ drTestCgName }}" + device: "{{ deviceName }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/delete_snapshot_cg.yml" + vars: + cgName: "{{ drTestCgName }}" + + - set_fact: + Step_2_3_Completed: True + + # End Step_2_3 + + # End block + when: Step_2_3_Execute + + - block: + - name: Step_2_4 - Re-Create DR Test Snapshot CG + debug: + msg: + params: + cgName: "{{ drTestCgName }}" + device: "{{ deviceName }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/create_snapshot_cg.yml" + vars: + pgName: "{{ drPgName }}" + cgName: "{{ drTestCgName }}" + snapNames: "{{ targetLunNames }}" + activate: False + snapDescs: "{{ targetLunDescs }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_luns.yml" + vars: + lunNames: "{{ targetLunNames }}" + + - set_fact: + targetLunIds: "{{ checkedLuns | json_query('[*].ID') }}" + targetLunSectors: "{{ checkedLuns | json_query('[*].CAPACITY') }}" + + - set_fact: + Step_2_4_Completed: True + + # End Step_2_4 + + # End block + when: Step_2_4_Execute + + - block: + - name: Step_2_5 - Add DR Test LUNs to LUN Group + debug: + msg: + params: + lunNames: "{{ targetLunNames }}" + device: "{{ deviceName }}" + + - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/add_luns_to_lg.yml" + vars: + lgName: "{{ param.0[:-5] + 'LG00' }}" + lunNames: [ "{{ param.0 }}" ] + addLunScsiIds: [ "{{ param.1 }}" ] + loop: "{{ targetLunNames | zip(targetLunLunScsiIds) | list }}" + loop_control: + loop_var: param + + - set_fact: + Step_2_5_Completed: True + + # End Step_2_5 + + # End block + when: Step_2_5_Execute + + - block: + - name: Step_2_6 - Delete Orphan DR LUNs + debug: + msg: + params: + lunNames: "{{ orphanDrLunNames }}" + device: "{{ deviceName }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/delete_luns.yml" + vars: + lunNames: "{{ orphanDrLunNames }}" + + - set_fact: + Step_2_6_Completed: True + + # End Step_2_6 + + # End block + when: Step_2_6_Execute + + - block: + - name: Step_3_1 - Update DR Test LUNs to KPI table + debug: + msg: + params: + lunIds: "{{ drTestLunIds }}" + class: "{{ drTestLunClass }}" + + - include_tasks: update_lun_kpi_table.yml + vars: + TYPE_OF_OPERATION: "delete" + WBE_CODE: "{{ WBE_CODE }}" + TICKET_NUMBER: "{{ TICKET_NUMBER }}" + SYSTEM_NAME: "{{ item.1[:-6] }}" + SITE: "{{ site }}" + ENVIRONMENT: "{{ osType }}" + STORAGE_CLASS: "{{ drTestLunClass[item.0] }}" + CAPACITY_GB: "-{{ (drTestLunSectors[item.0]|int / 1024 / 1024 / 2)|int }}" + STORAGE: "{{ deviceName }}" + VDISK_UID: "{{ item.1 }}" + with_indexed_items: "{{ drTestLunIds }}" + + - include_tasks: update_lun_kpi_table.yml + vars: + TYPE_OF_OPERATION: "create" + WBE_CODE: "{{ WBE_CODE }}" + TICKET_NUMBER: "{{ TICKET_NUMBER }}" + SYSTEM_NAME: "{{ item.1[:-6] }}" + SITE: "{{ site }}" + ENVIRONMENT: "{{ osType }}" + STORAGE_CLASS: "" + CAPACITY_GB: "{{ (targetLunSectors[item.0]|int / 1024 / 1024 / 2)|int }}" + STORAGE: "{{ deviceName }}" + VDISK_UID: "{{ item.1 }}" + with_indexed_items: "{{ targetLunIds }}" + when: targetLunIds|default([])|length > 0 + + - set_fact: + Step_3_1_Completed: True + + # End Step_3_1 + + # End block + when: Step_3_1_Execute + + - block: + - name: Step_3_2 - Update Orphan DR LUNs to KPI table + debug: + msg: + params: + lunIds: "{{ orphanDrLunIds }}" + + - include_tasks: update_lun_kpi_table.yml + vars: + TYPE_OF_OPERATION: "delete" + WBE_CODE: "{{ WBE_CODE }}" + TICKET_NUMBER: "{{ TICKET_NUMBER }}" + SYSTEM_NAME: "{{ drHostName }}" + SITE: "{{ site }}" + ENVIRONMENT: "{{ osType }}" + STORAGE_CLASS: "" + CAPACITY_GB: "-{{ (orphanDrLunSectors[item.0]|int / 1024 / 1024 / 2)|int }}" + STORAGE: "{{ deviceName }}" + VDISK_UID: "{{ item.1 }}" + with_indexed_items: "{{ orphanDrLunIds }}" + + - set_fact: + Step_3_2_Completed: True + + # End Step_3_2 + + # End block + when: Step_3_2_Execute + + # End Steps + rescue: + + # Unable to rollback DR Test CGs, need to manually rollback + + - block: + - name: Rollback_2_4 - Reactivated DR Test Snapshot CG + debug: + msg: + params: + cgName: "{{ drTestCgName }}" + device: "{{ deviceName }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/activate_snapshot_cg.yml" + vars: + cgName: "{{ drTestCgName }}" + + - set_fact: + Step_2_3_Rollbacked: True + Step_2_4_Rollbacked: True + + # End Rollback_2_4 + + # End block + when: Step_2_4_Completed + + - block: + - name: Rollback_1_2 - Remove WWNs from DR Hosts + debug: + msg: + params: + wwns: "{{ drHostWwns }}" + device: "{{ deviceName }}" + + - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/remove_ports_from_host.yml" + vars: + wwns: "{{ host2wwn.value }}" + hostName: "{{ host2wwn.key }}" + loop: "{{ lookup('dict', drHostWwns, wantlist=True) }}" + loop_control: + loop_var: host2wwn + + - set_fact: + Step_1_2_Rollbacked: True + + # End Rollback_1_2 + + # End block + when: Step_1_2_Completed + + - block: + - name: Rollback_1_1 - Add WWNs to DR Test Hosts + debug: + msg: + params: + wwns: "{{ drTestHostWwns }}" + device: "{{ deviceName }}" + + - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/add_ports_to_host.yml" + vars: + wwns: "{{ host2wwn.value }}" + hostName: "{{ host2wwn.key }}" + loop: "{{ lookup('dict', drTestHostWwns, wantlist=True) }}" + loop_control: + loop_var: host2wwn + + - set_fact: + Step_1_1_Rollbacked: True + + # End Rollback_1_1 + + # End block + when: Step_1_1_Completed + + # End Rollbacks + always: + + - name: Final_Step_1 - Sync DR Device + debug: + msg: + device: "{{ deviceName }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/sync_storage.yml" + + # End Final Steps + + # End Workflow + + + - block: + + # Begin Validate Results + + - name: Result_1_1 - Remove WWNs from DR Test Hosts + debug: + msg: + params: + wwns: "{{ drHostWwns }}" + device: "{{ deviceName }}" + result: + succeeded: "{{ Step_1_1_Completed }}" + rollbacked: "{{ Step_1_1_Rollbacked }}" + failed_when: Step_1_1_Completed|bool == False + when: Step_1_1_Execute + + - name: Result_1_2 - Add WWNs to DR Hosts + debug: + msg: + params: + wwns: "{{ drHostWwns }}" + device: "{{ deviceName }}" + result: + succeeded: "{{ Step_1_2_Completed }}" + rollbacked: "{{ Step_1_2_Rollbacked }}" + failed_when: Step_1_2_Completed|bool == False + when: Step_1_2_Execute + + - name: Result_2_1 - Remove DR Test LUNs from Class + debug: + msg: + params: + drTestLunsInTier: "{{ drTestLunsInTier }}" + result: + succeeded: "{{ Step_2_1_Completed }}" + rollbacked: "{{ Step_2_1_Rollbacked }}" + failed_when: Step_2_1_Completed|bool == False + when: Step_2_1_Execute + + - name: Result_2_2 - Remove DR Test LUNs from LUN Group + debug: + msg: + params: + lunNames: "{{ drTestLunNames }}" + device: "{{ deviceName }}" + result: + succeeded: "{{ Step_2_2_Completed }}" + rollbacked: "{{ Step_2_2_Rollbacked }}" + failed_when: Step_2_2_Completed|bool == False + when: Step_2_2_Execute + + - name: Result_2_3 - Delete DR Test Snapshot CG + debug: + msg: + params: + cgName: "{{ drTestCgName }}" + device: "{{ deviceName }}" + result: + succeeded: "{{ Step_2_3_Completed }}" + rollbacked: "{{ Step_2_3_Rollbacked }}" + failed_when: Step_2_3_Completed|bool == False + when: Step_2_3_Execute + + - name: Result_2_4 - Re-Create DR Test Snapshots + debug: + msg: + params: + cgName: "{{ drTestCgName }}" + device: "{{ deviceName }}" + result: + succeeded: "{{ Step_2_4_Completed }}" + rollbacked: "{{ Step_2_4_Rollbacked }}" + failed_when: Step_2_4_Completed|bool == False + when: Step_2_4_Execute + + - name: Result_2_5 - Add DR Test LUNs to LUN Group + debug: + msg: + params: + lunNames: "{{ targetLunNames }}" + addLunScsiIds: "{{ targetLunLunScsiIds }}" + device: "{{ deviceName }}" + result: + succeeded: "{{ Step_2_5_Completed }}" + rollbacked: "{{ Step_2_5_Rollbacked }}" + failed_when: Step_2_5_Completed|bool == False + when: Step_2_5_Execute + + - name: Result_2_6 - Delete Orphan DR LUNs + debug: + msg: + params: + lunNames: "{{ orphanDrLunNames }}" + device: "{{ deviceName }}" + result: + succeeded: "{{ Step_2_6_Completed }}" + rollbacked: "{{ Step_2_6_Rollbacked }}" + failed_when: Step_2_6_Completed|bool == False + when: Step_2_6_Execute + + - name: Result_3_1 - Update DR Test LUNs to KPI table + debug: + msg: + params: + lunIds: "{{ drTestLunIds }}" + result: + succeeded: "{{ Step_3_1_Completed }}" + failed_when: Step_3_1_Completed|bool == False + when: Step_3_1_Execute + + - name: Result_3_2 - Update Orphan DR LUNs to KPI table + debug: + msg: + params: + lunIds: "{{ orphanDrLunIds }}" + result: + succeeded: "{{ Step_3_2_Completed }}" + failed_when: Step_3_2_Completed|bool == False + when: Step_3_2_Execute + diff --git a/rundeck/workflow/project001/55_dr_test_for_multi_host.yml b/rundeck/workflow/project001/55_dr_test_for_multi_host.yml new file mode 100644 index 0000000..d1446fd --- /dev/null +++ b/rundeck/workflow/project001/55_dr_test_for_multi_host.yml @@ -0,0 +1,544 @@ +- name: DR Test for Hosts + hosts: localhost + vars_files: + - ../../../config/global.yml + - ../../../config/project001.yml + gather_facts: no + become: no + tasks: + + # Check Params + - block: + - set_fact: + checked_params: + Select_DR_Host: "{{ Select_DR_Host is not none and (Select_DR_Host|string).split(',')|length >= 1 }}" + DR_Storage: "{{ (DR_Storage is not none and DR_Storage != DEFAULT.noneValue) and (DR_Storage|string|length == 20) }}" + Check_Result_1: "{{ 'host' in Check_Result_1 }}" + + - name: Precheck_0_1 - Check Params + debug: + msg: "{{checked_params}}" + failed_when: checked_params.values()|unique != [True] + + - set_fact: + WBE_CODE: "{{ WBE_CODE }}" + TICKET_NUMBER: "{{ TICKET_NUMBER }}" + osType: "{{ OS_Type }}" + deviceSn: "{{ DR_Storage|string }}" + room: "{{ DR_Storage_Room }}" + site: "{{ AZ[DR_Storage_Room]['dc'] }}" + drHostNames: "{{ (Select_DR_Host|string).split(',') }}" + designateClass3: "{{ Designate_Class_3|default(none) }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/user/login.yml" + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/login_storage.yml" + + - name: Precheck_1 - Check Hosts, WWNs + debug: + msg: + drHostNames: "{{ drHostNames }}" + + - set_fact: + drTestHostNames: [] + drLgNames: [] + drPgNames: [] + drTestCgNames: [] + drCgNames: [] + drHostLunsAll: [] + drTestLunClasses: [] + + # check wwns + - set_fact: + drTestHostNames: "{{ drTestHostNames + [ item[:-1] + '3' ] }}" + with_items: "{{ drHostNames }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_host_wwns.yml" + vars: + hostNames: "{{ drTestHostNames }}" + checkExist: False + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_host_wwns.yml" + vars: + hostNames: "{{ drHostNames }}" + + - set_fact: + drHostWwns: "{{ checkedWwns }}" + drTestHostWwns: {} + + - set_fact: + drTestHostWwns: "{{ drTestHostWwns | combine( { item.0: drHostWwns[item.1] } ) }}" + with_together: + - "{{ drTestHostNames }}" + - "{{ drHostNames }}" + + # check host lun + - set_fact: + checkedHostLuns: [] + + - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_host_lun_id_loop_helper.yml" + vars: + hostName: "{{ drTestHostName }}" + loop: "{{ drTestHostNames }}" + loop_control: + loop_var: drTestHostName + + - set_fact: + combinedHostLuns: {} + - set_fact: + combinedHostLuns: "{{ combinedHostLuns | combine(item) }}" + loop: "{{ checkedHostLuns }}" + + - name: Check Host Luns Number in LGs + debug: + msg: + item: "{{ item }}" + failed_when: item.value|length == 0 + with_dict: "{{ combinedHostLuns }}" + + - set_fact: + drTestLunNames: "{{ combinedHostLuns.values() | flatten(levels=2) | json_query('[*].lunName') }}" + drTestLunIds: "{{ combinedHostLuns.values() | flatten(levels=2) | json_query('[*].lunId') }}" + drTestLgNames: "{{ combinedHostLuns.keys() }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_luns.yml" + vars: + lunNames: "{{ drTestLunNames }}" + + - set_fact: + drTestLunSectors: "{{ checkedLuns | json_query('[*].CAPACITY') }}" + + - set_fact: + drTestLunClasses: "{{ drTestLunClasses + [ designateClass3 if (designateClass3 != '' ) else item.split('_')[5] ]}}" + with_items: "{{ drTestLunNames }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/volume/check_volumes.yml" + vars: + volumeNames: "{{ drTestLunNames }}" + + - name: Check Volume in Tier Class + debug: + msg: + lunsInTierClass: "{{ checkedVolumes|json_query(queryLunsInTierClass) }}" + failed_when: checkedVolumes|json_query(queryLunsInTierClass)|length > 0 + vars: + queryLunsInTierClass: "[? service_level_name != '' && service_level_name != null ].name" + + - set_fact: + drPgNames: "{{ drPgNames + [ item[:-6] + '2_PG' + item[-2:] ] }}" + with_items: "{{ drTestLgNames }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_pgs.yml" + vars: + pgNames: "{{ drPgNames }}" + + - set_fact: + drPgIds: "{{ pgIds }}" + checkedPgSnapCgs: [] + + - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/get_snapshot_cgs_by_pg_loop_helper.yml" + vars: + pgId: "{{ drPgId }}" + loop: "{{ drPgIds }}" + loop_control: + loop_var: drPgId + + - name: Check Snapshot CGs Number and Status + debug: + msg: + SnapshotCgs: "{{ item }}" + status: "{{ item[0].RUNNINGSTATUS }}" + failed_when: (item|length|int != 1) or (item|length|int == 1 and item[0].RUNNINGSTATUS|int != SNAPCG.unactivated.enum) + loop: "{{ checkedPgSnapCgs }}" + + - set_fact: + drTestCgNames: "{{ drTestCgNames + [ item[0].NAME ] }}" + loop: "{{ checkedPgSnapCgs }}" + + - set_fact: + checkedPgRepCgs: [] + + - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/get_replication_cgs_by_pg_loop_helper.yml" + vars: + pgId: "{{ drPgId }}" + loop: "{{ drPgIds }}" + loop_control: + loop_var: drPgId + + - debug: + msg: + checkedPgRepCgs: "{{ checkedPgRepCgs }}" + drHostNames: "{{ drPgNames }}" + failed_when: item|length|int != 1 + loop: "{{ checkedPgRepCgs }}" + + - set_fact: + drCgNames: "{{ drCgNames + [ item[0].NAME ] }}" + loop: "{{ checkedPgRepCgs }}" + + - debug: + msg: + drHostWwns: "{{ drHostWwns }}" + drCgNames: "{{ drCgNames }}" + drTestCgNames: "{{ drTestCgNames }}" + drTestHostNames: "{{ drTestHostNames }}" + drTestLunNames: "{{ drTestLunNames }}" + drTestLunClasses: "{{ drTestLunClasses }}" + failed_when: (drHostWwns|length == 0) or (drTestLunNames|length == 0) + + - block: + + # Begin Workflow Steps + + - set_fact: + + # Activate DR Test Snapshot CGs + Step_1_1_Execute: True + Step_1_1_Completed: False + Step_1_1_Rollbacked: False + + # Set Class for DR Test LUNs + Step_1_2_Execute: True + Step_1_2_Completed: False + Step_1_2_Rollbacked: False + + # Remove WWNs from DR Hosts + Step_2_1_Execute: True + Step_2_1_Completed: False + Step_2_1_Rollbacked: False + + # Add WWNs to DR Test Hosts + Step_2_2_Execute: True + Step_2_2_Completed: False + Step_2_2_Rollbacked: False + + # Update DR Test LUNs to KPI table + Step_3_1_Execute: True + Step_3_1_Completed: False + + - name: Workflow - DR Test for Hosts + debug: + msg: + Step_1_1: "[{{Step_1_1_Execute}}] Activate DR Test Snapshot CGs" + Step_1_2: "[{{Step_1_2_Execute}}] Set Class for DR Test LUNs" + Step_2_1: "[{{Step_2_1_Execute}}] Remove WWNs from DR Hosts" + Step_2_2: "[{{Step_2_2_Execute}}] Add WWNs to DR Test Hosts" + Step_3_1: "[{{Step_3_1_Execute}}] Update DR Test LUNs to KPI table" + + - block: + - name: Step_1_1 - Activate DR Test Snapshot CGs + debug: + msg: + params: + cgNames: "{{ drCgNames }}" + cgTestNames: "{{ drTestCgNames }}" + device: "{{ deviceName }}" + + - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/activate_snapshot_cg.yml" + vars: + cgName: "{{ drTestCgName }}" + loop: "{{ drTestCgNames }}" + loop_control: + loop_var: drTestCgName + + - set_fact: + Step_1_1_Completed: True + + # End Step_1_1 + + # End block + when: Step_1_1_Execute + + - block: + - name: Step_1_2 - Set Class for DR Test LUNs + debug: + msg: + params: + volumeNames: "{{ drTestLunNames }}" + tierNames: "{{ drTestLunClasses }}" + + - include_tasks: "{{GLOBAL.baseDir}}/task/volume/add_volumes_to_tier.yml" + vars: + volumeNames: ["{{ drTestLun.0 }}"] + tierName: "{{ drTestLun.1 }}" + loop: "{{ drTestLunNames|zip(drTestLunClasses)|list }}" + loop_control: + loop_var: drTestLun + + - set_fact: + Step_1_2_Completed: True + + # End Step_1_2 + + # End block + when: Step_1_2_Execute + + - block: + - name: Step_2_1 - Remove WWNs from DR Hosts + debug: + msg: + params: + wwns: "{{ drHostWwns }}" + device: "{{ deviceName }}" + + - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/remove_ports_from_host.yml" + vars: + wwns: "{{ drHostWwnsItem.value }}" + hostName: "{{ drHostWwnsItem.key }}" + loop: "{{ lookup('dict', drHostWwns, wantlist=True) }}" + loop_control: + loop_var: drHostWwnsItem + + - set_fact: + Step_2_1_Completed: True + + # End Step_2_1 + + # End block + when: Step_2_1_Execute + + - block: + - name: Step_2_2 - Add WWNs to DR Test Hosts + debug: + msg: + params: + wwns: "{{ drTestHostWwns }}" + device: "{{ deviceName }}" + + - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/add_ports_to_host.yml" + vars: + wwns: "{{ drHostTestWwnsItem.value }}" + hostName: "{{ drHostTestWwnsItem.key }}" + loop: "{{ lookup('dict', drTestHostWwns, wantlist=True) }}" + loop_control: + loop_var: drHostTestWwnsItem + + - set_fact: + Step_2_2_Completed: True + + # End Step_2_2 + + # End block + when: Step_2_2_Execute + + - block: + - name: Step_3_1 - Update DR Test LUNs to KPI table + debug: + msg: + params: + lunIds: "{{ drTestLunIds }}" + classes: "{{ drTestLunClasses }}" + + # Minus Non-Class capacity + - include_tasks: update_lun_kpi_table.yml + vars: + TYPE_OF_OPERATION: "modify" + WBE_CODE: "{{ WBE_CODE }}" + TICKET_NUMBER: "{{ TICKET_NUMBER }}" + SYSTEM_NAME: "{{ '_'.join(drTestLunNames[item.0].split('_')[:4]) }}" + SITE: "{{ site }}" + ENVIRONMENT: "{{ osType }}" + STORAGE_CLASS: "" + CAPACITY_GB: "-{{ (drTestLunSectors[item.0]|int / 1024 / 1024 / 2)|int }}" + STORAGE: "{{ deviceName }}" + VDISK_UID: "{{ item.1 }}" + with_indexed_items: "{{ drTestLunIds }}" + + # Add capacity to Class + - include_tasks: update_lun_kpi_table.yml + vars: + TYPE_OF_OPERATION: "modify" + WBE_CODE: "{{ WBE_CODE }}" + TICKET_NUMBER: "{{ TICKET_NUMBER }}" + SYSTEM_NAME: "{{ '_'.join(drTestLunNames[item.0].split('_')[:4]) }}" + SITE: "{{ site }}" + ENVIRONMENT: "{{ osType }}" + STORAGE_CLASS: "{{ drTestLunClasses[item.0] }}" + CAPACITY_GB: "{{ (drTestLunSectors[item.0]|int / 1024 / 1024 / 2)|int }}" + STORAGE: "{{ deviceName }}" + VDISK_UID: "{{ item.1 }}" + with_indexed_items: "{{ drTestLunIds }}" + + - set_fact: + Step_3_1_Completed: True + + # End Step_3_1 + + # End block + when: Step_3_1_Execute + + # End Steps + rescue: + + - block: + - name: Rollback_2_2 - Remove WWNs from DR Test Hosts + debug: + msg: + params: + wwns: "{{ drTestHostWwns }}" + device: "{{ deviceName }}" + + - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/remove_ports_from_host.yml" + vars: + wwns: "{{ drTestHostWwnsItem.value }}" + hostName: "{{ drTestHostWwnsItem.key }}" + loop: "{{ lookup('dict', drTestHostWwns, wantlist=True) }}" + loop_control: + loop_var: drTestHostWwnsItem + + - set_fact: + Step_2_2_Rollbacked: True + + # End Rollback_2_2 + + # End block + when: Step_2_2_Completed + + - block: + - name: Rollback_2_1 - Add WWNs to DR Hosts + debug: + msg: + params: + wwns: "{{ drHostWwns }}" + device: "{{ deviceName }}" + + - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/add_ports_to_host.yml" + vars: + wwns: "{{ drHostWwnsItem.value }}" + hostName: "{{ drHostWwnsItem.key }}" + loop: "{{ lookup('dict', drHostWwns, wantlist=True) }}" + loop_control: + loop_var: drHostWwnsItem + + - set_fact: + Step_2_1_Rollbacked: True + + # End Rollback_2_1 + + # End block + when: Step_2_1_Completed + + - block: + - name: Rollback_1_2 - Remove Class for DR Test LUNs + debug: + msg: + params: + volumeNames: "{{ drTestLunNames }}" + tierNames: "{{ drTestLunClasses }}" + + - include_tasks: "{{GLOBAL.baseDir}}/task/volume/remove_volumes_from_tier.yml" + vars: + volumeNames: "{{ drTestLun.0 }}" + tierName: "{{ drTestLun.1 }}" + loop: "{{ drTestLunNames|zip(drTestLunClasses)|list }}" + loop_control: + loop_var: drTestLun + + - set_fact: + Step_1_2_Rollbacked: True + + # End Rollback_1_2 + + # End block + when: Step_1_2_Completed + + - block: + - name: Rollback_1_1 - Deactivate DR Test Snapshot CGs + debug: + msg: + params: + cgTestNames: "{{ drTestCgNames }}" + device: "{{ deviceName }}" + + - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/deactivate_snapshot_cg.yml" + vars: + cgName: "{{ drTestCgName }}" + loop: "{{ drTestCgNames }}" + loop_control: + loop_var: drTestCgName + + - set_fact: + Step_1_1_Rollbacked: True + + # End Rollback_1_1 + + # End block + when: Step_1_1_Completed + + # End Rollbacks + always: + + - name: Final_Step_1 - Sync DR Device + debug: + msg: + device: "{{ deviceName }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/sync_storage.yml" + + # End Final Steps + + # End Workflow + + + - block: + + # Begin Validate Results + + - name: Result_1_1 - Activate DR Test Snapshot CGs + debug: + msg: + params: + cgNames: "{{ drTestCgNames }}" + cgTestNames: "{{ drTestCgNames }}" + device: "{{ deviceName }}" + result: + succeeded: "{{ Step_1_1_Completed }}" + rollbacked: "{{ Step_1_1_Rollbacked }}" + failed_when: Step_1_1_Completed|bool == False + when: Step_1_1_Execute + + - name: Result_1_2 - Set Class for DR Test LUNs + debug: + msg: + params: + volumeNames: "{{ drTestLunNames }}" + tierName: "{{ drTestLunClasses }}" + result: + succeeded: "{{ Step_1_2_Completed }}" + rollbacked: "{{ Step_1_2_Rollbacked }}" + failed_when: Step_1_2_Completed|bool == False + when: Step_1_2_Execute + + - name: Result_2_1 - Remove WWNs from DR Host + debug: + msg: + params: + wwns: "{{ drHostWwns }}" + device: "{{ deviceName }}" + result: + succeeded: "{{ Step_2_1_Completed }}" + rollbacked: "{{ Step_2_1_Rollbacked }}" + failed_when: Step_2_1_Completed|bool == False + when: Step_2_1_Execute + + - name: Result_2_2 - Add WWNs to DR Test Hosts + debug: + msg: + params: + wwns: "{{ drHostWwns }}" + device: "{{ deviceName }}" + result: + succeeded: "{{ Step_2_2_Completed }}" + rollbacked: "{{ Step_2_2_Rollbacked }}" + failed_when: Step_2_2_Completed|bool == False + when: Step_2_2_Execute + + - name: Result_3_1 - Update DR Test LUNs to KPI table + debug: + msg: + params: + lunIds: "{{ drTestLunIds }}" + classes: "{{ drTestLunClasses }}" + result: + succeeded: "{{ Step_3_1_Completed }}" + failed_when: Step_3_1_Completed|bool == False + when: Step_3_1_Execute \ No newline at end of file diff --git a/rundeck/workflow/project001/56_dr_test_clean_for_multi_host.yml b/rundeck/workflow/project001/56_dr_test_clean_for_multi_host.yml new file mode 100644 index 0000000..9ffa055 --- /dev/null +++ b/rundeck/workflow/project001/56_dr_test_clean_for_multi_host.yml @@ -0,0 +1,844 @@ +- name: DR Test Clean for Hosts + hosts: localhost + vars_files: + - ../../../config/global.yml + - ../../../config/project001.yml + gather_facts: no + become: no + tasks: + + # Check Params + - block: + - set_fact: + checked_params: + Select_DR_Host: "{{ (Select_DR_Host|string).split(',')|length >= 1 }}" + DR_Storage: "{{ (DR_Storage is not none and DR_Storage != DEFAULT.noneValue) and (DR_Storage|string|length == 20) }}" + Check_Result_1: "{{ 'host' in Check_Result_1 }}" + + - name: Precheck_0_1 - Check Params + debug: + msg: "{{checked_params}}" + failed_when: checked_params.values()|unique != [True] + + - set_fact: + WBE_CODE: "{{ WBE_CODE }}" + TICKET_NUMBER: "{{ TICKET_NUMBER }}" + osType: "{{ OS_Type }}" + deviceSn: "{{ DR_Storage|string }}" + room: "{{ DR_Storage_Room }}" + site: "{{ AZ[DR_Storage_Room]['dc'] }}" + drHostNames: "{{ (Select_DR_Host|string).split(',') }}" + + - set_fact: + protectType: "{{ REPTYPE['N3']['enum'] }}" # N3 is same as Y3 enum, use one of them to stand all cases, See ../../config/project001.yml + + - set_fact: + lunNameTemplate: "%s_{{protectType}}N%0{{DEFAULT.suffixDigits}}d" + + - import_tasks: "{{GLOBAL.baseDir}}/task/user/login.yml" + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/login_storage.yml" + + - name: Precheck_1 - Check Hosts, WWNs + debug: + msg: + drHostNames: "{{ drHostNames }}" + + # check wwns + - set_fact: + drTestHostNames: [] + + - set_fact: + drTestHostNames: "{{ drTestHostNames + [ item[:-1] + '3' ] }}" + with_items: "{{ drHostNames }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_host_wwns.yml" + vars: + hostNames: "{{ drHostNames }}" + checkExist: False + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_host_wwns.yml" + vars: + hostNames: "{{ drTestHostNames }}" + + - set_fact: + drTestHostWwns: "{{ checkedWwns }}" + drHostWwns: {} + + - set_fact: + drHostWwns: "{{ drHostWwns | combine( { item.0: drTestHostWwns[item.1] } ) }}" + with_together: + - "{{ drHostNames }}" + - "{{ drTestHostNames }}" + + # check host lun + - set_fact: + checkedHostLuns: [] + + - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_host_lun_id_loop_helper.yml" + vars: + hostName: "{{ drHostName }}" + loop: "{{ drHostNames }}" + loop_control: + loop_var: drHostName + + - set_fact: + checkedDrHostLuns: {} + + - set_fact: + checkedDrHostLuns: "{{ checkedDrHostLuns | combine(item) }}" + loop: "{{ checkedHostLuns }}" + + - name: Check Host Luns Number in LGs + debug: + msg: + item: "{{ item }}" + failed_when: item.value|length == 0 + with_dict: "{{ checkedDrHostLuns }}" + + - set_fact: + drLgNames: "{{ checkedDrHostLuns.keys() }}" + drTestLgNames: [] + drPgNames: [] + + - set_fact: + drPgNames: "{{ drPgNames + [ item[:-6] + '2_PG' + item[-2:] ] }}" + drTestLgNames: "{{ drTestLgNames + [ item[:-6] + '3_LG' + item[-2:] ] }}" + with_items: "{{ drLgNames }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_pgs.yml" + vars: + pgNames: "{{ drPgNames }}" + + - set_fact: + drPgIds: "{{ pgIds }}" + checkedPgSnapCgs: [] + + - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/get_snapshot_cgs_by_pg_loop_helper.yml" + vars: + pgId: "{{ drPgId }}" + loop: "{{ drPgIds }}" + loop_control: + loop_var: drPgId + + - name: Check Snapshot CGs Number and Status + debug: + msg: + SnapshotCgs: "{{ item }}" + status: "{{ item[0].RUNNINGSTATUS }}" + failed_when: (item|length|int != 1) or (item|length|int == 1 and item[0].RUNNINGSTATUS|int != SNAPCG.activated.enum) + loop: "{{ checkedPgSnapCgs }}" + + - set_fact: + drTestCgNames: [] + drTestCgIds: [] + + - set_fact: + drTestCgNames: "{{ drTestCgNames + [ item[0].NAME ] }}" + drTestCgIds: "{{ drTestCgIds + [ item[0].ID ] }}" + loop: "{{ checkedPgSnapCgs }}" + + - set_fact: + checkedPgRepCgs: [] + + - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/get_replication_cgs_by_pg_loop_helper.yml" + vars: + pgId: "{{ drPgId }}" + loop: "{{ drPgIds }}" + loop_control: + loop_var: drPgId + + - debug: + msg: + checkedPgRepCgs: "{{ checkedPgRepCgs }}" + drHostNames: "{{ drPgNames }}" + failed_when: item|length|int != 1 + loop: "{{ checkedPgRepCgs }}" + + - set_fact: + drCgNames: [] + + - set_fact: + drCgNames: "{{ drCgNames + [ item[0].NAME ] }}" + loop: "{{ checkedPgRepCgs }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_lgs.yml" + vars: + lgNames: "{{ drLgNames }}" + + - set_fact: + targetLunsAll: [] + targetLunNamesAll: [] + + - include_tasks: "{{GLOBAL.baseDir}}/rundeck/workflow/project001/loop_helper/56_target_luns_loop_helper.yml" + vars: + luns: "{{ checkedLuns[drLgName] }}" + hostLuns: "{{ checkedDrHostLuns[drLgName] }}" + pgName: "{{ drPgNames[index] }}" + cgName: "{{ drTestCgNames[index] }}" + lgName: "{{ drTestLgNames[index] }}" + hostName: "{{ drTestHostNames[index] }}" + className: "{{ checkedLgs[index].DESCRIPTION[4:5] }}" + loop: "{{ drLgNames }}" + loop_control: + index_var: index + loop_var: drLgName + + - set_fact: + targetLunNamesAll: "{{ targetLunNamesAll + item.lunNames }}" + loop: "{{ targetLunsAll }}" + + - set_fact: + existDrLunNamesAll: [] + + - set_fact: + existDrLunNamesAll: "{{ existDrLunNames + [checkedLuns[item] | json_query('[*].NAME')] }}" + loop: "{{ drLgNames }}" + + + - name: Query Snapshots in CG + uri: + url: "https://{{deviceHost}}:{{devicePort}}/deviceManager/rest/{{deviceSn}}/snapshot/associate?ASSOCIATEOBJTYPE=57646&ASSOCIATEOBJID={{item}}" + method: GET + validate_certs: no + headers: + Accept: "application/json" + Content-Type: "application/json;charset=utf8" + iBaseToken: "{{ deviceToken }}" + Cookie: "session={{ deviceSession }}" + register: SNAPSHOTS + with_items: "{{ drTestCgIds }}" + + - set_fact: + sourceDrLunNames: [] + + - name: Get AZ IDs + set_fact: + sourceDrLunNames: "{{ sourceDrLunNames + SNAPSHOTS.json.data | default([]) | json_query('[*].SOURCELUNNAME') }}" + with_indexed_items: "{{ drTestCgIds }}" + + - set_fact: + orphanDrLunNames: "{{ sourceDrLunNames | difference(existDrLunNamesAll) }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_luns.yml" + vars: + lunNames: "{{ orphanDrLunNames }}" + when: orphanDrLunNames|length > 0 + + - set_fact: + orphanDrLunIds: "{{ checkedLuns | json_query('[*].ID') }}" + orphanDrLunSectors: "{{ checkedLuns | json_query('[*].CAPACITY') }}" + when: orphanDrLunNames|length > 0 + + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_lgs.yml" + vars: + lgNames: "{{ drTestLgNames }}" + + - set_fact: + checkedDrLgLuns: "{{ checkedLuns }}" + drTestLunNames: [] + drTestLunIds: [] + drTestLunSectors: [] + + - set_fact: + drTestLunNames: "{{ drTestLunNames + item.value | json_query('[*].NAME') }}" + drTestLunIds: "{{ drTestLunIds + item.value | json_query('[*].ID') }}" + drTestLunSectors: "{{ drTestLunSectors + item.value | json_query('[*].CAPACITY') }}" + with_dict: "{{ checkedLuns }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/volume/check_volumes.yml" + vars: + volumeNames: "{{ drTestLunNames }}" + + - set_fact: + drTestLunClass: [] + drTestLunsInTier: {} + tierNames: "{{ checkedVolumes | json_query('[*].service_level_name') | unique }}" + + - set_fact: + drTestLunClass: "{{ drTestLunClass + [ checkedVolumes[item.0].service_level_name ] }}" + with_indexed_items: "{{ drTestLunNames }}" + + - set_fact: + drTestLunsInTier: "{{ drTestLunsInTier | combine( { item: checkedVolumes | json_query(queryVolumesInTier) } ) }}" + vars: + queryVolumesInTier: "[? service_level_name == '{{ item }}' ].id" + with_items: "{{ tierNames }}" + + - debug: + msg: + drHostWwns: "{{ drHostWwns }}" + drCgNames: "{{ drCgNames }}" + drTestLunNames: "{{ drTestLunNames }}" + drTestCgNames: "{{ drTestCgNames }}" + targetLunsAll: "{{ targetLunsAll }}" + failed_when: drHostWwns|length == 0 or drTestLunNames|length == 0 + + - block: + + # Begin Workflow Steps + + - set_fact: + + # Remove WWNs from DR Test Hosts + Step_1_1_Execute: True + Step_1_1_Completed: False + Step_1_1_Rollbacked: False + + # Add WWNs to DR Hosts + Step_1_2_Execute: True + Step_1_2_Completed: False + Step_1_2_Rollbacked: False + + # Remove DR Test LUNs from Class + Step_2_1_Execute: True + Step_2_1_Completed: False + Step_2_1_Rollbacked: False + + # Remove DR Test LUNs from LUN Group + Step_2_2_Execute: True + Step_2_2_Completed: False + Step_2_2_Rollbacked: False + + # Delete DR Test Snapshot CGs + Step_2_3_Execute: True + Step_2_3_Completed: False + Step_2_3_Rollbacked: False + + # Re-Create DR Test Snapshot CGs + Step_2_4_Execute: "{{ targetLunNames|length > 0 }}" + Step_2_4_Completed: False + Step_2_4_Rollbacked: False + + # Add DR Test LUNs to LUN Group + Step_2_5_Execute: "{{ targetLunNames|length > 0 }}" + Step_2_5_Completed: False + Step_2_5_Rollbacked: False + + # Delete Orphan DR LUNs + Step_2_6_Execute: "{{ orphanDrLunNames|length > 0 }}" + Step_2_6_Completed: False + Step_2_6_Rollbacked: False + + # Update DR Test LUNs to KPI table + Step_3_1_Execute: True + Step_3_1_Completed: False + Step_3_1_Rollbacked: False + + # Update Orphan DR LUNs to KPI table + Step_3_2_Execute: "{{ orphanDrLunNames|length > 0 }}" + Step_3_2_Completed: False + Step_3_2_Rollbacked: False + + - name: Workflow - DR Test Clean for Multi-Host + debug: + msg: + Step_1_1: "[{{Step_1_1_Execute}}] Remove WWNs from DR Test Hosts" + Step_1_2: "[{{Step_1_2_Execute}}] Add WWNs to DR Hosts" + Step_2_1: "[{{Step_2_1_Execute}}] Remove DR Test LUNs from Class" + Step_2_2: "[{{Step_2_2_Execute}}] Remove DR Test LUNs from LUN Group" + Step_2_3: "[{{Step_2_3_Execute}}] Delete DR Test Snapshot CGs" + Step_2_4: "[{{Step_2_4_Execute}}] Re-Create DR Test Snapshot CGs" + Step_2_5: "[{{Step_2_5_Execute}}] Add DR Test LUNs to LUN Group" + Step_2_6: "[{{Step_2_6_Execute}}] Delete Orphan DR LUNs" + Step_3_1: "[{{Step_3_1_Execute}}] Update DR Test LUNs to KPI table" + Step_3_2: "[{{Step_3_2_Execute}}] Update Orphan DR LUNs to KPI table" + + - block: + - name: Step_1_1 - Remove WWNs from DR Test Hosts + debug: + msg: + params: + wwns: "{{ drTestHostWwns }}" + device: "{{ deviceName }}" + + - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/remove_ports_from_host.yml" + vars: + wwns: "{{ drTestHostWwnsItem.value }}" + hostName: "{{ drTestHostWwnsItem.key }}" + loop: "{{ lookup('dict', drTestHostWwns, wantlist=True) }}" + loop_control: + loop_var: drTestHostWwnsItem + + - set_fact: + Step_1_1_Completed: True + + # End Step_1_1 + + # End block + when: Step_1_1_Execute + + - block: + - name: Step_1_2 - Add WWNs to DR Hosts + debug: + msg: + params: + wwns: "{{ drHostWwns }}" + device: "{{ deviceName }}" + + - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/add_ports_to_host.yml" + vars: + wwns: "{{ drHostWwnsItem.value }}" + hostName: "{{ drHostWwnsItem.key }}" + loop: "{{ lookup('dict', drHostWwns, wantlist=True) }}" + loop_control: + loop_var: drHostWwnsItem + + - set_fact: + Step_1_2_Completed: True + + # End Step_1_2 + + # End block + when: Step_1_2_Execute + + - block: + - name: Step_2_1 - Remove DR Test LUNs from Class + debug: + msg: + params: + drTestLunsInTier: "{{ drTestLunsInTier }}" + + - include_tasks: "{{GLOBAL.baseDir}}/task/volume/remove_volumes_from_tier.yml" + vars: + volumeIds: "{{ drTestLunsInTierItem.value }}" + loop: "{{ lookup('dict', drTestLunsInTier, wantlist=True) }}" + loop_control: + loop_var: drTestLunsInTierItem + + - set_fact: + Step_2_1_Completed: True + + # End Step_2_1 + + # End block + when: Step_2_1_Execute + + - block: + - name: Step_2_2 - Remove DR Test LUNs from LUN Group + debug: + msg: + params: + lunNames: "{{ drTestLunNames }}" + lgName: "{{ drTestLgNames }}" + device: "{{ deviceName }}" + + - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/remove_luns_from_lg.yml" + vars: + lgName: "{{ checkedDrLgLunsItem.key }}" + lunNames: "{{ checkedDrLgLunsItem.value | json_query('[*].NAME') }}" + loop: "{{ lookup('dict', checkedDrLgLuns, wantlist=True) }}" + loop_control: + loop_var: checkedDrLgLunsItem + + - set_fact: + Step_2_2_Completed: True + + # End Step_2_2 + + # End block + when: Step_2_2_Execute + + - block: + - name: Step_2_3 - Delete DR Test Snapshot CGs + debug: + msg: + params: + cgNames: "{{ drTestCgNames }}" + device: "{{ deviceName }}" + + - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/delete_snapshot_cg.yml" + vars: + cgName: "{{ drTestCgName }}" + loop: "{{ drTestCgNames }}" + loop_control: + loop_var: drTestCgName + + - set_fact: + Step_2_3_Completed: True + + # End Step_2_3 + + # End block + when: Step_2_3_Execute + + - block: + - name: Step_2_4 - Re-Create DR Test Snapshot CGs + debug: + msg: + params: + cgNames: "{{ drTestCgNames }}" + device: "{{ deviceName }}" + + - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/create_snapshot_cg.yml" + vars: + pgName: "{{ targetLuns.pgName }}" + cgName: "{{ targetLuns.cgName }}" + snapNames: "{{ targetLuns.lunNames }}" + activate: False + snapDescs: "{{ targetLuns.lunDescs }}" + loop: "{{ targetLunsAll }}" + loop_control: + loop_var: targetLuns + + - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_luns.yml" + vars: + lunNames: "{{ targetLunNamesAll }}" + + - set_fact: + targetLunIdsAll: "{{ checkedLuns | json_query('[*].ID') }}" + targetLunSectorsAll: "{{ checkedLuns | json_query('[*].CAPACITY') }}" + + - set_fact: + Step_2_4_Completed: True + + # End Step_2_4 + + # End block + when: Step_2_4_Execute + + - block: + - name: Step_2_5 - Add DR Test LUNs to LUN Group + debug: + msg: + params: + luns: "{{ targetLunsAll }}" + device: "{{ deviceName }}" + + - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/add_luns_to_lg.yml" + vars: + lunNames: "{{ targetLuns.lunNames }}" + lgName: "{{ targetLuns.lgName }}" + addLunScsiIds: "{{ targetLuns.lunScsiIds }}" + loop: "{{ targetLunsAll }}" + loop_control: + loop_var: targetLuns + + - set_fact: + Step_2_5_Completed: True + + # End Step_2_5 + + # End block + when: Step_2_5_Execute + + - block: + - name: Step_2_6 - Delete Orphan DR LUNs + debug: + msg: + params: + lunNames: "{{ orphanDrLunNames }}" + device: "{{ deviceName }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/delete_luns.yml" + vars: + lunNames: "{{ orphanDrLunNames }}" + + - set_fact: + Step_2_6_Completed: True + + # End Step_2_6 + + # End block + when: Step_2_6_Execute + + - block: + - name: Step_3_1 - Update DR Test LUNs to KPI table + debug: + msg: + params: + lunIds: "{{ drTestLunIds }}" + lunNames: "{{ drTestLunNames }}" + + - include_tasks: update_lun_kpi_table.yml + vars: + TYPE_OF_OPERATION: "delete" + WBE_CODE: "{{ WBE_CODE }}" + TICKET_NUMBER: "{{ TICKET_NUMBER }}" + SYSTEM_NAME: "{{ '_'.join(drTestLunNames[index].split('_')[:4]) }}" + SITE: "{{ site }}" + ENVIRONMENT: "{{ osType }}" + STORAGE_CLASS: "{{ drTestLunClass[index] }}" + CAPACITY_GB: "-{{ (drTestLunSectors[index]|int / 1024 / 1024 / 2)|int }}" + STORAGE: "{{ deviceName }}" + VDISK_UID: "{{ lunId }}" + loop: "{{ drTestLunIds }}" + loop_control: + index_var: index + loop_var: lunId + + - include_tasks: update_lun_kpi_table.yml + vars: + TYPE_OF_OPERATION: "create" + WBE_CODE: "{{ WBE_CODE }}" + TICKET_NUMBER: "{{ TICKET_NUMBER }}" + SYSTEM_NAME: "{{ '_'.join(targetLunNamesAll[index].split('_')[:4]) }}" + SITE: "{{ site }}" + ENVIRONMENT: "{{ osType }}" + STORAGE_CLASS: "" + CAPACITY_GB: "{{ (targetLunSectorsAll[index]|int / 1024 / 1024 / 2)|int }}" + STORAGE: "{{ deviceName }}" + VDISK_UID: "{{ lunId }}" + loop: "{{ targetLunIdsAll }}" + loop_control: + index_var: index + loop_var: lunId + when: targetLunIdsAll|default([])|length > 0 + + - set_fact: + Step_3_1_Completed: True + + # End Step_3_1 + + # End block + when: Step_3_1_Execute + + - block: + - name: Step_3_2 - Update Orphan DR LUNs to KPI table + debug: + msg: + params: + lunIds: "{{ orphanDrLunIds }}" + + - include_tasks: update_lun_kpi_table.yml + vars: + TYPE_OF_OPERATION: "delete" + WBE_CODE: "{{ WBE_CODE }}" + TICKET_NUMBER: "{{ TICKET_NUMBER }}" + SYSTEM_NAME: "{{ orphanDrLunNames[index][:-6] }}" + SITE: "{{ site }}" + ENVIRONMENT: "{{ osType }}" + STORAGE_CLASS: "" + CAPACITY_GB: "-{{ (orphanDrLunSectors[index]|int / 1024 / 1024 / 2)|int }}" + STORAGE: "{{ deviceName }}" + VDISK_UID: "{{ lunId }}" + with_indexed_items: "{{ orphanDrLunIds }}" + loop: "{{ orphanDrLunIds }}" + loop_control: + index_var: index + loop_var: lunId + + - set_fact: + Step_3_2_Completed: True + + # End Step_3_2 + + # End block + when: Step_3_2_Execute + + # End Steps + rescue: + + # Unable to rollback DR Test CGs, need to manually rollback + + - block: + - name: Rollback_2_4 - Reactivated DR Test Snapshot CG + debug: + msg: + params: + cgNames: "{{ drTestCgNames }}" + device: "{{ deviceName }}" + + - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/activate_snapshot_cg.yml" + vars: + cgName: "{{ drTestCgName }}" + loop: "{{ drTestCgNames }}" + loop_control: + loop_var: drTestCgName + + - set_fact: + Step_2_3_Rollbacked: True + Step_2_4_Rollbacked: True + + # End Rollback_2_4 + + # End block + when: Step_2_4_Completed + + - block: + - name: Rollback_1_2 - Remove WWNs from DR Hosts + debug: + msg: + params: + wwns: "{{ drHostWwns }}" + hostNames: "{{ drHostNames }}" + device: "{{ deviceName }}" + + - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/remove_ports_from_host.yml" + vars: + wwns: "{{ drHostWwnsItem.value }}" + hostName: "{{ drHostWwnsItem.key }}" + loop: "{{ lookup('dict', drHostWwns, wantlist=True) }}" + loop_control: + loop_var: drHostWwnsItem + + - set_fact: + Step_1_2_Rollbacked: True + + # End Rollback_1_2 + + # End block + when: Step_1_2_Completed + + - block: + - name: Rollback_1_1 - Add WWNs to DR Test Hosts + debug: + msg: + params: + wwns: "{{ drTestHostWwns }}" + hostNames: "{{ drTestHostNames }}" + device: "{{ deviceName }}" + + - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/add_ports_to_host.yml" + vars: + wwns: "{{ drTestHostWwnsItem.value }}" + hostName: "{{ drTestHostWwnsItem.key }}" + loop: "{{ lookup('dict', drTestHostWwns, wantlist=True) }}" + loop_control: + loop_var: drTestHostWwnsItem + + - set_fact: + Step_1_1_Rollbacked: True + + # End Rollback_1_1 + + # End block + when: Step_1_1_Completed + + # End Rollbacks + always: + + - name: Final_Step_1 - Sync DR Device + debug: + msg: + device: "{{ deviceName }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/sync_storage.yml" + + # End Final Steps + + # End Workflow + + + - block: + + # Begin Validate Results + + - name: Result_1_1 - Remove WWNs from DR Test Hosts + debug: + msg: + params: + wwns: "{{ drHostWwns }}" + hostNames: "{{ drTestHostNames }}" + device: "{{ deviceName }}" + result: + succeeded: "{{ Step_1_1_Completed }}" + rollbacked: "{{ Step_1_1_Rollbacked }}" + failed_when: Step_1_1_Completed|bool == False + when: Step_1_1_Execute + + - name: Result_1_2 - Add WWNs to DR Hosts + debug: + msg: + params: + wwns: "{{ drHostWwns }}" + hostNames: "{{ drHostNames }}" + device: "{{ deviceName }}" + result: + succeeded: "{{ Step_1_2_Completed }}" + rollbacked: "{{ Step_1_2_Rollbacked }}" + failed_when: Step_1_2_Completed|bool == False + when: Step_1_2_Execute + + - name: Result_2_1 - Remove DR Test LUNs from Class + debug: + msg: + params: + drTestLunsInTier: "{{ drTestLunsInTier }}" + result: + succeeded: "{{ Step_2_1_Completed }}" + rollbacked: "{{ Step_2_1_Rollbacked }}" + failed_when: Step_2_1_Completed|bool == False + when: Step_2_1_Execute + + - name: Result_2_2 - Remove DR Test LUNs from LUN Group + debug: + msg: + params: + lunNames: "{{ drTestLunNames }}" + lgNames: "{{ drTestLgNames }}" + device: "{{ deviceName }}" + result: + succeeded: "{{ Step_2_2_Completed }}" + rollbacked: "{{ Step_2_2_Rollbacked }}" + failed_when: Step_2_2_Completed|bool == False + when: Step_2_2_Execute + + - name: Result_2_3 - Delete DR Test Snapshot CG + debug: + msg: + params: + cgNames: "{{ drTestCgNames }}" + device: "{{ deviceName }}" + result: + succeeded: "{{ Step_2_3_Completed }}" + rollbacked: "{{ Step_2_3_Rollbacked }}" + failed_when: Step_2_3_Completed|bool == False + when: Step_2_3_Execute + + - name: Result_2_4 - Re-Create DR Test Snapshots + debug: + msg: + params: + cgNames: "{{ drTestCgNames }}" + device: "{{ deviceName }}" + result: + succeeded: "{{ Step_2_4_Completed }}" + rollbacked: "{{ Step_2_4_Rollbacked }}" + failed_when: Step_2_4_Completed|bool == False + when: Step_2_4_Execute + + - name: Result_2_5 - Add DR Test LUNs to LUN Group + debug: + msg: + params: + luns: "{{ targetLunsAll }}" + device: "{{ deviceName }}" + result: + succeeded: "{{ Step_2_5_Completed }}" + rollbacked: "{{ Step_2_5_Rollbacked }}" + failed_when: Step_2_5_Completed|bool == False + when: Step_2_5_Execute + + - name: Result_2_6 - Delete Orphan DR LUNs + debug: + msg: + params: + lunNames: "{{ orphanDrLunNames }}" + device: "{{ deviceName }}" + result: + succeeded: "{{ Step_2_6_Completed }}" + rollbacked: "{{ Step_2_6_Rollbacked }}" + failed_when: Step_2_6_Completed|bool == False + when: Step_2_6_Execute + + - name: Result_3_1 - Update DR Test LUNs to KPI table + debug: + msg: + params: + lunIds: "{{ drTestLunIds }}" + result: + succeeded: "{{ Step_3_1_Completed }}" + failed_when: Step_3_1_Completed|bool == False + when: Step_3_1_Execute + + - name: Result_3_2 - Update Orphan DR LUNs to KPI table + debug: + msg: + params: + lunIds: "{{ orphanDrLunIds }}" + result: + succeeded: "{{ Step_3_2_Completed }}" + failed_when: Step_3_2_Completed|bool == False + when: Step_3_2_Execute + diff --git a/rundeck/workflow/project001/57_dr_test_for_multi_cluster.yml b/rundeck/workflow/project001/57_dr_test_for_multi_cluster.yml new file mode 100644 index 0000000..11479b3 --- /dev/null +++ b/rundeck/workflow/project001/57_dr_test_for_multi_cluster.yml @@ -0,0 +1,614 @@ +- name: DR Test for Clusters + hosts: localhost + vars_files: + - ../../../config/global.yml + - ../../../config/project001.yml + gather_facts: no + become: no + tasks: + # Check Params + - block: + - set_fact: + checked_params: + Select_DR_Cluster: "{% set clusters = [] %}{% set Select_DR_Cluster = Select_DR_Cluster|string %}{% for cluster in Select_DR_Cluster.split(',') if cluster.endswith('_2') %}{{ clusters.append(cluster) }}{% endfor %}{{ (clusters | length >= 1) and (clusters | length == Select_DR_Cluster.split(',') | length) }}" + DR_Storage: "{{ (DR_Storage is not none and DR_Storage != DEFAULT.noneValue) and (DR_Storage|string|length == 20) }}" + Check_Result_1: "{{ ('cluster' in Check_Result_1) }}" + + - name: Precheck_0_1 - Check Params + debug: + msg: "{{checked_params}}" + failed_when: checked_params.values()|unique != [True] + + - set_fact: + WBE_CODE: "{{ WBE_CODE }}" + TICKET_NUMBER: "{{ TICKET_NUMBER }}" + osType: "{{ OS_Type }}" + deviceSn: "{{ DR_Storage|string }}" + room: "{{ DR_Storage_Room }}" + site: "{{ AZ[DR_Storage_Room]['dc'] }}" + drClusterNames: "{{ (Select_DR_Cluster|string).split(',') }}" + designateClass3: "{{ Designate_Class_3|default(none) }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/user/login.yml" + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/login_storage.yml" + + - name: Precheck_1 - Check Clusters, Hosts, WWNs + debug: + msg: + hostGroupNames: "{{ drClusterNames }}" + + # check wwns + - set_fact: + drTestClusterNames: [] + - set_fact: + drTestClusterNames: "{{ drTestClusterNames + [ item[:-1] + '3' ] }}" + with_items: "{{ drClusterNames }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_hostgroups.yml" + vars: + hostGroupNames: "{{ drClusterNames }}" + - set_fact: + drClusterIds: "{{ hostGroupIds }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_hostgroups.yml" + vars: + hostGroupNames: "{{ drTestClusterNames }}" + - set_fact: + drTestClusterIds: "{{ hostGroupIds }}" + + - name: Get DR Hosts + uri: + url: "https://{{deviceHost}}:{{devicePort}}/deviceManager/rest/{{deviceSn}}/host/associate?ASSOCIATEOBJTYPE=14&ASSOCIATEOBJID={{item}}" + method: GET + validate_certs: no + headers: + Accept: "application/json" + Content-Type: "application/json;charset=utf8" + iBaseToken: "{{ deviceToken }}" + Cookie: "session={{ deviceSession }}" + register: DR_HOSTS + failed_when: (DR_HOSTS.json.error.code|int != 0) or ('data' not in DR_HOSTS.json) or (DR_HOSTS.json.data|length == 0) + with_items: "{{ drClusterIds }}" + + - set_fact: + drHostNames: "{{ DR_HOSTS.results | json_query('[*].json.data[*].NAME') | flatten(levels=1) }}" + drHostIds: "{{ DR_HOSTS.results | json_query('[*].json.data[*].ID') | flatten(levels=1) }}" + drHostWwns: {} + + - name: Get DR Test Hosts + uri: + url: "https://{{deviceHost}}:{{devicePort}}/deviceManager/rest/{{deviceSn}}/host/associate?ASSOCIATEOBJTYPE=14&ASSOCIATEOBJID={{item}}" + method: GET + validate_certs: no + headers: + Accept: "application/json" + Content-Type: "application/json;charset=utf8" + iBaseToken: "{{ deviceToken }}" + Cookie: "session={{ deviceSession }}" + register: DR_TEST_HOSTS + failed_when: (DR_TEST_HOSTS.json.error.code|int != 0) or ('data' not in DR_TEST_HOSTS.json) or (DR_TEST_HOSTS.json.data|length == 0) + with_items: "{{ drTestClusterIds }}" + + - set_fact: + drTestHostNames: "{{ DR_TEST_HOSTS.results | json_query('[*].json.data[*].NAME') | flatten(levels=1) }}" + drTestHostIds: "{{ DR_TEST_HOSTS.results | json_query('[*].json.data[*].ID') | flatten(levels=1) }}" + drTestHostWwns: {} + + - debug: + msg: + drHostNames: "{{ drHostNames }}" + drHostIds: "{{ drHostIds }}" + drTestHostNames: "{{ drTestHostNames }}" + drTestHostIds: "{{ drTestHostIds }}" + failed_when: drHostNames|length != drTestHostNames|length or drHostNames == 0 + + - name: Get WWNs + uri: + url: "https://{{deviceHost}}:{{devicePort}}/deviceManager/rest/{{deviceSn}}/fc_initiator?filter=PARENTID%3A%3A{{drHostIds[item.0]}}" + method: GET + validate_certs: no + headers: + Accept: "application/json" + Content-Type: "application/json;charset=utf8" + iBaseToken: "{{ deviceToken }}" + Cookie: "session={{ deviceSession }}" + register: WWNs + failed_when: (WWNs.json.error.code|int != 0) or ('data' not in WWNs.json) or (WWNs.json.data|length == 0) + with_indexed_items: "{{ drHostNames }}" + + - set_fact: + drHostWwns: "{{ drHostWwns | combine( { item.1: WWNs.results[item.0].json.data | json_query('[*].ID') } ) }}" + drTestHostWwns: "{{ drTestHostWwns | combine( { drTestHostNames[item.0]: WWNs.results[item.0].json.data | json_query('[*].ID') } ) }}" + with_indexed_items: "{{ drHostNames }}" + + - name: Query Host Mapping + uri: + url: "https://{{deviceHost}}:{{devicePort}}/deviceManager/rest/{{deviceSn}}/mapping/associate?ASSOCIATEOBJTYPE=21&ASSOCIATEOBJID={{item}}" + method: GET + validate_certs: no + headers: + Accept: "application/json" + Content-Type: "application/json;charset=utf8" + iBaseToken: "{{ deviceToken }}" + Cookie: "session={{ deviceSession }}" + register: HOST_MAPPINGs + with_items: "{{ drTestHostIds }}" + + - set_fact: + checkedLgNames: "{{ HOST_MAPPINGs.results | json_query(queryHostLgName) | flatten(levels=1) | unique }}" + vars: + queryHostLgName: "[*].json.data[?lunGroupName!=''].lunGroupName" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_lgs.yml" + vars: + lgNames: "{{ checkedLgNames }}" + + - set_fact: + drTestLunNames: "{{ checkedLuns.values() | flatten(levels=2) | json_query('[*].NAME') }}" + drTestLunIds: "{{ checkedLuns.values() | flatten(levels=2) | json_query('[*].ID') }}" + drTestLgNames: "{{ checkedLuns.keys() }}" + + - name: Check DR Host Luns Number in LGs + debug: + msg: + drTestLunNames: "{{ drTestLunNames }}" + failed_when: drTestLunNames|length == 0 + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_luns.yml" + vars: + lunNames: "{{ drTestLunNames }}" + + - set_fact: + drTestLunSectors: "{{ checkedLuns | json_query('[*].CAPACITY') }}" + drTestLunDesc: "{{ checkedLuns | json_query('[*].DESCRIPTION') }}" + drTestLunClasses: [] + + - set_fact: + drTestLunClasses: "{{ drTestLunClasses + [ designateClass3 if (designateClass3 != '' ) else item[:1] ]}}" + with_items: "{{ drTestLunDesc }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/volume/check_volumes.yml" + vars: + volumeNames: "{{ drTestLunNames }}" + + - name: Check Volume in Tier Class + debug: + msg: + lunsInTierClass: "{{ checkedVolumes|json_query(queryLunsInTierClass) }}" + failed_when: checkedVolumes|json_query(queryLunsInTierClass)|length > 0 + vars: + queryLunsInTierClass: "[? service_level_name != '' && service_level_name != null ].name" + + - set_fact: + drPgNames: [] + + - set_fact: + drPgNames: "{{ drPgNames + [ item[:-6] + '2_PG' + item[-2:] ] }}" + with_items: "{{ drTestLgNames }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_pgs.yml" + vars: + pgNames: "{{ drPgNames }}" + + - set_fact: + drPgIds: "{{ pgIds }}" + checkedPgSnapCgs: [] + + - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/get_snapshot_cgs_by_pg_loop_helper.yml" + vars: + pgId: "{{ drPgId }}" + ignoreEmpty: true + loop: "{{ drPgIds }}" + loop_control: + loop_var: drPgId + + - name: Check Snapshot CGs Number and Status + debug: + msg: + SnapshotCgs: "{{ item }}" + status: "{{ item[0].RUNNINGSTATUS }}" + failed_when: (item|length|int != 1) or (item|length|int == 1 and item[0].RUNNINGSTATUS|int != SNAPCG.unactivated.enum) + loop: "{{ checkedPgSnapCgs }}" + + - set_fact: + drTestCgNames: [] + + - set_fact: + drTestCgNames: "{{ drTestCgNames + [ item[0].NAME ] }}" + loop: "{{ checkedPgSnapCgs }}" + + - set_fact: + checkedPgRepCgs: [] + + - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/get_replication_cgs_by_pg_loop_helper.yml" + vars: + pgId: "{{ drPgId }}" + loop: "{{ drPgIds }}" + loop_control: + loop_var: drPgId + + - debug: + msg: + checkedPgRepCgs: "{{ checkedPgRepCgs }}" + drHostNames: "{{ drPgNames }}" + failed_when: item|length|int != 1 + loop: "{{ checkedPgRepCgs }}" + + - set_fact: + drCgNames: [] + + - set_fact: + drCgNames: "{{ drCgNames + [ item[0].NAME ] }}" + loop: "{{ checkedPgRepCgs }}" + + - debug: + msg: + drHostWwns: "{{ drHostWwns }}" + drCgNames: "{{ drCgNames }}" + drTestCgNames: "{{ drTestCgNames }}" + drTestHostNames: "{{ drTestHostNames }}" + drTestLunNames: "{{ drTestLunNames }}" + drTestLunClasses: "{{ drTestLunClasses }}" + failed_when: (drHostWwns|length == 0) or (drTestLunNames|length == 0) + + - block: + + # Begin Workflow Steps + + - set_fact: + # Activate DR Test Snapshot CGs + Step_1_1_Execute: True + Step_1_1_Completed: False + Step_1_1_Rollbacked: False + + # Set Class for DR Test LUNs + Step_1_2_Execute: True + Step_1_2_Completed: False + Step_1_2_Rollbacked: False + + # Remove WWNs from DR Hosts + Step_2_1_Execute: True + Step_2_1_Completed: False + Step_2_1_Rollbacked: False + + # Add WWNs to DR Test Hosts + Step_2_2_Execute: True + Step_2_2_Completed: False + Step_2_2_Rollbacked: False + + # Update DR Test LUNs to KPI table + Step_3_1_Execute: True + Step_3_1_Completed: False + + - name: Workflow - DR Test for Hosts + debug: + msg: + Step_1_1: "[{{Step_1_1_Execute}}] Activate DR Test Snapshot CGs" + Step_1_2: "[{{Step_1_2_Execute}}] Set Class for DR Test LUNs" + Step_2_1: "[{{Step_2_1_Execute}}] Remove WWNs from DR Hosts" + Step_2_2: "[{{Step_2_2_Execute}}] Add WWNs to DR Test Hosts" + Step_3_1: "[{{Step_3_1_Execute}}] Update DR Test LUNs to KPI table" + + - block: + - name: Step_1_1 - Activate DR Test Snapshot CGs + debug: + msg: + params: + cgNames: "{{ drCgNames }}" + cgTestNames: "{{ drTestCgNames }}" + device: "{{ deviceName }}" + + - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/activate_snapshot_cg.yml" + vars: + cgName: "{{ drTestCgName }}" + loop: "{{ drTestCgNames }}" + loop_control: + loop_var: drTestCgName + + - set_fact: + Step_1_1_Completed: True + + # End Step_1_1 + + # End block + when: Step_1_1_Execute + + - block: + - name: Step_1_2 - Set Class for DR Test LUNs + debug: + msg: + params: + volumeNames: "{{ drTestLunNames }}" + tierNames: "{{ drTestLunClasses }}" + + - include_tasks: "{{GLOBAL.baseDir}}/task/volume/add_volumes_to_tier.yml" + vars: + volumeNames: ["{{ drTestLun.0 }}"] + tierName: "{{ drTestLun.1 }}" + loop: "{{ drTestLunNames|zip(drTestLunClasses)|list }}" + loop_control: + loop_var: drTestLun + + - set_fact: + Step_1_2_Completed: True + + # End Step_1_2 + + # End block + when: Step_1_2_Execute + + - block: + - name: Step_2_1 - Remove WWNs from DR Hosts + debug: + msg: + params: + wwns: "{{ drHostWwns }}" + device: "{{ deviceName }}" + + - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/remove_ports_from_host.yml" + vars: + wwns: "{{ drHostWwnsItem.value }}" + hostName: "{{ drHostWwnsItem.key }}" + loop: "{{ lookup('dict', drHostWwns, wantlist=True) }}" + loop_control: + loop_var: drHostWwnsItem + + - set_fact: + Step_2_1_Completed: True + + # End Step_2_1 + + # End block + when: Step_2_1_Execute + + - block: + - name: Step_2_2 - Add WWNs to DR Test Hosts + debug: + msg: + params: + wwns: "{{ drTestHostWwns }}" + hostNames: "{{ drTestHostNames }}" + device: "{{ deviceName }}" + + - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/add_ports_to_host.yml" + vars: + wwns: "{{ drHostTestWwnsItem.value }}" + hostName: "{{ drHostTestWwnsItem.key }}" + loop: "{{ lookup('dict', drTestHostWwns, wantlist=True) }}" + loop_control: + loop_var: drHostTestWwnsItem + + - set_fact: + Step_2_2_Completed: True + + # End Step_2_2 + + # End block + when: Step_2_2_Execute + + - block: + - name: Step_3_1 - Update DR Test LUNs to KPI table + debug: + msg: + params: + lunIds: "{{ drTestLunIds }}" + classes: "{{ drTestLunClasses }}" + + # Minus Non-Class capacity + - include_tasks: update_lun_kpi_table.yml + vars: + TYPE_OF_OPERATION: "modify" + WBE_CODE: "{{ WBE_CODE }}" + TICKET_NUMBER: "{{ TICKET_NUMBER }}" + SYSTEM_NAME: "{{ '_'.join(drTestLunNames[item.0].split('_')[:4]) }}" + SITE: "{{ site }}" + ENVIRONMENT: "{{ osType }}" + STORAGE_CLASS: "" + CAPACITY_GB: "-{{ (drTestLunSectors[item.0]|int / 1024 / 1024 / 2)|int }}" + STORAGE: "{{ deviceName }}" + VDISK_UID: "{{ item.1 }}" + with_indexed_items: "{{ drTestLunIds }}" + + # Add capacity to Class + - include_tasks: update_lun_kpi_table.yml + vars: + TYPE_OF_OPERATION: "modify" + WBE_CODE: "{{ WBE_CODE }}" + TICKET_NUMBER: "{{ TICKET_NUMBER }}" + SYSTEM_NAME: "{{ '_'.join(drTestLunNames[item.0].split('_')[:4]) }}" + SITE: "{{ site }}" + ENVIRONMENT: "{{ osType }}" + STORAGE_CLASS: "{{ drTestLunClasses[item.0] }}" + CAPACITY_GB: "{{ (drTestLunSectors[item.0]|int / 1024 / 1024 / 2)|int }}" + STORAGE: "{{ deviceName }}" + VDISK_UID: "{{ item.1 }}" + with_indexed_items: "{{ drTestLunIds }}" + + - set_fact: + Step_3_1_Completed: True + + # End Step_3_1 + + # End block + when: Step_3_1_Execute + + # End Steps + rescue: + + - block: + - name: Rollback_2_2 - Remove WWNs from DR Test Hosts + debug: + msg: + params: + wwns: "{{ drTestHostWwns }}" + hostNames: "{{ drTestHostNames }}" + device: "{{ deviceName }}" + + - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/remove_ports_from_host.yml" + vars: + wwns: "{{ drTestHostWwnsItem.value }}" + hostName: "{{ drTestHostWwnsItem.key }}" + loop: "{{ lookup('dict', drTestHostWwns, wantlist=True) }}" + loop_control: + loop_var: drTestHostWwnsItem + + - set_fact: + Step_2_2_Rollbacked: True + + # End Rollback_2_2 + + # End block + when: Step_2_2_Completed + + - block: + - name: Rollback_2_1 - Add WWNs to DR Hosts + debug: + msg: + params: + wwns: "{{ drHostWwns }}" + hostNames: "{{ drHostNames }}" + device: "{{ deviceName }}" + + - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/add_ports_to_host.yml" + vars: + wwns: "{{ drHostWwnsItem.value }}" + hostName: "{{ drHostWwnsItem.key }}" + loop: "{{ lookup('dict', drHostWwns, wantlist=True) }}" + loop_control: + loop_var: drHostWwnsItem + + - set_fact: + Step_2_1_Rollbacked: True + + # End Rollback_2_1 + + # End block + when: Step_2_1_Completed + + - block: + - name: Rollback_1_2 - Remove Class for DR Test LUNs + debug: + msg: + params: + volumeNames: "{{ drTestLunNames }}" + tierNames: "{{ drTestLunClasses }}" + + - include_tasks: "{{GLOBAL.baseDir}}/task/volume/remove_volumes_from_tier.yml" + vars: + volumeNames: "{{ drTestLun.0 }}" + tierName: "{{ drTestLun.1 }}" + loop: "{{ drTestLunNames|zip(drTestLunClasses)|list }}" + loop_control: + loop_var: drTestLun + + - set_fact: + Step_1_2_Rollbacked: True + + # End Rollback_1_2 + + # End block + when: Step_1_2_Completed + + - block: + - name: Rollback_1_1 - Deactivate DR Test Snapshot CGs + debug: + msg: + params: + cgTestNames: "{{ drTestCgNames }}" + device: "{{ deviceName }}" + + - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/deactivate_snapshot_cg.yml" + vars: + cgName: "{{ drTestCgName }}" + loop: "{{ drTestCgNames }}" + loop_control: + loop_var: drTestCgName + + - set_fact: + Step_1_1_Rollbacked: True + + # End Rollback_1_1 + + # End block + when: Step_1_1_Completed + + # End Rollbacks + always: + + - name: Final_Step_1 - Sync DR Device + debug: + msg: + device: "{{ deviceName }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/sync_storage.yml" + + # End Final Steps + + # End Workflow + + + - block: + + # Begin Validate Results + + - name: Result_1_1 - Activate DR Test Snapshot CGs + debug: + msg: + params: + cgNames: "{{ drTestCgNames }}" + cgTestNames: "{{ drTestCgNames }}" + device: "{{ deviceName }}" + result: + succeeded: "{{ Step_1_1_Completed }}" + rollbacked: "{{ Step_1_1_Rollbacked }}" + failed_when: Step_1_1_Completed|bool == False + when: Step_1_1_Execute + + - name: Result_1_2 - Set Class for DR Test LUNs + debug: + msg: + params: + volumeNames: "{{ drTestLunNames }}" + tierName: "{{ drTestLunClasses }}" + result: + succeeded: "{{ Step_1_2_Completed }}" + rollbacked: "{{ Step_1_2_Rollbacked }}" + failed_when: Step_1_2_Completed|bool == False + when: Step_1_2_Execute + + - name: Result_2_1 - Remove WWNs from DR Host + debug: + msg: + params: + wwns: "{{ drHostWwns }}" + hostNames: "{{ drHostNames }}" + device: "{{ deviceName }}" + result: + succeeded: "{{ Step_2_1_Completed }}" + rollbacked: "{{ Step_2_1_Rollbacked }}" + failed_when: Step_2_1_Completed|bool == False + when: Step_2_1_Execute + + - name: Result_2_2 - Add WWNs to DR Test Hosts + debug: + msg: + params: + wwns: "{{ drTestHostWwns }}" + hostNames: "{{ drTestHostNames }}" + device: "{{ deviceName }}" + result: + succeeded: "{{ Step_2_2_Completed }}" + rollbacked: "{{ Step_2_2_Rollbacked }}" + failed_when: Step_2_2_Completed|bool == False + when: Step_2_2_Execute + + - name: Result_3_1 - Update DR Test LUNs to KPI table + debug: + msg: + params: + lunIds: "{{ drTestLunIds }}" + classes: "{{ drTestLunClasses }}" + result: + succeeded: "{{ Step_3_1_Completed }}" + failed_when: Step_3_1_Completed|bool == False + when: Step_3_1_Execute \ No newline at end of file diff --git a/rundeck/workflow/project001/58_dr_test_clean_for_multi_cluster.yml b/rundeck/workflow/project001/58_dr_test_clean_for_multi_cluster.yml new file mode 100644 index 0000000..336fa05 --- /dev/null +++ b/rundeck/workflow/project001/58_dr_test_clean_for_multi_cluster.yml @@ -0,0 +1,921 @@ +- name: DR Test Clean for Hosts + hosts: localhost + vars_files: + - ../../../config/global.yml + - ../../../config/project001.yml + gather_facts: no + become: no + tasks: + + # Check Params + - block: + - set_fact: + checked_params: + Select_DR_Test_Cluster: "{% set clusters = [] %}{% set Select_DR_Test_Cluster = Select_DR_Test_Cluster|string %}{% for cluster in Select_DR_Test_Cluster.split(',') if cluster.endswith('_3') %}{{ clusters.append(cluster) }}{% endfor %}{{ (clusters | length >= 1) and (clusters | length == Select_DR_Test_Cluster.split(',') | length) }}" + DR_Storage: "{{ (DR_Storage is not none and DR_Storage != DEFAULT.noneValue) and (DR_Storage|string|length == 20) }}" + Check_Result_1: "{{ ('cluster' in Check_Result_1) }}" + + - name: Precheck_0_1 - Check Params + debug: + msg: "{{checked_params}}" + failed_when: checked_params.values()|unique != [True] + + - set_fact: + WBE_CODE: "{{ WBE_CODE }}" + TICKET_NUMBER: "{{ TICKET_NUMBER }}" + osType: "{{ OS_Type }}" + deviceSn: "{{ DR_Storage|string }}" + room: "{{ DR_Storage_Room }}" + site: "{{ AZ[DR_Storage_Room]['dc'] }}" + drTestClusterNames: "{{ (Select_DR_Test_Cluster|string).split(',') }}" + drClusterNames: [] + + - set_fact: + drClusterNames: "{{ drClusterNames + [ item[:-1] + '2' ] }}" + with_items: "{{ drTestClusterNames }}" + + - set_fact: + protectType: "{{ REPTYPE['N3']['enum'] }}" # N3 is same as Y3 enum, use one of them to stand all cases, See ../../config/project001.yml + + - set_fact: + lunNameTemplate: "%s_{{protectType}}N%0{{DEFAULT.suffixDigits}}d" + + - import_tasks: "{{GLOBAL.baseDir}}/task/user/login.yml" + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/login_storage.yml" + + - name: Precheck_1 - Check Clusters, WWNs, Replication CG & Snapshots + debug: + msg: + drClusterNames: "{{drClusterNames}}" + drTestClusterNames: "{{drTestClusterNames}}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_hostgroups.yml" + vars: + hostGroupNames: "{{ drClusterNames }}" + - set_fact: + drClusterIds: "{{ hostGroupIds }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_hostgroups.yml" + vars: + hostGroupNames: "{{ drTestClusterNames }}" + - set_fact: + drTestClusterIds: "{{ hostGroupIds }}" + + - name: Get DR Hosts + uri: + url: "https://{{deviceHost}}:{{devicePort}}/deviceManager/rest/{{deviceSn}}/host/associate?ASSOCIATEOBJTYPE=14&ASSOCIATEOBJID={{item}}" + method: GET + validate_certs: no + headers: + Accept: "application/json" + Content-Type: "application/json;charset=utf8" + iBaseToken: "{{ deviceToken }}" + Cookie: "session={{ deviceSession }}" + register: DR_HOSTS + failed_when: (DR_HOSTS.json.error.code|int != 0) or ('data' not in DR_HOSTS.json) or (DR_HOSTS.json.data|length == 0) + with_items: "{{ drClusterIds }}" + + - set_fact: + drHostNames: "{{ DR_HOSTS.results | json_query('[*].json.data[*].NAME') | flatten(levels=1) }}" + drHostIds: "{{ DR_HOSTS.results | json_query('[*].json.data[*].ID') | flatten(levels=1) }}" + drHostWwns: {} + + - name: Get DR Test Hosts + uri: + url: "https://{{deviceHost}}:{{devicePort}}/deviceManager/rest/{{deviceSn}}/host/associate?ASSOCIATEOBJTYPE=14&ASSOCIATEOBJID={{item}}" + method: GET + validate_certs: no + headers: + Accept: "application/json" + Content-Type: "application/json;charset=utf8" + iBaseToken: "{{ deviceToken }}" + Cookie: "session={{ deviceSession }}" + register: DR_TEST_HOSTS + failed_when: (DR_TEST_HOSTS.json.error.code|int != 0) or ('data' not in DR_TEST_HOSTS.json) or (DR_TEST_HOSTS.json.data|length == 0) + with_items: "{{ drTestClusterIds }}" + + - set_fact: + drTestHostNames: "{{ DR_TEST_HOSTS.results | json_query('[*].json.data[*].NAME') | flatten(levels=1) }}" + drTestHostIds: "{{ DR_TEST_HOSTS.results | json_query('[*].json.data[*].ID') | flatten(levels=1) }}" + drTestHostWwns: {} + + - debug: + msg: + drHostNames: "{{ drHostNames }}" + drHostIds: "{{ drHostIds }}" + drTestHostNames: "{{ drTestHostNames }}" + drTestHostIds: "{{ drTestHostIds }}" + failed_when: drHostNames|length != drTestHostNames|length or drHostNames == 0 + + # check wwns + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_host_wwns.yml" + vars: + hostNames: "{{ drHostNames }}" + checkExist: False + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_host_wwns.yml" + vars: + hostNames: "{{ drTestHostNames }}" + + - set_fact: + drTestHostWwns: "{{ checkedWwns }}" + drHostWwns: {} + + - set_fact: + drHostWwns: "{{ drHostWwns | combine( { item.0: drTestHostWwns[item.1] } ) }}" + with_together: + - "{{ drHostNames }}" + - "{{ drTestHostNames }}" + + # check host lun + - set_fact: + checkedHostLuns: [] + + - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_host_lun_id_loop_helper.yml" + vars: + hostName: "{{ drHostName }}" + loop: "{{ drHostNames }}" + loop_control: + loop_var: drHostName + + - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_host_lun_id_loop_helper.yml" + vars: + hostGroupName: "{{ drClusterName }}" + loop: "{{ drClusterNames }}" + loop_control: + loop_var: drClusterName + + - set_fact: + checkedDrHostLuns: {} + + - set_fact: + checkedDrHostLuns: "{{ checkedDrHostLuns | combine({item.key:item.value}) }}" + with_dict: "{{ checkedHostLuns }}" + when: + - item.value|length > 0 + + - name: Check Host Luns Number in LGs + debug: + msg: + drTestLun: "{{ checkedDrHostLuns }}" + failed_when: checkedDrHostLuns|length == 0 + + - set_fact: + drLgNames: "{{ checkedDrHostLuns.keys() }}" + drTestLgNames: [] + drPgNames: [] + + - set_fact: + drPgNames: "{{ drPgNames + [ item[:-6] + '2_PG' + item[-2:] ] }}" + drTestLgNames: "{{ drTestLgNames + [ item[:-6] + '3_LG' + item[-2:] ] }}" + with_items: "{{ drLgNames }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_pgs.yml" + vars: + pgNames: "{{ drPgNames }}" + + - set_fact: + drPgIds: "{{ pgIds }}" + checkedPgSnapCgs: [] + + - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/get_snapshot_cgs_by_pg_loop_helper.yml" + vars: + pgId: "{{ drPgId }}" + ignoreEmpty: true + loop: "{{ drPgIds }}" + loop_control: + loop_var: drPgId + + - name: Check Snapshot CGs Number and Status + debug: + msg: + SnapshotCgs: "{{ item }}" + status: "{{ item[0].RUNNINGSTATUS }}" + failed_when: (item|length|int != 1) or (item|length|int == 1 and item[0].RUNNINGSTATUS|int != SNAPCG.activated.enum) + loop: "{{ checkedPgSnapCgs }}" + + - set_fact: + drTestCgNames: [] + drTestCgIds: [] + + - set_fact: + drTestCgNames: "{{ drTestCgNames + [ item[0].NAME ] }}" + drTestCgIds: "{{ drTestCgIds + [ item[0].ID ] }}" + loop: "{{ checkedPgSnapCgs }}" + + - set_fact: + checkedPgRepCgs: [] + + - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/get_replication_cgs_by_pg_loop_helper.yml" + vars: + pgId: "{{ drPgId }}" + loop: "{{ drPgIds }}" + loop_control: + loop_var: drPgId + + - debug: + msg: + checkedPgRepCgs: "{{ checkedPgRepCgs }}" + drHostNames: "{{ drPgNames }}" + failed_when: item|length|int != 1 + loop: "{{ checkedPgRepCgs }}" + + - set_fact: + drCgNames: [] + + - set_fact: + drCgNames: "{{ drCgNames + [ item[0].NAME ] }}" + loop: "{{ checkedPgRepCgs }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_lgs.yml" + vars: + lgNames: "{{ drLgNames }}" + + - set_fact: + targetLunsAll: [] + targetLunNamesAll: [] + + - debug: + msg: + drLgNames: "{{ drLgNames }}" + drPgNames: "{{ drPgNames }}" + drTestCgNames: "{{ drTestCgNames }}" + drTestLgNames: "{{ drTestLgNames }}" + drTestHostNames: "{{ drTestHostNames }}" + + - include_tasks: "{{GLOBAL.baseDir}}/rundeck/workflow/project001/loop_helper/56_target_luns_loop_helper.yml" + vars: + luns: "{{ checkedLuns[drLgName] }}" + hostLuns: "{{ checkedDrHostLuns[drLgName] }}" + pgName: "{{ drPgNames[index] }}" + cgName: "{{ drTestCgNames[index] }}" + lgName: "{{ drTestLgNames[index] }}" + hostName: "{{ drTestHostNames[index] }}" + className: "{{ checkedLgs[index].DESCRIPTION[4:5] }}" + loop: "{{ drLgNames }}" + loop_control: + index_var: index + loop_var: drLgName + + - debug: + msg: + targetLunsAll: "{{ targetLunsAll }}" + + - set_fact: + targetLunNamesAll: "{{ targetLunNamesAll + item.lunNames }}" + loop: "{{ targetLunsAll }}" + + - set_fact: + existDrLunNamesAll: [] + + - set_fact: + existDrLunNamesAll: "{{ existDrLunNames + [checkedLuns[item] | json_query('[*].NAME')] }}" + loop: "{{ drLgNames }}" + + - name: Query Snapshots in CG + uri: + url: "https://{{deviceHost}}:{{devicePort}}/deviceManager/rest/{{deviceSn}}/snapshot/associate?ASSOCIATEOBJTYPE=57646&ASSOCIATEOBJID={{item}}" + method: GET + validate_certs: no + headers: + Accept: "application/json" + Content-Type: "application/json;charset=utf8" + iBaseToken: "{{ deviceToken }}" + Cookie: "session={{ deviceSession }}" + register: SNAPSHOTS + with_items: "{{ drTestCgIds }}" + + - set_fact: + sourceDrLunNames: [] + + - name: Get AZ IDs + set_fact: + sourceDrLunNames: "{{ sourceDrLunNames + SNAPSHOTS.json.data | default([]) | json_query('[*].SOURCELUNNAME') }}" + with_indexed_items: "{{ drTestCgIds }}" + + - set_fact: + orphanDrLunNames: "{{ sourceDrLunNames | difference(existDrLunNamesAll) }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_luns.yml" + vars: + lunNames: "{{ orphanDrLunNames }}" + when: orphanDrLunNames|length > 0 + + - set_fact: + orphanDrLunIds: "{{ checkedLuns | json_query('[*].ID') }}" + orphanDrLunSectors: "{{ checkedLuns | json_query('[*].CAPACITY') }}" + when: orphanDrLunNames|length > 0 + + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_lgs.yml" + vars: + lgNames: "{{ drTestLgNames }}" + + - set_fact: + checkedDrLgLuns: "{{ checkedLuns }}" + drTestLunNames: [] + drTestLunIds: [] + drTestLunSectors: [] + + - set_fact: + drTestLunNames: "{{ drTestLunNames + item.value | json_query('[*].NAME') }}" + drTestLunIds: "{{ drTestLunIds + item.value | json_query('[*].ID') }}" + drTestLunSectors: "{{ drTestLunSectors + item.value | json_query('[*].CAPACITY') }}" + with_dict: "{{ checkedLuns }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/volume/check_volumes.yml" + vars: + volumeNames: "{{ drTestLunNames }}" + + - set_fact: + drTestLunClass: [] + drTestLunsInTier: {} + tierNames: "{{ checkedVolumes | json_query('[*].service_level_name') | unique }}" + + - set_fact: + drTestLunClass: "{{ drTestLunClass + [ checkedVolumes[item.0].service_level_name ] }}" + with_indexed_items: "{{ drTestLunNames }}" + + - set_fact: + drTestLunsInTier: "{{ drTestLunsInTier | combine( { item: checkedVolumes | json_query(queryVolumesInTier) } ) }}" + vars: + queryVolumesInTier: "[? service_level_name == '{{ item }}' ].id" + with_items: "{{ tierNames }}" + + - debug: + msg: + drHostWwns: "{{ drHostWwns }}" + drCgNames: "{{ drCgNames }}" + drTestLunNames: "{{ drTestLunNames }}" + drTestCgNames: "{{ drTestCgNames }}" + targetLunsAll: "{{ targetLunsAll }}" + failed_when: drHostWwns|length == 0 or drTestLunNames|length == 0 + + - block: + + # Begin Workflow Steps + + - set_fact: + + # Remove WWNs from DR Test Hosts + Step_1_1_Execute: True + Step_1_1_Completed: False + Step_1_1_Rollbacked: False + + # Add WWNs to DR Hosts + Step_1_2_Execute: True + Step_1_2_Completed: False + Step_1_2_Rollbacked: False + + # Remove DR Test LUNs from Class + Step_2_1_Execute: True + Step_2_1_Completed: False + Step_2_1_Rollbacked: False + + # Remove DR Test LUNs from LUN Group + Step_2_2_Execute: True + Step_2_2_Completed: False + Step_2_2_Rollbacked: False + + # Delete DR Test Snapshot CGs + Step_2_3_Execute: True + Step_2_3_Completed: False + Step_2_3_Rollbacked: False + + # Re-Create DR Test Snapshot CGs + Step_2_4_Execute: "{{ targetLunNames|length > 0 }}" + Step_2_4_Completed: False + Step_2_4_Rollbacked: False + + # Add DR Test LUNs to LUN Group + Step_2_5_Execute: "{{ targetLunNames|length > 0 }}" + Step_2_5_Completed: False + Step_2_5_Rollbacked: False + + # Delete Orphan DR LUNs + Step_2_6_Execute: "{{ orphanDrLunNames|length > 0 }}" + Step_2_6_Completed: False + Step_2_6_Rollbacked: False + + # Update DR Test LUNs to KPI table + Step_3_1_Execute: True + Step_3_1_Completed: False + Step_3_1_Rollbacked: False + + # Update Orphan DR LUNs to KPI table + Step_3_2_Execute: "{{ orphanDrLunNames|length > 0 }}" + Step_3_2_Completed: False + Step_3_2_Rollbacked: False + + - name: Workflow - DR Test Clean for Multi-Host + debug: + msg: + Step_1_1: "[{{Step_1_1_Execute}}] Remove WWNs from DR Test Hosts" + Step_1_2: "[{{Step_1_2_Execute}}] Add WWNs to DR Hosts" + Step_2_1: "[{{Step_2_1_Execute}}] Remove DR Test LUNs from Class" + Step_2_2: "[{{Step_2_2_Execute}}] Remove DR Test LUNs from LUN Group" + Step_2_3: "[{{Step_2_3_Execute}}] Delete DR Test Snapshot CGs" + Step_2_4: "[{{Step_2_4_Execute}}] Re-Create DR Test Snapshot CGs" + Step_2_5: "[{{Step_2_5_Execute}}] Add DR Test LUNs to LUN Group" + Step_2_6: "[{{Step_2_6_Execute}}] Delete Orphan DR LUNs" + Step_3_1: "[{{Step_3_1_Execute}}] Update DR Test LUNs to KPI table" + Step_3_2: "[{{Step_3_2_Execute}}] Update Orphan DR LUNs to KPI table" + + - block: + - name: Step_1_1 - Remove WWNs from DR Test Hosts + debug: + msg: + params: + wwns: "{{ drTestHostWwns }}" + device: "{{ deviceName }}" + + - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/remove_ports_from_host.yml" + vars: + wwns: "{{ drTestHostWwnsItem.value }}" + hostName: "{{ drTestHostWwnsItem.key }}" + loop: "{{ lookup('dict', drTestHostWwns, wantlist=True) }}" + loop_control: + loop_var: drTestHostWwnsItem + + - set_fact: + Step_1_1_Completed: True + + # End Step_1_1 + + # End block + when: Step_1_1_Execute + + - block: + - name: Step_1_2 - Add WWNs to DR Hosts + debug: + msg: + params: + wwns: "{{ drHostWwns }}" + device: "{{ deviceName }}" + + - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/add_ports_to_host.yml" + vars: + wwns: "{{ drHostWwnsItem.value }}" + hostName: "{{ drHostWwnsItem.key }}" + loop: "{{ lookup('dict', drHostWwns, wantlist=True) }}" + loop_control: + loop_var: drHostWwnsItem + + - set_fact: + Step_1_2_Completed: True + + # End Step_1_2 + + # End block + when: Step_1_2_Execute + + - block: + - name: Step_2_1 - Remove DR Test LUNs from Class + debug: + msg: + params: + drTestLunsInTier: "{{ drTestLunsInTier }}" + + - include_tasks: "{{GLOBAL.baseDir}}/task/volume/remove_volumes_from_tier.yml" + vars: + volumeIds: "{{ drTestLunsInTierItem.value }}" + loop: "{{ lookup('dict', drTestLunsInTier, wantlist=True) }}" + loop_control: + loop_var: drTestLunsInTierItem + + - set_fact: + Step_2_1_Completed: True + + # End Step_2_1 + + # End block + when: Step_2_1_Execute + + - block: + - name: Step_2_2 - Remove DR Test LUNs from LUN Group + debug: + msg: + params: + lunNames: "{{ drTestLunNames }}" + lgName: "{{ drTestLgNames }}" + device: "{{ deviceName }}" + + - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/remove_luns_from_lg.yml" + vars: + lgName: "{{ checkedDrLgLunsItem.key }}" + lunNames: "{{ checkedDrLgLunsItem.value | json_query('[*].NAME') }}" + loop: "{{ lookup('dict', checkedDrLgLuns, wantlist=True) }}" + loop_control: + loop_var: checkedDrLgLunsItem + + - set_fact: + Step_2_2_Completed: True + + # End Step_2_2 + + # End block + when: Step_2_2_Execute + + - block: + - name: Step_2_3 - Delete DR Test Snapshot CGs + debug: + msg: + params: + cgNames: "{{ drTestCgNames }}" + device: "{{ deviceName }}" + + - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/delete_snapshot_cg.yml" + vars: + cgName: "{{ drTestCgName }}" + loop: "{{ drTestCgNames }}" + loop_control: + loop_var: drTestCgName + + - set_fact: + Step_2_3_Completed: True + + # End Step_2_3 + + # End block + when: Step_2_3_Execute + + - block: + - name: Step_2_4 - Re-Create DR Test Snapshot CGs + debug: + msg: + params: + cgNames: "{{ drTestCgNames }}" + device: "{{ deviceName }}" + + - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/create_snapshot_cg.yml" + vars: + pgName: "{{ targetLuns.pgName }}" + cgName: "{{ targetLuns.cgName }}" + snapNames: "{{ targetLuns.lunNames }}" + activate: False + snapDescs: "{{ targetLuns.lunDescs }}" + loop: "{{ targetLunsAll }}" + loop_control: + loop_var: targetLuns + + - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_luns.yml" + vars: + lunNames: "{{ targetLunNamesAll }}" + + - set_fact: + targetLunIdsAll: "{{ checkedLuns | json_query('[*].ID') }}" + targetLunSectorsAll: "{{ checkedLuns | json_query('[*].CAPACITY') }}" + + - set_fact: + Step_2_4_Completed: True + + # End Step_2_4 + + # End block + when: Step_2_4_Execute + + - block: + - name: Step_2_5 - Add DR Test LUNs to LUN Group + debug: + msg: + params: + luns: "{{ targetLunsAll }}" + device: "{{ deviceName }}" + + - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/add_luns_to_lg.yml" + vars: + lunNames: "{{ targetLuns.lunNames }}" + lgName: "{{ targetLuns.lgName }}" + addLunScsiIds: "{{ targetLuns.lunScsiIds }}" + loop: "{{ targetLunsAll }}" + loop_control: + loop_var: targetLuns + + - set_fact: + Step_2_5_Completed: True + + # End Step_2_5 + + # End block + when: Step_2_5_Execute + + - block: + - name: Step_2_6 - Delete Orphan DR LUNs + debug: + msg: + params: + lunNames: "{{ orphanDrLunNames }}" + device: "{{ deviceName }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/delete_luns.yml" + vars: + lunNames: "{{ orphanDrLunNames }}" + + - set_fact: + Step_2_6_Completed: True + + # End Step_2_6 + + # End block + when: Step_2_6_Execute + + - block: + - name: Step_3_1 - Update DR Test LUNs to KPI table + debug: + msg: + params: + lunIds: "{{ drTestLunIds }}" + lunNames: "{{ drTestLunNames }}" + + - include_tasks: update_lun_kpi_table.yml + vars: + TYPE_OF_OPERATION: "delete" + WBE_CODE: "{{ WBE_CODE }}" + TICKET_NUMBER: "{{ TICKET_NUMBER }}" + SYSTEM_NAME: "{{ '_'.join(drTestLunNames[index].split('_')[:4]) }}" + SITE: "{{ site }}" + ENVIRONMENT: "{{ osType }}" + STORAGE_CLASS: "{{ drTestLunClass[index] }}" + CAPACITY_GB: "-{{ (drTestLunSectors[index]|int / 1024 / 1024 / 2)|int }}" + STORAGE: "{{ deviceName }}" + VDISK_UID: "{{ lunId }}" + loop: "{{ drTestLunIds }}" + loop_control: + index_var: index + loop_var: lunId + + - include_tasks: update_lun_kpi_table.yml + vars: + TYPE_OF_OPERATION: "create" + WBE_CODE: "{{ WBE_CODE }}" + TICKET_NUMBER: "{{ TICKET_NUMBER }}" + SYSTEM_NAME: "{{ '_'.join(targetLunNamesAll[index].split('_')[:4]) }}" + SITE: "{{ site }}" + ENVIRONMENT: "{{ osType }}" + STORAGE_CLASS: "" + CAPACITY_GB: "{{ (targetLunSectorsAll[index]|int / 1024 / 1024 / 2)|int }}" + STORAGE: "{{ deviceName }}" + VDISK_UID: "{{ lunId }}" + loop: "{{ targetLunIdsAll }}" + loop_control: + index_var: index + loop_var: lunId + when: targetLunIdsAll|default([])|length > 0 + + - set_fact: + Step_3_1_Completed: True + + # End Step_3_1 + + # End block + when: Step_3_1_Execute + + - block: + - name: Step_3_2 - Update Orphan DR LUNs to KPI table + debug: + msg: + params: + lunIds: "{{ orphanDrLunIds }}" + + - include_tasks: update_lun_kpi_table.yml + vars: + TYPE_OF_OPERATION: "delete" + WBE_CODE: "{{ WBE_CODE }}" + TICKET_NUMBER: "{{ TICKET_NUMBER }}" + SYSTEM_NAME: "{{ '_'.join(orphanDrLunNames[index].split('_')[:4]) }}" + SITE: "{{ site }}" + ENVIRONMENT: "{{ osType }}" + STORAGE_CLASS: "" + CAPACITY_GB: "-{{ (orphanDrLunSectors[index]|int / 1024 / 1024 / 2)|int }}" + STORAGE: "{{ deviceName }}" + VDISK_UID: "{{ lunId }}" + with_indexed_items: "{{ orphanDrLunIds }}" + loop: "{{ orphanDrLunIds }}" + loop_control: + index_var: index + loop_var: lunId + + - set_fact: + Step_3_2_Completed: True + + # End Step_3_2 + + # End block + when: Step_3_2_Execute + + # End Steps + rescue: + + # Unable to rollback DR Test CGs, need to manually rollback + + - block: + - name: Rollback_2_4 - Reactivated DR Test Snapshot CG + debug: + msg: + params: + cgNames: "{{ drTestCgNames }}" + device: "{{ deviceName }}" + + - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/activate_snapshot_cg.yml" + vars: + cgName: "{{ drTestCgName }}" + loop: "{{ drTestCgNames }}" + loop_control: + loop_var: drTestCgName + + - set_fact: + Step_2_3_Rollbacked: True + Step_2_4_Rollbacked: True + + # End Rollback_2_4 + + # End block + when: Step_2_4_Completed + + - block: + - name: Rollback_1_2 - Remove WWNs from DR Hosts + debug: + msg: + params: + wwns: "{{ drHostWwns }}" + hostNames: "{{ drHostNames }}" + device: "{{ deviceName }}" + + - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/remove_ports_from_host.yml" + vars: + wwns: "{{ drHostWwnsItem.value }}" + hostName: "{{ drHostWwnsItem.key }}" + loop: "{{ lookup('dict', drHostWwns, wantlist=True) }}" + loop_control: + loop_var: drHostWwnsItem + + - set_fact: + Step_1_2_Rollbacked: True + + # End Rollback_1_2 + + # End block + when: Step_1_2_Completed + + - block: + - name: Rollback_1_1 - Add WWNs to DR Test Hosts + debug: + msg: + params: + wwns: "{{ drTestHostWwns }}" + hostNames: "{{ drTestHostNames }}" + device: "{{ deviceName }}" + + - include_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/add_ports_to_host.yml" + vars: + wwns: "{{ drTestHostWwnsItem.value }}" + hostName: "{{ drTestHostWwnsItem.key }}" + loop: "{{ lookup('dict', drTestHostWwns, wantlist=True) }}" + loop_control: + loop_var: drTestHostWwnsItem + + - set_fact: + Step_1_1_Rollbacked: True + + # End Rollback_1_1 + + # End block + when: Step_1_1_Completed + + # End Rollbacks + always: + + - name: Final_Step_1 - Sync DR Device + debug: + msg: + device: "{{ deviceName }}" + + - import_tasks: "{{GLOBAL.baseDir}}/task/storage/sync_storage.yml" + + # End Final Steps + + # End Workflow + + + - block: + + # Begin Validate Results + + - name: Result_1_1 - Remove WWNs from DR Test Hosts + debug: + msg: + params: + wwns: "{{ drHostWwns }}" + hostNames: "{{ drTestHostNames }}" + device: "{{ deviceName }}" + result: + succeeded: "{{ Step_1_1_Completed }}" + rollbacked: "{{ Step_1_1_Rollbacked }}" + failed_when: Step_1_1_Completed|bool == False + when: Step_1_1_Execute + + - name: Result_1_2 - Add WWNs to DR Hosts + debug: + msg: + params: + wwns: "{{ drHostWwns }}" + hostNames: "{{ drHostNames }}" + device: "{{ deviceName }}" + result: + succeeded: "{{ Step_1_2_Completed }}" + rollbacked: "{{ Step_1_2_Rollbacked }}" + failed_when: Step_1_2_Completed|bool == False + when: Step_1_2_Execute + + - name: Result_2_1 - Remove DR Test LUNs from Class + debug: + msg: + params: + drTestLunsInTier: "{{ drTestLunsInTier }}" + result: + succeeded: "{{ Step_2_1_Completed }}" + rollbacked: "{{ Step_2_1_Rollbacked }}" + failed_when: Step_2_1_Completed|bool == False + when: Step_2_1_Execute + + - name: Result_2_2 - Remove DR Test LUNs from LUN Group + debug: + msg: + params: + lunNames: "{{ drTestLunNames }}" + lgNames: "{{ drTestLgNames }}" + device: "{{ deviceName }}" + result: + succeeded: "{{ Step_2_2_Completed }}" + rollbacked: "{{ Step_2_2_Rollbacked }}" + failed_when: Step_2_2_Completed|bool == False + when: Step_2_2_Execute + + - name: Result_2_3 - Delete DR Test Snapshot CG + debug: + msg: + params: + cgNames: "{{ drTestCgNames }}" + device: "{{ deviceName }}" + result: + succeeded: "{{ Step_2_3_Completed }}" + rollbacked: "{{ Step_2_3_Rollbacked }}" + failed_when: Step_2_3_Completed|bool == False + when: Step_2_3_Execute + + - name: Result_2_4 - Re-Create DR Test Snapshots + debug: + msg: + params: + cgNames: "{{ drTestCgNames }}" + device: "{{ deviceName }}" + result: + succeeded: "{{ Step_2_4_Completed }}" + rollbacked: "{{ Step_2_4_Rollbacked }}" + failed_when: Step_2_4_Completed|bool == False + when: Step_2_4_Execute + + - name: Result_2_5 - Add DR Test LUNs to LUN Group + debug: + msg: + params: + luns: "{{ targetLunsAll }}" + device: "{{ deviceName }}" + result: + succeeded: "{{ Step_2_5_Completed }}" + rollbacked: "{{ Step_2_5_Rollbacked }}" + failed_when: Step_2_5_Completed|bool == False + when: Step_2_5_Execute + + - name: Result_2_6 - Delete Orphan DR LUNs + debug: + msg: + params: + lunNames: "{{ orphanDrLunNames }}" + device: "{{ deviceName }}" + result: + succeeded: "{{ Step_2_6_Completed }}" + rollbacked: "{{ Step_2_6_Rollbacked }}" + failed_when: Step_2_6_Completed|bool == False + when: Step_2_6_Execute + + - name: Result_3_1 - Update DR Test LUNs to KPI table + debug: + msg: + params: + lunIds: "{{ drTestLunIds }}" + result: + succeeded: "{{ Step_3_1_Completed }}" + failed_when: Step_3_1_Completed|bool == False + when: Step_3_1_Execute + + - name: Result_3_2 - Update Orphan DR LUNs to KPI table + debug: + msg: + params: + lunIds: "{{ orphanDrLunIds }}" + result: + succeeded: "{{ Step_3_2_Completed }}" + failed_when: Step_3_2_Completed|bool == False + when: Step_3_2_Execute + diff --git a/rundeck/workflow/project001/loop_helper/50_exsit_dr_test_luns_loop_helper.yml b/rundeck/workflow/project001/loop_helper/50_exsit_dr_test_luns_loop_helper.yml new file mode 100644 index 0000000..6ecffe6 --- /dev/null +++ b/rundeck/workflow/project001/loop_helper/50_exsit_dr_test_luns_loop_helper.yml @@ -0,0 +1,34 @@ +# Build dr test lun parameter, cooperator with nested loop +# +# Required parameters: +# drTestLun: # Lun Info +# checkedHostLuns: # Host Lun info +# +# Generated variables: +# existDrTestLuns: # Exist Dr Test Lun Parameter Info, need clean before used. +- set_fact: + filteredHostLun: "{{ item.value | json_query(queryLun) | first }}" + filteredLgName: "{{ item.key }}" + vars: + queryLun: "[? lunName == '{{drTestLun.NAME}}']" + with_dict: "{{ checkedHostLuns }}" + when: + - item.value|length > 0 + - item.value|json_query(queryLun)|length > 0 + +- name: Check Filtered Host Lun + debug: + msg: "{{checkedHostLuns}}" + failed_when: filteredHostLun|default(none) is none + +- set_fact: + existDrTestLun: + lunName: "{{ drTestLun.NAME }}" + lunDesc: "{{ drTestLun.DESCRIPTION }}" + lunScsiId: "{{ filteredHostLun.hostLunId }}" + lunSector: "{{ drTestLun.USERCAPACITY }}" + lgName: "{{ filteredLgName }}" + +- set_fact: + existDrTestLuns: "{{ existDrTestLuns + [existDrTestLun] }}" + diff --git a/rundeck/workflow/project001/loop_helper/56_target_luns_loop_helper.yml b/rundeck/workflow/project001/loop_helper/56_target_luns_loop_helper.yml new file mode 100644 index 0000000..159329e --- /dev/null +++ b/rundeck/workflow/project001/loop_helper/56_target_luns_loop_helper.yml @@ -0,0 +1,40 @@ +# Build dr test lun parameter classified by lun group, cooperator with nested loop +# +# Required parameters: +# luns: # Lun Info +# hostLuns: # Host Lun Info +# pgName: # Protection Group Name +# cgName: # Snapshot Consistence Group Name +# lgName: # Lun Group Name +# className: # Service Level Name +# +# Generated variables: +# targetLunsAll: # Target Dr Test Lun Parameter Info, need clean before used. + +- set_fact: + existDrLunNames: "{{ luns | json_query('[*].NAME') }}" + lunScsiIds: "{{ hostLuns | json_query('[*].hostLunId') }}" + targetLunNames: [] + targetLunDescs: "{{ luns | json_query('[*].DESCRIPTION') }}" + +- set_fact: + targetLunNames: "{{ targetLunNames + [ targetLunName ] }}" + vars: + targetLunName: "{% set field = item.split('_') %}{% set output = field[:3] + ['3', field[4], className, '00', '00'] + field[8:-1] + [ field[-1][0] + '3' ] %}{{'_'.join(output)}}" + with_items: + - "{{ existDrLunNames }}" + +- set_fact: + targetLuns: + lunNames: "{{ targetLunNames }}" + lunDescs: "{{ targetLunDescs }}" + lunScsiIds: "{{ lunScsiIds }}" + pgName: "{{ pgName }}" + cgName: "{{ cgName }}" + hostName: "{{ hostName }}" + lgName: "{{ lgName }}" + +- set_fact: + targetLunsAll: "{{ targetLunsAll + [targetLuns] }}" + + diff --git a/rundeck/workflow/project001/update_lun_kpi_table.yml b/rundeck/workflow/project001/update_lun_kpi_table.yml index 42d358a..4918c36 100644 --- a/rundeck/workflow/project001/update_lun_kpi_table.yml +++ b/rundeck/workflow/project001/update_lun_kpi_table.yml @@ -11,8 +11,17 @@ # (e.g. in case of expansion the value is the delta between the current size and the expanded size) # STORAGE: the name of the storage in which the Volume is created/modified/deleted # VDISK_UID: the Universal Unique ID (UUID) of the Volume created/modified/deleted +# Country the country code +# Job_User the user name -- local_action: command psql automation -c "insert into activity(TYPE_OF_OPERATION,WBE_CODE,TICKET_NUMBER,SYSTEM_NAME,SITE,ENVIRONMENT,STORAGE_CLASS,CAPACITY_GB,STORAGE,VDISK_UID) values('{{TYPE_OF_OPERATION}}','{{WBE_CODE}}','{{TICKET_NUMBER}}','{{SYSTEM_NAME}}','{{SITE}}','{{ENVIRONMENT}}','{{STORAGE_CLASS}}','{{CAPACITY_GB}}','{{STORAGE}}','{{VDISK_UID}}')" +- local_action: command psql automation -c "insert into activity(TYPE_OF_OPERATION,WBE_CODE,TICKET_NUMBER,SYSTEM_NAME,SITE,ENVIRONMENT,STORAGE_CLASS,CAPACITY_GB,STORAGE,VDISK_UID,COUNTRY,\"USER\") values('{{TYPE_OF_OPERATION}}','{{WBE_CODE}}','{{TICKET_NUMBER}}','{{SYSTEM_NAME}}','{{SITE}}','{{ENVIRONMENT}}','{{STORAGE_CLASS}}','{{CAPACITY_GB}}','{{STORAGE}}','{{VDISK_UID}}','{{Country|default("")}}','{{Job_User}}')" -- local_action: command /opt/mssql-tools/bin/sqlcmd -S "{{KPIDB.host}}" -U "{{KPIDB.user}}" -P "{{KPIDB.pswd}}" -d "{{KPIDB.database}}" -Q "insert into {{KPIDB.table}}(TYPE_OF_OPERATION,WBE_CODE,TICKET_NUMBER,SYSTEM_NAME,SITE,ENVIRONMENT,STORAGE_CLASS,CAPACITY_GB,STORAGE,VDISK_UID) values('{{TYPE_OF_OPERATION}}','{{WBE_CODE}}','{{TICKET_NUMBER}}','{{SYSTEM_NAME}}','{{SITE}}','{{ENVIRONMENT}}','{{STORAGE_CLASS}}','{{CAPACITY_GB}}','{{STORAGE}}','{{VDISK_UID}}')" - when: KPIDB.enable|bool == True \ No newline at end of file +- block: + - local_action: command psql -qAt -d automation -c "select max(GSA_ID) AS NEXTID from activity" + register: KPI_NEXTID + + - local_action: command date +"%Y-%m-%d %H:%M:%S" + register: KPI_TIMESTAMP + + - local_action: command /opt/mssql-tools/bin/sqlcmd -S "{{KPIDB.host}}" -U "{{KPIDB.user}}" -P "{{KPIDB.pswd}}" -d "{{KPIDB.database}}" -Q "insert into {{KPIDB.table}}(ID,OPERATION_TYPE,WBE_CODE,TICKET_NUMBER,SYSTEM_NAME,SITE,ENVIRONMENT,STORAGE_CLASS,CAPACITY_GB,STORAGE,VDISK_UID,COUNTRY,[User],[Timestamp]) values('{{KPI_NEXTID.stdout}}','{{TYPE_OF_OPERATION}}','{{WBE_CODE}}','{{TICKET_NUMBER}}','{{SYSTEM_NAME}}','{{SITE}}','{{ENVIRONMENT}}','{{STORAGE_CLASS}}','{{CAPACITY_GB}}','{{STORAGE}}','{{VDISK_UID}}','{{Country|default("")}}','{{Job_User}}','{{KPI_TIMESTAMP.stdout}}')" + when: KPIDB.enable|bool == True diff --git a/service/dj_data_service.py b/service/dj_data_service.py index ea7cf2e..86b76a8 100644 --- a/service/dj_data_service.py +++ b/service/dj_data_service.py @@ -1,31 +1,34 @@ #!/usr/bin/python +import argparse +import ast import json -import yaml +import logging import os import time -import sys -import logging -import socket -import ast -import argparse import urllib -import requests +from operator import itemgetter + import BaseHTTPServer +import requests +import yaml from requests.packages.urllib3.exceptions import InsecureRequestWarning -from operator import itemgetter + +import log + class DJRestAPI(): - def __init__(self, host, user, pswd, port = 26335, verify = False, timeout = 10): + def __init__(self, host, user, pswd, port=26335, verify=False, timeout=10): self.user = user self.pswd = pswd self.verify = verify self.timeout = timeout self.url = "https://%s:%d" % (host, port) self.headers = { - 'Content-Type': 'application/json;charset=utf8', + 'Content-Type': 'application/json;charset=utf8', 'Accept': 'application/json' } self.connected = False + # end __init__ def login(self): @@ -35,17 +38,23 @@ def login(self): 'userName': self.user, 'value': self.pswd } - response = requests.put(url, json = data, headers = self.headers, verify = self.verify, timeout = self.timeout) - logging.debug('DJRestAPI.login - %d %s' %(response.status_code, url) ) + response = requests.put(url, json=data, headers=self.headers, + verify=self.verify, timeout=self.timeout) + logging.debug('DJRestAPI.login - %d %s' % (response.status_code, url)) body = response.json() if response.status_code == 200: self.headers['X-Auth-Token'] = body['accessSession'] self.connected = True else: - logging.error('DJRestAPI.login - %d %s' %( response.status_code, json.dumps(body, sort_keys=True, indent=4, ensure_ascii=False) ) ) + logging.error('DJRestAPI.login - %d %s' % (response.status_code, + json.dumps(body, + sort_keys=True, + indent=4, + ensure_ascii=False))) self.connected = False del self.headers['X-Auth-Token'] + # end login def get(self, uri): @@ -53,15 +62,18 @@ def get(self, uri): self.login() url = self.url + uri - response = requests.get(url, headers = self.headers, verify = self.verify, timeout = self.timeout) - logging.debug('DJRestAPI.get - %d %s' %( response.status_code, url) ) + response = requests.get(url, headers=self.headers, verify=self.verify, + timeout=self.timeout) + logging.debug('DJRestAPI.get - %d %s' % (response.status_code, url)) # token expired, login and try again if response.status_code == 401: self.login() - response = requests.get(url, headers = self.headers, verify = self.verify, timeout = self.timeout) + response = requests.get(url, headers=self.headers, + verify=self.verify, timeout=self.timeout) return response + # end get def put(self, uri, data): @@ -69,31 +81,37 @@ def put(self, uri, data): self.login() url = self.url + uri - response = requests.put(url, json = data, headers = self.headers, verify = self.verify, timeout = self.timeout) - logging.debug('DJRestAPI.put - %d %s' %( response.status_code, url) ) + response = requests.put(url, json=data, headers=self.headers, + verify=self.verify, timeout=self.timeout) + logging.debug('DJRestAPI.put - %d %s' % (response.status_code, url)) # token expired, login and try again if response.status_code == 401: self.login() - response = requests.put(url, json = data, headers = self.headers, verify = self.verify, timeout = self.timeout) + response = requests.put(url, json=data, headers=self.headers, + verify=self.verify, timeout=self.timeout) return response + # end put def post(self, uri, data): if self.connected == False: self.login() - + url = self.url + uri - response = requests.post(url, json = data, headers = self.headers, verify = self.verify, timeout = self.timeout) - logging.debug('DJRestAPI.post - %d %s' %( response.status_code, url) ) + response = requests.post(url, json=data, headers=self.headers, + verify=self.verify, timeout=self.timeout) + logging.debug('DJRestAPI.post - %d %s' % (response.status_code, url)) # token expired, login and try again if response.status_code == 401: self.login() - response = requests.put(url, json = data, headers = self.headers, verify = self.verify, timeout = self.timeout) + response = requests.put(url, json=data, headers=self.headers, + verify=self.verify, timeout=self.timeout) return response + # end post def delete(self, uri): @@ -101,27 +119,33 @@ def delete(self, uri): self.login() url = self.url + uri - response = requests.delete(url, headers = self.headers, verify = self.verify, timeout = self.timeout) - logging.debug('DJRestAPI.delete - %d %s' %( response.status_code, url) ) + response = requests.delete(url, headers=self.headers, + verify=self.verify, timeout=self.timeout) + logging.debug('DJRestAPI.delete - %d %s' % (response.status_code, url)) # token expired, login and try again if response.status_code == 401: self.login() - response = requests.delete(url, headers = self.headers, verify = self.verify, timeout = self.timeout) + response = requests.delete(url, headers=self.headers, + verify=self.verify, timeout=self.timeout) return response + # end delete def logout(self): if self.connected == True: - self.delete( '/rest/plat/smapp/v1/sessions' ) + self.delete('/rest/plat/smapp/v1/sessions') self.connected = False del self.headers['X-Auth-Token'] + # end logout def __del__(self): self.logout() # end __del__ + + # end DJRestAPI # Disable https warnings @@ -134,31 +158,27 @@ def __del__(self): for file in files: if file.endswith(".yml"): fd = open(os.path.join(root, file)) - VARS.update( yaml.load(fd) ) + VARS.update(yaml.load(fd)) fd.close() -# Set logging format -logging.basicConfig( - format = VARS['LOGGING']['format'], - level = VARS['LOGGING']['levelno'][ VARS['LOGGING']['level'] ], - datefmt = VARS['LOGGING']['datefmt'] -) - # load DJ credential -DJAPI = DJRestAPI(VARS['DJ']['host'], VARS['DJ']['user'], VARS['DJ']['pswd'], VARS['DJ']['port']) +DJAPI = DJRestAPI(VARS['DJ']['host'], VARS['DJ']['user'], VARS['DJ']['pswd'], + VARS['DJ']['port']) + class DjDataService(BaseHTTPServer.BaseHTTPRequestHandler): - - def _response(self, data, code = 200): - self.send_response( code ) - self.send_header('Content-type','application/json;charset=utf8') - self.send_header('Accept','application/json') + + def _response(self, data, code=200): + self.send_response(code) + self.send_header('Content-type', 'application/json;charset=utf8') + self.send_header('Accept', 'application/json') self.end_headers() - self.wfile.write(json.dumps(data, sort_keys=False, indent=4, ensure_ascii=False).encode('utf-8')) + self.wfile.write(json.dumps(data, sort_keys=False, indent=4, + ensure_ascii=False).encode('utf-8')) # /rest/data/v1/echo?k1=msg1&k2=msg2 def data_echo(self): - assert self.path.startswith( VARS['DJDATASERVICE']['API']['echo'] + '?' ) + assert self.path.startswith(VARS['DJDATASERVICE']['API']['echo'] + '?') query = urllib.unquote(self.path).split('?') @@ -166,25 +186,27 @@ def data_echo(self): for param in query[1].split('&'): kv = param.split('=') if len(kv) == 2: - resp.append( { 'name': kv[1], 'value': kv[0] } ) - + resp.append({'name': kv[1], 'value': kv[0]}) + if len(resp) == 0: self._response({}, 404) else: - self._response(sorted(resp, key=itemgetter('name')) ) + self._response(sorted(resp, key=itemgetter('name'))) + # end /rest/data/v1/echo # /rest/data/v1/enum/{type}?nameAttr=desc&valueAttr=key&filter={"attr1":"value1","attr2":"value2"} def data_enum(self): - assert self.path.startswith( VARS['DJDATASERVICE']['API']['enum'] + '/' ) + assert self.path.startswith(VARS['DJDATASERVICE']['API']['enum'] + '/') query = urllib.unquote(self.path).split('?') uri = query[0] - enumType = uri[uri.rfind('/')+1:] + enumType = uri[uri.rfind('/') + 1:] if enumType not in VARS: - self._response([{'name': VARS['DEFAULT']['noneName'],'value': VARS['DEFAULT']['noneValue']}]) + self._response([{'name': VARS['DEFAULT']['noneName'], + 'value': VARS['DEFAULT']['noneValue']}]) if len(query) == 2: params = dict(qc.split('=') for qc in query[1].split('&')) @@ -198,14 +220,14 @@ def data_enum(self): nameAttrs = params['nameAttr'].split(':') nameAttr = nameAttrs[0] if len(nameAttrs) > 1: - nameField = int(nameAttrs[1]) + nameField = int(nameAttrs[1]) if len(nameAttrs) > 2: nameFieldStart = int(nameAttrs[2]) if len(nameAttrs) > 3: nameFieldEnd = int(nameAttrs[3]) else: nameAttr = 'desc' - + valueField = None valueFieldStart = None valueFieldEnd = None @@ -278,7 +300,8 @@ def data_enum(self): if nameField is None: name = VARS[enumType][key][nameAttr] else: - name = VARS[enumType][key][nameAttr].split(nameSplit)[nameField][nameFieldStart:nameFieldEnd] + name = VARS[enumType][key][nameAttr].split(nameSplit)[ + nameField][nameFieldStart:nameFieldEnd] if valueAttr == 'key': value = key @@ -286,40 +309,46 @@ def data_enum(self): if valueField is None: value = VARS[enumType][key][valueAttr] else: - value = VARS[enumType][key][valueAttr].split(valueSplit)[valueField][valueFieldStart:valueFieldEnd] + value = VARS[enumType][key][valueAttr].split(valueSplit)[ + valueField][valueFieldStart:valueFieldEnd] matched = True - for attr,expect in filterAttrs.items(): + for attr, expect in filterAttrs.items(): if (attr == 'key') and (key == expect): break - if (attr not in VARS[enumType][key]) or (VARS[enumType][key][attr] != expect): + if (attr not in VARS[enumType][key]) or ( + VARS[enumType][key][attr] != expect): matched = False break # end filter if matched == True and len(name) > 0: - resp.append( { 'name': '{}{}{}'.format(namePrefix,name,nameSuffix), 'value': '{}{}{}'.format(valuePrefix,value,valueSuffix) } ) + resp.append( + {'name': '{}{}{}'.format(namePrefix, name, nameSuffix), + 'value': '{}{}{}'.format(valuePrefix, value, valueSuffix)}) # end keys if len(resp) == 0: self._response([{'name': nameDefault, 'value': valueDefault}]) else: - self._response(sorted(resp, key=itemgetter('name')) ) - # end /rest/data/v1/enum + self._response(sorted(resp, key=itemgetter('name'))) + # end /rest/data/v1/enum # /rest/data/v1/search/{objtype}?pageNo=1&pageSize=20&orderBy=last_Modified&orderAsc=False&nameAttr=name&valueAttr=id&descAttr=CAPACITY&descDivide=2097152&descUnit=GiB&condition={see cmdb api}&changedBefore=&changedAfter= def data_search(self): - assert self.path.startswith( VARS['DJDATASERVICE']['API']['search'] + '/' ) + assert self.path.startswith( + VARS['DJDATASERVICE']['API']['search'] + '/') query = urllib.unquote(self.path).split('?') uri = query[0] - objType = uri[uri.rfind('/')+1:] - + objType = uri[uri.rfind('/') + 1:] + if objType not in VARS['INVENTORY']: - logging.error( 'DjDataService.data_search - unsupported object type: ' + objType ) + logging.error( + 'DjDataService.data_search - unsupported object type: ' + objType) self._response({}, 404) return @@ -345,18 +374,19 @@ def data_search(self): pageSize = 20 djUri += '&pageSize=%d' % (pageSize) - + if 'orderBy' in params: orderBy = params['orderBy'] else: orderBy = 'last_Modified' if 'orderAsc' in params: - orderAsc = bool( params['orderAsc'] ) + orderAsc = bool(params['orderAsc']) else: orderAsc = False - djUri += '&orderBy=[{\"field\":\"%s\",\"asc\":\"%s\"}]' % (orderBy, orderAsc) + djUri += '&orderBy=[{\"field\":\"%s\",\"asc\":\"%s\"}]' % ( + orderBy, orderAsc) nameField = None nameFieldStart = None @@ -365,14 +395,14 @@ def data_search(self): nameAttrs = params['nameAttr'].split(':') nameAttr = nameAttrs[0] if len(nameAttrs) > 1: - nameField = int(nameAttrs[1]) + nameField = int(nameAttrs[1]) if len(nameAttrs) > 2: nameFieldStart = int(nameAttrs[2]) if len(nameAttrs) > 3: nameFieldEnd = int(nameAttrs[3]) else: nameAttr = 'name' - + valueField = None valueFieldStart = None valueFieldEnd = None @@ -419,12 +449,12 @@ def data_search(self): valueSuffix = '' if 'nameUnique' in params: - nameUnique = bool( params['nameUnique'] ) + nameUnique = bool(params['nameUnique']) else: nameUnique = False if 'valueUnique' in params: - valueUnique = bool( params['valueUnique'] ) + valueUnique = bool(params['valueUnique']) else: valueUnique = False @@ -450,12 +480,13 @@ def data_search(self): if 'descUnit' in params: descUnit = params['descUnit'] - contentSelector = [nameAttr,valueAttr] + contentSelector = [nameAttr, valueAttr] if (descAttr is not None) and (descAttr not in contentSelector): contentSelector.append(descAttr) - djUri += '&contentSelector=%s' % ( json.dumps(contentSelector, ensure_ascii=False) ) + djUri += '&contentSelector=%s' % ( + json.dumps(contentSelector, ensure_ascii=False)) condition = {} @@ -468,15 +499,23 @@ def data_search(self): currentTime = time.time() if 'changedBefore' in params: - last_Modified_Before = int( ( currentTime - int(params['changedBefore']) ) * 1000 ) - condition['constraint'].append( {"logOp":"and","simple":{"name":"last_Modified","operator":"less than","value":last_Modified_Before}} ) + last_Modified_Before = int( + (currentTime - int(params['changedBefore'])) * 1000) + condition['constraint'].append({"logOp": "and", + "simple": {"name": "last_Modified", + "operator": "less than", + "value": last_Modified_Before}}) if 'changedAfter' in params: - last_Modified_After = int( ( currentTime - int(params['changedAfter']) ) * 1000 ) - condition['constraint'].append( {"logOp":"and","simple":{"name":"last_Modified","operator":"not less than","value":last_Modified_After}} ) + last_Modified_After = int( + (currentTime - int(params['changedAfter'])) * 1000) + condition['constraint'].append({"logOp": "and", + "simple": {"name": "last_Modified", + "operator": "not less than", + "value": last_Modified_After}}) + + djUri += '&condition=%s' % (json.dumps(condition, ensure_ascii=False)) - djUri += '&condition=%s' %( json.dumps(condition, ensure_ascii=False) ) - # Forward request to DJ API response = DJAPI.get(djUri); body = response.json() @@ -489,42 +528,54 @@ def data_search(self): if nameField is None: name = obj[nameAttr] else: - name = obj[nameAttr].split(nameSplit)[nameField][nameFieldStart:nameFieldEnd] + name = obj[nameAttr].split(nameSplit)[nameField][ + nameFieldStart:nameFieldEnd] if descAttr is not None: desc = obj[descAttr] if descDivide is not None: desc = float(desc) / float(descDivide) - name = '{} ( {} {} )'.format(name,desc,descUnit) + name = '{} ( {} {} )'.format(name, desc, descUnit) if valueField is None: value = obj[valueAttr] else: - value = obj[valueAttr].split(valueSplit)[valueField][valueFieldStart:valueFieldEnd] - - if len(name) > 0 and ( (nameUnique == True and name not in names) or (nameUnique == False) ) and ( (valueUnique == True and value not in values) or (valueUnique == False) ): + value = obj[valueAttr].split(valueSplit)[valueField][ + valueFieldStart:valueFieldEnd] + + if len(name) > 0 and ( + (nameUnique == True and name not in names) or ( + nameUnique == False)) and ( + (valueUnique == True and value not in values) or ( + valueUnique == False)): names.append(name) values.append(value) - resp.append( { 'name': '{}{}{}'.format(namePrefix,name,nameSuffix), 'value': '{}{}{}'.format(valuePrefix,value,valueSuffix) } ) + resp.append({'name': '{}{}{}'.format(namePrefix, name, + nameSuffix), + 'value': '{}{}{}'.format(valuePrefix, + value, + valueSuffix)}) # end objList # end body if len(resp) == 0: self._response([{'name': nameDefault, 'value': valueDefault}]) else: - self._response(sorted(resp, key=itemgetter('name')) ) + self._response(sorted(resp, key=itemgetter('name'))) + # end search # /rest/data/v1/join/{objtype}?pageNo=1&pageSize=20&orderBy=last_Modified&orderAsc=False&nameAttr=name&valueAttr=id&descAttr=CAPACITY&descDivide=2097152&descUnit=GiB&relations=[{"obj":"releventObjType","condition":"queryCondition"},...]&joins=[{"joinAttr","sourceAttribute","obj":"{targetObjectType}","attr":"targetAttribute","condition":"targetObjectCondition"},...] def data_join(self): - assert self.path.startswith( VARS['DJDATASERVICE']['API']['join'] + '/' ) + assert self.path.startswith(VARS['DJDATASERVICE']['API']['join'] + '/') query = urllib.unquote(self.path).split('?') uri = query[0] - objType = uri[uri.rfind('/')+1:] + objType = uri[uri.rfind('/') + 1:] if objType not in VARS['INVENTORY']: - logging.error( 'DjDataService.data_join - unsupported object type: ' + objType ) + logging.error( + 'DjDataService.data_join - unsupported object type: ' + objType) self._response({}, 404) return @@ -550,18 +601,19 @@ def data_join(self): pageSize = 20 djUri += '&pageSize=%d' % (pageSize) - + if 'orderBy' in params: orderBy = params['orderBy'] else: orderBy = 'last_Modified' if 'orderAsc' in params: - orderAsc = bool( params['orderAsc'] ) + orderAsc = bool(params['orderAsc']) else: orderAsc = False - djUri += '&orderBy=[{\"field\":\"%s\",\"asc\":\"%s\"}]' % (orderBy, orderAsc) + djUri += '&orderBy=[{\"field\":\"%s\",\"asc\":\"%s\"}]' % ( + orderBy, orderAsc) nameField = None nameFieldStart = None @@ -570,14 +622,14 @@ def data_join(self): nameAttrs = params['nameAttr'].split(':') nameAttr = nameAttrs[0] if len(nameAttrs) > 1: - nameField = int(nameAttrs[1]) + nameField = int(nameAttrs[1]) if len(nameAttrs) > 2: nameFieldStart = int(nameAttrs[2]) if len(nameAttrs) > 3: nameFieldEnd = int(nameAttrs[3]) else: nameAttr = 'name' - + valueField = None valueFieldStart = None valueFieldEnd = None @@ -645,12 +697,13 @@ def data_join(self): if 'descUnit' in params: descUnit = params['descUnit'] - contentSelector = [nameAttr,valueAttr] + contentSelector = [nameAttr, valueAttr] if (descAttr is not None) and (descAttr not in contentSelector): contentSelector.append(descAttr) - djUri += '&contentSelector=%s' % ( json.dumps(contentSelector, ensure_ascii=False) ) + djUri += '&contentSelector=%s' % ( + json.dumps(contentSelector, ensure_ascii=False)) # more conditions if 'condition' in params: @@ -660,29 +713,39 @@ def data_join(self): if 'relationConstraint' not in condition: condition['relationConstraint'] = [] else: - condition = {"constraint":[],"relationConstraint":[]} + condition = {"constraint": [], "relationConstraint": []} if 'joins' in params: joins = ast.literal_eval(params['joins']) for join in joins: joinObjType = join['obj'] - joinCondition = json.dumps(join['condition'], ensure_ascii=False) + joinCondition = json.dumps(join['condition'], + ensure_ascii=False) joinAttr = join['joinAttr'] if joinObjType not in VARS['INVENTORY']: - logging.error( 'DjDataService.data_search - unsupported object type: ' + joinObjType ) + logging.error( + 'DjDataService.data_search - unsupported object type: ' + joinObjType) self._response({}, 404) return joinClassName = VARS['INVENTORY'][joinObjType]['className'] - joinUri = '%s/%s?condition=%s' %(VARS['DJSERVICE']['API']['instances'], joinClassName, joinCondition) - joinResponse = DJAPI.get( joinUri ); - logging.debug( 'DjDataService.data_join - %d %s' %(joinResponse.status_code, joinUri) ) + joinUri = '%s/%s?condition=%s' % ( + VARS['DJSERVICE']['API']['instances'], joinClassName, + joinCondition) + joinResponse = DJAPI.get(joinUri); + logging.debug('DjDataService.data_join - %d %s' % ( + joinResponse.status_code, joinUri)) joinBody = joinResponse.json() - if (joinResponse.status_code == 200) and ('totalNum' in joinBody) and (joinBody['totalNum'] > 0): + if (joinResponse.status_code == 200) and ( + 'totalNum' in joinBody) and (joinBody['totalNum'] > 0): joinValues = [] for joinObj in joinBody['objList']: joinValues.append(joinObj[join['attr']]) if len(joinValues) > 0: - condition['constraint'].append( {"logOp":"and","simple":{"name":joinAttr,"operator":"in","value":joinValues}} ) + condition['constraint'].append({"logOp": "and", + "simple": { + "name": joinAttr, + "operator": "in", + "value": joinValues}}) # end joinValues # end joinResponse # end joins @@ -691,33 +754,57 @@ def data_join(self): relations = ast.literal_eval(params['relations']) for relation in relations: relObjType = relation['obj'] - if (relObjType not in VARS['INVENTORY']) or (relObjType not in VARS['INVENTORY'][objType]['relations']): - logging.error( 'DjDataService.data_search - unsupported object type: ' + relObjType ) + if (relObjType not in VARS['INVENTORY']) or ( + relObjType not in VARS['INVENTORY'][objType][ + 'relations']): + logging.error( + 'DjDataService.data_search - unsupported object type: ' + relObjType) self._response({}, 404) return relClassName = VARS['INVENTORY'][relObjType]['className'] - relationName = VARS['INVENTORY'][objType]['relations'][relObjType]['relationName'] - isSourceObj = VARS['INVENTORY'][objType]['relations'][relObjType]['source'] - relCondition = json.dumps(relation['condition'], ensure_ascii=False) - relUri = '%s/%s?condition=%s' %(VARS['DJSERVICE']['API']['instances'], relClassName, relCondition) + relationName = \ + VARS['INVENTORY'][objType]['relations'][relObjType][ + 'relationName'] + isSourceObj = \ + VARS['INVENTORY'][objType]['relations'][relObjType][ + 'source'] + relCondition = json.dumps(relation['condition'], + ensure_ascii=False) + relUri = '%s/%s?condition=%s' % ( + VARS['DJSERVICE']['API']['instances'], relClassName, + relCondition) relResponse = DJAPI.get(relUri) - logging.debug( 'DjDataService.data_join - %d %s' %(relResponse.status_code, relUri) ) + logging.debug('DjDataService.data_join - %d %s' % ( + relResponse.status_code, relUri)) relBody = relResponse.json() - if (relResponse.status_code == 200) and ('totalNum' in relBody) and (relBody['totalNum'] > 0): + if (relResponse.status_code == 200) and ( + 'totalNum' in relBody) and (relBody['totalNum'] > 0): relValues = [] for relObj in relBody['objList']: relValues.append(relObj['id']) if len(relValues) > 0: if isSourceObj == True: - condition['relationConstraint'].append( {"logOp":"and","relationName":relationName,"sourceInstance":"false","constraint":[{"simple":{"name":"source_Instance_Id","operator":"in","value":relValues}}]} ) + condition['relationConstraint'].append( + {"logOp": "and", "relationName": relationName, + "sourceInstance": "false", "constraint": [{ + "simple": { + "name": "source_Instance_Id", + "operator": "in", + "value": relValues}}]}) else: - condition['relationConstraint'].append( {"logOp":"and","relationName":relationName,"sourceInstance":"true","constraint":[{"simple":{"name":"target_Instance_Id","operator":"in","value":relValues}}]} ) + condition['relationConstraint'].append( + {"logOp": "and", "relationName": relationName, + "sourceInstance": "true", "constraint": [{ + "simple": { + "name": "target_Instance_Id", + "operator": "in", + "value": relValues}}]}) # end relValues # end relResponse # end relations - djUri += ( '&condition=' + json.dumps(condition, ensure_ascii=False) ) - + djUri += ('&condition=' + json.dumps(condition, ensure_ascii=False)) + # Forward request to DJ API response = DJAPI.get(djUri); body = response.json() @@ -728,39 +815,47 @@ def data_join(self): if nameField is None: name = obj[nameAttr] else: - name = obj[nameAttr].split(nameSplit)[nameField][nameFieldStart:nameFieldEnd] + name = obj[nameAttr].split(nameSplit)[nameField][ + nameFieldStart:nameFieldEnd] if descAttr is not None: desc = obj[descAttr] if descDivide is not None: desc = float(desc) / float(descDivide) - name = '{} ( {} {} )'.format(name,desc,descUnit) + name = '{} ( {} {} )'.format(name, desc, descUnit) if valueField is None: value = obj[valueAttr] else: - value = obj[valueAttr].split(valueSplit)[valueField][valueFieldStart:valueFieldEnd] + value = obj[valueAttr].split(valueSplit)[valueField][ + valueFieldStart:valueFieldEnd] if len(name) > 0: - resp.append( { 'name': '{}{}{}'.format(namePrefix,name,nameSuffix), 'value': '{}{}{}'.format(valuePrefix,value,valueSuffix) } ) - + resp.append({'name': '{}{}{}'.format(namePrefix, name, + nameSuffix), + 'value': '{}{}{}'.format(valuePrefix, + value, + valueSuffix)}) + if len(resp) == 0: self._response([{'name': nameDefault, 'value': valueDefault}]) else: - self._response(sorted(resp, key=itemgetter('name')) ) + self._response(sorted(resp, key=itemgetter('name'))) + # end join # /rest/data/v1/split/{objtype}?valueAttr=name&valueSplit=_&bypass=bypass&match=match&selected=true&condition={see cmdb api} def data_split(self): - assert self.path.startswith( VARS['DJDATASERVICE']['API']['split'] + '/' ) + assert self.path.startswith(VARS['DJDATASERVICE']['API']['split'] + '/') query = urllib.unquote(self.path).split('?') uri = query[0] - objType = uri[uri.rfind('/')+1:] - + objType = uri[uri.rfind('/') + 1:] + if objType not in VARS['INVENTORY']: - logging.error( 'DjDataService.data_split - unsupported object type: ' + objType ) + logging.error( + 'DjDataService.data_split - unsupported object type: ' + objType) self._response({}, 404) return @@ -808,11 +903,11 @@ def data_split(self): else: selected = True - djUri += ( '?contentSelector=[\"%s\"]' % (valueAttr) ) + djUri += ('?contentSelector=[\"%s\"]' % (valueAttr)) if 'condition' in params: - djUri += '&condition=%s' %( params['condition'] ) - + djUri += '&condition=%s' % (params['condition']) + # Forward request to DJ API response = DJAPI.get(djUri); body = response.json() @@ -820,10 +915,12 @@ def data_split(self): if ('totalNum' in body) and (body['totalNum'] > 0): for obj in body['objList']: if valueAttr in obj: - values=obj[valueAttr].split(valueSplit) + values = obj[valueAttr].split(valueSplit) for value in values: - if (len(value) > 0) and (bypass not in value) and (match in value): - resp.append( { 'name': value, 'value': value, 'selected': selected } ) + if (len(value) > 0) and (bypass not in value) and ( + match in value): + resp.append({'name': value, 'value': value, + 'selected': selected}) # end values # end valueAttr # end objList @@ -831,32 +928,33 @@ def data_split(self): if len(resp) == 0: self._response([{'name': nameDefault, 'value': valueDefault}]) else: - self._response(sorted(resp, key=itemgetter('name')) ) + self._response(sorted(resp, key=itemgetter('name'))) + # end split def do_GET(self): # /rest/data/v1/echo - if self.path.startswith( VARS['DJDATASERVICE']['API']['echo'] + '?' ): + if self.path.startswith(VARS['DJDATASERVICE']['API']['echo'] + '?'): self.data_echo() return # /rest/data/v1/enum - if self.path.startswith( VARS['DJDATASERVICE']['API']['enum'] + '/' ): + if self.path.startswith(VARS['DJDATASERVICE']['API']['enum'] + '/'): self.data_enum() return # /rest/data/v1/search - if self.path.startswith( VARS['DJDATASERVICE']['API']['search'] + '/' ): + if self.path.startswith(VARS['DJDATASERVICE']['API']['search'] + '/'): self.data_search() return # /rest/data/v1/join - if self.path.startswith( VARS['DJDATASERVICE']['API']['join'] + '/' ): + if self.path.startswith(VARS['DJDATASERVICE']['API']['join'] + '/'): self.data_join() return # /rest/data/v1/split - if self.path.startswith( VARS['DJDATASERVICE']['API']['split'] + '/' ): + if self.path.startswith(VARS['DJDATASERVICE']['API']['split'] + '/'): self.data_split() return @@ -864,36 +962,49 @@ def do_GET(self): response = DJAPI.get(self.path) self._response(response.json(), response.status_code) return + # end do_GET def do_POST(self): self._response({}, 404) + # end do_POST def do_PUT(self): self._response({}, 404) + # end do_PUT def do_DELETE(self): self._response({}, 404) # end do_DELETE + + # end DjDataService def parse_args(): parser = argparse.ArgumentParser() - parser.add_argument('-H', '--host', type=str, required=False, default=VARS['DJDATASERVICE']['host'], help='Listening host or ip address, default: %s' % ( VARS['DJDATASERVICE']['host'] ) ) - parser.add_argument('-p', '--port', type=str, required=False, default=VARS['DJDATASERVICE']['port'], help='Listening port, default: %d' % ( VARS['DJDATASERVICE']['port'] ) ) + parser.add_argument('-H', '--host', type=str, required=False, + default=VARS['DJDATASERVICE']['host'], + help='Listening host or ip address, default: %s' % ( + VARS['DJDATASERVICE']['host'])) + parser.add_argument('-p', '--port', type=str, required=False, + default=VARS['DJDATASERVICE']['port'], + help='Listening port, default: %d' % ( + VARS['DJDATASERVICE']['port'])) return parser.parse_args() + if __name__ == '__main__': args = parse_args() - + log.setup(VARS, "dj_data_service") try: - server = BaseHTTPServer.HTTPServer((args.host, args.port), DjDataService) - logging.debug( 'Started server on %s:%d' % ( args.host, args.port ) ) - - #Wait forever for incoming htto requests + server = BaseHTTPServer.HTTPServer((args.host, args.port), + DjDataService) + logging.debug('Started server on %s:%d' % (args.host, args.port)) + + # Wait forever for incoming htto requests server.serve_forever() except KeyboardInterrupt: diff --git a/service/dm_data_service.py b/service/dm_data_service.py index 0de7dae..5499c7b 100644 --- a/service/dm_data_service.py +++ b/service/dm_data_service.py @@ -1,20 +1,24 @@ #!/usr/bin/python +# -*- coding: -*- +import argparse +import ast import json -import yaml -import sys -import os import logging +import os import socket -import ast -import argparse import urllib -import requests +from operator import itemgetter + import BaseHTTPServer +import requests +import yaml from requests.packages.urllib3.exceptions import InsecureRequestWarning -from operator import itemgetter + +import log + class DMRestAPI: - def __init__(self, ipList, user, pswd, port = 8088, verify = False, timeout = 10): + def __init__(self, ipList, user, pswd, port=8088, verify=False, timeout=10): self.user = user self.pswd = pswd self.verify = verify @@ -25,9 +29,10 @@ def __init__(self, ipList, user, pswd, port = 8088, verify = False, timeout = 10 self.connected = False self.timeout = timeout self.headers = { - 'Content-Type': 'application/json;charset=utf8', + 'Content-Type': 'application/json;charset=utf8', 'Accept': 'application/json' } + # end __init__ def login(self): @@ -36,16 +41,18 @@ def login(self): try: s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.settimeout(1) - s.connect( (ip, self.port) ) + s.connect((ip, self.port)) validIp = ip s.shutdown(socket.SHUT_RDWR) s.close() break except socket.error: - logging.error( 'DMRestAPI.login - %s is not accessible' %(ip) ) + logging.error('DMRestAPI.login - %s is not accessible' % (ip)) if validIp is None: - logging.error('DMRestAPI.login - storage is not accessible: ' + self.ipList.join(',')) + logging.error( + 'DMRestAPI.login - storage is not accessible: ' + self.ipList.join( + ',')) self.connected = False self.cookies = None del self.headers['iBaseToken'] @@ -54,12 +61,13 @@ def login(self): self.url = "https://%s:%d" % (validIp, self.port) url = self.url + "/deviceManager/rest/xxxxx/login" data = { - 'username' : self.user, - 'password' : self.pswd, - 'scope' : '0' + 'username': self.user, + 'password': self.pswd, + 'scope': '0' } - response = requests.post(url, json = data, headers = self.headers, verify = self.verify, timeout = self.timeout) - logging.debug('DMRestAPI.login - %d %s' %(response.status_code, url) ) + response = requests.post(url, json=data, headers=self.headers, + verify=self.verify, timeout=self.timeout) + logging.debug('DMRestAPI.login - %d %s' % (response.status_code, url)) body = response.json() if response.status_code == 200: @@ -68,16 +76,24 @@ def login(self): self.cookies = response.cookies self.connected = True else: - logging.error('DMRestAPI.login - %d %s' %( response.status_code, json.dumps(body, sort_keys=True, indent=4, ensure_ascii=False) ) ) + logging.error('DMRestAPI.login - %d %s' % (response.status_code, + json.dumps(body, + sort_keys=True, + indent=4, + ensure_ascii=False))) self.connected = False self.cookies = None del self.headers['iBaseToken'] else: - logging.error('DMRestAPI.login - %d %s' %( response.status_code, json.dumps(body, sort_keys=True, indent=4, ensure_ascii=False) ) ) + logging.error('DMRestAPI.login - %d %s' % (response.status_code, + json.dumps(body, + sort_keys=True, + indent=4, + ensure_ascii=False))) self.connected = False self.cookies = None del self.headers['iBaseToken'] - + # end login def get(self, uri): @@ -85,15 +101,20 @@ def get(self, uri): self.login() url = self.url + uri - response = requests.get(url, headers = self.headers, cookies = self.cookies, verify = self.verify, timeout = self.timeout) - logging.debug('DMRestAPI.get - %d - %s' %( response.status_code, url) ) + response = requests.get(url, headers=self.headers, cookies=self.cookies, + verify=self.verify, timeout=self.timeout) + logging.debug('DMRestAPI.get - %d - %s' % (response.status_code, url)) # token expired, login and try again - if response.status_code == 200 and response.json()['error']['code'] == -401: + if response.status_code == 200 and response.json()['error'][ + 'code'] == -401: self.login() - response = requests.get(url, headers = self.headers, cookies = self.cookies, verify = self.verify, timeout = self.timeout) + response = requests.get(url, headers=self.headers, + cookies=self.cookies, verify=self.verify, + timeout=self.timeout) return response + # end get def put(self, uri, data): @@ -101,15 +122,21 @@ def put(self, uri, data): self.login() url = self.url + uri - response = requests.put(url, json = data, headers = self.headers, cookies = self.cookies, verify = self.verify, timeout = self.timeout) - logging.debug('DMRestAPI.get - %d %s' %( response.status_code, url) ) + response = requests.put(url, json=data, headers=self.headers, + cookies=self.cookies, verify=self.verify, + timeout=self.timeout) + logging.debug('DMRestAPI.get - %d %s' % (response.status_code, url)) # token expired, login and try again - if response.status_code == 200 and response.json()['error']['code'] == -401: + if response.status_code == 200 and response.json()['error'][ + 'code'] == -401: self.login() - response = requests.put(url, json = data, headers = self.headers, cookies = self.cookies, verify = self.verify, timeout = self.timeout) + response = requests.put(url, json=data, headers=self.headers, + cookies=self.cookies, verify=self.verify, + timeout=self.timeout) return response + # end put def post(self, uri, data): @@ -117,15 +144,21 @@ def post(self, uri, data): self.login() url = self.url + uri - response = requests.post(url, json = data, headers = self.headers, cookies = self.cookies, verify = self.verify, timeout = self.timeout) - logging.debug('DMRestAPI.get - %d %s' %( response.status_code, url) ) + response = requests.post(url, json=data, headers=self.headers, + cookies=self.cookies, verify=self.verify, + timeout=self.timeout) + logging.debug('DMRestAPI.get - %d %s' % (response.status_code, url)) # token expired, login and try again - if response.status_code == 200 and response.json()['error']['code'] == -401: + if response.status_code == 200 and response.json()['error'][ + 'code'] == -401: self.login() - response = requests.post(url, json = data, headers = self.headers, cookies = self.cookies, verify = self.verify, timeout = self.timeout) + response = requests.post(url, json=data, headers=self.headers, + cookies=self.cookies, verify=self.verify, + timeout=self.timeout) return response + # end post def delete(self, uri): @@ -133,30 +166,38 @@ def delete(self, uri): self.login() url = self.url + uri - response = requests.delete(url, headers = self.headers, cookies = self.cookies, verify = self.verify, timeout = self.timeout) - logging.debug('DMRestAPI.get - %d %s' %( response.status_code, url) ) + response = requests.delete(url, headers=self.headers, + cookies=self.cookies, verify=self.verify, + timeout=self.timeout) + logging.debug('DMRestAPI.get - %d %s' % (response.status_code, url)) # token expired, login and try again - if response.status_code == 200 and response.json()['error']['code'] == -401: + if response.status_code == 200 and response.json()['error'][ + 'code'] == -401: self.login() - response = requests.delete(url, headers = self.headers, cookies = self.cookies, verify = self.verify, timeout = self.timeout) + response = requests.delete(url, headers=self.headers, + cookies=self.cookies, verify=self.verify, + timeout=self.timeout) return response + # end delete # logout session def logout(self): if self.connected == True: - self.delete( '/sessions' ) + self.delete('/sessions') self.connected = False self.cookies = None del self.headers['iBaseToken'] + # end logout def __del__(self): self.logout() # end __del__ + # end class DMRestAPI @@ -172,40 +213,39 @@ def __del__(self): for file in files: if file.endswith(".yml"): fd = open(os.path.join(root, file)) - VARS.update( yaml.load(fd) ) + VARS.update(yaml.safe_load(fd)) fd.close() -# set logging format -logging.basicConfig( - format = VARS['LOGGING']['format'], - level = VARS['LOGGING']['levelno'][ VARS['LOGGING']['level'] ], - datefmt = VARS['LOGGING']['datefmt'] -) - # load storage credential # load storage credential DMAPI = {} for storage in VARS['STORAGES']: - DMAPI[storage['sn']] = DMRestAPI(storage['ipList'], storage['user'], storage['pswd'], storage['port']) + DMAPI[storage['sn']] = DMRestAPI(storage['ipList'], storage['user'], + storage['pswd'], storage['port']) + + # end to load storage credential class DMDataService(BaseHTTPServer.BaseHTTPRequestHandler): - def _response(self, data, code = 200): - self.send_response( code ) - self.send_header('Content-type','application/json;charset=utf8') - self.send_header('Accept','application/json') + def _response(self, data, code=200): + self.send_response(code) + self.send_header('Content-type', 'application/json;charset=utf8') + self.send_header('Accept', 'application/json') self.end_headers() - self.wfile.write(json.dumps(data, sort_keys=False, indent=4, ensure_ascii=False).encode('utf-8')) + self.wfile.write(json.dumps(data, sort_keys=False, indent=4, + ensure_ascii=False).encode('utf-8')) # /data/v1/detail/{objtype}?nameAttr=NAME&valueAttr=ID&range=[0-19]&ID=objId def data_detail(self, sn): - assert self.path.startswith( '/deviceManager/rest/' + sn + VARS['DMDATASERVICE']['API']['detail'] + '/' ) + assert self.path.startswith( + '/deviceManager/rest/' + sn + VARS['DMDATASERVICE']['API'][ + 'detail'] + '/') query = urllib.unquote(self.path).split('?') uri = query[0] - objType = uri[uri.rfind('/')+1:] + objType = uri[uri.rfind('/') + 1:] dmUri = '/deviceManager/rest/' + sn + '/' + objType @@ -293,35 +333,44 @@ def data_detail(self, sn): response = DMAPI[sn].get(dmUri); body = response.json() resp = [] - if (response.status_code == 200) and (body['error']['code'] == 0) and ('data' in body): + if (response.status_code == 200) and (body['error']['code'] == 0) and ( + 'data' in body): obj = body['data'] if nameAttr in obj and valueAttr in obj: if nameField is None: name = obj[nameAttr] else: - name = obj[nameAttr].split(nameSplit)[nameField][nameFieldStart:nameFieldEnd] + name = obj[nameAttr].split(nameSplit)[nameField][ + nameFieldStart:nameFieldEnd] if valueField is None: value = obj[valueAttr] else: - value = obj[valueAttr].split(valueSplit)[valueField][valueFieldStart:valueFieldEnd] + value = obj[valueAttr].split(valueSplit)[valueField][ + valueFieldStart:valueFieldEnd] if (len(name) > 0): - resp.append( { 'name': '{}{}{}'.format(namePrefix,name,nameSuffix), 'value': '{}{}{}'.format(valuePrefix,value,valueSuffix) } ) + resp.append( + {'name': '{}{}{}'.format(namePrefix, name, nameSuffix), + 'value': '{}{}{}'.format(valuePrefix, value, + valueSuffix)}) # end body # end response if len(resp) == 0: self._response([{'name': nameDefault, 'value': valueDefault}]) else: - self._response(sorted(resp, key=itemgetter('name')) ) + self._response(sorted(resp, key=itemgetter('name'))) + # end detail # /data/v1/search/{objtype}?nameAttr=NAME&valueAttr=ID&descAttr=CAPACITY&descDivide=2097152&descUnit=GiB&range=[0-19]&filter={see DM APIs} def data_search(self, sn): - assert self.path.startswith( '/deviceManager/rest/' + sn + VARS['DMDATASERVICE']['API']['search'] + '/' ) + assert self.path.startswith( + '/deviceManager/rest/' + sn + VARS['DMDATASERVICE']['API'][ + 'search'] + '/') query = urllib.unquote(self.path).split('?') uri = query[0] - objType = uri[uri.rfind('/')+1:] + objType = uri[uri.rfind('/') + 1:] dmUri = '/deviceManager/rest/' + sn + '/' + objType @@ -337,7 +386,7 @@ def data_search(self, sn): nameAttrs = params['nameAttr'].split(':') nameAttr = nameAttrs[0] if len(nameAttrs) > 1: - nameField = int(nameAttrs[1]) + nameField = int(nameAttrs[1]) if len(nameAttrs) > 2: nameFieldStart = int(nameAttrs[2]) if len(nameAttrs) > 3: @@ -345,7 +394,7 @@ def data_search(self, sn): del params['nameAttr'] else: nameAttr = 'NAME' - + valueField = None valueFieldStart = None valueFieldEnd = None @@ -440,50 +489,60 @@ def data_search(self, sn): if len(params) > 0: dmUri += '?' - for k,v in params.items(): - dmUri += '{}={}&'.format(k,v) + for k, v in params.items(): + dmUri += '{}={}&'.format(k, v) # Forward request to DM API response = DMAPI[sn].get(dmUri); body = response.json() resp = [] - if (response.status_code == 200) and (body['error']['code'] == 0) and ('data' in body) and (len(body['data']) > 0): + if (response.status_code == 200) and (body['error']['code'] == 0) and ( + 'data' in body) and (len(body['data']) > 0): for obj in body['data']: if nameAttr in obj and valueAttr in obj and matchAttr in obj: if nameField is None: name = obj[nameAttr] else: - name = obj[nameAttr].split(nameSplit)[nameField][nameFieldStart:nameFieldEnd] + name = obj[nameAttr].split(nameSplit)[nameField][ + nameFieldStart:nameFieldEnd] if descAttr is not None: desc = obj[descAttr] if descDivide is not None: desc = float(desc) / float(descDivide) - name = '{} ( {} {} )'.format(name,desc,descUnit) + name = '{} ( {} {} )'.format(name, desc, descUnit) if valueField is None: value = obj[valueAttr] else: - value = obj[valueAttr].split(valueSplit)[valueField][valueFieldStart:valueFieldEnd] + value = obj[valueAttr].split(valueSplit)[valueField][ + valueFieldStart:valueFieldEnd] if (len(name) > 0) and (match in obj[matchAttr]): - resp.append( { 'name': '{}{}{}'.format(namePrefix,name,nameSuffix), 'value': '{}{}{}'.format(valuePrefix,value,valueSuffix) } ) + resp.append({'name': '{}{}{}'.format(namePrefix, name, + nameSuffix), + 'value': '{}{}{}'.format(valuePrefix, + value, + valueSuffix)}) # end obj # end body # end response if len(resp) == 0: self._response([{'name': nameDefault, 'value': valueDefault}]) else: - self._response(sorted(resp, key=itemgetter('name')) ) + self._response(sorted(resp, key=itemgetter('name'))) + # end search # /data/v1/join/{objtype}?nameAttr=NAME&valueAttr=ID&range=[0-19]&filter={see DM APIs}&joins=[{"joinAttr","sourceAttribute","obj":"{targetObjectType}","attr":"targetAttribute","filter":"targetObjectFilter"},...] def data_join(self, sn): - assert self.path.startswith( '/deviceManager/rest/' + sn + VARS['DMDATASERVICE']['API']['join'] + '/' ) + assert self.path.startswith( + '/deviceManager/rest/' + sn + VARS['DMDATASERVICE']['API'][ + 'join'] + '/') query = urllib.unquote(self.path).split('?') uri = query[0] - objType = uri[uri.rfind('/')+1:] + objType = uri[uri.rfind('/') + 1:] dmUri = '/deviceManager/rest/' + sn @@ -499,14 +558,14 @@ def data_join(self, sn): nameAttrs = params['nameAttr'].split(':') nameAttr = nameAttrs[0] if len(nameAttrs) > 1: - nameField = int(nameAttrs[1]) + nameField = int(nameAttrs[1]) if len(nameAttrs) > 2: nameFieldStart = int(nameAttrs[2]) if len(nameAttrs) > 3: nameFieldEnd = int(nameAttrs[3]) else: nameAttr = 'NAME' - + valueField = None valueFieldStart = None valueFieldEnd = None @@ -595,66 +654,83 @@ def data_join(self, sn): descUnit = params['descUnit'] if 'joins' not in params: - logging.error( 'DMDataService.data_join - No joins param') - self._response([{'name': nameDefault,'value': valueDefault}]) + logging.error('DMDataService.data_join - No joins param') + self._response([{'name': nameDefault, 'value': valueDefault}]) joins = ast.literal_eval(params['joins']) for join in joins: - joinResponse = DMAPI[sn].get( '%s/%s?filter=%s' %(dmUri, join['obj'], join['filter']) ); + joinResponse = DMAPI[sn].get( + '%s/%s?filter=%s' % (dmUri, join['obj'], join['filter'])); joinBody = joinResponse.json() - if (joinResponse.status_code == 200) and (joinBody['error']['code'] == 0) and ('data' in joinBody) and (len(joinBody['data']) == 1): + if (joinResponse.status_code == 200) and ( + joinBody['error']['code'] == 0) and ( + 'data' in joinBody) and (len(joinBody['data']) == 1): if filterParam is None: - filterParam = join['joinAttr'] + '::' + joinBody['data'][0][join['attr']] + filterParam = join['joinAttr'] + '::' + joinBody['data'][0][ + join['attr']] else: - filterParam = filterParam + ' and ' + join['joinAttr'] + '::' + joinBody['data'][0][join['attr']] + filterParam = filterParam + ' and ' + join[ + 'joinAttr'] + '::' + joinBody['data'][0][join['attr']] # end joins if filterParam is None: - logging.error( 'DMDataService.data_join - No matched objects or Not only 1 matched objects') - self._response([{'name': nameDefault,'value': valueDefault}]) + logging.error( + 'DMDataService.data_join - No matched objects or Not only 1 matched objects') + self._response([{'name': nameDefault, 'value': valueDefault}]) # Forward request to DM API - response = DMAPI[sn].get( '%s/%s?range=%s&filter=%s' %(dmUri, objType, rangeParam, filterParam) ); + response = DMAPI[sn].get('%s/%s?range=%s&filter=%s' % ( + dmUri, objType, rangeParam, filterParam)); body = response.json() resp = [] - if (response.status_code == 200) and (body['error']['code'] == 0) and ('data' in body) and (len(body['data']) > 0): + if (response.status_code == 200) and (body['error']['code'] == 0) and ( + 'data' in body) and (len(body['data']) > 0): for obj in body['data']: if nameAttr in obj and valueAttr in obj and matchAttr in obj: if nameField is None: name = obj[nameAttr] else: - name = obj[nameAttr].split(nameSplit)[nameField][nameFieldStart:nameFieldEnd] + name = obj[nameAttr].split(nameSplit)[nameField][ + nameFieldStart:nameFieldEnd] if descAttr is not None: desc = obj[descAttr] if descDivide is not None: desc = float(desc) / float(descDivide) - name = '{} ( {} {} )'.format(name,desc,descUnit) + name = '{} ( {} {} )'.format(name, desc, descUnit) if valueField is None: value = obj[valueAttr] else: - value = obj[valueAttr].split(valueSplit)[valueField][valueFieldStart:valueFieldEnd] + value = obj[valueAttr].split(valueSplit)[valueField][ + valueFieldStart:valueFieldEnd] if (len(name) > 0) and (match in obj[matchAttr]): - resp.append( { 'name': '{}{}{}'.format(namePrefix,name,nameSuffix), 'value': '{}{}{}'.format(valuePrefix,value,valueSuffix) } ) + resp.append({'name': '{}{}{}'.format(namePrefix, name, + nameSuffix), + 'value': '{}{}{}'.format(valuePrefix, + value, + valueSuffix)}) # end obj # end body # end response if len(resp) == 0: - self._response([{'name': nameDefault,'value': valueDefault}]) + self._response([{'name': nameDefault, 'value': valueDefault}]) else: - self._response(sorted(resp, key=itemgetter('name')) ) + self._response(sorted(resp, key=itemgetter('name'))) + # end data_join # /data/v1/associate/{objtype}?nameAttr=NAME&valueAttr=ID&matchAttr=NAME&match=xx&range=[0-19]&obj={associateObjType}&filter={associateObjFilter} def data_associate(self, sn): - assert self.path.startswith( '/deviceManager/rest/' + sn + VARS['DMDATASERVICE']['API']['associate'] + '/' ) + assert self.path.startswith( + '/deviceManager/rest/' + sn + VARS['DMDATASERVICE']['API'][ + 'associate'] + '/') query = urllib.unquote(self.path).split('?') uri = query[0] - objType = uri[uri.rfind('/')+1:] + objType = uri[uri.rfind('/') + 1:] dmUri = '/deviceManager/rest/' + sn @@ -670,14 +746,14 @@ def data_associate(self, sn): nameAttrs = params['nameAttr'].split(':') nameAttr = nameAttrs[0] if len(nameAttrs) > 1: - nameField = int(nameAttrs[1]) + nameField = int(nameAttrs[1]) if len(nameAttrs) > 2: nameFieldStart = int(nameAttrs[2]) if len(nameAttrs) > 3: nameFieldEnd = int(nameAttrs[3]) else: nameAttr = 'NAME' - + valueField = None valueFieldStart = None valueFieldEnd = None @@ -766,61 +842,87 @@ def data_associate(self, sn): objIdAttr = 'ID' if ('obj' not in params) or ('filter' not in params): - logging.error( 'DMDataService.data_associate - No associate obj or filter param') - self._response([{'name': nameDefault,'value': valueDefault}]) + logging.error( + 'DMDataService.data_associate - No associate obj or filter param') + self._response([{'name': nameDefault, 'value': valueDefault}]) resp = [] - joinResponse = DMAPI[sn].get( '%s/%s?filter=%s' %(dmUri, params['obj'], params['filter']) ); + joinResponse = DMAPI[sn].get( + '%s/%s?range=[0-100]&filter=%s' % (dmUri, params['obj'], params['filter'])); joinBody = joinResponse.json() - if (joinResponse.status_code == 200) and (joinBody['error']['code'] == 0) and ('data' in joinBody) and (len(joinBody['data']) == 1): + if (joinResponse.status_code == 200) and ( + joinBody['error']['code'] == 0) and ('data' in joinBody) and ( + len(joinBody['data']) == 1): ASSOCIATEOBJTYPE = joinBody['data'][0]['TYPE'] ASSOCIATEOBJID = joinBody['data'][0][objIdAttr] # Forward request to DM API - response = DMAPI[sn].get( '%s/%s/associate?range=%s&ASSOCIATEOBJTYPE=%s&ASSOCIATEOBJID=%s' %(dmUri, objType, rangeParam, ASSOCIATEOBJTYPE, ASSOCIATEOBJID) ); + response = DMAPI[sn].get( + '%s/%s/associate?range=%s&ASSOCIATEOBJTYPE=%s&ASSOCIATEOBJID=%s' % ( + dmUri, objType, rangeParam, ASSOCIATEOBJTYPE, + ASSOCIATEOBJID)); body = response.json() - if (response.status_code == 200) and (body['error']['code'] == 0) and ('data' in body) and (len(body['data']) > 0): + if (response.status_code == 200) and ( + body['error']['code'] == 0) and ('data' in body) and ( + len(body['data']) > 0): for obj in body['data']: if nameAttr in obj and valueAttr in obj and matchAttr in obj: if nameField is None: name = obj[nameAttr] else: - name = obj[nameAttr].split(nameSplit)[nameField][nameFieldStart:nameFieldEnd] + name = obj[nameAttr].split(nameSplit)[nameField][ + nameFieldStart:nameFieldEnd] if descAttr is not None: desc = obj[descAttr] if descDivide is not None: desc = float(desc) / float(descDivide) - name = '{} ( {} {} )'.format(name,desc,descUnit) + name = '{} ( {} {} )'.format(name, desc, descUnit) if valueField is None: value = obj[valueAttr] else: - value = obj[valueAttr].split(valueSplit)[valueField][valueFieldStart:valueFieldEnd] + value = obj[valueAttr].split(valueSplit)[ + valueField][ + valueFieldStart:valueFieldEnd] if (len(name) > 0) and (match in obj[matchAttr]): - resp.append( { 'name': '{}{}{}'.format(namePrefix,name,nameSuffix), 'value': '{}{}{}'.format(valuePrefix,value,valueSuffix) } ) + resp.append({'name': '{}{}{}'.format(namePrefix, + name, + nameSuffix), + 'value': '{}{}{}'.format(valuePrefix, + value, + valueSuffix)}) # end obj # end body # end response else: - logging.debug('DMDataService.data_associate - %d %s' %( response.status_code, json.dumps(body, sort_keys=True, indent=4, ensure_ascii=False) ) ) + logging.debug('DMDataService.data_associate - %d %s' % ( + response.status_code, + json.dumps(body, sort_keys=True, indent=4, + ensure_ascii=False))) # end join else: - logging.debug('DMDataService.data_associate - %d %s' %( joinResponse.status_code, json.dumps(joinBody, sort_keys=True, indent=4, ensure_ascii=False) ) ) + logging.debug('DMDataService.data_associate - %d %s' % ( + joinResponse.status_code, + json.dumps(joinBody, sort_keys=True, indent=4, + ensure_ascii=False))) if len(resp) == 0: - self._response([{'name': nameDefault,'value': valueDefault}]) + self._response([{'name': nameDefault, 'value': valueDefault}]) else: - self._response(sorted(resp, key=itemgetter('name')) ) + self._response(sorted(resp, key=itemgetter('name'))) + # end data_associate # /data/v1/split/{objtype}?valueAttr=name&valueSplit=_&bypass=bypass&match=match&selected=true&range=[0-19]&filter={see DM APIs} def data_split(self, sn): - assert self.path.startswith( '/deviceManager/rest/' + sn + VARS['DMDATASERVICE']['API']['split'] + '/' ) + assert self.path.startswith( + '/deviceManager/rest/' + sn + VARS['DMDATASERVICE']['API'][ + 'split'] + '/') query = urllib.unquote(self.path).split('?') uri = query[0] - objType = uri[uri.rfind('/')+1:] + objType = uri[uri.rfind('/') + 1:] dmUri = '/deviceManager/rest/' + sn + '/' + objType @@ -872,29 +974,33 @@ def data_split(self, sn): if len(params) > 0: dmUri += '?' - for k,v in params.items(): - dmUri += '{}={}&'.format(k,v) + for k, v in params.items(): + dmUri += '{}={}&'.format(k, v) # Forward request to DM API response = DMAPI[sn].get(dmUri); body = response.json() resp = [] - if (response.status_code == 200) and (body['error']['code'] == 0) and ('data' in body) and (len(body['data']) > 0): + if (response.status_code == 200) and (body['error']['code'] == 0) and ( + 'data' in body) and (len(body['data']) > 0): for obj in body['data']: if valueAttr in obj: - values=obj[valueAttr].split(valueSplit) + values = obj[valueAttr].split(valueSplit) for value in values: - if (len(value) > 0) and (bypass not in value) and (match in value): - resp.append( { 'name': value, 'value': value, 'selected': selected } ) + if (len(value) > 0) and (bypass not in value) and ( + match in value): + resp.append({'name': value, 'value': value, + 'selected': selected}) # end values # end valueAttr # end body # end response if len(resp) == 0: - self._response([{'name': nameDefault,'value': valueDefault}]) + self._response([{'name': nameDefault, 'value': valueDefault}]) else: - self._response(sorted(resp, key=itemgetter('name')) ) + self._response(sorted(resp, key=itemgetter('name'))) + # end split def do_GET(self): @@ -902,74 +1008,87 @@ def do_GET(self): uriPath = self.path.split('/') if len(uriPath) < 4 or uriPath[3] not in DMAPI: - self._response([{'name': VARS['DEFAULT']['noneName'],'value': VARS['DEFAULT']['noneValue']}]) + self._response([{'name': VARS['DEFAULT']['noneName'], + 'value': VARS['DEFAULT']['noneValue']}]) return sn = uriPath[3] uri = self.path.replace('/deviceManager/rest/' + sn, '') # /data/v1/detail - if uri.startswith( VARS['DMDATASERVICE']['API']['detail'] + '/' ): + if uri.startswith(VARS['DMDATASERVICE']['API']['detail'] + '/'): self.data_detail(sn) return # /data/v1/search - if uri.startswith( VARS['DMDATASERVICE']['API']['search'] + '/' ): + if uri.startswith(VARS['DMDATASERVICE']['API']['search'] + '/'): self.data_search(sn) return # /data/v1/join - if uri.startswith( VARS['DMDATASERVICE']['API']['join'] + '/' ): + if uri.startswith(VARS['DMDATASERVICE']['API']['join'] + '/'): self.data_join(sn) return # /data/v1/associate - if uri.startswith( VARS['DMDATASERVICE']['API']['associate'] + '/' ): + if uri.startswith(VARS['DMDATASERVICE']['API']['associate'] + '/'): self.data_associate(sn) return # /data/v1/split - if uri.startswith( VARS['DMDATASERVICE']['API']['split'] + '/' ): + if uri.startswith(VARS['DMDATASERVICE']['API']['split'] + '/'): self.data_split(sn) return - # Forward to DM API response = DMAPI[sn].get(self.path) self._response(response.json(), response.status_code) return # end of /deviceManager/rest/ self._response({}, 404) + # end do_GET def do_POST(self): self._response({}, 404) + # end do_POST def do_PUT(self): self._response({}, 404) + # end do_PUT def do_DELETE(self): self._response({}, 404) # end do_DELETE + + # end DMDataService def parse_args(): parser = argparse.ArgumentParser() - parser.add_argument('-H', '--host', type=str, required=False, default=VARS['DMDATASERVICE']['host'], help='Listening host or ip address, default: %s' % ( VARS['DMDATASERVICE']['host'] ) ) - parser.add_argument('-p', '--port', type=str, required=False, default=VARS['DMDATASERVICE']['port'], help='Listening port, default: %d' % ( VARS['DMDATASERVICE']['port'] ) ) + parser.add_argument('-H', '--host', type=str, required=False, + default=VARS['DMDATASERVICE']['host'], + help='Listening host or ip address, default: %s' % ( + VARS['DMDATASERVICE']['host'])) + parser.add_argument('-p', '--port', type=str, required=False, + default=VARS['DMDATASERVICE']['port'], + help='Listening port, default: %d' % ( + VARS['DMDATASERVICE']['port'])) return parser.parse_args() + if __name__ == '__main__': args = parse_args() - + log.setup(VARS, "dm_data_service") try: - server = BaseHTTPServer.HTTPServer((args.host, args.port), DMDataService) - logging.debug( 'Started server on %s:%d' % ( args.host, args.port ) ) - - #Wait forever for incoming htto requests + server = BaseHTTPServer.HTTPServer((args.host, args.port), + DMDataService) + logging.debug('Started server on %s:%d' % (args.host, args.port)) + + # Wait forever for incoming htto requests server.serve_forever() except KeyboardInterrupt: diff --git a/service/log.py b/service/log.py new file mode 100644 index 0000000..5502f0c --- /dev/null +++ b/service/log.py @@ -0,0 +1,46 @@ +import logging +import logging.handlers +import os + + +def _get_log_file_path(conf, logfile): + logdir = conf['LOGGING']['path'] + + if logfile and not logdir: + return logfile + + if logfile and logdir: + return os.path.join(logdir, logfile) + + return None + + +def _set_up_logging_from_conf(conf, service_name): + log_root = logging.getLogger() + + # Remove all handlers + for handler in list(log_root.handlers): + log_root.removeHandler(handler) + + logpath = _get_log_file_path(conf, service_name + ".log") + if logpath: + file_handler = logging.handlers.RotatingFileHandler + max_bytes = 50 * 1024 ** 2 # 20M + filelog = file_handler(logpath, + maxBytes=max_bytes, + backupCount=5) + log_root.addHandler(filelog) + + # user stdout + log_root.addHandler(logging.StreamHandler()) + + for handler in log_root.handlers: + handler.setFormatter(logging.Formatter( + fmt=conf['LOGGING']['format'], + datefmt=conf['LOGGING']['datefmt'])) + + log_root.setLevel(conf['LOGGING']['level']) + + +def setup(conf, service_name): + _set_up_logging_from_conf(conf, service_name) diff --git a/task/cmdb/list_instances.yml b/task/cmdb/list_instances.yml index b18e1ea..bab3ec5 100644 --- a/task/cmdb/list_instances.yml +++ b/task/cmdb/list_instances.yml @@ -20,31 +20,68 @@ # # Generated Parameters (can be overwritten): # className: CI class Name, see global.yml to get supported className in INVENTORY.objType.className -# modifiedEpochFrom: modified time from, format: epoch in seconds -# modifiedEpochTo: modified time to, format: epoch in seconds - set_fact: className: "{{ INVENTORY[objType].className if (objType is defined and objType is not none) else className }}" # map objType to className pageNo: "{{ pageNo | default(1) }}" pageSize: "{{ pageSize | default(10) }}" - modifiedEpochFrom: "{{ (ansible_date_time.epoch|int-7*24*3600) if (modifiedTimeFrom is not defined or modifiedTimeFrom is none) else (modifiedTimeFrom|to_datetime).strftime('%s') }}" - modifiedEpochTo: "{{ (ansible_date_time.epoch|int) if (modifiedTimeTo is not defined or modifiedTimeTo is none) else (modifiedTimeTo|to_datetime).strftime('%s') }}" orderBy: "{{ orderBy | default('last_Modified') }}" orderAsc: "{{ orderAsc | default(False) | bool }}" sep: "{{ sep | default('|') }}" - filterCondition: "" waitExist: "{{ waitExist | default(False) }}" waitSeconds: "{{ waitSeconds | default(600) }}" waitInterval: "{{ waitInterval | default(10) }}" + constraints: [] -- name: Set filters - set_fact: - filterCondition: "{{filterCondition}},{\"logOp\":\"and\",\"simple\":{\"name\":\"{{item.k}}\",\"operator\":\"{{item.op|urlencode}}\",\"value\":\"{{item.v|urlencode}}\"}}" +- set_fact: + constraints: "{{constraints + [timeFilter]}}" + vars: + timeFilter: + logOp: "and" + simple: + name: "last_Modified" + operator: "not less than" + value: "{{(modifiedTimeFrom|to_datetime).strftime('%s')}}000" + when: modifiedTimeFrom is defined + +- set_fact: + constraints: "{{constraints + [timeFilter]}}" + vars: + timeFilter: + logOp: "and" + simple: + name: "last_Modified" + operator: "less than" + value: "{{(modifiedTimeTo|to_datetime).strftime('%s')}}000" + when: modifiedTimeTo is defined + + +- set_fact: + constraints: "{{constraints + [constraint]}}" + vars: + constraint: + logOp: "and" + simple: + name: "{{item.k}}" + operator: "{{item.op}}" + value: "{{item.v}}" with_items: "{{ filters }}" when: filters is defined - set_fact: - params: "pageNo={{pageNo}}&pageSize={{pageSize}}&orderBy=[{\"field\":\"{{orderBy}}\",\"asc\":\"{{orderAsc}}\"}]&condition={\"constraint\":[{\"simple\":{\"name\":\"last_Modified\",\"operator\":\"not%20less%20than\",\"value\":\"{{modifiedEpochFrom}}000\"}},{\"logOp\":\"and\",\"simple\":{\"name\":\"last_Modified\",\"operator\":\"less%20than\",\"value\":\"{{modifiedEpochTo}}000\"}}{{filterCondition}}]}" + paramCondition: + constraint: "{{constraints}}" + +- set_fact: + paramOrderBy: + - field: "{{orderBy}}" + asc: "{{orderAsc}}" + +- set_fact: + params: "pageNo={{pageNo}}&pageSize={{pageSize}}&orderBy={{paramOrderBy | to_json | urlencode}}&condition={{paramCondition | to_json(ensure_ascii=False) | urlencode}}" + +- debug: + msg: "{{params}}" - name: List Instances uri: @@ -70,7 +107,7 @@ keys: "{{INVENTORY[objType].attributes}}" file: "{{export}}" sep: "{{sep}}" - when: + when: - export is defined - INSTANCES.json.objList is defined - INSTANCES.json.objList|length > 0 diff --git a/task/storage/oceanstor/activate_snapshots.yml b/task/storage/oceanstor/activate_snapshots.yml index 10a6deb..a224503 100644 --- a/task/storage/oceanstor/activate_snapshots.yml +++ b/task/storage/oceanstor/activate_snapshots.yml @@ -7,7 +7,7 @@ - block: - name: Query Snapshots uri: - url: "https://{{deviceHost}}:{{devicePort}}/deviceManager/rest/{{deviceSn}}/SNAPSHOT?filter=NAME%3A%3A{{item|urlencode}}" + url: "https://{{deviceHost}}:{{devicePort}}/deviceManager/rest/{{deviceSn}}/SNAPSHOT?range=%5B0-100%5D&filter=NAME%3A%3A{{item|urlencode}}" method: GET validate_certs: no headers: diff --git a/task/storage/oceanstor/add_luns_to_clone_cg.yml b/task/storage/oceanstor/add_luns_to_clone_cg.yml index bc771b0..e94293d 100644 --- a/task/storage/oceanstor/add_luns_to_clone_cg.yml +++ b/task/storage/oceanstor/add_luns_to_clone_cg.yml @@ -34,7 +34,7 @@ - name: Query LUNs by Name uri: - url: "https://{{deviceHost}}:{{devicePort}}/deviceManager/rest/{{deviceSn}}/lun?filter=NAME%3A%3A{{item|urlencode}}" + url: "https://{{deviceHost}}:{{devicePort}}/deviceManager/rest/{{deviceSn}}/lun?range=%5B0-100%5D&filter=NAME%3A%3A{{item|urlencode}}" method: GET validate_certs: no headers: diff --git a/task/storage/oceanstor/add_luns_to_lg.yml b/task/storage/oceanstor/add_luns_to_lg.yml index ed78211..a928315 100644 --- a/task/storage/oceanstor/add_luns_to_lg.yml +++ b/task/storage/oceanstor/add_luns_to_lg.yml @@ -33,7 +33,7 @@ - name: Query LUNs by Name uri: - url: "https://{{deviceHost}}:{{devicePort}}/deviceManager/rest/{{deviceSn}}/lun?filter=NAME%3A%3A{{item|urlencode}}" + url: "https://{{deviceHost}}:{{devicePort}}/deviceManager/rest/{{deviceSn}}/lun?range=%5B0-100%5D&filter=NAME%3A%3A{{item|urlencode}}" method: GET validate_certs: no headers: diff --git a/task/storage/oceanstor/add_luns_to_pg.yml b/task/storage/oceanstor/add_luns_to_pg.yml index ee13c83..af9ff19 100644 --- a/task/storage/oceanstor/add_luns_to_pg.yml +++ b/task/storage/oceanstor/add_luns_to_pg.yml @@ -28,7 +28,7 @@ - block: - name: Query LUNs by Name uri: - url: "https://{{deviceHost}}:{{devicePort}}/deviceManager/rest/{{deviceSn}}/lun?filter=NAME%3A%3A{{item|urlencode}}" + url: "https://{{deviceHost}}:{{devicePort}}/deviceManager/rest/{{deviceSn}}/lun?range=%5B0-100%5D&filter=NAME%3A%3A{{item|urlencode}}" method: GET validate_certs: no headers: @@ -83,4 +83,7 @@ queryMsg: "[*].json.error" debug: msg: "{{ PG_ADD_LUNS.results | json_query(queryMsg) }}" - failed_when: PG_ADD_LUNS.results | json_query(queryError) | difference([0]) | length > 0 \ No newline at end of file + failed_when: PG_ADD_LUNS.results | json_query(queryError) | difference([0]) | length > 0 + +- set_fact: + addLunIds: [] \ No newline at end of file diff --git a/task/storage/oceanstor/add_ports_to_host.yml b/task/storage/oceanstor/add_ports_to_host.yml index 4a5bba2..a0db0e9 100644 --- a/task/storage/oceanstor/add_ports_to_host.yml +++ b/task/storage/oceanstor/add_ports_to_host.yml @@ -38,7 +38,7 @@ - name: Query Host by Name uri: - url: "https://{{deviceHost}}:{{devicePort}}/deviceManager/rest/{{deviceSn}}/host?filter=NAME%3A%3A{{hostName|urlencode}}" + url: "https://{{deviceHost}}:{{devicePort}}/deviceManager/rest/{{deviceSn}}/host?range=%5B0-100%5D&filter=NAME%3A%3A{{hostName|urlencode}}" method: GET validate_certs: no headers: diff --git a/task/storage/oceanstor/check_host_lun_id.yml b/task/storage/oceanstor/check_host_lun_id.yml index 707e354..2f6ef9a 100644 --- a/task/storage/oceanstor/check_host_lun_id.yml +++ b/task/storage/oceanstor/check_host_lun_id.yml @@ -24,7 +24,7 @@ - block: - name: Query Host by Name uri: - url: "https://{{deviceHost}}:{{devicePort}}/deviceManager/rest/{{deviceSn}}/host?filter=NAME%3A%3A{{hostName|urlencode}}" + url: "https://{{deviceHost}}:{{devicePort}}/deviceManager/rest/{{deviceSn}}/host?range=%5B0-100%5D&filter=NAME%3A%3A{{hostName|urlencode}}" method: GET validate_certs: no headers: diff --git a/task/storage/oceanstor/check_host_lun_id_loop_helper.yml b/task/storage/oceanstor/check_host_lun_id_loop_helper.yml new file mode 100644 index 0000000..d585869 --- /dev/null +++ b/task/storage/oceanstor/check_host_lun_id_loop_helper.yml @@ -0,0 +1,14 @@ +# Get Host LUN ID Loop Helper, cooperator with nested loop +# +# Required parameters: +# hostName: Host Name +# hostGroupName: Host Group Name +# +# Generated parameters: +# checkedHostLuns Checked Host LUNs Info, Need Clean Before Used. + + +- import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/check_host_lun_id.yml" +- set_fact: + checkedHostLuns: "{{ checkedHostLuns + [checkedLuns] }}" + diff --git a/task/storage/oceanstor/check_host_wwns.yml b/task/storage/oceanstor/check_host_wwns.yml new file mode 100644 index 0000000..0af1583 --- /dev/null +++ b/task/storage/oceanstor/check_host_wwns.yml @@ -0,0 +1,66 @@ +# Check wwns exists on hosts +# +# Required parameters: +# hostNames: # a list of host names +# +# Optional parameters: +# checkExist: # check exist or not exist, default: true, options: true/false +# +# Generated variables: +# checkedHosts: # a list of hosts on storage device +# checkedWwns: # a map of wwns in hosts + +- name: Set default variables + set_fact: + hostIds: [] + checkedHosts: [] + checkedWwns: {} + +- name: Query Hosts by Name + uri: + url: "https://{{deviceHost}}:{{devicePort}}/deviceManager/rest/{{deviceSn}}/host?range=%5B0-100%5D&filter=NAME%3A%3A{{item|urlencode}}" + method: GET + validate_certs: no + headers: + Accept: "application/json" + Content-Type: "application/json;charset=utf8" + iBaseToken: "{{ deviceToken }}" + Cookie: "session={{ deviceSession }}" + register: HOSTS + with_items: "{{ hostNames }}" + +- name: Get Host IDs + set_fact: + hostIds: "{{ HOSTS.results | json_query('[*].json.data[*].ID') | flatten(levels=1) }}" + checkedHosts: "{{ HOSTS.results | json_query('[*].json.data[*]') | flatten(levels=1) }}" + +- name: Check Host Name Exist + debug: + msg: + hostIds: "{{ hostIds }}" + failed_when: (hostIds|length != hostNames|length) + +- name: Get WWNs + uri: + url: "https://{{deviceHost}}:{{devicePort}}/deviceManager/rest/{{deviceSn}}/fc_initiator?filter=PARENTID%3A%3A{{item}}" + method: GET + validate_certs: no + headers: + Accept: "application/json" + Content-Type: "application/json;charset=utf8" + iBaseToken: "{{ deviceToken }}" + Cookie: "session={{ deviceSession }}" + register: WWNs + failed_when: (WWNs.json.error.code|int != 0) + with_items: "{{ hostIds }}" + +- set_fact: + checkedWwns: "{{ checkedWwns | combine( { item.1: WWNs.results[item.0].json.data | default([]) | json_query('[*].ID') } ) }}" + with_indexed_items: "{{ hostNames }}" + +- name: Check WWNs Exist in Hosts + debug: + msg: + WWNs: "{{ item }}" + failed_when: (checkExist|default(True)|bool == True and item.value|length == 0) or (checkExist|default(True)|bool == False and item.value|length > 0) + loop: "{{ lookup('dict', checkedWwns, wantlist=True) }}" diff --git a/task/storage/oceanstor/check_hosts.yml b/task/storage/oceanstor/check_hosts.yml index 6c5405f..077dda7 100644 --- a/task/storage/oceanstor/check_hosts.yml +++ b/task/storage/oceanstor/check_hosts.yml @@ -21,7 +21,7 @@ - name: Query Hosts by Name uri: - url: "https://{{deviceHost}}:{{devicePort}}/deviceManager/rest/{{deviceSn}}/host?filter=NAME%3A%3A{{item|urlencode}}" + url: "https://{{deviceHost}}:{{devicePort}}/deviceManager/rest/{{deviceSn}}/host?range=%5B0-100%5D&filter=NAME%3A%3A{{item|urlencode}}" method: GET validate_certs: no headers: diff --git a/task/storage/oceanstor/check_luns.yml b/task/storage/oceanstor/check_luns.yml index 982934d..86c6d6c 100644 --- a/task/storage/oceanstor/check_luns.yml +++ b/task/storage/oceanstor/check_luns.yml @@ -16,7 +16,7 @@ - name: Query LUNs by Name uri: - url: "https://{{deviceHost}}:{{devicePort}}/deviceManager/rest/{{deviceSn}}/lun?filter=NAME%3A%3A{{item|urlencode}}" + url: "https://{{deviceHost}}:{{devicePort}}/deviceManager/rest/{{deviceSn}}/lun?range=%5B0-100%5D&filter=NAME%3A%3A{{item|urlencode}}" method: GET validate_certs: no headers: diff --git a/task/storage/oceanstor/create_clone.yml b/task/storage/oceanstor/create_clone.yml index 88488f2..63c598f 100644 --- a/task/storage/oceanstor/create_clone.yml +++ b/task/storage/oceanstor/create_clone.yml @@ -14,7 +14,7 @@ - name: Query Source LUN by Name uri: - url: "https://{{deviceHost}}:{{devicePort}}/deviceManager/rest/{{deviceSn}}/lun?filter=NAME%3A%3A{{sourceLun|urlencode}}" + url: "https://{{deviceHost}}:{{devicePort}}/deviceManager/rest/{{deviceSn}}/lun?range=%5B0-100%5D&filter=NAME%3A%3A{{sourceLun|urlencode}}" method: GET validate_certs: no headers: diff --git a/task/storage/oceanstor/create_drstar.yml b/task/storage/oceanstor/create_drstar.yml index 4fb0748..8eb7087 100644 --- a/task/storage/oceanstor/create_drstar.yml +++ b/task/storage/oceanstor/create_drstar.yml @@ -71,4 +71,8 @@ - name: Check Enable DR Star Result debug: msg: "{{ ENABLE_DRSTAR.json.error }}" - failed_when: (ENABLE_DRSTAR.json.error.code|int !=0) \ No newline at end of file + failed_when: (ENABLE_DRSTAR.json.error.code|int !=0) + +- name: Wait a replication cycle + pause: + seconds: "{{GLOBAL.replication.interval}}" \ No newline at end of file diff --git a/task/storage/oceanstor/create_lg.yml b/task/storage/oceanstor/create_lg.yml index 05cb1f7..d47a617 100644 --- a/task/storage/oceanstor/create_lg.yml +++ b/task/storage/oceanstor/create_lg.yml @@ -11,7 +11,7 @@ # mapHostNames: Map LUN Group to a list of Hosts # mapHostGroupNames: Map LUN Group to a list of Host Groups # pgName: Create Protection Group for LUN Group -# pgId: Specify Protection Grup ID +# pgId: Specify Protection Group ID # # Generated Parameters: # newLgId: New LG ID diff --git a/task/storage/oceanstor/create_pg.yml b/task/storage/oceanstor/create_pg.yml index 12628c1..6c2f03c 100644 --- a/task/storage/oceanstor/create_pg.yml +++ b/task/storage/oceanstor/create_pg.yml @@ -5,8 +5,10 @@ # # Optional parameters: # lgName: LUN Group Name +# lgId: Specify LUN Group ID # desc: Description # addLunNames: Add a list of LUNs to PG +# addLunIds: Add a list of LUN IDs to LUN Group # # Generated Parameters: # newPgId: New PG ID @@ -23,15 +25,22 @@ when: - desc|default(none) is not none -- import_tasks: check_lgs.yml - vars: - lgNames: ["{{ lgName }}"] - checkExist: True - when: lgName|default(none) is not none +- block: + - import_tasks: check_lgs.yml + vars: + lgNames: ["{{ lgName }}"] + checkExist: True + + - set_fact: + lgId: "{{ lgIds[0] }}" + + # End block + when: + lgName|default(none) is not none - name: Set param - lunGroupId set_fact: - paramCreatePg: "{{ paramCreatePg | combine( { 'lunGroupId': lgIds[0] } ) }}" + paramCreatePg: "{{ paramCreatePg | combine( { 'lunGroupId': lgId } ) }}" when: lgName|default(none) is not none - name: Create PG @@ -51,7 +60,7 @@ - name: Check Create PG Result debug: msg: "{{ NEW_PG.json.error }}" - failed_when: (NEW_PG.json.error.code|int != 0) or ('data' not in NEW_LG.json) + failed_when: (NEW_PG.json.error.code|int != 0) or ('data' not in NEW_PG.json) - set_fact: newPgId: "{{ NEW_PG.json.data.protectGroupId }}" @@ -60,7 +69,17 @@ - import_tasks: check_luns.yml vars: lunNames: "{{ addLunNames }}" + checkExist: True + - set_fact: + addLunIds: "{{ lunIds }}" + + # End block + when: + - addLunNames|default(none) is not none + - addLunNames|length > 0 + +- block: - name: Add LUN to PG uri: url: "https://{{deviceHost}}:{{devicePort}}/deviceManager/rest/{{deviceSn}}/protectgroup/associate" @@ -77,7 +96,7 @@ ASSOCIATEOBJTYPE: 11 ASSOCIATEOBJID: "{{ item }}" register: PG_ADD_LUNS - with_items: "{{ lunIds }}" + with_items: "{{ addLunIds }}" - name: Check Add LUN Results vars: @@ -89,5 +108,5 @@ # End Block when: - - addLunNames|default(none) is not none - - addLunNames|length > 0 \ No newline at end of file + - addLunIds|default(none) is not none + - addLunIds|length > 0 \ No newline at end of file diff --git a/task/storage/oceanstor/create_snapshot_cg.yml b/task/storage/oceanstor/create_snapshot_cg.yml index e110e03..1b959d1 100644 --- a/task/storage/oceanstor/create_snapshot_cg.yml +++ b/task/storage/oceanstor/create_snapshot_cg.yml @@ -59,10 +59,29 @@ - set_fact: newCgId: "{{ NEW_CG.json.data.ID }}" +- name: Unset snapIds + debug: + when: snapIds|default(None) != None + +- name: Wait create Complete + uri: + url: "https://{{deviceHost}}:{{devicePort}}/deviceManager/rest/{{deviceSn}}/snapshot/associate?ASSOCIATEOBJTYPE=57646&ASSOCIATEOBJID={{newCgId}}&range=%5B0-100%5D" + method: GET + validate_certs: no + headers: + Accept: "application/json" + Content-Type: "application/json;charset=utf8" + iBaseToken: "{{ deviceToken }}" + Cookie: "session={{ deviceSession }}" + register: SNAPSHOTS + retries: "20" + delay: "5" + until: SNAPSHOTS.json.data|default([])|length != 0 + - block: - name: Query Snapshots uri: - url: "https://{{deviceHost}}:{{devicePort}}/deviceManager/rest/{{deviceSn}}/snapshot/associate?ASSOCIATEOBJTYPE=57646&ASSOCIATEOBJID={{newCgId}}&range=[0-4096]" + url: "https://{{deviceHost}}:{{devicePort}}/deviceManager/rest/{{deviceSn}}/snapshot/associate?ASSOCIATEOBJTYPE=57646&ASSOCIATEOBJID={{newCgId}}&range=%5B0-100%5D" method: GET validate_certs: no headers: diff --git a/task/storage/oceanstor/create_snapshots.yml b/task/storage/oceanstor/create_snapshots.yml index f08754c..09d3f15 100644 --- a/task/storage/oceanstor/create_snapshots.yml +++ b/task/storage/oceanstor/create_snapshots.yml @@ -17,7 +17,7 @@ - block: - name: Query LUNs by Name uri: - url: "https://{{deviceHost}}:{{devicePort}}/deviceManager/rest/{{deviceSn}}/lun?filter=NAME%3A%3A{{item|urlencode}}" + url: "https://{{deviceHost}}:{{devicePort}}/deviceManager/rest/{{deviceSn}}/lun?range=%5B0-100%5D&filter=NAME%3A%3A{{item|urlencode}}" method: GET validate_certs: no headers: diff --git a/task/storage/oceanstor/deactivate_snapshots.yml b/task/storage/oceanstor/deactivate_snapshots.yml index 2ff0e01..9da073b 100644 --- a/task/storage/oceanstor/deactivate_snapshots.yml +++ b/task/storage/oceanstor/deactivate_snapshots.yml @@ -7,7 +7,7 @@ - block: - name: Query Snapshots uri: - url: "https://{{deviceHost}}:{{devicePort}}/deviceManager/rest/{{deviceSn}}/SNAPSHOT?filter=NAME%3A%3A{{item|urlencode}}" + url: "https://{{deviceHost}}:{{devicePort}}/deviceManager/rest/{{deviceSn}}/SNAPSHOT?range=%5B0-100%5D&filter=NAME%3A%3A{{item|urlencode}}" method: GET validate_certs: no headers: diff --git a/task/storage/oceanstor/delete_host.yml b/task/storage/oceanstor/delete_host.yml index 4135b0f..5421e0c 100644 --- a/task/storage/oceanstor/delete_host.yml +++ b/task/storage/oceanstor/delete_host.yml @@ -6,7 +6,7 @@ - name: Query Host by Name uri: - url: "https://{{deviceHost}}:{{devicePort}}/deviceManager/rest/{{deviceSn}}/host?filter=NAME%3A%3A{{hostName|urlencode}}" + url: "https://{{deviceHost}}:{{devicePort}}/deviceManager/rest/{{deviceSn}}/host?range=%5B0-100%5D&filter=NAME%3A%3A{{hostName|urlencode}}" method: GET validate_certs: no headers: diff --git a/task/storage/oceanstor/delete_lg.yml b/task/storage/oceanstor/delete_lg.yml index 3f67972..bde7f37 100644 --- a/task/storage/oceanstor/delete_lg.yml +++ b/task/storage/oceanstor/delete_lg.yml @@ -30,7 +30,7 @@ set_fact: deletedLg: "{{ lg }}" lgMapped: "{{ lg.ISADD2MAPPINGVIEW == 'true' }}" - lgReplicaNum: "{{ lg.cdpGroupNum|int + lg.cloneGroupNum|int + lg.replicationGroupNum|int + lg.snapshotGroupNum|int + lg.drStarNum|int + lg.hyperMetroGroupNum|int}}" + lgReplicaNum: "{{ lg.cloneGroupNum|int + lg.replicationGroupNum|int + lg.snapshotGroupNum|int + lg.drStarNum|int + lg.hyperMetroGroupNum|int}}" when: lgName|default(none) is not none @@ -54,7 +54,7 @@ set_fact: deletedLg: "{{ lg }}" lgMapped: "{{ lg.ISADD2MAPPINGVIEW == 'true' }}" - lgReplicaNum: "{{ lg.cdpGroupNum|int + lg.cloneGroupNum|int + lg.replicationGroupNum|int + lg.snapshotGroupNum|int + lg.drStarNum|int + lg.hyperMetroGroupNum|int}}" + lgReplicaNum: "{{ lg.cloneGroupNum|int + lg.replicationGroupNum|int + lg.snapshotGroupNum|int + lg.drStarNum|int + lg.hyperMetroGroupNum|int}}" when: lgId|default(none) is not none diff --git a/task/storage/oceanstor/delete_luns.yml b/task/storage/oceanstor/delete_luns.yml index 1eebb98..f26d8ae 100644 --- a/task/storage/oceanstor/delete_luns.yml +++ b/task/storage/oceanstor/delete_luns.yml @@ -14,7 +14,7 @@ - name: Query LUNs by Name uri: - url: "https://{{deviceHost}}:{{devicePort}}/deviceManager/rest/{{deviceSn}}/lun?filter=NAME%3A%3A{{item|urlencode}}" + url: "https://{{deviceHost}}:{{devicePort}}/deviceManager/rest/{{deviceSn}}/lun?range=%5B0-100%5D&filter=NAME%3A%3A{{item|urlencode}}" method: GET validate_certs: no headers: @@ -53,7 +53,7 @@ - name: Query Snapshots uri: - url: "https://{{deviceHost}}:{{devicePort}}/deviceManager/rest/{{deviceSn}}/SNAPSHOT?filter=PARENTNAME::{{item}}" + url: "https://{{deviceHost}}:{{devicePort}}/deviceManager/rest/{{deviceSn}}/SNAPSHOT?range=%5B0-100%5D&filter=PARENTNAME::{{item}}" method: GET validate_certs: no headers: diff --git a/task/storage/oceanstor/delete_snapshots.yml b/task/storage/oceanstor/delete_snapshots.yml index a2db2f9..1bb3c4f 100644 --- a/task/storage/oceanstor/delete_snapshots.yml +++ b/task/storage/oceanstor/delete_snapshots.yml @@ -8,7 +8,7 @@ - block: - name: Query Snapshots uri: - url: "https://{{deviceHost}}:{{devicePort}}/deviceManager/rest/{{deviceSn}}/SNAPSHOT?filter=NAME%3A%3A{{item|urlencode}}" + url: "https://{{deviceHost}}:{{devicePort}}/deviceManager/rest/{{deviceSn}}/SNAPSHOT?range=%5B0-100%5D&filter=NAME%3A%3A{{item|urlencode}}" method: GET validate_certs: no headers: diff --git a/task/storage/oceanstor/enable_drstar.yml b/task/storage/oceanstor/enable_drstar.yml index 6bf93d8..8a51d8c 100644 --- a/task/storage/oceanstor/enable_drstar.yml +++ b/task/storage/oceanstor/enable_drstar.yml @@ -38,4 +38,8 @@ - name: Check Enable DR Star Result debug: msg: "{{ ENABLE_DRSTAR.json.error }}" - failed_when: (ENABLE_DRSTAR.json.error.code|int !=0) \ No newline at end of file + failed_when: (ENABLE_DRSTAR.json.error.code|int !=0) + +- name: Wait a replication cycle + pause: + seconds: "{{GLOBAL.replication.interval}}" \ No newline at end of file diff --git a/task/storage/oceanstor/get_lgs_by_host.yml b/task/storage/oceanstor/get_lgs_by_host.yml new file mode 100644 index 0000000..47ce504 --- /dev/null +++ b/task/storage/oceanstor/get_lgs_by_host.yml @@ -0,0 +1,52 @@ +# Get LUN Groups by Host +# +# Required parameters: +# hostName: # Host Name, can be replaced with hostId +# +# Optional parameters: +# hostId: # Host ID +# +# Generated variables: +# checkedLgs: # Checked LUN groups associate with host + +- set_fact: + checkedLgs: "{{ none }}" + +- block: + - name: Query Host by Name + uri: + url: "https://{{deviceHost}}:{{devicePort}}/deviceManager/rest/{{deviceSn}}/host?range=%5B0-100%5D&filter=NAME%3A%3A{{hostName|urlencode}}" + method: GET + validate_certs: no + headers: + Accept: "application/json" + Content-Type: "application/json;charset=utf8" + iBaseToken: "{{ deviceToken }}" + Cookie: "session={{ deviceSession }}" + register: HOST + + - name: Get Host ID + vars: + host: "{{ HOST.json.data[0] }} " + set_fact: + hostId: "{{ host.ID }}" + failed_when: ('data' not in HOST.json) or (HOST.json.data|length != 1) + + when: hostName|default(none) is not none + + +- name: Get LUN Groups by Host ID + uri: + url: "https://{{deviceHost}}:{{devicePort}}/deviceManager/rest/{{deviceSn}}/mapping/associate?ASSOCIATEOBJTYPE=21&ASSOCIATEOBJID={{hostId}}" + method: GET + validate_certs: no + headers: + Accept: "application/json" + Content-Type: "application/json;charset=utf8" + iBaseToken: "{{ deviceToken }}" + Cookie: "session={{ deviceSession }}" + register: DETAIL + failed_when: (DETAIL.json.error.code != 0) or ('data' not in DETAIL.json ) + +- set_fact: + checkedLgs: "{{ DETAIL.json.data }}" \ No newline at end of file diff --git a/task/storage/oceanstor/get_luns_by_pg.yml b/task/storage/oceanstor/get_luns_by_pg.yml new file mode 100644 index 0000000..f0e85e8 --- /dev/null +++ b/task/storage/oceanstor/get_luns_by_pg.yml @@ -0,0 +1,52 @@ +# Get LUNs by Protection Group +# +# Required parameters: +# pgName: # Protection Group Name, can be replaced with pgId +# +# Optional parameters: +# pgId: # Protection Group ID +# +# Generated variables: +# checkedLuns: # Checked LUNs associate with protection group + +- set_fact: + checkedLuns: "{{ none }}" + +- block: + - name: Query PG by Name + uri: + url: "https://{{deviceHost}}:{{devicePort}}/deviceManager/rest/{{deviceSn}}/protectgroup?filter=protectGroupName%3A%3A{{pgName|urlencode}}" + method: GET + validate_certs: no + headers: + Accept: "application/json" + Content-Type: "application/json;charset=utf8" + iBaseToken: "{{ deviceToken }}" + Cookie: "session={{ deviceSession }}" + register: PG + + - name: Get PG ID + vars: + queryPgIds: "[? protectGroupName=='{{pgName}}'].protectGroupId" + pgIds: "{{ PG.json.data | default([]) | json_query(queryPgIds) }}" + set_fact: + pgId: "{{ pgIds | first }}" + failed_when: pgIds | length != 1 + + when: pgName|default(none) is not none + +- name: Get LUN by PG ID + uri: + url: "https://{{deviceHost}}:{{devicePort}}/deviceManager/rest/{{deviceSn}}/lun/associate?ASSOCIATEOBJTYPE=57846&ASSOCIATEOBJID={{pgId}}" + method: GET + validate_certs: no + headers: + Accept: "application/json" + Content-Type: "application/json;charset=utf8" + iBaseToken: "{{ deviceToken }}" + Cookie: "session={{ deviceSession }}" + register: DETAIL + failed_when: (DETAIL.json.error.code != 0) or ('data' not in DETAIL.json ) + +- set_fact: + checkedLuns: "{{ DETAIL.json.data }}" \ No newline at end of file diff --git a/task/storage/oceanstor/get_replication_cgs_by_pg.yml b/task/storage/oceanstor/get_replication_cgs_by_pg.yml new file mode 100644 index 0000000..d6893a8 --- /dev/null +++ b/task/storage/oceanstor/get_replication_cgs_by_pg.yml @@ -0,0 +1,54 @@ +# Get LUNs by Protection Group +# +# Required parameters: +# pgName: # Protection Group Name, can be replaced with pgId +# +# Optional parameters: +# pgId: # Protection Group ID +# +# Generated variables: +# checkedRepCgs: # Checked Replication CGs associate with protection group + +- set_fact: + checkedRepCgs: "{{ none }}" + +- block: + - name: Query PG by Name + uri: + url: "https://{{deviceHost}}:{{devicePort}}/deviceManager/rest/{{deviceSn}}/protectgroup?filter=protectGroupName%3A%3A{{pgName|urlencode}}" + method: GET + validate_certs: no + headers: + Accept: "application/json" + Content-Type: "application/json;charset=utf8" + iBaseToken: "{{ deviceToken }}" + Cookie: "session={{ deviceSession }}" + register: PG + + - name: Get PG ID + vars: + queryPgIds: "[? protectGroupName=='{{pgName}}'].protectGroupId" + pgIds: "{{ PG.json.data | default([]) | json_query(queryPgIds) }}" + set_fact: + pgId: "{{ pgIds | first }}" + failed_when: pgIds | length != 1 + + when: pgName|default(none) is not none + +- name: Get Replication CGs Associate with Protection Group + uri: + url: "https://{{deviceHost}}:{{devicePort}}/deviceManager/rest/{{deviceSn}}/CONSISTENTGROUP?filter=localpgId%3A%3A{{pgId}}" + method: GET + validate_certs: no + headers: + Accept: "application/json" + Content-Type: "application/json;charset=utf8" + iBaseToken: "{{ deviceToken }}" + Cookie: "session={{ deviceSession }}" + register: RCGs + failed_when: (RCGs.json.error.code != 0) or ('data' not in RCGs.json ) + +- name: Get Replication CG IDs + set_fact: + cgIds: "{{ RCGs.json.data | json_query('[*].ID') }}" + checkedRepCgs: "{{ RCGs.json.data }}" diff --git a/task/storage/oceanstor/get_replication_cgs_by_pg_loop_helper.yml b/task/storage/oceanstor/get_replication_cgs_by_pg_loop_helper.yml new file mode 100644 index 0000000..8b6a329 --- /dev/null +++ b/task/storage/oceanstor/get_replication_cgs_by_pg_loop_helper.yml @@ -0,0 +1,14 @@ +# Get Replication CGs by Protection Group Loop Helper, cooperator with nested loop +# +# Required parameters: +# pgName: # Protection Group Name, can be replaced with pgId +# +# Optional parameters: +# pgId: # Protection Group ID +# +# Generated variables: +# checkedPgRepCgs: # Checked Replication CGs associate with protection groups, need clean before used. + +- import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/get_replication_cgs_by_pg.yml" +- set_fact: + checkedPgRepCgs: "{{ checkedPgRepCgs + [checkedRepCgs] }}" diff --git a/task/storage/oceanstor/get_snapshot_cgs_by_pg.yml b/task/storage/oceanstor/get_snapshot_cgs_by_pg.yml new file mode 100644 index 0000000..2feb6eb --- /dev/null +++ b/task/storage/oceanstor/get_snapshot_cgs_by_pg.yml @@ -0,0 +1,58 @@ +# Get LUNs by Protection Group +# +# Required parameters: +# pgName: # Protection Group Name, can be replaced with pgId +# +# Optional parameters: +# pgId: # Protection Group ID +# ignoreEmpty: # Ignore error when got empty snapshot cgs. +# +# Generated variables: +# checkedSnapCgs: # Checked Snapshot CGs associate with protection group + +- set_fact: + checkedSnapCgs: [] + cgIds: [] + +- block: + - name: Query PG by Name + uri: + url: "https://{{deviceHost}}:{{devicePort}}/deviceManager/rest/{{deviceSn}}/protectgroup?filter=protectGroupName%3A%3A{{pgName|urlencode}}" + method: GET + validate_certs: no + headers: + Accept: "application/json" + Content-Type: "application/json;charset=utf8" + iBaseToken: "{{ deviceToken }}" + Cookie: "session={{ deviceSession }}" + register: PG + + - name: Get PG ID + vars: + queryPgIds: "[? protectGroupName=='{{pgName}}'].protectGroupId" + pgIds: "{{ PG.json.data | default([]) | json_query(queryPgIds) }}" + set_fact: + pgId: "{{ pgIds | first }}" + failed_when: pgIds | length != 1 + + when: pgName|default(none) is not none + +- name: Query Snapshot CGs Associate with Protection Group + uri: + url: "https://{{deviceHost}}:{{devicePort}}/deviceManager/rest/{{deviceSn}}/snapshot_consistency_group/associate?ASSOCIATEOBJTYPE=57846&ASSOCIATEOBJID={{pgId}}" + method: GET + validate_certs: no + headers: + Accept: "application/json" + Content-Type: "application/json;charset=utf8" + iBaseToken: "{{ deviceToken }}" + Cookie: "session={{ deviceSession }}" + register: SCGs + failed_when: (SCGs.json.error.code != 0) or (not ignoreEmpty|default(false) and 'data' not in SCGs.json ) + + +- name: Get Snapshot CG IDs + set_fact: + cgIds: "{{ SCGs.json.data | json_query('[*].ID') }}" + checkedSnapCgs: "{{ SCGs.json.data }}" + when: ( 'data' in SCGs.json ) \ No newline at end of file diff --git a/task/storage/oceanstor/get_snapshot_cgs_by_pg_loop_helper.yml b/task/storage/oceanstor/get_snapshot_cgs_by_pg_loop_helper.yml new file mode 100644 index 0000000..205ed35 --- /dev/null +++ b/task/storage/oceanstor/get_snapshot_cgs_by_pg_loop_helper.yml @@ -0,0 +1,16 @@ +# Get Snapshot CGs by Protection Group Loop Helper, cooperator with nested loop +# +# Required parameters: +# pgName: # Protection Group Name, can be replaced with pgId +# +# Optional parameters: +# pgId: # Protection Group ID +# ignoreEmpty: # Ignore error when got empty snapshot cgs. +# +# Generated variables: +# checkedPgSnapCgs: # Checked Snapshot CGs associate with protection groups, need clean before used. + +- import_tasks: "{{GLOBAL.baseDir}}/task/storage/oceanstor/get_snapshot_cgs_by_pg.yml" +- set_fact: + checkedPgSnapCgs: "{{ checkedPgSnapCgs + [checkedSnapCgs] }}" + when: (checkedSnapCgs|length > 0) diff --git a/task/storage/oceanstor/get_snapshots_by_cg.yml b/task/storage/oceanstor/get_snapshots_by_cg.yml new file mode 100644 index 0000000..6b5d154 --- /dev/null +++ b/task/storage/oceanstor/get_snapshots_by_cg.yml @@ -0,0 +1,50 @@ +# Get Snapshots by Snapshot Consistent Group +# +# Required parameters: +# cgName: # Snapshot Consistent Group Name, can be replaced with cgId +# +# Optional parameters: +# cgId: # Snapshot Consistent Group ID +# +# Generated variables: +# checkedSnapshots: # Checked Snapshots associate with snapshot consistent group + +- set_fact: + checkedSnapshots: "{{ none }}" + +- block: + - name: Query Snapshot CG by Name + uri: + url: "https://{{deviceHost}}:{{devicePort}}/deviceManager/rest/{{deviceSn}}/SNAPSHOT_CONSISTENCY_GROUP?filter=NAME%3A%3A{{cgName|urlencode}}" + method: GET + validate_certs: no + headers: + Accept: "application/json" + Content-Type: "application/json;charset=utf8" + iBaseToken: "{{ deviceToken }}" + Cookie: "session={{ deviceSession }}" + register: SCGs + + - name: Get CG ID + vars: + scg: "{{ SCGs.json.data[0] }} " + set_fact: + cgId: "{{ scg.ID }}" + failed_when: ('data' not in SCGs.json) or (SCGs.json.data|length != 1) + + when: cgName|default(none) is not none + +- name: Get Snapshots by CG ID + uri: + url: "https://{{deviceHost}}:{{devicePort}}/deviceManager/rest/{{deviceSn}}/snapshot/associate?ASSOCIATEOBJTYPE=57646&ASSOCIATEOBJID={{cgId}}" + method: GET + validate_certs: no + headers: + Accept: "application/json" + Content-Type: "application/json;charset=utf8" + iBaseToken: "{{ deviceToken }}" + Cookie: "session={{ deviceSession }}" + register: SNAPSHOTS + +- set_fact: + checkedSnapshots: "{{ SNAPSHOTS.json.data }}" diff --git a/task/storage/oceanstor/map_luns_to_host.yml b/task/storage/oceanstor/map_luns_to_host.yml index e01b3bc..6ce56e3 100644 --- a/task/storage/oceanstor/map_luns_to_host.yml +++ b/task/storage/oceanstor/map_luns_to_host.yml @@ -17,7 +17,7 @@ - name: Query LUNs by Name uri: - url: "https://{{deviceHost}}:{{devicePort}}/deviceManager/rest/{{deviceSn}}/lun?filter=NAME%3A%3A{{item|urlencode}}" + url: "https://{{deviceHost}}:{{devicePort}}/deviceManager/rest/{{deviceSn}}/lun?range=%5B0-100%5D&filter=NAME%3A%3A{{item|urlencode}}" method: GET validate_certs: no headers: @@ -57,7 +57,7 @@ - name: Query Host by Name uri: - url: "https://{{deviceHost}}:{{devicePort}}/deviceManager/rest/{{deviceSn}}/host?filter=NAME%3A%3A{{hostName|urlencode}}" + url: "https://{{deviceHost}}:{{devicePort}}/deviceManager/rest/{{deviceSn}}/host?range=%5B0-100%5D&filter=NAME%3A%3A{{hostName|urlencode}}" method: GET validate_certs: no headers: diff --git a/task/storage/oceanstor/map_luns_to_hostgroup.yml b/task/storage/oceanstor/map_luns_to_hostgroup.yml index 804af26..f3a038a 100644 --- a/task/storage/oceanstor/map_luns_to_hostgroup.yml +++ b/task/storage/oceanstor/map_luns_to_hostgroup.yml @@ -18,7 +18,7 @@ - name: Query LUNs by Name uri: - url: "https://{{deviceHost}}:{{devicePort}}/deviceManager/rest/{{deviceSn}}/lun?filter=NAME%3A%3A{{item|urlencode}}" + url: "https://{{deviceHost}}:{{devicePort}}/deviceManager/rest/{{deviceSn}}/lun?range=%5B0-100%5D&filter=NAME%3A%3A{{item|urlencode}}" method: GET validate_certs: no headers: @@ -58,7 +58,7 @@ - name: Query Host by Name uri: - url: "https://{{deviceHost}}:{{devicePort}}/deviceManager/rest/{{deviceSn}}/host?filter=NAME%3A%3A{{hostName|urlencode}}" + url: "https://{{deviceHost}}:{{devicePort}}/deviceManager/rest/{{deviceSn}}/host?range=%5B0-100%5D&filter=NAME%3A%3A{{hostName|urlencode}}" method: GET validate_certs: no headers: diff --git a/task/storage/oceanstor/modify_host.yml b/task/storage/oceanstor/modify_host.yml index 1d50e5c..2d86d6f 100644 --- a/task/storage/oceanstor/modify_host.yml +++ b/task/storage/oceanstor/modify_host.yml @@ -13,7 +13,7 @@ - name: Query Host by Name uri: - url: "https://{{deviceHost}}:{{devicePort}}/deviceManager/rest/{{deviceSn}}/host?filter=NAME%3A%3A{{hostName|urlencode}}" + url: "https://{{deviceHost}}:{{devicePort}}/deviceManager/rest/{{deviceSn}}/host?range=%5B0-100%5D&filter=NAME%3A%3A{{hostName|urlencode}}" method: GET validate_certs: no headers: diff --git a/task/storage/oceanstor/modify_lun.yml b/task/storage/oceanstor/modify_lun.yml index 61efecd..8f48921 100644 --- a/task/storage/oceanstor/modify_lun.yml +++ b/task/storage/oceanstor/modify_lun.yml @@ -13,7 +13,7 @@ - block: - name: Query LUN by Name uri: - url: "https://{{deviceHost}}:{{devicePort}}/deviceManager/rest/{{deviceSn}}/lun?filter=NAME%3A%3A{{lunName|urlencode}}" + url: "https://{{deviceHost}}:{{devicePort}}/deviceManager/rest/{{deviceSn}}/lun?range=%5B0-100%5D&filter=NAME%3A%3A{{lunName|urlencode}}" method: GET validate_certs: no headers: diff --git a/task/storage/oceanstor/remove_luns_from_clone_cg.yml b/task/storage/oceanstor/remove_luns_from_clone_cg.yml index 5759b83..b1c7168 100644 --- a/task/storage/oceanstor/remove_luns_from_clone_cg.yml +++ b/task/storage/oceanstor/remove_luns_from_clone_cg.yml @@ -37,7 +37,7 @@ - name: Query LUNs by Name uri: - url: "https://{{deviceHost}}:{{devicePort}}/deviceManager/rest/{{deviceSn}}/lun?filter=NAME%3A%3A{{item|urlencode}}" + url: "https://{{deviceHost}}:{{devicePort}}/deviceManager/rest/{{deviceSn}}/lun?range=%5B0-100%5D&filter=NAME%3A%3A{{item|urlencode}}" method: GET validate_certs: no headers: diff --git a/task/storage/oceanstor/remove_luns_from_lg.yml b/task/storage/oceanstor/remove_luns_from_lg.yml index 5d89cb0..5790768 100644 --- a/task/storage/oceanstor/remove_luns_from_lg.yml +++ b/task/storage/oceanstor/remove_luns_from_lg.yml @@ -31,7 +31,7 @@ - name: Query LUNs by Name uri: - url: "https://{{deviceHost}}:{{devicePort}}/deviceManager/rest/{{deviceSn}}/lun?filter=NAME%3A%3A{{item|urlencode}}" + url: "https://{{deviceHost}}:{{devicePort}}/deviceManager/rest/{{deviceSn}}/lun?range=%5B0-100%5D&filter=NAME%3A%3A{{item|urlencode}}" method: GET validate_certs: no headers: diff --git a/task/storage/oceanstor/remove_luns_from_pg.yml b/task/storage/oceanstor/remove_luns_from_pg.yml index 87437d3..d6e9e93 100644 --- a/task/storage/oceanstor/remove_luns_from_pg.yml +++ b/task/storage/oceanstor/remove_luns_from_pg.yml @@ -28,7 +28,7 @@ - block: - name: Query LUNs by Name uri: - url: "https://{{deviceHost}}:{{devicePort}}/deviceManager/rest/{{deviceSn}}/lun?filter=NAME%3A%3A{{item|urlencode}}" + url: "https://{{deviceHost}}:{{devicePort}}/deviceManager/rest/{{deviceSn}}/lun?range=%5B0-100%5D&filter=NAME%3A%3A{{item|urlencode}}" method: GET validate_certs: no headers: @@ -53,6 +53,7 @@ debug: msg: removeLunIds: "{{ removeLunIds }}" + lunNames: "{{ lunNames }}" failed_when: removeLunIds|length != lunNames|length when: - lunNames|default(none) is not none diff --git a/task/storage/oceanstor/remove_ports_from_host.yml b/task/storage/oceanstor/remove_ports_from_host.yml index a547b8e..e1d69ec 100644 --- a/task/storage/oceanstor/remove_ports_from_host.yml +++ b/task/storage/oceanstor/remove_ports_from_host.yml @@ -30,7 +30,7 @@ - name: Query Host by Name uri: - url: "https://{{deviceHost}}:{{devicePort}}/deviceManager/rest/{{deviceSn}}/host?filter=NAME%3A%3A{{hostName|urlencode}}" + url: "https://{{deviceHost}}:{{devicePort}}/deviceManager/rest/{{deviceSn}}/host?range=%5B0-100%5D&filter=NAME%3A%3A{{hostName|urlencode}}" method: GET validate_certs: no headers: diff --git a/task/storage/oceanstor/unmap_luns_from_host.yml b/task/storage/oceanstor/unmap_luns_from_host.yml index 9e180e0..ce60d7b 100644 --- a/task/storage/oceanstor/unmap_luns_from_host.yml +++ b/task/storage/oceanstor/unmap_luns_from_host.yml @@ -7,7 +7,7 @@ - name: Query Host by Name uri: - url: "https://{{deviceHost}}:{{devicePort}}/deviceManager/rest/{{deviceSn}}/host?filter=NAME%3A%3A{{hostName|urlencode}}" + url: "https://{{deviceHost}}:{{devicePort}}/deviceManager/rest/{{deviceSn}}/host?range=%5B0-100%5D&filter=NAME%3A%3A{{hostName|urlencode}}" method: GET validate_certs: no headers: @@ -48,7 +48,7 @@ - name: Query LUNs by Name uri: - url: "https://{{deviceHost}}:{{devicePort}}/deviceManager/rest/{{deviceSn}}/lun?filter=NAME%3A%3A{{item|urlencode}}" + url: "https://{{deviceHost}}:{{devicePort}}/deviceManager/rest/{{deviceSn}}/lun?range=%5B0-100%5D&filter=NAME%3A%3A{{item|urlencode}}" method: GET validate_certs: no headers: diff --git a/task/task/wait_task_complete.yml b/task/task/wait_task_complete.yml index 6bd5433..3375738 100644 --- a/task/task/wait_task_complete.yml +++ b/task/task/wait_task_complete.yml @@ -8,7 +8,7 @@ - name: Set default variables set_fact: - statusMap: { '1': 'Not Start', '2': 'Running', '3': 'Succeeded', '4': 'Partially Succeeded', '5': 'Failed', '6': 'Timeout'} + statusMap: { '1': 'Not Start', '2': 'Running', '3': 'Succeeded', '4': 'Partially Succeeded', '5': 'Failed', '6': 'Timeout', '7': 'Warning'} - name: Wait Task Complete uri: @@ -34,7 +34,7 @@ name: "{{task.name_en}}" sequence: "{{task.seq_no}}" progress: "{{task.progress}}" - status: "{{statusMap[task.status|string]}}" + status: "{{statusMap[task.status|string]|default('Unknown')}}" with_sequence: start=0 count="{{TASKS.json|length}}" - name: Task Result @@ -43,14 +43,14 @@ status: "{{ TASKS.json | json_query(queryStatus) | first }}" debug: msg: - Result: "{{statusMap[status]}}" + Result: "{{statusMap[status]|default('Unknown')}}" - name: Check Task Success vars: query: "[?id=='{{ taskId }}'].status" status: "{{ TASKS.json | json_query(query) | first }}" debug: - msg: - Result: "{{statusMap[status]}}" - failed_when: status|int != 3 + msg: + Result: "{{statusMap[status]|default('Unknown')}}" + failed_when: status|int != 3 and status|int != 7 when: checkSuccess|default(True)|bool == True diff --git a/task/util/csv2xml.py b/task/util/csv2xml.py new file mode 100644 index 0000000..f4a836a --- /dev/null +++ b/task/util/csv2xml.py @@ -0,0 +1,50 @@ +#!/usr/bin/python +# -*- encoding:utf-8 -*- + +# Required parameters: +# csv: CSV file to read in +# xml: XML file to export to +# +# Optional parameters: +# sep: separator, default ',' +# keys: keys to export, default '' (all) +# root: root node name, default 'rows' +# item: item node name, default 'row' + +import ast +import csv +import argparse + +def parse_args(): + parser = argparse.ArgumentParser() + parser.add_argument('-c', '--csv', type=str, required=True, help='CSV file to read') + parser.add_argument('-x', '--xml', type=str, required=True, help='XML file to export to') + parser.add_argument('-s', '--sep', type=str, required=False, default=',', help='Separator, default: ","') + parser.add_argument('-k', '--keys', type=str, required=False, default='', help='Keys to export, comma separate, default: "" (all)') + parser.add_argument('-r', '--root', type=str, required=False, default='rows', help='root node name, default: "rows"') + parser.add_argument('-i', '--item', type=str, required=False, default='row', help='item node name, default: "row"') + return parser.parse_args() + +if __name__ == '__main__': + args = parse_args() + xml_file = open(args.xml, mode='w') + csv_file = open(args.csv, mode='r') + csv_reader = csv.DictReader(csv_file, delimiter = args.sep) + + if args.keys == '': + keys = csv_reader.fieldnames + else: + keys = args.keys.split(',') + + xml_file.write('' + "\n") + xml_file.write("<{}>\n".format(args.root)) + for row in csv_reader: + item = '<{}'.format(args.item) + for key in keys: + if key in row: + item += ' {}="{}"'.format(key, row[key]) + item += "/>\n" + xml_file.write(item) + xml_file.write("".format(args.root)) + + xml_file.close() \ No newline at end of file diff --git a/task/util/csv2xml.yml b/task/util/csv2xml.yml new file mode 100644 index 0000000..8bc87d3 --- /dev/null +++ b/task/util/csv2xml.yml @@ -0,0 +1,12 @@ +# Required parameters: +# csv: CSV file to read in +# xml: XML file to export to +# +# Optional parameters: +# sep: separator, default ',' +# keys: keys to export, default '' (all) +# root: root node name, default 'rows' +# item: item node name, default 'row' + +- name: Export to {{file}} + local_action: command python "{{GLOBAL.baseDir}}"/task/util/csv2xml.py -c "{{csv}}" -x "{{xml}}" -s "{{ sep | default('|') }}" -k "{{keys | default('')}}" -r "{{root | default('rows')}} -i "{{item | default('row')}}" diff --git a/task/volume/remove_volumes_from_tier.yml b/task/volume/remove_volumes_from_tier.yml index aa7f722..07de123 100644 --- a/task/volume/remove_volumes_from_tier.yml +++ b/task/volume/remove_volumes_from_tier.yml @@ -37,6 +37,7 @@ debug: msg: volumeIds: "{{ volumeIds }}" + volumeNames: "{{ volumeNames }}" failed_when: volumeIds|length < volumeNames|length when: - volumeNames is defined