diff --git a/backport-AWS-agents-reuse-IMDS-token-until-it-expires-issue-1.patch b/backport-AWS-agents-reuse-IMDS-token-until-it-expires-issue-1.patch new file mode 100644 index 0000000000000000000000000000000000000000..be974fc6741a0575c6e25cea3aa2787775f2d456 --- /dev/null +++ b/backport-AWS-agents-reuse-IMDS-token-until-it-expires-issue-1.patch @@ -0,0 +1,267 @@ +From bfad7ecd6f968c35544dc1d115c32d9730d63267 Mon Sep 17 00:00:00 2001 +From: harshkiprofile <83770157+harshkiprofile@users.noreply.github.com> +Date: Wed, 6 Nov 2024 14:54:43 +0530 +Subject: [PATCH] AWS agents: reuse IMDS token until it expires (issue #1990) + (#1991) + +* Introduce a new shell function to reuse IMDS token +* Utilize the get_token function to reuse the token +* Move token renewal function to aws.sh for reuse in AWS agent scripts +--- + doc/man/Makefile.am | 2 +- + heartbeat/Makefile.am | 1 + + heartbeat/aws-vpc-move-ip | 7 ++---- + heartbeat/aws-vpc-route53.in | 7 ++---- + heartbeat/aws.sh | 46 ++++++++++++++++++++++++++++++++++++ + heartbeat/awseip | 7 ++---- + heartbeat/awsvip | 7 ++---- + heartbeat/ocf-shellfuncs.in | 2 +- + 8 files changed, 57 insertions(+), 22 deletions(-) + create mode 100644 heartbeat/aws.sh + +diff --git a/doc/man/Makefile.am b/doc/man/Makefile.am +index ef7639bf..447f5cba 100644 +--- a/doc/man/Makefile.am ++++ b/doc/man/Makefile.am +@@ -42,7 +42,7 @@ radir = $(abs_top_builddir)/heartbeat + # required for out-of-tree build + symlinkstargets = \ + ocf-distro ocf.py ocf-rarun ocf-returncodes \ +- findif.sh apache-conf.sh http-mon.sh mysql-common.sh \ ++ findif.sh apache-conf.sh aws.sh http-mon.sh mysql-common.sh \ + nfsserver-redhat.sh openstack-common.sh ora-common.sh + + preptree: +diff --git a/heartbeat/Makefile.am b/heartbeat/Makefile.am +index 40984797..8352f3a3 100644 +--- a/heartbeat/Makefile.am ++++ b/heartbeat/Makefile.am +@@ -218,6 +218,7 @@ ocfcommon_DATA = ocf-shellfuncs \ + ocf-rarun \ + ocf-distro \ + apache-conf.sh \ ++ aws.sh \ + http-mon.sh \ + sapdb-nosha.sh \ + sapdb.sh \ +diff --git a/heartbeat/aws-vpc-move-ip b/heartbeat/aws-vpc-move-ip +index 6115e5ba..3aa9ceb0 100755 +--- a/heartbeat/aws-vpc-move-ip ++++ b/heartbeat/aws-vpc-move-ip +@@ -33,6 +33,7 @@ + + : ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat} + . ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs ++. ${OCF_FUNCTIONS_DIR}/aws.sh + + # Defaults + OCF_RESKEY_awscli_default="/usr/bin/aws" +@@ -47,8 +48,6 @@ OCF_RESKEY_interface_default="eth0" + OCF_RESKEY_iflabel_default="" + OCF_RESKEY_monapi_default="false" + OCF_RESKEY_lookup_type_default="InstanceId" +-OCF_RESKEY_curl_retries_default="3" +-OCF_RESKEY_curl_sleep_default="1" + + : ${OCF_RESKEY_awscli=${OCF_RESKEY_awscli_default}} + : ${OCF_RESKEY_auth_type=${OCF_RESKEY_auth_type_default}} +@@ -62,8 +61,6 @@ OCF_RESKEY_curl_sleep_default="1" + : ${OCF_RESKEY_iflabel=${OCF_RESKEY_iflabel_default}} + : ${OCF_RESKEY_monapi=${OCF_RESKEY_monapi_default}} + : ${OCF_RESKEY_lookup_type=${OCF_RESKEY_lookup_type_default}} +-: ${OCF_RESKEY_curl_retries=${OCF_RESKEY_curl_retries_default}} +-: ${OCF_RESKEY_curl_sleep=${OCF_RESKEY_curl_sleep_default}} + ####################################################################### + + +@@ -270,7 +267,7 @@ ec2ip_validate() { + fi + fi + +- TOKEN=$(curl_retry "$OCF_RESKEY_curl_retries" "$OCF_RESKEY_curl_sleep" "--show-error -sX PUT -H 'X-aws-ec2-metadata-token-ttl-seconds: 21600'" "http://169.254.169.254/latest/api/token") ++ TOKEN=$(get_token) + [ $? -ne 0 ] && exit $OCF_ERR_GENERIC + EC2_INSTANCE_ID=$(curl_retry "$OCF_RESKEY_curl_retries" "$OCF_RESKEY_curl_sleep" "--show-error -s -H 'X-aws-ec2-metadata-token: $TOKEN'" "http://169.254.169.254/latest/meta-data/instance-id") + [ $? -ne 0 ] && exit $OCF_ERR_GENERIC +diff --git a/heartbeat/aws-vpc-route53.in b/heartbeat/aws-vpc-route53.in +index eba2ed95..85c8de3c 100644 +--- a/heartbeat/aws-vpc-route53.in ++++ b/heartbeat/aws-vpc-route53.in +@@ -43,6 +43,7 @@ + + : ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat} + . ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs ++. ${OCF_FUNCTIONS_DIR}/aws.sh + + # Defaults + OCF_RESKEY_awscli_default="/usr/bin/aws" +@@ -53,8 +54,6 @@ OCF_RESKEY_hostedzoneid_default="" + OCF_RESKEY_fullname_default="" + OCF_RESKEY_ip_default="local" + OCF_RESKEY_ttl_default=10 +-OCF_RESKEY_curl_retries_default="3" +-OCF_RESKEY_curl_sleep_default="1" + + : ${OCF_RESKEY_awscli=${OCF_RESKEY_awscli_default}} + : ${OCF_RESKEY_auth_type=${OCF_RESKEY_auth_type_default}} +@@ -64,8 +63,6 @@ OCF_RESKEY_curl_sleep_default="1" + : ${OCF_RESKEY_fullname:=${OCF_RESKEY_fullname_default}} + : ${OCF_RESKEY_ip:=${OCF_RESKEY_ip_default}} + : ${OCF_RESKEY_ttl:=${OCF_RESKEY_ttl_default}} +-: ${OCF_RESKEY_curl_retries=${OCF_RESKEY_curl_retries_default}} +-: ${OCF_RESKEY_curl_sleep=${OCF_RESKEY_curl_sleep_default}} + + usage() { + cat <<-EOT +@@ -377,7 +374,7 @@ r53_monitor() { + _get_ip() { + case $OCF_RESKEY_ip in + local|public) +- TOKEN=$(curl_retry "$OCF_RESKEY_curl_retries" "$OCF_RESKEY_curl_sleep" "--show-error -sX PUT -H 'X-aws-ec2-metadata-token-ttl-seconds: 21600'" "http://169.254.169.254/latest/api/token") ++ TOKEN=$(get_token) + [ $? -ne 0 ] && exit $OCF_ERR_GENERIC + IPADDRESS=$(curl_retry "$OCF_RESKEY_curl_retries" "$OCF_RESKEY_curl_sleep" "--show-error -s -H 'X-aws-ec2-metadata-token: $TOKEN'" "http://169.254.169.254/latest/meta-data/${OCF_RESKEY_ip}-ipv4") + [ $? -ne 0 ] && exit $OCF_ERR_GENERIC +diff --git a/heartbeat/aws.sh b/heartbeat/aws.sh +new file mode 100644 +index 00000000..c77f93b9 +--- /dev/null ++++ b/heartbeat/aws.sh +@@ -0,0 +1,46 @@ ++#!/bin/sh ++# ++# ++# AWS Helper Scripts ++# ++# ++ ++: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat} ++. ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs ++ ++# Defaults ++OCF_RESKEY_curl_retries_default="3" ++OCF_RESKEY_curl_sleep_default="1" ++ ++: ${OCF_RESKEY_curl_retries=${OCF_RESKEY_curl_retries_default}} ++: ${OCF_RESKEY_curl_sleep=${OCF_RESKEY_curl_sleep_default}} ++ ++# Function to enable reusable IMDS token retrieval for efficient repeated access ++# File to store the token and timestamp ++TOKEN_FILE="${HA_RSCTMP}/.aws_imds_token" ++TOKEN_LIFETIME=21600 # Token lifetime in seconds (6 hours) ++TOKEN_EXPIRY_THRESHOLD=3600 # Renew token if less than 60 minutes (1 hour) remaining ++ ++# Function to fetch a new token ++fetch_new_token() { ++ TOKEN=$(curl_retry "$OCF_RESKEY_curl_retries" "$OCF_RESKEY_curl_sleep" "--show-error -sX PUT -H 'X-aws-ec2-metadata-token-ttl-seconds: $TOKEN_LIFETIME'" "http://169.254.169.254/latest/api/token") ++ echo "$TOKEN $(date +%s)" > "$TOKEN_FILE" ++ echo "$TOKEN" ++} ++ ++# Function to retrieve or renew the token ++get_token() { ++ if [ -f "$TOKEN_FILE" ]; then ++ read -r STORED_TOKEN STORED_TIMESTAMP < "$TOKEN_FILE" ++ CURRENT_TIME=$(date +%s) ++ ELAPSED_TIME=$((CURRENT_TIME - STORED_TIMESTAMP)) ++ ++ if [ "$ELAPSED_TIME" -lt "$((TOKEN_LIFETIME - TOKEN_EXPIRY_THRESHOLD))" ]; then ++ # Token is still valid ++ echo "$STORED_TOKEN" ++ return ++ fi ++ fi ++ # Fetch a new token if not valid ++ fetch_new_token ++} +\ No newline at end of file +diff --git a/heartbeat/awseip b/heartbeat/awseip +index ffb6223a..4b1c3bc6 100755 +--- a/heartbeat/awseip ++++ b/heartbeat/awseip +@@ -38,6 +38,7 @@ + + : ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat} + . ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs ++. ${OCF_FUNCTIONS_DIR}/aws.sh + + ####################################################################### + +@@ -49,16 +50,12 @@ OCF_RESKEY_auth_type_default="key" + OCF_RESKEY_profile_default="default" + OCF_RESKEY_region_default="" + OCF_RESKEY_api_delay_default="3" +-OCF_RESKEY_curl_retries_default="3" +-OCF_RESKEY_curl_sleep_default="1" + + : ${OCF_RESKEY_awscli=${OCF_RESKEY_awscli_default}} + : ${OCF_RESKEY_auth_type=${OCF_RESKEY_auth_type_default}} + : ${OCF_RESKEY_profile=${OCF_RESKEY_profile_default}} + : ${OCF_RESKEY_region=${OCF_RESKEY_region_default}} + : ${OCF_RESKEY_api_delay=${OCF_RESKEY_api_delay_default}} +-: ${OCF_RESKEY_curl_retries=${OCF_RESKEY_curl_retries_default}} +-: ${OCF_RESKEY_curl_sleep=${OCF_RESKEY_curl_sleep_default}} + + meta_data() { + cat < - 4.16.0-3 +- AWS agents: reuse IMDS token until it expires + * Fri Nov 22 2024 bixiaoyan - 4.16.0-2 - High: storage-mon: Fixed a bug in storage-mon's daemon mode that delayed the reflection of initial scores, and made it compliant with OCF specifications - Storage_mon: remove unused macro variables