天天看點

使用邏輯編排解決阿裡雲費用賬單API內建資料結構差異的問題

內建阿裡雲的費用賬單,是公司運維小夥伴經常要承擔的工作。阿裡雲也開放了按照多個維次元查詢費用賬單的API供企業客戶使用,內建到雲管平台,财務系統等等。不過在實際工作中,常常會發現需要內建的雲供應商不止一家,每一家提供的API格式都不一樣。如果想要接入已經開發好的系統,資料結構不一緻就需要做額外的資料Mapping工作,費時費力。小編在阿裡雲上發現了一款神器,可對阿裡雲提供的API做快速的定制,輸出想要的格式,這就是阿裡雲的邏輯編排。 什麼是邏輯編排?

舉個實際的例子,阿裡雲賬單的API QueryInstanceBill可傳回按照執行個體次元或者計費項次元的賬單,傳回的格式是這樣的:

"Data": {

"Items": {
  "Item": [
    {
                "SubscriptionType": "PayAsYouGo",
                "ProductCode": "cdn",
                "RecordID": "2019080352963162",
                "BillingItem": "InlandNetworkOut",
                "ProductDetail": "cdn",
                "DeductedByPrepaidCard": 0,
                "PretaxAmount": 0,
                "DeductedByCoupons": 0,
                "RoundDownDiscount": 0,
                "UsageStartTime": "2019-08-08 12:00:00",
                "UsageEndTime": "2019-08-08 13:00:00",
                "Status": "NoSettle",
                "PaymentTime": "",
                "PaymentAmount": 0,
                "Item": "PayAsYouGoBill",
                "OutstandingAmount": 0,
                "ProductType": "",
                "DeductedByCashCoupons": 0,
                "OwnerID": "",
                "ProductName": "cdn",
                "Currency": "CNY",
                "PretaxGrossAmount": 0,
                "InvoiceDiscount": 0
            }
            ]
           

},

如果在內建的過程中,僅希望InlandNetworkOut這一個計費項的用量和金額彙總,輸出一個特定Json格式的結果,可以按照下面的步驟操作。

第一步 權限設定

邏輯編排過程中需要調用QueryInstanceBill接口,是以需要相關的權限。可以使用AliyunBSSFullAccess權限,但為了保證最小可用原則,建立一個新的權限政策AliyunBSSBillReadOnly,使用以下的Statement

{

"Version": "1",

"Statement": [

{
       "Action": ["bss:Query*", "bss:Describe*"],
       "Resource": "*",
       "Effect": "Allow"
   }           

]

}

使用邏輯編排解決阿裡雲費用賬單API內建資料結構差異的問題

同時建立一個擁有此權限Ram角色,并添加以下的信任政策:

  1. 建立RAM Role,選擇Alibaba Cloud Service類型
  2. 添加剛剛建立的政策AliyunBSSBillReadOnly
  3. 修改信任政策,讓邏輯編排可以通路
    "Statement": [
        {
            "Action": "sts:AssumeRole",
            "Effect": "Allow",
            "Principal": {
                "Service": [
                    "composer.aliyuncs.com"
                ]
            }
        }
    ],
    "Version": "1"           
使用邏輯編排解決阿裡雲費用賬單API內建資料結構差異的問題

第二步 編排流程

登入國際站并通路邏輯編排控制台

https://lc.console.aliyun.com/

,在左側的菜單選擇“我的工作流”,然後建立一個新的流程,輸入名稱和描述。建立完成後,轉到“代碼設計”,然後複制本文給出的一個段腳本。

"actions": {
    "查詢_InstanceBill_第一頁資料": {
        "type": "ACS::BSS::QueryInstanceBill",
        "inputs": {
            "method": "POST",
            "host": {
                "product": "BSS",
                "api": "QueryInstanceBill",
                "apiVersion": "2017-12-14"
            },
            "connection": {},
            "queries": {
                "RegionId": "ap-southeast-1",
                "BillingCycle": "@get(triggerOutputs(), 'queries.BillingCycle')",
                "ProductCode": "cdn",
                "PageNum": 1,
                "PageSize": 300,
                "IsBillingItem": true
            }
        },
        "runAfter": {
            "初始化變量存放所有記錄": [
                "Succeeded"
            ]
        }
    },
    "初始化變量存放所有記錄": {
        "type": "InitializeVariable",
        "inputs": {
            "name": "records",
            "type": "Array",
            "value": []
        },
        "runAfter": {}
    },
    "存入第一頁資料": {
        "type": "AppendToArrayVariable",
        "inputs": {
            "name": "records",
            "value": "@body('查詢_InstanceBill_第一頁資料')['Data']['Items']['Item']"
        },
        "runAfter": {
            "查詢_InstanceBill_第一頁資料": [
                "Succeeded"
            ]
        }
    },
    "周遊剩餘頁數": {
        "type": "Until",
        "inputs": {},
        "runAfter": {
            "初始化變量存放目前頁數": [
                "Succeeded"
            ]
        },
        "actions": {
            "查詢某一頁_InstanceBill_資料": {
                "type": "ACS::BSS::QueryInstanceBill",
                "inputs": {
                    "method": "POST",
                    "host": {
                        "product": "BSS",
                        "api": "QueryInstanceBill",
                        "apiVersion": "2017-12-14"
                    },
                    "connection": {},
                    "queries": {
                        "BillingCycle": "@get(triggerOutputs(), 'queries.BillingCycle')",
                        "RegionId": "ap-southeast-1",
                        "ProductCode": "cdn",
                        "PageNum": "@variables('pageNumber')",
                        "PageSize": 300,
                        "IsBillingItem": true
                    }
                },
                "runAfter": {
                    "設定頁數": [
                        "Succeeded"
                    ]
                }
            },
            "追加值至數組變量": {
                "type": "AppendToArrayVariable",
                "inputs": {
                    "name": "records",
                    "value": "@body('查詢某一頁_InstanceBill_資料')['Data']['Items']['Item']"
                },
                "runAfter": {
                    "查詢某一頁_InstanceBill_資料": [
                        "Succeeded"
                    ]
                }
            },
            "設定頁數": {
                "runAfter": {},
                "type": "SetVariable",
                "inputs": {
                    "name": "pageNumber",
                    "value": "@add(variables('pageNumber'), 1)"
                }
            }
        },
        "expression": "@lte(sub(ceil(div(body('查詢_InstanceBill_第一頁資料').Data.TotalCount, 300)), variables('pageNumber')), 0)"
    },
    "初始化變量存放目前頁數": {
        "type": "InitializeVariable",
        "inputs": {
            "name": "pageNumber",
            "type": "Integer",
            "value": 1
        },
        "runAfter": {
            "存入第一頁資料": [
                "Succeeded"
            ]
        }
    },
    "計算總數": {
        "type": "JavascriptCode",
        "inputs": {
            "code": "const records = $context.variables('records');\n\nconst allUsage = records.reduce((sum, group) => {\n    if (Array.isArray(group)) {\n        group.forEach((record) => {\n            if (record.BillingItem === 'InlandNetworkOut') {\n                if (record.Usage) {\n                    sum.Usage += parseFloat(record.Usage) || 0;\n                }\n                if (record.PretaxAmount) {\n                    sum.PretaxAmount += parseFloat(record.PretaxAmount) || 0;\n                }\n            }\n            \n        });\n    } else if (group.Usage || group.PretaxAmount) {\n        if (group.BillingItem === 'InlandNetworkOut') {\n            sum.Usage += parseFloat(group.Usage) || 0;\n            sum.PretaxAmount += parseFloat(group.PretaxAmount) || 0;\n        }\n    }\n    \n    return sum;\n}, { Usage: 0, PretaxAmount: 0 });\n\nreturn allUsage;"
        },
        "runAfter": {
            "周遊剩餘頁數": [
                "Succeeded"
            ]
        }
    },
    "響應": {
        "type": "Response",
        "outputs": {
            "statusCode": 500,
            "body": {                  
                "cost_data": [
                    {                        
                        "usage": "@body('計算總數').Usage",
                        "cost": "@body('計算總數').PretaxAmount"
                    }
                ]
            },
            "headers": {
                "Content-Type": "application/json"
            }
        },
        "runAfter": {
            "計算總數": [
                "Succeeded"
            ]
        }
    }
}           

傳回圖形化設定,這時需要對其中調用API的過程進行授權。點選并展開“查詢InstanceBill第一頁資料”,在下方點選Change Permissions,添加剛剛建立新的RAM Role,注意Authorized Policies是否包括了應該有的權限。再點開“周遊剩餘頁數”這一步,再展開“查詢某一頁InstanceBill資料”,進行如上的權限添加步驟。點選右上角的儲存按鍵儲存流程。

第三步 調用流程

在流程的第一步中,可以找到服務發起的URL,Copy到浏覽器中可進行測試。在上面的例子中,調用時需要添加一個查詢賬期的參數BillingCycle=YYYY-MM。根據所需,可更改調用方式為POST或者GET。

這就是一個利用流程編改變API結構的方式,希望能夠幫助到您。