diff --git a/bin/update-ips.bash b/bin/update-ips.bash index d8fa750af7..0be8f6307c 100755 --- a/bin/update-ips.bash +++ b/bin/update-ips.bash @@ -71,14 +71,103 @@ diffDNSIPs() { # Updates the list from the file and yaml path specified with IPs fetched from the domain updateDNSIPs() { - read -r -a IPS <<< "$(getDNSIPs "${1}")" - yq4 -i "${2}"' = []' "${3}" - for ip in "${IPS[@]}"; do - yq4 -i "${2}"' |= . + ["'"${ip}"'/32"]' "${3}" - done + endpoint="${1}" + inputSource="${2}" + inputConfig="$3" + + read -r -a IPS <<<"$(getDNSIPs "${endpoint}")" + + IPS_copy=("${IPS[@]}") + + configIPS=() + while IFS= read -r line; do + if [[ $line != */32 ]]; then + configIPS+=("${line//[- ]/}") + fi + done < <(yq4 e "$inputSource" "$inputConfig") + + inside_subnet=() + working_subnet=() + + # Clear config-values + yq4 -i "$inputSource"' = []' "$inputConfig" + + # IF config-value is not empty, go ahread with the following: + # 1. Check if any got kubectlIPs fits inside of the IPs existing in the config-files. + # 2. IF True = Put the working subnet-address and kube-address in assigned arrays for comparison and remove copies. + # 3. Merge the working subnet-adresses and kube-addresses into a finalized list. + if [ "${configIPS[*]}" != '[]' ]; then + for kubectlIP in "${IPS_copy[@]}"; do + + for configIP in "${configIPS[@]}"; do + + output=$(python3 -c " +import ipaddress +try: + result = ipaddress.ip_address('${kubectlIP}') in ipaddress.ip_network('${configIP}') + print('True' if result else 'False') +except ipaddress.AddressValueError: + print('Invalid IP address') +except Exception as e: + print('Error:', e) +") + + if [[ $output == "True" ]]; then + if [[ " ${inside_subnet[*]} " != *" $kubectlIP "* ]]; then + + inside_subnet+=("$kubectlIP") + + # Create a new array without the matching string + filtered_array=() + + for kubectl_ip in "${IPS[@]}"; do + if [[ "$kubectl_ip" != "$kubectlIP" ]]; then + filtered_array+=("$kubectl_ip") + fi + done + + IPS=("${filtered_array[@]}") + fi + + if [[ " ${working_subnet[*]} " != *" $configIP "* ]]; then + + working_subnet+=("$configIP") + fi + elif [[ $output == "False" ]]; then + : + else + echo "$output". This string is disregarded. + fi + + done + + done + + working_subnet+=("${IPS[@]}") + + merged_array=("${working_subnet[@]}") + + for ip in "${merged_array[@]}"; do + + if [[ $ip =~ "/" ]]; then + + yq4 -i "${inputSource}"' |= . + ["'"${ip}"'"]' "${inputConfig}" + else + yq4 -i "${inputSource}"' |= . + ["'"${ip}"'/32"]' "${inputConfig}" + fi + done + + else + + for ip in "${IPS[@]}"; do + yq4 -i "${inputSource}"' |= . + ["'"${ip}"'/32"]' "${inputConfig}" + done + + fi } + # Fetches the Internal IP and calico tunnel ip of kubernetes nodes using the label selector. # If label selector isn't specified, all nodes will be returned. getKubectlIPs() { @@ -109,13 +198,112 @@ diffKubectlIPs() { # Updates the list from the file and yaml path specified with IPs fetched from the nodes updateKubectlIPs() { + + cloud="${1}" + label="${2}" + inputSource="${3}" + inputConfig="${4}" + local IPS - read -r -a IPS <<< "$(getKubectlIPs "${1}" "${2}")" + read -r -a IPS <<<"$(getKubectlIPs "$cloud" "$label")" - yq4 -i "${3}"' = []' "${4}" - for ip in "${IPS[@]}"; do - yq4 -i "${3}"' |= . + ["'"${ip}"'/32"]' "${4}" - done + # Create copy of the kube-addresses array for for-loop purposes only + IPS_copy=("${IPS[@]}") + + configIPS=() + + # Read config-values and assign it to a array + while IFS= read -r line; do + if [[ $line != */32 ]]; then + configIPS+=("${line//[- ]/}") + fi + done < <(yq4 e "$inputSource" "$inputConfig") + + inside_subnet=() + working_subnet=() + + # Clear config-values + yq4 -i "$inputSource"' = []' "$inputConfig" + + # IF config-value is not empty, go ahread with the following: + # 1. Check if any got kubectlIPs fits inside of the IPs existing in the config-files. + # 2. IF True = Put the working subnet-address and kube-address in assigned arrays for comparison and remove copies. + # 3. Merge the working subnet-adresses and kube-addresses into a finalized list. + if [ "${configIPS[*]}" != '[]' ]; then + for kubectlIP in "${IPS_copy[@]}"; do + + for configIP in "${configIPS[@]}"; do + + output=$(python3 -c " +import ipaddress +try: + result = ipaddress.ip_address('${kubectlIP}') in ipaddress.ip_network('${configIP}') + print('True' if result else 'False') +except ipaddress.AddressValueError: + print('Invalid IP address') +except Exception as e: + print('Error:', e) +") + + if [[ $output == "True" ]]; then + if [[ " ${inside_subnet[*]} " != *" $kubectlIP "* ]]; then + + inside_subnet+=("$kubectlIP") + + # Create a new array without the matching string. + filtered_array=() + + for kubectl_ip in "${IPS[@]}"; do + if [[ "$kubectl_ip" != "$kubectlIP" ]]; then + filtered_array+=("$kubectl_ip") + fi + done + + + # Create and set a clean kubeIP list without copies. + IPS=("${filtered_array[@]}") + fi + + if [[ " ${working_subnet[*]} " != *" $configIP "* ]]; then + + working_subnet+=("$configIP") + fi + + # IF kubeIP does not fit into subnet, do nothing. + elif [[ $output == "False" ]]; then + : + # IF the subnet-check crashes, type it out. + else + echo "$output". This string is disregarded. + fi + done + + done + + # Add the working subnet-adresses and working kubeIPs together. + working_subnet+=("${IPS[@]}") + + merged_array=("${working_subnet[@]}") + + # Put the finalized IP list into the config-file. + for ip in "${merged_array[@]}"; do + + if [[ $ip =~ "/" ]]; then + yq4 -i "${inputSource}"' |= . + ["'"${ip}"'"]' "${inputConfig}" + else + yq4 -i "${inputSource}"' |= . + ["'"${ip}"'/32"]' "${inputConfig}" + fi + done + + else + + # If their was no config-values to take in concideration for the subnet-check, put in all kubeIPs. + yq4 -i "${inputSource}"' = []' "${inputConfig}" + for ip in "${IPS[@]}"; do + yq4 -i "${inputSource}"' |= . + ["'"${ip}"'/32"]' "${inputConfig}" + done + + fi } checkIfDiffAndUpdateDNSIPs() {