繁体   English   中英

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

[英]cURL works via terminal/Postman but not shell script or Python

我有一个 shell 脚本,它从 AWS SSM Parameter Store 中提取参数,并在一些 cURL 命令中使用它们到 3rd 方 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 中完成这项工作。

在 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 脚本中执行

如果有帮助,请告诉我!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM