From 38c8a5001fe08683910e42fc02b2aa3226dfc9c2 Mon Sep 17 00:00:00 2001 From: xs2suruchi Date: Fri, 2 Aug 2024 22:38:56 +0530 Subject: [PATCH 01/34] Automation Toolkit Release v2024.4.0 --- OCIWorkVMStack/scripts/installToolkit.sh | 2 +- .../create_terraform_dedicatedhosts.py | 3 - .../Compute/create_terraform_instances.py | 48 +- .../export_dedicatedvmhosts_nonGreenField.py | 53 +- .../Compute/export_instances_nonGreenField.py | 59 +- .../Budget/create_terraform_budget.py | 8 +- .../Budget/export_budgets_nonGreenField.py | 39 +- .../Database/create_terraform_adb.py | 46 +- .../create_terraform_dbsystems_vm_bm.py | 50 +- .../create_terraform_exa_vmclusters.py | 81 ++- .../Database/export_adb_nonGreenField.py | 63 +- .../export_dbsystems_vm_bm_nonGreenField.py | 59 +- .../export_exa_infra_nonGreenField.py | 48 +- .../export_exa_vmclusters_nonGreenField.py | 70 +- .../OKE/create_terraform_oke.py | 255 ++++---- .../OKE/export_oke_nonGreenField.py | 123 ++-- .../create_resource_manager_stack.py | 25 +- cd3_automation_toolkit/Excel_Columns | 10 +- .../Quota/create_terraform_quotas.py | 8 +- .../Quota/export_quotas_nonGreenField.py | 33 +- .../Tagging/export_tags_nonGreenField.py | 72 +- .../export_networkSources_nonGreenField.py | 43 +- .../Identity/export_identity_nonGreenField.py | 81 ++- ...port_events_notifications_nonGreenField.py | 108 +-- .../Logging/templates/logging-template | 3 +- .../Monitoring/export_alarms_nonGreenField.py | 46 +- .../export_sch_nonGreenField.py | 43 +- .../Network/BaseNetwork/exportNSG.py | 62 +- .../Network/BaseNetwork/exportRoutetable.py | 99 ++- .../Network/BaseNetwork/exportSeclist.py | 47 +- .../export_network_nonGreenField.py | 299 +++++---- .../Network/DNS/export_dns_resolvers.py | 57 +- .../DNS/export_dns_views_zones_records.py | 66 +- .../Network/Global/create_rpc_resources.py | 10 +- .../Network/LoadBalancers/__init__.py | 1 + .../create_backendset_backendservers.py | 33 +- .../Network/LoadBalancers/create_listener.py | 5 +- .../create_nlb_backendset_backendservers.py | 47 +- .../LoadBalancers/create_path_route_set.py | 5 +- .../LoadBalancers/create_routing_policy.py | 153 +++++ .../Network/LoadBalancers/create_ruleset.py | 5 +- .../create_terraform_lbr_hostname_certs.py | 70 +- .../create_terraform_nlb_listener.py | 52 +- .../LoadBalancers/export_lbr_nonGreenField.py | 619 +++++++++++------- .../LoadBalancers/export_nlb_nonGreenField.py | 104 ++- .../templates/lb-routing-policy-template | 62 ++ cd3_automation_toolkit/OCI_Regions | 3 + cd3_automation_toolkit/Release-Notes | 13 + .../SDDC/create_terraform_sddc.py | 39 +- .../SDDC/export_sddc_nonGreenField.py | 66 +- .../Firewall/export_firewall_nonGreenField.py | 55 +- .../export_firewallpolicy_nonGreenField.py | 278 ++++---- .../Security/Firewall/fw_create.py | 5 +- .../Security/Firewall/fwpolicy_create.py | 7 +- .../Firewall/fwpolicy_create_address.py | 6 +- .../fwpolicy_create_applicationlist.py | 6 +- .../Security/Firewall/fwpolicy_create_apps.py | 6 +- .../fwpolicy_create_decryptionprofile.py | 6 +- .../Firewall/fwpolicy_create_decryptrules.py | 6 +- .../Firewall/fwpolicy_create_secret.py | 6 +- .../Firewall/fwpolicy_create_secrules.py | 6 +- .../Firewall/fwpolicy_create_service.py | 8 +- .../Firewall/fwpolicy_create_servicelist.py | 8 +- .../Firewall/fwpolicy_create_urllist.py | 7 +- .../KeyVault/create_terraform_keyvault.py | 83 --- .../KeyVault/create_terraform_keyvaults.py | 3 - .../export_keyvaults_nonGreenField.py | 42 +- .../create_terraform_block_volumes.py | 6 +- .../export_blockvolumes_nonGreenField.py | 51 +- .../FileSystem/create_terraform_fss.py | 45 +- .../FileSystem/export_fss_nonGreenField.py | 91 ++- .../ObjectStorage/create_terraform_oss.py | 5 + .../ObjectStorage/export_terraform_oss.py | 57 +- cd3_automation_toolkit/commonTools.py | 31 + .../example/CD3-Blank-template.xlsx | Bin 203716 -> 204137 bytes .../example/CD3-CIS-template.xlsx | Bin 267358 -> 268844 bytes .../example/CD3-HubSpoke-template.xlsx | Bin 236627 -> 237838 bytes .../example/CD3-SingleVCN-template.xlsx | Bin 256687 -> 257898 bytes cd3_automation_toolkit/setUpOCI.properties | 3 + cd3_automation_toolkit/setUpOCI.py | 240 +++++-- cd3_automation_toolkit/shell_script.sh | 9 +- .../user-scripts/createTenancyConfig.py | 70 +- .../user-scripts/tenancyconfig.properties | 12 +- .../user-scripts/terraform/loadbalancer.tf | 22 +- .../loadbalancer/lb-routing-policy/main.tf | 27 + .../lb-routing-policy/oracle_provider_req.tf | 7 + .../loadbalancer/lb-routing-policy/outputs.tf | 11 + .../lb-routing-policy/variables.tf | 26 + .../security/cloud-guard-target/data.tf | 15 +- .../modules/storage/file-storage/fss/main.tf | 4 +- .../user-scripts/terraform/network.tf | 7 +- .../user-scripts/terraform/provider.tf | 4 +- .../terraform/variables_example.tf | 323 ++++----- .../{tf-apply.groovy => apply.groovy} | 120 ++-- jenkins_install/destroy.groovy | 176 +++++ jenkins_install/example/jenkins.properties | 2 + jenkins_install/init/01_jenkins-config.groovy | 113 ++-- jenkins_install/init/02_jenkins-view.groovy | 85 ++- jenkins_install/jcasc.yaml | 1 + jenkins_install/jenkins.sh | 54 +- .../scripts/AdditionalFilters.groovy | 87 ++- .../scriptler/scripts/MainOptions.groovy | 2 +- .../scriptler/scripts/SubChildOptions.groovy | 8 +- .../scriptler/scripts/SubOptions.groovy | 4 +- .../scriptler/scripts/ValidateParams.groovy | 4 +- jenkins_install/setUpOCI_config.xml | 53 +- jenkins_install/tf-destroy.groovy | 169 ----- .../cis_reports.py | 562 +++++++--------- othertools/oci-fsdr/commonLib.py | 14 + othertools/oci-fsdr/export_drplan.py | 214 ++++++ .../oci-fsdr/oci-fsdr-plan-template.xlsx | Bin 0 -> 12680 bytes othertools/oci-fsdr/region_file.json | 41 ++ othertools/oci-fsdr/update_drplan.py | 357 ++++++++++ 113 files changed, 4545 insertions(+), 2521 deletions(-) create mode 100755 cd3_automation_toolkit/Network/LoadBalancers/create_routing_policy.py create mode 100755 cd3_automation_toolkit/Network/LoadBalancers/templates/lb-routing-policy-template delete mode 100644 cd3_automation_toolkit/Security/KeyVault/create_terraform_keyvault.py mode change 100755 => 100644 cd3_automation_toolkit/commonTools.py create mode 100755 cd3_automation_toolkit/user-scripts/terraform/modules/loadbalancer/lb-routing-policy/main.tf create mode 100755 cd3_automation_toolkit/user-scripts/terraform/modules/loadbalancer/lb-routing-policy/oracle_provider_req.tf create mode 100755 cd3_automation_toolkit/user-scripts/terraform/modules/loadbalancer/lb-routing-policy/outputs.tf create mode 100755 cd3_automation_toolkit/user-scripts/terraform/modules/loadbalancer/lb-routing-policy/variables.tf rename jenkins_install/{tf-apply.groovy => apply.groovy} (75%) create mode 100644 jenkins_install/destroy.groovy mode change 100755 => 100644 jenkins_install/init/02_jenkins-view.groovy mode change 100755 => 100644 jenkins_install/setUpOCI_config.xml delete mode 100644 jenkins_install/tf-destroy.groovy rename {cd3_automation_toolkit => othertools}/cis_reports.py (94%) create mode 100644 othertools/oci-fsdr/commonLib.py create mode 100644 othertools/oci-fsdr/export_drplan.py create mode 100644 othertools/oci-fsdr/oci-fsdr-plan-template.xlsx create mode 100644 othertools/oci-fsdr/region_file.json create mode 100644 othertools/oci-fsdr/update_drplan.py diff --git a/OCIWorkVMStack/scripts/installToolkit.sh b/OCIWorkVMStack/scripts/installToolkit.sh index 90d4204bf..60c0d45aa 100644 --- a/OCIWorkVMStack/scripts/installToolkit.sh +++ b/OCIWorkVMStack/scripts/installToolkit.sh @@ -66,7 +66,7 @@ fi sudo podman --version >> $logfile 2>&1 echo "***Download Toolkit***" >> $logfile 2>&1 -sudo git clone https://github.com/oracle-devrel/cd3-automation-toolkit.git $toolkit_dir >> $logfile 2>&1 +sudo git clone https://github.com/oracle-devrel/cd3-automation-toolkit.git -b develop $toolkit_dir >> $logfile 2>&1 stop_exec curl -H "Authorization: Bearer Oracle" -L http://169.254.169.254/opc/v2/instance/ -o /tmp/metadata.json diff --git a/cd3_automation_toolkit/Compute/create_terraform_dedicatedhosts.py b/cd3_automation_toolkit/Compute/create_terraform_dedicatedhosts.py index c81368660..95b04ba64 100644 --- a/cd3_automation_toolkit/Compute/create_terraform_dedicatedhosts.py +++ b/cd3_automation_toolkit/Compute/create_terraform_dedicatedhosts.py @@ -130,9 +130,6 @@ def create_terraform_dedicatedhosts(inputfile, outdir, service_dir,prefix, ct): tfStr[reg] = template.render(count=0, region=reg).replace(src, tfStr[reg] + "\n" + src) tfStr[reg] = "".join([s for s in tfStr[reg].strip().splitlines(True) if s.strip("\r\n").strip()]) - resource = sheetName.lower() - commonTools.backup_file(reg_out_dir + "/", resource, auto_tfvars_filename) - # Write to TF file outfile = reg_out_dir + "/" + auto_tfvars_filename tfStr[reg] = "".join([s for s in tfStr[reg].strip().splitlines(True) if s.strip("\r\n").strip()]) diff --git a/cd3_automation_toolkit/Compute/create_terraform_instances.py b/cd3_automation_toolkit/Compute/create_terraform_instances.py index 837341b9b..410c36407 100755 --- a/cd3_automation_toolkit/Compute/create_terraform_instances.py +++ b/cd3_automation_toolkit/Compute/create_terraform_instances.py @@ -53,7 +53,7 @@ def create_terraform_instances(inputfile, outdir, service_dir, prefix, ct): tfStr[eachregion] = '' boot_policy_tfStr[eachregion] = '' - subnets = parseSubnets(filename) + #subnets = parseSubnets(filename) for i in df.index: region = str(df.loc[i, 'Region']) @@ -93,9 +93,9 @@ def create_terraform_instances(inputfile, outdir, service_dir, prefix, ct): df.loc[i, 'Shape']).lower() == 'nan' or str(df.loc[i, 'Compartment Name']).lower() == 'nan' or str( df.loc[i, 'Pub Address']).lower() == 'nan' or str( df.loc[i, 'Availability Domain(AD1|AD2|AD3)']).lower() == 'nan' or str( - df.loc[i, 'Subnet Name']).lower() == 'nan' or str(df.loc[i, 'Source Details']).lower() == 'nan'): + df.loc[i, 'Network Details']).lower() == 'nan' or str(df.loc[i, 'Source Details']).lower() == 'nan'): print( - "\nOne/All of the Column/Columns from Region, Shape, Compartment Name, Availability Domain, Display Name, Pub Address, Source Details and Subnet Name is empty in Instances sheet of CD3..exiting...Please check.") + "\nOne/All of the Column/Columns from Region, Shape, Compartment Name, Availability Domain, Display Name, Pub Address, Source Details and Network Details is empty in Instances sheet of CD3..exiting...Please check.") exit(1) # Perform the plugin match @@ -137,25 +137,30 @@ def create_terraform_instances(inputfile, outdir, service_dir, prefix, ct): columnvalue = columnvalue.strip() tempdict = {'shape': [columnvalue]} - if columnname == "Subnet Name": - subnet_tf_name = columnvalue.strip() - if ("ocid1.subnet.oc1" in subnet_tf_name): - network_compartment_id = "" + subnet_id = '' + network_compartment_id = '' + vcn_name = '' + if columnname == "Network Details": + columnvalue = columnvalue.strip() + if ("ocid1.subnet.oc" in columnvalue): + network_compartment_id = "root" vcn_name = "" - subnet_id = subnet_tf_name - else: - try: - key = region, subnet_tf_name - network_compartment_id = subnets.vcn_subnet_map[key][0] - vcn_name = subnets.vcn_subnet_map[key][1] - subnet_id = subnets.vcn_subnet_map[key][2] - except Exception as e: - print("Invalid Subnet Name specified for row " + str( - i + 3) + ". It Doesnt exist in Subnets sheet. Exiting!!!") + subnet_id = columnvalue + elif columnvalue.lower() != 'nan' and columnvalue.lower() != '': + if len(columnvalue.split("@")) == 2: + network_compartment_id = commonTools.check_tf_variable(columnvalue.split("@")[0].strip()) + vcn_subnet_name = columnvalue.split("@")[1].strip() + else: + network_compartment_id = commonTools.check_tf_variable( + str(df.loc[i, 'Compartment Name']).strip()) + vcn_subnet_name = columnvalue + if ("::" not in vcn_subnet_name): + print("Invalid Network Details format specified for row " + str(i + 3) + ". Exiting!!!") exit(1) - - tempdict = {'network_compartment_id': commonTools.check_tf_variable(network_compartment_id), - 'vcn_name': vcn_name, + else: + vcn_name = vcn_subnet_name.split("::")[0].strip() + subnet_id = vcn_subnet_name.split("::")[1].strip() + tempdict = {'network_compartment_id': network_compartment_id, 'vcn_name': vcn_name, 'subnet_id': subnet_id} if columnname == 'Display Name': @@ -255,9 +260,6 @@ def create_terraform_instances(inputfile, outdir, service_dir, prefix, ct): tfStr[reg] = template.render(count=0, region=reg).replace(src, tfStr[reg] + "\n" + src) tfStr[reg] = "".join([s for s in tfStr[reg].strip().splitlines(True) if s.strip("\r\n").strip()]) - resource = sheetName.lower() - commonTools.backup_file(reg_out_dir + "/", resource, auto_tfvars_filename) - # Write to TF file outfile = reg_out_dir + "/" + auto_tfvars_filename tfStr[reg] = "".join([s for s in tfStr[reg].strip().splitlines(True) if s.strip("\r\n").strip()]) diff --git a/cd3_automation_toolkit/Compute/export_dedicatedvmhosts_nonGreenField.py b/cd3_automation_toolkit/Compute/export_dedicatedvmhosts_nonGreenField.py index 43b9c3e0b..7464ee5e6 100644 --- a/cd3_automation_toolkit/Compute/export_dedicatedvmhosts_nonGreenField.py +++ b/cd3_automation_toolkit/Compute/export_dedicatedvmhosts_nonGreenField.py @@ -10,6 +10,7 @@ import oci import os +import subprocess as sp from oci.config import DEFAULT_LOCATION from commonTools import * @@ -18,9 +19,11 @@ oci_obj_names = {} -def print_dedicatedvmhosts(region, dedicatedvmhost, values_for_column, ntk_compartment_name): +def print_dedicatedvmhosts(region, dedicatedvmhost, values_for_column, ntk_compartment_name,state): dedicatedvmhost_tf_name = commonTools.check_tf_variable(dedicatedvmhost.display_name) - importCommands[region.lower()].write("\nterraform import \"module.dedicated-hosts[\\\"" +dedicatedvmhost_tf_name+ "\\\"].oci_core_dedicated_vm_host.dedicated_vm_host\" " + str(dedicatedvmhost.id)) + tf_resource = f'module.dedicated-hosts[\\"{dedicatedvmhost_tf_name}\\"].oci_core_dedicated_vm_host.dedicated_vm_host' + if tf_resource not in state["resources"]: + importCommands[region.lower()] += f'\n{tf_or_tofu} import "{tf_resource}" {str(dedicatedvmhost.id)}' for col_header in values_for_column: if col_header == 'Region': @@ -50,7 +53,10 @@ def export_dedicatedvmhosts(inputfile, outdir, service_dir, config, signer, ct, global importCommands global cd3file global reg - global values_for_column + global values_for_column,tf_or_tofu + + tf_or_tofu = ct.tf_or_tofu + tf_state_list = [tf_or_tofu, "state", "list"] cd3file = inputfile @@ -69,39 +75,48 @@ def export_dedicatedvmhosts(inputfile, outdir, service_dir, config, signer, ct, print("\nCD3 excel file should not be opened during export process!!!") print("Tabs- DedicatedVMHosts will be overwritten during export process!!!\n") + # Fetch DVH Details + print("\nFetching details of Dedicated VM Hosts...") + # Create backups - resource = 'tf_import_' + sheetName.lower() - file_name = 'tf_import_commands_' + sheetName.lower() + '_nonGF.sh' + resource = 'import_' + sheetName.lower() + file_name = 'import_commands_' + sheetName.lower() + '.sh' + for reg in export_regions: script_file = f'{outdir}/{reg}/{service_dir}/'+file_name if (os.path.exists(script_file)): commonTools.backup_file(outdir + "/" + reg+"/"+service_dir, resource, file_name) - importCommands[reg] = open(script_file, "w") - importCommands[reg].write("#!/bin/bash") - importCommands[reg].write("\n") - importCommands[reg].write("terraform init") - - # Fetch Block Volume Details - print("\nFetching details of Dedicated VM Hosts...") + importCommands[reg] = '' - for reg in export_regions: - importCommands[reg].write("\n\n######### Writing import for Dedicated VM Hosts #########\n\n") config.__setitem__("region", ct.region_dict[reg]) + state = {'path': f'{outdir}/{reg}/{service_dir}', 'resources': []} + try: + byteOutput = sp.check_output(tf_state_list, cwd=state["path"], stderr=sp.DEVNULL) + output = byteOutput.decode('UTF-8').rstrip() + for item in output.split('\n'): + state["resources"].append(item.replace("\"", "\\\"")) + except Exception as e: + pass region = reg.capitalize() compute_client = oci.core.ComputeClient(config=config,retry_strategy=oci.retry.DEFAULT_RETRY_STRATEGY, signer=signer) for ntk_compartment_name in export_compartments: dedicatedvmhosts = oci.pagination.list_call_get_all_results(compute_client.list_dedicated_vm_hosts,compartment_id=ct.ntk_compartment_ids[ntk_compartment_name], lifecycle_state="ACTIVE") + for dedicatedvmhost in dedicatedvmhosts.data: dedicatedvmhost=compute_client.get_dedicated_vm_host(dedicatedvmhost.id).data - print_dedicatedvmhosts(region, dedicatedvmhost,values_for_column, ntk_compartment_name) + print_dedicatedvmhosts(region, dedicatedvmhost,values_for_column, ntk_compartment_name,state) - # write data into file + # writing data for reg in export_regions: - script_file = f'{outdir}/{reg}/{service_dir}/'+file_name - with open(script_file, 'a') as importCommands[reg]: - importCommands[reg].write('\n\nterraform plan\n') + script_file = f'{outdir}/{reg}/{service_dir}/' + file_name + + init_commands = f'\n######### Writing import for Dedicated VM Hosts #########\n\n#!/bin/bash\n{tf_or_tofu} init' + if importCommands[reg] != "": + importCommands[reg] += f'\n{tf_or_tofu} plan\n' + with open(script_file, 'a') as importCommandsfile: + importCommandsfile.write(init_commands + importCommands[reg]) commonTools.write_to_cd3(values_for_column, cd3file, "DedicatedVMHosts") diff --git a/cd3_automation_toolkit/Compute/export_instances_nonGreenField.py b/cd3_automation_toolkit/Compute/export_instances_nonGreenField.py index b53295dfa..d7a5e5b33 100644 --- a/cd3_automation_toolkit/Compute/export_instances_nonGreenField.py +++ b/cd3_automation_toolkit/Compute/export_instances_nonGreenField.py @@ -7,6 +7,7 @@ import sys import oci import os +import subprocess as sp sys.path.append(os.getcwd() + "/..") from commonTools import * @@ -22,7 +23,7 @@ def adding_columns_values(region, ad, fd, vs, publicip, privateip, os_dname, sha values_for_column_instances[col_header].append(ad) elif (col_header == "Fault Domain"): values_for_column_instances[col_header].append(fd) - elif (col_header == "Subnet Name"): + elif (col_header == "Network Details"): values_for_column_instances[col_header].append(vs) elif (col_header == "Pub Address"): values_for_column_instances[col_header].append(publicip) @@ -80,7 +81,7 @@ def find_vnic(ins_id, compartment_id): return net -def __get_instances_info(compartment_name, compartment_id, reg_name, display_names, ad_names, ct): +def __get_instances_info(compartment_name, compartment_id, reg_name, display_names, ad_names, ct,state): config.__setitem__("region", ct.region_dict[reg_name]) compute = oci.core.ComputeClient(config=config, retry_strategy=oci.retry.DEFAULT_RETRY_STRATEGY,signer=signer) network = oci.core.VirtualNetworkClient(config=config, retry_strategy=oci.retry.DEFAULT_RETRY_STRATEGY,signer=signer) @@ -118,7 +119,9 @@ def __get_instances_info(compartment_name, compartment_id, reg_name, display_nam ins_fd = ins.fault_domain # FD ins_id = ins.id tf_name = commonTools.check_tf_variable(ins_dname) - importCommands[reg_name].write("\nterraform import \"module.instances[\\\"" + tf_name + "\\\"].oci_core_instance.instance\" " + str(ins.id)) + tf_resource = f'module.instances[\\"{tf_name}\\"].oci_core_instance.instance' + if tf_resource not in state["resources"]: + importCommands[reg_name] += f'\n{tf_or_tofu} import "{tf_resource}" {str(ins.id)}' # Shape Details ins_shape = ins.shape @@ -162,7 +165,9 @@ def __get_instances_info(compartment_name, compartment_id, reg_name, display_nam bkp_policy_name = bkp_pname.data.display_name.title() # backup policy name tf_name = commonTools.check_tf_variable(ins_dname) # print(bvp.data[0]) - importCommands[reg_name].write("\nterraform import \"module.instances[\\\"" + tf_name + "\\\"].oci_core_volume_backup_policy_assignment.volume_backup_policy_assignment[0]\" " + str(bvp.data[0].id)) + tf_resource = f'module.instances[\\"{tf_name}\\"].oci_core_volume_backup_policy_assignment.volume_backup_policy_assignment[0]' + if tf_resource not in state["resources"]: + importCommands[reg_name] += f'\n{tf_or_tofu} import "{tf_resource}" {str(bvp.data[0].id)}' if (bkp_pname.data.display_name not in ["Gold", "Silver", "Bronze"]): bkp_policy_name = bkp_pname.data.display_name for comp_name, comp_id in ct.ntk_compartment_ids.items(): @@ -199,7 +204,15 @@ def __get_instances_info(compartment_name, compartment_id, reg_name, display_nam vcn_id = subnet_info.data.vcn_id vcn_info = network.get_vcn(vcn_id=vcn_id) vcn_name = vcn_info.data.display_name - vs = vcn_name + "_" + subnet_name # VCN + Subnet Name + ntk_compartment_id = network.get_vcn(subnet_info.data.vcn_id).data.compartment_id # compartment-id + network_compartment_name = compartment_name + for comp_name, comp_id in ct.ntk_compartment_ids.items(): + if comp_id == ntk_compartment_id: + network_compartment_name = comp_name + + vs = network_compartment_name + "@" + vcn_name + "::" + subnet_name + + #vs = vcn_name + "_" + subnet_name # VCN + Subnet Name #vs = commonTools.check_tf_variable(vs) privateip = vnic_info.private_ip @@ -273,7 +286,10 @@ def export_instances(inputfile, outdir, service_dir,config1, signer1, ct, export print("\nAcceptable cd3 format: .xlsx") exit() - global instance_keys, user_data_in, os_keys, importCommands, idc, rows, AD, values_for_column_instances, df, sheet_dict_instances, config, signer # declaring global variables + global instance_keys, user_data_in, os_keys, importCommands, idc, rows, AD, values_for_column_instances, df, sheet_dict_instances, config, signer,tf_or_tofu # declaring global variables + + tf_or_tofu = ct.tf_or_tofu + tf_state_list = [tf_or_tofu, "state", "list"] config=config1 signer=signer1 @@ -294,22 +310,27 @@ def export_instances(inputfile, outdir, service_dir,config1, signer1, ct, export print("Tabs- Instances will be overwritten during this export process!!!\n") # Create of .sh file - resource = 'tf_import_' + sheetName.lower() - file_name = 'tf_import_commands_' + sheetName.lower() + '_nonGF.sh' + resource = 'import_' + sheetName.lower() + file_name = 'import_commands_' + sheetName.lower() + '.sh' + for reg in export_regions: script_file = f'{outdir}/{reg}/{service_dir}/' + file_name if (os.path.exists(script_file)): commonTools.backup_file(outdir + "/" + reg+"/"+service_dir, resource, file_name) - importCommands[reg] = open(script_file, "w") - importCommands[reg].write("#!/bin/bash") - importCommands[reg].write("\n") - importCommands[reg].write("terraform init") + importCommands[reg] = '' for reg in export_regions: - importCommands[reg].write("\n\n######### Writing import for Instances #########\n\n") config.__setitem__("region", ct.region_dict[reg]) + state = {'path': f'{outdir}/{reg}/{service_dir}', 'resources': []} + try: + byteOutput = sp.check_output(tf_state_list, cwd=state["path"], stderr=sp.DEVNULL) + output = byteOutput.decode('UTF-8').rstrip() + for item in output.split('\n'): + state["resources"].append(item.replace("\"", "\\\"")) + except Exception as e: + pass for ntk_compartment_name in export_compartments: - __get_instances_info(ntk_compartment_name, ct.ntk_compartment_ids[ntk_compartment_name], reg, display_names, ad_names,ct) + __get_instances_info(ntk_compartment_name, ct.ntk_compartment_ids[ntk_compartment_name], reg, display_names, ad_names,ct,state) # writing image ocids and SSH keys into variables file var_data = {} @@ -361,11 +382,15 @@ def export_instances(inputfile, outdir, service_dir,config1, signer1, ct, export f.write(var_data[reg]) f.close() - # write data into file + # writing data for reg in export_regions: script_file = f'{outdir}/{reg}/{service_dir}/' + file_name - with open(script_file, 'a') as importCommands[reg]: - importCommands[reg].write('\n\nterraform plan\n') + + init_commands = f'\n######### Writing import for Instances #########\n\n#!/bin/bash\n{tf_or_tofu} init' + if importCommands[reg] != "": + importCommands[reg] += f'\n{tf_or_tofu} plan\n' + with open(script_file, 'a') as importCommandsfile: + importCommandsfile.write(init_commands + importCommands[reg]) commonTools.write_to_cd3(values_for_column_instances, cd3file, "Instances") print("{0} Instance Details exported into CD3.\n".format(len(values_for_column_instances["Region"]))) diff --git a/cd3_automation_toolkit/CostManagement/Budget/create_terraform_budget.py b/cd3_automation_toolkit/CostManagement/Budget/create_terraform_budget.py index 76e1f7125..4170c90fb 100644 --- a/cd3_automation_toolkit/CostManagement/Budget/create_terraform_budget.py +++ b/cd3_automation_toolkit/CostManagement/Budget/create_terraform_budget.py @@ -45,9 +45,12 @@ def create_terraform_budgets(inputfile, outdir, service_dir, prefix,ct): dfcolumns = df.columns.values.tolist() # Take backup of files - for eachregion in ct.all_regions: + for eachregion in [ct.home_region]: tfStr_budget[eachregion] = '' tfStr_budget_alert_rule[eachregion] = '' + resource = sheetName.lower() + srcdir = outdir + "/" + eachregion + "/" + service_dir + "/" + commonTools.backup_file(srcdir + "/", resource, auto_tfvars_filename) for i in df.index: @@ -182,9 +185,6 @@ def create_terraform_budgets(inputfile, outdir, service_dir, prefix,ct): tfStr_budget[reg] += budget_alert_template.render(count=0, region=reg).replace(budget_alert_Str,tfStr_budget_alert_rule[reg]) tfStr_budget[reg] = "".join([s for s in tfStr_budget[reg].strip().splitlines(True) if s.strip("\r\n").strip()]) - resource=sheetName.lower() - commonTools.backup_file(reg_out_dir + "/", resource, auto_tfvars_filename) - oname = open(outfile, "w+") oname.write(tfStr_budget[reg]) oname.close() diff --git a/cd3_automation_toolkit/CostManagement/Budget/export_budgets_nonGreenField.py b/cd3_automation_toolkit/CostManagement/Budget/export_budgets_nonGreenField.py index a159f1329..8ab459e2c 100644 --- a/cd3_automation_toolkit/CostManagement/Budget/export_budgets_nonGreenField.py +++ b/cd3_automation_toolkit/CostManagement/Budget/export_budgets_nonGreenField.py @@ -9,6 +9,8 @@ import sys import oci import os +import subprocess as sp + from commonTools import * sys.path.append(os.getcwd()+"/..") @@ -105,7 +107,10 @@ def print_budgets(values_for_columns, region, budget,budget_name,budget_alert_ru def export_budgets_nongreenfield(inputfile, outdir, service_dir, config, signer, ct,export_regions=[]): global importCommands global values_for_column_budgets - global sheet_dict_budgets + global sheet_dict_budgets,tf_or_tofu + + tf_or_tofu = ct.tf_or_tofu + tf_state_list = [tf_or_tofu, "state", "list"] cd3file = inputfile total_resources = 0 budget_done = [] @@ -129,22 +134,26 @@ def export_budgets_nongreenfield(inputfile, outdir, service_dir, config, signer, for reg in [ct.home_region]: importCommands = "" region = reg.lower() - script_file = f'{outdir}/{region}/{service_dir}/tf_import_commands_budgets_nonGF.sh' + script_file = f'{outdir}/{region}/{service_dir}/import_commands_budgets.sh' # Create backups if os.path.exists(script_file): - commonTools.backup_file(os.path.dirname(script_file), "tf_import_budgets", os.path.basename(script_file)) + commonTools.backup_file(os.path.dirname(script_file), "import_budgets", os.path.basename(script_file)) config.__setitem__("region", ct.region_dict[region]) + state = {'path': f'{outdir}/{reg}/{service_dir}', 'resources': []} + try: + byteOutput = sp.check_output(tf_state_list, cwd=state["path"], stderr=sp.DEVNULL) + output = byteOutput.decode('UTF-8').rstrip() + for item in output.split('\n'): + state["resources"].append(item.replace("\"", "\\\"")) + except Exception as e: + pass tenancy_id = config["tenancy"] budgets_client = oci.budget.BudgetClient(config=config,retry_strategy=oci.retry.DEFAULT_RETRY_STRATEGY,signer=signer) budgets_list = oci.pagination.list_call_get_all_results(budgets_client.list_budgets,compartment_id=tenancy_id,lifecycle_state="ACTIVE",target_type="ALL") if budgets_list.data != []: - importCommands += "\n######### Writing import for budgets #########\n\n" - importCommands += "#!/bin/bash" - importCommands += "\n" - importCommands += "terraform init" for budget in budgets_list.data: budget_name = str(budget.display_name) budget_id = str(budget.id) @@ -159,17 +168,25 @@ def export_budgets_nongreenfield(inputfile, outdir, service_dir, config, signer, budget = [] print_budgets(values_for_column_budgets, region, budget,budget_name,budget_alert_rule,ct) budget_done.append(budget_tf_name) - importCommands += "\nterraform import \"module.budget-alert-rules[\\\""+alert_tf_name+"\\\"].oci_budget_alert_rule.alert_rule\" " + alert_id + tf_resource = f'module.budget-alert-rules[\\"{alert_tf_name}\\"].oci_budget_alert_rule.alert_rule' + if tf_resource not in state["resources"]: + importCommands += f'\n{tf_or_tofu} import "{tf_resource}" {alert_id}' + else: print_budgets(values_for_column_budgets, region, budget,budget.display_name, budget_alert_rules.data, ct) total_resources += 1 + tf_resource = f'module.budgets[\\"{budget_tf_name}\\"].oci_budget_budget.budget' + if tf_resource not in state["resources"]: + importCommands += f'\n{tf_or_tofu} import "{tf_resource}" {budget_id}' - importCommands += "\nterraform import \"module.budgets[\\\"" + budget_tf_name + "\\\"].oci_budget_budget.budget\" " + budget_id - importCommands += "\nterraform plan\n" + + init_commands = f'\n######### Writing import for Budgets #########\n\n#!/bin/bash\n{tf_or_tofu} init' if importCommands != "": + importCommands += f'\n{tf_or_tofu} plan\n' with open(script_file, 'a') as importCommandsfile: - importCommandsfile.write(importCommands) + importCommandsfile.write(init_commands + importCommands) + commonTools.write_to_cd3(values_for_column_budgets, cd3file, "Budgets") print("{0} rows exported into CD3 for Budgets and Budget alert-rules.\n".format(total_resources)) diff --git a/cd3_automation_toolkit/Database/create_terraform_adb.py b/cd3_automation_toolkit/Database/create_terraform_adb.py index 5cfee3ad8..0ccc5566d 100644 --- a/cd3_automation_toolkit/Database/create_terraform_adb.py +++ b/cd3_automation_toolkit/Database/create_terraform_adb.py @@ -43,7 +43,7 @@ def create_terraform_adb(inputfile, outdir, service_dir, prefix, ct): # List of the column headers dfcolumns = df.columns.values.tolist() - subnets = parseSubnets(filename) + #subnets = parseSubnets(filename) # Initialise empty TF string for each region for reg in ct.all_regions: tfStr[reg] = '' @@ -130,28 +130,30 @@ def create_terraform_adb(inputfile, outdir, service_dir, prefix, ct): tempStr.update(tempdict) continue - - if columnname == "Subnet Name": - if columnvalue != '': - subnet_tf_name = columnvalue.strip() - if ("ocid1.subnet.oc1" in subnet_tf_name): - network_compartment_id = "" - vcn_name = "" - subnet_id = subnet_tf_name - else: - try: - key = region, subnet_tf_name - network_compartment_id = commonTools.check_tf_variable(subnets.vcn_subnet_map[key][0]) - vcn_name = subnets.vcn_subnet_map[key][1] - subnet_id = subnets.vcn_subnet_map[key][2] - except Exception as e: - print("Invalid Subnet Name specified for row " + str( - i + 3) + ". It Doesnt exist in Subnets sheet. Exiting!!!") - exit(1) - else: - subnet_id = "" + subnet_id = '' + network_compartment_id = '' + vcn_name = '' + if columnname == "Network Details": + columnvalue = columnvalue.strip() + if ("ocid1.subnet.oc" in columnvalue): + network_compartment_id = "root" vcn_name = "" - network_compartment_id = "" + subnet_id = columnvalue + elif columnvalue.lower() != 'nan' and columnvalue.lower() != '': + if len(columnvalue.split("@")) == 2: + network_compartment_id = commonTools.check_tf_variable(columnvalue.split("@")[0].strip()) + vcn_subnet_name = columnvalue.split("@")[1].strip() + else: + network_compartment_id = commonTools.check_tf_variable( + str(df.loc[i, 'Compartment Name']).strip()) + vcn_subnet_name = columnvalue + if ("::" not in vcn_subnet_name): + print("Invalid Network Details format specified for row " + str(i + 3) + ". Exiting!!!") + exit(1) + else: + vcn_name = vcn_subnet_name.split("::")[0].strip() + subnet_id = vcn_subnet_name.split("::")[1].strip() + tempdict = {'network_compartment_id': network_compartment_id, 'vcn_name': vcn_name, 'subnet_id': subnet_id} diff --git a/cd3_automation_toolkit/Database/create_terraform_dbsystems_vm_bm.py b/cd3_automation_toolkit/Database/create_terraform_dbsystems_vm_bm.py index 7b4a0f481..2d8595924 100644 --- a/cd3_automation_toolkit/Database/create_terraform_dbsystems_vm_bm.py +++ b/cd3_automation_toolkit/Database/create_terraform_dbsystems_vm_bm.py @@ -30,7 +30,7 @@ def create_terraform_dbsystems_vm_bm(inputfile, outdir, service_dir, prefix, ct) oname = {} tfStr = {} ADS = ["AD1", "AD2", "AD3"] - subnets = parseSubnets(filename) + #subnets = parseSubnets(filename) # Load the template file file_loader = FileSystemLoader(f'{Path(__file__).parent}/templates') @@ -87,7 +87,7 @@ def create_terraform_dbsystems_vm_bm(inputfile, outdir, service_dir, prefix, ct) str(df.loc[i, 'Compartment Name']).lower() == 'nan' and \ str(df.loc[i, 'Availability Domain(AD1|AD2|AD3)']).lower() == 'nan' and \ str(df.loc[i, 'DB System Display Name']).lower() == 'nan' and \ - str(df.loc[i, 'Subnet Name']).lower() == 'nan' and \ + str(df.loc[i, 'Network Details']).lower() == 'nan' and \ str(df.loc[i, 'Shape']).lower() == 'nan' and \ str(df.loc[i, 'Node Count']).lower() == 'nan' and \ str(df.loc[i, 'CPU Core Count']).lower() == 'nan' and \ @@ -105,10 +105,10 @@ def create_terraform_dbsystems_vm_bm(inputfile, outdir, service_dir, prefix, ct) str(df.loc[i, 'Compartment Name']).lower() == 'nan' or \ str(df.loc[i, 'Availability Domain(AD1|AD2|AD3)']).lower() == 'nan' or \ str(df.loc[i, 'SSH Key Var Name']).lower() == 'nan' or \ - str(df.loc[i, 'Subnet Name']).lower() == 'nan' or \ + str(df.loc[i, 'Network Details']).lower() == 'nan' or \ str(df.loc[i, 'Hostname Prefix']).lower() == 'nan' or \ str(df.loc[i, 'Shape']).lower() == 'nan' : - print("\nRegion, Compartment Name, Availability Domain(AD1|AD2|AD3), SSH Key Var Name, Subnet Name, Hostname, Shape are mandatory fields. Please enter a value and try again.......Exiting!!") + print("\nRegion, Compartment Name, Availability Domain(AD1|AD2|AD3), SSH Key Var Name, Network Details, Hostname, Shape are mandatory fields. Please enter a value and try again.......Exiting!!") exit(1) if str(df.loc[i, 'DB Name']).lower() == 'nan' or \ str(df.loc[i, 'DB Version']).lower() == 'nan' or \ @@ -143,30 +143,32 @@ def create_terraform_dbsystems_vm_bm(inputfile, outdir, service_dir, prefix, ct) display_tf_name = commonTools.check_tf_variable(display_tf_name) tempdict = {'display_tf_name': display_tf_name} - if columnname == 'Subnet Name': - subnet_tf_name = columnvalue.strip() - if ("ocid1.subnet.oc1" in subnet_tf_name): - network_compartment_id = "" + subnet_id = '' + network_compartment_id = '' + vcn_name = '' + if columnname == 'Network Details': + columnvalue = columnvalue.strip() + if ("ocid1.subnet.oc" in columnvalue): + network_compartment_id = "root" vcn_name = "" - subnet_id = subnet_tf_name - else: - try: - key = region, subnet_tf_name - network_compartment_id = subnets.vcn_subnet_map[key][0] - vcn_name = subnets.vcn_subnet_map[key][1] - subnet_id = subnets.vcn_subnet_map[key][2] - except Exception as e: - print("Invalid Subnet Name specified for row " + str( - i + 3) + ". It Doesnt exist in Subnets sheet. Exiting!!!") + subnet_id = columnvalue + elif columnvalue.lower() != 'nan' and columnvalue.lower() != '': + if len(columnvalue.split("@")) == 2: + network_compartment_id = commonTools.check_tf_variable(columnvalue.split("@")[0].strip()) + vcn_subnet_name = columnvalue.split("@")[1].strip() + else: + network_compartment_id = commonTools.check_tf_variable( + str(df.loc[i, 'Compartment Name']).strip()) + vcn_subnet_name = columnvalue + if ("::" not in vcn_subnet_name): + print("Invalid Network Details format specified for row " + str(i + 3) + ". Exiting!!!") exit(1) - - tempdict = {'network_compartment_id': commonTools.check_tf_variable(network_compartment_id), - 'vcn_name': vcn_name, + else: + vcn_name = vcn_subnet_name.split("::")[0].strip() + subnet_id = vcn_subnet_name.split("::")[1].strip() + tempdict = {'network_compartment_id': network_compartment_id, 'vcn_name': vcn_name, 'subnet_id': subnet_id} - # if columnname == 'Backup Subnet Name': - # columnvalue = commonTools.check_tf_variable(columnvalue) - if columnname == 'Availability Domain(AD1|AD2|AD3)': columnname = 'availability_domain' diff --git a/cd3_automation_toolkit/Database/create_terraform_exa_vmclusters.py b/cd3_automation_toolkit/Database/create_terraform_exa_vmclusters.py index d234e5a61..737261a6f 100644 --- a/cd3_automation_toolkit/Database/create_terraform_exa_vmclusters.py +++ b/cd3_automation_toolkit/Database/create_terraform_exa_vmclusters.py @@ -44,7 +44,7 @@ def create_terraform_exa_vmclusters(inputfile, outdir, service_dir, prefix, ct): # List of the column headers dfcolumns = df.columns.values.tolist() - subnets = parseSubnets(filename) + #subnets = parseSubnets(filename) # Initialise empty TF string for each region for reg in ct.all_regions: @@ -85,13 +85,13 @@ def create_terraform_exa_vmclusters(inputfile, outdir, service_dir, prefix, ct): str(df.loc[i, 'Compartment Name']).lower() == 'nan' or \ str(df.loc[i, 'Exadata Infra Display Name']).lower() == 'nan' or \ str(df.loc[i, 'VM Cluster Display Name']).lower() == 'nan' or \ - str(df.loc[i, 'Client Subnet Name']).lower() == 'nan' or \ - str(df.loc[i, 'Backup Subnet Name']).lower() == 'nan' or \ + str(df.loc[i, 'Client Network Details']).lower() == 'nan' or \ + str(df.loc[i, 'Backup Network Details']).lower() == 'nan' or \ str(df.loc[i, 'CPU Core Count']).lower() == 'nan' or \ str(df.loc[i, 'SSH Key Var Name']).lower() == 'nan' or \ str(df.loc[i, 'Hostname Prefix']).lower() == 'nan' or \ str(df.loc[i, 'Oracle Grid Infrastructure Version']).lower() == 'nan': - print("\nRegion, Compartment Name, Exadata Infra Display Name, VM Cluster Display Name, Subnet Names, CPU Core Count, Hostname Prefix, Oracle Grid Infrastructure Version, SSH Key Var Name are mandatory fields. Please enter a value and try again.......Exiting!!") + print("\nRegion, Compartment Name, Exadata Infra Display Name, VM Cluster Display Name, Network Details, CPU Core Count, Hostname Prefix, Oracle Grid Infrastructure Version, SSH Key Var Name are mandatory fields. Please enter a value and try again.......Exiting!!") exit(1) # tempdict = {'oracle_db_software_edition' : 'ENTERPRISE_EDITION_EXTREME_PERFORMANCE'} @@ -127,43 +127,54 @@ def create_terraform_exa_vmclusters(inputfile, outdir, service_dir, prefix, ct): display_tf_name = commonTools.check_tf_variable(display_tf_name) tempdict = {'exadata_infra_display_tf_name': display_tf_name} - if columnname == 'Client Subnet Name': - subnet_tf_name = columnvalue.strip() - if ("ocid1.subnet.oc1" in subnet_tf_name): - network_compartment_id = "" + subnet_id = '' + network_compartment_id = '' + vcn_name = '' + if columnname == 'Client Network Details': + columnvalue = columnvalue.strip() + if ("ocid1.subnet.oc" in columnvalue): + network_compartment_id = "root" vcn_name = "" - subnet_id = subnet_tf_name - else: - try: - key = region, subnet_tf_name - network_compartment_id = subnets.vcn_subnet_map[key][0] - vcn_name = subnets.vcn_subnet_map[key][1] - subnet_id = subnets.vcn_subnet_map[key][2] - except Exception as e: - print("Invalid Subnet Name specified for row " + str( - i + 3) + ". It Doesnt exist in Subnets sheet. Exiting!!!") + subnet_id = columnvalue + elif columnvalue.lower() != 'nan' and columnvalue.lower() != '': + if len(columnvalue.split("@")) == 2: + network_compartment_id = commonTools.check_tf_variable(columnvalue.split("@")[0].strip()) + vcn_subnet_name = columnvalue.split("@")[1].strip() + else: + network_compartment_id = commonTools.check_tf_variable( + str(df.loc[i, 'Compartment Name']).strip()) + vcn_subnet_name = columnvalue + if ("::" not in vcn_subnet_name): + print("Invalid Network Details format specified for row " + str(i + 3) + ". Exiting!!!") exit(1) - - tempdict = {'network_compartment_id': commonTools.check_tf_variable(network_compartment_id), - 'vcn_name': vcn_name, + else: + vcn_name = vcn_subnet_name.split("::")[0].strip() + subnet_id = vcn_subnet_name.split("::")[1].strip() + tempdict = {'network_compartment_id': network_compartment_id, 'vcn_name': vcn_name, 'client_subnet_name': subnet_id} - if columnname == 'Backup Subnet Name': - subnet_tf_name = columnvalue.strip() - if ("ocid1.subnet.oc1" in subnet_tf_name): - network_compartment_id = "" + subnet_id = '' + network_compartment_id = '' + vcn_name = '' + if columnname == 'Backup Network Details': + columnvalue = columnvalue.strip() + if ("ocid1.subnet.oc" in columnvalue): + network_compartment_id = "root" vcn_name = "" - subnet_id = subnet_tf_name - else: - try: - key = region, subnet_tf_name - network_compartment_id = subnets.vcn_subnet_map[key][0] - vcn_name = subnets.vcn_subnet_map[key][1] - subnet_id = subnets.vcn_subnet_map[key][2] - except Exception as e: - print("Invalid Subnet Name specified for row " + str( - i + 3) + ". It Doesnt exist in Subnets sheet. Exiting!!!") + subnet_id = columnvalue + elif columnvalue.lower() != 'nan' and columnvalue.lower() != '': + if len(columnvalue.split("@")) == 2: + network_compartment_id = commonTools.check_tf_variable(columnvalue.split("@")[0].strip()) + vcn_subnet_name = columnvalue.split("@")[1].strip() + else: + network_compartment_id = commonTools.check_tf_variable(str(df.loc[i, 'Compartment Name']).strip()) + vcn_subnet_name = columnvalue + if ("::" not in vcn_subnet_name): + print("Invalid Network Details format specified for row " + str(i + 3) + ". Exiting!!!") exit(1) + else: + vcn_name = vcn_subnet_name.split("::")[0].strip() + subnet_id = vcn_subnet_name.split("::")[1].strip() tempdict = {'backup_subnet_name': subnet_id} diff --git a/cd3_automation_toolkit/Database/export_adb_nonGreenField.py b/cd3_automation_toolkit/Database/export_adb_nonGreenField.py index 92bd18ce8..f1ec973db 100644 --- a/cd3_automation_toolkit/Database/export_adb_nonGreenField.py +++ b/cd3_automation_toolkit/Database/export_adb_nonGreenField.py @@ -8,6 +8,7 @@ # import oci import os +import subprocess as sp from commonTools import * from oci.config import DEFAULT_LOCATION @@ -15,7 +16,7 @@ oci_obj_names = {} -def print_adbs(region, vnc_client, adb, values_for_column, ntk_compartment_name): +def print_adbs(region, vnc_client, adb, values_for_column, ntk_compartment_name,state,ct): adb_tf_name = commonTools.check_tf_variable(adb.display_name) customer_emails = "" if hasattr(adb,"customer_contacts") and adb.customer_contacts: @@ -28,9 +29,13 @@ def print_adbs(region, vnc_client, adb, values_for_column, ntk_compartment_name) adb_subnet_name = adb_subnet_info.data.display_name # Subnet-Name adb_vcn_name = vnc_client.get_vcn(adb_subnet_info.data.vcn_id).data.display_name - else: - adb_subnet_name = "" - adb_vcn_name = "" + ntk_compartment_id = vnc_client.get_vcn(adb_subnet_info.data.vcn_id).data.compartment_id # compartment-id + network_compartment_name = ntk_compartment_name + for comp_name, comp_id in ct.ntk_compartment_ids.items(): + if comp_id == ntk_compartment_id: + network_compartment_name = comp_name + + vs = network_compartment_name + "@" + adb_vcn_name + "::" + adb_subnet_name # Fetch NSGs @@ -49,8 +54,9 @@ def print_adbs(region, vnc_client, adb, values_for_column, ntk_compartment_name) whitelisted_ips = whitelisted_ips + "," + ip whitelisted_ips = whitelisted_ips[1:] - importCommands[region.lower()].write( - "\nterraform import \"module.adb[\\\"" + adb_tf_name + "\\\"].oci_database_autonomous_database.autonomous_database\" " + str(adb.id)) + tf_resource = f'module.adb[\\"{adb_tf_name}\\"].oci_database_autonomous_database.autonomous_database' + if tf_resource not in state["resources"]: + importCommands[region.lower()] += f'\n{tf_or_tofu} import "{tf_resource}" {str(adb.id)}' for col_header in values_for_column: if col_header == 'Region': @@ -59,9 +65,9 @@ def print_adbs(region, vnc_client, adb, values_for_column, ntk_compartment_name) values_for_column[col_header].append(ntk_compartment_name) elif col_header == 'ADB Display Name': values_for_column[col_header].append(adb.display_name) - elif col_header == 'Subnet Name': + elif col_header == 'Network Details': if (adb_subnet_id is not None): - values_for_column[col_header].append(adb_vcn_name + "_" + adb_subnet_name) + values_for_column[col_header].append(vs) else: values_for_column[col_header].append("") elif col_header == 'Whitelisted IP Addresses': @@ -117,7 +123,10 @@ def export_adbs(inputfile, outdir, service_dir, config, signer, ct, export_compa global importCommands global cd3file global reg - global values_for_column + global values_for_column,tf_or_tofu + + tf_or_tofu = ct.tf_or_tofu + tf_state_list = [tf_or_tofu, "state", "list"] cd3file = inputfile # input file if ('.xls' not in cd3file): @@ -136,25 +145,27 @@ def export_adbs(inputfile, outdir, service_dir, config, signer, ct, export_compa print("Tabs- ADB will be overwritten during export process!!!\n") # Create backups - resource = 'tf_import_' + sheetName.lower() - file_name = 'tf_import_commands_' + sheetName.lower() + '_nonGF.sh' + resource = 'import_' + sheetName.lower() + file_name = 'import_commands_' + sheetName.lower() + '.sh' for reg in export_regions: script_file = f'{outdir}/{reg}/{service_dir}/' + file_name if (os.path.exists(script_file)): commonTools.backup_file(outdir + "/" + reg + "/" + service_dir, resource, file_name) - importCommands[reg] = open(script_file, "w") - importCommands[reg].write("#!/bin/bash") - importCommands[reg].write("\n") - importCommands[reg].write("terraform init") + importCommands[reg] = '' # Fetch ADB details print("\nFetching details of ADBs...") - - for reg in export_regions: - importCommands[reg].write("\n\n######### Writing import for ADBs #########\n\n") config.__setitem__("region", ct.region_dict[reg]) + state = {'path': f'{outdir}/{reg}/{service_dir}', 'resources': []} + try: + byteOutput = sp.check_output(tf_state_list, cwd=state["path"], stderr=sp.DEVNULL) + output = byteOutput.decode('UTF-8').rstrip() + for item in output.split('\n'): + state["resources"].append(item.replace("\"", "\\\"")) + except Exception as e: + pass region = reg.capitalize() adb_client = oci.database.DatabaseClient(config=config, retry_strategy=oci.retry.DEFAULT_RETRY_STRATEGY, signer=signer) @@ -163,17 +174,19 @@ def export_adbs(inputfile, outdir, service_dir, config, signer, ct, export_compa for ntk_compartment_name in export_compartments: adbs = oci.pagination.list_call_get_all_results(adb_client.list_autonomous_databases,compartment_id=ct.ntk_compartment_ids[ntk_compartment_name],lifecycle_state="AVAILABLE") - for adb in adbs.data: adb = adb_client.get_autonomous_database(adb.id).data - print_adbs(region, vnc_client, adb, values_for_column, ntk_compartment_name) + print_adbs(region, vnc_client, adb, values_for_column, ntk_compartment_name,state,ct) - for reg in export_regions: - script_file = f'{outdir}/{reg}/{service_dir}/' + file_name - with open(script_file, 'a') as importCommands[reg]: - importCommands[reg].write('\n\nterraform plan\n') commonTools.write_to_cd3(values_for_column, cd3file, "ADB") - print("{0} ADBs exported into CD3.\n".format(len(values_for_column["Region"]))) + # writing data + for reg in export_regions: + script_file = f'{outdir}/{reg}/{service_dir}/' + file_name + init_commands = f'\n######### Writing import for ADBs #########\n\n#!/bin/bash\n{tf_or_tofu} init' + if importCommands[reg] != "": + importCommands[reg] += f'\n{tf_or_tofu} plan\n' + with open(script_file, 'a') as importCommandsfile: + importCommandsfile.write(init_commands + importCommands[reg]) diff --git a/cd3_automation_toolkit/Database/export_dbsystems_vm_bm_nonGreenField.py b/cd3_automation_toolkit/Database/export_dbsystems_vm_bm_nonGreenField.py index 94f90a75f..7c19ee9af 100644 --- a/cd3_automation_toolkit/Database/export_dbsystems_vm_bm_nonGreenField.py +++ b/cd3_automation_toolkit/Database/export_dbsystems_vm_bm_nonGreenField.py @@ -14,12 +14,13 @@ from jinja2 import Environment, FileSystemLoader import json import re +import subprocess as sp importCommands = {} oci_obj_names = {} -def print_dbsystem_vm_bm(region, db_system_vm_bm, count,db_home, database ,vnc_client, key_name, values_for_column, ntk_compartment_name): +def print_dbsystem_vm_bm(region, db_system_vm_bm, count,db_home, database ,vnc_client, key_name, values_for_column, ntk_compartment_name,state,ct): db_system_vm_bm_tf_name = commonTools.check_tf_variable(db_system_vm_bm.display_name) db_system_subnet_id = db_system_vm_bm.subnet_id @@ -27,6 +28,13 @@ def print_dbsystem_vm_bm(region, db_system_vm_bm, count,db_home, database ,vnc_c sub_name = subnet_info.data.display_name # Subnet-Name vcn_name = vnc_client.get_vcn(subnet_info.data.vcn_id).data.display_name # vcn-Name + ntk_compartment_id = vnc_client.get_vcn(subnet_info.data.vcn_id).data.compartment_id # compartment-id + network_compartment_name = ntk_compartment_name + for comp_name, comp_id in ct.ntk_compartment_ids.items(): + if comp_id == ntk_compartment_id: + network_compartment_name = comp_name + vs = network_compartment_name + "@" + vcn_name + "::" + sub_name + db_system_options = db_system_vm_bm.db_system_options maintenance_window = db_system_vm_bm.maintenance_window @@ -43,12 +51,13 @@ def print_dbsystem_vm_bm(region, db_system_vm_bm, count,db_home, database ,vnc_c connection_strings = database.connection_strings database_management_config = database.database_management_config - if (count ==1): - importCommands[region.lower()].write("\nterraform import \"module.dbsystems-vm-bm[\\\"" + db_system_vm_bm_tf_name + "\\\"].oci_database_db_system.database_db_system\" " + str(db_system_vm_bm.id)) + tf_resource = f'module.dbsystems-vm-bm[\\"{db_system_vm_bm_tf_name}\\"].oci_database_db_system.database_db_system' + if (count ==1) and tf_resource not in state["resources"]: + importCommands[region.lower()] += f'\n{tf_or_tofu} import "{tf_resource}" {str(db_system_vm_bm.id)}' if(count!=1): for col_header in values_for_column: - if col_header == 'Region' or col_header == 'Compartment Name' or col_header == 'Subnet Name' or "Availability Domain" in col_header or \ + if col_header == 'Region' or col_header == 'Compartment Name' or col_header == 'Network Details' or "Availability Domain" in col_header or \ col_header == 'Shape' or col_header == 'DB System Display Name' or col_header == 'Node Count' or col_header == 'CPU Core Count' or col_header == "Database Edition" or \ col_header == 'Data Storage in GB' or col_header == 'Data Storage Percentage' or col_header == 'Disk Redundancy' or col_header == 'License Model' or \ col_header == 'Hostname Prefix' or col_header == 'SSH Key Var Name' or col_header == 'Time Zone' or col_header == 'NSGs': @@ -70,8 +79,8 @@ def print_dbsystem_vm_bm(region, db_system_vm_bm, count,db_home, database ,vnc_c values_for_column[col_header].append(region) elif col_header == 'Compartment Name': values_for_column[col_header].append(ntk_compartment_name) - elif col_header == 'Subnet Name': - values_for_column[col_header].append(vcn_name + "_" + sub_name) + elif col_header == 'Network Details': + values_for_column[col_header].append(vs) elif col_header == 'DB Admin Password': values_for_column[col_header].append('nullval') elif col_header == 'SSH Key Var Name': @@ -102,7 +111,10 @@ def export_dbsystems_vm_bm(inputfile, outdir, service_dir, config, signer, ct, e global importCommands global cd3file global reg - global values_for_column + global values_for_column,tf_or_tofu + + tf_or_tofu = ct.tf_or_tofu + tf_state_list = [tf_or_tofu, "state", "list"] cd3file = inputfile @@ -128,25 +140,29 @@ def export_dbsystems_vm_bm(inputfile, outdir, service_dir, config, signer, ct, e env = Environment(loader=file_loader, keep_trailing_newline=True, trim_blocks=True, lstrip_blocks=True) # Create backups - resource = 'tf_import_' + sheetName.lower() - file_name = 'tf_import_commands_' + sheetName.lower() + '_nonGF.sh' + resource = 'import_' + sheetName.lower() + file_name = 'import_commands_' + sheetName.lower() + '.sh' for reg in export_regions: script_file = f'{outdir}/{reg}/{service_dir}/' + file_name if (os.path.exists(script_file)): commonTools.backup_file(outdir + "/" + reg + "/" + service_dir, resource, file_name) - importCommands[reg] = open(script_file, "w") - importCommands[reg].write("#!/bin/bash") - importCommands[reg].write("\n") - importCommands[reg].write("terraform init") + importCommands[reg] = '' # Fetch Block Volume Details print("\nFetching details of VM and BM DB Systems...") for reg in export_regions: var_data[reg] = "" - importCommands[reg].write("\n\n######### Writing import for DB System VM and DB System BM #########\n\n") config.__setitem__("region", ct.region_dict[reg]) + state = {'path': f'{outdir}/{reg}/{service_dir}', 'resources': []} + try: + byteOutput = sp.check_output(tf_state_list, cwd=state["path"], stderr=sp.DEVNULL) + output = byteOutput.decode('UTF-8').rstrip() + for item in output.split('\n'): + state["resources"].append(item.replace("\"", "\\\"")) + except Exception as e: + pass region = reg.capitalize() db_client = oci.database.DatabaseClient(config=config,retry_strategy=oci.retry.DEFAULT_RETRY_STRATEGY,signer=signer) @@ -171,7 +187,7 @@ def export_dbsystems_vm_bm(inputfile, outdir, service_dir, config, signer, ct, e break databases = oci.pagination.list_call_get_all_results(db_client.list_databases,compartment_id=ct.ntk_compartment_ids[ntk_compartment_name],db_home_id=db_home.id,system_id=db_system.id,lifecycle_state="AVAILABLE") for database in databases.data: - print_dbsystem_vm_bm(region, db_system, count,db_home, database, vnc_client, key_name,values_for_column, ntk_compartment_name) + print_dbsystem_vm_bm(region, db_system, count,db_home, database, vnc_client, key_name,values_for_column, ntk_compartment_name,state,ct) file = f'{outdir}/{reg}/{service_dir}/variables_{reg}.tf' # Read variables file data @@ -191,11 +207,14 @@ def export_dbsystems_vm_bm(inputfile, outdir, service_dir, config, signer, ct, e with open(file, "w") as f: f.write(var_data[reg]) - - with open(script_file, 'a') as importCommands[reg]: - importCommands[reg].write('\n\nterraform plan\n') - commonTools.write_to_cd3(values_for_column, cd3file, sheetName) - print("{0} Virtual Machine and Bare Metal DB Systems exported into CD3.\n".format(len(values_for_column["Region"]))) + # writing data + for reg in export_regions: + script_file = f'{outdir}/{reg}/{service_dir}/' + file_name + init_commands = f'\n######### Writing import for DB System VM and DB System BM #########\n\n#!/bin/bash\n{tf_or_tofu} init' + if importCommands[reg] != "": + importCommands[reg] += f'\n{tf_or_tofu} plan\n' + with open(script_file, 'a') as importCommandsfile: + importCommandsfile.write(init_commands + importCommands[reg]) diff --git a/cd3_automation_toolkit/Database/export_exa_infra_nonGreenField.py b/cd3_automation_toolkit/Database/export_exa_infra_nonGreenField.py index 830b2448d..5aaad0873 100644 --- a/cd3_automation_toolkit/Database/export_exa_infra_nonGreenField.py +++ b/cd3_automation_toolkit/Database/export_exa_infra_nonGreenField.py @@ -10,18 +10,19 @@ import oci import os +import subprocess as sp from commonTools import * importCommands = {} oci_obj_names = {} -def print_exa_infra(region, exa_infra, values_for_column, ntk_compartment_name): +def print_exa_infra(region, exa_infra, values_for_column, ntk_compartment_name,state): exa_infra_tf_name = commonTools.check_tf_variable(exa_infra.display_name) maintenance_window = exa_infra.maintenance_window - - #importCommands[region.lower()].write("\nterraform import oci_database_cloud_exadata_infrastructure." + exa_infra_tf_name + " " + str(exa_infra.id)) - importCommands[region.lower()].write("\nterraform import \"module.exa-infra[\\\"" + exa_infra_tf_name + "\\\"].oci_database_cloud_exadata_infrastructure.exa_infra\" " + str(exa_infra.id)) + tf_resource = f'module.exa-infra[\\"{exa_infra_tf_name}\\"].oci_database_cloud_exadata_infrastructure.exa_infra' + if tf_resource not in state["resources"]: + importCommands[region.lower()] += f'\n{tf_or_tofu} import "{tf_resource}" {str(exa_infra.id)}' for col_header in values_for_column: if col_header == 'Region': @@ -53,7 +54,10 @@ def export_exa_infra(inputfile, outdir, service_dir, config, signer, ct, export_ global importCommands global cd3file global reg - global values_for_column + global values_for_column,tf_or_tofu + + tf_or_tofu = ct.tf_or_tofu + tf_state_list = [tf_or_tofu, "state", "list"] cd3file = inputfile @@ -72,24 +76,28 @@ def export_exa_infra(inputfile, outdir, service_dir, config, signer, ct, export_ print("Tabs- EXA-Infra will be overwritten during export process!!!\n") # Create backups - resource = 'tf_import_' + sheetName.lower() - file_name = 'tf_import_commands_' + sheetName.lower() + '_nonGF.sh' + resource = 'import_' + sheetName.lower() + file_name = 'import_commands_' + sheetName.lower() + '.sh' for reg in export_regions: script_file = f'{outdir}/{reg}/{service_dir}/' + file_name if (os.path.exists(script_file)): commonTools.backup_file(outdir + "/" + reg + "/" + service_dir, resource, file_name) - importCommands[reg] = open(script_file, "w") - importCommands[reg].write("#!/bin/bash") - importCommands[reg].write("\n") - importCommands[reg].write("terraform init") + importCommands[reg] = '' # Fetch Block Volume Details print("\nFetching details of Exadata Infra...") for reg in export_regions: - importCommands[reg].write("\n\n######### Writing import for Exadata Infra #########\n\n") config.__setitem__("region", ct.region_dict[reg]) + state = {'path': f'{outdir}/{reg}/{service_dir}', 'resources': []} + try: + byteOutput = sp.check_output(tf_state_list, cwd=state["path"], stderr=sp.DEVNULL) + output = byteOutput.decode('UTF-8').rstrip() + for item in output.split('\n'): + state["resources"].append(item.replace("\"", "\\\"")) + except Exception as e: + pass region = reg.capitalize() db_client = oci.database.DatabaseClient(config=config,retry_strategy=oci.retry.DEFAULT_RETRY_STRATEGY, signer=signer) @@ -97,13 +105,19 @@ def export_exa_infra(inputfile, outdir, service_dir, config, signer, ct, export_ for ntk_compartment_name in export_compartments: exa_infras = oci.pagination.list_call_get_all_results(db_client.list_cloud_exadata_infrastructures,compartment_id=ct.ntk_compartment_ids[ntk_compartment_name], lifecycle_state="AVAILABLE") for exa_infra in exa_infras.data: - print_exa_infra(region, exa_infra,values_for_column, ntk_compartment_name) + print_exa_infra(region, exa_infra,values_for_column, ntk_compartment_name,state) + + + commonTools.write_to_cd3(values_for_column, cd3file, sheetName) + print("{0} Exadata Infra exported into CD3.\n".format(len(values_for_column["Region"]))) + # writing data for reg in export_regions: script_file = f'{outdir}/{reg}/{service_dir}/' + file_name - with open(script_file, 'a') as importCommands[reg]: - importCommands[reg].write('\n\nterraform plan\n') - commonTools.write_to_cd3(values_for_column, cd3file, sheetName) + init_commands = f'\n######### Writing import for Exadata Infra #########\n\n#!/bin/bash\n{tf_or_tofu} init' + if importCommands[reg] != "": + importCommands[reg] += f'\n{tf_or_tofu} plan\n' + with open(script_file, 'a') as importCommandsfile: + importCommandsfile.write(init_commands + importCommands[reg]) - print("{0} Exadata Infra exported into CD3.\n".format(len(values_for_column["Region"]))) diff --git a/cd3_automation_toolkit/Database/export_exa_vmclusters_nonGreenField.py b/cd3_automation_toolkit/Database/export_exa_vmclusters_nonGreenField.py index 13ee92cdc..bc7d19678 100644 --- a/cd3_automation_toolkit/Database/export_exa_vmclusters_nonGreenField.py +++ b/cd3_automation_toolkit/Database/export_exa_vmclusters_nonGreenField.py @@ -12,6 +12,7 @@ import os import json import re +import subprocess as sp from pathlib import Path from commonTools import * from jinja2 import Environment, FileSystemLoader @@ -20,7 +21,7 @@ oci_obj_names = {} -def print_exa_vmcluster(region, vnc_client,exa_infra, exa_vmcluster, key_name,values_for_column, ntk_compartment_name, db_servers): +def print_exa_vmcluster(region, vnc_client,exa_infra, exa_vmcluster, key_name,values_for_column, ntk_compartment_name, db_servers,state,ct): exa_infra_tf_name = commonTools.check_tf_variable(exa_infra.display_name) exa_vmcluster_tf_name = commonTools.check_tf_variable(exa_vmcluster.display_name) @@ -28,11 +29,23 @@ def print_exa_vmcluster(region, vnc_client,exa_infra, exa_vmcluster, key_name,va client_subnet_info = vnc_client.get_subnet(exa_vmcluster_client_subnet_id) client_subnet_name = client_subnet_info.data.display_name # Subnet-Name client_vcn_name = vnc_client.get_vcn(client_subnet_info.data.vcn_id).data.display_name # vcn-Name + ntk_compartment_id = vnc_client.get_vcn(client_subnet_info.data.vcn_id).data.compartment_id # compartment-id + network_compartment_name = ntk_compartment_name + for comp_name, comp_id in ct.ntk_compartment_ids.items(): + if comp_id == ntk_compartment_id: + network_compartment_name = comp_name + client_network = network_compartment_name + "@" + client_vcn_name + "::" + client_subnet_name exa_vmcluster_backup_subnet_id = exa_vmcluster.backup_subnet_id backup_subnet_info = vnc_client.get_subnet(exa_vmcluster_backup_subnet_id) backup_subnet_name = backup_subnet_info.data.display_name # Subnet-Name backup_vcn_name = vnc_client.get_vcn(backup_subnet_info.data.vcn_id).data.display_name # vcn-Name + ntk_compartment_id = vnc_client.get_vcn(backup_subnet_info.data.vcn_id).data.compartment_id # compartment-id + network_compartment_name = ntk_compartment_name + for comp_name, comp_id in ct.ntk_compartment_ids.items(): + if comp_id == ntk_compartment_id: + network_compartment_name = comp_name + backup_network = network_compartment_name + "@" + backup_vcn_name + "::" + backup_subnet_name NSGs = exa_vmcluster.nsg_ids @@ -53,9 +66,9 @@ def print_exa_vmcluster(region, vnc_client,exa_infra, exa_vmcluster, key_name,va maintenance_window = exa_infra.maintenance_window - - - importCommands[region.lower()].write("\nterraform import \"module.exa-vmclusters[\\\"" + exa_vmcluster_tf_name + "\\\"].oci_database_cloud_vm_cluster.exa_vmcluster\" " + str(exa_vmcluster.id)) + tf_resource = f'module.exa-vmclusters[\\"{exa_vmcluster_tf_name}\\"].oci_database_cloud_vm_cluster.exa_vmcluster' + if tf_resource not in state["resources"]: + importCommands[region.lower()] += f'\n{tf_or_tofu} import "{tf_resource}" {str(exa_vmcluster.id)}' for col_header in values_for_column: if col_header == 'Region': @@ -66,10 +79,10 @@ def print_exa_vmcluster(region, vnc_client,exa_infra, exa_vmcluster, key_name,va values_for_column[col_header].append(exa_infra.display_name) elif col_header == 'SSH Key Var Name': values_for_column[col_header].append(key_name) - elif col_header == 'Client Subnet Name': - values_for_column[col_header].append(client_vcn_name+"_"+client_subnet_name) - elif col_header == 'Backup Subnet Name': - values_for_column[col_header].append(backup_vcn_name + "_" + backup_subnet_name) + elif col_header == 'Client Network Details': + values_for_column[col_header].append(client_network) + elif col_header == 'Backup Network Detailse': + values_for_column[col_header].append(backup_network) elif (col_header == "NSGs"): values_for_column[col_header].append(nsg_names) elif (col_header == "Backup Network NSGs"): @@ -91,7 +104,10 @@ def export_exa_vmclusters(inputfile, outdir, service_dir, config, signer, ct, ex global importCommands global cd3file global reg - global values_for_column + global values_for_column,tf_or_tofu + + tf_or_tofu = ct.tf_or_tofu + tf_state_list = [tf_or_tofu, "state", "list"] cd3file = inputfile @@ -99,7 +115,6 @@ def export_exa_vmclusters(inputfile, outdir, service_dir, config, signer, ct, ex print("\nAcceptable cd3 format: .xlsx") exit() - sheetName = 'EXA-VMClusters' var_data ={} @@ -118,17 +133,14 @@ def export_exa_vmclusters(inputfile, outdir, service_dir, config, signer, ct, ex env = Environment(loader=file_loader, keep_trailing_newline=True, trim_blocks=True, lstrip_blocks=True) # Create backups - resource = 'tf_import_' + sheetName.lower() - file_name = 'tf_import_commands_' + sheetName.lower() + '_nonGF.sh' + resource = 'import_' + sheetName.lower() + file_name = 'import_commands_' + sheetName.lower() + '.sh' for reg in export_regions: script_file = f'{outdir}/{reg}/{service_dir}/' + file_name if (os.path.exists(script_file)): commonTools.backup_file(outdir + "/" + reg + "/" + service_dir, resource, file_name) - importCommands[reg] = open(script_file, "w") - importCommands[reg].write("#!/bin/bash") - importCommands[reg].write("\n") - importCommands[reg].write("terraform init") + importCommands[reg] = '' # Fetch Block Volume Details print("\nFetching details of Exadata VM Clusters...") @@ -136,8 +148,15 @@ def export_exa_vmclusters(inputfile, outdir, service_dir, config, signer, ct, ex for reg in export_regions: var_data[reg] = "" - importCommands[reg].write("\n\n######### Writing import for Exadata VM Clusters #########\n\n") config.__setitem__("region", ct.region_dict[reg]) + state = {'path': f'{outdir}/{reg}/{service_dir}', 'resources': []} + try: + byteOutput = sp.check_output(tf_state_list, cwd=state["path"], stderr=sp.DEVNULL) + output = byteOutput.decode('UTF-8').rstrip() + for item in output.split('\n'): + state["resources"].append(item.replace("\"", "\\\"")) + except Exception as e: + pass region = reg.capitalize() db_client = oci.database.DatabaseClient(config=config,retry_strategy=oci.retry.DEFAULT_RETRY_STRATEGY, signer=signer) @@ -162,8 +181,9 @@ def export_exa_vmclusters(inputfile, outdir, service_dir, config, signer, ct, ex for db_server in db_serverids: db_server_name = db_client.get_db_server(exa_infra.id, db_server).data.display_name db_servers = db_server_name +","+db_servers + db_servers=db_servers.removesuffix(',') - print_exa_vmcluster(region, vnc_client, exa_infra,exa_vmcluster,key_name, values_for_column, ntk_compartment_name_again,db_servers) + print_exa_vmcluster(region, vnc_client, exa_infra,exa_vmcluster,key_name, values_for_column, ntk_compartment_name_again,db_servers,state,ct) file = f'{outdir}/{reg}/{service_dir}/variables_{reg}.tf' # Read variables file data @@ -183,11 +203,15 @@ def export_exa_vmclusters(inputfile, outdir, service_dir, config, signer, ct, ex with open(file, "w") as f: f.write(var_data[reg]) - - with open(script_file, 'a') as importCommands[reg]: - importCommands[reg].write('\n\nterraform plan\n') - commonTools.write_to_cd3(values_for_column, cd3file, sheetName) - print("{0} Exadata VM Clusters exported into CD3.\n".format(len(values_for_column["Region"]))) + # writing data + for reg in export_regions: + script_file = f'{outdir}/{reg}/{service_dir}/' + file_name + init_commands = f'\n######### Writing import for Exadata VM Clusters #########\n\n#!/bin/bash\n{tf_or_tofu} init' + if importCommands[reg] != "": + importCommands[reg] += f'\n{tf_or_tofu} plan\n' + with open(script_file, 'a') as importCommandsfile: + importCommandsfile.write(init_commands + importCommands[reg]) + diff --git a/cd3_automation_toolkit/DeveloperServices/OKE/create_terraform_oke.py b/cd3_automation_toolkit/DeveloperServices/OKE/create_terraform_oke.py index 5fa5fe61c..30e95fc11 100644 --- a/cd3_automation_toolkit/DeveloperServices/OKE/create_terraform_oke.py +++ b/cd3_automation_toolkit/DeveloperServices/OKE/create_terraform_oke.py @@ -47,13 +47,13 @@ def create_terraform_oke(inputfile, outdir, service_dir, prefix, ct): # fill the empty values with that in previous row. dffill = df[ ['Region', 'Compartment Name', 'Cluster Name', 'Cluster Kubernetes Version','Network Type', 'Pod Security Policies Enforced', - 'Load Balancer Subnets', 'API Endpoint Subnet']] + 'Load Balancer Network Details', 'API Endpoint Network Details']] dffill = dffill.fillna(method='ffill') #Drop unnecessary columns dfdrop = df[ ['Region', 'Compartment Name', 'Cluster Name', 'Cluster Kubernetes Version','Network Type', 'Pod Security Policies Enforced', - 'Load Balancer Subnets', 'API Endpoint Subnet']] + 'Load Balancer Network Details', 'API Endpoint Network Details']] dfdrop = df.drop(dfdrop, axis=1) df = pd.concat([dffill, dfdrop], axis=1) @@ -62,11 +62,16 @@ def create_terraform_oke(inputfile, outdir, service_dir, prefix, ct): cluster_str[reg] = '' node_str[reg] = '' virtual_node_str[reg] = '' + resource = sheetName.lower() + srcdir = outdir + "/" + reg + "/" + service_dir + "/" + commonTools.backup_file(srcdir, resource, cluster_auto_tfvars_filename) + commonTools.backup_file(srcdir, resource, nodepool_auto_tfvars_filename) + commonTools.backup_file(srcdir, resource, virtual_nodepool_auto_tfvars_filename) # List of the column headers dfcolumns = df.columns.values.tolist() - subnets = parseSubnets(filename) + #subnets = parseSubnets(filename) for i in df.index: @@ -97,24 +102,24 @@ def create_terraform_oke(inputfile, outdir, service_dir, prefix, ct): str(df.loc[i, 'Network Type']).lower() == 'nan' or \ str(df.loc[i, 'Cluster Kubernetes Version']).lower() == 'nan' or \ str(df.loc[i, 'Pod Security Policies Enforced']).lower() == 'nan' or \ - str(df.loc[i, 'Load Balancer Subnets']).lower() == 'nan' or \ - str(df.loc[i, 'API Endpoint Subnet']).lower() == 'nan': + str(df.loc[i, 'Load Balancer Network Details']).lower() == 'nan' or \ + str(df.loc[i, 'API Endpoint Network Details']).lower() == 'nan': print( - "\nRegion, Compartment Name, Cluster Name, Network Type, Cluster Kubernetes Version, Pod Security Policies, Load Balancer Subnets, API Endpoint Subnet fields are mandatory. Please enter a value and try again !!\n\nPlease fix it for row : {}".format( + "\nRegion, Compartment Name, Cluster Name, Network Type, Cluster Kubernetes Version, Pod Security Policies, Load Balancer Network Details, API Endpoint Network Details fields are mandatory. Please enter a value and try again !!\n\nPlease fix it for row : {}".format( i + 3)) print("\n** Exiting **") exit(1) - if str(df.loc[i, 'CompartmentName&Node Pool Name:Node Pool Type']).lower() != 'nan': - nodepool_tf_name_type = str(df.loc[i, 'CompartmentName&Node Pool Name:Node Pool Type']).strip().split("&")[1] + if str(df.loc[i, 'CompartmentName@Node Pool Name:Node Pool Type']).lower() != 'nan': + nodepool_tf_name_type = str(df.loc[i, 'CompartmentName@Node Pool Name:Node Pool Type']).strip().split("@")[1] if (":" in nodepool_tf_name_type): nodepool_type = nodepool_tf_name_type.split(":")[1] nodepool_type = nodepool_type.lower() else: nodepool_type = 'managed' - if str(df.loc[i, 'Worker Node Subnet']).lower() == 'nan' or \ + if str(df.loc[i, 'Worker Node Network Details']).lower() == 'nan' or \ str(df.loc[i, 'Availability Domain(AD1|AD2|AD3)']).lower() == 'nan': - print("\nCompartmentName&Node Pool Name:Node Pool Type, Worker Node Subnet and Availability Domain(AD1|AD2|AD3) fields are mandatory. \n\nPlease fix it for row : {} and try again.".format(i+3)) + print("\nCompartmentName@Node Pool Name:Node Pool Type, Worker Node Network Details and Availability Domain(AD1|AD2|AD3) fields are mandatory. \n\nPlease fix it for row : {} and try again.".format(i+3)) print("\n** Exiting **") exit(1) if (nodepool_type == "managed"): @@ -122,9 +127,9 @@ def create_terraform_oke(inputfile, outdir, service_dir, prefix, ct): str(df.loc[i, 'Shape']).lower() == 'nan' or \ str(df.loc[i, 'Source Details']).lower() == 'nan' or \ str(df.loc[i, 'Number of Nodes']).lower() == 'nan' or \ - str(df.loc[i, 'Worker Node Subnet']).lower() == 'nan' or \ + str(df.loc[i, 'Worker Node Network Details']).lower() == 'nan' or \ str(df.loc[i, 'Availability Domain(AD1|AD2|AD3)']).lower() == 'nan': - print("\nCompartmentName&Node Pool Name:Node Pool Type, Nodepool Kubernetes Version, Shape, Source Details, Number of Nodes, Worker Node Subnet and Availability Domain(AD1|AD2|AD3) fields are mandatory. \n\nPlease fix it for row : {} and try again.".format(i+3)) + print("\nCompartmentName@Node Pool Name:Node Pool Type, Nodepool Kubernetes Version, Shape, Source Details, Number of Nodes, Worker Node Network Details and Availability Domain(AD1|AD2|AD3) fields are mandatory. \n\nPlease fix it for row : {} and try again.".format(i+3)) print("\n** Exiting **") exit(1) @@ -152,8 +157,8 @@ def create_terraform_oke(inputfile, outdir, service_dir, prefix, ct): ''' if str(df.loc[i, 'Network Type']).lower() == 'oci_vcn_ip_native': - if str(df.loc[i, 'Pod Communication Subnet']).lower() == 'nan': - print("\nPod Communication Subnet required for cluster with networking type:OCI_VCN_IP_NATIVE") + if str(df.loc[i, 'Pod Communication Network Details']).lower() == 'nan': + print("\nPod Communication Network Details required for cluster with networking type:OCI_VCN_IP_NATIVE") print("\n** Exiting **") exit(1) ''' @@ -197,12 +202,12 @@ def create_terraform_oke(inputfile, outdir, service_dir, prefix, ct): cluster_tf_name = commonTools.check_tf_variable(columnvalue) tempdict = {'cluster_tf_name': cluster_tf_name, 'cluster_display_name': columnvalue} - if columnname == "CompartmentName&Node Pool Name:Node Pool Type": + if columnname == "CompartmentName@Node Pool Name:Node Pool Type": if columnvalue != '': try: - node_compartment = columnvalue.split("&")[0] + node_compartment = columnvalue.split("@")[0] node_compartment = commonTools.check_tf_variable(node_compartment) - nodepool_tf_name_type = columnvalue.split("&")[1] + nodepool_tf_name_type = columnvalue.split("@")[1] nodepool_tf_name = nodepool_tf_name_type.split(":")[0] nodepool_tf_name = commonTools.check_tf_variable(nodepool_tf_name) nodepool_display_name = nodepool_tf_name @@ -222,10 +227,6 @@ def create_terraform_oke(inputfile, outdir, service_dir, prefix, ct): columnvalue = columnvalue.strip() tempdict = {'shape': [columnvalue]} - oke_lb_subnets_list = [] - #network_compartment_id = '' - #vcn_name = '' - if columnname == "SSH Key Var Name": if columnvalue.strip() != '' and columnvalue.strip().lower() != 'nan': if "ssh-rsa" in columnvalue.strip(): @@ -242,111 +243,124 @@ def create_terraform_oke(inputfile, outdir, service_dir, prefix, ct): taints='nan' tempdict = {'taints': taints} - - if columnname == 'Load Balancer Subnets': - oke_lb_subnets = str(columnvalue).strip().split(",") - if len(oke_lb_subnets) == 1: - if len(oke_lb_subnets[0]) == 0: - pass - elif ("ocid1.subnet.oc1" in str(oke_lb_subnets[0]).strip()): - oke_lb_subnets_list.append(str(oke_lb_subnets[0]).strip()) - network_compartment_id = '' - vcn_name = '' - else: - subnet_tf_name = commonTools.check_tf_variable(str(oke_lb_subnets[0]).strip()) - try: - key = region, subnet_tf_name - network_compartment_id = commonTools.check_tf_variable(subnets.vcn_subnet_map[key][0]) - vcn_name = subnets.vcn_subnet_map[key][1] - oke_lb_subnets_list.append(subnets.vcn_subnet_map[key][2]) - except Exception as e: - print("Invalid Subnet Name specified for row {} and column \"{}\". It Doesnt exist in Subnets sheet. Exiting!!!".format(i+3,columnname)) - exit(1) - tempdict = {'network_compartment_tf_name': network_compartment_id, 'vcn_name': vcn_name,'oke_lb_subnets': json.dumps(oke_lb_subnets_list)} + oke_lb_subnets_list = [] + if columnname == 'Load Balancer Network Details': + if columnvalue!='': + oke_lb_subnets = str(columnvalue).strip().split(",") + if len(oke_lb_subnets) == 1: + columnvalue = str(oke_lb_subnets[0]).strip() + if ("ocid1.subnet.oc" in columnvalue): + subnet_id = columnvalue + oke_lb_subnets_list.append(subnet_id) + tempdict = {'oke_lb_subnets': json.dumps(oke_lb_subnets_list)} + + elif columnvalue.lower() != 'nan' and columnvalue.lower() != '': + if len(columnvalue.split("@")) == 2: + network_compartment_id = commonTools.check_tf_variable(columnvalue.split("@")[0].strip()) + vcn_subnet_name = columnvalue.split("@")[1].strip() + else: + network_compartment_id = commonTools.check_tf_variable(str(df.loc[i, 'Compartment Name']).strip()) + vcn_subnet_name = columnvalue + if ("::" not in vcn_subnet_name): + print("Invalid Network Details format specified for row " + str(i + 3) + ". Exiting!!!") + exit(1) + else: + vcn_name = vcn_subnet_name.split("::")[0].strip() + subnet_id = vcn_subnet_name.split("::")[1].strip() + oke_lb_subnets_list.append(subnet_id) + tempdict = {'network_compartment_tf_name': network_compartment_id, 'vcn_name': vcn_name,'oke_lb_subnets': json.dumps(oke_lb_subnets_list)} elif len(oke_lb_subnets) > 1: for subnet in oke_lb_subnets: - if "ocid1.subnet.oc1" in subnet: - oke_lb_subnets_list.append(str(subnet).strip()) - else: - subnet_tf_name = commonTools.check_tf_variable(str(subnet).strip()) - try: - key = region, subnet_tf_name - network_compartment_id = commonTools.check_tf_variable(subnets.vcn_subnet_map[key][0]) - vcn_name = subnets.vcn_subnet_map[key][1] - oke_lb_subnets_list.append(subnets.vcn_subnet_map[key][2]) - except Exception as e: - print("Invalid Subnet Name specified for row {} and column \"{}\". It Doesnt exist in Subnets sheet. Exiting!!!".format(i+3,columnname)) + columnvalue = subnet + if ("ocid1.subnet.oc" in columnvalue): + subnet_id = columnvalue + oke_lb_subnets_list.append(subnet_id) + tempdict = {'oke_lb_subnets': json.dumps(oke_lb_subnets_list)} + elif columnvalue.lower() != 'nan' and columnvalue.lower() != '': + if len(columnvalue.split("@")) == 2: + network_compartment_id = commonTools.check_tf_variable( + columnvalue.split("@")[0].strip()) + vcn_subnet_name = columnvalue.split("@")[1].strip() + else: + network_compartment_id = commonTools.check_tf_variable( + str(df.loc[i, 'Compartment Name']).strip()) + vcn_subnet_name = columnvalue + if ("::" not in vcn_subnet_name): + print("Invalid Network Details format specified for row " + str(i + 3) + ". Exiting!!!") exit(1) - tempdict = {'network_compartment_tf_name': network_compartment_id, 'vcn_name': vcn_name,'oke_lb_subnets': json.dumps(oke_lb_subnets_list) } - - if columnname == 'API Endpoint Subnet': - subnet_tf_name = str(columnvalue).strip().split() - if len(subnet_tf_name) == 1: - if len(subnet_tf_name[0]) == 0: - pass - elif ("ocid1.subnet.oc1" in str(subnet_tf_name[0]).strip()): - api_endpoint_subnet = str(subnet_tf_name[0]).strip() - network_compartment_id = '' - vcn_name = '' + else: + vcn_name = vcn_subnet_name.split("::")[0].strip() + subnet_id = vcn_subnet_name.split("::")[1].strip() + oke_lb_subnets_list.append(subnet_id) + tempdict = {'network_compartment_id': network_compartment_id, 'vcn_name': vcn_name, + 'oke_lb_subnets': json.dumps(oke_lb_subnets_list)} + + if columnname == 'API Endpoint Network Details': + columnvalue = columnvalue.strip() + if ("ocid1.subnet.oc" in columnvalue): + network_compartment_id="root" + vcn_name="" + subnet_id = columnvalue + elif columnvalue.lower() != 'nan' and columnvalue.lower() != '': + if len(columnvalue.split("@")) == 2: + network_compartment_id = commonTools.check_tf_variable(columnvalue.split("@")[0].strip()) + vcn_subnet_name = columnvalue.split("@")[1].strip() else: - try: - key = region, str(subnet_tf_name[0]).strip() - network_compartment_id = commonTools.check_tf_variable(subnets.vcn_subnet_map[key][0]) - vcn_name = subnets.vcn_subnet_map[key][1] - api_endpoint_subnet = subnets.vcn_subnet_map[key][2] - except Exception as e: - print("Invalid Subnet Name specified for row {} and column \"{}\". It Doesnt exist in Subnets sheet. Exiting!!!".format(i+3,columnname)) - exit(1) - tempdict = {'network_compartment_tf_name': network_compartment_id, 'vcn_name': vcn_name,'api_endpoint_subnet': api_endpoint_subnet} - elif len(subnet_tf_name) > 1: - print("Invalid Subnet Values for row {} and column \"{}\". Only one subnet allowed".format(i+3,columnname)) - exit(1) + network_compartment_id = commonTools.check_tf_variable( + str(df.loc[i, 'Compartment Name']).strip()) + vcn_subnet_name = columnvalue + if ("::" not in vcn_subnet_name): + print("Invalid Network Details format specified for row " + str(i + 3) + ". Exiting!!!") + exit(1) + else: + vcn_name = vcn_subnet_name.split("::")[0].strip() + subnet_id = vcn_subnet_name.split("::")[1].strip() + tempdict = {'network_compartment_tf_name': network_compartment_id, 'vcn_name': vcn_name, + 'api_endpoint_subnet': subnet_id} - if columnname == 'Worker Node Subnet': - subnet_tf_name = str(columnvalue).strip().split() - if len(subnet_tf_name) == 1: - if len(subnet_tf_name[0]) == 0: - pass - elif subnet_tf_name != "": - if ("ocid1.subnet.oc1" in str(subnet_tf_name[0]).strip()): - worker_node_subnet = str(subnet_tf_name[0]).strip() - network_compartment_id = '' - vcn_name = '' - else: - try: - key = region, str(subnet_tf_name[0]).strip() - network_compartment_id = commonTools.check_tf_variable(subnets.vcn_subnet_map[key][0]) - vcn_name = subnets.vcn_subnet_map[key][1] - worker_node_subnet = subnets.vcn_subnet_map[key][2] - except Exception as e: - print("Invalid Subnet Name specified for row {} and column \"{}\". It Doesnt exist in Subnets sheet. Exiting!!!".format(i+3,columnname)) - exit(1) + if columnname == 'Worker Node Network Details': + columnvalue = columnvalue.strip() + if ("ocid1.subnet.oc" in columnvalue): + subnet_id = columnvalue + tempdict = {'worker_node_subnet': subnet_id} + elif columnvalue.lower() != 'nan' and columnvalue.lower() != '': + if len(columnvalue.split("@")) == 2: + network_compartment_id = commonTools.check_tf_variable(columnvalue.split("@")[0].strip()) + vcn_subnet_name = columnvalue.split("@")[1].strip() else: - worker_node_subnet = "" - tempdict = {'network_compartment_tf_name': network_compartment_id, 'vcn_name': vcn_name,'worker_node_subnet': worker_node_subnet} - elif len(subnet_tf_name) > 1: - print("Invalid Subnet Values for row {} and column \"{}\". Only one subnet allowed".format(i+3,columnname)) - exit(1) + network_compartment_id = commonTools.check_tf_variable( + str(df.loc[i, 'Compartment Name']).strip()) + vcn_subnet_name = columnvalue + if ("::" not in vcn_subnet_name): + print("Invalid Network Details format specified for row " + str(i + 3) + ". Exiting!!!") + exit(1) + else: + vcn_name = vcn_subnet_name.split("::")[0].strip() + subnet_id = vcn_subnet_name.split("::")[1].strip() + tempdict = {'network_compartment_tf_name': network_compartment_id, 'vcn_name': vcn_name, + 'worker_node_subnet': subnet_id} - if columnname == 'Pod Communication Subnet': - subnet_tf_name = columnvalue.strip() - if subnet_tf_name != "": - if ("ocid1.subnet.oc1" in subnet_tf_name): - pod_communication_subnet = subnet_tf_name - network_compartment_id = '' - vcn_name = '' + if columnname == 'Pod Communication Network Details': + columnvalue = columnvalue.strip() + if ("ocid1.subnet.oc" in columnvalue): + subnet_id = columnvalue + tempdict = {'pod_communication_subnet': subnet_id} + elif columnvalue.lower() != 'nan' and columnvalue.lower() != '': + if len(columnvalue.split("@")) == 2: + network_compartment_id = commonTools.check_tf_variable(columnvalue.split("@")[0].strip()) + vcn_subnet_name = columnvalue.split("@")[1].strip() else: - try: - key = region, subnet_tf_name - network_compartment_id = commonTools.check_tf_variable(subnets.vcn_subnet_map[key][0]) - vcn_name = subnets.vcn_subnet_map[key][1] - pod_communication_subnet = subnets.vcn_subnet_map[key][2] - except Exception as e: - print("Invalid Subnet Name specified for row {} and column \"{}\". It Doesnt exist in Subnets sheet. Exiting!!!".format(i+3,columnname)) - exit(1) - else: - pod_communication_subnet = "" - tempdict = {'network_compartment_tf_name': network_compartment_id, 'vcn_name': vcn_name,'pod_communication_subnet': pod_communication_subnet} + network_compartment_id = commonTools.check_tf_variable( + str(df.loc[i, 'Compartment Name']).strip()) + vcn_subnet_name = columnvalue + if ("::" not in vcn_subnet_name): + print("Invalid Network Details format specified for row " + str(i + 3) + ". Exiting!!!") + exit(1) + else: + vcn_name = vcn_subnet_name.split("::")[0].strip() + subnet_id = vcn_subnet_name.split("::")[1].strip() + tempdict = {'network_compartment_tf_name': network_compartment_id, 'vcn_name': vcn_name, + 'pod_communication_subnet': subnet_id} if columnname == "API Endpoint NSGs": if columnvalue != '' and columnvalue.strip().lower() != 'nan': @@ -402,6 +416,7 @@ def create_terraform_oke(inputfile, outdir, service_dir, prefix, ct): node_str[region] = node_str[region] + node.render(tempStr) elif nodepool_type=='virtual': virtual_node_str[region] = virtual_node_str[region] + virtual_node.render(tempStr) + if i!=0 and (df.loc[i, 'Cluster Name'] == df.loc[i-1, 'Cluster Name']) and (df.loc[i, 'Region'] == df.loc[i-1, 'Region']): continue cluster_str[region] = cluster_str[region] + cluster.render(tempStr) @@ -417,7 +432,6 @@ def create_terraform_oke(inputfile, outdir, service_dir, prefix, ct): cluster_str[reg] = cluster.render(skeleton=True, count=0, region=reg).replace(src,cluster_str[reg]+"\n"+src) cluster_str[reg] = "".join([s for s in cluster_str[reg].strip().splitlines(True) if s.strip("\r\n").strip()]) resource = sheetName.lower() - commonTools.backup_file(reg_out_dir, resource, cluster_auto_tfvars_filename) # Write to TF file outfile = reg_out_dir + "/" + cluster_auto_tfvars_filename @@ -433,7 +447,7 @@ def create_terraform_oke(inputfile, outdir, service_dir, prefix, ct): node_str[reg] = node.render(skeleton=True, count=0, region=reg).replace(src,node_str[reg]+"\n"+src) node_str[reg] = "".join([s for s in node_str[reg].strip().splitlines(True) if s.strip("\r\n").strip()]) resource = sheetName.lower() - commonTools.backup_file(reg_out_dir, resource, nodepool_auto_tfvars_filename) + # Write to TF file outfile = reg_out_dir + "/" + nodepool_auto_tfvars_filename @@ -449,7 +463,6 @@ def create_terraform_oke(inputfile, outdir, service_dir, prefix, ct): virtual_node_str[reg] = virtual_node.render(skeleton=True, count=0, region=reg).replace(src,virtual_node_str[reg]+"\n"+src) virtual_node_str[reg] = "".join([s for s in virtual_node_str[reg].strip().splitlines(True) if s.strip("\r\n").strip()]) resource = sheetName.lower() - commonTools.backup_file(reg_out_dir, resource, virtual_nodepool_auto_tfvars_filename) # Write to TF file outfile = reg_out_dir + "/" + virtual_nodepool_auto_tfvars_filename diff --git a/cd3_automation_toolkit/DeveloperServices/OKE/export_oke_nonGreenField.py b/cd3_automation_toolkit/DeveloperServices/OKE/export_oke_nonGreenField.py index c76ab0322..d00f490da 100644 --- a/cd3_automation_toolkit/DeveloperServices/OKE/export_oke_nonGreenField.py +++ b/cd3_automation_toolkit/DeveloperServices/OKE/export_oke_nonGreenField.py @@ -11,6 +11,7 @@ import oci import os import re +import subprocess as sp from oci.core.virtual_network_client import VirtualNetworkClient from oci.container_engine import ContainerEngineClient from oci.config import DEFAULT_LOCATION @@ -18,7 +19,7 @@ sys.path.append(os.getcwd() + "/..") -def print_oke(values_for_column_oke, reg, compartment_name, compartment_name_nodepool,nodepool_count, nodepool_info,cluster_info,network,nodepool_type): +def print_oke(values_for_column_oke, reg, compartment_name, compartment_name_nodepool,nodepool_count, nodepool_info,cluster_info,network,nodepool_type,ct): image_policy_config = cluster_info.image_policy_config for col_header in values_for_column_oke.keys(): if (col_header == "Region"): @@ -61,26 +62,40 @@ def print_oke(values_for_column_oke, reg, compartment_name, compartment_name_nod cluster_info.options.admission_controller_options.is_pod_security_policy_enabled) else: values_for_column_oke[col_header].append(None) - elif col_header == 'Load Balancer Subnets': + elif col_header == 'Load Balancer Network Details': if nodepool_count <=1: subnets = [] for id in cluster_info.options.service_lb_subnet_ids: try: vcn = network.get_vcn(vcn_id=(network.get_subnet(subnet_id=id).data.vcn_id)).data.display_name subnet = network.get_subnet(subnet_id=id).data.display_name - combined = vcn + "_" + subnet + + ntk_compartment_id = network.get_vcn(vcn_id=(network.get_subnet(subnet_id=id).data.vcn_id)).data.compartment_id # compartment-id + network_compartment_name = compartment_name + for comp_name, comp_id in ct.ntk_compartment_ids.items(): + if comp_id == ntk_compartment_id: + network_compartment_name = comp_name + + combined = network_compartment_name + "@" + vcn + "::" + subnet except Exception as e: combined = id subnets.append(combined) values_for_column_oke[col_header].append(','.join(subnets)) else: values_for_column_oke[col_header].append(None) - elif col_header == 'API Endpoint Subnet': + elif col_header == 'API Endpoint Network Details': if nodepool_count <= 1: try: vcn = network.get_vcn(vcn_id=(network.get_subnet(subnet_id=cluster_info.endpoint_config.subnet_id).data.vcn_id)).data.display_name subnet = network.get_subnet(subnet_id=cluster_info.endpoint_config.subnet_id).data.display_name - combined = vcn + "_" + subnet + ntk_compartment_id = network.get_vcn( + vcn_id=(network.get_subnet(subnet_id=cluster_info.endpoint_config.subnet_id).data.vcn_id)).data.compartment_id # compartment-id + network_compartment_name = compartment_name + for comp_name, comp_id in ct.ntk_compartment_ids.items(): + if comp_id == ntk_compartment_id: + network_compartment_name = comp_name + + combined = network_compartment_name + "@" + vcn + "::" + subnet except Exception as e: combined = id values_for_column_oke[col_header].append(combined) @@ -115,13 +130,13 @@ def print_oke(values_for_column_oke, reg, compartment_name, compartment_name_nod values_for_column_oke[col_header].append(','.join(nsgs)) else: values_for_column_oke[col_header].append(None) - elif (col_header == "CompartmentName&Node Pool Name:Node Pool Type"): + elif (col_header == "CompartmentName@Node Pool Name:Node Pool Type"): if (nodepool_info != None): if nodepool_type=="managed": - comp_np_value = compartment_name_nodepool + "&" + nodepool_info.name+":Managed" + comp_np_value = compartment_name_nodepool + "@" + nodepool_info.name+":Managed" values_for_column_oke[col_header].append(comp_np_value) elif nodepool_type == "virtual": - comp_np_value = compartment_name_nodepool + "&" + nodepool_info.display_name + ":Virtual" + comp_np_value = compartment_name_nodepool + "@" + nodepool_info.display_name + ":Virtual" values_for_column_oke[col_header].append(comp_np_value) else: @@ -193,7 +208,7 @@ def print_oke(values_for_column_oke, reg, compartment_name, compartment_name_nod else: values_for_column_oke[col_header].append(None) - elif (col_header == "Worker Node Subnet"): + elif (col_header == "Worker Node Network Details"): if (nodepool_info != None): subnet_id = "" if (nodepool_type=='managed'): @@ -203,7 +218,14 @@ def print_oke(values_for_column_oke, reg, compartment_name, compartment_name_nod try: vcn = network.get_vcn(vcn_id=(network.get_subnet(subnet_id=subnet_id).data.vcn_id)).data.display_name subnet = network.get_subnet(subnet_id=subnet_id).data.display_name - combined = vcn + "_" + subnet + ntk_compartment_id = network.get_vcn( + vcn_id=(network.get_subnet(subnet_id=subnet_id).data.vcn_id)).data.compartment_id # compartment-id + network_compartment_name = compartment_name + for comp_name, comp_id in ct.ntk_compartment_ids.items(): + if comp_id == ntk_compartment_id: + network_compartment_name = comp_name + + combined = network_compartment_name + "@" + vcn + "::" + subnet except Exception as e: combined = id values_for_column_oke[col_header].append(combined) @@ -272,7 +294,7 @@ def print_oke(values_for_column_oke, reg, compartment_name, compartment_name_nod values_for_column_oke[col_header].append(','.join(nsgs)) else: values_for_column_oke[col_header].append(None) - elif (col_header == "Pod Communication Subnet"): + elif (col_header == "Pod Communication Network Details"): if (nodepool_info != None): if nodepool_type == "managed": if nodepool_info.node_config_details.node_pool_pod_network_option_details.cni_type == "OCI_VCN_IP_NATIVE": @@ -281,7 +303,14 @@ def print_oke(values_for_column_oke, reg, compartment_name, compartment_name_nod try: vcn = network.get_vcn(vcn_id=(network.get_subnet(subnet_id=id).data.vcn_id)).data.display_name subnet = network.get_subnet(subnet_id=id).data.display_name - combined = vcn + "_" + subnet + ntk_compartment_id = network.get_vcn(vcn_id=( + network.get_subnet(subnet_id=id).data.vcn_id)).data.compartment_id # compartment-id + network_compartment_name = compartment_name + for comp_name, comp_id in ct.ntk_compartment_ids.items(): + if comp_id == ntk_compartment_id: + network_compartment_name = comp_name + + combined = network_compartment_name + "@" + vcn + "::" + subnet except Exception as e: combined = id subnets.append(combined) @@ -293,7 +322,14 @@ def print_oke(values_for_column_oke, reg, compartment_name, compartment_name_nod try: vcn = network.get_vcn(vcn_id=(network.get_subnet(subnet_id=pod_subnet_id).data.vcn_id)).data.display_name subnet = network.get_subnet(subnet_id=pod_subnet_id).data.display_name - combined = vcn + "_" + subnet + ntk_compartment_id = network.get_vcn( + vcn_id=(network.get_subnet(subnet_id=pod_subnet_id).data.vcn_id)).data.compartment_id # compartment-id + network_compartment_name = compartment_name + for comp_name, comp_id in ct.ntk_compartment_ids.items(): + if comp_id == ntk_compartment_id: + network_compartment_name = comp_name + + combined = network_compartment_name + "@" + vcn + "::" + subnet except Exception as e: combined = id values_for_column_oke[col_header].append(combined) @@ -402,7 +438,9 @@ def export_oke(inputfile, outdir,service_dir, config, signer, ct, export_compart global importCommands global tf_import_cmd global values_for_column_oke - global sheet_dict_oke + global sheet_dict_oke,tf_or_tofu + tf_or_tofu = ct.tf_or_tofu + tf_state_list = [tf_or_tofu, "state", "list"] cd3file = inputfile if ('.xls' not in cd3file): @@ -410,12 +448,11 @@ def export_oke(inputfile, outdir,service_dir, config, signer, ct, export_compart exit() sheetName = "OKE" - resource = 'tf_import_' + sheetName.lower() - file_name = 'tf_import_commands_' + sheetName.lower() + '_nonGF.sh' + resource = 'import_' + sheetName.lower() + file_name = 'import_commands_' + sheetName.lower() + '.sh' importCommands={} - df, values_for_column_oke = commonTools.read_cd3(cd3file, "OKE") # Get dict for columns from Excel_Columns @@ -427,23 +464,27 @@ def export_oke(inputfile, outdir,service_dir, config, signer, ct, export_compart # Create backups for reg in export_regions: script_file = f'{outdir}/{reg}/{service_dir}/' + file_name - if os.path.exists(script_file): - commonTools.backup_file(outdir + "/" + reg+"/"+service_dir, resource, file_name) - importCommands[reg] = open(script_file, "w") - importCommands[reg].write("#!/bin/bash") - importCommands[reg].write("\n") - importCommands[reg].write("terraform init") + if (os.path.exists(script_file)): + commonTools.backup_file(outdir + "/" + reg + "/" + service_dir, resource, file_name) + importCommands[reg] = '' # Fetch OKE Details print("\nFetching details of OKE...") tempImageDict = {} tempsshDict = {} + total_resources = 0 for reg in export_regions: script_file = f'{outdir}/{reg}/{service_dir}/' + file_name - importCommands[reg].write("\n\n######### Writing import for OKE Objects #########\n\n") - importCommands[reg].write("\n\n######### Writing import for OKE Objects #########\n\n") config.__setitem__("region", ct.region_dict[reg]) + state = {'path': f'{outdir}/{reg}/{service_dir}', 'resources': []} + try: + byteOutput = sp.check_output(tf_state_list, cwd=state["path"], stderr=sp.DEVNULL) + output = byteOutput.decode('UTF-8').rstrip() + for item in output.split('\n'): + state["resources"].append(item.replace("\"", "\\\"")) + except Exception as e: + pass oke = ContainerEngineClient(config=config, retry_strategy=oci.retry.DEFAULT_RETRY_STRATEGY,signer=signer) network = VirtualNetworkClient(config=config, retry_strategy=oci.retry.DEFAULT_RETRY_STRATEGY,signer=signer) @@ -454,16 +495,18 @@ def export_oke(inputfile, outdir,service_dir, config, signer, ct, export_compart compartment_name], lifecycle_state=["ACTIVE"],sort_by="TIME_CREATED") clusterList.extend(clusterResponse.data) + total_resources +=len(clusterList) for cluster_info in clusterList: empty_cluter = True nodepool_count = 0 nodepool_info = None nodepool_type="" - importCommands[reg] = open(script_file, "a") cluster_display_name = cluster_info.name cluster_tf_name = commonTools.check_tf_variable(cluster_display_name) - importCommands[reg].write("\nterraform import \"module.clusters[\\\"" + str(cluster_tf_name) + "\\\"].oci_containerengine_cluster.cluster\" " + cluster_info.id) + tf_resource = f'module.clusters[\\"{str(cluster_tf_name)}\\"].oci_containerengine_cluster.cluster' + if tf_resource not in state["resources"]: + importCommands[reg] += f'\n{tf_or_tofu} import "{tf_resource}" {cluster_info.id}' for compartment_name_nodepool in export_compartments: nodepoolList = [] @@ -486,13 +529,14 @@ def export_oke(inputfile, outdir,service_dir, config, signer, ct, export_compart empty_cluter = False nodepool_count=nodepool_count+1 - importCommands[reg] = open(script_file, "a") #Virtual NodePool if ("ocid1.virtualnodepool.oc1" in nodepool_info.id): nodepool_display_name = nodepool_info.display_name np_tf_name = commonTools.check_tf_variable(nodepool_display_name) - importCommands[reg].write("\nterraform import \"module.virtual-nodepools[\\\"" + str(cluster_tf_name) + "_" + str(np_tf_name) + "\\\"].oci_containerengine_virtual_node_pool.virtual_nodepool\" " + nodepool_info.id) + tf_resource = f'module.virtual-nodepools[\\"{cluster_tf_name}_{np_tf_name}\\"].oci_containerengine_virtual_node_pool.virtual_nodepool' + if tf_resource not in state["resources"]: + importCommands[reg] += f'\n{tf_or_tofu} import "{tf_resource}" {nodepool_info.id}' nodepool_type = "virtual" # Managed NodePool @@ -500,8 +544,9 @@ def export_oke(inputfile, outdir,service_dir, config, signer, ct, export_compart nodepool_display_name = nodepool_info.name np_tf_name = commonTools.check_tf_variable(nodepool_display_name) nodepool_type = "managed" - importCommands[reg].write("\nterraform import \"module.nodepools[\\\"" + str(cluster_tf_name) + "_" + str( - np_tf_name) + "\\\"].oci_containerengine_node_pool.nodepool\" " + nodepool_info.id) + tf_resource = f'module.nodepools[\\"{cluster_tf_name}_{np_tf_name}\\"].oci_containerengine_node_pool.nodepool' + if tf_resource not in state["resources"]: + importCommands[reg] += f'\n{tf_or_tofu} import "{tf_resource}" {nodepool_info.id}' # Extract the image details tempImageDict[reg + "::" + commonTools.check_tf_variable(nodepool_info.node_source.source_name)] = nodepool_info.node_source.image_id @@ -511,10 +556,10 @@ def export_oke(inputfile, outdir,service_dir, config, signer, ct, export_compart elif nodepool_info.ssh_public_key: tempsshDict[reg + "::" + commonTools.check_tf_variable(cluster_display_name + "_" + nodepool_info.name) + "_" + nodepool_info.id[-6:]] = nodepool_info.ssh_public_key - print_oke(values_for_column_oke,reg, compartment_name, compartment_name_nodepool,nodepool_count,nodepool_info,cluster_info,network,nodepool_type) + print_oke(values_for_column_oke,reg, compartment_name, compartment_name_nodepool,nodepool_count,nodepool_info,cluster_info,network,nodepool_type,ct) if(empty_cluter==True): - print_oke(values_for_column_oke, reg, compartment_name, compartment_name_nodepool,nodepool_count, nodepool_info,cluster_info,network,nodepool_type) + print_oke(values_for_column_oke, reg, compartment_name, compartment_name_nodepool,nodepool_count, nodepool_info,cluster_info,network,nodepool_type,ct) # write oke image ocids and ssh keys @@ -571,11 +616,13 @@ def export_oke(inputfile, outdir,service_dir, config, signer, ct, export_compart # writing data for reg in export_regions: - script_file = f'{outdir}/{reg}/{service_dir}/tf_import_commands_oke_nonGF.sh' - with open(script_file, 'a') as importCommands[reg]: - importCommands[reg].write('\n\nterraform plan\n') + script_file = f'{outdir}/{reg}/{service_dir}/' + file_name + init_commands = f'\n######### Writing import for OKE #########\n\n#!/bin/bash\n{tf_or_tofu} init' + if importCommands[reg] != "": + importCommands[reg] += f'\n{tf_or_tofu} plan\n' + with open(script_file, 'a') as importCommandsfile: + importCommandsfile.write(init_commands + importCommands[reg]) commonTools.write_to_cd3(values_for_column_oke, cd3file, "OKE") - - print("{0} OKE exported into CD3.\n".format(len(values_for_column_oke["Region"]))) + print("{0} OKE clusters exported into CD3.\n".format(total_resources)) diff --git a/cd3_automation_toolkit/DeveloperServices/ResourceManager/create_resource_manager_stack.py b/cd3_automation_toolkit/DeveloperServices/ResourceManager/create_resource_manager_stack.py index 106dc6359..1377eab63 100644 --- a/cd3_automation_toolkit/DeveloperServices/ResourceManager/create_resource_manager_stack.py +++ b/cd3_automation_toolkit/DeveloperServices/ResourceManager/create_resource_manager_stack.py @@ -34,7 +34,7 @@ def create_rm(service_rm_name, comp_id,ocs_stack,svcs): stackdetails.description = "Created by Automation ToolKit" else: stackdetails.description = "Created by Automation ToolKit for services - "+ ','.join(svcs) - stackdetails.terraform_version = "1.0.x" + stackdetails.terraform_version = "1.5.x" stackdetails.compartment_id = comp_id stackdetails.display_name = service_rm_name @@ -63,7 +63,7 @@ def update_rm(service_rm_name,service_rm_ocid,ocs_stack,svcs): zipConfigSource.config_source_type = 'ZIP_UPLOAD' zipConfigSource.zip_file_base64_encoded = encodedZip updatestackdetails.config_source = zipConfigSource - updatestackdetails.terraform_version = "1.0.x" + updatestackdetails.terraform_version = "1.5.x" if svcs == []: updatestackdetails.description = "Updated by Automation ToolKit" else: @@ -136,10 +136,10 @@ def create_resource_manager(outdir,var_file, outdir_struct,prefix,auth_mechanism for line in origfile: if 'version' in line or 'tenancy_ocid' in line or "user_ocid" in line or "fingerprint" in line or "private_key_path" in line: pass - elif 'terraform {' in line: - experimental_line = "experiments = [module_variable_optional_attrs]" - line = line + "\n " + experimental_line + "\n " - newfile.write(line) + #elif 'terraform {' in line: + # experimental_line = "experiments = [module_variable_optional_attrs]" + # line = line + "\n " + experimental_line + "\n " + # newfile.write(line) else: newfile.write(line) except FileNotFoundError as e: @@ -150,10 +150,12 @@ def create_resource_manager(outdir,var_file, outdir_struct,prefix,auth_mechanism try: with open(region_dir + '/variables_' + region + '.tf') as origfile, open(rm_dir + '/variables_' + region + '.tf', 'w') as newfile: for line in origfile: + ''' if 'gateway_route_table = optional(bool,false)' in line: line = line.replace('gateway_route_table = optional(bool,false)','gateway_route_table = optional(bool)') if 'default_route_table = optional(bool,false)' in line: line = line.replace('default_route_table = optional(bool,false)','default_route_table = optional(bool)') + ''' if "user_ocid" in line or "fingerprint" in line or "private_key_path" in line: skipline = True if not skipline: @@ -171,10 +173,11 @@ def create_resource_manager(outdir,var_file, outdir_struct,prefix,auth_mechanism for line in origfile: if 'version' in line or 'tenancy_ocid' in line or "user_ocid" in line or "fingerprint" in line or "private_key_path" in line: pass - elif 'terraform {' in line: - experimental_line = "experiments = [module_variable_optional_attrs]" - line = line+"\n "+experimental_line+"\n " - newfile.write(line) + + #elif 'terraform {' in line: + # experimental_line = "experiments = [module_variable_optional_attrs]" + # line = line+"\n "+experimental_line+"\n " + # newfile.write(line) else: newfile.write(line) except FileNotFoundError as e: @@ -185,12 +188,14 @@ def create_resource_manager(outdir,var_file, outdir_struct,prefix,auth_mechanism try: with open(region_dir+'/'+service_dir+'/variables_' + region + '.tf') as origfile, open(rm_dir + '/'+ service_dir +'/variables_' + region + '.tf','w') as newfile: for line in origfile: + ''' if 'gateway_route_table = optional(bool,false)' in line: line = line.replace('gateway_route_table = optional(bool,false)', 'gateway_route_table = optional(bool)') if 'default_route_table = optional(bool,false)' in line: line = line.replace('default_route_table = optional(bool,false)', 'default_route_table = optional(bool)') + ''' if "user_ocid" in line or "fingerprint" in line or "private_key_path" in line: skipline = True if not skipline: diff --git a/cd3_automation_toolkit/Excel_Columns b/cd3_automation_toolkit/Excel_Columns index 9bd2b229f..045eff600 100644 --- a/cd3_automation_toolkit/Excel_Columns +++ b/cd3_automation_toolkit/Excel_Columns @@ -106,7 +106,7 @@ }, "LB-BackendSet-BackendServer" : { - "Backend ServerComp&ServerName:Port" : "backend_server_name:port", + "Backend ServerComp@ServerName:Port" : "backend_server_name:port", "Backend Set Name" : "backend_set_name", "Certificate Name or OCID" : "certificates", "Backend Policy(LEAST_CONNECTIONS|ROUND_ROBIN|IP_HASH)" : "policy", @@ -144,6 +144,10 @@ "LB-PathRouteSet": { "Path Route Set Name" : "name" + }, + "LB-RoutingPolicy": + { + "Display Name" : "display_name" }, "Common-LBR-Headers" : { @@ -165,7 +169,7 @@ "Service CIDR Block" : "services_cidr", "Pod CIDR Block" : "pods_cidr", "API Endpoint NSGs" : "nsg_ids", - "CompartmentName&Node Pool Name" : "nodepool_display_name", + "CompartmentName@Node Pool Name" : "nodepool_display_name", "Policy KMS Key ID" : "image_policy_config.key_details.kms_key_id" }, @@ -236,7 +240,7 @@ "NLB-BackendSets-BackendServers" : { "Is Preserve Source(True|False)" : "is_preserve_source", - "Backend ServerComp&ServerName:Port" : "backend_server_name:port", + "Backend ServerComp@ServerName:Port" : "backend_server_name:port", "Backend Set Name" : "backend_set_name", "Backend Policy(FIVE_TUPLE|THREE_TUPLE|TWO_TUPLE)" : "policy", "Backend HealthCheck Protocol(HTTP|HTTPS|TCP|UDP|DNS)" : "protocol", diff --git a/cd3_automation_toolkit/Governance/Quota/create_terraform_quotas.py b/cd3_automation_toolkit/Governance/Quota/create_terraform_quotas.py index 32855f4e0..bbe55bae7 100644 --- a/cd3_automation_toolkit/Governance/Quota/create_terraform_quotas.py +++ b/cd3_automation_toolkit/Governance/Quota/create_terraform_quotas.py @@ -45,6 +45,10 @@ def create_terraform_quotas(inputfile, outdir, service_dir, prefix, ct): # Initialise empty TF string for each region tfStr[ct.home_region] = '' + resource = sheetName.lower() + reg = ct.home_region + reg_out_dir = outdir + "/" + reg + "/" + service_dir + commonTools.backup_file(reg_out_dir + "/", resource, auto_tfvars_filename) # Iterate over rows for i in df.index: @@ -125,10 +129,6 @@ def create_terraform_quotas(inputfile, outdir, service_dir, prefix, ct): src = "##Add New quota-policy for "+reg.lower()+" here##" tfStr[reg] = quota_template.render(count=0, region=reg).replace(src, tfStr[reg]) tfStr[reg] = "".join([s for s in tfStr[reg].strip().splitlines(True) if s.strip("\r\n").strip()]) - - resource = sheetName.lower() - commonTools.backup_file(reg_out_dir + "/", resource, auto_tfvars_filename) - tfStr[reg] = "".join([s for s in tfStr[reg].strip().splitlines(True) if s.strip("\r\n").strip()]) oname[reg] = open(outfile[reg], 'w') oname[reg].write(tfStr[reg]) diff --git a/cd3_automation_toolkit/Governance/Quota/export_quotas_nonGreenField.py b/cd3_automation_toolkit/Governance/Quota/export_quotas_nonGreenField.py index 33a32d490..b324502c5 100644 --- a/cd3_automation_toolkit/Governance/Quota/export_quotas_nonGreenField.py +++ b/cd3_automation_toolkit/Governance/Quota/export_quotas_nonGreenField.py @@ -9,6 +9,7 @@ import sys import oci import os +import subprocess as sp from commonTools import * sys.path.append(os.getcwd()+"/..") @@ -35,9 +36,11 @@ def export_quotas_nongreenfield(inputfile, outdir, service_dir, config, signer, global tf_import_cmd global values_for_column_quotas global sheet_dict_quotas - global importCommands + global importCommands,tf_or_tofu + tf_or_tofu = ct.tf_or_tofu + tf_state_list = [tf_or_tofu, "state", "list"] sheet_name = 'Quotas' - script_file = f'{outdir}/{ct.home_region}/{service_dir}/tf_import_commands_'+sheet_name.lower()+'_nonGF.sh' + script_file = f'{outdir}/{ct.home_region}/{service_dir}/import_commands_'+sheet_name.lower()+'.sh' cd3file = inputfile importCommands = "" if ('.xls' not in cd3file): @@ -55,21 +58,26 @@ def export_quotas_nongreenfield(inputfile, outdir, service_dir, config, signer, # Create backups if os.path.exists(script_file): - commonTools.backup_file(os.path.dirname(script_file), "tf_import_"+sheet_name.lower(), os.path.basename(script_file)) + commonTools.backup_file(os.path.dirname(script_file), "import_"+sheet_name.lower(), os.path.basename(script_file)) # Fetch quotas print("\nFetching quotas...") - config.__setitem__("region", ct.region_dict[ct.home_region]) + reg = (ct.home_region).lower() + config.__setitem__("region", ct.region_dict[reg]) + state = {'path': f'{outdir}/{reg}/{service_dir}', 'resources': []} + try: + byteOutput = sp.check_output(tf_state_list, cwd=state["path"], stderr=sp.DEVNULL) + output = byteOutput.decode('UTF-8').rstrip() + for item in output.split('\n'): + state["resources"].append(item.replace("\"", "\\\"")) + except Exception as e: + pass tenancy_id = config["tenancy"] quotas_client = oci.limits.QuotasClient(config=config,retry_strategy=oci.retry.DEFAULT_RETRY_STRATEGY,signer=signer) region = ct.home_region.lower() quotas_list = oci.pagination.list_call_get_all_results(quotas_client.list_quotas,compartment_id=tenancy_id,lifecycle_state="ACTIVE") if quotas_list.data != []: - importCommands += "\n######### Writing import for quotas #########\n\n" - importCommands += "#!/bin/bash" - importCommands += "\n" - importCommands += "terraform init" for quota_info in quotas_list.data: quota_policy = "" quota = quotas_client.get_quota(quota_id=quota_info.id).data @@ -78,14 +86,17 @@ def export_quotas_nongreenfield(inputfile, outdir, service_dir, config, signer, print_quotas(values_for_column_quotas, region, quota,quota_policy[1:]) quota_tf_name = commonTools.check_tf_variable(quota_info.name) - importCommands += "\nterraform import \"module.quota_policies[\\\"" + quota_tf_name+ "\\\"].oci_limits_quota.quota\" " + str(quota_info.id) + tf_resource = f'module.quota_policies[\\"{quota_tf_name}\\"].oci_limits_quota.quota' + if tf_resource not in state["resources"]: + importCommands += f'\n{tf_or_tofu} import "{tf_resource}" {str(quota_info.id)}' - importCommands += "\nterraform plan" commonTools.write_to_cd3(values_for_column_quotas, cd3file, sheet_name) print("{0} quotas exported into CD3.\n".format(len(values_for_column_quotas["Region"]))) + init_commands = f'\n######### Writing import for Quota #########\n\n#!/bin/bash\n{tf_or_tofu} init' if importCommands != "": + importCommands += f'\n{tf_or_tofu} plan\n' with open(script_file, 'a') as importCommandsfile: - importCommandsfile.write(importCommands) + importCommandsfile.write(init_commands + importCommands) diff --git a/cd3_automation_toolkit/Governance/Tagging/export_tags_nonGreenField.py b/cd3_automation_toolkit/Governance/Tagging/export_tags_nonGreenField.py index 9d4a9e500..003e27372 100644 --- a/cd3_automation_toolkit/Governance/Tagging/export_tags_nonGreenField.py +++ b/cd3_automation_toolkit/Governance/Tagging/export_tags_nonGreenField.py @@ -11,12 +11,12 @@ import oci from oci.identity import IdentityClient import os +import subprocess as sp from commonTools import * sys.path.append(os.getcwd()+"/..") compartment_ids={} -importCommands={} tf_name_namespace_list = [] def add_values_in_dict(sample_dict, key, list_of_values): @@ -27,7 +27,7 @@ def add_values_in_dict(sample_dict, key, list_of_values): sample_dict[key].extend(list_of_values) return sample_dict -def print_tags(values_for_column_tags,region, ntk_compartment_name, tag, tag_key, tag_default_value): +def print_tags(values_for_column_tags,region, ntk_compartment_name, tag, tag_key, tag_default_value,reg,state): validator = '' tag_key_name = '' tag_key_description = '' @@ -84,15 +84,20 @@ def print_tags(values_for_column_tags,region, ntk_compartment_name, tag, tag_ke tf_name_namespace = commonTools.check_tf_variable(tagname) tf_name_key = commonTools.check_tf_variable(tag_key_name) - if (tag.id not in tf_name_namespace_list): - importCommands[region].write("\nterraform import \"module.tag-namespaces[\\\"" + tf_name_namespace + "\\\"].oci_identity_tag_namespace.tag_namespace\" " + str(tag.id)) + tf_resource = f'module.tag-namespaces[\\"{tf_name_namespace}\\"].oci_identity_tag_namespace.tag_namespace' + if tag.id not in tf_name_namespace_list and tf_resource not in state["resources"]: + importCommands[reg] += f'\n{tf_or_tofu} import "{tf_resource}" {str(tag.id)}' tf_name_namespace_list.append(tag.id) - if ( str(tag_key) != "Nan" ): - importCommands[region].write("\nterraform import \"module.tag-keys[\\\""+tf_name_namespace + '_' + tf_name_key + '\\\"].oci_identity_tag.tag\" ' + "tagNamespaces/"+ str(tag.id) +"/tags/\"" + str(tag_key_name) + "\"") - if ( tag_default_value != []): + tf_resource = f'module.tag-keys[\\"{tf_name_namespace}_{tf_name_key}\\"].oci_identity_tag.tag' + if str(tag_key) != "Nan" and tf_resource not in state["resources"]: + importCommands[reg] += f'\n{tf_or_tofu} import "{tf_resource}" tagNamespaces/{str(tag.id)}/tags/{str(tag_key_name)}' + if tag_default_value != []: if len(tag_default_value) != 0: for value in tag_default_value: - importCommands[region].write("\nterraform import \"module.tag-defaults[\\\""+ tf_name_namespace+'_' +tf_name_key + '_' +commonTools.check_tf_variable(value.split("=")[0]).strip()+ '-default'+ '\\\"].oci_identity_tag_default.tag_default\" ' + str(defaultcomp_to_tagid_map[tf_name_key+"-"+commonTools.check_tf_variable(value.split("=")[0])])) + tf_resource = f'module.tag-defaults[\\"{tf_name_namespace}_{tf_name_key}_{commonTools.check_tf_variable(value.split("=")[0]).strip()}-default\\"].oci_identity_tag_default.tag_default' + if tf_resource not in state["resources"]: + importCommands[reg] += f'\n{tf_or_tofu} import "{tf_resource}" {str(defaultcomp_to_tagid_map[tf_name_key+"-"+commonTools.check_tf_variable(value.split("=")[0])])}' + # Execution of the code begins here def export_tags_nongreenfield(inputfile, outdir, service_dir, config, signer, ct, export_compartments): @@ -101,40 +106,51 @@ def export_tags_nongreenfield(inputfile, outdir, service_dir, config, signer, ct global sheet_dict_tags global importCommands global tag_default_comps_map - global defaultcomp_to_tagid_map + global defaultcomp_to_tagid_map,tf_or_tofu + importCommands = {} + tf_or_tofu = ct.tf_or_tofu + tf_state_list = [tf_or_tofu, "state", "list"] cd3file = inputfile + sheetName="Tags" if ('.xls' not in cd3file): print("\nAcceptable cd3 format: .xlsx") exit() # Read CD3 - df, values_for_column_tags = commonTools.read_cd3(cd3file, "Tags") + df, values_for_column_tags = commonTools.read_cd3(cd3file, sheetName) tag_default_comps_map = {} tag_name_id_map = {} defaultcomp_to_tagid_map = {} # Get dict for columns from Excel_Columns - sheet_dict_tags = ct.sheet_dict["Tags"] + sheet_dict_tags = ct.sheet_dict[sheetName] print("\nCD3 excel file should not be opened during export process!!!") print("Tabs- Tags would be overwritten during export process!!!\n") - # Create backups - if (os.path.exists(outdir + "/" + ct.home_region + "/" + service_dir + "/tf_import_commands_tags_nonGF.sh")): - commonTools.backup_file(outdir + "/" + ct.home_region + "/" + service_dir, "tf_import_tags", "tf_import_commands_tags_nonGF.sh") - importCommands[ct.home_region] = open(outdir + "/" + ct.home_region + "/" + service_dir + "/tf_import_commands_tags_nonGF.sh", "w") - importCommands[ct.home_region].write("#!/bin/bash") - importCommands[ct.home_region].write("\n") - importCommands[ct.home_region].write("terraform init") + # Create backup + resource = 'import_' + sheetName.lower() + file_name = 'import_commands_' + sheetName.lower() + '.sh' + script_file = f'{outdir}/{ct.home_region}/{service_dir}/' + file_name + if (os.path.exists(script_file)): + commonTools.backup_file(outdir + "/" + ct.home_region + "/" + service_dir, resource, file_name) + importCommands[ct.home_region] = '' # Fetch Tags print("\nFetching Tags...") - importCommands[ct.home_region].write("\n\n######### Writing import for Tags #########\n\n") config.__setitem__("region", ct.region_dict[ct.home_region]) + state = {'path': f'{outdir}/{ct.home_region}/{service_dir}', 'resources': []} + try: + byteOutput = sp.check_output(tf_state_list, cwd=state["path"], stderr=sp.DEVNULL) + output = byteOutput.decode('UTF-8').rstrip() + for item in output.split('\n'): + state["resources"].append(item.replace("\"", "\\\"")) + except Exception as e: + pass identity = IdentityClient(config=config,retry_strategy=oci.retry.DEFAULT_RETRY_STRATEGY,signer=signer) region = ct.home_region.lower() comp_ocid_done = [] @@ -181,8 +197,7 @@ def export_tags_nongreenfield(inputfile, outdir, service_dir, config, signer, ct tag_default_check.append(str(tag_key.id)) tag_default_value = tag_default_comps_map[tag_key.id+"="+tag_key.name] tag_namespace_check.append(str(tag.id)) - print_tags(values_for_column_tags, region, ntk_compartment_name, tag, tag_key,tag_default_value) - + print_tags(values_for_column_tags, region, ntk_compartment_name, tag, tag_key,tag_default_value,ct.home_region,state) check_non_default_tags = [i for i in tag_key_check + tag_default_check if i not in tag_key_check or i not in tag_default_check] for tag_check in check_non_default_tags: for tag_key in tag_keys.data: @@ -191,8 +206,7 @@ def export_tags_nongreenfield(inputfile, outdir, service_dir, config, signer, ct tag_key = tag_key.data tag_default_value = '' tag_namespace_check.append(str(tag.id)) - print_tags(values_for_column_tags, region, ntk_compartment_name, tag, tag_key,tag_default_value) - + print_tags(values_for_column_tags, region, ntk_compartment_name, tag, tag_key,tag_default_value,ct.home_region,state) tag_namespace_check = list(dict.fromkeys(tag_namespace_check)) check_non_key_tags = [i for i in tag_list + tag_namespace_check if i not in tag_list or i not in tag_namespace_check] for tag_check in check_non_key_tags: @@ -201,12 +215,14 @@ def export_tags_nongreenfield(inputfile, outdir, service_dir, config, signer, ct for tag in tags.data: if (tag_check in tag.id): tag = identity.get_tag_namespace(tag.id).data - print_tags(values_for_column_tags, region, ntk_compartment_name, tag, tag_key,tag_default_value) + print_tags(values_for_column_tags, region, ntk_compartment_name, tag, tag_key,tag_default_value,ct.home_region,state) commonTools.write_to_cd3(values_for_column_tags, cd3file, "Tags") - print("{0} Tags exported into CD3.\n".format(len(values_for_column_tags["Region"]))) + print("{0} rows exported into CD3 for Tagging Resources.\n".format(len(values_for_column_tags["Region"]))) - script_file = f'{outdir}/{ct.home_region}/{service_dir}/tf_import_commands_tags_nonGF.sh' - with open(script_file, 'a') as importCommands[ct.home_region]: - importCommands[ct.home_region].write('\n\nterraform plan\n') + init_commands = f'\n######### Writing import for Tagging #########\n\n#!/bin/bash\n{tf_or_tofu} init' + if importCommands[ct.home_region] != "": + importCommands[ct.home_region] += f'\n{tf_or_tofu} plan\n' + with open(script_file, 'a') as importCommandsfile: + importCommandsfile.write(init_commands + importCommands[ct.home_region]) diff --git a/cd3_automation_toolkit/Identity/NetworkSources/export_networkSources_nonGreenField.py b/cd3_automation_toolkit/Identity/NetworkSources/export_networkSources_nonGreenField.py index ec4f56741..352be8894 100644 --- a/cd3_automation_toolkit/Identity/NetworkSources/export_networkSources_nonGreenField.py +++ b/cd3_automation_toolkit/Identity/NetworkSources/export_networkSources_nonGreenField.py @@ -12,13 +12,16 @@ import oci from oci.identity import IdentityClient import os +import subprocess as sp sys.path.append(os.getcwd()+"/..") from commonTools import * # Execution of the code begins here def export_networkSources(inputfile, outdir, service_dir, config, signer, ct): global values_for_column_networkSources - global cd3file + global cd3file,tf_or_tofu + tf_or_tofu = ct.tf_or_tofu + tf_state_list = [tf_or_tofu, "state", "list"] cd3file = inputfile @@ -26,7 +29,7 @@ def export_networkSources(inputfile, outdir, service_dir, config, signer, ct): print("\nAcceptable cd3 format: .xlsx") exit() - importCommands={} + importCommands = "" sheetName = "NetworkSources" @@ -37,22 +40,25 @@ def export_networkSources(inputfile, outdir, service_dir, config, signer, ct): print("Tab- Network Sources would be overwritten during export process!!!\n") # Create backup - resource = 'tf_import_' + sheetName.lower() - file_name = 'tf_import_commands_' + sheetName.lower() + '_nonGF.sh' + resource = 'import_' + sheetName.lower() + file_name = 'import_commands_' + sheetName.lower() + '.sh' script_file = f'{outdir}/{ct.home_region}/{service_dir}/' + file_name if (os.path.exists(script_file)): commonTools.backup_file(outdir + "/" + ct.home_region + "/" + service_dir, resource, file_name) - importCommands[ct.home_region] = open(script_file, "w") - importCommands[ct.home_region].write("#!/bin/bash") - importCommands[ct.home_region].write("\n") - importCommands[ct.home_region].write("terraform init") config.__setitem__("region", ct.region_dict[ct.home_region]) + state = {'path': f'{outdir}/{ct.home_region}/{service_dir}', 'resources': []} + try: + byteOutput = sp.check_output(tf_state_list, cwd=state["path"], stderr=sp.DEVNULL) + output = byteOutput.decode('UTF-8').rstrip() + for item in output.split('\n'): + state["resources"].append(item.replace("\"", "\\\"")) + except Exception as e: + pass idc=IdentityClient(config=config,retry_strategy=oci.retry.DEFAULT_RETRY_STRATEGY,signer=signer) # Fetch Network Sources print("\nFetching Network Sources...") - importCommands[ct.home_region].write("\n######### Writing import for Network Sources #########\n") network_sources = oci.pagination.list_call_get_all_results(idc.list_network_sources ,compartment_id=config['tenancy']) compIDvsName = {} @@ -61,14 +67,17 @@ def export_networkSources(inputfile, outdir, service_dir, config, signer, ct): compIDvsName[ct.ntk_compartment_ids[key]] = key index = 0 + total_resource = 0 + for network_source in network_sources.data: + total_resource = total_resource+1 network_source_info = network_source name = network_source_info.name tf_name = commonTools.check_tf_variable(name) - - importCommands[ct.home_region].write("\nterraform import \"module.iam-network-sources[\\\"" + str( - tf_name) + "\\\"].oci_identity_network_source.network_source \" " + network_source_info.id) + tf_resource = f'module.iam-network-sources[\\"{tf_name}\\"].oci_identity_network_source.network_source' + if tf_resource not in state["resources"]: + importCommands += f'\n{tf_or_tofu} import "{tf_resource}" {str(network_source_info.id)}' index = index + 1 for col_header in values_for_column_networkSources.keys(): @@ -104,8 +113,10 @@ def export_networkSources(inputfile, outdir, service_dir, config, signer, ct): values_for_column_networkSources = commonTools.export_tags(network_source_info, col_header, values_for_column_networkSources) commonTools.write_to_cd3(values_for_column_networkSources, cd3file, sheetName) - print("{0} Network Sources exported into CD3.\n".format(len(values_for_column_networkSources["Region"]))) - - with open(script_file, 'a') as importCommands[ct.home_region]: - importCommands[ct.home_region].write('\n\nterraform plan\n') + print("{0} Network Sources exported into CD3.\n".format(total_resource)) + if importCommands != "": + init_commands = f'\n######### Writing import for Network Sources #########\n\n#!/bin/bash\n{tf_or_tofu} init' + importCommands += f'\n{tf_or_tofu} plan\n' + with open(script_file, 'a') as importCommandsfile: + importCommandsfile.write(init_commands + importCommands) diff --git a/cd3_automation_toolkit/Identity/export_identity_nonGreenField.py b/cd3_automation_toolkit/Identity/export_identity_nonGreenField.py index 31b261a16..cc78ac5a7 100644 --- a/cd3_automation_toolkit/Identity/export_identity_nonGreenField.py +++ b/cd3_automation_toolkit/Identity/export_identity_nonGreenField.py @@ -30,12 +30,12 @@ def export_identity(inputfile, outdir, service_dir,resource, config, signer, ct, cd3file = inputfile + tf_or_tofu=ct.tf_or_tofu if('.xls' not in cd3file): print("\nAcceptable cd3 format: .xlsx") exit() - importCommands={} config.__setitem__("region", ct.region_dict[ct.home_region]) idc = IdentityClient(config=config, retry_strategy=oci.retry.DEFAULT_RETRY_STRATEGY, signer=signer) @@ -48,14 +48,12 @@ def export_identity(inputfile, outdir, service_dir,resource, config, signer, ct, sheet_dict_comps = ct.sheet_dict[sheetName_comps] print("Tabs- Compartments would be overwritten during export process!!!\n") # Create backup - resource = 'tf_import_' + sheetName_comps.lower() - file_name = 'tf_import_commands_' + sheetName_comps.lower() + '_nonGF.sh' + resource = 'import_' + sheetName_comps.lower() + file_name = 'import_commands_' + sheetName_comps.lower()+".sh" script_file = f'{outdir}/{ct.home_region}/{service_dir}/' + file_name if (os.path.exists(script_file)): commonTools.backup_file(outdir + "/" + ct.home_region + "/" + service_dir, resource, file_name) - importCommands += "#!/bin/bash\n" - importCommands += "terraform init\n" - importCommands += "\n######### Writing import for Compartments #########\n\n" + # Fetch Compartments print("\nFetching Compartments...") @@ -68,13 +66,22 @@ def export_identity(inputfile, outdir, service_dir,resource, config, signer, ct, sub_comp_l4_index = 0 sub_comp_l5_index = 0 + compartments={} + if ct.ntk_compartment_ids: compartments = ct.ntk_compartment_ids.items() else: ct.get_network_compartment_ids(config['tenancy'], "root", config, signer) compartments = ct.ntk_compartment_ids.items() + if compartments!={}: + importCommands += "\n######### Writing import for Compartments #########\n\n" + importCommands += "#!/bin/bash\n" + importCommands += tf_or_tofu+" init\n" + + total_c = 0 for c_name, c_id in compartments: + total_c = total_c+1 c_details = idc.get_compartment(c_id).data # write child comps info @@ -84,27 +91,27 @@ def export_identity(inputfile, outdir, service_dir,resource, config, signer, ct, comp_parent_name = c_names[0] tf_name = commonTools.check_tf_variable(c_name) if len(c_name.split("::")) == 2: - importCommands += "\nterraform import \"module.sub-compartments-level1[\\\"" + str(tf_name + importCommands += "\n"+tf_or_tofu+" import \"module.sub-compartments-level1[\\\"" + str(tf_name ) + "\\\"].oci_identity_compartment.compartment\" " + c_id sub_comp_l1_index = sub_comp_l1_index + 1 if len(c_name.split("::")) == 3: - importCommands += "\nterraform import \"module.sub-compartments-level2[\\\"" + str(tf_name + importCommands += "\n"+tf_or_tofu +" import \"module.sub-compartments-level2[\\\"" + str(tf_name ) + "\\\"].oci_identity_compartment.compartment\" " + c_id sub_comp_l2_index = sub_comp_l2_index + 1 if len(c_name.split("::")) == 4: - importCommands += "\nterraform import \"module.sub-compartments-level3[\\\"" + str(tf_name + importCommands += "\n"+tf_or_tofu +" import \"module.sub-compartments-level3[\\\"" + str(tf_name ) + "\\\"].oci_identity_compartment.compartment\" " + c_id sub_comp_l3_index = sub_comp_l3_index + 1 if len(c_name.split("::")) == 5: - importCommands += "\nterraform import \"module.sub-compartments-level4[\\\"" + str(tf_name + importCommands += "\n"+tf_or_tofu +" import \"module.sub-compartments-level4[\\\"" + str(tf_name ) + "\\\"].oci_identity_compartment.compartment\" " + c_id sub_comp_l4_index = sub_comp_l4_index + 1 if len(c_name.split("::")) == 6: - importCommands += "\nterraform import \"module.sub-compartments-level5[\\\"" + str(tf_name + importCommands += "\n"+tf_or_tofu +" import \"module.sub-compartments-level5[\\\"" + str(tf_name ) + "\\\"].oci_identity_compartment.compartment\" " + c_id sub_comp_l5_index = sub_comp_l5_index + 1 @@ -117,7 +124,7 @@ def export_identity(inputfile, outdir, service_dir,resource, config, signer, ct, comp_display_name = c_name comp_parent_name = "root" tf_name = commonTools.check_tf_variable(c_name) - importCommands += "\nterraform import \"module.iam-compartments[\\\"" + str( + importCommands += "\n"+tf_or_tofu +" import \"module.iam-compartments[\\\"" + str( tf_name ) + "\\\"].oci_identity_compartment.compartment\" " + c_id @@ -143,12 +150,13 @@ def export_identity(inputfile, outdir, service_dir,resource, config, signer, ct, sheet_dict_comps, values_for_column_comps ) - importCommands += "\nterraform plan" + if importCommands != "": + importCommands += "\n"+ tf_or_tofu+" plan" with open(script_file, 'a') as importCommandsfile: importCommandsfile.write(importCommands) commonTools.write_to_cd3(values_for_column_comps, cd3file, sheetName_comps) - print("{0} Compartments exported into CD3.\n".format(len(values_for_column_comps["Region"]))) + print("{0} Compartments exported into CD3.\n".format(total_c)) elif resource == "IAM Policies": importCommands = "" @@ -157,18 +165,16 @@ def export_identity(inputfile, outdir, service_dir,resource, config, signer, ct, sheet_dict_policies = ct.sheet_dict[sheetName_policies] print("Tabs- Policies would be overwritten during export process!!!\n") # Create backup - resource = 'tf_import_' + sheetName_policies.lower() - file_name = 'tf_import_commands_' + sheetName_policies.lower() + '_nonGF.sh' + resource = 'import_' + sheetName_policies.lower() + file_name = 'import_commands_' + sheetName_policies.lower() + '.sh' script_file = f'{outdir}/{ct.home_region}/{service_dir}/' + file_name if (os.path.exists(script_file)): commonTools.backup_file(outdir + "/" + ct.home_region + "/" + service_dir, resource, file_name) - importCommands += "#!/bin/bash\n" - importCommands += "terraform init\n" - importCommands += "\n######### Writing import for Policies #########\n\n" # Fetch Policies print("\nFetching Policies...") comp_ocid_done = [] index = 0 + total_p = 0 for ntk_compartment_name in export_compartments: if ct.ntk_compartment_ids[ntk_compartment_name] not in comp_ocid_done: comp_ocid_done.append(ct.ntk_compartment_ids[ntk_compartment_name]) @@ -176,7 +182,13 @@ def export_identity(inputfile, outdir, service_dir,resource, config, signer, ct, compartment_id=ct.ntk_compartment_ids[ ntk_compartment_name] ) + if policies.data!=[] and importCommands!='': + importCommands += "#!/bin/bash\n" + importCommands += tf_or_tofu+" init\n" + importCommands += "\n######### Writing import for Policies #########\n\n" + for policy in policies.data: + total_p = total_p+1 policy_name = policy.name policy_comp_id = policy.compartment_id if (policy_comp_id == config['tenancy']): @@ -200,7 +212,7 @@ def export_identity(inputfile, outdir, service_dir,resource, config, signer, ct, tf_name = policy_name tf_name = commonTools.check_tf_variable(tf_name) - importCommands += "\nterraform import \"module.iam-policies[\\\"" + str(tf_name + importCommands += "\n"+tf_or_tofu+" import \"module.iam-policies[\\\"" + str(tf_name ) + "\\\"].oci_identity_policy.policy\" " + policy.id index = index + 1 @@ -250,12 +262,12 @@ def export_identity(inputfile, outdir, service_dir,resource, config, signer, ct, values_for_column_policies[col_header].append("") count = count + 1 - importCommands += "\nterraform plan" if importCommands != "": + importCommands += "\n"+tf_or_tofu+" plan" with open(script_file, 'a') as importCommandsfile: importCommandsfile.write(importCommands) commonTools.write_to_cd3(values_for_column_policies, cd3file, sheetName_policies) - print("{0} Policies exported into CD3.\n".format(len(values_for_column_policies["Region"]))) + print("{0} Policies exported into CD3.\n".format(total_p)) elif resource == "IAM Groups": importCommands = "" @@ -268,14 +280,12 @@ def export_identity(inputfile, outdir, service_dir,resource, config, signer, ct, idc = IdentityClient(config=config, retry_strategy=oci.retry.DEFAULT_RETRY_STRATEGY, signer=signer) # Create backup - resource = 'tf_import_'+ sheetName_groups.lower() - file_name = 'tf_import_commands_' + sheetName_groups.lower() + '_nonGF.sh' + resource = 'import_'+ sheetName_groups.lower() + file_name = 'import_commands_' + sheetName_groups.lower() + '.sh' script_file = f'{outdir}/{ct.home_region}/{service_dir}/' + file_name if os.path.exists(script_file): commonTools.backup_file(outdir + "/" + ct.home_region + "/" + service_dir, resource, file_name) - importCommands += "#!/bin/bash\n" - importCommands += "terraform init\n" - importCommands += "\n######### Writing import for Groups #########\n\n" + # Fetch Groups print("\nFetching Groups...") @@ -283,14 +293,22 @@ def export_identity(inputfile, outdir, service_dir,resource, config, signer, ct, dyngroups=oci.pagination.list_call_get_all_results(idc.list_dynamic_groups,compartment_id=config['tenancy']) index = 0 groupsDict = {} + total_g =0 + + if groups.data!=[] or dyngroups.data!=[]: + importCommands += "#!/bin/bash\n" + importCommands += tf_or_tofu+" init\n" + importCommands += "\n######### Writing import for Groups #########\n\n" + for group in groups.data: + total_g = total_g + 1 grp_info=group if(grp_info.lifecycle_state == "ACTIVE"): groupsDict[grp_info.id] = grp_info.name grp_display_name=grp_info.name tf_name=commonTools.check_tf_variable(grp_display_name) - importCommands += "\nterraform import \"module.iam-groups[\\\""+str(tf_name)+"\\\"].oci_identity_group.group[0]\" "+grp_info.id + importCommands += "\n"+tf_or_tofu+" import \"module.iam-groups[\\\""+str(tf_name)+"\\\"].oci_identity_group.group[0]\" "+grp_info.id index = index + 1 for col_header in values_for_column_groups.keys(): if (col_header == "Region"): @@ -302,12 +320,13 @@ def export_identity(inputfile, outdir, service_dir,resource, config, signer, ct, values_for_column_groups = commonTools.export_extra_columns(oci_objs, col_header, sheet_dict_groups,values_for_column_groups) for group in dyngroups.data: + total_g = total_g + 1 grp_info=group if(grp_info.lifecycle_state == "ACTIVE"): groupsDict[grp_info.id] = grp_info.name grp_display_name=grp_info.name tf_name=commonTools.check_tf_variable(grp_display_name) - importCommands += "\nterraform import \"module.iam-groups[\\\""+str(tf_name)+"\\\"].oci_identity_dynamic_group.dynamic_group[0]\" "+grp_info.id + importCommands += "\n"+tf_or_tofu+" import \"module.iam-groups[\\\""+str(tf_name)+"\\\"].oci_identity_dynamic_group.dynamic_group[0]\" "+grp_info.id index = index + 1 for col_header in values_for_column_groups.keys(): if (col_header == "Region"): @@ -318,9 +337,9 @@ def export_identity(inputfile, outdir, service_dir,resource, config, signer, ct, oci_objs=[grp_info] values_for_column_groups = commonTools.export_extra_columns(oci_objs, col_header, sheet_dict_groups,values_for_column_groups) - importCommands += "\nterraform plan" if importCommands != "": + importCommands += "\n"+tf_or_tofu+" plan" with open(script_file, 'a') as importCommandsfile: importCommandsfile.write(importCommands) commonTools.write_to_cd3(values_for_column_groups,cd3file,sheetName_groups) - print("{0} Groups exported into CD3.\n".format(len(values_for_column_groups["Region"]))) + print("{0} rows exported into CD3 for Groups and Dynamic Groups.\n".format(total_g)) diff --git a/cd3_automation_toolkit/ManagementServices/EventsAndNotifications/export_events_notifications_nonGreenField.py b/cd3_automation_toolkit/ManagementServices/EventsAndNotifications/export_events_notifications_nonGreenField.py index f8ee99793..171884d33 100644 --- a/cd3_automation_toolkit/ManagementServices/EventsAndNotifications/export_events_notifications_nonGreenField.py +++ b/cd3_automation_toolkit/ManagementServices/EventsAndNotifications/export_events_notifications_nonGreenField.py @@ -10,19 +10,20 @@ import sys import oci import json +import subprocess as sp +import os from oci.ons import NotificationControlPlaneClient from oci.events import EventsClient from oci.ons import NotificationDataPlaneClient from oci.functions import FunctionsManagementClient from oci.config import DEFAULT_LOCATION -import os -sys.path.append(os.getcwd() + "/..") from commonTools import * +sys.path.append(os.getcwd() + "/..") compartment_ids={} importCommands={} -def print_notifications(values_for_column_notifications,region, ntk_compartment_name, sbpn, nftn_info, i, fun): +def print_notifications(values_for_column_notifications,region, ntk_compartment_name, sbpn, nftn_info, i, fun,state): tf_name_nftn = commonTools.check_tf_variable(str(nftn_info.name)) sbpn_name = nftn_info.name + "_" + "sub" + str(i) @@ -61,16 +62,16 @@ def print_notifications(values_for_column_notifications,region, ntk_compartment else: oci_objs = [nftn_info,sbpn] values_for_column_notifications = commonTools.export_extra_columns(oci_objs, col_header, sheet_dict_notifications,values_for_column_notifications) + tf_resource = f'module.notifications-topics[\\"{tf_name_nftn}\\"].oci_ons_notification_topic.topic' + if (i ==0 or i == 1) and tf_resource not in state["resources"]: + importCommands[region.lower()] += f'\n{tf_or_tofu} import "{tf_resource}" {str(nftn_info.topic_id)}' - if (i ==0 or i == 1): - importCommands[region.lower()].write("\nterraform import \"module.notifications-topics[\\\"" + str(tf_name_nftn) + "\\\"].oci_ons_notification_topic.topic\" " + str(nftn_info.topic_id)) + tf_resource = f'module.notifications-subscriptions[\\"{tf_name_sbpn}\\"].oci_ons_subscription.subscription' + if(i!=0) and tf_resource not in state["resources"]: + importCommands[region.lower()] += f'\n{tf_or_tofu} import "{tf_resource}" {str(sbpn.id)}' - if(i!=0): - importCommands[region.lower()].write("\nterraform import \"module.notifications-subscriptions[\\\"" + str(tf_name_sbpn) + "\\\"].oci_ons_subscription.subscription\" " + str(sbpn.id)) - - -def print_events(values_for_column_events, region, ntk_compartment_name, event, event_info, ncpc, fun): +def print_events(values_for_column_events, region, ntk_compartment_name, event, event_info, ncpc, fun,state): tf_name = commonTools.check_tf_variable(str(event.display_name)) event_name = event.display_name action_type = "" @@ -131,9 +132,9 @@ def print_events(values_for_column_events, region, ntk_compartment_name, event, if ( i > 0 and action_name != ""): events_rows(values_for_column_events, region, ntk_compartment_name, event_name, event_desc, action_type, action_is_enabled, action_description, event_prod, event_res,data, event_is_enabled, action_name, event, event_info) i = i + 1 - if ( action_name != "" ): - #importCommands[region.lower()].write("\nterraform import oci_events_rule." + tf_name + " " + str(event.id)) - importCommands[region.lower()].write("\nterraform import \"module.events[\\\"" + str(tf_name) + "\\\"].oci_events_rule.event\" " + str(event.id)) + tf_resource = f'module.events[\\"{tf_name}\\"].oci_events_rule.event' + if ( action_name != "" ) and tf_resource not in state["resources"]: + importCommands[region.lower()] += f'\n{tf_or_tofu} import "{tf_resource}" {event.id}' def events_rows(values_for_column_events, region, ntk_compartment_name, event_name, event_desc, action_type, action_is_enabled, action_description, event_prod, event_res,data, event_is_enabled, action_name, event, event_info): for col_header in values_for_column_events.keys(): @@ -175,7 +176,9 @@ def export_events(inputfile, outdir, service_dir, config, signer, ct,export_comp global values_for_column_notifications global sheet_dict_events global sheet_dict_notifications - global importCommands + global importCommands,tf_or_tofu + tf_or_tofu = ct.tf_or_tofu + tf_state_list = [tf_or_tofu, "state", "list"] sheetName = "Events" @@ -195,23 +198,27 @@ def export_events(inputfile, outdir, service_dir, config, signer, ct,export_comp print("Tabs- Events would be overwritten during export process!!!\n") # Create backups - resource = 'tf_import_' + sheetName.lower() - file_name = 'tf_import_commands_' + sheetName.lower() + '_nonGF.sh' + resource = 'import_' + sheetName.lower() + file_name = 'import_commands_' + sheetName.lower() + '.sh' for reg in export_regions: script_file = f'{outdir}/{reg}/{service_dir}/' + file_name if (os.path.exists(script_file)): commonTools.backup_file(outdir + "/" + reg +"/" + service_dir, resource, file_name) - importCommands[reg] = open(script_file, "w") - importCommands[reg].write("#!/bin/bash") - importCommands[reg].write("\n") - importCommands[reg].write("terraform init") + importCommands[reg] = '' # Fetch Events print("\nFetching Events...") for reg in export_regions: - importCommands[reg].write("\n\n######### Writing import for Events #########\n\n") config.__setitem__("region", ct.region_dict[reg]) + state = {'path': f'{outdir}/{reg}/{service_dir}', 'resources': []} + try: + byteOutput = sp.check_output(tf_state_list, cwd=state["path"], stderr=sp.DEVNULL) + output = byteOutput.decode('UTF-8').rstrip() + for item in output.split('\n'): + state["resources"].append(item.replace("\"", "\\\"")) + except Exception as e: + pass # comp_ocid_done = [] ncpc = NotificationControlPlaneClient(config=config, retry_strategy=oci.retry.DEFAULT_RETRY_STRATEGY,signer=signer) fun = FunctionsManagementClient(config=config, retry_strategy=oci.retry.DEFAULT_RETRY_STRATEGY,signer=signer) @@ -220,21 +227,29 @@ def export_events(inputfile, outdir, service_dir, config, signer, ct,export_comp for ntk_compartment_name in export_compartments: evts = oci.pagination.list_call_get_all_results(evt.list_rules, compartment_id=ct.ntk_compartment_ids[ ntk_compartment_name], lifecycle_state="ACTIVE") + for event in evts.data: event_info = evt.get_rule(event.id).data - print_events(values_for_column_events, region, ntk_compartment_name, event, event_info, ncpc, fun) + print_events(values_for_column_events, region, ntk_compartment_name, event, event_info, ncpc, fun,state) + ievts = oci.pagination.list_call_get_all_results(evt.list_rules, compartment_id=ct.ntk_compartment_ids[ ntk_compartment_name], lifecycle_state="INACTIVE") + for event in ievts.data: event_info = evt.get_rule(event.id).data - print_events(values_for_column_events, region, ntk_compartment_name, event, event_info, ncpc, fun) + print_events(values_for_column_events, region, ntk_compartment_name, event, event_info, ncpc, fun,state) commonTools.write_to_cd3(values_for_column_events, cd3file, sheetName) print("{0} Events exported into CD3.\n".format(len(values_for_column_events["Region"]))) + # writing data for reg in export_regions: - with open(script_file, 'a') as importCommands[reg]: - importCommands[reg].write('\n\nterraform plan\n') + script_file = f'{outdir}/{reg}/{service_dir}/' + file_name + if importCommands[reg] != "": + init_commands = f'\n######### Writing import for Events #########\n\n#!/bin/bash\n{tf_or_tofu} init' + importCommands[reg] += f'\n{tf_or_tofu} plan\n' + with open(script_file, 'a') as importCommandsfile: + importCommandsfile.write(init_commands + importCommands[reg]) # Execution for Notifications export starts here def export_notifications(inputfile, outdir, service_dir, config, signer, ct, export_compartments=[], export_regions=[]): @@ -244,7 +259,9 @@ def export_notifications(inputfile, outdir, service_dir, config, signer, ct, exp global values_for_column_notifications global sheet_dict_events global sheet_dict_notifications - global importCommands + global importCommands,tf_or_tofu + tf_or_tofu = ct.tf_or_tofu + tf_state_list = [tf_or_tofu, "state", "list"] sheetName = "Notifications" @@ -263,42 +280,48 @@ def export_notifications(inputfile, outdir, service_dir, config, signer, ct, exp print("Tabs- Notifications would be overwritten during export process!!!\n") # Create backups - resource = 'tf_import_' + sheetName.lower() - file_name = 'tf_import_commands_' + sheetName.lower() + '_nonGF.sh' + resource = 'import_' + sheetName.lower() + file_name = 'import_commands_' + sheetName.lower() + '.sh' for reg in export_regions: script_file = f'{outdir}/{reg}/{service_dir}/' + file_name if (os.path.exists(script_file)): commonTools.backup_file(outdir + "/" + reg +"/" + service_dir, resource, file_name) - importCommands[reg] = open(script_file, "w") - importCommands[reg].write("#!/bin/bash") - importCommands[reg].write("\n") - importCommands[reg].write("terraform init") + importCommands[reg] = '' # Fetch Notifications & Subscriptions print("\nFetching Notifications - Topics & Subscriptions...") + total_resources=0 for reg in export_regions: - importCommands[reg].write("\n\n######### Writing import for Notifications #########\n\n") config.__setitem__("region", ct.region_dict[reg]) + state = {'path': f'{outdir}/{reg}/{service_dir}', 'resources': []} + try: + byteOutput = sp.check_output(tf_state_list, cwd=state["path"], stderr=sp.DEVNULL) + output = byteOutput.decode('UTF-8').rstrip() + for item in output.split('\n'): + state["resources"].append(item.replace("\"", "\\\"")) + except Exception as e: + pass ncpc = NotificationControlPlaneClient(config=config, retry_strategy=oci.retry.DEFAULT_RETRY_STRATEGY,signer=signer) ndpc = NotificationDataPlaneClient(config=config, retry_strategy=oci.retry.DEFAULT_RETRY_STRATEGY,signer=signer) fun = FunctionsManagementClient(config=config, retry_strategy=oci.retry.DEFAULT_RETRY_STRATEGY,signer=signer) region = reg.capitalize() for ntk_compartment_name in export_compartments: - topics = oci.pagination.list_call_get_all_results(ncpc.list_topics,compartment_id=ct.ntk_compartment_ids[ntk_compartment_name]) + topics = oci.pagination.list_call_get_all_results(ncpc.list_topics,compartment_id=ct.ntk_compartment_ids[ntk_compartment_name],lifecycle_state='ACTIVE') #sbpns = oci.pagination.list_call_get_all_results(ndpc.list_subscriptions,compartment_id=ct.ntk_compartment_ids[ntk_compartment_name]) for topic in topics.data: + total_resources+=1 #subscriptions get created in same comp as topic sbpns = oci.pagination.list_call_get_all_results(ndpc.list_subscriptions,compartment_id=ct.ntk_compartment_ids[ntk_compartment_name],topic_id = topic.topic_id) i=0 sbpn = None for sbpn in sbpns.data: i=i+1 - print_notifications(values_for_column_notifications, region, ntk_compartment_name, sbpn,topic, i, fun) + print_notifications(values_for_column_notifications, region, ntk_compartment_name, sbpn,topic, i, fun,state) # Empty Topic - No Subscription in the same compartment as Topic's if(i==0): - print_notifications(values_for_column_notifications, region, ntk_compartment_name, sbpn, topic,i, fun) + print_notifications(values_for_column_notifications, region, ntk_compartment_name, sbpn, topic,i, fun,state) ''' @@ -319,9 +342,14 @@ def export_notifications(inputfile, outdir, service_dir, config, signer, ct, exp commonTools.write_to_cd3(values_for_column_notifications, cd3file, sheetName) - print("{0} Notifications exported into CD3.\n".format(len(values_for_column_notifications["Region"]))) - + print("{0} Notifications exported into CD3.\n".format(total_resources)) + # writing data for reg in export_regions: - with open(script_file, 'a') as importCommands[reg]: - importCommands[reg].write('\n\nterraform plan\n') + script_file = f'{outdir}/{reg}/{service_dir}/' + file_name + if importCommands[reg] != "": + init_commands = f'\n######### Writing import for Notifications #########\n\n#!/bin/bash\n{tf_or_tofu} init' + importCommands[reg] += f'\n{tf_or_tofu} plan\n' + with open(script_file, 'a') as importCommandsfile: + importCommandsfile.write(init_commands + importCommands[reg]) + diff --git a/cd3_automation_toolkit/ManagementServices/Logging/templates/logging-template b/cd3_automation_toolkit/ManagementServices/Logging/templates/logging-template index 4a228677e..343cfb7f9 100644 --- a/cd3_automation_toolkit/ManagementServices/Logging/templates/logging-template +++ b/cd3_automation_toolkit/ManagementServices/Logging/templates/logging-template @@ -8,8 +8,9 @@ # Allowed Values: # compartment_id can be the ocid or the name of the compartment hierarchy delimited by double hiphens "--" # Example : compartment_id = "ocid1.compartment.oc1..aaaaaaaahwwiefb56epvdlzfic6ah6jy3xf3c" or compartment_id = "Security--Prod" where "Security" is the parent of "Prod" compartment +# terraform import "module.vcn-log-groups[\"<>\"].oci_logging_log_group.log_group" <> +# terraform import "module.vcn-logs[\"<>\"].oci_logging_log.log" logGroupId/<>/logId/<> ############################ - {{ oci_service }}_log_groups = { # Log Group map # ##Add New Log Groups for {{ region.lower() }} here## diff --git a/cd3_automation_toolkit/ManagementServices/Monitoring/export_alarms_nonGreenField.py b/cd3_automation_toolkit/ManagementServices/Monitoring/export_alarms_nonGreenField.py index e55e13044..3d8922064 100644 --- a/cd3_automation_toolkit/ManagementServices/Monitoring/export_alarms_nonGreenField.py +++ b/cd3_automation_toolkit/ManagementServices/Monitoring/export_alarms_nonGreenField.py @@ -10,6 +10,7 @@ import oci import os +import subprocess as sp from commonTools import * @@ -19,7 +20,7 @@ oci_obj_names = {} -def print_alarms(region, alarm, ncpclient,values_for_column, ntk_compartment_name,ct): +def print_alarms(region, alarm, ncpclient,values_for_column, ntk_compartment_name,ct,state): alarm_tf_name = commonTools.check_tf_variable(alarm.display_name) comp_tf_name = commonTools.check_tf_variable(ntk_compartment_name) suppression = alarm.suppression @@ -65,9 +66,9 @@ def print_alarms(region, alarm, ncpclient,values_for_column, ntk_compartment_nam oci_objs = [alarm,suppression] values_for_column = commonTools.export_extra_columns(oci_objs, col_header, sheet_dict, values_for_column) - if(skip_row == 0): - #importCommands[region.lower()].write("\nterraform import oci_monitoring_alarm." + alarm_tf_name + " " + str(alarm.id)) - importCommands[region.lower()].write("\nterraform import \"module.alarms[\\\"" + str(comp_tf_name+"_"+alarm_tf_name) + "\\\"].oci_monitoring_alarm.alarm\" " + str(alarm.id)) + tf_resource = f'module.alarms[\\"{comp_tf_name}_{alarm_tf_name}\\"].oci_monitoring_alarm.alarm' + if skip_row == 0 and tf_resource not in state["resources"]: + importCommands[region.lower()] += f'\n{tf_or_tofu} import "{tf_resource}" {alarm.id}' # Execution of the code begins here def export_alarms(inputfile, outdir, service_dir, config, signer, ct, export_compartments=[],export_regions=[]): @@ -76,7 +77,9 @@ def export_alarms(inputfile, outdir, service_dir, config, signer, ct, export_com global importCommands global cd3file global reg - global values_for_column + global values_for_column,tf_or_tofu + tf_or_tofu = ct.tf_or_tofu + tf_state_list = [tf_or_tofu, "state", "list"] cd3file = inputfile @@ -97,23 +100,27 @@ def export_alarms(inputfile, outdir, service_dir, config, signer, ct, export_com print("Tabs- Alarms will be overwritten during export process!!!\n") # Create backups - resource = 'tf_import_' + sheetName.lower() - file_name = 'tf_import_commands_' + sheetName.lower() + '_nonGF.sh' + resource = 'import_' + sheetName.lower() + file_name = 'import_commands_' + sheetName.lower() + '.sh' for reg in export_regions: script_file = f'{outdir}/{reg}/{service_dir}/' + file_name if (os.path.exists(script_file)): commonTools.backup_file(outdir + "/" + reg +"/" + service_dir, resource, file_name) - importCommands[reg] = open(script_file, "w") - importCommands[reg].write("#!/bin/bash") - importCommands[reg].write("\n") - importCommands[reg].write("terraform init") + importCommands[reg] = '' # Fetch Block Volume Details print("\nFetching details of Alarms...") for reg in export_regions: - importCommands[reg].write("\n\n######### Writing import for Alarms #########\n\n") config.__setitem__("region", ct.region_dict[reg]) + state = {'path': f'{outdir}/{reg}/{service_dir}', 'resources': []} + try: + byteOutput = sp.check_output(tf_state_list, cwd=state["path"], stderr=sp.DEVNULL) + output = byteOutput.decode('UTF-8').rstrip() + for item in output.split('\n'): + state["resources"].append(item.replace("\"", "\\\"")) + except Exception as e: + pass region = reg.capitalize() mclient = oci.monitoring.MonitoringClient(config=config, retry_strategy=oci.retry.DEFAULT_RETRY_STRATEGY,signer=signer) @@ -124,13 +131,18 @@ def export_alarms(inputfile, outdir, service_dir, config, signer, ct, export_com for alarmSummary in alarms.data: alarm=mclient.get_alarm(alarmSummary.id).data - print_alarms(region, alarm,ncpclient,values_for_column, ntk_compartment_name,ct) - - - with open(script_file, 'a') as importCommands[reg]: - importCommands[reg].write('\n\nterraform plan\n') + print_alarms(region, alarm,ncpclient,values_for_column, ntk_compartment_name,ct,state) commonTools.write_to_cd3(values_for_column, cd3file, sheetName) print("{0} Alarms exported into CD3.\n".format(len(values_for_column["Region"]))) + # writing data + for reg in export_regions: + script_file = f'{outdir}/{reg}/{service_dir}/' + file_name + if importCommands[reg] != "": + init_commands = f'\n######### Writing import for Alarms #########\n\n#!/bin/bash\n{tf_or_tofu} init' + importCommands[reg] += f'\n{tf_or_tofu} plan\n' + with open(script_file, 'a') as importCommandsfile: + importCommandsfile.write(init_commands + importCommands[reg]) + diff --git a/cd3_automation_toolkit/ManagementServices/ServiceConnectorHub/export_sch_nonGreenField.py b/cd3_automation_toolkit/ManagementServices/ServiceConnectorHub/export_sch_nonGreenField.py index 7d4d9d8a1..9e99ba6e6 100755 --- a/cd3_automation_toolkit/ManagementServices/ServiceConnectorHub/export_sch_nonGreenField.py +++ b/cd3_automation_toolkit/ManagementServices/ServiceConnectorHub/export_sch_nonGreenField.py @@ -10,6 +10,7 @@ import oci import os +import subprocess as sp from commonTools import * importCommands = {} @@ -17,7 +18,7 @@ def get_service_connectors(config, region, SCH_LIST, sch_client, log_client, la_client, stream_client, - notification_client, func_client, ct, values_for_column, ntk_compartment_name): + notification_client, func_client, ct, values_for_column, ntk_compartment_name,state): volume_comp = "" log_source_list = [] target_la_string = "" @@ -247,10 +248,9 @@ def get_comp_details(comp_data): if sch_compartment_id == comp_id and sch_compartment_id not in comp_done_ids: volume_comp = comp_name comp_done_ids.append(sch_compartment_id) - - importCommands[region.lower()].write( - "\nterraform import \"module.service-connectors[\\\"" + sch_tf_name + "\\\"].oci_sch_service_connector.service_connector\" " + str( - sch_id)) + tf_resource = f'module.service-connectors[\\"{sch_tf_name}\\"].oci_sch_service_connector.service_connector' + if tf_resource not in state["resources"]: + importCommands[region.lower()] += f'\n{tf_or_tofu} import "{tf_resource}" {str(sch_id)}' for col_header in values_for_column: if col_header == 'Region': @@ -304,7 +304,9 @@ def export_service_connectors(inputfile, outdir, service_dir, config, signer, ct global importCommands global cd3file global reg - global valuesforcolumn + global valuesforcolumn,tf_or_tofu + tf_or_tofu = ct.tf_or_tofu + tf_state_list = [tf_or_tofu, "state", "list"] cd3file = inputfile if ('.xls' not in cd3file): @@ -322,23 +324,27 @@ def export_service_connectors(inputfile, outdir, service_dir, config, signer, ct print("Tab- ServiceConnectors will be overwritten during export process!!!\n") # Create backups - resource = 'tf_import_' + sheetName.lower() - file_name = 'tf_import_commands_' + sheetName.lower() + '_nonGF.sh' + resource = 'import_' + sheetName.lower() + file_name = 'import_commands_' + sheetName.lower() + '.sh' for reg in export_regions: script_file = f'{outdir}/{reg}/{service_dir}/' + file_name if (os.path.exists(script_file)): commonTools.backup_file(outdir + "/" + reg + "/" + service_dir, resource, file_name) - importCommands[reg] = open(script_file, "w") - importCommands[reg].write("#!/bin/bash") - importCommands[reg].write("\n") - importCommands[reg].write("terraform init") + importCommands[reg] = '' # Fetch Service Connector Hub Details print("\nFetching details of Service Connectors...") for reg in export_regions: - importCommands[reg].write("\n\n######### Writing import for Service Connectors #########\n\n") config.__setitem__("region", ct.region_dict[reg]) + state = {'path': f'{outdir}/{reg}/{service_dir}', 'resources': []} + try: + byteOutput = sp.check_output(tf_state_list, cwd=state["path"], stderr=sp.DEVNULL) + output = byteOutput.decode('UTF-8').rstrip() + for item in output.split('\n'): + state["resources"].append(item.replace("\"", "\\\"")) + except Exception as e: + pass region = reg.capitalize() sch_client = oci.sch.ServiceConnectorClient(config=config, retry_strategy=oci.retry.DEFAULT_RETRY_STRATEGY, signer=signer) @@ -362,14 +368,17 @@ def export_service_connectors(inputfile, outdir, service_dir, config, signer, ct sort_by="timeCreated") get_service_connectors(config, region, SCH_LIST, sch_client, log_client, la_client, stream_client, notification_client, func_client, ct, values_for_column, - ntk_compartment_name) + ntk_compartment_name,state) commonTools.write_to_cd3(values_for_column, cd3file, sheetName) print("{0} Service Connectors exported into CD3.\n".format(len(values_for_column["Region"]))) - # writing data for reg in export_regions: script_file = f'{outdir}/{reg}/{service_dir}/' + file_name - with open(script_file, 'a') as importCommands[reg]: - importCommands[reg].write('\n\nterraform plan\n') + if importCommands[reg] != "": + init_commands = f'\n######### Writing import for Service Connectors #########\n\n#!/bin/bash\n{tf_or_tofu} init' + importCommands[reg] += f'\n{tf_or_tofu} plan\n' + with open(script_file, 'a') as importCommandsfile: + importCommandsfile.write(init_commands + importCommands[reg]) + diff --git a/cd3_automation_toolkit/Network/BaseNetwork/exportNSG.py b/cd3_automation_toolkit/Network/BaseNetwork/exportNSG.py index 11d3b6c3c..434da8d0f 100644 --- a/cd3_automation_toolkit/Network/BaseNetwork/exportNSG.py +++ b/cd3_automation_toolkit/Network/BaseNetwork/exportNSG.py @@ -4,6 +4,7 @@ import oci from oci.core.virtual_network_client import VirtualNetworkClient import os +import subprocess as sp sys.path.append(os.getcwd()+"/../../..") from commonTools import * @@ -13,7 +14,7 @@ def convertNullToNothing(input): return EMPTY_STRING else: return str(input) -def print_nsgsl(values_for_column_nsgs,vnc,region, comp_name, vcn_name, nsg, nsgsl,i): +def print_nsgsl(values_for_column_nsgs,vnc,region, comp_name, vcn_name, nsg, nsgsl,i,state): tf_name = commonTools.check_tf_variable(str(vcn_name)+"_"+str(nsg.display_name)) sportmin = "" sportmax = "" @@ -133,13 +134,14 @@ def print_nsgsl(values_for_column_nsgs,vnc,region, comp_name, vcn_name, nsg, nsg values_for_column_nsgs = commonTools.export_extra_columns(oci_objs, col_header, sheet_dict_nsgs,values_for_column_nsgs) nsg_rule_tf_name = tf_name + "_security_rule" + str(i) - if tf_import_cmd: - importCommands[region.lower()].write("\nterraform import \"module.nsg-rules[\\\""+nsg_rule_tf_name+"\\\"].oci_core_network_security_group_security_rule.nsg_rule\" " + "networkSecurityGroups/" + str(nsg.id) + "/securityRules/" + str(nsgsl.id)) + tf_resource = f'module.nsg-rules[\\"{nsg_rule_tf_name}\\"].oci_core_network_security_group_security_rule.nsg_rule' + if tf_import_cmd and tf_resource not in state["resources"]: + importCommands[region.lower()] += f'\n{tf_or_tofu} import "{tf_resource}" networkSecurityGroups/{str(nsg.id)}/securityRules/{str(nsgsl.id)}' # importCommands[region.lower()].write("\nterraform import oci_core_network_security_group_security_rule." + tf_name + "_security_rule" + str(i) + " " + "networkSecurityGroups/" + str(nsg.id) + "/securityRules/" + str(nsgsl.id)) -def print_nsg(values_for_column_nsgs,region, comp_name, vcn_name, nsg): +def print_nsg(values_for_column_nsgs,region, comp_name, vcn_name, nsg,state): tf_name = commonTools.check_tf_variable(str(vcn_name)+"_"+str(nsg.display_name)) for col_header in values_for_column_nsgs.keys(): @@ -154,17 +156,21 @@ def print_nsg(values_for_column_nsgs,region, comp_name, vcn_name, nsg): else: oci_objs = [nsg] values_for_column_nsgs = commonTools.export_extra_columns(oci_objs, col_header, sheet_dict_nsgs,values_for_column_nsgs) - if tf_import_cmd: - importCommands[region.lower()].write("\nterraform import \"module.nsgs[\\\"" + tf_name + "\\\"].oci_core_network_security_group.network_security_group\" " + str(nsg.id)) + tf_resource = f'module.nsgs[\\"{tf_name}\\"].oci_core_network_security_group.network_security_group' + if tf_import_cmd and tf_resource not in state["resources"]: + importCommands[region.lower()] += f'\n{tf_or_tofu} import "{tf_resource}" {str(nsg.id)}' # Execution of the code begins here def export_nsg(inputfile, outdir, service_dir,config,signer, ct, export_compartments,export_regions,_tf_import_cmd): global tf_import_cmd global values_for_column_nsgs global sheet_dict_nsgs - global importCommands + global importCommands,tf_or_tofu cd3file = inputfile + tf_or_tofu = ct.tf_or_tofu + tf_state_list = [tf_or_tofu, "state", "list"] + if '.xls' not in cd3file: print("\nAcceptable cd3 format: .xlsx") exit() @@ -184,18 +190,22 @@ def export_nsg(inputfile, outdir, service_dir,config,signer, ct, export_compartm if tf_import_cmd: importCommands={} for reg in export_regions: - if (os.path.exists(outdir + "/" + reg + "/" + service_dir + "/tf_import_commands_network_nsg_nonGF.sh")): - commonTools.backup_file(outdir + "/" + reg + "/" + service_dir, "tf_import_network", - "tf_import_commands_network_nsg_nonGF.sh") - importCommands[reg] = open(outdir + "/" + reg + "/" + service_dir+ "/tf_import_commands_network_nsg_nonGF.sh", "w") - importCommands[reg].write("#!/bin/bash") - importCommands[reg].write("\n") - importCommands[reg].write("terraform init") - importCommands[reg].write("\n\n######### Writing import for NSG #########\n\n") + if (os.path.exists(outdir + "/" + reg + "/" + service_dir + "/import_commands_network_nsg.sh")): + commonTools.backup_file(outdir + "/" + reg + "/" + service_dir, "import_network", + "import_commands_network_nsg.sh") + importCommands[reg] = "" for reg in export_regions: config.__setitem__("region", commonTools().region_dict[reg]) + state = {'path': f'{outdir}/{reg}/{service_dir}', 'resources': []} + try: + byteOutput = sp.check_output(tf_state_list, cwd=state["path"],stderr=sp.DEVNULL) + output = byteOutput.decode('UTF-8').rstrip() + for item in output.split('\n'): + state["resources"].append(item.replace("\"", "\\\"")) + except Exception as e: + pass vnc = VirtualNetworkClient(config=config, retry_strategy=oci.retry.DEFAULT_RETRY_STRATEGY,signer=signer) region = reg.capitalize() nsglist = [""] @@ -213,28 +223,34 @@ def export_nsg(inputfile, outdir, service_dir,config,signer, ct, export_compartm lifecycle_state="AVAILABLE") for nsg in NSGs.data: - NSGSLs = vnc.list_network_security_group_security_rules(nsg.id, sort_by="TIMECREATED") + NSGSLs = oci.pagination.list_call_get_all_results(vnc.list_network_security_group_security_rules, network_security_group_id= nsg.id, sort_by="TIMECREATED") i = 1 for nsgsl in NSGSLs.data: nsglist.append(nsg.id) print_nsgsl(values_for_column_nsgs, vnc, region, ntk_compartment_name_again, - vcn_info.display_name, nsg, nsgsl, i) + vcn_info.display_name, nsg, nsgsl, i,state) i = i + 1 if (nsg.id not in nsglist): print_nsg(values_for_column_nsgs, region, ntk_compartment_name_again, vcn_info.display_name, - nsg) + nsg,state) else: tf_name = commonTools.check_tf_variable(str(vcn_info.display_name)+"_"+str(nsg.display_name)) - if tf_import_cmd: - importCommands[region.lower()].write("\nterraform import \"module.nsgs[\\\"" + tf_name + "\\\"].oci_core_network_security_group.network_security_group\" " + str( - nsg.id)) + tf_resource = f'module.nsgs[\\"{tf_name}\\"].oci_core_network_security_group.network_security_group' + if tf_import_cmd and tf_resource not in state["resources"]: + importCommands[region.lower()] += f'\n{tf_or_tofu} import "{tf_resource}" {str(nsg.id)}' + commonTools.write_to_cd3(values_for_column_nsgs, cd3file, "NSGs") print("NSGs exported to CD3\n") if tf_import_cmd: for reg in export_regions: - importCommands[reg].write('\n\nterraform plan\n') - importCommands[reg].close() + script_file = f'{outdir}/{reg}/{service_dir}/import_commands_network_nsg.sh' + init_commands = f'\n#!/bin/bash\n{tf_or_tofu} init\n######### Writing import for NSGs #########\n' + if importCommands[reg] != "": + importCommands[reg] += f'\n{tf_or_tofu} plan\n' + with open(script_file, 'a') as importCommandsfile: + importCommandsfile.write(init_commands + importCommands[reg]) + diff --git a/cd3_automation_toolkit/Network/BaseNetwork/exportRoutetable.py b/cd3_automation_toolkit/Network/BaseNetwork/exportRoutetable.py index 50e1044b3..f86deef41 100644 --- a/cd3_automation_toolkit/Network/BaseNetwork/exportRoutetable.py +++ b/cd3_automation_toolkit/Network/BaseNetwork/exportRoutetable.py @@ -4,10 +4,10 @@ import oci from oci.core.virtual_network_client import VirtualNetworkClient import os +import subprocess as sp sys.path.append(os.getcwd()+"/../../..") from commonTools import * - def get_network_entity_name(config,signer,network_identity_id): vcn1 = VirtualNetworkClient(config=config, retry_strategy=oci.retry.DEFAULT_RETRY_STRATEGY,signer=signer) if('internetgateway' in network_identity_id): @@ -111,7 +111,7 @@ def insert_values_drg(routetable,import_drg_route_distribution_name,values_for_c -def print_drg_routerules(drg_rt_info,drg_display_name,drg_route_table_name,import_drg_route_distribution_name,drg_rules,region,comp_name): +def print_drg_routerules(drg_rt_info,drg_display_name,drg_route_table_name,import_drg_route_distribution_name,drg_rules,region,comp_name,state): drg_rt_name = drg_display_name + "_" + drg_route_table_name drg_rt_tf_name = commonTools.check_tf_variable(drg_rt_name) if (not drg_rules.data): @@ -125,10 +125,12 @@ def print_drg_routerules(drg_rt_info,drg_display_name,drg_route_table_name,impor print(drg_route_table_name) else: if rule.route_type.lower()=='static': - importCommands_drg[region.lower()].write("\nterraform import \"module.drg-route-rules[\\\"" + drg_rt_tf_name+ "_route_rule" + str(i) + "\\\"].oci_core_drg_route_table_route_rule.drg_route_rule\" drgRouteTables/"+str(drg_rt_info.id)+"/routeRules/"+str(rule.id)) + tf_resource = f'module.drg-route-rules[\\"{drg_rt_tf_name}_route_rule{str(i)}\\"].oci_core_drg_route_table_route_rule.drg_route_rule' + if tf_resource not in state["resources"]: + importCommands_drg[region.lower()] += f'\n{tf_or_tofu} import "{tf_resource}" drgRouteTables/{str(drg_rt_info.id)}/routeRules/{str(rule.id)}' i=i+1 -def print_routetables(routetables,region,vcn_name,comp_name,gw_route_table_ids): +def print_routetables(routetables,region,vcn_name,comp_name,gw_route_table_ids,state): for routetable in routetables.data: rules = routetable.route_rules display_name = routetable.display_name @@ -139,14 +141,17 @@ def print_routetables(routetables,region,vcn_name,comp_name,gw_route_table_ids): if routetable.id in gw_route_table_ids: if ("Default Route Table for " in dn): - importCommands[region.lower()].write("\nterraform import \"module.gateway-route-tables[\\\"" + tf_name + "\\\"].oci_core_default_route_table.default_route_table[0]\" " + str(routetable.id)) + tf_resource = f'module.gateway-route-tables[\\"{tf_name}\\"].oci_core_default_route_table.default_route_table[0]' else: - importCommands[region.lower()].write("\nterraform import \"module.gateway-route-tables[\\\"" + tf_name + "\\\"].oci_core_route_table.route_table[0]\" " + str(routetable.id)) + tf_resource = f'module.gateway-route-tables[\\"{tf_name}\\"].oci_core_route_table.route_table[0]' else: if ("Default Route Table for " in dn): - importCommands[region.lower()].write("\nterraform import \"module.route-tables[\\\"" + tf_name + "\\\"].oci_core_default_route_table.default_route_table[0]\" " + str(routetable.id)) + tf_resource = f'module.route-tables[\\"{tf_name}\\"].oci_core_default_route_table.default_route_table[0]' else: - importCommands[region.lower()].write("\nterraform import \"module.route-tables[\\\"" + tf_name + "\\\"].oci_core_route_table.route_table[0]\" " + str(routetable.id)) + tf_resource = f'module.route-tables[\\"{tf_name}\\"].oci_core_route_table.route_table[0]' + + if tf_resource not in state["resources"]: + importCommands[region.lower()] += f'\n{tf_or_tofu} import "{tf_resource}" {str(routetable.id)}' if(not rules): insert_values(routetable, values_for_column, region, comp_name, vcn_name,None) @@ -170,9 +175,12 @@ def export_drg_routetable(inputfile, outdir, service_dir,config1,signer1, ct, ex global importCommands_drg global config config=config1 - global signer + global signer,tf_or_tofu signer=signer1 + tf_or_tofu = ct.tf_or_tofu + tf_state_list = [tf_or_tofu, "state", "list"] + cd3file = inputfile if '.xls' not in cd3file: print("\nAcceptable cd3 format: .xlsx") @@ -194,17 +202,21 @@ def export_drg_routetable(inputfile, outdir, service_dir,config1,signer1, ct, ex if tf_import_cmd_drg: importCommands_drg = {} for reg in export_regions: - if (os.path.exists(outdir + "/" + reg + "/" + service_dir+ "/tf_import_commands_network_drg_routerules_nonGF.sh")): - commonTools.backup_file(outdir + "/" + reg+ "/" + service_dir, "tf_import_network", - "tf_import_commands_network_drg_routerules_nonGF.sh") - importCommands_drg[reg] = open(outdir + "/" + reg + "/" + service_dir+ "/tf_import_commands_network_drg_routerules_nonGF.sh", "w") - importCommands_drg[reg].write("#!/bin/bash") - importCommands_drg[reg].write("\n") - importCommands_drg[reg].write("terraform init") - importCommands_drg[reg].write("\n\n######### Writing import for DRG Route Tables #########\n\n") + if (os.path.exists(outdir + "/" + reg + "/" + service_dir+ "/import_commands_network_drg_routerules.sh")): + commonTools.backup_file(outdir + "/" + reg+ "/" + service_dir, "import_network", + "import_commands_network_drg_routerules.sh") + importCommands_drg[reg] = "" for reg in export_regions: config.__setitem__("region", commonTools().region_dict[reg]) + state = {'path': f'{outdir}/{reg}/{service_dir}', 'resources': []} + try: + byteOutput = sp.check_output(tf_state_list, cwd=state["path"],stderr=sp.DEVNULL) + output = byteOutput.decode('UTF-8').rstrip() + for item in output.split('\n'): + state["resources"].append(item.replace("\"", "\\\"")) + except Exception as e: + pass vcn = VirtualNetworkClient(config=config, retry_strategy=oci.retry.DEFAULT_RETRY_STRATEGY,signer=signer,timeout=(30,120)) region = reg.capitalize() #comp_ocid_done = [] @@ -234,23 +246,28 @@ def export_drg_routetable(inputfile, outdir, service_dir,config1,signer1, ct, ex drg_rt_tf_name = commonTools.check_tf_variable(drg_rt_name) if tf_import_cmd_drg: if drg_route_table_name not in commonTools.drg_auto_RTs: - importCommands_drg[reg].write("\nterraform import \"module.drg-route-tables[\\\"" + drg_rt_tf_name + "\\\"].oci_core_drg_route_table.drg_route_table\" " + drg_route_table_id) - - + tf_resource = f'module.drg-route-tables[\\"{drg_rt_tf_name}\\"].oci_core_drg_route_table.drg_route_table' + if tf_resource not in state["resources"]: + importCommands_drg[reg] += f'\n{tf_or_tofu} import "{tf_resource}" {drg_route_table_id}' #drg_rt_rules = vcn.list_drg_route_rules(drg_route_table_id) drg_rt_rules = oci.pagination.list_call_get_all_results(vcn.list_drg_route_rules, drg_route_table_id,route_type="STATIC") #drg_rt_rules = None print_drg_routerules(drg_route_table_info, drg_display_name,drg_route_table_name, import_drg_route_distribution_name, - drg_rt_rules, region, ntk_compartment_name) + drg_rt_rules, region, ntk_compartment_name,state) commonTools.write_to_cd3(values_for_column_drg, cd3file, "DRGRouteRulesinOCI") print("DRG RouteRules exported to CD3\n") if tf_import_cmd_drg: for reg in export_regions: - importCommands_drg[reg].write('\n\nterraform plan\n') - importCommands_drg[reg].close() + script_file = f'{outdir}/{reg}/{service_dir}/import_commands_network_drg_routerules.sh' + init_commands = f'\n#!/bin/bash\n{tf_or_tofu} init\n######### Writing import for DRG Route Tables #########\n' + if importCommands_drg[reg] != "": + importCommands_drg[reg] += f'\n{tf_or_tofu} plan\n' + with open(script_file, 'a') as importCommandsfile: + importCommandsfile.write(init_commands + importCommands_drg[reg]) + # Execution of the code begins here for route table export @@ -263,9 +280,12 @@ def export_routetable(inputfile, outdir, service_dir,config1,signer1, ct, export global values_for_vcninfo global config config=config1 - global signer + global signer,tf_or_tofu signer=signer1 + tf_or_tofu = ct.tf_or_tofu + tf_state_list = [tf_or_tofu, "state", "list"] + cd3file = inputfile if '.xls' not in cd3file: print("\nAcceptable cd3 format: .xlsx") @@ -291,17 +311,21 @@ def export_routetable(inputfile, outdir, service_dir,config1,signer1, ct, export if tf_import_cmd: importCommands={} for reg in export_regions: - if (os.path.exists(outdir + "/" + reg + "/" + service_dir+ "/tf_import_commands_network_routerules_nonGF.sh")): - commonTools.backup_file(outdir + "/" + reg+ "/" + service_dir, "tf_import_network", - "tf_import_commands_network_routerules_nonGF.sh") - importCommands[reg] = open(outdir + "/" + reg + "/" + service_dir+ "/tf_import_commands_network_routerules_nonGF.sh", "a") - importCommands[reg].write("#!/bin/bash") - importCommands[reg].write("\n") - importCommands[reg].write("terraform init") - importCommands[reg].write("\n\n######### Writing import for Route Tables #########\n\n") + if (os.path.exists(outdir + "/" + reg + "/" + service_dir+ "/import_commands_network_routerules.sh")): + commonTools.backup_file(outdir + "/" + reg+ "/" + service_dir, "import_network", + "import_commands_network_routerules.sh") + importCommands[reg] = '' for reg in export_regions: config.__setitem__("region", commonTools().region_dict[reg]) + state = {'path': f'{outdir}/{reg}/{service_dir}', 'resources': []} + try: + byteOutput = sp.check_output(tf_state_list, cwd=state["path"],stderr=sp.DEVNULL) + output = byteOutput.decode('UTF-8').rstrip() + for item in output.split('\n'): + state["resources"].append(item.replace("\"", "\\\"")) + except Exception as e: + pass vcn = VirtualNetworkClient(config=config, retry_strategy=oci.retry.DEFAULT_RETRY_STRATEGY,signer=signer) region = reg.capitalize() #comp_ocid_done = [] @@ -336,13 +360,18 @@ def export_routetable(inputfile, outdir, service_dir,config1,signer1, ct, export for ntk_compartment_name_again in export_compartments: routetables = oci.pagination.list_call_get_all_results(vcn.list_route_tables, compartment_id=ct.ntk_compartment_ids[ntk_compartment_name_again], vcn_id=vcn_id, lifecycle_state='AVAILABLE') - print_routetables(routetables,region,vcn_name,ntk_compartment_name_again,gw_route_table_ids) + print_routetables(routetables,region,vcn_name,ntk_compartment_name_again,gw_route_table_ids,state) commonTools.write_to_cd3(values_for_column,cd3file,"RouteRulesinOCI") print("RouteRules exported to CD3\n") if tf_import_cmd: commonTools.write_to_cd3(values_for_vcninfo, cd3file, "VCN Info") for reg in export_regions: - importCommands[reg].write('\n\nterraform plan\n') - importCommands[reg].close() + script_file = f'{outdir}/{reg}/{service_dir}/import_commands_network_routerules.sh' + init_commands = f'\n#!/bin/bash\n{tf_or_tofu} init\n######### Writing import for Route Tables #########\n' + if importCommands[reg] != "": + importCommands[reg] += f'\n{tf_or_tofu} plan\n' + with open(script_file, 'a') as importCommandsfile: + importCommandsfile.write(init_commands + importCommands[reg]) + diff --git a/cd3_automation_toolkit/Network/BaseNetwork/exportSeclist.py b/cd3_automation_toolkit/Network/BaseNetwork/exportSeclist.py index ad5c00708..2c56d935a 100644 --- a/cd3_automation_toolkit/Network/BaseNetwork/exportSeclist.py +++ b/cd3_automation_toolkit/Network/BaseNetwork/exportSeclist.py @@ -4,6 +4,7 @@ import oci from oci.core.virtual_network_client import VirtualNetworkClient import os +import subprocess as sp sys.path.append(os.getcwd()+"/../../..") from commonTools import * @@ -44,7 +45,7 @@ def insert_values(values_for_column,oci_objs, region, comp_name, vcn_name, rulet values_for_column = commonTools.export_extra_columns(oci_objs, col_header, sheet_dict,values_for_column) -def print_secrules(seclists,region,vcn_name,comp_name): +def print_secrules(seclists,region,vcn_name,comp_name,state): for seclist in seclists.data: isec_rules = seclist.ingress_security_rules esec_rules = seclist.egress_security_rules @@ -53,11 +54,13 @@ def print_secrules(seclists,region,vcn_name,comp_name): if tf_import_cmd: tf_name = vcn_name + "_" + dn - tf_name=commonTools.check_tf_variable(tf_name) + tf_name = commonTools.check_tf_variable(tf_name) if("Default Security List for " in dn): - importCommands[region.lower()].write("\nterraform import \"module.security-lists[\\\"" + tf_name + "\\\"].oci_core_default_security_list.default_security_list[0]\" " + str(seclist.id)) + tf_resource = f'module.security-lists[\\"{tf_name}\\"].oci_core_default_security_list.default_security_list[0]' else: - importCommands[region.lower()].write("\nterraform import \"module.security-lists[\\\"" + tf_name + "\\\"].oci_core_security_list.security_list[0]\" " + str(seclist.id)) + tf_resource = f'module.security-lists[\\"{tf_name}\\"].oci_core_security_list.security_list[0]' + if tf_resource not in state["resources"]: + importCommands[region.lower()] += f'\n{tf_or_tofu} import "{tf_resource}" {str(seclist.id)}' if(len(isec_rules)==0 and len(esec_rules)==0): @@ -211,7 +214,10 @@ def export_seclist(inputfile, outdir, service_dir,config,signer, ct, export_comp global tf_import_cmd global values_for_column global sheet_dict - global importCommands + global importCommands,tf_or_tofu + + tf_or_tofu = ct.tf_or_tofu + tf_state_list = [tf_or_tofu, "state", "list"] cd3file = inputfile @@ -234,18 +240,22 @@ def export_seclist(inputfile, outdir, service_dir,config,signer, ct, export_comp if tf_import_cmd: importCommands={} for reg in export_regions: - if (os.path.exists(outdir + "/" + reg + "/" + service_dir+ "/tf_import_commands_network_secrules_nonGF.sh")): - commonTools.backup_file(outdir + "/" + reg+ "/" + service_dir, "tf_import_network", - "tf_import_commands_network_secrules_nonGF.sh") - importCommands[reg] = open(outdir + "/" + reg + "/" + service_dir+ "/tf_import_commands_network_secrules_nonGF.sh", "w") - importCommands[reg].write("#!/bin/bash") - importCommands[reg].write("\n") - importCommands[reg].write("terraform init") - importCommands[reg].write("\n\n######### Writing import for Security Lists #########\n\n") + if (os.path.exists(outdir + "/" + reg + "/" + service_dir+ "/import_commands_network_secrules.sh")): + commonTools.backup_file(outdir + "/" + reg+ "/" + service_dir, "import_network", + "import_commands_network_secrules.sh") + importCommands[reg] = '' for reg in export_regions: config.__setitem__("region", commonTools().region_dict[reg]) + state = {'path': f'{outdir}/{reg}/{service_dir}', 'resources': []} + try: + byteOutput = sp.check_output(tf_state_list, cwd=state["path"],stderr=sp.DEVNULL) + output = byteOutput.decode('UTF-8').rstrip() + for item in output.split('\n'): + state["resources"].append(item.replace("\"", "\\\"")) + except Exception as e: + pass vcn = VirtualNetworkClient(config=config, retry_strategy=oci.retry.DEFAULT_RETRY_STRATEGY,signer=signer) region = reg.capitalize() #comp_ocid_done = [] @@ -256,11 +266,16 @@ def export_seclist(inputfile, outdir, service_dir,config,signer, ct, export_comp vcn_name=v.display_name for ntk_compartment_name_again in export_compartments: seclists = oci.pagination.list_call_get_all_results(vcn.list_security_lists,compartment_id=ct.ntk_compartment_ids[ntk_compartment_name_again], vcn_id=vcn_id, lifecycle_state='AVAILABLE',sort_by='DISPLAYNAME') - print_secrules(seclists,region,vcn_name,ntk_compartment_name_again) + print_secrules(seclists,region,vcn_name,ntk_compartment_name_again,state) commonTools.write_to_cd3(values_for_column,cd3file,"SecRulesinOCI") print("SecRules exported to CD3\n") if tf_import_cmd: for reg in export_regions: - importCommands[reg].write('\n\nterraform plan\n') - importCommands[reg].close() + script_file = f'{outdir}/{reg}/{service_dir}/import_commands_network_secrules.sh' + init_commands = f'\n#!/bin/bash\n{tf_or_tofu} init\n######### Writing import for Security Lists #########\n' + if importCommands[reg] != "": + importCommands[reg] += f'\n{tf_or_tofu} plan\n' + with open(script_file, 'a') as importCommandsfile: + importCommandsfile.write(init_commands + importCommands[reg]) + diff --git a/cd3_automation_toolkit/Network/BaseNetwork/export_network_nonGreenField.py b/cd3_automation_toolkit/Network/BaseNetwork/export_network_nonGreenField.py index 5a7cb75b7..fae4465c6 100644 --- a/cd3_automation_toolkit/Network/BaseNetwork/export_network_nonGreenField.py +++ b/cd3_automation_toolkit/Network/BaseNetwork/export_network_nonGreenField.py @@ -8,13 +8,16 @@ from .exportRoutetable import export_drg_routetable from .exportSeclist import export_seclist from .exportNSG import export_nsg +import subprocess as sp sys.path.append(os.getcwd() + "/..") from commonTools import * importCommands = {} +importCommands_dhcp = {} importCommands_rpc = {} importCommands_vlan = {} +importCommands_subnet = {} oci_obj_names = {} @@ -87,7 +90,7 @@ def print_drgv2(values_for_column_drgv2, region, comp_name, vcn_info, drg_info, def print_vcns(values_for_column_vcns, region, comp_name, vnc,vcn_info, drg_attachment_info, igw_info, ngw_info, sgw_info, - lpg_display_names): + lpg_display_names,state): drg_info=None for col_header in values_for_column_vcns.keys(): @@ -161,11 +164,12 @@ def print_vcns(values_for_column_vcns, region, comp_name, vnc,vcn_info, drg_atta values_for_column_vcns) tf_name = commonTools.check_tf_variable(vcn_info.display_name) - importCommands[region.lower()].write( - "\nterraform import \"module.vcns[\\\"" + tf_name + "\\\"].oci_core_vcn.vcn\" " + str(vcn_info.id)) + tf_resource = f'module.vcns[\\"{tf_name}\\"].oci_core_vcn.vcn' + if tf_resource not in state["resources"]: + importCommands[region.lower()].write(f'\n{tf_or_tofu} import "{tf_resource}" {str(vcn_info.id)}') -def print_dhcp(values_for_column_dhcp, region, comp_name, vcn_name, dhcp_info): +def print_dhcp(values_for_column_dhcp, region, comp_name, vcn_name, dhcp_info,state): tf_name = vcn_name + "_" + str(dhcp_info.display_name) tf_name = commonTools.check_tf_variable(tf_name) @@ -206,27 +210,26 @@ def print_dhcp(values_for_column_dhcp, region, comp_name, vcn_name, dhcp_info): values_for_column_dhcp = commonTools.export_extra_columns(oci_objs, col_header, sheet_dict_dhcp, values_for_column_dhcp) if ("Default DHCP Options for " in dhcp_info.display_name): - importCommands[region.lower()].write( - "\nterraform import \"module.default-dhcps[\\\"" + tf_name + "\\\"].oci_core_default_dhcp_options.default_dhcp_option\" " + str( - dhcp_info.id)) + tf_resource = f'module.default-dhcps[\\"{tf_name}\\"].oci_core_default_dhcp_options.default_dhcp_option' else: - importCommands[region.lower()].write( - "\nterraform import \"module.custom-dhcps[\\\"" + tf_name + "\\\"].oci_core_dhcp_options.custom_dhcp_option\" " + str( - dhcp_info.id)) + tf_resource = f'module.custom-dhcps[\\"{tf_name}\\"].oci_core_dhcp_options.custom_dhcp_option' + if tf_resource not in state["resources"]: + importCommands_dhcp[region.lower()].write(f'\n{tf_or_tofu} import "{tf_resource}" {str(dhcp_info.id)}') def print_subnets_vlans(values_for_column_subnets_vlans, region, comp_name, vcn_name, subnet_vlan_info, dhcp_name, - rt_name, sl_nsg_names, add_def_seclist, subnet_vlan_in_excel): + rt_name, sl_nsg_names, add_def_seclist, subnet_vlan_in_excel,state): tf_name = vcn_name + "_" + str(subnet_vlan_info.display_name) tf_name = commonTools.check_tf_variable(tf_name) if subnet_vlan_in_excel == 'Subnet': - importCommands[region.lower()].write( - "\nterraform import \"module.subnets[\\\"" + tf_name + "\\\"].oci_core_subnet.subnet\" " + str( - subnet_vlan_info.id)) + tf_resource = f'module.subnets[\\"{tf_name}\\"].oci_core_subnet.subnet' + if tf_resource not in state["resources"]: + importCommands_subnet[region.lower()].write(f'\n{tf_or_tofu} import "{tf_resource}" {str(subnet_vlan_info.id)}') + elif subnet_vlan_in_excel == 'VLAN': - importCommands_vlan[region.lower()].write( - "\nterraform import \"module.vlans[\\\"" + tf_name + "\\\"].oci_core_vlan.vlan\" " + str( - subnet_vlan_info.id)) + tf_resource = f'module.vlans[\\"{tf_name}\\"].oci_core_vlan.vlan' + if tf_resource not in state["resources"]: + importCommands_vlan[region.lower()].write(f'\n{tf_or_tofu} import "{tf_resource}" {str(subnet_vlan_info.id)}') for col_header in values_for_column_subnets_vlans.keys(): if (col_header == "Region"): @@ -322,7 +325,7 @@ def get_drg_rt_name(drg_rpc_attachment_list, source_rpc_id, rpc_source_client): def get_rpc_resources(source_region, SOURCE_RPC_LIST, dest_rpc_dict, rpc_source_client, ct, values_for_column, - ntk_compartment_name, outdir): + ntk_compartment_name, outdir,drg_info, drg_attachment_info,state_rpc): # Variables dest_rpc_drg_name = "" src_drg_rt_name = "" @@ -381,6 +384,7 @@ def get_comp_details(comp_data): src_drg_rt_import_dist_id = getattr(src_drg_rt_dist.data, 'import_drg_route_distribution_id') if (src_drg_rt_import_dist_id!=None): import_rt_info = rpc_source_client.get_drg_route_distribution(drg_route_distribution_id=src_drg_rt_import_dist_id) + src_drg_rt_dist_info = import_rt_info drg_rt_import_dist_name = getattr(import_rt_info.data, "display_name") import_rt_statements = rpc_source_client.list_drg_route_distribution_statements(drg_route_distribution_id=src_drg_rt_import_dist_id) @@ -406,6 +410,7 @@ def get_comp_details(comp_data): dest_rpc_details = client.get_remote_peering_connection( remote_peering_connection_id=source_rpc_peer_id) dest_rpc_drg_id = dest_rpc.drg_id + dest_drg_info=client.get_drg(drg_id=dest_rpc_drg_id).data dest_rpc_drg_name = getattr(client.get_drg(drg_id=dest_rpc_drg_id).data, 'display_name') dest_drg_comp_name = get_comp_details(getattr(client.get_drg(drg_id=dest_rpc_drg_id).data, 'compartment_id')) dest_rpc_display_name = dest_rpc.display_name @@ -428,16 +433,18 @@ def get_comp_details(comp_data): 'import_drg_route_distribution_id') if dest_drg_rt_import_dist_id!=None: dest_import_rt_info = client.get_drg_route_distribution(drg_route_distribution_id=dest_drg_rt_import_dist_id) + dest_drg_rt_dist_info=dest_import_rt_info dest_drg_rt_import_dist_name = getattr(dest_import_rt_info.data, "display_name") dest_import_rt_statements = client.list_drg_route_distribution_statements(drg_route_distribution_id=dest_drg_rt_import_dist_id) - importCommands_rpc["global"].write( - "\nterraform import \"module.rpcs[\\\"" + rpc_tf_name + f"\\\"].oci_core_remote_peering_connection.{source_region.lower()}_{region.lower()}_requester_rpc[\\\"region\\\"]\" " + str( - source_rpc_id)) - importCommands_rpc["global"].write( - "\nterraform import \"module.rpcs[\\\"" + rpc_tf_name + f"\\\"].oci_core_remote_peering_connection.{source_region.lower()}_{region.lower()}_accepter_rpc[\\\"region\\\"]\" " + str( - dest_rpc_id)) - importCommands_rpc["global"].write("\nterraform plan") + tf_resource = f'module.rpcs[\\"{rpc_tf_name}\\"].oci_core_remote_peering_connection.{source_region.lower()}_{region.lower()}_requester_rpc[\\"region\\"]' + if tf_resource not in state_rpc["resources"]: + importCommands_rpc["global"].write(f'\n{tf_or_tofu} import "{tf_resource}" {str(source_rpc_id)}') + tf_resource = f'module.rpcs[\\"{rpc_tf_name}\\"].oci_core_remote_peering_connection.{source_region.lower()}_{region.lower()}_accepter_rpc[\\"region\\"]' + if tf_resource not in state_rpc["resources"]: + importCommands_rpc["global"].write(f'\n{tf_or_tofu} import "{tf_resource}" {str(dest_rpc_id)}') + + importCommands_rpc["global"].write(f'\n{tf_or_tofu} plan') for col_header in values_for_column: if col_header == 'Region': values_for_column[col_header].append(source_region) @@ -480,9 +487,10 @@ def get_comp_details(comp_data): values_for_column[col_header].append(statement_val) elif col_header.lower() in commonTools.tagColumns: - values_for_column = commonTools.export_tags(new_rpc, col_header, values_for_column) + values_for_column = commonTools.export_tags(drg_info, col_header, values_for_column) else: - oci_objs = [new_rpc] + oci_objs = [new_rpc, drg_info, drg_attachment_info, src_drg_rt_dist, + src_drg_rt_dist_info] values_for_column = commonTools.export_extra_columns(oci_objs, col_header, sheet_dict, values_for_column) @@ -529,9 +537,10 @@ def get_comp_details(comp_data): values_for_column[col_header].append(statement_val) elif col_header.lower() in commonTools.tagColumns: - values_for_column = commonTools.export_tags(new_rpc, col_header, values_for_column) + values_for_column = commonTools.export_tags(dest_drg_info, col_header, values_for_column) else: - oci_objs = [new_rpc] + oci_objs = [new_rpc, dest_drg_info, dest_drg_rt_dist, + dest_drg_rt_dist_info] values_for_column = commonTools.export_extra_columns(oci_objs, col_header, sheet_dict, values_for_column) @@ -544,7 +553,9 @@ def get_comp_details(comp_data): def export_major_objects(inputfile, outdir, service_dir, config, signer, ct, export_compartments=[], export_regions=[]): global sheet_dict_vcns - global sheet_dict_drgv2 + global sheet_dict_drgv2,tf_or_tofu + tf_or_tofu = ct.tf_or_tofu + tf_state_list = [tf_or_tofu, "state", "list"] cd3file = inputfile if ('.xls' not in cd3file): @@ -563,7 +574,7 @@ def export_major_objects(inputfile, outdir, service_dir, config, signer, ct, exp # For RPCs import file. # Create backups - rpc_file_name = 'tf_import_commands_' + "rpcs" + '_nonGF.sh' + rpc_file_name = 'import_commands_' + "rpcs" + '.sh' rpc_script_file = f'{outdir}/global/rpc/{rpc_file_name}' os.makedirs(os.path.dirname(rpc_script_file), exist_ok=True) importCommands_rpc["global"] = open(rpc_script_file, "w+") @@ -571,6 +582,14 @@ def export_major_objects(inputfile, outdir, service_dir, config, signer, ct, exp importCommands_rpc["global"].write("\n") importCommands_rpc["global"].write("terraform init") importCommands_rpc["global"].write("\n\n######### Writing import for RPC #########\n\n") + state_rpc = {'path': f'{outdir}/global/rpc/', 'resources': []} + try: + byteOutput = sp.check_output(tf_state_list, cwd=state_rpc["path"],stderr=sp.DEVNULL) + output = byteOutput.decode('UTF-8').rstrip() + for item in output.split('\n'): + state_rpc["resources"].append(item.replace("\"", "\\\"")) + except Exception as e: + pass # Remove existing rpc.safe file if exists. file_path = f'{outdir}/global/rpc/' + "rpc.safe" @@ -579,16 +598,23 @@ def export_major_objects(inputfile, outdir, service_dir, config, signer, ct, exp # Create backups for reg in export_regions: - if (os.path.exists(outdir + "/" + reg + "/" + service_dir + "/tf_import_commands_network_major-objects_nonGF.sh")): - commonTools.backup_file(outdir + "/" + reg + "/" + service_dir, "tf_import_network", - "tf_import_commands_network_major-objects_nonGF.sh") + file_name = "import_commands_network_major-objects.sh" + if (os.path.exists(outdir + "/" + reg + "/" + service_dir +"/"+ file_name)): + commonTools.backup_file(outdir + "/" + reg + "/" + service_dir, "import_network",file_name) if (os.path.exists(outdir + "/" + reg + "/" + service_dir + "/obj_names.safe")): commonTools.backup_file(outdir + "/" + reg + "/" + service_dir, "obj_names", "obj_names.safe") - importCommands[reg] = open( - outdir + "/" + reg + "/" + service_dir + "/tf_import_commands_network_major-objects_nonGF.sh", "w") + importCommands[reg] = open(outdir + "/" + reg + "/" + service_dir +"/"+ file_name, "w") + state = {'path': f'{outdir}/{reg}/{service_dir}', 'resources': []} + try: + byteOutput = sp.check_output(tf_state_list, cwd=state["path"],stderr=sp.DEVNULL) + output = byteOutput.decode('UTF-8').rstrip() + for item in output.split('\n'): + state["resources"].append(item.replace("\"", "\\\"")) + except Exception as e: + pass importCommands[reg].write("#!/bin/bash") importCommands[reg].write("\n") - importCommands[reg].write("terraform init") + importCommands[reg].write(f'{tf_or_tofu} init') oci_obj_names[reg] = open(outdir + "/" + reg + "/" + service_dir + "/obj_names.safe", "w") print("Tabs- VCNs and DRGs would be overwritten during export process!!!\n") @@ -632,8 +658,9 @@ def export_major_objects(inputfile, outdir, service_dir, config, signer, ct, exp tf_name = commonTools.check_tf_variable(drg_display_name) if (drg_id not in drg_ocid): oci_obj_names[reg].write("\nDRG Version::::" + drg_display_name + "::::" + drg_version) - importCommands[reg].write( - "\nterraform import \"module.drgs[\\\"" + tf_name + "\\\"].oci_core_drg.drg\" " + drg_info.id) + tf_resource = f'module.drgs[\\"{tf_name}\\"].oci_core_drg.drg' + if tf_resource not in state["resources"]: + importCommands[reg].write( f'\n{tf_or_tofu} import "{tf_resource}" {str(drg_info.id)}') drg_ocid.append(drg_id) # Get Attachment Details @@ -647,8 +674,6 @@ def export_major_objects(inputfile, outdir, service_dir, config, signer, ct, exp attach_type = "VCN" attach_id = drg_attachment_info.vcn_id - - vcn_info = None if (attach_type.upper() == "VCN"): vcn_drgattach_route_table_id = drg_attachment_info.route_table_id @@ -656,9 +681,9 @@ def export_major_objects(inputfile, outdir, service_dir, config, signer, ct, exp # tf_name = vcn_info.display_name + "_" + drg_attachment_name tf_name = commonTools.check_tf_variable(drg_attachment_name) - - importCommands[reg].write( - "\nterraform import \"module.drg-attachments[\\\"" + tf_name + "\\\"].oci_core_drg_attachment.drg_attachment\" " + drg_attachment_info.id) + tf_resource = f'module.drg-attachments[\\"{tf_name}\\"].oci_core_drg_attachment.drg_attachment' + if tf_resource not in state["resources"]: + importCommands[reg].write(f'\n{tf_or_tofu} import "{tf_resource}" {str(drg_attachment_info.id)}') #oci_obj_names[reg].write( #"\ndrgattachinfo::::" + vcn_info.display_name + "::::" + drg_display_name + "::::" + drg_attachment_name) @@ -683,14 +708,15 @@ def export_major_objects(inputfile, outdir, service_dir, config, signer, ct, exp tf_name = commonTools.check_tf_variable( drg_display_name + "_" + import_drg_route_distribution_info.display_name) if (import_drg_route_distribution_info.display_name not in commonTools.drg_auto_RDs): - importCommands[reg].write( - "\nterraform import \"module.drg-route-distributions[\\\"" + tf_name + "\\\"].oci_core_drg_route_distribution.drg_route_distribution\" " + import_drg_route_distribution_info.id) + tf_resource = f'module.drg-route-distributions[\\"{tf_name}\\"].oci_core_drg_route_distribution.drg_route_distribution' + if tf_resource not in state["resources"]: + importCommands[reg].write(f'\n{tf_or_tofu} import "{tf_resource}" {str(import_drg_route_distribution_info.id)}') k = 1 for stmt in drg_route_distribution_statements.data: - importCommands[reg].write( - "\nterraform import \"module.drg-route-distribution-statements[\\\"" + tf_name + "_statement" + str( - k) + "\\\"].oci_core_drg_route_distribution_statement.drg_route_distribution_statement\" drgRouteDistributions/" + import_drg_route_distribution_info.id + "/statements/" + stmt.id) + tf_resource = f'module.drg-route-distribution-statements[\\"{tf_name}_statement{str(k)}\\"].oci_core_drg_route_distribution_statement.drg_route_distribution_statement' + if tf_resource not in state["resources"]: + importCommands[reg].write( f'\n{tf_or_tofu} import "{tf_resource}" drgRouteDistributions/{str(import_drg_route_distribution_info.id)}/statements/{stmt.id}') k = k + 1 print_drgv2(values_for_column_drgv2, region, drg_comp_name, vcn_info, drg_info, drg_attachment_info, @@ -721,14 +747,14 @@ def export_major_objects(inputfile, outdir, service_dir, config, signer, ct, exp tf_name = commonTools.check_tf_variable( drg_display_name + "_" + import_drg_route_distribution_info.display_name) if (import_drg_route_distribution_info.display_name not in commonTools.drg_auto_RDs): - importCommands[reg].write( - "\nterraform import \"module.drg-route-distributions[\\\"" + tf_name + "\\\"].oci_core_drg_route_distribution.drg_route_distribution\" " + import_drg_route_distribution_info.id) - + tf_resource = f'module.drg-route-distributions[\\"{tf_name}\\"].oci_core_drg_route_distribution.drg_route_distribution' + if tf_resource not in state["resources"]: + importCommands[reg].write(f'\n{tf_or_tofu} import "{tf_resource}" {str(import_drg_route_distribution_info.id)}') k = 1 for stmt in drg_route_distribution_statements.data: - importCommands[reg].write( - "\nterraform import \"module.drg-route-distribution-statements[\\\"" + tf_name + "_statement" + str( - k) + "\\\"].oci_core_drg_route_distribution_statement.drg_route_distribution_statement\" drgRouteDistributions/" + import_drg_route_distribution_info.id + "/statements/" + stmt.id) + tf_resource = f'module.drg-route-distribution-statements[\\"{tf_name}_statement{str(k)}\\"].oci_core_drg_route_distribution_statement.drg_route_distribution_statement' + if tf_resource not in state["resources"]: + importCommands[reg].write(f'\n{tf_or_tofu} import "{tf_resource}" drgRouteDistributions/{str(import_drg_route_distribution_info.id)}/statements/{stmt.id}') k = k + 1 dest_rpc_dict = {} @@ -746,7 +772,7 @@ def export_major_objects(inputfile, outdir, service_dir, config, signer, ct, exp ntk_compartment_name]) get_rpc_resources(region, SOURCE_RPC_LIST, dest_rpc_dict, vnc, - ct, values_for_column_drgv2, ntk_compartment_name, outdir) + ct, values_for_column_drgv2, ntk_compartment_name, outdir,drg_info, drg_attachment_info,state_rpc) rpc_execution = False # Get All Other RTs for this DRG only if it is DRGv2 @@ -779,14 +805,15 @@ def export_major_objects(inputfile, outdir, service_dir, config, signer, ct, exp tf_name = commonTools.check_tf_variable( drg_display_name + "_" + import_drg_route_distribution_info.display_name) if (import_drg_route_distribution_info.display_name not in commonTools.drg_auto_RDs): - importCommands[reg].write( - "\nterraform import \"module.drg-route-distributions[\\\"" + tf_name + "\\\"].oci_core_drg_route_distribution.drg_route_distribution\" " + import_drg_route_distribution_info.id) - + tf_resource = f'module.drg-route-distributions[\\"{tf_name}\\"].oci_core_drg_route_distribution.drg_route_distribution' + if tf_resource not in state["resources"]: + importCommands[reg].write(f'\n{tf_or_tofu} import "{tf_resource}" {str(import_drg_route_distribution_info.id)}') k = 1 for stmt in drg_route_distribution_statements.data: - importCommands[reg].write( - "\nterraform import \"module.drg-route-distribution-statements[\\\"" + tf_name + "_statement" + str( - k) + "\\\"].oci_core_drg_route_distribution_statement.drg_route_distribution_statement\" drgRouteDistributions/" + import_drg_route_distribution_info.id + "/statements/" + stmt.id) + tf_resource = f'module.drg-route-distribution-statements[\\"{tf_name}_statement{str(k)}\\"].oci_core_drg_route_distribution_statement.drg_route_distribution_statement' + if tf_resource not in state["resources"]: + importCommands[reg].write(f'\n{tf_or_tofu} import "{tf_resource}" drgRouteDistributions/{str(import_drg_route_distribution_info.id)}/statements/{stmt.id}') + k = k + 1 print_drgv2(values_for_column_drgv2, region, drg_comp_name, vcn_info, drg_info, drg_attachment_info, drg_route_table_info, @@ -799,6 +826,14 @@ def export_major_objects(inputfile, outdir, service_dir, config, signer, ct, exp # Fetch VCNs for reg in export_regions: + state = {'path': f'{outdir}/{reg}/{service_dir}', 'resources': []} + try: + byteOutput = sp.check_output(tf_state_list, cwd=state["path"],stderr=sp.DEVNULL) + output = byteOutput.decode('UTF-8').rstrip() + for item in output.split('\n'): + state["resources"].append(item.replace("\"", "\\\"")) + except Exception as e: + pass importCommands[reg].write("\n######### Writing import for VCNs #########\n") config.__setitem__("region", ct.region_dict[reg]) vnc = VirtualNetworkClient(config=config, retry_strategy=oci.retry.DEFAULT_RETRY_STRATEGY,signer=signer) @@ -834,9 +869,9 @@ def export_major_objects(inputfile, outdir, service_dir, config, signer, ct, exp igw_display_name = igw_info.display_name tf_name = vcn_info.display_name + "_" + igw_display_name tf_name = commonTools.check_tf_variable(tf_name) - importCommands[reg].write( - "\nterraform import \"module.igws[\\\"" + tf_name + "\\\"].oci_core_internet_gateway.internet_gateway\" " + igw_info.id) - + tf_resource = f'module.igws[\\"{tf_name}\\"].oci_core_internet_gateway.internet_gateway' + if tf_resource not in state["resources"]: + importCommands[reg].write(f'\n{tf_or_tofu} import "{tf_resource}" {str(igw_info.id)}') # ngw_display_name = "n" NGWs = oci.pagination.list_call_get_all_results(vnc.list_nat_gateways, @@ -848,9 +883,9 @@ def export_major_objects(inputfile, outdir, service_dir, config, signer, ct, exp ngw_display_name = ngw_info.display_name tf_name = vcn_info.display_name + "_" + ngw_display_name tf_name = commonTools.check_tf_variable(tf_name) - - importCommands[reg].write( - "\nterraform import \"module.ngws[\\\"" + tf_name + "\\\"].oci_core_nat_gateway.nat_gateway\" " + ngw_info.id) + tf_resource = f'module.ngws[\\"{tf_name}\\"].oci_core_nat_gateway.nat_gateway' + if tf_resource not in state["resources"]: + importCommands[reg].write(f'\n{tf_or_tofu} import "{tf_resource}" {str(ngw_info.id)}') # sgw_display_name = "n" SGWs = oci.pagination.list_call_get_all_results(vnc.list_service_gateways, @@ -862,8 +897,9 @@ def export_major_objects(inputfile, outdir, service_dir, config, signer, ct, exp sgw_display_name = sgw_info.display_name tf_name = vcn_info.display_name + "_" + sgw_display_name tf_name = commonTools.check_tf_variable(tf_name) - importCommands[reg].write( - "\nterraform import \"module.sgws[\\\"" + tf_name + "\\\"].oci_core_service_gateway.service_gateway\" " + sgw_info.id) + tf_resource = f'module.sgws[\\"{tf_name}\\"].oci_core_service_gateway.service_gateway' + if tf_resource not in state["resources"]: + importCommands[reg].write(f'\n{tf_or_tofu} import "{tf_resource}" {str(sgw_info.id)}') lpg_display_names = "" LPGs = oci.pagination.list_call_get_all_results(vnc.list_local_peering_gateways, @@ -884,8 +920,9 @@ def export_major_objects(inputfile, outdir, service_dir, config, signer, ct, exp tf_name = vcn_info.display_name + "_" + lpg_info.display_name tf_name = commonTools.check_tf_variable(tf_name) - importCommands[reg].write( - "\nterraform import \"module.exported-lpgs[\\\"" + tf_name + "\\\"].oci_core_local_peering_gateway.local_peering_gateway\" " + lpg_info.id) + tf_resource = f'module.exported-lpgs[\\"{tf_name}\\"].oci_core_local_peering_gateway.local_peering_gateway' + if tf_resource not in state["resources"]: + importCommands[reg].write(f'\n{tf_or_tofu} import "{tf_resource}" {str(lpg_info.id)}') if (lpg_display_names == ""): lpg_display_names = "n" @@ -894,19 +931,22 @@ def export_major_objects(inputfile, outdir, service_dir, config, signer, ct, exp # Fill VCNs Tab print_vcns(values_for_column_vcns, region, ntk_compartment_name, vnc,vcn_info, drg_attachment_info, igw_info, ngw_info, - sgw_info, lpg_display_names) + sgw_info, lpg_display_names,state) commonTools.write_to_cd3(values_for_column_vcns, cd3file, "VCNs") print("VCNs exported to CD3\n") for reg in export_regions: - importCommands[reg].write('\n\nterraform plan\n') + importCommands[reg].write(f'\n\n{tf_or_tofu} plan\n') importCommands[reg].close() oci_obj_names[reg].close() def export_dhcp(inputfile, outdir, service_dir, config, signer, ct, export_compartments=[], export_regions=[]): - global sheet_dict_dhcp + global sheet_dict_dhcp,tf_or_tofu + + tf_or_tofu = ct.tf_or_tofu + tf_state_list = [tf_or_tofu, "state", "list"] cd3file = inputfile if ('.xls' not in cd3file): @@ -923,19 +963,26 @@ def export_dhcp(inputfile, outdir, service_dir, config, signer, ct, export_compa # Create backups for reg in export_regions: - if (os.path.exists(outdir + "/" + reg + "/" + service_dir + "/tf_import_commands_network_dhcp_nonGF.sh")): - commonTools.backup_file(outdir + "/" + reg + "/" + service_dir, "tf_import_network", - "tf_import_commands_network_dhcp_nonGF.sh") - importCommands[reg] = open(outdir + "/" + reg + "/" + service_dir + "/tf_import_commands_network_dhcp_nonGF.sh", - "w") - importCommands[reg].write("#!/bin/bash") - importCommands[reg].write("\n") - importCommands[reg].write("terraform init") + dhcp_file_name = "import_commands_network_dhcp.sh" + if (os.path.exists(outdir + "/" + reg + "/" + service_dir + "/"+dhcp_file_name)): + commonTools.backup_file(outdir + "/" + reg + "/" + service_dir, "import_network",dhcp_file_name) + importCommands_dhcp[reg] = open(outdir + "/" + reg + "/" + service_dir + "/"+dhcp_file_name,"w") + importCommands_dhcp[reg].write("#!/bin/bash") + importCommands_dhcp[reg].write("\n") + importCommands_dhcp[reg].write(f'{tf_or_tofu} init') print("Tab- DHCP would be overwritten during export process!!!") for reg in export_regions: - importCommands[reg].write("\n\n######### Writing import for DHCP #########\n\n") + importCommands_dhcp[reg].write("\n\n######### Writing import for DHCP #########\n\n") config.__setitem__("region", ct.region_dict[reg]) + state = {'path': f'{outdir}/{reg}/{service_dir}', 'resources': []} + try: + byteOutput = sp.check_output(tf_state_list, cwd=state["path"],stderr=sp.DEVNULL) + output = byteOutput.decode('UTF-8').rstrip() + for item in output.split('\n'): + state["resources"].append(item.replace("\"", "\\\"")) + except Exception as e: + pass vnc = VirtualNetworkClient(config=config, retry_strategy=oci.retry.DEFAULT_RETRY_STRATEGY,signer=signer) region = reg.capitalize() # comp_ocid_done = [] @@ -954,17 +1001,20 @@ def export_dhcp(inputfile, outdir, service_dir, config, signer, ct, export_compa for dhcp in DHCPs.data: dhcp_info = dhcp print_dhcp(values_for_column_dhcp, region, ntk_compartment_name_again, vcn_info.display_name, - dhcp_info) + dhcp_info,state) commonTools.write_to_cd3(values_for_column_dhcp, cd3file, "DHCP") print("DHCP exported to CD3\n") for reg in export_regions: - importCommands[reg].write('\n\nterraform plan\n') - importCommands[reg].close() + importCommands_dhcp[reg].write(f'\n\n{tf_or_tofu} plan\n') + importCommands_dhcp[reg].close() def export_subnets_vlans(inputfile, outdir, service_dir, config, signer, ct, export_compartments=[], export_regions=[]): - global sheet_dict_subnets_vlans + global sheet_dict_subnets_vlans,tf_or_tofu + tf_or_tofu = ct.tf_or_tofu + tf_state_list = [tf_or_tofu, "state", "list"] + skip_vlans = {} cd3file = inputfile if ('.xls' not in cd3file): @@ -987,41 +1037,44 @@ def export_subnets_vlans(inputfile, outdir, service_dir, config, signer, ct, exp # Create backups for subnets/vlans tf import shell script files for reg in export_regions: - if (os.path.exists( - outdir + "/" + reg + "/" + service_dir_network + "/tf_import_commands_network_subnets_nonGF.sh")): - commonTools.backup_file(outdir + "/" + reg + "/" + service_dir_network, "tf_import_network", - "tf_import_commands_network_subnets_nonGF.sh") - importCommands[reg] = open( - outdir + "/" + reg + "/" + service_dir_network + "/tf_import_commands_network_subnets_nonGF.sh", "w") - importCommands[reg].write("#!/bin/bash") - importCommands[reg].write("\n") - importCommands[reg].write("terraform init") + subnet_file_name = "import_commands_network_subnets.sh" + if (os.path.exists(outdir + "/" + reg + "/" + service_dir_network + "/"+subnet_file_name)): + commonTools.backup_file(outdir + "/" + reg + "/" + service_dir_network, "import_network",subnet_file_name) + importCommands_subnet[reg] = open(outdir + "/" + reg + "/" + service_dir_network + "/"+subnet_file_name, "w") + importCommands_subnet[reg].write("#!/bin/bash") + importCommands_subnet[reg].write("\n") + importCommands_subnet[reg].write(f'{tf_or_tofu} init') + + vlan_file_name = "import_commands_network_vlans.sh" - if (os.path.exists(outdir + "/" + reg + "/" + service_dir_vlan + "/tf_import_commands_network_vlans_nonGF.sh")): - commonTools.backup_file(outdir + "/" + reg + "/" + service_dir_vlan, "tf_import_network", - "tf_import_commands_network_vlans_nonGF.sh") - importCommands_vlan[reg] = open( - outdir + "/" + reg + "/" + service_dir_vlan + "/tf_import_commands_network_vlans_nonGF.sh", "w") - importCommands_vlan[reg].write("#!/bin/bash") - importCommands_vlan[reg].write("\n") - importCommands_vlan[reg].write("terraform init") + if (os.path.exists(outdir + "/" + reg + "/" + service_dir_vlan + "/"+vlan_file_name)): + commonTools.backup_file(outdir + "/" + reg + "/" + service_dir_vlan, "import_network",vlan_file_name) + importCommands_vlan[reg] = open(outdir + "/" + reg + "/" + service_dir_vlan + "/" + vlan_file_name, "w") print("Tab- 'SubnetsVLANs' would be overwritten during export process!!!") for reg in export_regions: - importCommands[reg].write("\n\n######### Writing import for Subnets #########\n\n") - importCommands_vlan[reg].write("\n\n######### Writing import for VLANs #########\n\n") + importCommands_subnet[reg].write("\n\n######### Writing import for Subnets #########\n\n") config.__setitem__("region", ct.region_dict[reg]) + # check resources in subnet state + state = {'path': f'{outdir}/{reg}/{service_dir_network}', 'resources': []} + try: + byteOutput = sp.check_output(tf_state_list, cwd=state["path"],stderr=sp.DEVNULL) + output = byteOutput.decode('UTF-8').rstrip() + for item in output.split('\n'): + state["resources"].append(item.replace("\"", "\\\"")) + except Exception as e: + pass vnc = VirtualNetworkClient(config=config, retry_strategy=oci.retry.DEFAULT_RETRY_STRATEGY,signer=signer) region = reg.capitalize() - skip_vlans = 0 + skip_vlans['reg'] = 0 try: VLANs = oci.pagination.list_call_get_all_results(vnc.list_vlans, compartment_id=ct.ntk_compartment_ids['root']) except Exception as e: if ('Tenancy is NOT whitelisted for VMware SKU' in str(e)): print('Tenancy is NOT whitelisted for VMware SKU..skipping export of VLANs') - skip_vlans = 1 + skip_vlans['reg'] = 1 for ntk_compartment_name in export_compartments: vcns = oci.pagination.list_call_get_all_results(vnc.list_vcns, @@ -1065,12 +1118,24 @@ def export_subnets_vlans(inputfile, outdir, service_dir, config, signer, ct, exp # Fill Subnets tab print_subnets_vlans(values_for_column_subnets_vlans, region, ntk_compartment_name_again, vcn_info.display_name, subnet_info, dhcp_name, - rt_name, sl_names, add_def_seclist, subnet_vlan_in_excel) + rt_name, sl_names, add_def_seclist, subnet_vlan_in_excel,state) # VLAN Data - if skip_vlans == 1: + if skip_vlans['reg'] == 1: continue - + importCommands_vlan[reg].write("#!/bin/bash") + importCommands_vlan[reg].write("\n") + importCommands_vlan[reg].write(f'{tf_or_tofu} init') + importCommands_vlan[reg].write("\n\n######### Writing import for VLANs #########\n\n") + # check resources in vlan state + state_vlan = {'path': f'{outdir}/{reg}/{service_dir_vlan}', 'resources': []} + try: + byteOutput = sp.check_output(tf_state_list, cwd=state_vlan["path"],stderr=sp.DEVNULL) + output = byteOutput.decode('UTF-8').rstrip() + for item in output.split('\n'): + state_vlan["resources"].append(item.replace("\"", "\\\"")) + except Exception as e: + pass subnet_vlan_in_excel = "VLAN" VLANs = oci.pagination.list_call_get_all_results(vnc.list_vlans, compartment_id=ct.ntk_compartment_ids[ @@ -1098,15 +1163,17 @@ def export_subnets_vlans(inputfile, outdir, service_dir, config, signer, ct, exp # Fill Subnets tab print_subnets_vlans(values_for_column_subnets_vlans, region, ntk_compartment_name_again, vcn_info.display_name, vlan_info, dhcp_name, - rt_name, nsg_names, add_def_seclist, subnet_vlan_in_excel) + rt_name, nsg_names, add_def_seclist, subnet_vlan_in_excel,state_vlan) commonTools.write_to_cd3(values_for_column_subnets_vlans, cd3file, "SubnetsVLANs") print("SubnetsVLANs exported to CD3\n") for reg in export_regions: - importCommands[reg].write('\n\nterraform plan\n') - importCommands[reg].close() - importCommands_vlan[reg].write('\n\nterraform plan\n') + importCommands_subnet[reg].write(f'\n\n{tf_or_tofu} plan\n') + importCommands_subnet[reg].close() + if skip_vlans['reg'] == 1: + continue + importCommands_vlan[reg].write(f'\n\n{tf_or_tofu} plan\n') importCommands_vlan[reg].close() # Execution of the code begins here diff --git a/cd3_automation_toolkit/Network/DNS/export_dns_resolvers.py b/cd3_automation_toolkit/Network/DNS/export_dns_resolvers.py index b2a3d7172..c3add289f 100644 --- a/cd3_automation_toolkit/Network/DNS/export_dns_resolvers.py +++ b/cd3_automation_toolkit/Network/DNS/export_dns_resolvers.py @@ -6,6 +6,7 @@ # import oci import os +import subprocess as sp from commonTools import * importCommands = {} oci_obj_names = {} @@ -102,12 +103,14 @@ def get_e_map(region, dns_client, vnc_client, ct, resolver, ntk_compartment_name # Write values to columns map - values_for_column -def print_resolvers(resolver_tf_name, resolver, values_for_column, **value): +def print_resolvers(resolver_tf_name, resolver, values_for_column,state, **value): endpoint_value = value region = endpoint_value['region'] res_id = endpoint_value['res_id'] e_name = endpoint_value['e_name'] - importCommands[region.lower()].write("\nterraform import \"module.dns-resolvers[\\\"" + resolver_tf_name + "\\\"].oci_dns_resolver_endpoint.resolver_endpoint[\\\"" + e_name + "\\\"]\" resolverId/"+ str(res_id)+"/name/" + str(e_name)) + tf_resource = f'module.dns-resolvers[\\"{resolver_tf_name}\\"].oci_dns_resolver_endpoint.resolver_endpoint[\\"{e_name}\\"]' + if e_name and tf_resource not in state["resources"]: + importCommands[region.lower()] += f'\n{tf_or_tofu} import "{tf_resource}" resolverId/{str(res_id)}/name/{str(e_name)}' for col_header in values_for_column: if col_header == 'Region': @@ -142,7 +145,9 @@ def export_dns_resolvers(inputfile, outdir, service_dir, config, signer, ct, exp global cd3file global reg global values_for_column - global serv_dir + global serv_dir,tf_or_tofu + tf_or_tofu = ct.tf_or_tofu + tf_state_list = [tf_or_tofu, "state", "list"] serv_dir = service_dir cd3file = inputfile @@ -160,41 +165,48 @@ def export_dns_resolvers(inputfile, outdir, service_dir, config, signer, ct, exp print("\nCD3 excel file should not be opened during export process!!!") print("Tabs- DNS-Resolvers will be overwritten during export process!!!\n") - # Create backups - resource = 'tf_import_' + sheetName.lower() - file_name = 'tf_import_commands_' + sheetName.lower() + '_nonGF.sh' + # Fetch Resolver Details + print("\nFetching details of DNS Resolvers ...") + + resource = 'import_' + sheetName.lower() + file_name = 'import_commands_' + sheetName.lower() + '.sh' + for reg in export_regions: script_file = f'{outdir}/{reg}/{serv_dir}/' + file_name + resource = 'import_' + sheetName.lower() + # Create backups if os.path.exists(script_file): commonTools.backup_file(outdir + "/" + reg + "/" + serv_dir, resource, file_name) - importCommands[reg] = open(script_file, "w") - importCommands[reg].write("#!/bin/bash") - importCommands[reg].write("\n") - importCommands[reg].write("terraform init") - # Fetch Resolver Details - print("\nFetching details of DNS Resolvers ...") + importCommands[reg] = '' - for reg in export_regions: - importCommands[reg].write("\n\n######### Writing import for DNS Resolvers #########\n\n") config.__setitem__("region", ct.region_dict[reg]) + state = {'path': f'{outdir}/{reg}/{service_dir}', 'resources': []} + try: + byteOutput = sp.check_output(tf_state_list, cwd=state["path"], stderr=sp.DEVNULL) + output = byteOutput.decode('UTF-8').rstrip() + for item in output.split('\n'): + state["resources"].append(item.replace("\"", "\\\"")) + except Exception as e: + pass region = reg.capitalize() dns_client = oci.dns.DnsClient(config=config, retry_strategy=oci.retry.DEFAULT_RETRY_STRATEGY,signer=signer) vnc_client = oci.core.VirtualNetworkClient(config=config, retry_strategy=oci.retry.DEFAULT_RETRY_STRATEGY,signer=signer) for ntk_compartment_name in export_compartments: vcns = oci.pagination.list_call_get_all_results(vnc_client.list_vcns, compartment_id=ct.ntk_compartment_ids[ntk_compartment_name], lifecycle_state="AVAILABLE") + for vcn in vcns.data: resolver_id = vnc_client.get_vcn_dns_resolver_association(vcn.id).data.dns_resolver_id resolver = dns_client.get_resolver(resolver_id).data endpoint_map = get_e_map(region, dns_client, vnc_client, ct, resolver, ntk_compartment_name) vcn_name = vnc_client.get_vcn(resolver.attached_vcn_id).data.display_name resolver_tf_name = vcn_name - importCommands[region.lower()].write( - "\nterraform import \"module.dns-resolvers[\\\"" + resolver_tf_name + "\\\"].oci_dns_resolver.resolver\" " + str( - resolver.id)) + tf_resource = f'module.dns-resolvers[\\"{resolver_tf_name}\\"].oci_dns_resolver.resolver' + if tf_resource not in state["resources"]: + importCommands[region.lower()] += f'\n{tf_or_tofu} import "{tf_resource}" {str(resolver.id)}' for key, value in endpoint_map.items(): - print_resolvers(resolver_tf_name, resolver, values_for_column, **value) + print_resolvers(resolver_tf_name, resolver, values_for_column,state,**value) commonTools.write_to_cd3(values_for_column, cd3file, sheetName) print("{0} DNS Resolvers and Endpoints exported into CD3.\n".format(len(values_for_column["Region"]))) @@ -202,7 +214,10 @@ def export_dns_resolvers(inputfile, outdir, service_dir, config, signer, ct, exp # writing data for reg in export_regions: - script_file = f'{outdir}/{reg}/{serv_dir}/' + file_name - with open(script_file, 'a') as importCommands[reg]: - importCommands[reg].write('\n\nterraform plan\n') + script_file = f'{outdir}/{reg}/{service_dir}/' + file_name + if importCommands[reg] != "": + init_commands = f'\n######### Writing import for DNS Resolvers #########\n\n#!/bin/bash\n{tf_or_tofu} init' + importCommands[reg] += f'\n{tf_or_tofu} plan\n' + with open(script_file, 'a') as importCommandsfile: + importCommandsfile.write(init_commands + importCommands[reg]) diff --git a/cd3_automation_toolkit/Network/DNS/export_dns_views_zones_records.py b/cd3_automation_toolkit/Network/DNS/export_dns_views_zones_records.py index 6037b6cb0..11ba5a798 100644 --- a/cd3_automation_toolkit/Network/DNS/export_dns_views_zones_records.py +++ b/cd3_automation_toolkit/Network/DNS/export_dns_views_zones_records.py @@ -6,6 +6,7 @@ # import oci import os +import subprocess as sp from commonTools import * importCommands = {} @@ -15,7 +16,7 @@ def get_rrset(zone_data,dns_client,record_default): r_map = {} r_tmp = {} - zone_records = dns_client.get_zone_records(zone_data.id).data + zone_records = oci.pagination.list_call_get_all_results(dns_client.get_zone_records,zone_data.id).data for zone_record in zone_records.items: if record_default == 'n' and zone_record.is_protected == True: @@ -40,7 +41,7 @@ def get_rrset(zone_data,dns_client,record_default): return r_map -def print_data(region, ntk_compartment_name, rrset, zone_data, view_data, values_for_column): +def print_data(region, ntk_compartment_name, rrset, zone_data, view_data, values_for_column,state): view_tf_name = str(view_data.display_name) #zone_tf_name = view_tf_name + "_" + str(zone_data.name).replace(".", "_") zone_name = str(zone_data.name).replace(".", "_") @@ -49,9 +50,9 @@ def print_data(region, ntk_compartment_name, rrset, zone_data, view_data, values rrset_tf_name = str(view_tf_name + "_" + zone_name + "_" + domain.replace(".", "_") + "_" + rtype).replace(".", "_") rrset_id = "zoneNameOrId/"+str(zone_data.id)+"/domain/"+domain+"/rtype/"+rtype+"/scope/PRIVATE/viewId/"+str( view_data.id) - importCommands[region.lower()].write( - "\nterraform import \"module.dns-rrsets[\\\"" + rrset_tf_name + "\\\"].oci_dns_rrset.rrset\" " + rrset_id) - + tf_resource = f'module.dns-rrsets[\\"{rrset_tf_name}\\"].oci_dns_rrset.rrset' + if tf_resource not in state["resources"]: + importCommands[region.lower()] += f'\n{tf_or_tofu} import "{tf_resource}" {rrset_id}' for col_header in values_for_column: if col_header == 'Region': @@ -104,7 +105,9 @@ def export_dns_views_zones_rrsets(inputfile, outdir, service_dir, config, signer global values_for_vcninfo global cd3file global reg - global values_for_column + global values_for_column,tf_or_tofu + tf_or_tofu = ct.tf_or_tofu + tf_state_list = [tf_or_tofu, "state", "list"] cd3file = inputfile if ('.xls' not in cd3file): @@ -127,23 +130,28 @@ def export_dns_views_zones_rrsets(inputfile, outdir, service_dir, config, signer print("Tabs- DNS-ViewsZonesRecords will be overwritten during export process!!!\n") # Create backups - resource = 'tf_import_' + sheetName.lower() - file_name = 'tf_import_commands_' + sheetName.lower() + '_nonGF.sh' - for reg in export_regions: - script_file = f'{outdir}/{reg}/{service_dir}/' + file_name - if (os.path.exists(script_file)): - commonTools.backup_file(outdir + "/" + reg +"/" + service_dir, resource, file_name) - importCommands[reg] = open(script_file, "w") - importCommands[reg].write("#!/bin/bash") - importCommands[reg].write("\n") - importCommands[reg].write("terraform init") + resource = 'import_' + sheetName.lower() + file_name = 'import_commands_' + sheetName.lower() + '.sh' # Fetch Views/Zones/rrsets Details print("\nFetching details of DNS Views/Zones/Records...") for reg in export_regions: - importCommands[reg].write("\n\n######### Writing import for DNS Views/Zones/RRsets #########\n\n") + resource = 'import_' + sheetName.lower() + importCommands[reg] = "" + script_file = f'{outdir}/{reg}/{service_dir}/' + file_name + if (os.path.exists(script_file)): + commonTools.backup_file(outdir + "/" + reg + "/" + service_dir, resource, file_name) + config.__setitem__("region", ct.region_dict[reg]) + state = {'path': f'{outdir}/{reg}/{service_dir}', 'resources': []} + try: + byteOutput = sp.check_output(tf_state_list, cwd=state["path"], stderr=sp.DEVNULL) + output = byteOutput.decode('UTF-8').rstrip() + for item in output.split('\n'): + state["resources"].append(item.replace("\"", "\\\"")) + except Exception as e: + pass region = reg.capitalize() dns_client = oci.dns.DnsClient(config=config, retry_strategy=oci.retry.DEFAULT_RETRY_STRATEGY, signer=signer) # Same compartment will be used to export view/zones @@ -152,6 +160,7 @@ def export_dns_views_zones_rrsets(inputfile, outdir, service_dir, config, signer for view_data in views.data: if view_default == 'n' and view_data.is_protected == True: continue + #view_data = dns_client.get_view(view.id).data view_tf_name = str(view_data.display_name) zones = oci.pagination.list_call_get_all_results(dns_client.list_zones, @@ -167,18 +176,18 @@ def export_dns_views_zones_rrsets(inputfile, outdir, service_dir, config, signer rrsets = get_rrset(zone_data, dns_client, record_default) if rrsets: for rrset in rrsets.values(): - print_data(region, ntk_compartment_name, rrset, zone_data, view_data, values_for_column) - importCommands[region.lower()].write( - "\nterraform import \"module.dns-zones[\\\"" + zone_tf_name + "\\\"].oci_dns_zone.zone\" " + str( - zone_data.id)) + print_data(region, ntk_compartment_name, rrset, zone_data, view_data, values_for_column,state) + tf_resource = f'module.dns-zones[\\"{zone_tf_name}\\"].oci_dns_zone.zone' + if tf_resource not in state["resources"]: + importCommands[region.lower()] += f'\n{tf_or_tofu} import "{tf_resource}" {str(zone_data.id)}' + else: print_empty_view(region, ntk_compartment_name, view_data, values_for_column) else: print_empty_view(region, ntk_compartment_name, view_data, values_for_column) - - importCommands[region.lower()].write( - "\nterraform import \"module.dns-views[\\\"" + view_tf_name + "\\\"].oci_dns_view.view\" " + str( - view_data.id)) + tf_resource = f'module.dns-views[\\"{view_tf_name}\\"].oci_dns_view.view' + if tf_resource not in state["resources"]: + importCommands[region.lower()] += f'\n{tf_or_tofu} import "{tf_resource}" {str(view_data.id)}' #print_data(region, view_data) @@ -190,5 +199,8 @@ def export_dns_views_zones_rrsets(inputfile, outdir, service_dir, config, signer # writing data for reg in export_regions: script_file = f'{outdir}/{reg}/{service_dir}/' + file_name - with open(script_file, 'a') as importCommands[reg]: - importCommands[reg].write('\n\nterraform plan\n') + if importCommands[reg] != "": + init_commands = f'\n######### Writing import for DNS Views/Zones/RRsets #########\n\n#!/bin/bash\n{tf_or_tofu} init' + importCommands[reg] += f'\n{tf_or_tofu} plan\n' + with open(script_file, 'a') as importCommandsfile: + importCommandsfile.write(init_commands + importCommands[reg]) diff --git a/cd3_automation_toolkit/Network/Global/create_rpc_resources.py b/cd3_automation_toolkit/Network/Global/create_rpc_resources.py index 91bc86c6a..5dbd83592 100755 --- a/cd3_automation_toolkit/Network/Global/create_rpc_resources.py +++ b/cd3_automation_toolkit/Network/Global/create_rpc_resources.py @@ -138,6 +138,7 @@ def create_rpc_resource(inputfile, outdir, service_dir, prefix, auth_mechanism, for eachregion in ct.all_regions: tfStr["global"] = '' + match_list = [] for i in df.index: if str(df.loc[i, 'Attached To']).lower().startswith("rpc"): @@ -270,19 +271,20 @@ def create_rpc_resource(inputfile, outdir, service_dir, prefix, auth_mechanism, # Write all info to TF string tfStr["global"] = tfStr["global"] + template.render(tempStr) - # Write TF string to the file in respective region directory - # for reg in ct.all_regions: + # Write TF string to the file in global directory + reg_out_dir = f'{outdir}/global/rpc/' if not os.path.exists(reg_out_dir): os.makedirs(reg_out_dir) + resource = sheetName.lower() + commonTools.backup_file(reg_out_dir + "/", resource, auto_tfvars_filename) + if tfStr["global"] != '': # Generate RPC String src = "##Add New RPC for global here##" tfStr["global"] = template.render(count=0).replace(src, tfStr["global"] + "\n" + src) tfStr["global"] = "".join([s for s in tfStr["global"].strip().splitlines(True) if s.strip("\r\n").strip()]) - resource = sheetName.lower() - commonTools.backup_file(reg_out_dir + "/", resource, auto_tfvars_filename) # Write to TF file outfile = reg_out_dir + "/" + auto_tfvars_filename diff --git a/cd3_automation_toolkit/Network/LoadBalancers/__init__.py b/cd3_automation_toolkit/Network/LoadBalancers/__init__.py index f6371ef04..6b42427d1 100644 --- a/cd3_automation_toolkit/Network/LoadBalancers/__init__.py +++ b/cd3_automation_toolkit/Network/LoadBalancers/__init__.py @@ -4,6 +4,7 @@ from .create_backendset_backendservers import create_backendset_backendservers from .create_listener import create_listener from .create_path_route_set import create_path_route_set +from .create_routing_policy import create_lb_routing_policy from .create_ruleset import create_ruleset from .export_lbr_nonGreenField import export_lbr from .export_nlb_nonGreenField import export_nlb diff --git a/cd3_automation_toolkit/Network/LoadBalancers/create_backendset_backendservers.py b/cd3_automation_toolkit/Network/LoadBalancers/create_backendset_backendservers.py index 49b2c3803..61c8836d0 100644 --- a/cd3_automation_toolkit/Network/LoadBalancers/create_backendset_backendservers.py +++ b/cd3_automation_toolkit/Network/LoadBalancers/create_backendset_backendservers.py @@ -55,6 +55,10 @@ def create_backendset_backendservers(inputfile, outdir, service_dir, prefix, ct) beset_str[reg] = '' beserver_str[reg] = '' + srcdir = outdir + "/" + reg + "/" + service_dir + "/" + resource = sheetName.lower() + commonTools.backup_file(srcdir, resource, lb_auto_tfvars_filename) + # List of the column headers dfcolumns = df.columns.values.tolist() @@ -173,7 +177,7 @@ def create_backendset_backendservers(inputfile, outdir, service_dir, prefix, ct) else: pass - if columnname == "Backend ServerComp&ServerName:Port": + if columnname == "Backend ServerComp@ServerName:Port": columnname = "backend_server" columnname = commonTools.check_column_headers(columnname) @@ -186,13 +190,28 @@ def create_backendset_backendservers(inputfile, outdir, service_dir, prefix, ct) cnt = 0 #beserver_str = '' - columnvalue = str(df.loc[i,'Backend ServerComp&ServerName:Port']).strip().split(',') + columnvalue = str(df.loc[i,'Backend ServerComp@ServerName:Port']).strip().split(',') for lbr_be_server in columnvalue: + lbr_be_server=lbr_be_server.strip() + if (lbr_be_server != "" and lbr_be_server != "nan"): bserver_list = str(df.loc[i, 'Backup ']).strip().split(',') cnt = cnt + 1 - serverinfo = lbr_be_server.strip().split("&") - servername = serverinfo[1].split(":")[0].strip() + + inst_compartment_tf_name = commonTools.check_tf_variable(str(df.loc[i, 'Compartment Name']).strip()) + if len(lbr_be_server.split("@")) == 2: + if(len(lbr_be_server.split("@")[0].strip())!=0): + inst_compartment_tf_name = commonTools.check_tf_variable(lbr_be_server.split("@")[0].strip()) + serverinfo = lbr_be_server.split("@")[1] + else: + serverinfo=lbr_be_server + if (":" not in serverinfo): + print("Invalid Backend ServerComp@ServerName:Port format specified for row " + str(i + 3) + ". Exiting!!!") + exit(1) + else: + servername = serverinfo.split(":")[0].strip() + serverport = serverinfo.split(":")[1].strip() + if servername in bserver_list: backup = "true" else: @@ -202,16 +221,12 @@ def create_backendset_backendservers(inputfile, outdir, service_dir, prefix, ct) tempStr.update(tempback) backend_server_tf_name = commonTools.check_tf_variable(servername+"-"+str(cnt)) - serverport = serverinfo[1].split(":")[1].strip() - inst_compartment_tf_name = '' e = servername.count(".") if (e == 3): backend_server_ip_address = "IP:"+servername else: backend_server_ip_address = "NAME:" + servername - if serverinfo[0].strip() != "": - inst_compartment_tf_name = commonTools.check_tf_variable(serverinfo[0].strip()) tempback = {'backend_server_tf_name': backend_set_tf_name+"_"+backend_server_tf_name,'serverport':serverport,'backend_server_ip_address':backend_server_ip_address, 'instance_tf_compartment': inst_compartment_tf_name } tempStr.update(tempback) @@ -235,9 +250,7 @@ def create_backendset_backendservers(inputfile, outdir, service_dir, prefix, ct) if finalstring != "": - resource = sheetName.lower() srcdir = outdir + "/" + reg + "/" + service_dir + "/" - commonTools.backup_file(srcdir, resource, lb_auto_tfvars_filename) # Write to TF file outfile = srcdir + lb_auto_tfvars_filename diff --git a/cd3_automation_toolkit/Network/LoadBalancers/create_listener.py b/cd3_automation_toolkit/Network/LoadBalancers/create_listener.py index e1ad0ff91..0f6ece5a7 100644 --- a/cd3_automation_toolkit/Network/LoadBalancers/create_listener.py +++ b/cd3_automation_toolkit/Network/LoadBalancers/create_listener.py @@ -51,6 +51,9 @@ def create_listener(inputfile, outdir, service_dir, prefix, ct): # Take backup of files for reg in ct.all_regions: listener_str[reg] = "" + srcdir = outdir + "/" + reg + "/" + service_dir + "/" + resource = sheetName.lower() + commonTools.backup_file(srcdir, resource, lb_auto_tfvars_filename) # List of the column headers dfcolumns = df.columns.values.tolist() @@ -217,9 +220,7 @@ def create_listener(inputfile, outdir, service_dir, prefix, ct): listener_str[reg] = listener.render(skeleton=True, count=0, region=reg).replace(src,listener_str[reg]+"\n"+src) finalstring = "".join([s for s in listener_str[reg].strip().splitlines(True) if s.strip("\r\n").strip()]) - resource=sheetName.lower() srcdir = outdir + "/" + reg + "/" + service_dir + "/" - commonTools.backup_file(srcdir, resource, lb_auto_tfvars_filename) # Write to TF file outfile = srcdir + lb_auto_tfvars_filename diff --git a/cd3_automation_toolkit/Network/LoadBalancers/create_nlb_backendset_backendservers.py b/cd3_automation_toolkit/Network/LoadBalancers/create_nlb_backendset_backendservers.py index 366bf396b..86bad49e8 100644 --- a/cd3_automation_toolkit/Network/LoadBalancers/create_nlb_backendset_backendservers.py +++ b/cd3_automation_toolkit/Network/LoadBalancers/create_nlb_backendset_backendservers.py @@ -43,10 +43,14 @@ def create_nlb_backendset_backendservers(inputfile, outdir, service_dir, prefix, beset_str[reg] = '' beserver_str[reg] = '' nlb_names[reg] = [] + srcdir = outdir + "/" + reg + "/" + service_dir + "/" + resource = sheetName.lower() + commonTools.backup_file(srcdir, resource, lb_auto_tfvars_filename) # List of the column headers dfcolumns = df.columns.values.tolist() prevreg = '' + prevcomp='' for i in df.index: region = str(df.loc[i, 'Region']) @@ -60,9 +64,16 @@ def create_nlb_backendset_backendservers(inputfile, outdir, service_dir, prefix, if region in commonTools.endNames: break + if region != 'nan' and region not in ct.all_regions: print("\nInvalid Region; It should be one of the values mentioned in VCN Info tab...Exiting!!") exit(1) + compname = str(df.loc[i, 'Compartment Name']) + + if compname.lower() != 'nan': + compname = compname.strip() + prevcomp = compname + # temporary dictionaries tempStr= {} @@ -120,7 +131,7 @@ def create_nlb_backendset_backendservers(inputfile, outdir, service_dir, prefix, if columnname == "Backend HealthCheck Interval In Millis": columnname = 'interval_in_millis' - if columnname == "Backend ServerComp&ServerName:Port": + if columnname == "Backend ServerComp@ServerName:Port": columnname = "backend_server" columnname = commonTools.check_column_headers(columnname) @@ -135,25 +146,38 @@ def create_nlb_backendset_backendservers(inputfile, outdir, service_dir, prefix, cnt = 0 #beserver_str = '' - columnvalue = str(df.loc[i,'Backend ServerComp&ServerName:Port']).strip().split(',') + columnvalue = str(df.loc[i,'Backend ServerComp@ServerName:Port']).strip().split(',') for nlb_be_server in columnvalue: + + nlb_be_server = nlb_be_server.strip() + if (nlb_be_server != "" and nlb_be_server != "nan"): cnt = cnt + 1 - serverinfo = nlb_be_server.strip().split("&") - servername = serverinfo[1].split(":")[0].strip() - backend_server_tf_name = commonTools.check_tf_variable(servername+"-"+str(cnt)) - serverport = serverinfo[1].split(":")[1].strip() - inst_compartment_tf_name = '' + inst_compartment_tf_name = commonTools.check_tf_variable(prevcomp).strip() + #inst_compartment_tf_name = tempStr['compartment_tf_name'] + if len(nlb_be_server.split("@")) == 2: + if (len(nlb_be_server.split("@")[0].strip()) != 0): + inst_compartment_tf_name = commonTools.check_tf_variable(nlb_be_server.split("@")[0].strip()) + serverinfo = nlb_be_server.split("@")[1] + else: + serverinfo = nlb_be_server + if (":" not in serverinfo): + print("Invalid Backend ServerComp@ServerName:Port format specified for row " + str( + i + 3) + ". Exiting!!!") + exit(1) + else: + servername = serverinfo.split(":")[0].strip() + serverport = serverinfo.split(":")[1].strip() + + backend_server_tf_name = commonTools.check_tf_variable(servername + "-" + str(cnt)) e = servername.count(".") if (e == 3): - backend_server_ip_address = "IP:"+servername + backend_server_ip_address = "IP:" + servername servername = "" else: backend_server_ip_address = "NAME:" + servername - if serverinfo[0].strip() != "": - inst_compartment_tf_name = commonTools.check_tf_variable(serverinfo[0].strip()) tempback = {'backend_server_tf_name': backend_set_tf_name+"_"+backend_server_tf_name,'serverport':serverport,'backend_server_ip_address':backend_server_ip_address, 'instance_tf_compartment': inst_compartment_tf_name, 'servername': servername } tempStr.update(tempback) @@ -175,9 +199,8 @@ def create_nlb_backendset_backendservers(inputfile, outdir, service_dir, prefix, finalstring = "".join([s for s in finalstring.strip().splitlines(True) if s.strip("\r\n").strip()]) if finalstring != "": - resource = sheetName.lower() + srcdir = outdir + "/" + reg + "/" + service_dir + "/" - commonTools.backup_file(srcdir, resource, lb_auto_tfvars_filename) # Write to TF file outfile = srcdir + lb_auto_tfvars_filename diff --git a/cd3_automation_toolkit/Network/LoadBalancers/create_path_route_set.py b/cd3_automation_toolkit/Network/LoadBalancers/create_path_route_set.py index c4c07733b..f84290270 100644 --- a/cd3_automation_toolkit/Network/LoadBalancers/create_path_route_set.py +++ b/cd3_automation_toolkit/Network/LoadBalancers/create_path_route_set.py @@ -56,6 +56,9 @@ def create_path_route_set(inputfile, outdir, service_dir, prefix, ct): prs_str[reg] = '' rule_str[reg] = '' path_route_set_list[reg] = [] + resource = sheetName.lower() + srcdir = outdir + "/" + reg + "/" + service_dir + "/" + commonTools.backup_file(srcdir, resource, lb_auto_tfvars_filename) # List of the column headers dfcolumns = df.columns.values.tolist() @@ -156,9 +159,7 @@ def create_path_route_set(inputfile, outdir, service_dir, prefix, ct): prs_str[reg] = prs.render(skeleton=True, count=0, region=reg).replace(src,prs_str[reg]+"\n"+src) finalstring = "".join([s for s in prs_str[reg].strip().splitlines(True) if s.strip("\r\n").strip()]) - resource=sheetName.lower() srcdir = outdir + "/" + reg + "/" + service_dir + "/" - commonTools.backup_file(srcdir, resource, lb_auto_tfvars_filename) # Write to TF file outfile = srcdir + lb_auto_tfvars_filename diff --git a/cd3_automation_toolkit/Network/LoadBalancers/create_routing_policy.py b/cd3_automation_toolkit/Network/LoadBalancers/create_routing_policy.py new file mode 100755 index 000000000..09851538f --- /dev/null +++ b/cd3_automation_toolkit/Network/LoadBalancers/create_routing_policy.py @@ -0,0 +1,153 @@ +#!/usr/bin/python3 +# Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. +# +# This script will produce a Terraform file that will be used to set up OCI core components +# Create LB Routing Policy +# +# Author: Ulaganathan N +# Oracle Consulting + + +import pandas as pd +from jinja2 import Environment, FileSystemLoader +from pathlib import Path +from commonTools import * + + + +def create_lb_routing_policy(inputfile, outdir, service_dir, prefix, ct): + # Load the template file + file_loader = FileSystemLoader(f'{Path(__file__).parent}/templates') + env = Environment(loader=file_loader, keep_trailing_newline=True) + lb_routing_policy_template = env.get_template('lb-routing-policy-template') + filename = inputfile + sheetName = "LB-RoutingPolicy" + lb_auto_tfvars_filename = prefix + "_"+sheetName.lower()+".auto.tfvars" + + # Read cd3 using pandas dataframe + df, col_headers = commonTools.read_cd3(filename, sheetName) + + df = df.dropna(how='all') + df = df.reset_index(drop=True) + + # DF with just the load balancer names and the Region details + dffill = df[['Region', 'LBR Name', 'Routing Policy Name']] + dffill = dffill.fillna(method='ffill') + + # Drop unnecessary columns + dfdrop = df[['Region', 'LBR Name', 'Routing Policy Name']] + dfdrop = df.drop(dfdrop, axis=1) + + # dfcert with required details + df = pd.concat([dffill, dfdrop], axis=1) + routing_policies = {} + defined_tags = {} + freeform_tags = {} + + # Take backup of files + for reg in ct.all_regions: + routing_policies[reg] = '' + defined_tags[reg] = '' + freeform_tags[reg] = '' + resource = sheetName.lower() + srcdir = outdir + "/" + reg + "/" + service_dir + "/" + commonTools.backup_file(srcdir, resource, lb_auto_tfvars_filename) + + # List of the column headers + dfcolumns = df.columns.values.tolist() + for i in df.index: + region = str(df.loc[i, 'Region']) + + if region.lower() == 'nan': + continue + + region = region.strip().lower() + + if region in commonTools.endNames: + break + + if region not in ct.all_regions: + print("\nInvalid Region; It should be one of the values mentioned in VCN Info tab...Exiting!!") + exit() + + # temporary dictionaries + tempStr = {} + tempdict = {} + lbr_tf_name = '' + routing_policy_tf_name = '' + + # Check if mandatory field is empty + if pd.isna(df.loc[i, 'Rules']): + print("\nColumn Rules cannot be left empty.....Exiting!") + exit(1) + + # Fetch data; loop through columns + for columnname in dfcolumns: + # Column value + columnvalue = str(df[columnname][i]).strip() + + # Check for boolean/null in column values + columnvalue = commonTools.check_columnvalue(columnvalue) + + # Check for multivalued columns + tempdict = commonTools.check_multivalues_columnvalue(columnvalue, columnname, tempdict) + + # Process Defined and Freeform Tags + if columnname.lower() in commonTools.tagColumns: + tempdict = commonTools.split_tag_values(columnname, columnvalue, tempdict) + + if columnname == "LBR Name": + lbr_tf_name = commonTools.check_tf_variable(columnvalue) + tempdict = {'load_balancer_id': columnvalue, 'lbr_tf_name': lbr_tf_name} + + if columnname == "Routing Policy Name": + routing_policy_tf_name = commonTools.check_tf_variable(columnvalue) + tempdict = {'name': routing_policy_tf_name, 'routing_policy_tf_name': routing_policy_tf_name} + + if columnname == "Rules": + # Split the string into lines and remove any trailing commas + rules = [line.strip() for line in columnvalue.split('\n')] + processed_rules = [] + + for rule in rules: + parts = [part.strip() for part in rule.split('::')] + + if len(parts) >= 2: + name = parts[0] + condition = parts[1] + backend_set_name = parts[2] if len(parts) > 2 else "" + + processed_rules.append({ + 'name': name, + 'condition': condition, + 'backend_set_name': backend_set_name + }) + tempdict = {'rules': processed_rules} + + columnname = commonTools.check_column_headers(columnname) + tempStr[columnname] = str(columnvalue).strip() + tempStr.update(tempdict) + + routing_policy_name = lbr_tf_name + "_" + routing_policy_tf_name + + if routing_policy_name != '': + if routing_policy_name not in routing_policies[region]: + routing_policies[region] = routing_policies[region] + lb_routing_policy_template.render(tempStr) + + + # Take backup of files + for reg in ct.all_regions: + if routing_policies[reg] != '': + # Generate Final String + src = "##Add New Routing Policy for " + reg.lower() + " here##" + routing_policies[reg] = lb_routing_policy_template.render(skeleton=True, count=0, region=reg).replace(src, routing_policies[reg] + "\n" + src) + finalstring = "".join([s for s in routing_policies[reg].strip().splitlines(True) if s.strip("\r\n").strip()]) + + srcdir = outdir + "/" + reg + "/" + service_dir + "/" + + # Write to TF file + outfile = srcdir + lb_auto_tfvars_filename + oname = open(outfile, "w+") + print("Writing to " + outfile) + oname.write(finalstring) + oname.close() diff --git a/cd3_automation_toolkit/Network/LoadBalancers/create_ruleset.py b/cd3_automation_toolkit/Network/LoadBalancers/create_ruleset.py index 98069a765..55133f6f3 100644 --- a/cd3_automation_toolkit/Network/LoadBalancers/create_ruleset.py +++ b/cd3_automation_toolkit/Network/LoadBalancers/create_ruleset.py @@ -65,6 +65,9 @@ def create_ruleset(inputfile, outdir, service_dir, prefix, ct): # Take backup of files for reg in ct.all_regions: rs_str[reg] = '' + resource = sheetName.lower() + srcdir = outdir + "/" + reg + "/" + service_dir + "/" + commonTools.backup_file(srcdir, resource, lb_auto_tfvars_filename) # List of the column headers dfcolumns = df.columns.values.tolist() @@ -307,9 +310,7 @@ def add_rules(df,rs_str,tempStr,control_access): rs_str[reg] = rs.render(skeleton=True, count=0, region=reg).replace(src,rs_str[reg]+"\n"+src) finalstring = "".join([s for s in rs_str[reg].strip().splitlines(True) if s.strip("\r\n").strip()]) - resource=sheetName.lower() srcdir = outdir + "/" + reg + "/" + service_dir + "/" - commonTools.backup_file(srcdir, resource, lb_auto_tfvars_filename) outfile = srcdir + lb_auto_tfvars_filename diff --git a/cd3_automation_toolkit/Network/LoadBalancers/create_terraform_lbr_hostname_certs.py b/cd3_automation_toolkit/Network/LoadBalancers/create_terraform_lbr_hostname_certs.py index c783eb3d3..e320c3765 100644 --- a/cd3_automation_toolkit/Network/LoadBalancers/create_terraform_lbr_hostname_certs.py +++ b/cd3_automation_toolkit/Network/LoadBalancers/create_terraform_lbr_hostname_certs.py @@ -74,6 +74,9 @@ def create_terraform_lbr_hostname_certs(inputfile, outdir, service_dir, prefix, certificate_str[reg] = '' cipher_suites[reg] = '' hostname_str_02[reg] = '' + resource = sheetName.lower() + srcdir = outdir + "/" + reg + "/" + service_dir + "/" + commonTools.backup_file(srcdir, resource, lb_auto_tfvars_filename) def certificate_templates(dfcert): @@ -181,7 +184,7 @@ def certificate_templates(dfcert): # List of the column headers dfcolumns = df.columns.values.tolist() - subnets = parseSubnets(filename) + #subnets = parseSubnets(filename) for i in df.index: region = str(df.loc[i, 'Region']) @@ -254,35 +257,52 @@ def certificate_templates(dfcert): lbr_subnets_list = [] network_compartment_id = '' vcn_name = '' - if columnname == 'LBR Subnets': + if columnname == 'Network Details': lbr_subnets = str(columnvalue).strip().split(",") if len(lbr_subnets) == 1: - if ("ocid1.subnet.oc1" in str(lbr_subnets[0]).strip()): - lbr_subnets_list.append(str(lbr_subnets[0]).strip()) - else: - try: - key = region, str(lbr_subnets[0]).strip() - network_compartment_id = subnets.vcn_subnet_map[key][0] - vcn_name = subnets.vcn_subnet_map[key][1] - lbr_subnets_list.append(subnets.vcn_subnet_map[key][2]) - except Exception as e: - print("Invalid Subnet Name specified for row " + str(i + 3) + ". It Doesnt exist in Subnets sheet. Exiting!!!") + columnvalue=str(lbr_subnets[0]).strip() + if ("ocid1.subnet.oc" in columnvalue): + network_compartment_id = "root" + vcn_name = "" + subnet_id = columnvalue + elif columnvalue.lower() != 'nan' and columnvalue.lower() != '': + if len(columnvalue.split("@")) == 2: + network_compartment_id = commonTools.check_tf_variable(columnvalue.split("@")[0].strip()) + vcn_subnet_name = columnvalue.split("@")[1].strip() + else: + network_compartment_id = commonTools.check_tf_variable(str(df.loc[i, 'Compartment Name']).strip()) + vcn_subnet_name = columnvalue + if ("::" not in vcn_subnet_name): + print("Invalid Network Details format specified for row " + str(i + 3) + ". Exiting!!!") exit(1) - tempdict = {'network_compartment_tf_name': commonTools.check_tf_variable(network_compartment_id), 'vcn_name': vcn_name,'lbr_subnets': json.dumps(lbr_subnets_list)} + else: + vcn_name = vcn_subnet_name.split("::")[0].strip() + subnet_id = vcn_subnet_name.split("::")[1].strip() + + lbr_subnets_list.append(subnet_id) + tempdict = {'network_compartment_tf_name': network_compartment_id, 'vcn_name': vcn_name,'lbr_subnets': json.dumps(lbr_subnets_list)} elif len(lbr_subnets) == 2: for subnet in lbr_subnets: - if "ocid1.subnet.oc1" in subnet: - lbr_subnets_list.append(str(subnet).strip()) - else: - try: - key = region, str(subnet).strip() - network_compartment_id = subnets.vcn_subnet_map[key][0] - vcn_name = subnets.vcn_subnet_map[key][1] - lbr_subnets_list.append(subnets.vcn_subnet_map[key][2]) - except Exception as e: - print("Invalid Subnet Name specified for row " + str(i + 3) + ". It Doesnt exist in Subnets sheet. Exiting!!!") + columnvalue=subnet + if ("ocid1.subnet.oc" in columnvalue): + network_compartment_id = "root" + vcn_name = "" + subnet_id = columnvalue + elif columnvalue.lower() != 'nan' and columnvalue.lower() != '': + if len(columnvalue.split("@")) == 2: + network_compartment_id = commonTools.check_tf_variable(columnvalue.split("@")[0].strip()) + vcn_subnet_name = columnvalue.split("@")[1].strip() + else: + network_compartment_id = commonTools.check_tf_variable(str(df.loc[i, 'Compartment Name']).strip()) + vcn_subnet_name = columnvalue + if ("::" not in vcn_subnet_name): + print("Invalid Network Details format specified for row " + str(i + 3) + ". Exiting!!!") exit(1) - tempdict = {'network_compartment_tf_name': commonTools.check_tf_variable(network_compartment_id), 'vcn_name': vcn_name,'lbr_subnets': json.dumps(lbr_subnets_list) } + else: + vcn_name = vcn_subnet_name.split("::")[0].strip() + subnet_id = vcn_subnet_name.split("::")[1].strip() + lbr_subnets_list.append(subnet_id) + tempdict = {'network_compartment_tf_name': network_compartment_id, 'vcn_name': vcn_name,'lbr_subnets': json.dumps(lbr_subnets_list)} if columnname == "NSGs": if columnvalue != '': @@ -386,9 +406,7 @@ def certificate_templates(dfcert): finalstring = "".join([s for s in finalstring.strip().splitlines(True) if s.strip("\r\n").strip()]) if finalstring != "": - resource = sheetName.lower() srcdir = outdir + "/" + reg + "/" + service_dir + "/" - commonTools.backup_file(srcdir, resource, lb_auto_tfvars_filename) # Write to TF file outfile = srcdir + lb_auto_tfvars_filename diff --git a/cd3_automation_toolkit/Network/LoadBalancers/create_terraform_nlb_listener.py b/cd3_automation_toolkit/Network/LoadBalancers/create_terraform_nlb_listener.py index d03faf8c6..d6d5406ff 100644 --- a/cd3_automation_toolkit/Network/LoadBalancers/create_terraform_nlb_listener.py +++ b/cd3_automation_toolkit/Network/LoadBalancers/create_terraform_nlb_listener.py @@ -48,10 +48,13 @@ def create_terraform_nlb_listener(inputfile, outdir, service_dir, prefix, ct): reserved_ips_str[reg] = '' nlb_listener_str[reg] = '' nlb_names[reg] = [] + resource = sheetName.lower() + srcdir = outdir + "/" + reg + "/" + service_dir + "/" + commonTools.backup_file(srcdir, resource, nlb_auto_tfvars_filename) # List of the column headers dfcolumns = df.columns.values.tolist() - subnets = parseSubnets(filename) + #subnets = parseSubnets(filename) prevreg = '' for i in df.index: @@ -76,18 +79,18 @@ def create_terraform_nlb_listener(inputfile, outdir, service_dir, prefix, ct): empty_nlb = 1 #NLB having multiple Listeners can't have null values for listener properties - elif (str(df.loc[i, 'Region']).lower() == 'nan') and (str(df.loc[i, 'Compartment Name']).lower() == 'nan') and (str(df.loc[i, 'NLB Name']).lower() == 'nan') and (str(df.loc[i, 'Subnet Name']).lower() == 'nan'): + elif (str(df.loc[i, 'Region']).lower() == 'nan') and (str(df.loc[i, 'Compartment Name']).lower() == 'nan') and (str(df.loc[i, 'NLB Name']).lower() == 'nan') and (str(df.loc[i, 'Network Details']).lower() == 'nan'): if (str(df.loc[i, 'Listener Name']).lower() == 'nan') or (str(df.loc[i, 'Listener Protocol(UDP|TCP|UDP/TCP|Any)']).lower() == 'nan') or (str(df.loc[i, 'Listener Port']).lower() == 'nan') or (str(df.loc[i, 'Backend Set Name']).lower() == 'nan'): print("\nColumns Backend Set Name, Listener Name, Listener Protocol and Listener Port cannot be left empty.....Exiting! Check Row No "+(str(i+3))) exit(1) - elif (str(df.loc[i, 'Region']).lower() != 'nan') and (str(df.loc[i, 'Compartment Name']).lower() != 'nan') and (str(df.loc[i, 'NLB Name']).lower() != 'nan') and (str(df.loc[i, 'Subnet Name']).lower() != 'nan'): + elif (str(df.loc[i, 'Region']).lower() != 'nan') and (str(df.loc[i, 'Compartment Name']).lower() != 'nan') and (str(df.loc[i, 'NLB Name']).lower() != 'nan') and (str(df.loc[i, 'Network Details']).lower() != 'nan'): if (str(df.loc[i, 'Listener Name']).lower() == 'nan') or (str(df.loc[i, 'Listener Protocol(UDP|TCP|UDP/TCP|Any)']).lower() == 'nan') or (str(df.loc[i, 'Listener Port']).lower() == 'nan') or (str(df.loc[i, 'Backend Set Name']).lower() == 'nan'): print("\nColumns Backend Set Name, Listener Name, Listener Protocol and Listener Port cannot be left empty.....Exiting! Check Row No " + (str(i + 3))) exit(1) elif (str(df.loc[i, 'Listener Name']).lower() != 'nan') and (str(df.loc[i, 'Listener Protocol(UDP|TCP|UDP/TCP|Any)']).lower() != 'nan') and (str(df.loc[i, 'Listener Port']).lower() != 'nan') and (str(df.loc[i, 'Backend Set Name']).lower() != 'nan'): - if (str(df.loc[i, 'Region']).lower() == 'nan') or (str(df.loc[i, 'Compartment Name']).lower() == 'nan') or (str(df.loc[i, 'NLB Name']).lower() == 'nan') or (str(df.loc[i, 'Subnet Name']).lower() == 'nan'): - print("\nColumns Region, Compartment Name, NLB Name and Subnet Name cannot be left empty.....Exiting! Check Row No "+(str(i+3))) + if (str(df.loc[i, 'Region']).lower() == 'nan') or (str(df.loc[i, 'Compartment Name']).lower() == 'nan') or (str(df.loc[i, 'NLB Name']).lower() == 'nan') or (str(df.loc[i, 'Network Details']).lower() == 'nan'): + print("\nColumns Region, Compartment Name, NLB Name and Network Details cannot be left empty.....Exiting! Check Row No "+(str(i+3))) exit(1) # temporary dictionaries @@ -130,26 +133,31 @@ def create_terraform_nlb_listener(inputfile, outdir, service_dir, prefix, ct): nlb_tf_name = commonTools.check_tf_variable(columnvalue) tempdict = {'nlb_tf_name': nlb_tf_name, 'nlb_name': nlb_name} + subnet_id = '' network_compartment_id = '' vcn_name = '' - if columnname == 'Subnet Name': - subnet_tf_name = str(columnvalue).strip() - if subnet_tf_name == 'nan' or subnet_tf_name == '': - continue - if ("ocid1.subnet.oc1" in subnet_tf_name): - network_compartment_id = "" + if columnname == 'Network Details': + columnvalue = columnvalue.strip() + if ("ocid1.subnet.oc" in columnvalue): + network_compartment_id = "root" vcn_name = "" - subnet_id = subnet_tf_name - else: - try: - key = region, subnet_tf_name - network_compartment_id = subnets.vcn_subnet_map[key][0] - vcn_name = subnets.vcn_subnet_map[key][1] - subnet_id = subnets.vcn_subnet_map[key][2] - except Exception as e: - print("Invalid Subnet Name specified for row " + str(i + 3) + ". It Doesnt exist in Subnets sheet. Exiting!!!") + subnet_id = columnvalue + elif columnvalue.lower() != 'nan' and columnvalue.lower() != '': + if len(columnvalue.split("@")) == 2: + network_compartment_id = commonTools.check_tf_variable(columnvalue.split("@")[0].strip()) + vcn_subnet_name = columnvalue.split("@")[1].strip() + else: + network_compartment_id = commonTools.check_tf_variable( + str(df.loc[i, 'Compartment Name']).strip()) + vcn_subnet_name = columnvalue + if ("::" not in vcn_subnet_name): + print("Invalid Network Details format specified for row " + str(i + 3) + ". Exiting!!!") exit(1) - tempdict = {'network_compartment_tf_name': commonTools.check_tf_variable(network_compartment_id), 'vcn_name': vcn_name,'subnet_id': subnet_id} + else: + vcn_name = vcn_subnet_name.split("::")[0].strip() + subnet_id = vcn_subnet_name.split("::")[1].strip() + tempdict = {'network_compartment_tf_name': network_compartment_id, 'vcn_name': vcn_name, + 'subnet_id': subnet_id} if columnname == "NSGs": if columnvalue != '' and columnvalue != 'nan': @@ -221,9 +229,7 @@ def create_terraform_nlb_listener(inputfile, outdir, service_dir, prefix, ct): finalstring = "".join([s for s in finalstring.strip().splitlines(True) if s.strip("\r\n").strip()]) if finalstring != "": - resource = sheetName.lower() srcdir = outdir + "/" + reg + "/" + service_dir + "/" - commonTools.backup_file(srcdir, resource, nlb_auto_tfvars_filename) # Write to TF file outfile = srcdir + nlb_auto_tfvars_filename diff --git a/cd3_automation_toolkit/Network/LoadBalancers/export_lbr_nonGreenField.py b/cd3_automation_toolkit/Network/LoadBalancers/export_lbr_nonGreenField.py index dfd120722..4466568a7 100644 --- a/cd3_automation_toolkit/Network/LoadBalancers/export_lbr_nonGreenField.py +++ b/cd3_automation_toolkit/Network/LoadBalancers/export_lbr_nonGreenField.py @@ -10,21 +10,25 @@ import sys import oci import os +import subprocess as sp from oci.certificates import CertificatesClient from oci.core.virtual_network_client import VirtualNetworkClient from oci.load_balancer.load_balancer_client import LoadBalancerClient -sys.path.append(os.getcwd()+"/..") + +sys.path.append(os.getcwd() + "/..") from commonTools import * importCommands = {} oci_obj_names = {} + def cookie_headers(values_for_column, session_persistence, excel_header_map): for headers in values_for_column: if headers == 'Cookie Name': if (session_persistence.__getattribute__(commonTools.check_column_headers(headers))): - values_for_column[headers].append(str(session_persistence.__getattribute__(commonTools.check_column_headers(headers)))) + values_for_column[headers].append( + str(session_persistence.__getattribute__(commonTools.check_column_headers(headers)))) else: values_for_column[headers].append("") @@ -47,6 +51,7 @@ def cookie_headers(values_for_column, session_persistence, excel_header_map): values_for_column[headers].append("") return values_for_column + def common_headers(region, headers, values_for_column, eachlbr, excel_header_map, lbr_compartment_name): if headers == 'Region': values_for_column[headers].append(str(region)) @@ -63,82 +68,84 @@ def common_headers(region, headers, values_for_column, eachlbr, excel_header_map pass return values_for_column -def print_certs(obj, reg, outdir,service_dir): +def print_certs(obj, reg, outdir, service_dir): cname = "" pname = "" ca_certificate = obj.ca_certificate public_certificate = obj.public_certificate - #print(obj.certificate_name, outdir, reg) + # print(obj.certificate_name, outdir, reg) if str(ca_certificate).lower() != "none": - cname = outdir + "/" + str(reg).lower() + "/"+ service_dir +"/" + str(obj.certificate_name) + "-ca-certificate.cert" + cname = outdir + "/" + str(reg).lower() + "/" + service_dir + "/" + str( + obj.certificate_name) + "-ca-certificate.cert" ca_cert = open(cname, "w") ca_cert.write(ca_certificate) ca_cert.close() if str(public_certificate).lower() != "none": - pname = outdir + "/" + str(reg).lower() + "/"+ service_dir +"/" + str(obj.certificate_name) + "-public_certificate.cert" + pname = outdir + "/" + str(reg).lower() + "/" + service_dir + "/" + str( + obj.certificate_name) + "-public_certificate.cert" public_cert = open(pname, "w") public_cert.write(public_certificate) public_cert.close() cert_name = obj.certificate_name - ca_cert = str(cname)#.replace("\\", "\\\\") - public_cert = str(pname)#.replace("\\", "\\\\") + ca_cert = str(cname) # .replace("\\", "\\\\") + public_cert = str(pname) # .replace("\\", "\\\\") return cert_name, ca_cert, public_cert -def insert_values(values_for_column, oci_objs, sheet_dict, region,comp_name, display_name, minimum_bandwidth_in_mbps, maximum_bandwidth_in_mbps, subnets, nsgs, reserved_ip, hostnames, cert_name, ca_cert, +def insert_values(values_for_column, oci_objs, sheet_dict, region, comp_name, display_name, minimum_bandwidth_in_mbps, + maximum_bandwidth_in_mbps, subnets, nsgs, reserved_ip, hostnames, cert_name, ca_cert, passphrase, privatekey, public_cert, cipher_name, cipher_suites): - for col_header in values_for_column.keys(): - if col_header == 'Region': - values_for_column[col_header].append(str(region)) - elif col_header == 'Compartment Name': - values_for_column[col_header].append(comp_name) - elif col_header == 'LBR Name': - values_for_column[col_header].append(display_name) - elif col_header == "LBR Subnets": - values_for_column[col_header].append(subnets) - elif (col_header == "NSGs"): - values_for_column[col_header].append(nsgs) - elif (col_header == "Reserved IP (Y|N|OCID)"): - values_for_column[col_header].append(reserved_ip) - elif (col_header == 'LBR Hostname(Name:Hostname)'): - values_for_column[col_header].append(hostnames) - elif col_header == 'Certificate Name': - values_for_column[col_header].append(cert_name) - elif col_header == 'CA Cert': - values_for_column[col_header].append(ca_cert) - elif col_header == 'Passphrase': - values_for_column[col_header].append(passphrase) - elif col_header == 'Private Key': - values_for_column[col_header].append(privatekey) - elif col_header == 'Public Cert': - values_for_column[col_header].append(public_cert) - elif col_header == 'Cipher Suite Name': - values_for_column[col_header].append(cipher_name) - elif col_header == 'Ciphers': - values_for_column[col_header].append(cipher_suites) - elif col_header == 'Minimum Bandwidth In Mbps (Flexible shapes only)': - values_for_column[col_header].append(minimum_bandwidth_in_mbps) - elif col_header == 'Maximum Bandwidth In Mbps (Flexible shapes only)': - values_for_column[col_header].append(maximum_bandwidth_in_mbps) - elif col_header.lower() in commonTools.tagColumns: - values_for_column = commonTools.export_tags(oci_objs[0], col_header, values_for_column) - else: - values_for_column = commonTools.export_extra_columns(oci_objs, col_header, sheet_dict, values_for_column) - + if col_header == 'Region': + values_for_column[col_header].append(str(region)) + elif col_header == 'Compartment Name': + values_for_column[col_header].append(comp_name) + elif col_header == 'LBR Name': + values_for_column[col_header].append(display_name) + elif col_header == "Network Details": + values_for_column[col_header].append(subnets) + elif (col_header == "NSGs"): + values_for_column[col_header].append(nsgs) + elif (col_header == "Reserved IP (Y|N|OCID)"): + values_for_column[col_header].append(reserved_ip) + elif (col_header == 'LBR Hostname(Name:Hostname)'): + values_for_column[col_header].append(hostnames) + elif col_header == 'Certificate Name': + values_for_column[col_header].append(cert_name) + elif col_header == 'CA Cert': + values_for_column[col_header].append(ca_cert) + elif col_header == 'Passphrase': + values_for_column[col_header].append(passphrase) + elif col_header == 'Private Key': + values_for_column[col_header].append(privatekey) + elif col_header == 'Public Cert': + values_for_column[col_header].append(public_cert) + elif col_header == 'Cipher Suite Name': + values_for_column[col_header].append(cipher_name) + elif col_header == 'Ciphers': + values_for_column[col_header].append(cipher_suites) + elif col_header == 'Minimum Bandwidth In Mbps (Flexible shapes only)': + values_for_column[col_header].append(minimum_bandwidth_in_mbps) + elif col_header == 'Maximum Bandwidth In Mbps (Flexible shapes only)': + values_for_column[col_header].append(maximum_bandwidth_in_mbps) + elif col_header.lower() in commonTools.tagColumns: + values_for_column = commonTools.export_tags(oci_objs[0], col_header, values_for_column) + else: + values_for_column = commonTools.export_extra_columns(oci_objs, col_header, sheet_dict, values_for_column) -def print_lbr_hostname_certs(region, ct, outdir, values_for_column_lhc, lbr, LBRs, lbr_compartment_name, network,service_dir): +def print_lbr_hostname_certs(region, ct, outdir, values_for_column_lhc, lbr, LBRs, lbr_compartment_name, network, + service_dir): for eachlbr in LBRs.data: - #Fetch LBR Name + # Fetch LBR Name display_name = eachlbr.display_name # Filter out the LBs provisioned by oke @@ -158,30 +165,30 @@ def print_lbr_hostname_certs(region, ct, outdir, values_for_column_lhc, lbr, LBR else: reserved_ip = ips.reserved_ip.id - #Fetch Network Compartment Name - #Fetch Compartment Name + # Fetch Network Compartment Name + # Fetch Compartment Name lbr_comp_id = eachlbr.compartment_id comp_done_ids = [] - for comp_name,comp_id in ct.ntk_compartment_ids.items(): + for comp_name, comp_id in ct.ntk_compartment_ids.items(): if lbr_comp_id == comp_id and lbr_comp_id not in comp_done_ids: lbr_compartment_name = comp_name comp_done_ids.append(lbr_comp_id) - #Fetch hostname + # Fetch hostname hostname_name_list = '' - if(eachlbr.hostnames): + if (eachlbr.hostnames): for hostname in eachlbr.hostnames: hostname_info = lbr.get_hostname(eachlbr.id, hostname).data value = hostname_info.name + ":" + hostname_info.hostname - hostname_name_list = hostname_name_list +','+value + hostname_name_list = hostname_name_list + ',' + value if (hostname_name_list != "" and hostname_name_list[0] == ','): hostname_name_list = hostname_name_list.lstrip(',') - #Fetch NSGs + # Fetch NSGs nsg_detail = "" - #if eachlbr.network_security_group_ids: + # if eachlbr.network_security_group_ids: for nsg_id in eachlbr.network_security_group_ids: - #for nsgs in NSGs.data: + # for nsgs in NSGs.data: # id = nsgs.id # if nsg_ids == id: # nsg_name = nsgs.display_name + "," + nsg_name @@ -193,7 +200,7 @@ def print_lbr_hostname_certs(region, ct, outdir, values_for_column_lhc, lbr, LBR nsg_name = nsg_detail - #Fetch Subnets + # Fetch Subnets subnet_name_list = "" if eachlbr.subnet_ids: for subnet_id in eachlbr.subnet_ids: @@ -202,7 +209,14 @@ def print_lbr_hostname_certs(region, ct, outdir, values_for_column_lhc, lbr, LBR vcn_id = subnet_info.data.vcn_id vcn_info = network.get_vcn(vcn_id=vcn_id) vcn_name = vcn_info.data.display_name - vs = vcn_name + "_" + subnet_name + + ntk_compartment_id = network.get_vcn(subnet_info.data.vcn_id).data.compartment_id # compartment-id + network_compartment_name = lbr_compartment_name + for comp_name, comp_id in ct.ntk_compartment_ids.items(): + if comp_id == ntk_compartment_id: + network_compartment_name = comp_name + + vs = network_compartment_name + "@" + vcn_name + "::" + subnet_name subnet_name_list = subnet_name_list + ',' + vs if (subnet_name_list != "" and subnet_name_list[0] == ','): subnet_name_list = subnet_name_list.lstrip(',') @@ -215,19 +229,21 @@ def print_lbr_hostname_certs(region, ct, outdir, values_for_column_lhc, lbr, LBR maximum_bandwidth_in_mbps = eachlbr.shape_details.maximum_bandwidth_in_mbps minimum_bandwidth_in_mbps = eachlbr.shape_details.minimum_bandwidth_in_mbps - #Loops for fetching Certificates and Cipher Suites + # Loops for fetching Certificates and Cipher Suites ciphers = eachlbr.ssl_cipher_suites certs = eachlbr.certificates cert_ct = 0 cipher_ct = 0 no_of_certs = '' no_of_ciphers = '' - cipher_list =[] + cipher_list = [] certificate_list = [] if (not certs and not ciphers): oci_objs = [eachlbr] - insert_values(values_for_column_lhc, oci_objs, sheet_dict_lhc, region, lbr_compartment_name,display_name, minimum_bandwidth_in_mbps, maximum_bandwidth_in_mbps, subnet_name_list, nsg_name, reserved_ip, hostname_name_list, '', '', '', '', '','','') + insert_values(values_for_column_lhc, oci_objs, sheet_dict_lhc, region, lbr_compartment_name, display_name, + minimum_bandwidth_in_mbps, maximum_bandwidth_in_mbps, subnet_name_list, nsg_name, reserved_ip, + hostname_name_list, '', '', '', '', '', '', '') elif (not certs and ciphers): oci_objs = [eachlbr, ciphers] @@ -245,28 +261,36 @@ def print_lbr_hostname_certs(region, ct, outdir, values_for_column_lhc, lbr, LBR cipher_ct = cipher_ct + 1 if (cipher_ct == 1): - insert_values(values_for_column_lhc, oci_objs, sheet_dict_lhc, region, lbr_compartment_name, display_name, minimum_bandwidth_in_mbps, maximum_bandwidth_in_mbps, subnet_name_list, nsg_name, reserved_ip, hostname_name_list, '','','','','',cipher_name,cipher_suites) + insert_values(values_for_column_lhc, oci_objs, sheet_dict_lhc, region, lbr_compartment_name, + display_name, minimum_bandwidth_in_mbps, maximum_bandwidth_in_mbps, subnet_name_list, + nsg_name, reserved_ip, hostname_name_list, '', '', '', '', '', cipher_name, + cipher_suites) else: - insert_values(values_for_column_lhc, oci_objs, sheet_dict_lhc,'','','','','','','','','','','','','','', cipher_name,cipher_suites) + insert_values(values_for_column_lhc, oci_objs, sheet_dict_lhc, '', '', '', '', '', '', '', '', '', + '', '', '', '', '', cipher_name, cipher_suites) elif (certs and not ciphers): oci_objs = [eachlbr, certs] for certificates, details in certs.items(): # Get cert info - cert_name,ca_cert,public_cert = print_certs(details,region,outdir,service_dir) + cert_name, ca_cert, public_cert = print_certs(details, region, outdir, service_dir) cert_ct = cert_ct + 1 if (cert_ct == 1): - insert_values(values_for_column_lhc, oci_objs, sheet_dict_lhc, region, lbr_compartment_name,display_name, minimum_bandwidth_in_mbps, maximum_bandwidth_in_mbps, subnet_name_list, nsg_name, reserved_ip, hostname_name_list, cert_name,ca_cert,'','',public_cert, '','') + insert_values(values_for_column_lhc, oci_objs, sheet_dict_lhc, region, lbr_compartment_name, + display_name, minimum_bandwidth_in_mbps, maximum_bandwidth_in_mbps, subnet_name_list, + nsg_name, reserved_ip, hostname_name_list, cert_name, ca_cert, '', '', public_cert, + '', '') else: - insert_values(values_for_column_lhc, oci_objs, sheet_dict_lhc,'','','','','','','','','', cert_name,ca_cert,'','',public_cert, '','') + insert_values(values_for_column_lhc, oci_objs, sheet_dict_lhc, '', '', '', '', '', '', '', '', '', + cert_name, ca_cert, '', '', public_cert, '', '') elif (certs and ciphers): oci_objs = [eachlbr, certs, ciphers] - #Check the number of certs and ciphers; consider largest count for loop - for certificates,cert_details in certs.items(): + # Check the number of certs and ciphers; consider largest count for loop + for certificates, cert_details in certs.items(): certificate_list.append(certificates) no_of_certs = len(certificate_list) @@ -291,19 +315,24 @@ def print_lbr_hostname_certs(region, ct, outdir, values_for_column_lhc, lbr, LBR j = 0 for cert, cert_details in certs.items(): if i == j: - #Insert values of certs and cipher till they are equal - cert_name, ca_cert, public_cert = print_certs(cert_details, region, outdir,service_dir) + # Insert values of certs and cipher till they are equal + cert_name, ca_cert, public_cert = print_certs(cert_details, region, outdir, service_dir) if i != 0: - insert_values(values_for_column_lhc, oci_objs, sheet_dict_lhc, '','','', - '', '', '', '','', + insert_values(values_for_column_lhc, oci_objs, sheet_dict_lhc, '', '', '', + '', '', '', '', '', '', cert_name, ca_cert, '', '', public_cert, cipher_name, cipher_suites) else: - insert_values(values_for_column_lhc, oci_objs, sheet_dict_lhc, region, lbr_compartment_name, display_name, minimum_bandwidth_in_mbps, maximum_bandwidth_in_mbps, subnet_name_list, nsg_name, reserved_ip, hostname_name_list, cert_name, ca_cert, '', '', public_cert, cipher_name, cipher_suites) + insert_values(values_for_column_lhc, oci_objs, sheet_dict_lhc, region, + lbr_compartment_name, display_name, minimum_bandwidth_in_mbps, + maximum_bandwidth_in_mbps, subnet_name_list, nsg_name, reserved_ip, + hostname_name_list, cert_name, ca_cert, '', '', public_cert, + cipher_name, cipher_suites) elif i >= no_of_certs and j == no_of_certs - 1: - #Insert additional values of cipher; as count of cipher is more - insert_values(values_for_column_lhc, oci_objs, sheet_dict_lhc, '','','','','','','','','','', '','', '', '', cipher_name, cipher_suites) + # Insert additional values of cipher; as count of cipher is more + insert_values(values_for_column_lhc, oci_objs, sheet_dict_lhc, '', '', '', '', '', '', + '', '', '', '', '', '', '', '', cipher_name, cipher_suites) else: pass j = j + 1 @@ -317,7 +346,7 @@ def print_lbr_hostname_certs(region, ct, outdir, values_for_column_lhc, lbr, LBR else: for cert, cert_details in certs.items(): # Fetch Cert values - cert_name, ca_cert, public_cert = print_certs(cert_details, region, outdir,service_dir) + cert_name, ca_cert, public_cert = print_certs(cert_details, region, outdir, service_dir) j = 0 for cipher, cipher_details in ciphers.items(): cipher_suites = '' @@ -329,15 +358,20 @@ def print_lbr_hostname_certs(region, ct, outdir, values_for_column_lhc, lbr, LBR cipher_suites = cipher_suites.lstrip(',') cipher_name = cipher_details.name if i != 0: - insert_values(values_for_column_lhc, oci_objs, sheet_dict_lhc,'','','','', + insert_values(values_for_column_lhc, oci_objs, sheet_dict_lhc, '', '', '', '', '', '', '', '', '', cert_name, ca_cert, '', '', public_cert, cipher_name, cipher_suites) else: - insert_values(values_for_column_lhc, oci_objs, sheet_dict_lhc, region, lbr_compartment_name, display_name, minimum_bandwidth_in_mbps, maximum_bandwidth_in_mbps, subnet_name_list, nsg_name, reserved_ip, hostname_name_list, cert_name, ca_cert, '', '', public_cert, cipher_name, cipher_suites) + insert_values(values_for_column_lhc, oci_objs, sheet_dict_lhc, region, + lbr_compartment_name, display_name, minimum_bandwidth_in_mbps, + maximum_bandwidth_in_mbps, subnet_name_list, nsg_name, reserved_ip, + hostname_name_list, cert_name, ca_cert, '', '', public_cert, + cipher_name, cipher_suites) elif i >= no_of_ciphers and j == no_of_ciphers - 1: - #Insert additional values of certs; as count of certs is more - insert_values(values_for_column_lhc, oci_objs, sheet_dict_lhc, '','','','','','','','','',cert_name, ca_cert, '', '', public_cert, '', '') + # Insert additional values of certs; as count of certs is more + insert_values(values_for_column_lhc, oci_objs, sheet_dict_lhc, '', '', '', '', '', '', + '', '', '', cert_name, ca_cert, '', '', public_cert, '', '') else: pass j = j + 1 @@ -345,7 +379,7 @@ def print_lbr_hostname_certs(region, ct, outdir, values_for_column_lhc, lbr, LBR # if both are equal, loop through one of them as main; other as secondary elif no_of_certs == no_of_ciphers: - i=0 + i = 0 if i == no_of_ciphers: break else: @@ -360,20 +394,25 @@ def print_lbr_hostname_certs(region, ct, outdir, values_for_column_lhc, lbr, LBR j = 0 for cert, cert_details in certs.items(): if i == j: - cert_name, ca_cert, public_cert = print_certs(cert_details, region, outdir,service_dir) + cert_name, ca_cert, public_cert = print_certs(cert_details, region, outdir, service_dir) if i != 0: - insert_values(values_for_column_lhc, oci_objs, sheet_dict_lhc, '','','','', + insert_values(values_for_column_lhc, oci_objs, sheet_dict_lhc, '', '', '', '', '', '', '', '', '', cert_name, ca_cert, '', '', public_cert, cipher_name, cipher_suites) else: - insert_values(values_for_column_lhc, oci_objs, sheet_dict_lhc, region, lbr_compartment_name, display_name, minimum_bandwidth_in_mbps, maximum_bandwidth_in_mbps, subnet_name_list, nsg_name, reserved_ip, hostname_name_list, cert_name, ca_cert, '','', public_cert, cipher_name, cipher_suites) + insert_values(values_for_column_lhc, oci_objs, sheet_dict_lhc, region, + lbr_compartment_name, display_name, minimum_bandwidth_in_mbps, + maximum_bandwidth_in_mbps, subnet_name_list, nsg_name, reserved_ip, + hostname_name_list, cert_name, ca_cert, '', '', public_cert, + cipher_name, cipher_suites) j = j + 1 i = i + 1 return values_for_column_lhc + def print_backendset_backendserver(region, ct, values_for_column_bss, lbr, LBRs, lbr_compartment_name): - certs = CertificatesClient(config=config,retry_strategy=oci.retry.DEFAULT_RETRY_STRATEGY,signer=signer) + certs = CertificatesClient(config=config, retry_strategy=oci.retry.DEFAULT_RETRY_STRATEGY, signer=signer) for eachlbr in LBRs.data: @@ -387,10 +426,10 @@ def print_backendset_backendserver(region, ct, values_for_column_bss, lbr, LBRs, # Loop through Backend Sets - #Fetch Compartment Name + # Fetch Compartment Name lbr_comp_id = eachlbr.compartment_id comp_done_ids = [] - for comp_name,comp_id in ct.ntk_compartment_ids.items(): + for comp_name, comp_id in ct.ntk_compartment_ids.items(): if lbr_comp_id == comp_id and lbr_comp_id not in comp_done_ids: lbr_compartment_name = comp_name comp_done_ids.append(lbr_comp_id) @@ -401,34 +440,35 @@ def print_backendset_backendserver(region, ct, values_for_column_bss, lbr, LBRs, backendset_details = lbr.get_backend_set(eachlbr.__getattribute__('id'), backendsets).data certificate_list = '' hc = '' - # Process the Backend Server and Backup server details for backends in backendset_details.__getattribute__('backends'): if str(backends.__getattribute__('name')).lower() != "none": backend_value = str(backends.__getattribute__('name')) - backend_list= backend_list+","+"&"+backend_value + backend_list = backend_list + "," + backend_value if (backend_list != "" and backend_list[0] == ','): backend_list = backend_list.lstrip(',') if str(backends.__getattribute__('backup')).lower() == 'true': backup_value = backends.ip_address - backup_list = backup_list +',' +backup_value + backup_list = backup_list + ',' + backup_value if (backup_list != "" and backup_list[0] == ','): backup_list = backup_list.lstrip(',') - # Process columns related to Session Cookies - lb_cookie_session_persistence_configuration = backendset_details.__getattribute__('lb_cookie_session_persistence_configuration') + lb_cookie_session_persistence_configuration = backendset_details.__getattribute__( + 'lb_cookie_session_persistence_configuration') session_persistence_configuration = backendset_details.__getattribute__('session_persistence_configuration') if str(lb_cookie_session_persistence_configuration).lower() != 'none': lb_session = 'LB' values_for_column_bss['Cookie Session(n|LB|Backend Server)'].append(lb_session) - values_for_column_bss = cookie_headers(values_for_column_bss, lb_cookie_session_persistence_configuration, sheet_dict_bss) + values_for_column_bss = cookie_headers(values_for_column_bss, + lb_cookie_session_persistence_configuration, sheet_dict_bss) elif str(session_persistence_configuration).lower() != 'none': lb_session = 'Backend Server' values_for_column_bss['Cookie Session(n|LB|Backend Server)'].append(lb_session) - values_for_column_bss = cookie_headers(values_for_column_bss, session_persistence_configuration, sheet_dict_bss) + values_for_column_bss = cookie_headers(values_for_column_bss, session_persistence_configuration, + sheet_dict_bss) else: lb_session = 'n' @@ -442,7 +482,8 @@ def print_backendset_backendserver(region, ct, values_for_column_bss, lbr, LBRs, # Process Columns that are common across LBR sheets - Region, Compartment Name and LBR Name if col_headers in sheet_dict_common.keys(): - values_for_column_bss = common_headers(region, col_headers, values_for_column_bss, eachlbr, sheet_dict_common,lbr_compartment_name) + values_for_column_bss = common_headers(region, col_headers, values_for_column_bss, eachlbr, + sheet_dict_common, lbr_compartment_name) # Process the Tag Columns elif headers_lower in commonTools.tagColumns: @@ -455,7 +496,7 @@ def print_backendset_backendserver(region, ct, values_for_column_bss, lbr, LBRs, values_for_column_bss[col_headers].append("") else: for protocols in certificate_list.protocols: - protocols_list = protocols_list+","+protocols + protocols_list = protocols_list + "," + protocols if (protocols_list != "" and protocols_list[0] == ','): protocols_list = protocols_list.lstrip(',') values_for_column_bss[col_headers].append(protocols_list) @@ -466,12 +507,13 @@ def print_backendset_backendserver(region, ct, values_for_column_bss, lbr, LBRs, if col_headers == "Backend Policy(LEAST_CONNECTIONS|ROUND_ROBIN|IP_HASH)": policy = backendset_details.__getattribute__(sheet_dict_bss[col_headers]) - values_for_column_bss['Backend Policy(LEAST_CONNECTIONS|ROUND_ROBIN|IP_HASH)'].append(str(policy)) + values_for_column_bss['Backend Policy(LEAST_CONNECTIONS|ROUND_ROBIN|IP_HASH)'].append( + str(policy)) elif 'Backend HealthCheck' in col_headers: values_for_column_bss[col_headers].append(hc.__getattribute__(sheet_dict_bss[col_headers])) - elif col_headers == "Backend ServerComp&ServerName:Port": + elif col_headers == "Backend ServerComp@ServerName:Port": values_for_column_bss[col_headers].append(backend_list) elif col_headers == "Backend Set Name": @@ -484,8 +526,10 @@ def print_backendset_backendserver(region, ct, values_for_column_bss, lbr, LBRs, certificates = "" for certificate_ids in certificate_list.certificate_ids: certificates = certificates + "," + certificate_ids - values_for_column_bss[col_headers].append(str(certificate_list.certificate_ids).lstrip(",")) - elif certificate_list.certificate_name != "" and str(certificate_list.certificate_name).lower() != "none": + values_for_column_bss[col_headers].append( + str(certificate_list.certificate_ids).lstrip(",")) + elif certificate_list.certificate_name != "" and str( + certificate_list.certificate_name).lower() != "none": values_for_column_bss[col_headers].append(certificate_list.certificate_name) else: values_for_column_bss[col_headers].append("") @@ -515,14 +559,16 @@ def print_backendset_backendserver(region, ct, values_for_column_bss, lbr, LBRs, continue else: - oci_objs = [backendset_details,eachlbr,hc,certificate_list] - values_for_column_bss = commonTools.export_extra_columns(oci_objs, col_headers, sheet_dict_bss,values_for_column_bss) + oci_objs = [backendset_details, eachlbr, hc, certificate_list] + values_for_column_bss = commonTools.export_extra_columns(oci_objs, col_headers, sheet_dict_bss, + values_for_column_bss) else: if "Cookie" not in col_headers: # Process the remaining Columns - oci_objs = [backendset_details,eachlbr,hc,certificate_list] - values_for_column_bss = commonTools.export_extra_columns(oci_objs, col_headers, sheet_dict_bss,values_for_column_bss) + oci_objs = [backendset_details, eachlbr, hc, certificate_list] + values_for_column_bss = commonTools.export_extra_columns(oci_objs, col_headers, sheet_dict_bss, + values_for_column_bss) return values_for_column_bss @@ -539,10 +585,10 @@ def print_listener(region, ct, values_for_column_lis, LBRs, lbr_compartment_name if 'ocid1.cluster' in created_by: continue - #Fetch Compartment Name + # Fetch Compartment Name lbr_comp_id = eachlbr.compartment_id comp_done_ids = [] - for comp_name,comp_id in ct.ntk_compartment_ids.items(): + for comp_name, comp_id in ct.ntk_compartment_ids.items(): if lbr_comp_id == comp_id and lbr_comp_id not in comp_done_ids: lbr_compartment_name = comp_name comp_done_ids.append(lbr_comp_id) @@ -556,9 +602,10 @@ def print_listener(region, ct, values_for_column_lis, LBRs, lbr_compartment_name if col_headers == 'Certificate Name or OCID': sslcerts = values.__getattribute__(sheet_dict_lis['UseSSL (y|n)']) if str(sslcerts).lower() != "none": - if sslcerts.__getattribute__('certificate_name') != "" and str(sslcerts.__getattribute__('certificate_name')).lower() != "none": + if sslcerts.__getattribute__('certificate_name') != "" and str( + sslcerts.__getattribute__('certificate_name')).lower() != "none": values_for_column_lis[col_headers].append(sslcerts.__getattribute__('certificate_name')) - elif sslcerts.certificate_ids != [] : + elif sslcerts.certificate_ids != []: certificates = "" for certificate_ids in sslcerts.certificate_ids: certificates = certificates + "," + certificate_ids @@ -586,14 +633,15 @@ def print_listener(region, ct, values_for_column_lis, LBRs, lbr_compartment_name values_for_column_lis[col_headers].append("") else: for protocols in sslcerts.protocols: - protocols_list = protocols_list+","+protocols + protocols_list = protocols_list + "," + protocols if (protocols_list != "" and protocols_list[0] == ','): protocols_list = protocols_list.lstrip(',') values_for_column_lis[col_headers].append(protocols_list) # Process Columns that are common across LBR sheets - Region, Compartment Name and LBR Name elif col_headers in sheet_dict_common.keys(): - values_for_column_lis = common_headers(region, col_headers, values_for_column_lis, eachlbr, sheet_dict_common, lbr_compartment_name) + values_for_column_lis = common_headers(region, col_headers, values_for_column_lis, eachlbr, + sheet_dict_common, lbr_compartment_name) # Process the Tag Columns elif headers_lower in commonTools.tagColumns: @@ -605,7 +653,7 @@ def print_listener(region, ct, values_for_column_lis, LBRs, lbr_compartment_name rule_str = "" if values.__getattribute__(sheet_dict_lis[col_headers]) != []: for rule in values.__getattribute__(sheet_dict_lis[col_headers]): - rule_str = rule_str +","+rule + rule_str = rule_str + "," + rule if (rule_str != "" and rule_str[0] == ','): rule_str = rule_str.lstrip(',') values_for_column_lis[col_headers].append(rule_str) @@ -617,28 +665,32 @@ def print_listener(region, ct, values_for_column_lis, LBRs, lbr_compartment_name values_for_column_lis[col_headers].append("n") elif col_headers == "LBR Hostnames (Name)": - hostnames="" + hostnames = "" if values.__getattribute__(sheet_dict_lis[col_headers]): for eachhostname in values.__getattribute__(sheet_dict_lis[col_headers]): - hostnames = hostnames+","+eachhostname + hostnames = hostnames + "," + eachhostname if (hostnames != "" and hostnames[0] == ','): hostnames = hostnames.lstrip(',') values_for_column_lis[col_headers].append(hostnames) elif col_headers == 'Idle Time Out (in Seconds)': connection_config = values.__getattribute__('connection_configuration') - values_for_column_lis[col_headers].append(connection_config.__getattribute__(sheet_dict_lis[col_headers])) + values_for_column_lis[col_headers].append( + connection_config.__getattribute__(sheet_dict_lis[col_headers])) else: - oci_objs = [values,eachlbr,sslcerts] - values_for_column_lis = commonTools.export_extra_columns(oci_objs, col_headers, sheet_dict_lis, values_for_column_lis) + oci_objs = [values, eachlbr, sslcerts] + values_for_column_lis = commonTools.export_extra_columns(oci_objs, col_headers, sheet_dict_lis, + values_for_column_lis) else: - oci_objs = [eachlbr,values,sslcerts] - values_for_column_lis = commonTools.export_extra_columns(oci_objs, col_headers, sheet_dict_lis, values_for_column_lis) + oci_objs = [eachlbr, values, sslcerts] + values_for_column_lis = commonTools.export_extra_columns(oci_objs, col_headers, sheet_dict_lis, + values_for_column_lis) return values_for_column_lis + def print_rule(region, ct, values_for_column_rule, LBRs, lbr_compartment_name): for eachlbr in LBRs.data: @@ -650,11 +702,10 @@ def print_rule(region, ct, values_for_column_rule, LBRs, lbr_compartment_name): if 'ocid1.cluster' in created_by: continue - - #Fetch Compartment Name + # Fetch Compartment Name lbr_comp_id = eachlbr.compartment_id comp_done_ids = [] - for comp_name,comp_id in ct.ntk_compartment_ids.items(): + for comp_name, comp_id in ct.ntk_compartment_ids.items(): if lbr_comp_id == comp_id and lbr_comp_id not in comp_done_ids: lbr_compartment_name = comp_name comp_done_ids.append(lbr_comp_id) @@ -665,7 +716,8 @@ def print_rule(region, ct, values_for_column_rule, LBRs, lbr_compartment_name): headers_lower = commonTools.check_column_headers(col_headers) if col_headers in sheet_dict_common.keys(): - values_for_column_rule = common_headers(region, col_headers, values_for_column_rule, eachlbr,sheet_dict_common, lbr_compartment_name) + values_for_column_rule = common_headers(region, col_headers, values_for_column_rule, eachlbr, + sheet_dict_common, lbr_compartment_name) elif col_headers == 'Rule Set Name': values_for_column_rule[col_headers].append(rulesets) @@ -686,11 +738,11 @@ def print_rule(region, ct, values_for_column_rule, LBRs, lbr_compartment_name): uri_details.query = '' if 'Host:Port' in col_headers: - value = uri_details.host+":"+str(uri_details.port) + value = uri_details.host + ":" + str(uri_details.port) values_for_column_rule[col_headers].append(value) if 'Protocol:Path' in col_headers: - value = uri_details.protocol+":"+uri_details.path + value = uri_details.protocol + ":" + uri_details.path values_for_column_rule[col_headers].append(value) if 'Query' in col_headers: @@ -699,7 +751,7 @@ def print_rule(region, ct, values_for_column_rule, LBRs, lbr_compartment_name): else: value = str(eachitem.__getattribute__(sheet_dict_rule[col_headers])) if value.lower() == 'none': - value="" + value = "" values_for_column_rule[col_headers].append(value) except AttributeError as e: @@ -710,7 +762,7 @@ def print_rule(region, ct, values_for_column_rule, LBRs, lbr_compartment_name): allowed_method = '' if eachitem.action == "CONTROL_ACCESS_USING_HTTP_METHODS": for method in eachitem.__getattribute__(headers_lower): - allowed_method = allowed_method +",\"" + method + "\"" + allowed_method = allowed_method + ",\"" + method + "\"" if (allowed_method != "" and allowed_method[0] == ','): allowed_method = allowed_method.lstrip(',') @@ -722,7 +774,7 @@ def print_rule(region, ct, values_for_column_rule, LBRs, lbr_compartment_name): for attributes in eachitem.conditions: values_for_column_rule[col_headers].append(attributes.__getattribute__(headers_lower)) except AttributeError as e: - values_for_column_rule[col_headers].append("") + values_for_column_rule[col_headers].append("") elif 'Operator' in col_headers: try: @@ -732,8 +784,8 @@ def print_rule(region, ct, values_for_column_rule, LBRs, lbr_compartment_name): values_for_column_rule[col_headers].append("") elif col_headers == "Suffix or Prefix (suffix:|prefix:)": - combined_suffix='' - combined_prefix='' + combined_suffix = '' + combined_prefix = '' try: suffix_val = eachitem.suffix if suffix_val != "" and suffix_val != 'nan' and suffix_val != None: @@ -748,11 +800,13 @@ def print_rule(region, ct, values_for_column_rule, LBRs, lbr_compartment_name): pass else: oci_objs = [eachlbr, eachitem] - values_for_column_rule = commonTools.export_extra_columns(oci_objs, col_headers, sheet_dict_rule, - values_for_column_rule) + values_for_column_rule = commonTools.export_extra_columns(oci_objs, col_headers, + sheet_dict_rule, + values_for_column_rule) return values_for_column_rule + def print_prs(region, ct, values_for_column_prs, LBRs, lbr_compartment_name): for eachlbr in LBRs.data: @@ -764,23 +818,24 @@ def print_prs(region, ct, values_for_column_prs, LBRs, lbr_compartment_name): if 'ocid1.cluster' in created_by: continue - #Fetch Compartment Name + # Fetch Compartment Name lbr_comp_id = eachlbr.compartment_id comp_done_ids = [] - for comp_name,comp_id in ct.ntk_compartment_ids.items(): + for comp_name, comp_id in ct.ntk_compartment_ids.items(): if lbr_comp_id == comp_id and lbr_comp_id not in comp_done_ids: lbr_compartment_name = comp_name comp_done_ids.append(lbr_comp_id) - for prs,values in eachlbr.__getattribute__('path_route_sets').items(): + for prs, values in eachlbr.__getattribute__('path_route_sets').items(): for path_routes in values.__getattribute__('path_routes'): for col_headers in values_for_column_prs.keys(): headers_lower = commonTools.check_column_headers(col_headers) if col_headers in sheet_dict_common.keys(): - values_for_column_prs = common_headers(region, col_headers, values_for_column_prs, eachlbr,sheet_dict_common, lbr_compartment_name) + values_for_column_prs = common_headers(region, col_headers, values_for_column_prs, eachlbr, + sheet_dict_common, lbr_compartment_name) elif col_headers == 'Match Type': try: - key = path_routes.__getattribute__('path_match_type') + key = path_routes.__getattribute__('path_match_type') match_type = key.match_type values_for_column_prs[col_headers].append(match_type) except AttributeError as e: @@ -796,8 +851,68 @@ def print_prs(region, ct, values_for_column_prs, LBRs, lbr_compartment_name): values_for_column_prs) return values_for_column_prs + + +def print_routing_policies(region, ct, values_for_column_rp, LBRs, lbr_compartment_name): + for eachlbr in LBRs.data: + # Retrieve the routing policies for the load balancer + routing_policies = eachlbr.routing_policies + + # Filter out the LBs provisioned by OKE + eachlbr_defined_tags = eachlbr.defined_tags + if 'Oracle-Tags' in eachlbr_defined_tags.keys(): + if 'CreatedBy' in eachlbr_defined_tags['Oracle-Tags'].keys(): + created_by = eachlbr_defined_tags['Oracle-Tags']['CreatedBy'] + if 'ocid1.cluster' in created_by: + continue + + # Fetch the compartment name + lbr_comp_id = eachlbr.compartment_id + comp_done_ids = [] + for comp_name, comp_id in ct.ntk_compartment_ids.items(): + if lbr_comp_id == comp_id and lbr_comp_id not in comp_done_ids: + # Retrieve the values for the routing policies + for rp, values in eachlbr.__getattribute__('routing_policies').items(): + for col_headers in values_for_column_rp.keys(): + headers_lower = commonTools.check_column_headers(col_headers) + + if col_headers in sheet_dict_common.keys(): + values_for_column_rp = common_headers(region, col_headers, values_for_column_rp, eachlbr, + sheet_dict_common, lbr_compartment_name) + elif col_headers == 'LBR Name': + values_for_column_rp[col_headers].append(eachlbr.display_name) + + elif col_headers == 'Routing Policy Name': + values_for_column_rp[col_headers].append(values.__getattribute__('name')) + + elif col_headers == "Rules": + rules = [] + for rule in values.rules: + if hasattr(rule, 'actions') and rule.actions and hasattr(rule.actions[0], 'backend_set_name'): + backend_set_name = rule.actions[0].backend_set_name + else: + backend_set_name = None + rule_str = f"{rule.name}::{rule.condition}::{backend_set_name}" + rules.append(rule_str) + rules_string = "\n".join(rules) + values_for_column_rp[col_headers].append(rules_string) + + elif col_headers in sheet_dict_rp.keys(): + values_for_column_rp[col_headers].append( + values.__getattribute__(sheet_dict_rp[col_headers])) + + else: + # Process the remaining Columns + oci_objs = [eachlbr, values] + values_for_column_rp = commonTools.export_extra_columns(oci_objs, col_headers, + sheet_dict_rp, + values_for_column_rp) + + return values_for_column_rp + + # Execution of the code begins here -def export_lbr(inputfile, outdir, service_dir, config1,signer1, ct, export_compartments, export_regions): +def export_lbr(inputfile, outdir, service_dir, config1, signer1, ct, export_compartments, export_regions): global tf_import_cmd global sheet_dict global importCommands @@ -809,134 +924,188 @@ def export_lbr(inputfile, outdir, service_dir, config1,signer1, ct, export_compa global values_for_column_lis global values_for_column_rule global values_for_column_prs + global values_for_column_rp global sheet_dict_common global sheet_dict_lhc global sheet_dict_bss global sheet_dict_lis global sheet_dict_rule global sheet_dict_prs + global sheet_dict_rp global listener_to_cd3 - global config,signer - signer=signer1 - config=config1 + global config, signer,tf_or_tofu + tf_or_tofu = ct.tf_or_tofu + tf_state_list = [tf_or_tofu, "state", "list"] + signer = signer1 + config = config1 cd3file = inputfile if ('.xls' not in cd3file): print("\nAcceptable cd3 format: .xlsx") exit() - # Read CD3 - df, values_for_column_lhc= commonTools.read_cd3(cd3file,"LB-Hostname-Certs") + df, values_for_column_lhc = commonTools.read_cd3(cd3file, "LB-Hostname-Certs") df, values_for_column_bss = commonTools.read_cd3(cd3file, "LB-BackendSet-BackendServer") df, values_for_column_lis = commonTools.read_cd3(cd3file, "LB-Listener") df, values_for_column_rule = commonTools.read_cd3(cd3file, "LB-RuleSet") df, values_for_column_prs = commonTools.read_cd3(cd3file, "LB-PathRouteSet") + df, values_for_column_rp = commonTools.read_cd3(cd3file, "LB-RoutingPolicy") # Get dict for columns from Excel_Columns - sheet_dict_common=ct.sheet_dict["Common-LBR-Headers"] + sheet_dict_common = ct.sheet_dict["Common-LBR-Headers"] sheet_dict_lhc = ct.sheet_dict["LB-Hostname-Certs"] sheet_dict_bss = ct.sheet_dict["LB-BackendSet-BackendServer"] sheet_dict_lis = ct.sheet_dict["LB-Listener"] sheet_dict_rule = ct.sheet_dict["LB-RuleSet"] sheet_dict_prs = ct.sheet_dict["LB-PathRouteSet"] + sheet_dict_rp = ct.sheet_dict["LB-RoutingPolicy"] print("\nCD3 excel file should not be opened during export process!!!") - print("Tabs- LB-Hostname-Certs, LB-BackendSet-BackendServer, LB-Listener, LB-RuleSet, LB-PathRouteSet will be overwritten during export process!!!\n") - - # Create backups - for reg in export_regions: - resource='tf_import_lbr' - if (os.path.exists(outdir + "/" + reg + "/" + service_dir + "/tf_import_commands_lbr_nonGF.sh")): - commonTools.backup_file(outdir + "/" + reg + "/" + service_dir, resource, "tf_import_commands_lbr_nonGF.sh") - importCommands[reg] = open(outdir + "/" + reg + "/" + service_dir + "/tf_import_commands_lbr_nonGF.sh", "w") - importCommands[reg].write("#!/bin/bash") - importCommands[reg].write("\n") - importCommands[reg].write("terraform init") + print("Tabs- LB-Hostname-Certs, LB-BackendSet-BackendServer, LB-Listener, LB-RuleSet, LB-PathRouteSet, LB-RoutingPolicy will be overwritten during export process!!!\n") # Fetch LBR Details print("\nFetching details of Load Balancer...") + # Create backups + file_name = 'import_commands_lbr_nonGF.sh' + resource = 'import_lbr' + total_resources=0 + for reg in export_regions: - importCommands[reg].write("\n\n######### Writing import for Load Balancer Objects #########\n\n") - config.__setitem__("region", ct.region_dict[reg]) - lbr = LoadBalancerClient(config=config,retry_strategy=oci.retry.DEFAULT_RETRY_STRATEGY,signer=signer) - network = oci.core.VirtualNetworkClient(config=config, retry_strategy=oci.retry.DEFAULT_RETRY_STRATEGY,signer=signer) + script_file = f'{outdir}/{reg}/{service_dir}/' + file_name + + if os.path.exists(script_file): + commonTools.backup_file(outdir + "/" + reg + "/" + service_dir, resource, file_name) + importCommands[reg] = '' + + config.__setitem__("region", ct.region_dict[reg]) + state = {'path': f'{outdir}/{reg}/{service_dir}', 'resources': []} + try: + byteOutput = sp.check_output(tf_state_list, cwd=state["path"], stderr=sp.DEVNULL) + output = byteOutput.decode('UTF-8').rstrip() + for item in output.split('\n'): + state["resources"].append(item.replace("\"", "\\\"")) + except Exception as e: + pass + lbr = LoadBalancerClient(config=config, retry_strategy=oci.retry.DEFAULT_RETRY_STRATEGY, signer=signer) + network = oci.core.VirtualNetworkClient(config=config, retry_strategy=oci.retry.DEFAULT_RETRY_STRATEGY, + signer=signer) region = reg.capitalize() for compartment_name in export_compartments: - LBRs = oci.pagination.list_call_get_all_results(lbr.list_load_balancers,compartment_id=ct.ntk_compartment_ids[compartment_name], - lifecycle_state="ACTIVE") - values_for_column_lhc = print_lbr_hostname_certs(region, ct, outdir, values_for_column_lhc, lbr, LBRs, compartment_name, network,service_dir) - values_for_column_lis = print_listener(region, ct, values_for_column_lis,LBRs,compartment_name) - values_for_column_bss = print_backendset_backendserver(region, ct, values_for_column_bss, lbr,LBRs,compartment_name) - values_for_column_rule = print_rule(region, ct, values_for_column_rule, LBRs, compartment_name) - values_for_column_prs = print_prs(region, ct, values_for_column_prs, LBRs, compartment_name) - - for eachlbr in LBRs.data: - - # Filter out the LBs provisioned by oke - eachlbr_defined_tags = eachlbr.defined_tags - if 'Oracle-Tags' in eachlbr_defined_tags.keys(): - if 'CreatedBy' in eachlbr_defined_tags['Oracle-Tags'].keys(): - created_by = eachlbr_defined_tags['Oracle-Tags']['CreatedBy'] - if 'ocid1.cluster' in created_by: - continue - - - importCommands[reg] = open(outdir + "/" + reg + "/" + service_dir + "/tf_import_commands_lbr_nonGF.sh", "a") - lbr_info = eachlbr - lbr_display_name = lbr_info.display_name - tf_name = commonTools.check_tf_variable(lbr_display_name) - importCommands[reg].write("\nterraform import \"module.load-balancers[\\\""+str(tf_name)+"\\\"].oci_load_balancer_load_balancer.load_balancer\" " + lbr_info.id) - - for certificates in eachlbr.certificates: - cert_tf_name = commonTools.check_tf_variable(certificates) - importCommands[reg].write("\nterraform import \"module.certificates[\\\""+str(tf_name)+"_" + str(cert_tf_name) + "_cert""\\\"].oci_load_balancer_certificate.certificate\" loadBalancers/" + lbr_info.id + "/certificates/" + certificates) - - for hostnames in eachlbr.hostnames: - hostname_tf_name = commonTools.check_tf_variable(hostnames) - importCommands[reg].write("\nterraform import \"module.hostnames[\\\""+str(tf_name)+ "_" + str(hostname_tf_name) + "_hostname""\\\"].oci_load_balancer_hostname.hostname\" loadBalancers/" + lbr_info.id + "/hostnames/" + hostnames) - - for listeners in eachlbr.listeners: - listener_tf_name = commonTools.check_tf_variable(listeners) - importCommands[reg].write("\nterraform import \"module.listeners[\\\""+str(tf_name)+"_" + str(listener_tf_name) +"\\\"].oci_load_balancer_listener.listener\" loadBalancers/" + lbr_info.id + "/listeners/" + listeners) - - for backendsets, values in eachlbr.backend_sets.items(): - backendsets_tf_name = commonTools.check_tf_variable(backendsets) - importCommands[reg].write("\nterraform import \"module.backend-sets[\\\""+str(tf_name)+"_" + str(backendsets_tf_name) +"\\\"].oci_load_balancer_backend_set.backend_set\" loadBalancers/" + lbr_info.id + "/backendSets/" + backendsets) - - cnt = 0 - for keys in values.backends: - cnt = cnt + 1 - backendservers_name = keys.name - backendservers_tf_name = commonTools.check_tf_variable(keys.ip_address+"-"+str(cnt)) - importCommands[reg].write("\nterraform import \"module.backends[\\\""+str(tf_name)+"_" + backendsets_tf_name + "_" + backendservers_tf_name +"\\\"].oci_load_balancer_backend.backend\" loadBalancers/" + lbr_info.id + "/backendSets/" + backendsets + "/backends/" + backendservers_name) - - for pathroutes in eachlbr.path_route_sets: - pathroutes_tf_name = commonTools.check_tf_variable(pathroutes) - importCommands[reg].write("\nterraform import \"module.path-route-sets[\\\""+str(tf_name)+"_" + pathroutes_tf_name +"\\\"].oci_load_balancer_path_route_set.path_route_set\" loadBalancers/" + lbr_info.id + "/pathRouteSets/" + pathroutes) - - for routerules in eachlbr.rule_sets: - routerules_tf_name = commonTools.check_tf_variable(routerules) - importCommands[reg].write("\nterraform import \"module.rule-sets[\\\""+str(tf_name)+"_" + routerules_tf_name + "\\\"].oci_load_balancer_rule_set.rule_set\" loadBalancers/" + lbr_info.id + "/ruleSets/" + routerules) - - for ciphers in eachlbr.ssl_cipher_suites: - ciphers_tf_name = commonTools.check_tf_variable(ciphers) - importCommands[reg].write("\nterraform import \"module.cipher-suites[\\\""+str(tf_name)+"_" + ciphers_tf_name +"\\\"].oci_load_balancer_ssl_cipher_suite.ssl_cipher_suite\" loadBalancers/" + lbr_info.id + "/sslCipherSuites/" + ciphers) + LBRs = oci.pagination.list_call_get_all_results(lbr.list_load_balancers, + compartment_id=ct.ntk_compartment_ids[compartment_name], + lifecycle_state="ACTIVE") + values_for_column_lhc = print_lbr_hostname_certs(region, ct, outdir, values_for_column_lhc, lbr, LBRs, + compartment_name, network, service_dir) + values_for_column_lis = print_listener(region, ct, values_for_column_lis, LBRs, compartment_name) + values_for_column_bss = print_backendset_backendserver(region, ct, values_for_column_bss, lbr, LBRs, + compartment_name) + values_for_column_rule = print_rule(region, ct, values_for_column_rule, LBRs, compartment_name) + values_for_column_prs = print_prs(region, ct, values_for_column_prs, LBRs, compartment_name) + values_for_column_rp = print_routing_policies(region, ct, values_for_column_rp, LBRs, compartment_name) + + + for eachlbr in LBRs.data: + total_resources+=1 + + # Filter out the LBs provisioned by oke + eachlbr_defined_tags = eachlbr.defined_tags + if 'Oracle-Tags' in eachlbr_defined_tags.keys(): + if 'CreatedBy' in eachlbr_defined_tags['Oracle-Tags'].keys(): + created_by = eachlbr_defined_tags['Oracle-Tags']['CreatedBy'] + if 'ocid1.cluster' in created_by: + continue + + + lbr_info = eachlbr + lbr_display_name = lbr_info.display_name + tf_name = commonTools.check_tf_variable(lbr_display_name) + tf_resource = f'module.load-balancers[\\"{tf_name}\\"].oci_load_balancer_load_balancer.load_balancer' + if tf_resource not in state["resources"]: + importCommands[reg] += f'\n{tf_or_tofu} import "{tf_resource}" {lbr_info.id}' + + for certificates in eachlbr.certificates: + cert_tf_name = commonTools.check_tf_variable(certificates) + tf_resource = f'module.certificates[\\"{tf_name}_{cert_tf_name}_cert\\"].oci_load_balancer_certificate.certificate' + if tf_resource not in state["resources"]: + importCommands[reg] += f'\n{tf_or_tofu} import "{tf_resource}" loadBalancers/{lbr_info.id}/certificates/{certificates}' + + for hostnames in eachlbr.hostnames: + hostname_tf_name = commonTools.check_tf_variable(hostnames) + tf_resource = f'module.hostnames[\\"{tf_name}_{hostname_tf_name}_hostname\\"].oci_load_balancer_hostname.hostname' + if tf_resource not in state["resources"]: + importCommands[ + reg] += f'\n{tf_or_tofu} import "{tf_resource}" loadBalancers/{lbr_info.id}/hostnames/{hostnames}' + + for listeners in eachlbr.listeners: + listener_tf_name = commonTools.check_tf_variable(listeners) + tf_resource = f'module.listeners[\\"{tf_name}_{listener_tf_name}\\"].oci_load_balancer_listener.listener' + if tf_resource not in state["resources"]: + importCommands[ + reg] += f'\n{tf_or_tofu} import "{tf_resource}" loadBalancers/{lbr_info.id}/listeners/{listeners}' + + for backendsets, values in eachlbr.backend_sets.items(): + backendsets_tf_name = commonTools.check_tf_variable(backendsets) + tf_resource = f'module.backend-sets[\\"{tf_name}_{backendsets_tf_name}\\"].oci_load_balancer_backend_set.backend_set' + if tf_resource not in state["resources"]: + importCommands[ + reg] += f'\n{tf_or_tofu} import "{tf_resource}" loadBalancers/{lbr_info.id}/backendSets/{backendsets}' + + cnt = 0 + for keys in values.backends: + cnt = cnt + 1 + backendservers_name = keys.name + backendservers_tf_name = commonTools.check_tf_variable(keys.ip_address + "-" + str(cnt)) + tf_resource = f'module.backends[\\"{tf_name}_{backendsets_tf_name}_{backendservers_tf_name}\\"].oci_load_balancer_backend.backend' + if tf_resource not in state["resources"]: + importCommands[ + reg] += f'\n{tf_or_tofu} import "{tf_resource}" loadBalancers/{lbr_info.id}/backendSets/{backendsets}/backends/{backendservers_name}' + + for pathroutes in eachlbr.path_route_sets: + pathroutes_tf_name = commonTools.check_tf_variable(pathroutes) + tf_resource = f'module.path-route-sets[\\"{tf_name}_{pathroutes_tf_name}\\"].oci_load_balancer_path_route_set.path_route_set' + if tf_resource not in state["resources"]: + importCommands[ + reg] += f'\n{tf_or_tofu} import "{tf_resource}" loadBalancers/{lbr_info.id}/pathRouteSets/{pathroutes}' + + for routing_policy in eachlbr.routing_policies: + routing_policy_tf_name = commonTools.check_tf_variable(routing_policy) + tf_resource = f'module.routing-policies[\\"{tf_name}_{routing_policy_tf_name}\\"].oci_load_balancer_load_balancer_routing_policy.load_balancer_routing_policy' + if tf_resource not in state["resources"]: + importCommands[ + reg] += f'\n{tf_or_tofu} import "{tf_resource}" loadBalancers/{lbr_info.id}/routingPolicies/{routing_policy}' + + for routerules in eachlbr.rule_sets: + routerules_tf_name = commonTools.check_tf_variable(routerules) + tf_resource = f'module.rule-sets[\\"{tf_name}_{routerules_tf_name}\\"].oci_load_balancer_rule_set.rule_set' + if tf_resource not in state["resources"]: + importCommands[ + reg] += f'\n{tf_or_tofu} import "{tf_resource}" loadBalancers/{lbr_info.id}/ruleSets/{routerules}' + + for ciphers in eachlbr.ssl_cipher_suites: + ciphers_tf_name = commonTools.check_tf_variable(ciphers) + tf_resource = f'module.cipher-suites[\\"{tf_name}_{ciphers_tf_name}\\"].oci_load_balancer_ssl_cipher_suite.ssl_cipher_suite' + if tf_resource not in state["resources"]: + importCommands[ + reg] += f'\n{tf_or_tofu} import "{tf_resource}" loadBalancers/{lbr_info.id}/sslCipherSuites/{ciphers}' commonTools.write_to_cd3(values_for_column_lhc, cd3file, "LB-Hostname-Certs") commonTools.write_to_cd3(values_for_column_bss, cd3file, "LB-BackendSet-BackendServer") commonTools.write_to_cd3(values_for_column_lis, cd3file, "LB-Listener") - commonTools.write_to_cd3(values_for_column_rule,cd3file, "LB-RuleSet") + commonTools.write_to_cd3(values_for_column_rule, cd3file, "LB-RuleSet") commonTools.write_to_cd3(values_for_column_prs, cd3file, "LB-PathRouteSet") + commonTools.write_to_cd3(values_for_column_rp, cd3file, "LB-RoutingPolicy") - print("{0} LBRs exported into CD3.\n".format(len(values_for_column_lhc["Region"]))) - + print("{0} LBRs exported into CD3.\n".format(total_resources)) # writing data for reg in export_regions: - script_file = f'{outdir}/{reg}/{service_dir}/tf_import_commands_lbr_nonGF.sh' - with open(script_file, 'a') as importCommands[reg]: - importCommands[reg].write('\n\nterraform plan\n') + script_file = f'{outdir}/{reg}/{service_dir}/' + file_name + if importCommands[reg] != "": + init_commands = f'\n######### Writing import for Load Balancer Objects #########\n\n#!/bin/bash\n{tf_or_tofu} init' + importCommands[reg] += f'\n{tf_or_tofu} plan\n' + with open(script_file, 'a') as importCommandsfile: + importCommandsfile.write(init_commands + importCommands[reg]) diff --git a/cd3_automation_toolkit/Network/LoadBalancers/export_nlb_nonGreenField.py b/cd3_automation_toolkit/Network/LoadBalancers/export_nlb_nonGreenField.py index 1de4afadc..2b17554c6 100644 --- a/cd3_automation_toolkit/Network/LoadBalancers/export_nlb_nonGreenField.py +++ b/cd3_automation_toolkit/Network/LoadBalancers/export_nlb_nonGreenField.py @@ -10,6 +10,7 @@ import sys import oci import os +import subprocess as sp from oci.core.virtual_network_client import VirtualNetworkClient from oci.network_load_balancer import NetworkLoadBalancerClient @@ -20,7 +21,7 @@ importCommands = {} oci_obj_names = {} -def print_nlb_backendset_backendserver(region, ct, values_for_column_bss,NLBs, nlb_compartment_name,cmpt,vcn,nlb): +def print_nlb_backendset_backendserver(region, ct, values_for_column_bss,NLBs, nlb_compartment_name,cmpt,vcn,nlb,state): for eachnlb in NLBs.data: cnt_bss = 0 @@ -40,7 +41,9 @@ def print_nlb_backendset_backendserver(region, ct, values_for_column_bss,NLBs, n cnt_bss = cnt_bss + 1 backendsets_tf_name = commonTools.check_tf_variable(backendsets) - importCommands[reg].write("\nterraform import \"module.nlb-backend-sets[\\\"" + str(tf_name) + "_" + str(backendsets_tf_name) + "\\\"].oci_network_load_balancer_backend_set.backend_set\" networkLoadBalancers/" + eachnlb.id + "/backendSets/" + backendsets) + tf_resource = f'module.nlb-backend-sets[\\"{tf_name}_{backendsets_tf_name}\\"].oci_network_load_balancer_backend_set.backend_set' + if tf_resource not in state["resources"]: + importCommands[reg] += f'\n{tf_or_tofu} import "{tf_resource}" networkLoadBalancers/{eachnlb.id}/backendSets/{backendsets}' backend_list = "" backendset_details = nlb.get_backend_set(eachnlb.__getattribute__('id'), backendsets).data @@ -59,7 +62,12 @@ def print_nlb_backendset_backendserver(region, ct, values_for_column_bss,NLBs, n if "ocid1.privateip" in backend_value: private_ip_ocid = backend_value.split(":")[0] #port = backend_value.split(":")[1] - private_ip = vcn.get_private_ip(private_ip_ocid).data + try: + private_ip = vcn.get_private_ip(private_ip_ocid).data + except Exception as e: + print("Some issue with Backend "+backend_value+ " for NLB "+nlb_display_name+". Skipping it...") + continue + vnic_ocid = private_ip.vnic_id vnic = vcn.get_vnic(vnic_ocid).data vnic_found = 0 @@ -75,19 +83,20 @@ def print_nlb_backendset_backendserver(region, ct, values_for_column_bss,NLBs, n if vnic_found==1: break - backend = instance_comp_name+"&"+instance_display_name+":"+port + backend = instance_comp_name+"@"+instance_display_name+":"+port backend_list = backend_list + "," + backend backendservers_name = instance_display_name +"-"+str(cnt_bes) backendservers_tf_name = commonTools.check_tf_variable(backendservers_name) else: backend = backend_value - backend_list= backend_list+","+"&"+backend + backend_list= backend_list+","+backend backendservers_name = backend.split(":")[0] +"-"+str(cnt_bes) backendservers_tf_name = commonTools.check_tf_variable(backendservers_name) - - importCommands[reg].write("\nterraform import \"module.nlb-backends[\\\"" + str(tf_name) + "_" + backendsets_tf_name + "_" + backendservers_tf_name + "\\\"].oci_network_load_balancer_backend.backend\" networkLoadBalancers/" + eachnlb.id + "/backendSets/" + backendsets + "/backends/" + backend_value) + tf_resource = f'module.nlb-backends[\\"{tf_name}_{backendsets_tf_name}_{backendservers_tf_name}\\"].oci_network_load_balancer_backend.backend' + if tf_resource not in state["resources"]: + importCommands[reg] += f'\n{tf_or_tofu} import "{tf_resource}" networkLoadBalancers/{eachnlb.id}/backendSets/{backendsets}/backends/{backend_value}' if (backend_list != "" and backend_list[0] == ','): backend_list = backend_list.lstrip(',') @@ -123,7 +132,7 @@ def print_nlb_backendset_backendserver(region, ct, values_for_column_bss,NLBs, n elif 'Backend HealthCheck' in col_header: values_for_column_bss[col_header].append(hc.__getattribute__(sheet_dict_bss[col_header])) - elif col_header == "Backend ServerComp&ServerName:Port": + elif col_header == "Backend ServerComp@ServerName:Port": values_for_column_bss[col_header].append(backend_list) elif col_header == "Backend Set Name": @@ -135,7 +144,7 @@ def print_nlb_backendset_backendserver(region, ct, values_for_column_bss,NLBs, n return values_for_column_bss -def print_nlb_listener(region, outdir, values_for_column_lis, NLBs, nlb_compartment_name,vcn): +def print_nlb_listener(region, outdir, values_for_column_lis, NLBs, nlb_compartment_name,vcn,ct,state): for eachnlb in NLBs.data: # Filter out the NLBs provisioned by oke @@ -148,7 +157,9 @@ def print_nlb_listener(region, outdir, values_for_column_lis, NLBs, nlb_compartm nlb_display_name = eachnlb.display_name tf_name = commonTools.check_tf_variable(nlb_display_name) - importCommands[reg].write("\nterraform import \"module.network-load-balancers[\\\"" + str(tf_name) + "\\\"].oci_network_load_balancer_network_load_balancer.network_load_balancer\" " + eachnlb.id) + tf_resource = f'module.network-load-balancers[\\"{tf_name}\\"].oci_network_load_balancer_network_load_balancer.network_load_balancer' + if tf_resource not in state["resources"]: + importCommands[reg] += f'\n{tf_or_tofu} import "{tf_resource}" {eachnlb.id}' cnt_lsnr = 0 @@ -159,8 +170,13 @@ def print_nlb_listener(region, outdir, values_for_column_lis, NLBs, nlb_compartm vcn_id = subnet_info.vcn_id vcn_info = vcn.get_vcn(vcn_id).data vcn_name = vcn_info.display_name + ntk_compartment_id = vcn.get_vcn(vcn_id).data.compartment_id # compartment-id + network_compartment_name = nlb_compartment_name + for comp_name, comp_id in ct.ntk_compartment_ids.items(): + if comp_id == ntk_compartment_id: + network_compartment_name = comp_name - subnet_detail = vcn_name + "_" + subnet_name + subnet_detail = network_compartment_name + "@" + vcn_name + "::" + subnet_name #Fetch NSGs nsg_detail = "" @@ -173,9 +189,11 @@ def print_nlb_listener(region, outdir, values_for_column_lis, NLBs, nlb_compartm # Fetch reserved IP address reserved_ip = "" + is_public=False if eachnlb.ip_addresses != []: for ips in eachnlb.ip_addresses: if(ips.is_public == True): + is_public=ips.is_public if str(ips.reserved_ip) == "null" or str(ips.reserved_ip) == "None": reserved_ip = "N" else: @@ -186,7 +204,9 @@ def print_nlb_listener(region, outdir, values_for_column_lis, NLBs, nlb_compartm cnt_lsnr = cnt_lsnr + 1 listener_tf_name = commonTools.check_tf_variable(listeners) - importCommands[reg].write("\nterraform import \"module.nlb-listeners[\\\"" + str(tf_name) + "_" + str(listener_tf_name) + "\\\"].oci_network_load_balancer_listener.listener\" networkLoadBalancers/" + eachnlb.id + "/listeners/" + listeners) + tf_resource = f'module.nlb-listeners[\\"{tf_name}_{listener_tf_name}\\"].oci_network_load_balancer_listener.listener' + if tf_resource not in state["resources"]: + importCommands[reg] += f'\n{tf_or_tofu} import "{tf_resource}" networkLoadBalancers/{eachnlb.id}/listeners/{listeners}' for col_header in values_for_column_lis.keys(): if col_header == 'Region': @@ -204,7 +224,7 @@ def print_nlb_listener(region, outdir, values_for_column_lis, NLBs, nlb_compartm values_for_column_lis[col_header].append(eachnlb.display_name) else: values_for_column_lis[col_header].append("") - elif col_header == "Subnet Name": + elif col_header == "Network Details": if cnt_lsnr == 1: values_for_column_lis[col_header].append(subnet_detail) else: @@ -217,7 +237,7 @@ def print_nlb_listener(region, outdir, values_for_column_lis, NLBs, nlb_compartm elif (col_header == "Is Private(True|False)"): if cnt_lsnr == 1: - values_for_column_lis[col_header].append(not(ips.is_public)) + values_for_column_lis[col_header].append(not(is_public)) else: values_for_column_lis[col_header].append("") @@ -245,7 +265,7 @@ def print_nlb_listener(region, outdir, values_for_column_lis, NLBs, nlb_compartm values_for_column_lis[col_header].append(nlb_compartment_name) elif col_header == 'NLB Name': values_for_column_lis[col_header].append(eachnlb.display_name) - elif col_header == "Subnet Name": + elif col_header == "Network Details": values_for_column_lis[col_header].append(subnet_detail) elif (col_header == "NSGs"): values_for_column_lis[col_header].append(nsg_detail) @@ -274,7 +294,9 @@ def export_nlb(inputfile, outdir, service_dir, config,signer, ct, export_compart global values_for_column_lis global sheet_dict_bss global sheet_dict_lis - global listener_to_cd3 + global listener_to_cd3,tf_or_tofu + tf_or_tofu = ct.tf_or_tofu + tf_state_list = [tf_or_tofu, "state", "list"] cd3file = inputfile if ('.xls' not in cd3file): @@ -293,45 +315,57 @@ def export_nlb(inputfile, outdir, service_dir, config,signer, ct, export_compart print("\nCD3 excel file should not be opened during export process!!!") print("Tabs- NLB-Listeners, NLB-BackendSets-BackendServers will be overwritten during export process!!!\n") - # Create backups - for reg in export_regions: - resource='tf_import_nlb' - if (os.path.exists(outdir + "/" + reg + "/" + service_dir + "/tf_import_commands_nlb_nonGF.sh")): - commonTools.backup_file(outdir + "/" + reg + "/" + service_dir, resource, "tf_import_commands_nlb_nonGF.sh") - importCommands[reg] = open(outdir + "/" + reg + "/" + service_dir + "/tf_import_commands_nlb_nonGF.sh", "w") - importCommands[reg].write("#!/bin/bash") - importCommands[reg].write("\n") - importCommands[reg].write("terraform init") - # Fetch NLB Details print("\nFetching details of Network Load Balancer...") + file_name = 'import_commands_nlb.sh' + resource = 'import_nlb' + total_resources = 0 + for reg in export_regions: - importCommands[reg].write("\n\n######### Writing import for Network Load Balancer Objects #########\n\n") + script_file = f'{outdir}/{reg}/{service_dir}/' + file_name + + # Create backups + if os.path.exists(script_file): + commonTools.backup_file(outdir + "/" + reg + "/" + service_dir, resource, file_name) + + importCommands[reg] = '' + config.__setitem__("region", ct.region_dict[reg]) + state = {'path': f'{outdir}/{reg}/{service_dir}', 'resources': []} + try: + byteOutput = sp.check_output(tf_state_list, cwd=state["path"], stderr=sp.DEVNULL) + output = byteOutput.decode('UTF-8').rstrip() + for item in output.split('\n'): + state["resources"].append(item.replace("\"", "\\\"")) + except Exception as e: + pass nlb = NetworkLoadBalancerClient(config=config,retry_strategy=oci.retry.DEFAULT_RETRY_STRATEGY,signer=signer) vcn = VirtualNetworkClient(config=config,retry_strategy=oci.retry.DEFAULT_RETRY_STRATEGY,signer=signer) cmpt = ComputeClient(config=config,retry_strategy=oci.retry.DEFAULT_RETRY_STRATEGY,signer=signer) region = reg.capitalize() - for compartment_name in export_compartments: NLBs = oci.pagination.list_call_get_all_results(nlb.list_network_load_balancers,compartment_id=ct.ntk_compartment_ids[compartment_name], lifecycle_state="ACTIVE") + if NLBs.data != [] and importCommands[reg] == '': + total_resources += len(NLBs.data) - values_for_column_lis = print_nlb_listener(region, outdir, values_for_column_lis,NLBs,compartment_name,vcn) - values_for_column_bss = print_nlb_backendset_backendserver(region, ct, values_for_column_bss,NLBs,compartment_name,cmpt,vcn,nlb) + values_for_column_lis = print_nlb_listener(region, outdir, values_for_column_lis,NLBs,compartment_name,vcn,ct,state) + values_for_column_bss = print_nlb_backendset_backendserver(region, ct, values_for_column_bss,NLBs,compartment_name,cmpt,vcn,nlb,state) commonTools.write_to_cd3(values_for_column_lis, cd3file, "NLB-Listeners") commonTools.write_to_cd3(values_for_column_bss, cd3file, "NLB-BackendSets-BackendServers") - print("{0} NLBs exported into CD3.\n".format(len(values_for_column_lis["Region"]))) - + print("{0} NLBs exported into CD3.\n".format(total_resources)) # writing data for reg in export_regions: - script_file = f'{outdir}/{reg}/{service_dir}/tf_import_commands_nlb_nonGF.sh' - with open(script_file, 'a') as importCommands[reg]: - importCommands[reg].write('\n\nterraform plan\n') + script_file = f'{outdir}/{reg}/{service_dir}/' + file_name + if importCommands[reg] != "": + init_commands = f'\n######### Writing import for Network Load Balancer Objects #########\n\n#!/bin/bash\n{tf_or_tofu} init' + importCommands[reg] += f'\n{tf_or_tofu} plan\n' + with open(script_file, 'a') as importCommandsfile: + importCommandsfile.write(init_commands + importCommands[reg]) diff --git a/cd3_automation_toolkit/Network/LoadBalancers/templates/lb-routing-policy-template b/cd3_automation_toolkit/Network/LoadBalancers/templates/lb-routing-policy-template new file mode 100755 index 000000000..1785895ee --- /dev/null +++ b/cd3_automation_toolkit/Network/LoadBalancers/templates/lb-routing-policy-template @@ -0,0 +1,62 @@ +{% if (skeleton and count == 0) %} +// Copyright (c) 2024, 2025, Oracle and/or its affiliates. + +############################# +# Network +# Routing Policy - tfvars +# Allowed Values: +# load_balancer_id can be the ocid or the key of load_balancers (map) +# Sample import command for Routing Policy: +# terraform import "module.routing-policy\"<>\"].oci_load_balancer_load_balancer_routing_policy.load_balancer_routing_policy" <> +############################# + +lb_routing_policies = { +##Add New Routing Policy for {{ region|lower }} here## +}{% else %} + {{ lbr_tf_name }}_{{ routing_policy_tf_name }} = { + condition_language_version = "V1" + load_balancer_id = "{{ load_balancer_id }}" + name = "{{ routing_policy_name }}" + rules = [ + {% for rule in rules %} + { + condition = "{{ rule.condition }}" + name = "{{ rule.name }}" + backend_set_name = "{{ rule.backend_set_name }}" + }{% if not loop.last %},{% endif %} + {% endfor %} + ] + + {# ##Do not modify below this line## #} + {# #} + {# ###Section for adding Defined and Freeform Tags### #} + {% if defined_tags and defined_tags != 'nan' and defined_tags != '' and defined_tags != [['nan']] %} + {% if defined_tags[0] %} + defined_tags = { + {% for tags in defined_tags %} + {% if not loop.last %} + "{{ tags[0] }}"= "{{ tags[1] }}" , + {% else %} + "{{ tags[0] }}"= "{{ tags[1] }}" + {% endif %} + {% endfor %} + } + {% endif %} + {% endif %} + {% if freeform_tags and freeform_tags != 'nan' and freeform_tags != '' and freeform_tags != [['nan']] %} + {% if freeform_tags[0] %} + freeform_tags = { + {% for tags in freeform_tags %} + {% if not loop.last %} + "{{ tags[0] }}"="{{ tags[1] }}", + {% else %} + "{{ tags[0] }}"="{{ tags[1] }}" + {% endif %} + {% endfor %} + } + {% endif %} + {% endif %} + {# ###Section for adding Defined and Freeform Tags ends here### #} + }, + +{% endif %} \ No newline at end of file diff --git a/cd3_automation_toolkit/OCI_Regions b/cd3_automation_toolkit/OCI_Regions index 5d3767430..da2a8419e 100644 --- a/cd3_automation_toolkit/OCI_Regions +++ b/cd3_automation_toolkit/OCI_Regions @@ -3,6 +3,7 @@ saltlake:us-saltlake-2 amsterdam:eu-amsterdam-1 stockholm:eu-stockholm-1 abudhabi:me-abudhabi-1 +saltlake:us-saltlake-1 bogota:sa-bogota-1 mumbai:ap-mumbai-1 paris:eu-paris-1 @@ -16,6 +17,7 @@ seoul:ap-seoul-1 jeddah:me-jeddah-1 johannesburg:af-johannesburg-1 osaka:ap-osaka-1 +kragujevac:eu-kragujevac-1 london:uk-london-1 milan:eu-milan-1 madrid:eu-madrid-1 @@ -24,6 +26,7 @@ marseille:eu-marseille-1 monterrey:mx-monterrey-1 jerusalem:il-jerusalem-1 tokyo:ap-tokyo-1 +neom:me-neom-1 chicago:us-chicago-1 phoenix:us-phoenix-1 queretaro:mx-queretaro-1 diff --git a/cd3_automation_toolkit/Release-Notes b/cd3_automation_toolkit/Release-Notes index 21f771400..a0ec5eaaa 100644 --- a/cd3_automation_toolkit/Release-Notes +++ b/cd3_automation_toolkit/Release-Notes @@ -1,3 +1,16 @@ +------------------------------------- +CD3 Automation Toolkit Tag v2024.4.0 +Aug 16th, 2024 +------------------------------------- +1. Users/Groups for Custom Identity Domains +2. Routing Policies for Load Balancers. +3. Terraform version upgrade to 1.5.7 on the container. OCI RM stack version also upgraded to 1.5.x +4. Support for OpenTofu 1.6.2. Update tenancyconfig.properties to specify the IaC tool to be configured for a particular prefix. +5. Differential state import - Import commands during CD3 export process will only be written for the OCI objects which are not already in state file. +6. Independence from Network Tabs while exporting all other OCI resources. ie network tabs do not need to have data to export instances/databses etc. +7. Inclusion of OCI FSDR export and update functionality (using python) under 'OCI Other Tools'. Output files generated are made available at + /cd3user/tenancies//othertools_files and also under artifacts in Jenkins console. + ------------------------------------- CD3 Automation Toolkit Tag v2024.3.2 Jun 26th, 2024 diff --git a/cd3_automation_toolkit/SDDC/create_terraform_sddc.py b/cd3_automation_toolkit/SDDC/create_terraform_sddc.py index 0f184dedd..456f5dbe6 100755 --- a/cd3_automation_toolkit/SDDC/create_terraform_sddc.py +++ b/cd3_automation_toolkit/SDDC/create_terraform_sddc.py @@ -126,24 +126,31 @@ def create_terraform_sddc_cluster(inputfile, outdir, service_dir, prefix, ct, sd columnvalue = commonTools.check_columnvalue(str(df1[columnname][i]).strip()) # Check for multivalued columns tempdict = commonTools.check_multivalues_columnvalue(columnvalue, columnname, tempdict) - if columnname == 'Provisioning Subnet': - subnet_tf_name = columnvalue.strip() - if ("ocid1.subnet.oc1" in subnet_tf_name): - network_compartment_id = "" + + subnet_id = '' + network_compartment_id = '' + vcn_name = '' + if columnname == 'Network Details': + columnvalue = columnvalue.strip() + if ("ocid1.subnet.oc" in columnvalue): + network_compartment_id = "root" vcn_name = "" - subnet_id = subnet_tf_name - else: - try: - key = region, subnet_tf_name - network_compartment_id = subnets.vcn_subnet_map[key][0] - vcn_name = subnets.vcn_subnet_map[key][1] - subnet_id = subnets.vcn_subnet_map[key][2] - except Exception as e: - print("Invalid Subnet Name specified for row " + str(i + 3) + ". It Doesnt exist in SubnetsVLANs sheet. Exiting!!!") + subnet_id = columnvalue + elif columnvalue.lower() != 'nan' and columnvalue.lower() != '': + if len(columnvalue.split("@")) == 2: + network_compartment_id = commonTools.check_tf_variable(columnvalue.split("@")[0].strip()) + vcn_subnet_name = columnvalue.split("@")[1].strip() + else: + network_compartment_id = commonTools.check_tf_variable(str(df.loc[i, 'Compartment Name']).strip()) + vcn_subnet_name = columnvalue + if ("::" not in vcn_subnet_name): + print("Invalid Network Details format specified for row " + str(i + 3) + ". Exiting!!!") exit(1) - - tempdict = {'network_compartment_id': commonTools.check_tf_variable(network_compartment_id), - 'vcn_name': vcn_name,'provisioning_subnet': subnet_id} + else: + vcn_name = vcn_subnet_name.split("::")[0].strip() + subnet_id = vcn_subnet_name.split("::")[1].strip() + tempdict = {'network_compartment_id': network_compartment_id, 'vcn_name': vcn_name, + 'provisioning_subnet': subnet_id} columnname = commonTools.check_column_headers(columnname) tempStr[columnname] = str(columnvalue).strip() diff --git a/cd3_automation_toolkit/SDDC/export_sddc_nonGreenField.py b/cd3_automation_toolkit/SDDC/export_sddc_nonGreenField.py index d9611ad50..3af083e0c 100644 --- a/cd3_automation_toolkit/SDDC/export_sddc_nonGreenField.py +++ b/cd3_automation_toolkit/SDDC/export_sddc_nonGreenField.py @@ -10,6 +10,7 @@ from oci.core.virtual_network_client import VirtualNetworkClient from oci.core.blockstorage_client import BlockstorageClient import os +import subprocess as sp sys.path.append(os.getcwd() + "/..") from commonTools import * @@ -21,14 +22,16 @@ def get_volume_data(bvol, volume_id, ct): vol_comp = list(ct.ntk_compartment_ids.keys())[comp_list.index(volume_data.compartment_id)] return vol_comp+'@'+vol_name -###SDDC Data +### Execution start here - SDDC Data def export_sddc(inputfile, outdir, service_dir,config,signer, ct, export_compartments=[], export_regions=[]): cd3file = inputfile if ('.xls' not in cd3file): print("\nAcceptable cd3 format: .xlsx") exit() - - global importCommands,importCommands_cluster, values_for_column_sddc, df, sheet_dict_sddc # declaring global variables + # declaring global variables + global importCommands,importCommands_cluster, values_for_column_sddc, df, sheet_dict_sddc,tf_or_tofu + tf_or_tofu = ct.tf_or_tofu + tf_state_list = [tf_or_tofu, "state", "list"] sheetName= "SDDCs" sheetNameNetwork = "SDDCs-Network" @@ -51,23 +54,29 @@ def export_sddc(inputfile, outdir, service_dir,config,signer, ct, export_compart print("Tabs- SDDCs and SDDCs-Network will be overwritten during this export process!!!\n") # Create of .sh file - resource = 'tf_import_' + sheetName.lower() - file_name = 'tf_import_commands_' + sheetName.lower() + '_nonGF.sh' + resource = 'import_' + sheetName.lower() + file_name = 'import_commands_' + sheetName.lower() + '.sh' + total_resources=0 + + # Create backups for reg in export_regions: - ## Create of .sh file for sddc script_file = f'{outdir}/{reg}/{service_dir}/' + file_name if (os.path.exists(script_file)): - commonTools.backup_file(outdir + "/" + reg+"/"+service_dir, resource, file_name) - importCommands[reg] = open(script_file, "w") - importCommands[reg].write("#!/bin/bash") - importCommands[reg].write("\n") - importCommands[reg].write("terraform init") + commonTools.backup_file(outdir + "/" + reg + "/" + service_dir, resource, file_name) + importCommands[reg] = '' for reg in export_regions: var_data[reg] = "" script_file = f'{outdir}/{reg}/{service_dir}/' + file_name - importCommands[reg].write("\n######### Writing import for SDDC #########\n") config.__setitem__("region", ct.region_dict[reg]) + state = {'path': f'{outdir}/{reg}/{service_dir}', 'resources': []} + try: + byteOutput = sp.check_output(tf_state_list, cwd=state["path"], stderr=sp.DEVNULL) + output = byteOutput.decode('UTF-8').rstrip() + for item in output.split('\n'): + state["resources"].append(item.replace("\"", "\\\"")) + except Exception as e: + pass sddc_client = oci.ocvp.SddcClient(config=config, retry_strategy=oci.retry.DEFAULT_RETRY_STRATEGY,signer=signer) sddc_cluster_client = oci.ocvp.ClusterClient(config=config, retry_strategy=oci.retry.DEFAULT_RETRY_STRATEGY,signer=signer) vnc = VirtualNetworkClient(config=config, retry_strategy=oci.retry.DEFAULT_RETRY_STRATEGY,signer=signer) @@ -104,18 +113,18 @@ def export_sddc(inputfile, outdir, service_dir,config,signer, ct, export_compart key_name = commonTools.check_tf_variable(sddc.display_name) ssh_key = json.dumps(sddc.ssh_authorized_keys) sddc_keys[key_name] = ssh_key - - importCommands[reg].write( - "\nterraform import \"module.sddcs[\\\"" + tf_name + "\\\"].oci_ocvp_sddc.sddc\" " + sddc.id) + tf_resource = f'module.sddcs[\\"{tf_name}\\"].oci_ocvp_sddc.sddc' + if tf_resource not in state["resources"]: + importCommands[reg] += f'\n{tf_or_tofu} import "{tf_resource}" {sddc.id}' elif sddc_cluster.vsphere_type == "WORKLOAD": sddc_network = sddc_cluster_data.network_configuration sddc_datastores = sddc_cluster_data.datastores tf_name = commonTools.check_tf_variable( sddc.display_name + "--" + sddc_cluster_data.display_name) - - importCommands[reg].write( - "\nterraform import \"module.sddc-clusters[\\\"" + tf_name + "\\\"].oci_ocvp_cluster.sddc_cluster\" " + sddc_cluster.id) + tf_resource = f'module.sddc-clusters[\\"{tf_name}\\"].oci_ocvp_cluster.sddc_cluster' + if tf_resource not in state["resources"]: + importCommands[reg] += f'\n{tf_or_tofu} import "{tf_resource}" {sddc_cluster.id}' if 'Standard' in ( sddc_init_config.initial_host_shape_name if sddc_cluster.vsphere_type == "MANAGEMENT" else sddc_cluster.initial_host_shape_name): @@ -170,12 +179,20 @@ def export_sddc(inputfile, outdir, service_dir,config,signer, ct, export_compart elif col_header == 'SSH Key Var Name': values_for_column_sddc[col_header].append( key_name if sddc_cluster.vsphere_type == "MANAGEMENT" else "") - elif col_header == "Provisioning Subnet": + elif col_header == "Network Details": subnet_id = sddc_network.provisioning_subnet_id subnet_info = vnc.get_subnet(subnet_id) sub_name = subnet_info.data.display_name vcn_name = vnc.get_vcn(subnet_info.data.vcn_id).data.display_name - values_for_column_sddc[col_header].append(vcn_name + "_" + sub_name) + + ntk_compartment_id = vnc.get_vcn(subnet_info.data.vcn_id).data.compartment_id # compartment-id + network_compartment_name = ntk_compartment_name + for comp_name, comp_id in ct.ntk_compartment_ids.items(): + if comp_id == ntk_compartment_id: + network_compartment_name = comp_name + + vplussubnet = network_compartment_name + "@" + vcn_name + "::" + sub_name + values_for_column_sddc[col_header].append(vplussubnet) elif col_header == "NSX Edge Uplink1 VLAN": vlan_id = sddc_network.nsx_edge_uplink1_vlan_id values_for_column_sddc[col_header].append(vnc.get_vlan(vlan_id).data.display_name) @@ -241,9 +258,12 @@ def export_sddc(inputfile, outdir, service_dir,config,signer, ct, export_compart with open(file, "w") as f: f.write(var_data[reg]) - with open(script_file, 'a') as importCommands[reg]: - importCommands[reg].write('\n\nterraform plan\n') + init_commands = f'\n#!/bin/bash\n{tf_or_tofu} init\n######### Writing import for SDDC #########\n' + if importCommands[reg] != "": + importCommands[reg] += f'\n{tf_or_tofu} plan\n' + with open(script_file, 'a') as importCommandsfile: + importCommandsfile.write(init_commands + importCommands[reg]) commonTools.write_to_cd3(values_for_column_sddc, cd3file, sheetName) commonTools.write_to_cd3(values_for_column_sddc, cd3file, sheetNameNetwork) - print("{0} SDDC Cluster Details exported into CD3.\n".format(len(values_for_column_sddc["Region"]))) + print("{0} SDDC Clusters exported into CD3.\n".format(len(values_for_column_sddc["Region"]))) diff --git a/cd3_automation_toolkit/Security/Firewall/export_firewall_nonGreenField.py b/cd3_automation_toolkit/Security/Firewall/export_firewall_nonGreenField.py index f7b5b9a6e..e830e4641 100644 --- a/cd3_automation_toolkit/Security/Firewall/export_firewall_nonGreenField.py +++ b/cd3_automation_toolkit/Security/Firewall/export_firewall_nonGreenField.py @@ -10,6 +10,7 @@ import sys import oci import os +import subprocess as sp from oci.network_firewall import NetworkFirewallClient from oci.core.virtual_network_client import VirtualNetworkClient @@ -21,11 +22,13 @@ oci_obj_names = {} AD = lambda ad: "AD1" if ("AD-1" in ad or "ad-1" in ad) else ("AD2" if ("AD-2" in ad or "ad-2" in ad) else ("AD3" if ("AD-3" in ad or "ad-3" in ad) else " NULL")) -def print_firewall(region, ct, values_for_column_fw, fws, fw_compartment_name, vcn, fw): +def print_firewall(region, ct, values_for_column_fw, fws, fw_compartment_name, vcn, fw,state): for eachfw in fws.data: fw_display_name = eachfw.display_name tf_name = commonTools.check_tf_variable(fw_display_name) - importCommands[reg].write("\nterraform import \"module.firewalls[\\\"" + str(tf_name) + "\\\"].oci_network_firewall_network_firewall.network_firewall\" "+eachfw.id) + tf_resource = f'module.firewalls[\\"{str(tf_name)}\\"].oci_network_firewall_network_firewall.network_firewall' + if tf_resource not in state["resources"]: + importCommands[reg] += f'\n{tf_or_tofu} import "{tf_resource}" {eachfw.id}' # Fetch subnet and Compartment name comp_done_ids = [] subnet_ocid = eachfw.subnet_id @@ -110,8 +113,9 @@ def export_firewall(inputfile, _outdir, service_dir, config, signer, ct, export_ global values_for_column_fwpolicy global sheet_dict_fwpolicy global sheet_dict_fwaddress - global listener_to_cd3 - + global listener_to_cd3,tf_or_tofu + tf_or_tofu = ct.tf_or_tofu + tf_state_list = [tf_or_tofu, "state", "list"] cd3file = inputfile if ('.xls' not in cd3file): @@ -127,25 +131,29 @@ def export_firewall(inputfile, _outdir, service_dir, config, signer, ct, export_ print("Tabs- Firewall will be overwritten during export process!!!\n") # Create backups - resource = 'tf_import_' + sheetName.lower() - file_name = 'tf_import_commands_' + sheetName.lower() + '_nonGF.sh' + resource = 'import_' + sheetName.lower() + file_name = 'import_commands_' + sheetName.lower() + '.sh' + + # Create backups for reg in export_regions: script_file = f'{outdir}/{reg}/{service_dir}/' + file_name - if (os.path.exists(script_file)): - commonTools.backup_file(outdir + "/" + reg + "/" + service_dir, resource, - file_name) - importCommands[reg] = open(script_file, "w") - importCommands[reg].write("#!/bin/bash") - importCommands[reg].write("\n") - importCommands[reg].write("terraform init") + commonTools.backup_file(outdir + "/" + reg + "/" + service_dir, resource, file_name) + importCommands[reg] = '' # Fetch Network firewall Policy Details print("\nFetching details of Network Firewall...") for reg in export_regions: - importCommands[reg].write("\n\n######### Writing import for Network Firewall Objects #########\n\n") config.__setitem__("region", ct.region_dict[reg]) + state = {'path': f'{outdir}/{reg}/{service_dir}', 'resources': []} + try: + byteOutput = sp.check_output(tf_state_list, cwd=state["path"], stderr=sp.DEVNULL) + output = byteOutput.decode('UTF-8').rstrip() + for item in output.split('\n'): + state["resources"].append(item.replace("\"", "\\\"")) + except Exception as e: + pass fw = NetworkFirewallClient(config=config, retry_strategy=oci.retry.DEFAULT_RETRY_STRATEGY,signer=signer) vcn = VirtualNetworkClient(config=config, retry_strategy=oci.retry.DEFAULT_RETRY_STRATEGY,signer=signer) @@ -157,14 +165,17 @@ def export_firewall(inputfile, _outdir, service_dir, config, signer, ct, export_ fws = oci.pagination.list_call_get_all_results(fw.list_network_firewalls, compartment_id=ct.ntk_compartment_ids[compartment_name], lifecycle_state="ACTIVE") # fwpolicies = oci.pagination.list_call_get_all_results(fwpolicy.list_network_firewall_policies,compartment_id=ct.ntk_compartment_ids[compartment_name],lifecycle_state = "ACTIVE") - values_for_column_fw = print_firewall(region, ct, values_for_column_fw, fws, compartment_name, vcn, fw) + values_for_column_fw = print_firewall(region, ct, values_for_column_fw, fws, compartment_name, vcn, fw,state) - commonTools.write_to_cd3(values_for_column_fw, cd3file, sheetName) - # commonTools.write_to_cd3(values_for_column_bss, cd3file, "NLB-BackendSets-BackendServers") - - print("Firewalls exported to CD3\n") - # writing data + # writing data + init_commands = f'\n######### Writing import for Network Firewall Objects #########\n\n#!/bin/bash\n{tf_or_tofu} init' for reg in export_regions: script_file = f'{outdir}/{reg}/{service_dir}/' + file_name - with open(script_file, 'a') as importCommands[reg]: - importCommands[reg].write('\n\nterraform plan\n') \ No newline at end of file + if importCommands[reg] != "": + importCommands[reg] += f'\n{tf_or_tofu} plan\n' + with open(script_file, 'a') as importCommandsfile: + importCommandsfile.write(init_commands + importCommands[reg]) + + commonTools.write_to_cd3(values_for_column_fw, cd3file, sheetName) + print("{0} Firewalls exported into CD3.\n".format(len(values_for_column_fw["Region"]))) + diff --git a/cd3_automation_toolkit/Security/Firewall/export_firewallpolicy_nonGreenField.py b/cd3_automation_toolkit/Security/Firewall/export_firewallpolicy_nonGreenField.py index a84b4c4e3..3fbcbfc1c 100644 --- a/cd3_automation_toolkit/Security/Firewall/export_firewallpolicy_nonGreenField.py +++ b/cd3_automation_toolkit/Security/Firewall/export_firewallpolicy_nonGreenField.py @@ -16,18 +16,18 @@ from oci.key_management import KmsVaultClient from oci.identity import IdentityClient import time +import subprocess as sp from oci.network_load_balancer import NetworkLoadBalancerClient sys.path.append(os.getcwd() + "/..") from commonTools import * -importCommands = {} +importCommands,importCommands_nfp,importCommands_nfao,importCommands_ulo,importCommands_slo,importCommands_alo,importCommands_sro,importCommands_mso,importCommands_dpo,importCommands_dro,importCommands_fpo = {},{},{},{},{},{},{},{},{},{},{} oci_obj_names = {} -def print_firewall_policy(region, ct, values_for_column_fwpolicy, fwpolicies, fwpolicy_compartment_name): +def print_firewall_policy(region, ct, values_for_column_fwpolicy, fwpolicies, fwpolicy_compartment_name,state): if not clone: - importCommands[reg].write("\n\n######### Writing import for Network firewall Policy #########\n\n") print("Exporting Policy details for " + region) for eachfwpolicy in fwpolicies: fwpolicy_display_name = eachfwpolicy.display_name @@ -35,7 +35,9 @@ def print_firewall_policy(region, ct, values_for_column_fwpolicy, fwpolicies, fw fwpolicy_display_name = target_pol[src_pol.index(fwpolicy_display_name)] else: tf_name = commonTools.check_tf_variable(fwpolicy_display_name) - importCommands[reg].write("\nterraform import \"module.policies[\\\"" + str(tf_name) + "\\\"].oci_network_firewall_network_firewall_policy.network_firewall_policy\" "+eachfwpolicy.id) + tf_resource = f'module.policies[\\"{str(tf_name)}\\"].oci_network_firewall_network_firewall_policy.network_firewall_policy' + if tf_resource not in state["resources"]: + importCommands_nfp[reg] += f'\n{tf_or_tofu} import "{tf_resource}" {eachfwpolicy.id}' for col_header in values_for_column_fwpolicy: if col_header == 'Region': @@ -51,9 +53,8 @@ def print_firewall_policy(region, ct, values_for_column_fwpolicy, fwpolicies, fw return values_for_column_fwpolicy -def print_firewall_address(region, ct, values_for_column_fwaddress, fwpolicies, fwpolicy): +def print_firewall_address(region, ct, values_for_column_fwaddress, fwpolicies, fwclient,state): if not clone: - importCommands[reg].write("\n\n######### Writing import for Network firewall Address Objects #########\n\n") print("Exporting Address-list details " + region) for policy in fwpolicies: policy_id = policy.id @@ -62,18 +63,16 @@ def print_firewall_address(region, ct, values_for_column_fwaddress, fwpolicies, addpolicy_display_name = target_pol[src_pol.index(addpolicy_display_name)] addpolicy_tf_name = commonTools.check_tf_variable(addpolicy_display_name) - fwaddresslist = oci.pagination.list_call_get_all_results(fwpolicy.list_address_lists, policy_id) + fwaddresslist = oci.pagination.list_call_get_all_results(fwclient.list_address_lists, policy_id) addresslist_info = fwaddresslist.data - #importCommands[reg].write("\nterraform import \"module.address_list[\\\"" + str(addpolicy_tf_name) + "_" + str(address_tf_name) + "\\\"].oci_network_firewall_network_firewall_policy_address_list.network_firewall_policy_address_list\" networkFirewallPolicies/" + policy_id + "/addressLists/" + address_display_name) - for add in addresslist_info: - address_info = fwpolicy.get_address_list(add.parent_resource_id, add.name).data.addresses + address_info = fwclient.get_address_list(add.parent_resource_id, add.name).data.addresses address_display_name = add.name address_tf_name = commonTools.check_tf_variable(address_display_name) - if not clone: - importCommands[reg].write("\nterraform import \"module.address_lists[\\\"" + str(addpolicy_tf_name) + "_" + str(address_tf_name) + "\\\"].oci_network_firewall_network_firewall_policy_address_list.network_firewall_policy_address_list\" networkFirewallPolicies/" + policy_id + "/addressLists/" + address_display_name) - + tf_resource = f'module.address_lists[\\"{str(addpolicy_tf_name)}_{str(address_tf_name)}\\"].oci_network_firewall_network_firewall_policy_address_list.network_firewall_policy_address_list' + if not clone and tf_resource not in state["resources"]: + importCommands_nfao[reg] += f'\n{tf_or_tofu} import "{tf_resource}" networkFirewallPolicies/{policy_id}/addressLists/{address_display_name}' address_detail = "" for address in address_info: @@ -98,9 +97,8 @@ def print_firewall_address(region, ct, values_for_column_fwaddress, fwpolicies, return values_for_column_fwaddress -def print_firewall_urllist(region, ct, values_for_column_fwurllist, fwpolicies, fwpolicy): +def print_firewall_urllist(region, ct, values_for_column_fwurllist, fwpolicies, fwclient,state): if not clone: - importCommands[reg].write("\n\n######### Writing import for Network firewall url list Objects #########\n\n") print("Exporting Url-list details " + region) for urlpolicy in fwpolicies: urlpolicy_id = urlpolicy.id @@ -108,14 +106,16 @@ def print_firewall_urllist(region, ct, values_for_column_fwurllist, fwpolicies, if clone: urlpolicy_display_name = target_pol[src_pol.index(urlpolicy_display_name)] urlpolicy_tf_name = commonTools.check_tf_variable(urlpolicy_display_name) - fwurllists = oci.pagination.list_call_get_all_results(fwpolicy.list_url_lists, urlpolicy_id) + fwurllists = oci.pagination.list_call_get_all_results(fwclient.list_url_lists, urlpolicy_id) urllist_info = fwurllists.data for url in urllist_info: - url_info = fwpolicy.get_url_list(url.parent_resource_id, url.name).data.urls + url_info = fwclient.get_url_list(url.parent_resource_id, url.name).data.urls url_display_name = url.name url_tf_name = commonTools.check_tf_variable(url_display_name) - if not clone: - importCommands[reg].write("\nterraform import \"module.url_lists[\\\"" + str(urlpolicy_tf_name) + "_" + str(url_tf_name) + "\\\"].oci_network_firewall_network_firewall_policy_url_list.network_firewall_policy_url_list\" networkFirewallPolicies/" + urlpolicy_id + "/urlLists/" + url_display_name) + tf_resource = f'module.url_lists[\\"{str(urlpolicy_tf_name)}_{str(url_tf_name)}\\"].oci_network_firewall_network_firewall_policy_url_list.network_firewall_policy_url_list' + if not clone and tf_resource not in state["resources"]: + importCommands_ulo[ + reg] += f'\n{tf_or_tofu} import "{tf_resource}" networkFirewallPolicies/{urlpolicy_id}/urlLists/{url_display_name}' a = url_info url_detail = "" for b in a: @@ -137,9 +137,8 @@ def print_firewall_urllist(region, ct, values_for_column_fwurllist, fwpolicies, return values_for_column_fwurllist -def print_firewall_servicelist(region, ct, values_for_column_fwservicelist, fwpolicies, fwpolicy): +def print_firewall_servicelist(region, ct, values_for_column_fwservicelist, fwpolicies, fwclient,state): if not clone: - importCommands[reg].write("\n\n######### Writing import for Network firewall service list Objects #########\n\n") print("Exporting Service and Service-list details " + region) for servicelistpolicy in fwpolicies: @@ -148,28 +147,32 @@ def print_firewall_servicelist(region, ct, values_for_column_fwservicelist, fwpo if clone: servicelistpolicy_display_name = target_pol[src_pol.index(servicelistpolicy_display_name)] servicelistpolicy_tf_name = commonTools.check_tf_variable(servicelistpolicy_display_name) - fwservicelists = oci.pagination.list_call_get_all_results(fwpolicy.list_service_lists, servicelistpolicy_id) + fwservicelists = oci.pagination.list_call_get_all_results(fwclient.list_service_lists, servicelistpolicy_id) servicelist_info = fwservicelists.data service_seen_so_far = set() for service in servicelist_info: - service_info = fwpolicy.get_service_list(service.parent_resource_id, service.name).data.services + service_info = fwclient.get_service_list(service.parent_resource_id, service.name).data.services service_display_name = service.name service_tf_name = commonTools.check_tf_variable(service_display_name) - if not clone: - importCommands[reg].write("\nterraform import \"module.service_lists[\\\"" + str(servicelistpolicy_tf_name) + "_" + str(service_display_name) + "\\\"].oci_network_firewall_network_firewall_policy_service_list.network_firewall_policy_service_list\" networkFirewallPolicies/" + servicelistpolicy_id + "/serviceLists/" + service_display_name) + tf_resource = f'module.service_lists[\\"{str(servicelistpolicy_tf_name)}_{str(service_display_name)}\\"].oci_network_firewall_network_firewall_policy_service_list.network_firewall_policy_service_list' + if not clone and tf_resource not in state["resources"]: + importCommands_slo[ + reg] += f'\n{tf_or_tofu} import "{tf_resource}" networkFirewallPolicies/{servicelistpolicy_id}/serviceLists/{service_display_name}' service_detail = "" for eachservice in service_info: service_seen_so_far.add(eachservice) - servicelist = fwpolicy.get_service(service.parent_resource_id, eachservice).data + servicelist = fwclient.get_service(service.parent_resource_id, eachservice).data servicetype = servicelist.type port_detail = "" servicename = servicelist.name servicename_tf =commonTools.check_tf_variable(servicename) - if not clone: - importCommands[reg].write("\nterraform import \"module.services[\\\"" + str(servicelistpolicy_tf_name) + "_" + str(servicename_tf) + "\\\"].oci_network_firewall_network_firewall_policy_service.network_firewall_policy_service\" networkFirewallPolicies/" + servicelistpolicy_id + "/services/" + servicename) + tf_resource = f'module.services[\\"{str(servicelistpolicy_tf_name)}_{str(servicename_tf)}\\"].oci_network_firewall_network_firewall_policy_service.network_firewall_policy_service' + if not clone and tf_resource not in state["resources"]: + importCommands_slo[ + reg] += f'\n{tf_or_tofu} import "{tf_resource}" networkFirewallPolicies/{servicelistpolicy_id}/services/{servicename}' for svc in servicelist.port_ranges: port_detail = port_detail + "," + str(svc.minimum_port) + "-" + str(svc.maximum_port) if (port_detail != ""): @@ -193,7 +196,7 @@ def print_firewall_servicelist(region, ct, values_for_column_fwservicelist, fwpo values_for_column_fwservicelist = commonTools.export_tags(servicelistpolicy, col_header,values_for_column_fwservicelist) ## Fetch services without Lists - fwservices = oci.pagination.list_call_get_all_results(fwpolicy.list_services,servicelistpolicy_id) + fwservices = oci.pagination.list_call_get_all_results(fwclient.list_services,servicelistpolicy_id) services = fwservices.data service_detail = "" for service in services: @@ -202,10 +205,12 @@ def print_firewall_servicelist(region, ct, values_for_column_fwservicelist, fwpo if service.name in service_seen_so_far: continue - service_data = fwpolicy.get_service(service.parent_resource_id, service.name).data + service_data = fwclient.get_service(service.parent_resource_id, service.name).data service_tf_name = commonTools.check_tf_variable(service_display_name) - if not clone: - importCommands[reg].write("\nterraform import \"module.services[\\\"" + str(servicelistpolicy_tf_name) + "_" + str(service_tf_name) + "\\\"].oci_network_firewall_network_firewall_policy_service.network_firewall_policy_service\" networkFirewallPolicies/" + servicelistpolicy_id + "/services/" + service_display_name) + tf_resource = f'module.services[\\"{str(servicelistpolicy_tf_name)}_{str(service_tf_name)}\\"].oci_network_firewall_network_firewall_policy_service.network_firewall_policy_service' + if not clone and tf_resource not in state["resources"]: + importCommands_slo[ + reg] += f'\n{tf_or_tofu} import "{tf_resource}" networkFirewallPolicies/{servicelistpolicy_id}/services/{service_display_name}' port_detail = "" for svc_port_range in service_data.port_ranges: @@ -232,9 +237,8 @@ def print_firewall_servicelist(region, ct, values_for_column_fwservicelist, fwpo return values_for_column_fwservicelist -def print_firewall_applist(region, ct, values_for_column_fwapplist, fwpolicies, fwpolicy): +def print_firewall_applist(region, ct, values_for_column_fwapplist, fwpolicies, fwclient,state): if not clone: - importCommands[reg].write("\n\n######### Writing import for Network firewall application list Objects #########\n\n") print("Exporting Application and Application-list details " + region) for applistpolicy in fwpolicies: applistpolicy_id = applistpolicy.id @@ -242,26 +246,31 @@ def print_firewall_applist(region, ct, values_for_column_fwapplist, fwpolicies, if clone: applistpolicy_display_name = target_pol[src_pol.index(applistpolicy_display_name)] applistpolicy_tf_name = commonTools.check_tf_variable(applistpolicy_display_name) - fwapplists = oci.pagination.list_call_get_all_results(fwpolicy.list_application_groups, applistpolicy_id) + fwapplists = oci.pagination.list_call_get_all_results(fwclient.list_application_groups, applistpolicy_id) applist_info = fwapplists.data app_seen_so_far = set() for application in applist_info: - application_info = fwpolicy.get_application_group(application.parent_resource_id, application.name).data.apps + application_info = fwclient.get_application_group(application.parent_resource_id, application.name).data.apps application_display_name = application.name application_tf_name = commonTools.check_tf_variable(application_display_name) - if not clone: - importCommands[reg].write("\nterraform import \"module.application_groups[\\\"" + str(applistpolicy_tf_name) + "_" + str(application_tf_name) + "\\\"].oci_network_firewall_network_firewall_policy_application_group.network_firewall_policy_application_group\" networkFirewallPolicies/" + applistpolicy_id + "/applicationGroups/" + application_display_name) + tf_resource = f'module.application_groups[\\"{str(applistpolicy_tf_name)}_{str(application_tf_name)}\\"].oci_network_firewall_network_firewall_policy_application_group.network_firewall_policy_application_group' + if not clone and tf_resource not in state["resources"]: + importCommands_alo[ + reg] += f'\n{tf_or_tofu} import "{tf_resource}" networkFirewallPolicies/{applistpolicy_id}/applicationGroups/{application_display_name}' application_detail = "" for eachapplication in application_info: - applist = fwpolicy.get_application(application.parent_resource_id, eachapplication).data + applist = fwclient.get_application(application.parent_resource_id, eachapplication).data applicationname = applist.name app_seen_so_far.add(eachapplication) applicationname_tf = commonTools.check_tf_variable(applicationname) - if not clone: - importCommands[reg].write("\nterraform import \"module.applications[\\\"" + str(applistpolicy_tf_name) + "_" + str(applicationname_tf) + "\\\"].oci_network_firewall_network_firewall_policy_application.network_firewall_policy_application\" networkFirewallPolicies/" + applistpolicy_id + "/applications/" + applicationname) + tf_resource = f'module.applications[\\"{str(applistpolicy_tf_name)}_{str(applicationname_tf)}\\"].oci_network_firewall_network_firewall_policy_application.network_firewall_policy_application' + if not clone and tf_resource not in state["resources"]: + importCommands_alo[ + reg] += f'\n{tf_or_tofu} import "{tf_resource}" networkFirewallPolicies/{applistpolicy_id}/applications/{applicationname}' + if applist.icmp_code != None: application_detail = application_detail + "\n" + applist.name + "::" + applist.type + "::" + str(applist.icmp_type) + "::" + str(applist.icmp_code) else: @@ -284,19 +293,19 @@ def print_firewall_applist(region, ct, values_for_column_fwapplist, fwpolicies, values_for_column_fwapplist = commonTools.export_tags(applistpolicy, col_header,values_for_column_fwapplist) ## Fetch apps without Lists - fwapps = oci.pagination.list_call_get_all_results(fwpolicy.list_applications, applistpolicy_id) + fwapps = oci.pagination.list_call_get_all_results(fwclient.list_applications, applistpolicy_id) apps = fwapps.data application_detail = "" for app in apps: app_display_name = app.name if app.name in app_seen_so_far: continue - app_data = fwpolicy.get_application(app.parent_resource_id, app.name).data + app_data = fwclient.get_application(app.parent_resource_id, app.name).data app_tf_name = commonTools.check_tf_variable(app_display_name) - if not clone: - importCommands[reg].write( - "\nterraform import \"module.applications[\\\"" + str(applistpolicy_tf_name) + "_" + str( - app_tf_name) + "\\\"].oci_network_firewall_network_firewall_policy_application.network_firewall_policy_application\" networkFirewallPolicies/" + applistpolicy_id + "/applications/" + app_display_name) + tf_resource = f'module.applications[\\"{str(applistpolicy_tf_name)}_{str(app_tf_name)}\\"].oci_network_firewall_network_firewall_policy_application.network_firewall_policy_application' + if not clone and tf_resource not in state["resources"]: + importCommands_alo[ + reg] += f'\n{tf_or_tofu} import "{tf_resource}" networkFirewallPolicies/{applistpolicy_id}/applications/{app_display_name}' if app_data.icmp_code != None: application_detail = application_detail + "\n" + app.name + "::" + app.type + "::" + str( @@ -323,9 +332,8 @@ def print_firewall_applist(region, ct, values_for_column_fwapplist, fwpolicies, return values_for_column_fwapplist -def print_firewall_secrules(region, ct, values_for_column_fwsecrules, fwpolicies, fwpolicy): +def print_firewall_secrules(region, ct, values_for_column_fwsecrules, fwpolicies, fwclient,state): if not clone: - importCommands[reg].write("\n\n######### Writing import for Network firewall Security Rules Objects #########\n\n") print("Exporting Security rules details " + region) for secrulespolicy in fwpolicies: secrulespolicy_id = secrulespolicy.id @@ -333,15 +341,18 @@ def print_firewall_secrules(region, ct, values_for_column_fwsecrules, fwpolicies if clone: secrulespolicy_display_name = target_pol[src_pol.index(secrulespolicy_display_name)] secrulespolicy_tf_name = commonTools.check_tf_variable(secrulespolicy_display_name) - fwsecrules = oci.pagination.list_call_get_all_results(fwpolicy.list_security_rules,secrulespolicy_id) + fwsecrules = oci.pagination.list_call_get_all_results(fwclient.list_security_rules,secrulespolicy_id) secrules_info = fwsecrules.data #print(secrules_info) for rules in secrules_info: - rule_info = fwpolicy.get_security_rule(rules.parent_resource_id, rules.name).data + rule_info = fwclient.get_security_rule(rules.parent_resource_id, rules.name).data rules_display_name = rules.name rules_tf_name = commonTools.check_tf_variable(rules_display_name) - if not clone: - importCommands[reg].write("\nterraform import \"module.security_rules[\\\"" + str(secrulespolicy_tf_name) + "_" + str(rules_tf_name) + "\\\"].oci_network_firewall_network_firewall_policy_security_rule.network_firewall_policy_security_rule\" networkFirewallPolicies/" + secrulespolicy_id + "/securityRules/" + rules_display_name) + tf_resource = f'module.security_rules[\\"{str(secrulespolicy_tf_name)}_{str(rules_tf_name)}\\"].oci_network_firewall_network_firewall_policy_security_rule.network_firewall_policy_security_rule' + if not clone and tf_resource not in state["resources"]: + importCommands_sro[ + reg] += f'\n{tf_or_tofu} import "{tf_resource}" networkFirewallPolicies/{secrulespolicy_id}/securityRules/{rules_display_name}' + rsrc_detail = "" rdst_detail = "" rapp_detail = "" @@ -413,9 +424,8 @@ def print_firewall_secrules(region, ct, values_for_column_fwsecrules, fwpolicies values_for_column_fwsecrules = commonTools.export_tags(secrulespolicy, col_header,values_for_column_fwsecrules) return values_for_column_fwsecrules -def print_firewall_secret(region, ct, values_for_column_fwsecret, fwpolicies, fwpolicy, vault, compartment, kmsvault): +def print_firewall_secret(region, ct, values_for_column_fwsecret, fwpolicies, fwclient, vault, compartment, kmsvault,state): if not clone: - importCommands[reg].write("\n\n######### Writing import for Network firewall Mapped Secret Objects #########\n\n") print("Exporting Mapped secret details " + region) for secretpolicy in fwpolicies: secretpolicy_id = secretpolicy.id @@ -423,18 +433,20 @@ def print_firewall_secret(region, ct, values_for_column_fwsecret, fwpolicies, fw if clone: secretpolicy_display_name = target_pol[src_pol.index(secretpolicy_display_name)] secretpolicy_tf_name = commonTools.check_tf_variable(secretpolicy_display_name) - fwsecrets = oci.pagination.list_call_get_all_results(fwpolicy.list_mapped_secrets, secretpolicy_id) + fwsecrets = oci.pagination.list_call_get_all_results(fwclient.list_mapped_secrets, secretpolicy_id) secret_info = fwsecrets.data for key in secret_info: - key_info = fwpolicy.get_mapped_secret(key.parent_resource_id, key.name).data + key_info = fwclient.get_mapped_secret(key.parent_resource_id, key.name).data secretdisplay_name = key.name secretdisplay_tf_name = commonTools.check_tf_variable(secretdisplay_name) vault_secret = vault.get_secret(key_info.vault_secret_id).data kmsvault_name = kmsvault.get_vault(vault_secret.vault_id).data vault_secret_name = kmsvault_name.display_name + '::' + vault_secret.secret_name vault_secret_compartment_detail = compartment.get_compartment(vault_secret.compartment_id).data.name - if not clone: - importCommands[reg].write("\nterraform import \"module.secrets[\\\"" + str(secretpolicy_tf_name) + "_" + str(secretdisplay_tf_name) + "\\\"].oci_network_firewall_network_firewall_policy_mapped_secret.network_firewall_policy_mapped_secret\" networkFirewallPolicies/" + secretpolicy_id + "/mappedSecrets/" + secretdisplay_name) + tf_resource = f'module.secrets[\\"{str(secretpolicy_tf_name)}_{str(secretdisplay_tf_name)}\\"].oci_network_firewall_network_firewall_policy_mapped_secret.network_firewall_policy_mapped_secret' + if not clone and tf_resource not in state["resources"]: + importCommands_mso[ + reg] += f'\n{tf_or_tofu} import "{tf_resource}" networkFirewallPolicies/{secretpolicy_id}/mappedSecrets/{secretdisplay_name}' for col_header in values_for_column_fwsecret: if col_header == 'Region': @@ -458,9 +470,8 @@ def print_firewall_secret(region, ct, values_for_column_fwsecret, fwpolicies, fw return values_for_column_fwsecret -def print_firewall_decryptprofile(region, ct, values_for_column_fwdecryptprofile, fwpolicies, fwpolicy): +def print_firewall_decryptprofile(region, ct, values_for_column_fwdecryptprofile, fwpolicies, fwclient,state): if not clone: - importCommands[reg].write("\n\n######### Writing import for Network firewall Decrypt profile Objects #########\n\n") print("Exporting Decryption Profile details " + region) for decryptionprofile in fwpolicies: decryptionprofile_id = decryptionprofile.id @@ -468,14 +479,17 @@ def print_firewall_decryptprofile(region, ct, values_for_column_fwdecryptprofile if clone: decryptionprofile_display_name = target_pol[src_pol.index(decryptionprofile_display_name)] decryptionprofile_tf_name = commonTools.check_tf_variable(decryptionprofile_display_name) - fwdcyrptionprofiles = oci.pagination.list_call_get_all_results(fwpolicy.list_decryption_profiles, decryptionprofile_id) + fwdcyrptionprofiles = oci.pagination.list_call_get_all_results(fwclient.list_decryption_profiles, decryptionprofile_id) decryptionprofile_info = fwdcyrptionprofiles.data for decryption in decryptionprofile_info: - key_info = fwpolicy.get_decryption_profile(decryption.parent_resource_id, decryption.name).data + key_info = fwclient.get_decryption_profile(decryption.parent_resource_id, decryption.name).data key_info_name = key_info.name key_info_tf_name = commonTools.check_tf_variable(key_info.name) - if not clone: - importCommands[reg].write("\nterraform import \"module.decryption_profiles[\\\"" + str(decryptionprofile_tf_name) + "_" + str(key_info_tf_name) + "\\\"].oci_network_firewall_network_firewall_policy_decryption_profile.network_firewall_policy_decryption_profile\" networkFirewallPolicies/" + decryptionprofile_id + "/decryptionProfiles/" + key_info_name) + tf_resource = f'module.decryption_profiles[\\"{str(decryptionprofile_tf_name)}_{str(key_info_tf_name)}\\"].oci_network_firewall_network_firewall_policy_decryption_profile.network_firewall_policy_decryption_profile' + if not clone and tf_resource not in state["resources"]: + importCommands_dpo[ + reg] += f'\n{tf_or_tofu} import "{tf_resource}" networkFirewallPolicies/{decryptionprofile_id}/decryptionProfiles/{key_info_name}' + if key_info.type == "SSL_INBOUND_INSPECTION": key_info1_are_certificate_extensions_restricted = "" key_info1_is_auto_include_alt_name = "" @@ -522,9 +536,8 @@ def print_firewall_decryptprofile(region, ct, values_for_column_fwdecryptprofile values_for_column_fwdecryptprofile = commonTools.export_tags(decryptionprofile, col_header,values_for_column_fwdecryptprofile) return values_for_column_fwdecryptprofile -def print_firewall_decryptrule(region, ct, values_for_column_fwdecryptrule, fwpolicies, fwpolicy): +def print_firewall_decryptrule(region, ct, values_for_column_fwdecryptrule, fwpolicies, fwclient,state): if not clone: - importCommands[reg].write("\n\n######### Writing import for Network firewall decryption Rules Objects #########\n\n") print("Exporting Decryption rules details " + region) for decryptrulepolicy in fwpolicies: decryptrulepolicy_id = decryptrulepolicy.id @@ -532,14 +545,16 @@ def print_firewall_decryptrule(region, ct, values_for_column_fwdecryptrule, fwpo if clone: decryptrulepolicy_display_name = target_pol[src_pol.index(decryptrulepolicy_display_name)] decryptrulepolicy_tf_name = commonTools.check_tf_variable(decryptrulepolicy_display_name) - fwdecrypteules = oci.pagination.list_call_get_all_results(fwpolicy.list_decryption_rules, decryptrulepolicy_id) + fwdecrypteules = oci.pagination.list_call_get_all_results(fwclient.list_decryption_rules, decryptrulepolicy_id) decrypteules_info = fwdecrypteules.data for drules in decrypteules_info: - drule_info = fwpolicy.get_decryption_rule(drules.parent_resource_id, drules.name).data + drule_info = fwclient.get_decryption_rule(drules.parent_resource_id, drules.name).data drules_display_name = drules.name drules_tf_name = commonTools.check_tf_variable(drules_display_name) - if not clone: - importCommands[reg].write("\nterraform import \"module.decryption_rules[\\\"" + str(decryptrulepolicy_tf_name) + "_" + str(drules_tf_name) + "\\\"].oci_network_firewall_network_firewall_policy_decryption_rule.network_firewall_policy_decryption_rule\" networkFirewallPolicies/" + decryptrulepolicy_id + "/decryptionRules/" + drules_display_name) + tf_resource = f'module.decryption_rules[\\"{str(decryptrulepolicy_tf_name)}_{str(drules_tf_name)}\\"].oci_network_firewall_network_firewall_policy_decryption_rule.network_firewall_policy_decryption_rule' + if not clone and tf_resource not in state["resources"]: + importCommands_dro[reg] += f'\n{tf_or_tofu} import "{tf_resource}" networkFirewallPolicies/{decryptrulepolicy_id}/decryptionRules/{drules_display_name}' + rsrc_detail = "" rdst_detail = "" if drule_info.condition.source_address != None: @@ -583,12 +598,12 @@ def print_firewall_decryptrule(region, ct, values_for_column_fwdecryptrule, fwpo elif col_header.lower() in commonTools.tagColumns: values_for_column_fwdecryptrule = commonTools.export_tags(decryptrulepolicy, col_header,values_for_column_fwdecryptrule) return values_for_column_fwdecryptrule -# Execution of the code begins here +# Execution of the code begins here def export_firewallpolicy(inputfile, _outdir, service_dir, config, signer, ct, export_compartments, export_regions, export_policies,target_policies=[],attached_policy_only="",clone_policy=False): global tf_import_cmd global sheet_dict - global importCommands + global importCommands,importCommands_nfp,importCommands_nfao,importCommands_ulo,importCommands_slo,importCommands_alo,importCommands_sro,importCommands_mso,importCommands_dpo,importCommands_dro,importCommands_fpo global values_for_vcninfo global cd3file global reg @@ -609,7 +624,9 @@ def export_firewallpolicy(inputfile, _outdir, service_dir, config, signer, ct, e global listener_to_cd3 global clone global src_pol - global target_pol + global target_pol,tf_or_tofu + tf_or_tofu = ct.tf_or_tofu + tf_state_list = [tf_or_tofu, "state", "list"] src_pol = export_policies.copy() if export_policies else [] target_pol = [] if not target_policies : @@ -650,24 +667,29 @@ def export_firewallpolicy(inputfile, _outdir, service_dir, config, signer, ct, e print("Tabs related to firewall and firewall policies will be overwritten during export process!!!\n") for reg in export_regions: - resource = 'tf_import_fwpolicy' + resource = 'import_fwpolicy' + if (os.path.exists(outdir + "/" + reg + "/" + service_dir + "/import_commands_firewallpolicy.sh")): + commonTools.backup_file(outdir + "/" + reg + "/" + service_dir, resource, "import_commands_firewallpolicy.sh") + importCommands[reg], importCommands_nfp[reg], importCommands_nfao[reg], importCommands_ulo[reg], \ + importCommands_slo[reg], importCommands_alo[reg], importCommands_sro[reg], importCommands_mso[reg], \ + importCommands_dpo[reg], importCommands_dro[reg], importCommands_fpo[ + reg] = "", "", "", "", "", "", "", "", "", "", "" - if (os.path.exists(outdir + "/" + reg + "/" + service_dir + "/tf_import_commands_firewallpolicy_nonGF.sh")): - commonTools.backup_file(outdir + "/" + reg + "/" + service_dir, resource, "tf_import_commands_firewallpolicy_nonGF.sh") - importCommands[reg] = open( - outdir + "/" + reg + "/" + service_dir + "/temppolicyfile", "w") - importCommands[reg].write("#!/bin/bash") - importCommands[reg].write("\n") - importCommands[reg].write("terraform init") - importCommands[reg].write("\n\n######### Writing import for Network firewall policy Objects #########\n\n") - # Fetch Network firewall Policy Details print("\nFetching details of Network firewall policy...") for reg in export_regions: config.__setitem__("region", ct.region_dict[reg]) - fwpolicy = NetworkFirewallClient(config=config, retry_strategy=oci.retry.DEFAULT_RETRY_STRATEGY, signer=signer) + state = {'path': f'{outdir}/{reg}/{service_dir}', 'resources': []} + try: + byteOutput = sp.check_output(tf_state_list, cwd=state["path"], stderr=sp.DEVNULL) + output = byteOutput.decode('UTF-8').rstrip() + for item in output.split('\n'): + state["resources"].append(item.replace("\"", "\\\"")) + except Exception as e: + pass + fwclient = NetworkFirewallClient(config=config, retry_strategy=oci.retry.DEFAULT_RETRY_STRATEGY, signer=signer) vault = VaultsClient(config=config, retry_strategy=oci.retry.DEFAULT_RETRY_STRATEGY,signer=signer) kmsvault = KmsVaultClient(config=config, retry_strategy=oci.retry.DEFAULT_RETRY_STRATEGY,signer=signer) compartment = IdentityClient(config=config, retry_strategy=oci.retry.DEFAULT_RETRY_STRATEGY,signer=signer) @@ -676,41 +698,36 @@ def export_firewallpolicy(inputfile, _outdir, service_dir, config, signer, ct, e for compartment_name in export_compartments: fwpolicies = [] - fw_data = oci.pagination.list_call_get_all_results(fwpolicy.list_network_firewall_policies,compartment_id=ct.ntk_compartment_ids[compartment_name], lifecycle_state="ACTIVE") - fw_data = fw_data.data - if (export_policies is not None): - for eachfwpolicy in fw_data: - policy_ocid = eachfwpolicy.id - policydata = fwpolicy.get_network_firewall_policy(network_firewall_policy_id=policy_ocid) - eachfwpolicy1 = policydata.data + fw_data = oci.pagination.list_call_get_all_results(fwclient.list_network_firewall_policies,compartment_id=ct.ntk_compartment_ids[compartment_name], lifecycle_state="ACTIVE").data + for eachfwpolicy in fw_data: + if export_policies is not None: + eachfwpolicy1 = fwclient.get_network_firewall_policy(network_firewall_policy_id=eachfwpolicy.id).data fwpolicy_display_name1 = eachfwpolicy1.display_name - if (any(e in fwpolicy_display_name1 for e in export_policies)): + if (fwpolicy_display_name1 in export_policies): if clone: - if fwpolicy_display_name1 in export_policies: - if attached_policy_only == "y": - if eachfwpolicy1.attached_network_firewall_count == 0: - print("Skipping "+str(fwpolicy_display_name1) + " as it is not attached.") - continue - print("Cloning " + str(fwpolicy_display_name1) +" to "+str(target_pol[src_pol.index(fwpolicy_display_name1)]) ) - fwpolicies.append(eachfwpolicy) + if attached_policy_only == "y": + if eachfwpolicy1.attached_network_firewall_count == 0: + print("Skipping "+str(fwpolicy_display_name1) + " as it is not attached.") + continue + print("Cloning " + str(fwpolicy_display_name1) +" to "+str(target_pol[src_pol.index(fwpolicy_display_name1)]) ) + fwpolicies.append(eachfwpolicy) continue print("Processing "+str(fwpolicy_display_name1)) fwpolicies.append(eachfwpolicy) - else: - for eachfwpolicy in fw_data: + else: fwpolicies.append(eachfwpolicy) #fwpolicies.append(data) - values_for_column_fwpolicy = print_firewall_policy(region, ct, values_for_column_fwpolicy, fwpolicies,compartment_name) - values_for_column_fwaddress = print_firewall_address(region, ct, values_for_column_fwaddress, fwpolicies, fwpolicy) - values_for_column_fwurllist = print_firewall_urllist(region, ct, values_for_column_fwurllist, fwpolicies, fwpolicy) - values_for_column_fwservicelist = print_firewall_servicelist(region, ct, values_for_column_fwservicelist, fwpolicies, fwpolicy) - values_for_column_fwapplist = print_firewall_applist(region, ct, values_for_column_fwapplist, fwpolicies, fwpolicy) - values_for_column_fwsecrules = print_firewall_secrules(region, ct, values_for_column_fwsecrules,fwpolicies, fwpolicy) - values_for_column_fwsecret = print_firewall_secret(region, ct, values_for_column_fwsecret, fwpolicies,fwpolicy, vault, compartment, kmsvault) - values_for_column_fwdecryptprofile = print_firewall_decryptprofile(region, ct,values_for_column_fwdecryptprofile,fwpolicies, fwpolicy) - values_for_column_fwdecryptrule = print_firewall_decryptrule(region, ct, values_for_column_fwdecryptrule,fwpolicies, fwpolicy) - + values_for_column_fwpolicy = print_firewall_policy(region, ct, values_for_column_fwpolicy, fwpolicies,compartment_name,state) + values_for_column_fwaddress = print_firewall_address(region, ct, values_for_column_fwaddress, fwpolicies, fwclient,state) + values_for_column_fwurllist = print_firewall_urllist(region, ct, values_for_column_fwurllist, fwpolicies, fwclient,state) + values_for_column_fwservicelist = print_firewall_servicelist(region, ct, values_for_column_fwservicelist, fwpolicies, fwclient,state) + values_for_column_fwapplist = print_firewall_applist(region, ct, values_for_column_fwapplist, fwpolicies, fwclient,state) + values_for_column_fwsecrules = print_firewall_secrules(region, ct, values_for_column_fwsecrules,fwpolicies, fwclient,state) + values_for_column_fwsecret = print_firewall_secret(region, ct, values_for_column_fwsecret, fwpolicies,fwclient, vault, compartment, kmsvault,state) + values_for_column_fwdecryptprofile = print_firewall_decryptprofile(region, ct,values_for_column_fwdecryptprofile,fwpolicies, fwclient,state) + values_for_column_fwdecryptrule = print_firewall_decryptrule(region, ct, values_for_column_fwdecryptrule,fwpolicies, fwclient,state) + print(importCommands_nfp[reg]) if clone: commonTools.write_to_cd3(values_for_column_fwpolicy, cd3file, "Firewall-Policy",append=True) commonTools.write_to_cd3(values_for_column_fwaddress, cd3file, "Firewall-Policy-AddressList",append=True) @@ -735,23 +752,24 @@ def export_firewallpolicy(inputfile, _outdir, service_dir, config, signer, ct, e print("Firewall Policies exported to CD3\n") # writing data + init_commands = f'\n######### Writing import for Network firewall policy Objects #########\n\n#!/bin/bash\n{tf_or_tofu} init' + importCommands_message = ["Policy","Address Objects","url list Objects","service list Objects","application list Objects","Security Rules Objects","Mapped Secret Objects","Decrypt profile Objects","decryption Rules Objects","policy Objects"] for reg in export_regions: - script_file = f'{outdir}/{reg}/{service_dir}/temppolicyfile' - with open(script_file, 'a') as importCommands[reg]: - importCommands[reg].write('\n\nterraform plan\n') - readfilepath = outdir + "/" + reg + "/" + service_dir + "/temppolicyfile" - writefilepath = outdir + "/" + reg + "/" + service_dir + "/tf_import_commands_firewallpolicy_nonGF.sh" - input_file = open(readfilepath, "r") - output_file = open(writefilepath, "w") - lines_seen_so_far = set() - for line in input_file: - if not line.isspace() and line not in lines_seen_so_far: - output_file.write(line) - lines_seen_so_far.add(line) - if line in ['\n', '\r\n']: - output_file.write(line) - input_file.close() - output_file.close() - os.remove(readfilepath) - #os.chmod(outdir + "/" + reg + "/" + service_dir + "/tf_import_commands_firewallpolicy_nonGF.sh", 777) + count = 0 + all_importCommands = [importCommands_nfp[reg], importCommands_nfao[reg], importCommands_ulo[reg], importCommands_slo[reg], + importCommands_alo[reg], importCommands_sro[reg], importCommands_mso[reg], importCommands_dpo[reg], + importCommands_dro[reg], importCommands_fpo[reg]] + print(importCommands_nfp[reg]) + for item in all_importCommands: + if item != "": + importCommands[reg] += f'\n\n######### Writing import for Network firewall {importCommands_message[count]} #########\n\n' + importCommands[reg] += item + count += 1 + script_file = f'{outdir}/{reg}/{service_dir}/import_commands_firewallpolicy.sh' + + if importCommands[reg] != "": + importCommands[reg] += f'\n{tf_or_tofu} plan\n' + with open(script_file, 'a') as importCommandsfile: + importCommandsfile.write(init_commands + importCommands[reg]) + diff --git a/cd3_automation_toolkit/Security/Firewall/fw_create.py b/cd3_automation_toolkit/Security/Firewall/fw_create.py index 09c2ad265..37535024a 100644 --- a/cd3_automation_toolkit/Security/Firewall/fw_create.py +++ b/cd3_automation_toolkit/Security/Firewall/fw_create.py @@ -48,6 +48,9 @@ def fw_create(inputfile, outdir, service_dir, prefix, ct): for reg in ct.all_regions: firewall_str[reg] = '' firewall_names[reg] = [] + resource = sheetName.lower() + reg_out_dir = outdir + "/" + reg + "/" + service_dir + commonTools.backup_file(reg_out_dir, resource, firewall_auto_tfvars_filename) # List of the column headers dfcolumns = df.columns.values.tolist() @@ -167,12 +170,10 @@ def fw_create(inputfile, outdir, service_dir, prefix, ct): firewall_str[region] = firewall_str[region] + firewall.render(tempStr) for reg in region_list: - resource = sheetName.lower() reg_out_dir = outdir + "/" + reg + "/" + service_dir if not os.path.exists(reg_out_dir): os.makedirs(reg_out_dir) outfile[reg] = reg_out_dir + "/" + firewall_auto_tfvars_filename - commonTools.backup_file(reg_out_dir, resource, firewall_auto_tfvars_filename) if firewall_str[reg] != '': # Generate Final String src = "##Add New firewall for " + reg.lower() + " here##" diff --git a/cd3_automation_toolkit/Security/Firewall/fwpolicy_create.py b/cd3_automation_toolkit/Security/Firewall/fwpolicy_create.py index 46d2020b6..18f97d618 100644 --- a/cd3_automation_toolkit/Security/Firewall/fwpolicy_create.py +++ b/cd3_automation_toolkit/Security/Firewall/fwpolicy_create.py @@ -49,6 +49,9 @@ def firewallpolicy_create(inputfile, outdir, service_dir, prefix, ct): for reg in ct.all_regions: policy_str[reg] = '' policy_names[reg] = [] + reg_out_dir = outdir + "/" + reg + "/" + service_dir + resource = sheetName.lower() + commonTools.backup_file(reg_out_dir, resource, policy_auto_tfvars_filename) # List of the column headers dfcolumns = df.columns.values.tolist() @@ -107,12 +110,12 @@ def firewallpolicy_create(inputfile, outdir, service_dir, prefix, ct): policy_str[region] = policy_str[region] + policy.render(tempStr) for reg in region_list: - resource = sheetName.lower() + reg_out_dir = outdir + "/" + reg + "/" + service_dir if not os.path.exists(reg_out_dir): os.makedirs(reg_out_dir) outfile[reg] = reg_out_dir + "/" + policy_auto_tfvars_filename - commonTools.backup_file(reg_out_dir, resource, policy_auto_tfvars_filename) + if policy_str[reg] != '': # Generate Final String src = "##Add New firewall policy for " + reg.lower() + " here##" diff --git a/cd3_automation_toolkit/Security/Firewall/fwpolicy_create_address.py b/cd3_automation_toolkit/Security/Firewall/fwpolicy_create_address.py index 2d493ec60..a7e90e0dc 100644 --- a/cd3_automation_toolkit/Security/Firewall/fwpolicy_create_address.py +++ b/cd3_automation_toolkit/Security/Firewall/fwpolicy_create_address.py @@ -53,6 +53,9 @@ def fwpolicy_create_address(inputfile, outdir, service_dir, prefix, ct): for reg in ct.all_regions: address_str[reg] = '' address_names[reg] = [] + resource = sheetName.lower() + reg_out_dir = outdir + "/" + reg + "/" + service_dir + commonTools.backup_file(reg_out_dir, resource, address_auto_tfvars_filename) # List of the column headers @@ -136,12 +139,11 @@ def fwpolicy_create_address(inputfile, outdir, service_dir, prefix, ct): for reg in region_list: - resource = sheetName.lower() reg_out_dir = outdir + "/" + reg + "/" + service_dir if not os.path.exists(reg_out_dir): os.makedirs(reg_out_dir) outfile[reg] = reg_out_dir + "/" + address_auto_tfvars_filename - commonTools.backup_file(reg_out_dir, resource, address_auto_tfvars_filename) + if address_str[reg] != '': # Generate Final String src = "##Add New addresses for " + reg.lower() + " here##" diff --git a/cd3_automation_toolkit/Security/Firewall/fwpolicy_create_applicationlist.py b/cd3_automation_toolkit/Security/Firewall/fwpolicy_create_applicationlist.py index 56d556f26..441b8a4df 100644 --- a/cd3_automation_toolkit/Security/Firewall/fwpolicy_create_applicationlist.py +++ b/cd3_automation_toolkit/Security/Firewall/fwpolicy_create_applicationlist.py @@ -47,6 +47,9 @@ def fwpolicy_create_applicationlist(inputfile, outdir, service_dir, prefix, ct): for reg in ct.all_regions: applicationlist_str[reg] = '' applicationlist_names[reg] = [] + reg_out_dir = outdir + "/" + reg + "/" + service_dir + resource = sheetName.lower() + commonTools.backup_file(reg_out_dir, resource, applicationlist_auto_tfvars_filename) # List of the column headers @@ -137,12 +140,11 @@ def fwpolicy_create_applicationlist(inputfile, outdir, service_dir, prefix, ct): applicationlist_str[region] = applicationlist_str[region] + applicationlist.render(tempStr) for reg in region_list: - resource = sheetName.lower() reg_out_dir = outdir + "/" + reg + "/" + service_dir if not os.path.exists(reg_out_dir): os.makedirs(reg_out_dir) outfile[reg] = reg_out_dir + "/" + applicationlist_auto_tfvars_filename - commonTools.backup_file(reg_out_dir, resource, applicationlist_auto_tfvars_filename) + if applicationlist_str[reg] != '': # Generate Final String src = "##Add New application list for " + reg.lower() + " here##" diff --git a/cd3_automation_toolkit/Security/Firewall/fwpolicy_create_apps.py b/cd3_automation_toolkit/Security/Firewall/fwpolicy_create_apps.py index 95433123b..b8811c288 100644 --- a/cd3_automation_toolkit/Security/Firewall/fwpolicy_create_apps.py +++ b/cd3_automation_toolkit/Security/Firewall/fwpolicy_create_apps.py @@ -54,6 +54,9 @@ def fwpolicy_create_apps(inputfile, outdir, service_dir, prefix, ct): apps_str[reg] = '' apps_names[reg] = [] apps_str_02[reg] = '' + reg_out_dir = outdir + "/" + reg + "/" + service_dir + resource = sheetName.lower() + commonTools.backup_file(reg_out_dir, resource, apps_auto_tfvars_filename) # List of the column headers @@ -165,12 +168,11 @@ def fwpolicy_create_apps(inputfile, outdir, service_dir, prefix, ct): apps_str_02[region] = apps_str_02[region] + apps_str[region] for reg in region_list: - resource = "firewall-policy-apps" reg_out_dir = outdir + "/" + reg + "/" + service_dir if not os.path.exists(reg_out_dir): os.makedirs(reg_out_dir) outfile[reg] = reg_out_dir + "/" + apps_auto_tfvars_filename - commonTools.backup_file(reg_out_dir, resource, apps_auto_tfvars_filename) + if apps_str_02[reg] != '': # Generate Final String src = "##Add New apps for " + reg.lower() + " here##" diff --git a/cd3_automation_toolkit/Security/Firewall/fwpolicy_create_decryptionprofile.py b/cd3_automation_toolkit/Security/Firewall/fwpolicy_create_decryptionprofile.py index a6c7d18bf..5e6f61c06 100644 --- a/cd3_automation_toolkit/Security/Firewall/fwpolicy_create_decryptionprofile.py +++ b/cd3_automation_toolkit/Security/Firewall/fwpolicy_create_decryptionprofile.py @@ -45,6 +45,9 @@ def fwpolicy_create_decryptionprofile(inputfile, outdir, service_dir, prefix, ct for reg in ct.all_regions: decryptionprofile_str[reg] = '' + reg_out_dir = outdir + "/" + reg + "/" + service_dir + resource = sheetName.lower() + commonTools.backup_file(reg_out_dir, resource, decryptionprofile_auto_tfvars_filename) # List of the column headers dfcolumns = df.columns.values.tolist() @@ -109,12 +112,11 @@ def fwpolicy_create_decryptionprofile(inputfile, outdir, service_dir, prefix, ct for reg in region_list: - resource = sheetName.lower() reg_out_dir = outdir + "/" + reg + "/" + service_dir if not os.path.exists(reg_out_dir): os.makedirs(reg_out_dir) outfile[reg] = reg_out_dir + "/" + decryptionprofile_auto_tfvars_filename - commonTools.backup_file(reg_out_dir, resource, decryptionprofile_auto_tfvars_filename) + if decryptionprofile_str[reg] != '': # Generate Final String src = "##Add New Decryption Profile for " + reg.lower() + " here##" diff --git a/cd3_automation_toolkit/Security/Firewall/fwpolicy_create_decryptrules.py b/cd3_automation_toolkit/Security/Firewall/fwpolicy_create_decryptrules.py index 08783bbba..20991bd9f 100644 --- a/cd3_automation_toolkit/Security/Firewall/fwpolicy_create_decryptrules.py +++ b/cd3_automation_toolkit/Security/Firewall/fwpolicy_create_decryptrules.py @@ -47,6 +47,9 @@ def fwpolicy_create_decryptrules(inputfile, outdir, service_dir, prefix, ct): for reg in ct.all_regions: decryptrules_str[reg] = '' decryptrules_names[reg] = [] + reg_out_dir = outdir + "/" + reg + "/" + service_dir + resource = sheetName.lower() + commonTools.backup_file(reg_out_dir, resource, decryptrules_auto_tfvars_filename) # List of the column headers @@ -161,12 +164,11 @@ def fwpolicy_create_decryptrules(inputfile, outdir, service_dir, prefix, ct): for reg in region_list: - resource = sheetName.lower() reg_out_dir = outdir + "/" + reg + "/" + service_dir if not os.path.exists(reg_out_dir): os.makedirs(reg_out_dir) outfile[reg] = reg_out_dir + "/" + decryptrules_auto_tfvars_filename - commonTools.backup_file(reg_out_dir, resource, decryptrules_auto_tfvars_filename) + if decryptrules_str[reg] != '': # Generate Final String src = "##Add New Decryption rules for " + reg.lower() + " here##" diff --git a/cd3_automation_toolkit/Security/Firewall/fwpolicy_create_secret.py b/cd3_automation_toolkit/Security/Firewall/fwpolicy_create_secret.py index b7dc7cc73..cf2247a8d 100644 --- a/cd3_automation_toolkit/Security/Firewall/fwpolicy_create_secret.py +++ b/cd3_automation_toolkit/Security/Firewall/fwpolicy_create_secret.py @@ -46,6 +46,9 @@ def fwpolicy_create_secret(inputfile, outdir, service_dir, prefix, ct): for reg in ct.all_regions: secret_str[reg] = '' + reg_out_dir = outdir + "/" + reg + "/" + service_dir + resource = sheetName.lower() + commonTools.backup_file(reg_out_dir, resource, secret_auto_tfvars_filename) # List of the column headers dfcolumns = df.columns.values.tolist() @@ -125,12 +128,11 @@ def fwpolicy_create_secret(inputfile, outdir, service_dir, prefix, ct): for reg in region_list: - resource = sheetName.lower() reg_out_dir = outdir + "/" + reg + "/" + service_dir if not os.path.exists(reg_out_dir): os.makedirs(reg_out_dir) outfile[reg] = reg_out_dir + "/" + secret_auto_tfvars_filename - commonTools.backup_file(reg_out_dir, resource, secret_auto_tfvars_filename) + if secret_str[reg] != '': # Generate Final String src = "##Add New Secrets for " + reg.lower() + " here##" diff --git a/cd3_automation_toolkit/Security/Firewall/fwpolicy_create_secrules.py b/cd3_automation_toolkit/Security/Firewall/fwpolicy_create_secrules.py index 64f608364..33fe4a81a 100644 --- a/cd3_automation_toolkit/Security/Firewall/fwpolicy_create_secrules.py +++ b/cd3_automation_toolkit/Security/Firewall/fwpolicy_create_secrules.py @@ -47,6 +47,9 @@ def fwpolicy_create_secrules(inputfile, outdir, service_dir, prefix, ct): for reg in ct.all_regions: secrules_str[reg] = '' secrules_names[reg] = [] + resource = sheetName.lower() + reg_out_dir = outdir + "/" + reg + "/" + service_dir + commonTools.backup_file(reg_out_dir, resource, secrules_auto_tfvars_filename) # List of the column headers @@ -248,12 +251,11 @@ def fwpolicy_create_secrules(inputfile, outdir, service_dir, prefix, ct): for reg in region_list: - resource = sheetName.lower() reg_out_dir = outdir + "/" + reg + "/" + service_dir if not os.path.exists(reg_out_dir): os.makedirs(reg_out_dir) outfile[reg] = reg_out_dir + "/" + secrules_auto_tfvars_filename - commonTools.backup_file(reg_out_dir, resource, secrules_auto_tfvars_filename) + if secrules_str[reg] != '': # Generate Final String src = "##Add New Security rules for " + reg.lower() + " here##" diff --git a/cd3_automation_toolkit/Security/Firewall/fwpolicy_create_service.py b/cd3_automation_toolkit/Security/Firewall/fwpolicy_create_service.py index f4c604087..aa1d20735 100644 --- a/cd3_automation_toolkit/Security/Firewall/fwpolicy_create_service.py +++ b/cd3_automation_toolkit/Security/Firewall/fwpolicy_create_service.py @@ -55,8 +55,9 @@ def fwpolicy_create_service(inputfile, outdir, service_dir, prefix, ct): service_str[reg] = '' service_names[reg] = [] service_str_02[reg] = '' - - + reg_out_dir = outdir + "/" + reg + "/" + service_dir + resource = "firewall-policy-services" + commonTools.backup_file(reg_out_dir, resource, service_auto_tfvars_filename) # List of the column headers dfcolumns = df.columns.values.tolist() region_seen_so_far = [] @@ -190,12 +191,11 @@ def fwpolicy_create_service(inputfile, outdir, service_dir, prefix, ct): #print(service_str_02[region]) for reg in region_list: - resource = "firewall-policy-services" reg_out_dir = outdir + "/" + reg + "/" + service_dir if not os.path.exists(reg_out_dir): os.makedirs(reg_out_dir) outfile[reg] = reg_out_dir + "/" + service_auto_tfvars_filename - commonTools.backup_file(reg_out_dir, resource, service_auto_tfvars_filename) + if service_str_02[reg] != '': # Generate Final String src = "##Add New service policy for " + reg.lower() + " here##" diff --git a/cd3_automation_toolkit/Security/Firewall/fwpolicy_create_servicelist.py b/cd3_automation_toolkit/Security/Firewall/fwpolicy_create_servicelist.py index bf203e233..5e39aefa9 100644 --- a/cd3_automation_toolkit/Security/Firewall/fwpolicy_create_servicelist.py +++ b/cd3_automation_toolkit/Security/Firewall/fwpolicy_create_servicelist.py @@ -56,8 +56,9 @@ def fwpolicy_create_servicelist(inputfile, outdir, service_dir, prefix, ct): for reg in ct.all_regions: servicelist_str[reg] = '' servicelist_names[reg] = [] - - + reg_out_dir = outdir + "/" + reg + "/" + service_dir + resource = sheetName.lower() + commonTools.backup_file(reg_out_dir, resource, servicelist_auto_tfvars_filename) # List of the column headers dfcolumns = df.columns.values.tolist() @@ -156,12 +157,11 @@ def fwpolicy_create_servicelist(inputfile, outdir, service_dir, prefix, ct): servicelist_str[region] = servicelist_str[region] + servicelist.render(tempStr) for reg in region_list: - resource = sheetName.lower() reg_out_dir = outdir + "/" + reg + "/" + service_dir if not os.path.exists(reg_out_dir): os.makedirs(reg_out_dir) outfile[reg] = reg_out_dir + "/" + servicelist_auto_tfvars_filename - commonTools.backup_file(reg_out_dir, resource, servicelist_auto_tfvars_filename) + if servicelist_str[reg] != '': # Generate Final String src = "##Add New service list for " + reg.lower() + " here##" diff --git a/cd3_automation_toolkit/Security/Firewall/fwpolicy_create_urllist.py b/cd3_automation_toolkit/Security/Firewall/fwpolicy_create_urllist.py index b193e2a3c..2d860db4a 100644 --- a/cd3_automation_toolkit/Security/Firewall/fwpolicy_create_urllist.py +++ b/cd3_automation_toolkit/Security/Firewall/fwpolicy_create_urllist.py @@ -51,7 +51,9 @@ def fwpolicy_create_urllist(inputfile, outdir, service_dir, prefix, ct): for reg in ct.all_regions: urllist_str[reg] = '' urllist_names[reg] = [] - + resource = sheetName.lower() + reg_out_dir = outdir + "/" + reg + "/" + service_dir + commonTools.backup_file(reg_out_dir, resource, urllist_auto_tfvars_filename) # List of the column headers dfcolumns = df.columns.values.tolist() @@ -138,12 +140,11 @@ def fwpolicy_create_urllist(inputfile, outdir, service_dir, prefix, ct): for reg in region_list: - resource = sheetName.lower() reg_out_dir = outdir + "/" + reg + "/" + service_dir if not os.path.exists(reg_out_dir): os.makedirs(reg_out_dir) outfile[reg] = reg_out_dir + "/" + urllist_auto_tfvars_filename - commonTools.backup_file(reg_out_dir, resource, urllist_auto_tfvars_filename) + if urllist_str[reg] != '': # Generate Final String src = "##Add New urllist for " + reg.lower() + " here##" diff --git a/cd3_automation_toolkit/Security/KeyVault/create_terraform_keyvault.py b/cd3_automation_toolkit/Security/KeyVault/create_terraform_keyvault.py deleted file mode 100644 index e3eb3dea4..000000000 --- a/cd3_automation_toolkit/Security/KeyVault/create_terraform_keyvault.py +++ /dev/null @@ -1,83 +0,0 @@ -#!/usr/bin/python3 -# Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. -# -# This script will produce a Terraform file that will be used to set up OCI Security components -# Key/Vault -# -# Author: Suruchi Singla -# Oracle Consulting -# Modified (TF Upgrade): Shruthi Subramanian -# - -from jinja2 import Environment, FileSystemLoader -from pathlib import Path -from oci.config import DEFAULT_LOCATION -from commonTools import * - -###### -# Required Inputs- Config file, prefix AND outdir -###### -# Execution of the code begins here -def create_cis_keyvault(outdir, service_dir, service_dir_iam, prefix, ct, region_name, comp_name): - - # Declare variables - region_name = region_name.strip().lower() - comp_name = comp_name.strip() - - if region_name not in ct.all_regions: - print("Invalid Region!! Tenancy is not subscribed to this region. Please try again") - exit(1) - - - # Load the template file - file_loader = FileSystemLoader(f'{Path(__file__).parent}/templates') - env = Environment(loader=file_loader, keep_trailing_newline=True, trim_blocks=True, lstrip_blocks=True) - vault_template = env.get_template('vaults-template') - key_template = env.get_template('keys-template') - - tempStr = {} - vaultStr = '' - keyStr = '' - auto_tfvars_filename = "cis-keyvault.auto.tfvars" - - compartmentVarName = commonTools.check_tf_variable(comp_name) - columnvalue = str(compartmentVarName) - tempStr['compartment_tf_name'] = columnvalue - - key_name = prefix+"-"+region_name+"-kms-key" - vault_name = prefix+"-"+region_name+"-kms-vault" - - tempStr['key_name'] = key_name - tempStr['key_tf_name'] = key_name - tempStr['vault_name'] = vault_name - tempStr['vault_tf_name'] = vault_name - tempStr['management_endpoint'] = vault_name - tempStr['algorithm'] = "AES" - - vaultStr = vaultStr + vault_template.render(tempStr) - keyStr= keyStr + key_template.render(tempStr) - - if vaultStr != '': - # Generate Final String - src = "##Add New Vaults for " + region_name + " here##" - vaultStr = vault_template.render(skeleton=True, count=0, region=region_name).replace(src, vaultStr+"\n"+src) - - if keyStr != '': - # Generate Final String - src = "##Add New Keys for " + region_name + " here##" - keyStr = key_template.render(skeleton=True, count=0, region=region_name).replace(src, keyStr+"\n"+src) - - finalstring = vaultStr + keyStr - finalstring = "".join([s for s in finalstring.strip().splitlines(True) if s.strip("\r\n").strip()]) - - if finalstring != "": - resource = "keyvault" - srcdir = outdir + "/" + region_name + "/" + service_dir +"/" - commonTools.backup_file(srcdir, resource, auto_tfvars_filename) - - # Write to TF file - outfile = outdir + "/" + region_name + "/" + service_dir + "/" + auto_tfvars_filename - oname = open(outfile, "w+") - print(outfile + " containing TF for Key/Vault has been created for region "+region_name) - oname.write(finalstring) - oname.close() diff --git a/cd3_automation_toolkit/Security/KeyVault/create_terraform_keyvaults.py b/cd3_automation_toolkit/Security/KeyVault/create_terraform_keyvaults.py index 9e751b680..64d08fec3 100644 --- a/cd3_automation_toolkit/Security/KeyVault/create_terraform_keyvaults.py +++ b/cd3_automation_toolkit/Security/KeyVault/create_terraform_keyvaults.py @@ -314,9 +314,6 @@ def create_terraform_keyvaults(inputfile, outdir, service_dir, prefix, ct): vaultStr[reg] += key_template.render(count=0, region=reg).replace(key_str, keyStr[reg] + "\n" + key_str) vaultStr[reg] = "".join([s for s in vaultStr[reg].strip().splitlines(True) if s.strip("\r\n").strip()]) - resource = sheetName.lower() - commonTools.backup_file(reg_out_dir + "/", resource, auto_tfvars_filename) - oname = open(outfile, "w+") oname.write(vaultStr[reg]) oname.close() diff --git a/cd3_automation_toolkit/Security/KeyVault/export_keyvaults_nonGreenField.py b/cd3_automation_toolkit/Security/KeyVault/export_keyvaults_nonGreenField.py index 85b0074d0..faae3e517 100644 --- a/cd3_automation_toolkit/Security/KeyVault/export_keyvaults_nonGreenField.py +++ b/cd3_automation_toolkit/Security/KeyVault/export_keyvaults_nonGreenField.py @@ -12,13 +12,16 @@ import oci from oci.key_management import KmsVaultClient import os +import subprocess as sp sys.path.append(os.getcwd() + "/..") from commonTools import * # Execution of the code begins here def export_keyvaults(inputfile, outdir, service_dir, config, signer, ct, export_regions=[], export_compartments=[]): global values_for_column_kms - global cd3file + global cd3file,tf_or_tofu + tf_or_tofu = ct.tf_or_tofu + tf_state_list = [tf_or_tofu, "state", "list"] comp_id_list = list(ct.ntk_compartment_ids.values()) comp_name_list = list(ct.ntk_compartment_ids.keys()) @@ -47,12 +50,20 @@ def export_keyvaults(inputfile, outdir, service_dir, config, signer, ct, export_ for reg in export_regions: importCommands = "" region = reg.lower() - script_file = f'{outdir}/{region}/{service_dir}/tf_import_commands_kms_nonGF.sh' + script_file = f'{outdir}/{region}/{service_dir}/import_commands_kms.sh' # create backups if os.path.exists(script_file): commonTools.backup_file(os.path.dirname(script_file), "tf_import_kms", os.path.basename(script_file)) config["region"] = ct.region_dict[reg] + state = {'path': f'{outdir}/{reg}/{service_dir}', 'resources': []} + try: + byteOutput = sp.check_output(tf_state_list, cwd=state["path"], stderr=sp.DEVNULL) + output = byteOutput.decode('UTF-8').rstrip() + for item in output.split('\n'): + state["resources"].append(item.replace("\"", "\\\"")) + except Exception as e: + pass kms_vault_client = KmsVaultClient(config=config, retry_strategy=oci.retry.DEFAULT_RETRY_STRATEGY, signer=signer) for ntk_compartment_name in export_compartments: vaults = oci.pagination.list_call_get_all_results(kms_vault_client.list_vaults, @@ -63,12 +74,11 @@ def export_keyvaults(inputfile, outdir, service_dir, config, signer, ct, export_ get_vault_data = kms_vault_client.get_vault(vault_id=vault.id).data key_count = 0 if vault.lifecycle_state == "ACTIVE": - if importCommands == '': - importCommands += "\n######### Writing import for Vaults and Keys #########\n\n#!/bin/bash\nterraform init" total_vaults += 1 vault_tf_name = commonTools.check_tf_variable(vault.display_name) - - importCommands += f'\nterraform import "module.vaults[\\\"{vault_tf_name}\\\"].oci_kms_vault.vault" {vault.id}' + tf_resource = f'module.vaults[\\"{vault_tf_name}\\"].oci_kms_vault.vault' + if tf_resource not in state["resources"]: + importCommands += f'\n{tf_or_tofu} import "{tf_resource}" {vault.id}' kms_key_client = oci.key_management.KmsManagementClient(config, service_endpoint=vault.management_endpoint) keys = oci.pagination.list_call_get_all_results(kms_key_client.list_keys, @@ -81,7 +91,9 @@ def export_keyvaults(inputfile, outdir, service_dir, config, signer, ct, export_ key_count += 1 total_keys += 1 key_tf_name = commonTools.check_tf_variable(key.display_name) - importCommands += f'\nterraform import "module.keys[\\\"{key_tf_name}\\\"].oci_kms_key.key" managementEndpoint/{vault.management_endpoint}/keys/{key.id}' + tf_resource = f'module.keys[\\"{key_tf_name}\\"].oci_kms_key.key' + if tf_resource not in state["resources"]: + importCommands += f'\n{tf_or_tofu} import "{tf_resource}" managementEndpoint/{vault.management_endpoint}/keys/{key.id}' get_key_data = kms_key_client.get_key(key_id=key.id).data if get_key_data.vault_id == vault.id and get_key_data.lifecycle_state != "PENDING_DELETION": if key_count == 1: @@ -129,9 +141,9 @@ def export_keyvaults(inputfile, outdir, service_dir, config, signer, ct, export_ elif col_header == 'Curve Id': values_for_column_kms[col_header].append(get_key_data.key_shape.curve_id if get_key_data.key_shape.algorithm == 'ECDSA' else '') elif col_header == 'Auto rotation': - values_for_column_kms[col_header].append("TRUE" if get_key_data.is_auto_rotation_enabled else "FALSE") + values_for_column_kms[col_header].append("TRUE" if hasattr(get_key_data, 'is_auto_rotation_enabled') else "FALSE") elif col_header == 'Rotation interval in days': - values_for_column_kms[col_header].append(get_key_data.auto_key_rotation_details.rotation_interval_in_days if get_key_data.is_auto_rotation_enabled else '') + values_for_column_kms[col_header].append(get_key_data.auto_key_rotation_details.rotation_interval_in_days if hasattr(get_key_data,'is_auto_rotation_enabled') else '') elif str(col_header).lower() in ["key defined tags" , "key freeform tags"]: if len(key.defined_tags) != 0: values_for_column_kms = commonTools.export_tags(key, col_header, values_for_column_kms) @@ -160,10 +172,10 @@ def export_keyvaults(inputfile, outdir, service_dir, config, signer, ct, export_ get_key_data.key_shape.curve_id if get_key_data.key_shape.algorithm == 'ECDSA' else '') elif col_header == 'Auto rotation': values_for_column_kms[col_header].append( - "TRUE" if get_key_data.is_auto_rotation_enabled else "FALSE") + "TRUE" if hasattr(get_key_data,'is_auto_rotation_enabled') else "FALSE") elif col_header == 'Rotation interval in days': values_for_column_kms[col_header].append( - get_key_data.auto_key_rotation_details.rotation_interval_in_days if get_key_data.is_auto_rotation_enabled else '') + get_key_data.auto_key_rotation_details.rotation_interval_in_days if hasattr(get_key_data,'is_auto_rotation_enabled') else '') elif str(col_header).lower() in ["key defined tags", "key freeform tags"]: if len(key.defined_tags) != 0: values_for_column_kms = commonTools.export_tags(key, col_header, @@ -210,10 +222,12 @@ def export_keyvaults(inputfile, outdir, service_dir, config, signer, ct, export_ values_for_column_kms) #Write Import Commands to script file - if importCommands!="": - importCommands += "\nterraform plan\n" + init_commands = f'\n######### Writing import for OCI Vaults #########\n\n#!/bin/bash\n{tf_or_tofu} init' + + if importCommands != "": + importCommands += f'\n{tf_or_tofu} plan\n' with open(script_file, 'a') as importCommandsfile: - importCommandsfile.write(importCommands) + importCommandsfile.write(init_commands + importCommands) #Write resource data to input Excel sheet commonTools.write_to_cd3(values_for_column_kms, cd3file, sheetName) diff --git a/cd3_automation_toolkit/Storage/BlockVolume/create_terraform_block_volumes.py b/cd3_automation_toolkit/Storage/BlockVolume/create_terraform_block_volumes.py index dfe1f497b..75b683258 100644 --- a/cd3_automation_toolkit/Storage/BlockVolume/create_terraform_block_volumes.py +++ b/cd3_automation_toolkit/Storage/BlockVolume/create_terraform_block_volumes.py @@ -47,6 +47,9 @@ def create_terraform_block_volumes(inputfile, outdir, service_dir, prefix,ct): # Take backup of files for eachregion in ct.all_regions: tfStr[eachregion] = '' + reg_out_dir = outdir + "/" + eachregion + "/" + service_dir + resource = sheetName.lower() + commonTools.backup_file(reg_out_dir + "/", resource, auto_tfvars_filename) for i in df.index: @@ -265,9 +268,6 @@ def create_terraform_block_volumes(inputfile, outdir, service_dir, prefix,ct): tfStr[reg] = template.render(count=0, region=reg).replace(src,tfStr[reg]) tfStr[reg] = "".join([s for s in tfStr[reg].strip().splitlines(True) if s.strip("\r\n").strip()]) - resource=sheetName.lower() - commonTools.backup_file(reg_out_dir + "/", resource, auto_tfvars_filename) - # Write to TF file tfStr[reg] = "".join([s for s in tfStr[reg].strip().splitlines(True) if s.strip("\r\n").strip()]) outfile = reg_out_dir+ "/" + auto_tfvars_filename diff --git a/cd3_automation_toolkit/Storage/BlockVolume/export_blockvolumes_nonGreenField.py b/cd3_automation_toolkit/Storage/BlockVolume/export_blockvolumes_nonGreenField.py index 1ed17c990..b015a6c8d 100644 --- a/cd3_automation_toolkit/Storage/BlockVolume/export_blockvolumes_nonGreenField.py +++ b/cd3_automation_toolkit/Storage/BlockVolume/export_blockvolumes_nonGreenField.py @@ -14,6 +14,7 @@ from oci.core.blockstorage_client import BlockstorageClient from oci.core.compute_client import ComputeClient from commonTools import * +import subprocess as sp importCommands = {} oci_obj_names = {} @@ -61,7 +62,7 @@ def volume_attachment_info(compute,ct,volume_id,export_compartments): return attachments,attachment_id, instance_name, attachment_type -def print_blockvolumes(region, BVOLS, bvol, compute, ct, values_for_column, ntk_compartment_name, display_names, ad_names,export_compartments): +def print_blockvolumes(region, BVOLS, bvol, compute, ct, values_for_column, ntk_compartment_name, display_names, ad_names,export_compartments,state): volume_comp = '' for blockvols in BVOLS.data: volume_id = blockvols.id @@ -144,13 +145,17 @@ def print_blockvolumes(region, BVOLS, bvol, compute, ct, values_for_column, ntk_ if volume_compartment_id == comp_id and volume_compartment_id not in comp_done_ids: volume_comp = comp_name comp_done_ids.append(volume_compartment_id) + tf_resource = f'module.block-volumes[\\"{block_tf_name}\\"].oci_core_volume.block_volume' + if tf_resource not in state["resources"]: + importCommands[region.lower()] += f'\n{tf_or_tofu} import "{tf_resource}" {str(blockvols.id)}' - importCommands[region.lower()].write("\nterraform import \"module.block-volumes[\\\"" + block_tf_name + "\\\"].oci_core_volume.block_volume\" " + str(blockvols.id)) - if attachment_id != '': - importCommands[region.lower()].write("\nterraform import \"module.block-volumes[\\\"" + block_tf_name + "\\\"].oci_core_volume_attachment.block_vol_instance_attachment[0]\" " + str(attachment_id)) + tf_resource = f'module.block-volumes[\\"{block_tf_name}\\"].oci_core_volume_attachment.block_vol_instance_attachment[0]' + if attachment_id != '' and tf_resource not in state["resources"]: + importCommands[region.lower()] += f'\n{tf_or_tofu} import "{tf_resource}" {str(attachment_id)}' - if asset_assignment_id != '': - importCommands[region.lower()].write("\nterraform import \"module.block-volumes[\\\"" + block_tf_name + "\\\"].oci_core_volume_backup_policy_assignment.volume_backup_policy_assignment[0]\" " + str(asset_assignment_id)) + tf_resource = f'module.block-volumes[\\"{block_tf_name}\\"].oci_core_volume_backup_policy_assignment.volume_backup_policy_assignment[0]' + if asset_assignment_id != '' and tf_resource not in state["resources"]: + importCommands[region.lower()]+= f'\n{tf_or_tofu} import "{tf_resource}" {str(asset_assignment_id)}' pass for col_header in values_for_column: if col_header == 'Region': @@ -199,7 +204,9 @@ def export_blockvolumes(inputfile, outdir, service_dir, config, signer, ct, expo global values_for_vcninfo global cd3file global reg - global values_for_column + global values_for_column,tf_or_tofu + tf_or_tofu = ct.tf_or_tofu + tf_state_list = [tf_or_tofu, "state", "list"] cd3file = inputfile if ('.xls' not in cd3file): @@ -217,30 +224,34 @@ def export_blockvolumes(inputfile, outdir, service_dir, config, signer, ct, expo print("Tabs- BlockVolumes will be overwritten during export process!!!\n") # Create backups - resource = 'tf_import_' + sheetName.lower() - file_name = 'tf_import_commands_' + sheetName.lower() + '_nonGF.sh' + resource = 'import_' + sheetName.lower() + file_name = 'import_commands_' + sheetName.lower() + '.sh' for reg in export_regions: script_file = f'{outdir}/{reg}/{service_dir}/' + file_name if (os.path.exists(script_file)): - commonTools.backup_file(outdir + "/" + reg +"/" + service_dir, resource, file_name) - importCommands[reg] = open(script_file, "w") - importCommands[reg].write("#!/bin/bash") - importCommands[reg].write("\n") - importCommands[reg].write("terraform init") + commonTools.backup_file(outdir + "/" + reg + "/" + service_dir, resource, file_name) + importCommands[reg] = '' # Fetch Block Volume Details print("\nFetching details of Block Volumes...") for reg in export_regions: - importCommands[reg].write("\n\n######### Writing import for Block Volumes #########\n\n") config.__setitem__("region", ct.region_dict[reg]) + state = {'path': f'{outdir}/{reg}/{service_dir}', 'resources': []} + try: + byteOutput = sp.check_output(tf_state_list, cwd=state["path"], stderr=sp.DEVNULL) + output = byteOutput.decode('UTF-8').rstrip() + for item in output.split('\n'): + state["resources"].append(item.replace("\"", "\\\"")) + except Exception as e: + pass region = reg.capitalize() compute = ComputeClient(config=config,retry_strategy=oci.retry.DEFAULT_RETRY_STRATEGY,signer=signer) bvol = BlockstorageClient(config=config,retry_strategy=oci.retry.DEFAULT_RETRY_STRATEGY,signer=signer) for ntk_compartment_name in export_compartments: BVOLS = oci.pagination.list_call_get_all_results(bvol.list_volumes,compartment_id=ct.ntk_compartment_ids[ntk_compartment_name],lifecycle_state="AVAILABLE") - print_blockvolumes(region, BVOLS, bvol, compute, ct, values_for_column, ntk_compartment_name, display_names, ad_names, export_compartments) + print_blockvolumes(region, BVOLS, bvol, compute, ct, values_for_column, ntk_compartment_name, display_names, ad_names, export_compartments,state) # writing volume source into variables file var_data = {} @@ -268,10 +279,12 @@ def export_blockvolumes(inputfile, outdir, service_dir, config, signer, ct, expo commonTools.write_to_cd3(values_for_column, cd3file, sheetName) print("{0} Block Volumes exported into CD3.\n".format(len(values_for_column["Region"]))) - # writing data + init_commands = f'\n#!/bin/bash\n{tf_or_tofu} init\n######### Writing import for Block Volumes #########\n' for reg in export_regions: script_file = f'{outdir}/{reg}/{service_dir}/' + file_name - with open(script_file, 'a') as importCommands[reg]: - importCommands[reg].write('\n\nterraform plan\n') + if importCommands[reg] != "": + importCommands[reg] += f'\n{tf_or_tofu} plan\n' + with open(script_file, 'a') as importCommandsfile: + importCommandsfile.write(init_commands + importCommands[reg]) diff --git a/cd3_automation_toolkit/Storage/FileSystem/create_terraform_fss.py b/cd3_automation_toolkit/Storage/FileSystem/create_terraform_fss.py index a0cb28d3d..e3108eb47 100644 --- a/cd3_automation_toolkit/Storage/FileSystem/create_terraform_fss.py +++ b/cd3_automation_toolkit/Storage/FileSystem/create_terraform_fss.py @@ -167,7 +167,7 @@ def fss_exports(i, df, tempStr): srcdir = outdir + "/" + eachregion + "/" + service_dir + "/" commonTools.backup_file(srcdir, resource, auto_tfvars_filename) - subnets = parseSubnets(filename) + #subnets = parseSubnets(filename) fss_tf_name = '' for i in df.index: @@ -189,7 +189,7 @@ def fss_exports(i, df, tempStr): if region in commonTools.endNames: break - if region.lower() == 'nan' and str(df.loc[i, 'Compartment Name']).strip().lower() == 'nan' and str(df.loc[i, 'Availability Domain(AD1|AD2|AD3)']).strip().lower() == 'nan' and str(df.loc[i, 'MountTarget Name']).strip().lower() == 'nan' and str(df.loc[i, 'MountTarget SubnetName']).strip().lower() == 'nan': + if region.lower() == 'nan' and str(df.loc[i, 'Compartment Name']).strip().lower() == 'nan' and str(df.loc[i, 'Availability Domain(AD1|AD2|AD3)']).strip().lower() == 'nan' and str(df.loc[i, 'MountTarget Name']).strip().lower() == 'nan' and str(df.loc[i, 'Network Details']).strip().lower() == 'nan': continue region = str(region).lower().strip() @@ -232,23 +232,26 @@ def fss_exports(i, df, tempStr): subnet_id = '' network_compartment_id='' vcn_name='' - if columnname == 'MountTarget SubnetName': - subnet_tf_name = columnvalue.strip() - if ("ocid1.subnet.oc1" in subnet_tf_name): - network_compartment_id = "" + if columnname == 'Network Details': + columnvalue = columnvalue.strip() + if ("ocid1.subnet.oc" in columnvalue): + network_compartment_id = "root" vcn_name = "" - subnet_id = subnet_tf_name - elif subnet_tf_name.lower()!='nan' and subnet_tf_name.lower()!='': - try: - key = region, subnet_tf_name - network_compartment_id = subnets.vcn_subnet_map[key][0] - vcn_name = subnets.vcn_subnet_map[key][1] - subnet_id = subnets.vcn_subnet_map[key][2] - except Exception as e: - print("Invalid Subnet Name specified for row " + str(i + 3) + ". It Doesnt exist in Subnets sheet. Exiting!!!") + subnet_id = columnvalue + elif columnvalue.lower()!='nan' and columnvalue.lower()!='': + if len(columnvalue.split("@")) == 2: + network_compartment_id = commonTools.check_tf_variable(columnvalue.split("@")[0].strip()) + vcn_subnet_name = columnvalue.split("@")[1].strip() + else: + network_compartment_id = commonTools.check_tf_variable(str(df.loc[i, 'Compartment Name']).strip()) + vcn_subnet_name = columnvalue + if("::" not in vcn_subnet_name): + print("Invalid Network Details format specified for row " + str(i + 3) + ". Exiting!!!") exit(1) - - tempdict = {'network_compartment_id': commonTools.check_tf_variable(network_compartment_id), 'vcn_name': vcn_name, + else: + vcn_name=vcn_subnet_name.split("::")[0].strip() + subnet_id = vcn_subnet_name.split("::")[1].strip() + tempdict = {'network_compartment_id': network_compartment_id, 'vcn_name': vcn_name, 'subnet_id': subnet_id} if columnname == "Access (READ_ONLY|READ_WRITE)": @@ -366,16 +369,12 @@ def fss_exports(i, df, tempStr): tempStr.update(tempdict) if columnname == "Snapshot Policy": if columnvalue != '': - if "@" in columnvalue: - if len(columnvalue.split("@")) == 2: + if len(columnvalue.split("@")) == 2: snapshot_policy_comp = columnvalue.split("@")[0].strip() snapshot_policy_comp = commonTools.check_tf_variable(snapshot_policy_comp) snapshot_policy_name = columnvalue.split("@")[1].strip() - else: - snapshot_policy_comp = '' - snapshot_policy_name = '' else: - snapshot_policy_comp = '' + snapshot_policy_comp = commonTools.check_tf_variable(str(df.loc[i, 'Compartment Name']).strip()) snapshot_policy_name = columnvalue.strip() else: snapshot_policy_comp = '' diff --git a/cd3_automation_toolkit/Storage/FileSystem/export_fss_nonGreenField.py b/cd3_automation_toolkit/Storage/FileSystem/export_fss_nonGreenField.py index 5e691f90b..aa1994faa 100644 --- a/cd3_automation_toolkit/Storage/FileSystem/export_fss_nonGreenField.py +++ b/cd3_automation_toolkit/Storage/FileSystem/export_fss_nonGreenField.py @@ -9,6 +9,7 @@ import re from oci.config import DEFAULT_LOCATION from commonTools import * +import subprocess as sp fs_source_snapshots = {} fss_all_dict = {} @@ -27,7 +28,7 @@ def add_column_data(reg, cname, AD_name, mt_display_name, vplussubnet, mnt_p_ip, values_for_column_fss[col_header].append(AD_name) elif (col_header == "MountTarget Name"): values_for_column_fss[col_header].append(mt_display_name) - elif (col_header == "MountTarget SubnetName"): + elif (col_header == "Network Details"): values_for_column_fss[col_header].append(vplussubnet) elif (col_header == "MountTarget IP"): values_for_column_fss[col_header].append(mnt_p_ip) @@ -90,7 +91,7 @@ def add_column_data(reg, cname, AD_name, mt_display_name, vplussubnet, mnt_p_ip, values_for_column_fss) -def __get_mount_info(cname, ntk_compartment_ids, compartment_id, reg, availability_domain_name, signer): +def __get_mount_info(cname, ntk_compartment_ids, compartment_id, reg, availability_domain_name, signer,state): file_system = oci.file_storage.FileStorageClient(config, retry_strategy=oci.retry.DEFAULT_RETRY_STRATEGY, signer=signer) network = oci.core.VirtualNetworkClient(config, retry_strategy=oci.retry.DEFAULT_RETRY_STRATEGY, signer=signer) @@ -101,13 +102,12 @@ def __get_mount_info(cname, ntk_compartment_ids, compartment_id, reg, availabili try: mount_info = oci.pagination.list_call_get_all_results(file_system.list_mount_targets, compartment_id=compartment_id, - availability_domain=availability_domain_name) + availability_domain=availability_domain_name,sort_by="TIMECREATED") list_replications = oci.pagination.list_call_get_all_results(file_system.list_replications, compartment_id=compartment_id, - availability_domain=availability_domain_name) + availability_domain=availability_domain_name,sort_by="timeCreated") list_fss = oci.pagination.list_call_get_all_results(file_system.list_file_systems, - compartment_id=compartment_id, - availability_domain=availability_domain_name) + compartment_id=compartment_id,availability_domain=availability_domain_name,sort_by="TIMECREATED") for fss in list_fss.data: fss_all_dict[fss.id] = fss.display_name replications_dict = {} @@ -124,13 +124,13 @@ def __get_mount_info(cname, ntk_compartment_ids, compartment_id, reg, availabili mnt_info_dict = {} mnt_with_export = [] for mnt in mount_info.data: - mnt_id = mnt.id + mnt_id = str(mnt.id) export_set_id = mnt.export_set_id # Export Set Id mt_display_name = mnt.display_name # Mount Target Name tf_name = commonTools.check_tf_variable(mt_display_name) - importCommands[reg].write( - "\nterraform import \"module.mts[\\\"" + tf_name + "\\\"].oci_file_storage_mount_target.mount_target\" " + str( - mnt_id)) + tf_resource = f'module.mts[\\"{tf_name}\\"].oci_file_storage_mount_target.mount_target' + if tf_resource not in state["resources"]: + importCommands[reg]+=f'\n{tf_or_tofu} import "{tf_resource}" {mnt_id}' subnet_id = mnt.subnet_id private_ip_ids = mnt.private_ip_ids nsg_id = mnt.nsg_ids @@ -143,7 +143,14 @@ def __get_mount_info(cname, ntk_compartment_ids, compartment_id, reg, availabili subnet_info = vnc_info.get_subnet(subnet_id) mnt_sub_name = subnet_info.data.display_name # Subnet-Name vnc_name = vnc_info.get_vcn(subnet_info.data.vcn_id).data.display_name # vcn-Name - vplussubnet = vnc_name + "_" + mnt_sub_name + ntk_compartment_id = vnc_info.get_vcn(subnet_info.data.vcn_id).data.compartment_id # compartment-id + network_compartment_name=cname + for comp_name, comp_id in ntk_compartment_ids.items(): + if comp_id == ntk_compartment_id: + network_compartment_name = comp_name + + + vplussubnet = network_compartment_name+"@"+vnc_name + "::" + mnt_sub_name for ips in private_ip_ids: private_address = vnc_info.get_private_ip(ips) @@ -179,6 +186,7 @@ def __get_mount_info(cname, ntk_compartment_ids, compartment_id, reg, availabili fs_source_snapshot_id = fs_name fs_snapshot_policy_id = file_system_info.data.filesystem_snapshot_policy_id if fs_snapshot_policy_id != '': + policy_comp_name=cname snapshot_policy_info = file_system.get_filesystem_snapshot_policy(filesystem_snapshot_policy_id=fs_snapshot_policy_id) policy_name = snapshot_policy_info.data.display_name policy_comp_id = snapshot_policy_info.data.compartment_id @@ -195,6 +203,8 @@ def __get_mount_info(cname, ntk_compartment_ids, compartment_id, reg, availabili for id,name in fss_all_dict.items(): if id == v['targetid']: targetid = name + else: + targetid = v['targetid'] rep_format = targetid + "::" + str(v['interval']) + "::" + v['displayname'] fss_replication = fss_replication + rep_format + '\n' @@ -202,18 +212,19 @@ def __get_mount_info(cname, ntk_compartment_ids, compartment_id, reg, availabili if (str(fs_id) not in fss): # print(mt_display_name,"-",str(fs_name)) tf_name = commonTools.check_tf_variable(fs_name) - importCommands[reg].write( - "\nterraform import \"module.fss[\\\"" + tf_name + "\\\"].oci_file_storage_file_system.file_system\" " + str( - fs_id)) + tf_resource = f'module.fss[\\"{tf_name}\\"].oci_file_storage_file_system.file_system' + if tf_resource not in state["resources"]: + importCommands[reg] += f'\n{tf_or_tofu} import "{tf_resource}" {fs_id}' + fss.append(str(fs_id)) if len(replications_dict) > 0: for k, v in replications_dict.items(): if v['sourceid'] == fs_id: if (str(k) not in rep_ids): tf_rep_name = commonTools.check_tf_variable(v['displayname'].strip()) - importCommands[reg].write( - "\nterraform import \"module.fss-replication[\\\"" + tf_rep_name + "\\\"].oci_file_storage_replication.file_system_replication\" " + str( - k)) + tf_resource = f'module.fss-replication[\\"{tf_rep_name}\\"].oci_file_storage_replication.file_system_replication' + if tf_resource not in state["resources"]: + importCommands[reg] += f'\n{tf_or_tofu} import "{tf_resource}" {str(k)}' rep_ids.append(str(k)) elen = (len(einfo_export_data.export_options)) @@ -262,9 +273,10 @@ def __get_mount_info(cname, ntk_compartment_ids, compartment_id, reg, availabili tf_name = commonTools.check_tf_variable( "FSE-" + commonTools.check_tf_variable(mt_display_name) + "-" + commonTools.check_tf_variable( fs_name) + "-" + einfo_path[1:]) - importCommands[reg].write( - "\nterraform import \"module.fss-export-options[\\\"" + tf_name + "\\\"].oci_file_storage_export.export\" " + str( - einfo.id)) # exports import + tf_resource = f'module.fss-export-options[\\"{tf_name}\\"].oci_file_storage_export.export' + if tf_resource not in state["resources"]: + importCommands[reg] += f'\n{tf_or_tofu} import "{tf_resource}" {str(einfo.id)}' + ###### code to fetch FSS without any exports ##### fss_all_ids = [] @@ -291,6 +303,7 @@ def __get_mount_info(cname, ntk_compartment_ids, compartment_id, reg, availabili snapshot_policy_info = file_system.get_filesystem_snapshot_policy(filesystem_snapshot_policy_id=fs_snapshot_policy_id) policy_name = snapshot_policy_info.data.display_name policy_comp_id = snapshot_policy_info.data.compartment_id + policy_comp_name=cname for comp_name, comp_id in ntk_compartment_ids.items(): if comp_id == policy_comp_id: policy_comp_name = comp_name @@ -303,6 +316,8 @@ def __get_mount_info(cname, ntk_compartment_ids, compartment_id, reg, availabili for id, name in fss_all_dict.items(): if id == v['targetid']: targetid = name + else: + targetid = v['targetid'] rep_format = targetid + "::" + str(v['interval']) + "::" + v['displayname'] fss_replication = fss_replication + rep_format + '\n' @@ -315,9 +330,9 @@ def __get_mount_info(cname, ntk_compartment_ids, compartment_id, reg, availabili if (str(fss_id) not in fss): # print(mt_display_name,"-",str(fs_name)) tf_name = commonTools.check_tf_variable(fs_name) - importCommands[reg].write( - "\nterraform import \"module.fss[\\\"" + tf_name + "\\\"].oci_file_storage_file_system.file_system\" " + str( - fss_id)) + tf_resource = f'module.fss[\\"{tf_name}\\"].oci_file_storage_file_system.file_system' + if tf_resource not in state["resources"]: + importCommands[reg] += f'\n{tf_or_tofu} import "{tf_resource}" {str(fss_id)}' fss.append(str(fss_id)) ###### code to fetch MT without any exports ##### @@ -345,6 +360,9 @@ def __get_mount_info(cname, ntk_compartment_ids, compartment_id, reg, availabili # Execution of the code begins here def export_fss(inputfile, outdir, service_dir, config1, signer1, ct, export_compartments=[], export_regions=[]): + global tf_or_tofu + tf_or_tofu = ct.tf_or_tofu + tf_state_list = [tf_or_tofu, "state", "list"] input_compartment_names = export_compartments cd3file = inputfile @@ -385,25 +403,29 @@ def export_fss(inputfile, outdir, service_dir, config1, signer1, ct, export_comp all_ads.append(aval.name) # backup of .sh file - resource = 'tf_import_' + sheetName.lower() - file_name = 'tf_import_commands_' + sheetName.lower() + '_nonGF.sh' + resource = 'import_' + sheetName.lower() + file_name = 'import_commands_' + sheetName.lower() + '.sh' for reg in export_regions: script_file = f'{outdir}/{reg}/{service_dir}/' + file_name if (os.path.exists(script_file)): commonTools.backup_file(outdir + "/" + reg + "/" + service_dir + "/", resource, file_name) - importCommands[reg] = open(script_file, "w") - importCommands[reg].write("#!/bin/bash") - importCommands[reg].write("\n") - importCommands[reg].write("terraform init") - + importCommands[reg] ='' for reg in export_regions: config.__setitem__("region", ct.region_dict[reg]) + state = {'path': f'{outdir}/{reg}/{service_dir}', 'resources': []} + try: + byteOutput = sp.check_output(tf_state_list, cwd=state["path"],stderr=sp.DEVNULL) + output = byteOutput.decode('UTF-8').rstrip() + for item in output.split('\n'): + state["resources"].append(item.replace("\"", "\\\"")) + except Exception as e: + pass for ntk_compartment_name in export_compartments: ads = oci.identity.IdentityClient(config=config, retry_strategy=oci.retry.DEFAULT_RETRY_STRATEGY, signer=signer) for aval in ads.list_availability_domains(compartment_id=config['tenancy']).data: __get_mount_info(ntk_compartment_name, ct.ntk_compartment_ids, ct.ntk_compartment_ids[ntk_compartment_name], reg, aval.name, - signer) + signer,state) # writing volume source into variables file var_data = {} @@ -433,5 +455,8 @@ def export_fss(inputfile, outdir, service_dir, config1, signer1, ct, export_comp # writing data for reg in export_regions: script_file = f'{outdir}/{reg}/{service_dir}/' + file_name - with open(script_file, 'a') as importCommands[reg]: - importCommands[reg].write('\n\nterraform plan\n') + init_commands = f'\n######### Writing import for File Storage #########\n\n#!/bin/bash\n{tf_or_tofu} init' + if importCommands[reg] != "": + importCommands[reg] += f'\n{tf_or_tofu} plan\n' + with open(script_file, 'a') as importCommandsfile: + importCommandsfile.write(init_commands + importCommands[reg]) diff --git a/cd3_automation_toolkit/Storage/ObjectStorage/create_terraform_oss.py b/cd3_automation_toolkit/Storage/ObjectStorage/create_terraform_oss.py index de2a30571..ab77d99bb 100644 --- a/cd3_automation_toolkit/Storage/ObjectStorage/create_terraform_oss.py +++ b/cd3_automation_toolkit/Storage/ObjectStorage/create_terraform_oss.py @@ -54,6 +54,9 @@ def create_terraform_oss(inputfile, outdir, service_dir, prefix, ct): # Initialise empty TF string for each region to take backup of files for eachregion in ct.all_regions: tfStr[eachregion] = '' + srcdir = outdir + "/" + eachregion + "/" + service_dir + resource = sheetName.lower() + commonTools.backup_file(srcdir + "/", resource, auto_tfvars_filename) #Declaration bucket_lifecycle_policy = {} @@ -340,6 +343,8 @@ def create_terraform_oss(inputfile, outdir, service_dir, prefix, ct): src = "##Add New OSS Buckets for " + reg.lower() + " here##" tfStr[reg] = oss_template.render(count = 0, region = reg).replace(src, tfStr[reg] + "\n" + src) tfStr[reg] = "".join([s for s in tfStr[reg].strip().splitlines(True) if s.strip("\r\n").strip()]) + + oname[reg]=open(outfile[reg],'w') oname[reg].write(tfStr[reg]) oname[reg].close() diff --git a/cd3_automation_toolkit/Storage/ObjectStorage/export_terraform_oss.py b/cd3_automation_toolkit/Storage/ObjectStorage/export_terraform_oss.py index cb8a02792..425d1361f 100644 --- a/cd3_automation_toolkit/Storage/ObjectStorage/export_terraform_oss.py +++ b/cd3_automation_toolkit/Storage/ObjectStorage/export_terraform_oss.py @@ -19,21 +19,26 @@ sys.path.append(os.getcwd()+"/..") from commonTools import * from dateutil import parser +import subprocess as sp importCommands = {} oci_obj_names = {} -def print_buckets(region, outdir, service_dir, bucket_data, values_for_column, ntk_compartment_name,namespace_name, rp_id, retention_rule_data, rp_details, rp_name,lf_name_list,lf_name,lf_mapping,lf_excl,lf_incl,lf_prefix,ta_map,tgt_map): +def print_buckets(region, outdir, service_dir,state, bucket_data, values_for_column, ntk_compartment_name,namespace_name, rp_id, retention_rule_data, rp_details, rp_name,lf_name_list,lf_name,lf_mapping,lf_excl,lf_incl,lf_prefix,ta_map,tgt_map): buckets_tf_name = commonTools.check_tf_variable(bucket_data.name) - importCommands[region.lower()].write(f'\nterraform import "module.oss-buckets[\\"{buckets_tf_name}\\"].oci_objectstorage_bucket.bucket" 'f'n/{namespace_name}/b/{bucket_data.name}') + tf_resource = f'module.oss-buckets[\\"{buckets_tf_name}\\"].oci_objectstorage_bucket.bucket' + if tf_resource not in state["resources"]: + importCommands[region.lower()]+=f'\n{tf_or_tofu} import "{tf_resource}" n/{namespace_name}/b/{bucket_data.name}' - if rp_name: - importCommands[region.lower()].write(f'\nterraform import "module.oss-buckets[\\"{buckets_tf_name}\\"].oci_objectstorage_replication_policy.replication_policy[0]" 'f'n/{namespace_name}/b/{bucket_data.name}/replicationPolicies/{rp_id}') + tf_resource = f'module.oss-buckets[\\"{buckets_tf_name}\\"].oci_objectstorage_replication_policy.replication_policy[0]' + if rp_name and tf_resource not in state["resources"]: + importCommands[region.lower()]+=f'\n{tf_or_tofu} import "{tf_resource}" n/{namespace_name}/b/{bucket_data.name}/replicationPolicies/{rp_id}' - if bucket_data.object_lifecycle_policy_etag != None: - importCommands[region.lower()].write(f'\nterraform import "module.oss-buckets[\\"{buckets_tf_name}\\"].oci_objectstorage_object_lifecycle_policy.lifecycle_policy[0]" 'f'n/{namespace_name}/b/{bucket_data.name}/l') + tf_resource = f'module.oss-buckets[\\"{buckets_tf_name}\\"].oci_objectstorage_object_lifecycle_policy.lifecycle_policy[0]' + if bucket_data.object_lifecycle_policy_etag != None and tf_resource not in state["resources"]: + importCommands[region.lower()]+=f'\n{tf_or_tofu} import "{tf_resource}" n/{namespace_name}/b/{bucket_data.name}/l' lf_names = lf_name_list if lf_name_list else [''] for lf_name in lf_names: @@ -155,8 +160,10 @@ def export_buckets(inputfile, outdir, service_dir, config, signer, ct, export_co global importCommands global cd3file global reg - global values_for_column + global values_for_column,tf_or_tofu + tf_or_tofu = ct.tf_or_tofu + tf_state_list = [tf_or_tofu, "state", "list"] cd3file = inputfile if ('.xls' not in cd3file): print("\nAcceptable cd3 format: .xlsx") @@ -175,41 +182,49 @@ def export_buckets(inputfile, outdir, service_dir, config, signer, ct, export_co print("Tabs- Buckets will be overwritten during export process!!!\n") # Create backups - resource = 'tf_import_' + sheetName.lower() - file_name = 'tf_import_commands_' + sheetName.lower() + '_nonGF.sh' + resource = 'import_' + sheetName.lower() + file_name = 'import_commands_' + sheetName.lower() + '.sh' for reg in export_regions: script_file = f'{outdir}/{reg}/{service_dir}/' + file_name if (os.path.exists(script_file)): commonTools.backup_file(outdir + "/" + reg + "/" + service_dir, resource, file_name) - importCommands[reg] = open(script_file, "w") - importCommands[reg].write("#!/bin/bash") - importCommands[reg].write("\n") - importCommands[reg].write("terraform init") + importCommands[reg] = '' # Fetch Bucket Details print("\nFetching details of Buckets...") lifecycle_map = {} + total_resources=0 for reg in export_regions: - importCommands[reg].write("\n\n######### Writing import for Buckets #########\n\n") config.__setitem__("region", ct.region_dict[reg]) region = reg.capitalize() buckets_client = ObjectStorageClient(config=config, retry_strategy = oci.retry.DEFAULT_RETRY_STRATEGY, signer=signer) namespace = buckets_client.get_namespace().data namespace_name = namespace + state = {'path':f'{outdir}/{reg}/{service_dir}','resources':[]} + try: + byteOutput = sp.check_output(tf_state_list, cwd=state["path"],stderr=sp.DEVNULL ) + output = byteOutput.decode('UTF-8').rstrip() + for item in output.split('\n'): + state["resources"].append(item.replace("\"","\\\"")) + except Exception as e: + pass + for ntk_compartment_name in export_compartments: ossbuckets = oci.pagination.list_call_get_all_results(buckets_client.list_buckets,namespace,compartment_id = ct.ntk_compartment_ids[ntk_compartment_name]) for bucket in ossbuckets.data: + bucket_name = bucket.name ##buckets info## try: bucket_data = buckets_client.get_bucket(namespace_name, bucket_name, fields=['autoTiering']).data except Exception as e: print("Skipping Bucket "+bucket_name +" because of some issue. Check OCI console for details") + bucket_data=None continue - + total_resources+=1 #Get Retention Policies for bucket retention_policies = buckets_client.list_retention_rules(namespace_name, bucket_name).data retention_rule_data_list = [] @@ -315,13 +330,17 @@ def export_buckets(inputfile, outdir, service_dir, config, signer, ct, export_co else: lf_prefix[lf_name] = [lf_inclusion_prefixes] - print_buckets(region, outdir, service_dir,bucket_data, values_for_column, ntk_compartment_name, namespace_name,rp_id,retention_rule_data,rp_details,rp_name,lf_name_list,lf_name,lf_mapping,lf_excl,lf_incl,lf_prefix,ta_map,tgt_map) + print_buckets(region, outdir, service_dir,state,bucket_data, values_for_column, ntk_compartment_name, namespace_name,rp_id,retention_rule_data,rp_details,rp_name,lf_name_list,lf_name,lf_mapping,lf_excl,lf_incl,lf_prefix,ta_map,tgt_map) commonTools.write_to_cd3(values_for_column, cd3file, sheetName) - print("{0} Buckets exported into CD3.\n".format(len(values_for_column["Region"]))) + print("{0} Buckets exported into CD3.\n".format(total_resources)) + # writing data for reg in export_regions: script_file = f'{outdir}/{reg}/{service_dir}/' + file_name - with open(script_file, 'a') as importCommands[reg]: - importCommands[reg].write('\n\nterraform plan\n') + init_commands = f'\n######### Writing import for Buckets #########\n\n#!/bin/bash\n{tf_or_tofu} init' + if importCommands[reg] != "": + importCommands[reg] += f'\n{tf_or_tofu} plan\n' + with open(script_file, 'a') as importCommandsfile: + importCommandsfile.write(init_commands+importCommands[reg]) \ No newline at end of file diff --git a/cd3_automation_toolkit/commonTools.py b/cd3_automation_toolkit/commonTools.py old mode 100755 new mode 100644 index 7329954c3..cd61a60e9 --- a/cd3_automation_toolkit/commonTools.py +++ b/cd3_automation_toolkit/commonTools.py @@ -46,6 +46,13 @@ class commonTools(): drg_auto_RTs = {'Autogenerated Drg Route Table for RPC, VC, and IPSec attachments', 'Autogenerated Drg Route Table for VCN attachments'} drg_auto_RDs = {'Autogenerated Import Route Distribution for ALL routes', 'Autogenerated Import Route Distribution for VCN Routes'} + def setInputParameters(self, prefix, outdir, inputfile, tf_or_tofu): + self.prefix = prefix + self.outdir = outdir + self.inputfile = inputfile + self.tf_or_tofu = tf_or_tofu + + #Read Regions and Protocols Files and Excel_Columns and create dicts def __init__(self): self.all_regions=[] @@ -79,6 +86,17 @@ def __init__(self): self.fwl_pol_pattern_filter = None self.attached_policy_only = None + self.fsdr_ex_filename = None + self.fsdr_ex_sheet = None + self.fsdr_ex_ocid = None + self.fsdr_up_filename = None + self.fsdr_up_sheet = None + self.fsdr_up_ocid = None + + self.prefix='' + self.outdir='' + self.inputfile='' + self.tf_or_tofu = 'terraform' # When called from wthin OCSWorkVM or user-scripts dir=os.getcwd() @@ -192,6 +210,19 @@ def get_export_filters(self,export_filters): if 'attached_policy_only' in i: self.attached_policy_only = (i.split("=")[1])[2:][:-2] + if 'fsdr_ex_filename' in i: + self.fsdr_ex_filename = (i.split("=")[1])[2:][:-2] + if 'fsdr_ex_sheet' in i: + self.fsdr_ex_sheet = (i.split("=")[1])[2:][:-2] + if 'fsdr_ex_ocid' in i: + self.fsdr_ex_ocid = (i.split("=")[1])[2:][:-2] + if 'fsdr_up_filename' in i: + self.fsdr_up_filename = (i.split("=")[1])[2:][:-2] + if 'fsdr_up_sheet' in i: + self.fsdr_up_sheet = (i.split("=")[1])[2:][:-2] + if 'fsdr_up_ocid' in i: + self.fsdr_up_ocid = (i.split("=")[1])[2:][:-2] + # OCI API Authentication def authenticate(self,auth_mechanism,config_file_path=DEFAULT_LOCATION): diff --git a/cd3_automation_toolkit/example/CD3-Blank-template.xlsx b/cd3_automation_toolkit/example/CD3-Blank-template.xlsx index a257f4f2901261f895dd8ee52c1deb4f60b6c413..d3a7f7dde72e90b7bd87d835e9b12aa2f9001199 100644 GIT binary patch delta 121826 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 LhI!QmbCCH9@!IlC delta 121049 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 diff --git a/cd3_automation_toolkit/example/CD3-CIS-template.xlsx b/cd3_automation_toolkit/example/CD3-CIS-template.xlsx index ead7234e231815d221bcdefef1a954e7200be28f..13cc3ad95a69ee0984ae6de8e1e0968fd2e7eb52 100644 GIT binary patch delta 150567 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∓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

  • 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

    Rlj&?3Nf=vGe% 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

    %Y1;@whtnbF6~g$ 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 A?f?J) delta 130241 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

    Gh-*E;4& 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 Zswg6ZmjDomKls-LUUNO#1rI{V{{qCvi;MsO delta 148741 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 z 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