github.com/gravitational/teleport/api@v0.0.0-20240507183017-3110591cbafc/types/installers/installer.sh.tmpl (about)

     1  #!/usr/bin/env bash
     2  # shellcheck disable=SC1083,SC2215,SC2288 # caused by Go templating, and shellcheck won't parse if the lines are excluded individually
     3  
     4  set -eu
     5  
     6  upgrade_endpoint="{{ .PublicProxyAddr }}/v1/webapi/automaticupgrades/channel/default"
     7  
     8  # upgrade_endpoint_fetch loads the specified value from the upgrade endpoint. the only
     9  # currently supported values are 'version' and 'critical'.
    10  upgrade_endpoint_fetch() {
    11      host_path="${upgrade_endpoint}/${1}"
    12  
    13      if sf_output="$(curl --proto '=https' --tlsv1.2 -sSf "https://${host_path}")"; then
    14          # emit output with empty lines and extra whitespace removed
    15          echo "$sf_output" | grep -v -e '^[[:space:]]*$' | awk '{$1=$1};1'
    16          return 0
    17      else
    18          return 1
    19      fi
    20  }
    21  
    22  # get_target_version loads the current value of the /version endpoint.
    23  get_target_version() {
    24      if tv_output="$(upgrade_endpoint_fetch version)"; then
    25          # emit version string with leading 'v' removed if one is present
    26          echo "${tv_output#v}"
    27          return 0
    28      fi
    29      return 1
    30  }
    31  
    32  on_ec2() {
    33    IMDS_TOKEN=$(curl -m5 -sS -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 300")
    34    [ -z "$IMDS_TOKEN" ] && return 1
    35    EC2_STATUS=$(curl -o /dev/null -w "%{http_code}" -m5 -sS -H "X-aws-ec2-metadata-token: ${IMDS_TOKEN}" "http://169.254.169.254/latest/meta-data")
    36    [ "$EC2_STATUS" = "200" ]
    37  }
    38  
    39  on_azure() {
    40    AZURE_STATUS=$(curl -o /dev/null -w "%{http_code}" -m5 -sS -H "Metadata: true" --noproxy "*" "http://169.254.169.254/metadata/instance?api-version=2021-02-01")
    41    [ "$AZURE_STATUS" = "200" ]
    42  }
    43  
    44  on_gcp() {
    45    GCP_STATUS=$(curl -o /dev/null -w "%{http_code}" -m5 -sS -H "Metadata-Flavor: Google" "http://metadata.google.internal/")
    46    [ "$GCP_STATUS" = "200" ]
    47  }
    48  
    49  (
    50    flock -n 9 || exit 1
    51    if test -f /usr/local/bin/teleport; then
    52      exit 0
    53    fi
    54    # shellcheck disable=SC1091
    55    . /etc/os-release
    56  
    57    TELEPORT_PACKAGE="{{ .TeleportPackage }}"
    58    TELEPORT_UPDATER_PACKAGE="{{ .TeleportPackage }}-updater"
    59  
    60    if [ "$ID" = "debian" ] || [ "$ID" = "ubuntu" ]; then
    61      # old versions of ubuntu require that keys get added by `apt-key add`, without
    62      # adding the key apt shows a key signing error when installing teleport.
    63      if [ "$VERSION_CODENAME" = "xenial" ] || [ "$VERSION_CODENAME" = "trusty" ]; then
    64        curl -o /tmp/teleport-pubkey.asc https://apt.releases.teleport.dev/gpg
    65        sudo apt-key add /tmp/teleport-pubkey.asc
    66        echo "deb https://apt.releases.teleport.dev/ubuntu ${VERSION_CODENAME?} {{ .RepoChannel }}" | sudo tee /etc/apt/sources.list.d/teleport.list
    67        rm /tmp/teleport-pubkey.asc
    68      else
    69        sudo curl https://apt.releases.teleport.dev/gpg \
    70          -o /usr/share/keyrings/teleport-archive-keyring.asc
    71        echo "deb [signed-by=/usr/share/keyrings/teleport-archive-keyring.asc]  https://apt.releases.teleport.dev/${ID?} ${VERSION_CODENAME?} {{ .RepoChannel }}" | sudo tee /etc/apt/sources.list.d/teleport.list >/dev/null
    72      fi
    73      sudo apt-get update
    74  
    75      # shellcheck disable=SC2050
    76      if [ "{{ .AutomaticUpgrades }}" = "true" ]; then
    77        # automatic upgrades
    78        if ! target_version="$(get_target_version)"; then
    79          # error getting the target version
    80          sudo apt-get install -y "$TELEPORT_PACKAGE" jq "$TELEPORT_UPDATER_PACKAGE"
    81        elif [ "$target_version" == "none" ]; then
    82          # no target version advertised
    83          sudo apt-get install -y "$TELEPORT_PACKAGE" jq "$TELEPORT_UPDATER_PACKAGE"
    84        else
    85          # successfully retrieved target version
    86          sudo apt-get install -y "$TELEPORT_PACKAGE=$target_version" jq "$TELEPORT_UPDATER_PACKAGE=$target_version"
    87        fi
    88      else
    89        # no automatic upgrades
    90        sudo apt-get install -y "$TELEPORT_PACKAGE" jq
    91      fi
    92  
    93    elif [ "$ID" = "amzn" ] || [ "$ID" = "rhel" ]; then
    94      if [ "$ID" = "rhel" ]; then
    95        VERSION_ID=${VERSION_ID//\.*/} # convert version numbers like '7.2' to only include the major version
    96      fi
    97      sudo yum install -y yum-utils
    98      sudo yum-config-manager --add-repo \
    99        "$(rpm --eval "https://yum.releases.teleport.dev/$ID/$VERSION_ID/Teleport/%{_arch}/{{ .RepoChannel }}/teleport.repo")"
   100  
   101      # shellcheck disable=SC2050
   102      if [ "{{ .AutomaticUpgrades }}" = "true" ]; then
   103        # automatic upgrades
   104        if ! target_version="$(get_target_version)"; then
   105          # error getting the target version
   106          sudo yum install -y "$TELEPORT_PACKAGE" jq "$TELEPORT_UPDATER_PACKAGE"
   107        elif [ "$target_version" == "none" ]; then
   108          # no target version advertised
   109          sudo yum install -y "$TELEPORT_PACKAGE" jq "$TELEPORT_UPDATER_PACKAGE"
   110        else
   111          # successfully retrieved target version
   112          sudo yum install -y "$TELEPORT_PACKAGE-$target_version" jq "$TELEPORT_UPDATER_PACKAGE-$target_version"
   113        fi
   114      else
   115        # no automatic upgrades
   116        sudo yum install -y "$TELEPORT_PACKAGE" jq
   117      fi
   118  
   119    elif [ "$ID" = "sles" ] || [ "$ID" = "opensuse-tumbleweed" ] || [ "$ID" = "opensuse-leap" ]; then
   120      if [ "$ID" = "opensuse-tumbleweed" ]; then
   121        VERSION_ID="15" # tumbleweed uses dated VERSION_IDs like 20230702
   122      else
   123        VERSION_ID="${VERSION_ID//.*/}" # convert version numbers like '7.2' to only include the major version
   124      fi
   125      sudo rpm --import "https://zypper.releases.teleport.dev/gpg"
   126      sudo zypper --non-interactive addrepo "$(rpm --eval "https://zypper.releases.teleport.dev/sles/$VERSION_ID/Teleport/%{_arch}/{{ .RepoChannel }}/teleport.repo")"
   127      sudo zypper --gpg-auto-import-keys refresh
   128  
   129      # shellcheck disable=SC2050
   130      if [ "{{ .AutomaticUpgrades }}" = "true" ]; then
   131        # automatic upgrades
   132        if ! target_version="$(get_target_version)"; then
   133          # error getting the target version
   134          sudo zypper --non-interactive install -y "$TELEPORT_PACKAGE" jq "$TELEPORT_UPDATER_PACKAGE"
   135        elif [ "$target_version" == "none" ]; then
   136          # no target version advertised
   137          sudo zypper --non-interactive install -y "$TELEPORT_PACKAGE" jq "$TELEPORT_UPDATER_PACKAGE"
   138        else
   139          # successfully retrieved target version
   140          sudo zypper --non-interactive install -y "$TELEPORT_PACKAGE-$target_version" jq "$TELEPORT_UPDATER_PACKAGE-$target_version"
   141        fi
   142      else
   143        # no automatic upgrades
   144        sudo zypper --non-interactive install -y "$TELEPORT_PACKAGE" jq
   145      fi
   146    else
   147      echo "Unsupported distro: $ID"
   148      exit 1
   149    fi
   150  
   151    if on_azure; then
   152      API_VERSION=$(curl -m5 -sS -H "Metadata: true" --noproxy "*" "http://169.254.169.254/metadata/versions" | jq -r ".apiVersions[-1]")
   153      INSTANCE_INFO=$(curl -m5 -sS -H "Metadata: true" --noproxy "*" "http://169.254.169.254/metadata/instance?api-version=$API_VERSION&format=json")
   154  
   155      REGION="$(echo "$INSTANCE_INFO" | jq -r .compute.location)"
   156      RESOURCE_GROUP="$(echo "$INSTANCE_INFO" | jq -r .compute.resourceGroupName)"
   157      SUBSCRIPTION_ID="$(echo "$INSTANCE_INFO" | jq -r .compute.subscriptionId)"
   158      VM_ID="$(echo "$INSTANCE_INFO" | jq -r .compute.vmId)"
   159  
   160      JOIN_METHOD=azure
   161      LABELS="teleport.internal/vm-id=${VM_ID},teleport.internal/subscription-id=${SUBSCRIPTION_ID},teleport.internal/region=${REGION},teleport.internal/resource-group=${RESOURCE_GROUP}"
   162    elif on_ec2; then
   163      IMDS_TOKEN=$(curl -m5 -sS -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 300")
   164      INSTANCE_INFO=$(curl -m5 -sS -H "X-aws-ec2-metadata-token: ${IMDS_TOKEN}" "http://169.254.169.254/latest/dynamic/instance-identity/document")
   165  
   166      ACCOUNT_ID="$(echo "$INSTANCE_INFO" | jq -r .accountId)"
   167      INSTANCE_ID="$(echo "$INSTANCE_INFO" | jq -r .instanceId)"
   168  
   169      JOIN_METHOD=iam
   170      LABELS="teleport.dev/instance-id=${INSTANCE_ID},teleport.dev/account-id=${ACCOUNT_ID}"
   171    elif on_gcp; then
   172      NAME="$(curl -m5 -sS -H "Metadata-Flavor:Google" "http://metadata.google.internal/computeMetadata/v1/instance/name")"
   173      # GCP metadata returns fully qualified zone ("projects/<project-id>/zones/<zone>"), so we need to parse the zone name.
   174      FULL_ZONE="$(curl -m5 -sS -H "Metadata-Flavor:Google" "http://metadata.google.internal/computeMetadata/v1/instance/zone")"
   175      ZONE="$(basename $FULL_ZONE)"
   176      PROJECT_ID=$(curl -m5 -sS -H "Metadata-Flavor: Google" "http://metadata.google.internal/computeMetadata/v1/project/project-id")
   177  
   178      JOIN_METHOD=gcp
   179      LABELS="teleport.internal/name=${NAME},teleport.internal/zone=${ZONE},teleport.internal/project-id=${PROJECT_ID}"
   180    else
   181      echo "Could not determine cloud provider"
   182      exit 1
   183    fi
   184  
   185    # generate teleport ssh config
   186    # token is read as a parameter from the AWS ssm script run and
   187    # passed as the first argument to the script
   188    sudo /usr/local/bin/teleport node configure \
   189      --proxy="{{ .PublicProxyAddr }}" \
   190      --join-method=${JOIN_METHOD} \
   191      {{- if .AzureClientID }}
   192      --azure-client-id="{{ .AzureClientID }}" \
   193      {{ end -}}
   194      --token="$1" \
   195      --output=file \
   196      --labels="${LABELS}"
   197  
   198    # enable and start teleport service
   199    sudo systemctl enable --now teleport
   200  
   201  ) 9>/var/lock/teleport_install.lock