|
| 1 | +#!/usr/bin/env bash |
| 2 | +# |
| 3 | +# Run on: LOCAL MACHINE (workstation with Azure CLI installed). |
| 4 | +# Purpose: Create the application rules required by an ARO disconnected cluster. |
| 5 | +# Based on: https://github.com/redhat-cop/ocp-disconnected-docs/blob/main/AROInstall.md |
| 6 | +# Requires: An ARO cluster and Azure Firewall created by install-aro-disconnected.sh. |
| 7 | +# |
| 8 | + |
| 9 | +set -euo pipefail |
| 10 | + |
| 11 | +SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd) |
| 12 | + |
| 13 | +print_status() { |
| 14 | + printf '[INFO] %s\n' "$1" |
| 15 | +} |
| 16 | + |
| 17 | +print_warning() { |
| 18 | + printf '[WARNING] %s\n' "$1" |
| 19 | +} |
| 20 | + |
| 21 | +print_error() { |
| 22 | + printf '[ERROR] %s\n' "$1" >&2 |
| 23 | +} |
| 24 | + |
| 25 | +if [[ ! -f "${SCRIPT_DIR}/.env" ]]; then |
| 26 | + print_error 'Missing .env. Copy .env.example to .env and edit it first.' |
| 27 | + exit 1 |
| 28 | +fi |
| 29 | + |
| 30 | +# shellcheck disable=SC1091 |
| 31 | +source "${SCRIPT_DIR}/.env" |
| 32 | + |
| 33 | +if [[ -z "${RESOURCEGROUP:-}" || -z "${FIREWALL_NAME:-}" || -z "${FIREWALL_COLLECTION_NAME:-}" ]]; then |
| 34 | + print_error 'RESOURCEGROUP, FIREWALL_NAME, and FIREWALL_COLLECTION_NAME are required.' |
| 35 | + exit 1 |
| 36 | +fi |
| 37 | + |
| 38 | +RESOURCE_GROUP="$RESOURCEGROUP" |
| 39 | +RULE_COLLECTION_NAME="$FIREWALL_COLLECTION_NAME" |
| 40 | +SOURCE_ADDRESSES=(10.0.0.0/24 10.0.1.0/24) |
| 41 | +PROTOCOLS=(Http=80 Https=443) |
| 42 | +RULE_NAMES=( |
| 43 | + azure |
| 44 | + redhat |
| 45 | + ms-graph |
| 46 | + github |
| 47 | + gitlab |
| 48 | + pagerduty |
| 49 | + quay |
| 50 | + okta |
| 51 | + auth0 |
| 52 | + atlassian |
| 53 | + atlassian-third-party |
| 54 | +) |
| 55 | +RULE_TARGETS=( |
| 56 | + 'management.azure.com mirror.openshift.com login.microsoftonline.com gcs.prod.monitoring.core.windows.net *.blob.core.windows.net *.servicebus.windows.net *.table.core.windows.net' |
| 57 | + '*.redhat.com redhat.com redhat.io *.redhat.io' |
| 58 | + 'graph.microsoft.com' |
| 59 | + '*.github.com github.com *.githubusercontent.com' |
| 60 | + 'gitlab.com *.gitlab.com *.gitlab.io' |
| 61 | + '*.pagerduty.com pagerduty.com' |
| 62 | + 'quay.io *.quay.io' |
| 63 | + '*.okta.com *.mtls.okta.com *.oktapreview.com *.mtls.oktapreview.com *.oktacdn.com *.okta-emea.com *.mtls.okta-emea.com *.kerberos.okta.com *.kerberos.okta-emea.com *.kerberos.oktapreview.com *.okta-gov.com *.mtls.okta-gov.com *.okta.mil *.mtls.okta.mil *.awsglobalaccelerator.com' |
| 64 | + 'auth0.com *.auth0.com' |
| 65 | + '*.atlassian.com atlassian.com' |
| 66 | + '*.pndsn.com *.cloudfront.net *.wp.com *.gravatar.com *.googleapis.com' |
| 67 | +) |
| 68 | + |
| 69 | +check_prerequisites() { |
| 70 | + print_status 'Checking prerequisites' |
| 71 | + if ! command -v az > /dev/null 2>&1; then |
| 72 | + print_error 'Azure CLI is not installed.' |
| 73 | + exit 1 |
| 74 | + fi |
| 75 | + if ! az account show > /dev/null 2>&1; then |
| 76 | + print_error "Not logged in to Azure. Run 'az login' first." |
| 77 | + exit 1 |
| 78 | + fi |
| 79 | +} |
| 80 | + |
| 81 | +check_firewall() { |
| 82 | + print_status "Checking firewall: ${FIREWALL_NAME}" |
| 83 | + if ! az network firewall show \ |
| 84 | + --resource-group "$RESOURCE_GROUP" \ |
| 85 | + --name "$FIREWALL_NAME" > /dev/null; then |
| 86 | + print_error "Firewall '${FIREWALL_NAME}' not found in resource group '${RESOURCE_GROUP}'." |
| 87 | + exit 1 |
| 88 | + fi |
| 89 | +} |
| 90 | + |
| 91 | +check_existing_rule_collection() { |
| 92 | + print_status "Checking rule collection: ${RULE_COLLECTION_NAME}" |
| 93 | + if ! az network firewall application-rule collection show \ |
| 94 | + --resource-group "$RESOURCE_GROUP" \ |
| 95 | + --firewall-name "$FIREWALL_NAME" \ |
| 96 | + --collection-name "$RULE_COLLECTION_NAME" > /dev/null 2>&1; then |
| 97 | + print_status "Rule collection '${RULE_COLLECTION_NAME}' does not exist." |
| 98 | + return |
| 99 | + fi |
| 100 | + |
| 101 | + print_warning "Rule collection '${RULE_COLLECTION_NAME}' already exists." |
| 102 | + read -r -p 'Overwrite it? (y/N): ' -n 1 REPLY || REPLY='' |
| 103 | + printf '\n' |
| 104 | + if [[ ! "$REPLY" =~ ^[Yy]$ ]]; then |
| 105 | + print_status 'Operation cancelled.' |
| 106 | + exit 0 |
| 107 | + fi |
| 108 | + |
| 109 | + print_status "Removing existing rule collection: ${RULE_COLLECTION_NAME}" |
| 110 | + az network firewall application-rule collection delete \ |
| 111 | + --resource-group "$RESOURCE_GROUP" \ |
| 112 | + --firewall-name "$FIREWALL_NAME" \ |
| 113 | + --collection-name "$RULE_COLLECTION_NAME" |
| 114 | +} |
| 115 | + |
| 116 | +create_application_rule() { |
| 117 | + local rule_name="$1" |
| 118 | + local target_definition="$2" |
| 119 | + local rule_index="$3" |
| 120 | + local -a target_fqdns |
| 121 | + local -a command |
| 122 | + |
| 123 | + read -r -a target_fqdns <<< "$target_definition" |
| 124 | + command=( |
| 125 | + az network firewall application-rule create |
| 126 | + --resource-group "$RESOURCE_GROUP" |
| 127 | + --firewall-name "$FIREWALL_NAME" |
| 128 | + --collection-name "$RULE_COLLECTION_NAME" |
| 129 | + --name "$rule_name" |
| 130 | + --target-fqdns "${target_fqdns[@]}" |
| 131 | + --source-addresses "${SOURCE_ADDRESSES[@]}" |
| 132 | + --protocols "${PROTOCOLS[@]}" |
| 133 | + ) |
| 134 | + |
| 135 | + if [[ "$rule_index" -eq 0 ]]; then |
| 136 | + command+=(--action Allow --priority 200) |
| 137 | + fi |
| 138 | + |
| 139 | + print_status "Adding firewall rule: ${rule_name}" |
| 140 | + "${command[@]}" |
| 141 | +} |
| 142 | + |
| 143 | +create_rule_collection() { |
| 144 | + print_status "Creating firewall rule collection: ${RULE_COLLECTION_NAME}" |
| 145 | + if [[ "${#RULE_NAMES[@]}" -ne "${#RULE_TARGETS[@]}" ]]; then |
| 146 | + print_error 'Firewall rule names and target definitions are out of sync.' |
| 147 | + exit 1 |
| 148 | + fi |
| 149 | + |
| 150 | + for rule_index in "${!RULE_NAMES[@]}"; do |
| 151 | + create_application_rule \ |
| 152 | + "${RULE_NAMES[$rule_index]}" \ |
| 153 | + "${RULE_TARGETS[$rule_index]}" \ |
| 154 | + "$rule_index" |
| 155 | + done |
| 156 | +} |
| 157 | + |
| 158 | +check_prerequisites |
| 159 | +check_firewall |
| 160 | +check_existing_rule_collection |
| 161 | +create_rule_collection |
| 162 | +print_status "Rule collection '${RULE_COLLECTION_NAME}' created successfully." |
0 commit comments