cURL 通过终端/邮递员工作,但不能通过 shell 脚本或 Python 工作



我有一个 shell 脚本,它从 AWS SSM 参数存储中提取参数,并在一些 cURL 命令中将它们用于第三方 API。如果我通过终端手动执行每个命令,它们都运行良好,没有问题;但是,一旦我将它们放入下面的脚本中,用于创建 AWS 账户连接器的 cURL 命令就会不断引发 500 内部服务错误。

下面是一个片段:

#!/bin/bash
# Creating random guid to use for ExternalId
UUID=$(uuidgen)
echo "UUID: $UUID"
# Replacing ExternalId in assumepolicy doc with created guid
$SED_COMMAND -i "s/"sts:ExternalId": ".*"/"sts:ExternalId": "${UUID}"/g" ./trust-policy.json
# Create new cross-account role with assume role policy
echo "Creating new cross-account role."
aws iam create-role --role-name ${ROLENAME} --assume-role-policy-document file://trust-policy.json
# Attach role policy to newly created role
aws iam put-role-policy --role-name ${ROLENAME} --policy-name ${POLICYNAME} --policy-document file://inline-policy.json
# Grabbing role arn
ARN=$(aws iam get-role --role-name ${ROLENAME} | jq -r '.Role.Arn')
# Logging into SaaS instance; retrieving SID for subsequent API calls
SID=`curl -ks -H "Content-Type: application/json" "Accept: application/json" -X POST "${URL}/rest/authentication/login" -d '{"dsCredentials":{"userName":"'${USER_ID}'","password":"'${PASSWORD}'"}}'`
# Create AWS account connector
echo "Creating AWS account connector."
curl -ks --cookie "sID=${SID}" -H "Content-Type: application/json" "Accept: application/json" -X POST "${URL}/rest/cloudaccounts/aws" -d '{"AddAwsAccountRequest": {"useInstanceRole": false,"crossAccountRole": {"roleArn": "'${ARN}'","externalId": "'${UUID}'"},"workspacesEnabled": false}}'
# Log out of SaaS instance
echo "Logging out."
curl -k -X DELETE ${URL}/rest/authentication/logout?sID=${SID}

第一个 cURL 语句在脚本中工作正常,该语句获取用于身份验证的 SID。

SID=`curl -ks -H "Content-Type: application/json" "Accept: application/json" -X POST "${URL}/rest/authentication/login" -d '{"dsCredentials":{"userName":"'${USER_ID}'","password":"'${PASSWORD}'"}}'`

但是,第二个 cURL 语句在通过 shell 脚本运行时不断抛出 500:{"error":{"message":"Internal server error"}}

curl -ks --cookie "sID=${SID}" -H "Content-Type: application/json" "Accept: application/json" -X POST "${URL}/rest/cloudaccounts/aws" -d '{"AddAwsAccountRequest": {"useInstanceRole": false,"crossAccountRole": {"roleArn": "'${ARN}'","externalId": "'${UUID}'"},"workspacesEnabled": false}}'

如果我采用完全相同的 cURL 命令并在终端中手动执行,它可以正常工作。我也能够在邮递员中完成这项工作。

在Postman中,我发现如果请求中的一段数据格式不正确或为空,我会返回相同的"内部服务器错误",所以我的预感是请求正文有问题;但是,我可以通过终端上的bash -x运行确切的curl命令输出,并且它可以工作。

例如,下面是使用此命令运行上述脚本的输出:bash -x ./cloudConnectorAutomation.sh

+ echo 'Creating AWS account connector.'
Creating AWS account connector.
+ curl -ks --cookie sID=XXXX -H 'Content-Type: application/json' 'Accept: application/json' -X POST https://XXXX/rest/cloudaccounts/aws -d '{"AddAwsAccountRequest": {"useInstanceRole": false,"crossAccountRole": {"roleArn": "arn:aws:iam::XXXXXXXXXXXX:role/XXXX","externalId": "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"},"workspacesEnabled": false}}'
{"error":{"message":"Internal server error"}}

如果我直接从终端的输出中复制并粘贴完全相同的 curl 命令并执行它,它会完美执行。

我记下了在脚本和终端中运行的命令的 curl -v 输出,除了不同的 SID(由于不同的身份验证会话(之外,它们是相同的。脚本中运行的一个将其显示为状态代码:< HTTP/1.1 500,而我手动运行的一个将其显示为状态代码:< HTTP/1.1 200


在最后的努力中,我甚至测试了调用python脚本而不是使用cURL。下面是 Python 脚本。在本文开头的初始脚本中,在有问题的 cURL 请求的位置调用它:

import requests
import sys
import json
SID = sys.argv[1]
URL = sys.argv[2]
ARN = sys.argv[3]
UUID = sys.argv[4]
# Do not proceed if required parameters are empty
if not SID or not URL or not ARN or not UUID:
print ("nERROR: Required parameters are empty.")
print ("SID: " + SID)
print ("URL: " + URL)
print ("ARN: " + ARN)
print ("UUID: " + UUID)
exit()
endpoint = URL + '/rest/cloudaccounts/aws'
cookies = {
'sID': SID
}
headers = {
'Content-Type': 'application/json',
'Accept': 'application/json'
}
payload = {'AddAwsAccountRequest': {'useInstanceRole': False,'crossAccountRole': {'roleArn': ARN,'externalId': UUID},'workspacesEnabled': False}}
response = requests.post(endpoint, headers=headers, cookies=cookies, data=json.dumps(payload), verify=False)

它返回相同的内部服务器错误:

Creating AWS account connector.
+ python3 ./account_connector.py XXXX https://XXXX.com arn:aws:iam::XXXXXXXXX:role/XXXX XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
/usr/local/lib/python3.7/site-packages/urllib3/connectionpool.py:847: InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings
InsecureRequestWarning)
{"error":{"message":"Internal server error"}}

但是,如果我在 ipython 中逐行执行此任务,它可以完美运行。

我在这里不知所措,我花了一天多的时间试图弄清楚这一点。

同样,我真的相信问题是我的数据块以某种方式格式不正确,但我看不到它在哪里。我也对为什么我可以采用完全相同的 cURL 命令并且它在终端中工作感到困惑。我正在研究通过终端与 shell 脚本运行 cURL 命令是否有任何细微差别或细微差别,但我没有发现有。

对此的任何帮助将不胜感激。

你能试着逃离你的身体吗:

"{"AddAwsAccountRequest": {"useInstanceRole": false,"crossAccountRole": {"roleArn": "${ARN}","externalId": "${UUID}"},"workspacesEnabled": false}}"

从终端运行与运行脚本时有一些微妙之处,此处所述的转义问题:curl 有效,但不会在 BASH 脚本中执行

让我知道它是否有帮助!

最新更新