The Will Will Web

記載著 Will 在網路世界的學習心得與技術分享

如何從 Azure DevOps Service 刪除自動建立的 Service connections

在我的 Azure DevOps Service 上面有個專案,之前已經都設定好 CI/CD 並運作正常一段時間,最近因為 Azure Subscription 有些異動,導致原本的 Azure Resource Manager 服務連線 (Service connection) 無法正常運作,不但無法修改,也刪除不掉。我手動建立一條新的服務連線後,原本的 Release 已經可以正常部署,但是原先透過 Azure Pipelines 自動建立的服務連線卻怎樣都刪除不了。最後向微軟提出技術支援要求之後,才得知一個透過 REST API 刪除的方法,透過 Web 介面已經確定無法刪除該項目。

認識 Azure DevOps Services REST API

其實整個 Azure DevOps Services 複雜網頁介面的背後,都是一支一支的 Web API 建構而成,在 Web UI 尚未更新之前,其實 API 會走在最前面,所以有些功能確實無法透過 Web UI 進行新增、修改或刪除。要上手 Azure DevOps Services REST API 的第一步,就是查看 Azure DevOps Services REST API Reference 文件!

要成功透過 REST API 操作 Azure DevOps Services 服務,底下 2 件事要先搞定:

  1. 認識 REST API 的封包結構(Request/Response)

    • 要求網址 (Request URI)

      若以 Azure DevOps Service 來說,可以用以下網址結構:

      VERB https://dev.azure.com/{organization}[/{team-project}]/_apis[/{area}]/{resource}?api-version={version}
      

      若是 Azure DevOps Server 的話,可以用以下網址結構:

      VERB https://{instance}[/{team-project}]/_apis[/{area}]/{resource}?api-version={version}
      
    • 要求標頭 (Request message header)

      這裡最重要的應該是 Authorization 標頭,用來對操作者的身分進行驗證!

      Authorization: Basic BASE64PATSTRING
      

      這裡的 BASE64PATSTRING:PAT 的 Base64 編碼字串,也就是 冒號(:) + PAT字串

      PAT = Personal Access Token

    • 要求內文 (Request message body)

      通常要求內文的 Content-Type 都以 application/json 為主。

    • 回應標頭 (Response message header)

      回應標頭最重要的不外乎是 狀態碼 與內文的 Content-Type ( application/json )。

    • 回應內文 (Response message body)

      通常回應內文內容類型也以 application/json 為主,但也支援 XML 類型 (text/xml)。

  2. 學習如何發出 REST API 要求

    • 認證方式

      你可以使用 Basic AuthOAuth 2.0 的方式與 Azure DevOps Services REST API 進行驗證。

    • 使用 cURL 工具發出要求

      我以取得 Service connections 的 Endpoints 為例,命令與參數大概長這樣:

      curl -s -u :{PAT} https://dev.azure.com/{organization}/{team-project}/_apis/serviceendpoint/endpoints?api-version=5.1-preview.2
      

      建立 PAT 請參考 Authenticate access with personal access tokens 這份文件。

    • 使用 Postman 工具發出要求

      這裡最重要的就是選對 Auth 的方式,請參考以下畫面進行設定即可:

      2020-02-10_21-23-07

取得並刪除自動建立的 Service Endpoints

注意:你從 Web UI 看到的 Service Connections 在 REST API 中的名稱為 Service Endpoints

  1. 取得 Service Endpoints 清單

    你可以透過以下 API 要求取得所有 Service Endpoints

    curl -s -u :{PAT} https://dev.azure.com/{organization}/{team-project}/_apis/serviceendpoint/endpoints?api-version=5.1-preview.2 | jq ".value[]"
    

    我拿這份資料跟 Web UI 上面的 Service connections 顯示的項目比較一下,發現數量不一致!我在 Azure DevOps Service 上面專案內的 Service connections 其實有 4 筆資料,但是透過 REST API 卻只看到 3 筆而已!

    經過研究後發現,原來已經認證失敗的 Service connections 不會自動出現在 REST API 中,如果要顯示所有的 Service Endpoints 還必須加上 includeFailed=true 這個 URI 參數才行,例如:

    curl -s -u :{PAT} https://dev.azure.com/{organization}/{team-project}/_apis/serviceendpoint/endpoints?api-version=5.1-preview.2&includeFailed=true | jq ".value[]"
    

    我用 jq 的過濾語法,僅列出無法連線的清單:

    curl -s -u :{PAT} "https://dev.azure.com/{organization}/{team-project}/_apis/serviceendpoint/endpoints?api-version=5.1-preview.2&includeFailed=true" | jq "[.value[] | select(.isReady==false)]"
    
  2. 先設法取得無法刪除的 Endpoint Id

    我用 jq 的過濾語法,僅列出自動建立的 Ids:

    curl -s -u :{PAT} "https://dev.azure.com/{organization}/{team-project}/_apis/serviceendpoint/endpoints?api-version=5.1-preview.2&includeFailed=true" | jq '[(.value[] | select(.data.creationMode=="Automatic")).id]'
    

    或是直接用 Web UI 進行查找:

    image

    image

  3. 先取得該 Endpoint Id 的完整 JSON 內容

    將內容輸出成 data.txt 檔案

    curl -s -u :{PAT} "https://dev.azure.com/{organization}/{team-project}/_apis/serviceendpoint/endpoints/e3ed4887-1647-4954-a76e-24c5fb2d6d19?api-version=5.1-preview.2" | jq "." > data.txt
    
  4. 將該筆 Endpoint 資料更新為手動建立 (Manual)

    編輯 data.txt 檔案內容,做出以下修改:

    1. "creationMode" 的值從 "Automatic" 改為 "Manual"
    2. 移除 "spnObjectId"
    3. 移除 "appObjectId"

    將內容透過 PUT 方法更新回去:

    curl -s -u :{PAT} -X PUT -H "Content-Type: application/json" -d "@data.txt" "https://dev.azure.com/{organization}/{team-project}/_apis/serviceendpoint/endpoints/e3ed4887-1647-4954-a76e-24c5fb2d6d19?api-version=5.1-preview.2" | jq "."
    
  5. 刪除該筆 Endpoint 資料

    只要你將該筆 Endpoint 資料更新為手動建立模式,就可以從 Azure DevOps Service 的 Web UI 刪除了!

    或是直接透過 REST API 刪除該筆 Endpoint

    curl -s -u :{PAT} -X DELETE "https://dev.azure.com/{organization}/{team-project}/_apis/serviceendpoint/endpoints/e3ed4887-1647-4954-a76e-24c5fb2d6d19?api-version=5.1-preview.2" | jq "."
    

相關連結

留言評論