|
60 | 60 | fi |
61 | 61 |
|
62 | 62 | echo "Checking for firewall rule '${SUBNET_NAME}'..." |
63 | | -current_fw="$(gcloud compute firewall-rules describe "${SUBNET_NAME}" \ |
| 63 | +existing_fw_name="$(gcloud compute firewall-rules list \ |
64 | 64 | --project="${GCP_PROJECT_ID}" \ |
65 | | - --format='csv[no-heading](network.basename(),direction,allowed[0].IPProtocol,sourceRanges[0],disabled)' \ |
66 | | - 2>"${gcloud_stderr}")" && fw_exists=true || fw_exists=false |
67 | | - |
68 | | -if ${fw_exists}; then |
69 | | - expected_fw="${GCP_NETWORK_NAME},INGRESS,all,${SUBNET_CIDR},False" |
70 | | - if [[ "${current_fw}" != "${expected_fw}" ]]; then |
71 | | - echo "ERROR: Firewall rule '${SUBNET_NAME}' exists but is misconfigured." |
72 | | - echo " Expected: ${expected_fw}" |
73 | | - echo " Actual: ${current_fw}" |
74 | | - exit 1 |
75 | | - fi |
76 | | - # Validate target tags independently; sort before comparing since order is not deterministic |
77 | | - current_tags="$(gcloud compute firewall-rules describe "${SUBNET_NAME}" \ |
78 | | - --project="${GCP_PROJECT_ID}" \ |
79 | | - --format='value(targetTags.list())' \ |
80 | | - 2>"${gcloud_stderr}" \ |
81 | | - | tr ',;' '\n' | LC_ALL=C sort | tr '\n' ',' | sed 's/,$//')" && current_tags_read=true || current_tags_read=false |
82 | | - if ! ${current_tags_read}; then |
83 | | - echo "ERROR: gcloud describe failed while reading target tags for firewall rule '${SUBNET_NAME}':" |
84 | | - cat "${gcloud_stderr}" >&2 |
85 | | - exit 1 |
86 | | - fi |
87 | | - expected_tags="$(printf '%s\n' ${FIREWALL_TAGS//,/ } | LC_ALL=C sort | tr '\n' ',' | sed 's/,$//')" |
88 | | - if [[ "${current_tags}" != "${expected_tags}" ]]; then |
89 | | - echo "ERROR: Firewall rule '${SUBNET_NAME}' has wrong target tags." |
90 | | - echo " Expected: ${expected_tags}" |
91 | | - echo " Actual: ${current_tags}" |
92 | | - exit 1 |
| 65 | + --filter="name=('${SUBNET_NAME}')" \ |
| 66 | + --format='value(name)' \ |
| 67 | + 2>"${gcloud_stderr}")" && fw_lookup_ok=true || fw_lookup_ok=false |
| 68 | + |
| 69 | +if ${fw_lookup_ok}; then |
| 70 | + if [[ -n "${existing_fw_name}" ]]; then |
| 71 | + current_fw_json="$(gcloud compute firewall-rules describe "${SUBNET_NAME}" \ |
| 72 | + --project="${GCP_PROJECT_ID}" \ |
| 73 | + --format=json \ |
| 74 | + 2>"${gcloud_stderr}")" |
| 75 | + |
| 76 | + # Validate network, direction, disabled |
| 77 | + actual_network="$(echo "${current_fw_json}" | jq -r '.network | split("/") | last')" |
| 78 | + actual_direction="$(echo "${current_fw_json}" | jq -r '.direction')" |
| 79 | + actual_disabled="$(echo "${current_fw_json}" | jq -r '.disabled')" |
| 80 | + |
| 81 | + if [[ "${actual_network}" != "${GCP_NETWORK_NAME}" ]] || \ |
| 82 | + [[ "${actual_direction}" != "INGRESS" ]] || \ |
| 83 | + [[ "${actual_disabled}" != "false" ]]; then |
| 84 | + echo "ERROR: Firewall rule '${SUBNET_NAME}' exists but is misconfigured." |
| 85 | + echo " Expected network=${GCP_NETWORK_NAME}, direction=INGRESS, disabled=false" |
| 86 | + echo " Actual network=${actual_network}, direction=${actual_direction}, disabled=${actual_disabled}" |
| 87 | + exit 1 |
| 88 | + fi |
| 89 | + |
| 90 | + # Validate allowed (should be exactly [{IPProtocol: "all"}]) |
| 91 | + actual_allowed="$(echo "${current_fw_json}" | jq -c '[.allowed[] | {protocol: .IPProtocol, ports: (.ports // [])}] | sort_by(.protocol)')" |
| 92 | + expected_allowed='[{"protocol":"all","ports":[]}]' |
| 93 | + if [[ "${actual_allowed}" != "${expected_allowed}" ]]; then |
| 94 | + echo "ERROR: Firewall rule '${SUBNET_NAME}' has wrong allowed configuration." |
| 95 | + echo " Expected: ${expected_allowed}" |
| 96 | + echo " Actual: ${actual_allowed}" |
| 97 | + exit 1 |
| 98 | + fi |
| 99 | + |
| 100 | + # Validate sourceRanges (should be exactly the subnet CIDR) |
| 101 | + actual_ranges="$(echo "${current_fw_json}" | jq -c '(.sourceRanges // []) | sort')" |
| 102 | + expected_ranges="$(printf '["%s"]' "${SUBNET_CIDR}")" |
| 103 | + if [[ "${actual_ranges}" != "${expected_ranges}" ]]; then |
| 104 | + echo "ERROR: Firewall rule '${SUBNET_NAME}' has wrong source ranges." |
| 105 | + echo " Expected: ${expected_ranges}" |
| 106 | + echo " Actual: ${actual_ranges}" |
| 107 | + exit 1 |
| 108 | + fi |
| 109 | + |
| 110 | + # Validate targetTags (order-insensitive) |
| 111 | + actual_tags="$(echo "${current_fw_json}" | jq -c '(.targetTags // []) | sort')" |
| 112 | + expected_tags="$(printf '%s\n' ${FIREWALL_TAGS//,/ } | jq -R . | jq -sc 'sort')" |
| 113 | + if [[ "${actual_tags}" != "${expected_tags}" ]]; then |
| 114 | + echo "ERROR: Firewall rule '${SUBNET_NAME}' has wrong target tags." |
| 115 | + echo " Expected: ${expected_tags}" |
| 116 | + echo " Actual: ${actual_tags}" |
| 117 | + exit 1 |
| 118 | + fi |
| 119 | + |
| 120 | + echo "Firewall rule '${SUBNET_NAME}' already exists and matches expected configuration." |
| 121 | + else |
| 122 | + echo "Creating firewall rule '${SUBNET_NAME}'..." |
| 123 | + gcloud compute firewall-rules create "${SUBNET_NAME}" \ |
| 124 | + --network="${GCP_NETWORK_NAME}" \ |
| 125 | + --project="${GCP_PROJECT_ID}" \ |
| 126 | + --direction=INGRESS \ |
| 127 | + --priority=1000 \ |
| 128 | + --allow=all \ |
| 129 | + --source-ranges="${SUBNET_CIDR}" \ |
| 130 | + --target-tags="${FIREWALL_TAGS}" |
| 131 | + echo "Firewall rule '${SUBNET_NAME}' created." |
93 | 132 | fi |
94 | | - echo "Firewall rule '${SUBNET_NAME}' already exists and matches expected configuration." |
95 | | -elif grep -q "was not found" "${gcloud_stderr}"; then |
96 | | - echo "Creating firewall rule '${SUBNET_NAME}'..." |
97 | | - gcloud compute firewall-rules create "${SUBNET_NAME}" \ |
98 | | - --network="${GCP_NETWORK_NAME}" \ |
99 | | - --project="${GCP_PROJECT_ID}" \ |
100 | | - --direction=INGRESS \ |
101 | | - --priority=1000 \ |
102 | | - --allow=all \ |
103 | | - --source-ranges="${SUBNET_CIDR}" \ |
104 | | - --target-tags="${FIREWALL_TAGS}" |
105 | | - echo "Firewall rule '${SUBNET_NAME}' created." |
106 | 133 | else |
107 | | - echo "ERROR: gcloud describe failed for firewall rule '${SUBNET_NAME}':" |
| 134 | + echo "ERROR: gcloud firewall-rules lookup failed for '${SUBNET_NAME}':" |
108 | 135 | cat "${gcloud_stderr}" >&2 |
109 | 136 | exit 1 |
110 | 137 | fi |
|
0 commit comments