【问题标题】:Invalid update_mask. - how to specify a JSON update mask correctly for googleapis?无效的更新掩码。 - 如何为 googleapis 正确指定 JSON 更新掩码​​?
【发布时间】:2021-12-09 12:10:01
【问题描述】:

我正在尝试使用以下 API: https://cloud.google.com/access-context-manager/docs/reference/rest/v1/accessPolicies.accessLevels/patch

我的目标很简单:在 GCP 的后端更新(“补丁”)一个“AccessLevel”对象。

我正在使用 Google Apps 脚本中的“UrlFetchApp.fetch”方法调用 API:

var result = UrlFetchApp.fetch('https://accesscontextmanager.googleapis.com/v1/accessPolicies/12345678/accessLevels/User_A_Home_IP?updateMask=updateMask',options);

其中“选项”(作为 url 端点后的第二个参数传递)是:

  var options = 
  {
    method: 'PATCH',
    headers: {
      'Authorization': 'Bearer ' + ScriptApp.getOAuthToken(),
      'Content-Type' : 'application/json',
    },
    payload : JSON.stringify(payload),
    muteHttpExceptions : true,
    "updateMask" : "*"
   }

而“有效载荷”是:

var payload=
  {
    "basic": {
      "combiningFunction": "OR",
      "conditions": [
      {
        "ipSubnetworks": [
          "11.12.13.14/32"
        ]
      }
      ]
    },
  "name": "accessPolicies/12345678/accessLevels/User_A_Home_IP",
  "title": "User A Home IP"
  }

我得到的结果是:

{
  "error": {
    "code": 400,
    "message": "Invalid update_mask. All paths must be in the AccessLevel message.",
    "status": "INVALID_ARGUMENT"
  }
}

根据文档(本文中的第一个链接) 请求正文应包含 AccessLevel 的实例(这是我的代码中的“有效负载”对象) 还需要一个“updateMask”查询参数,它指示后端目标 json 对象的哪些字段得到更新。

updateMask,如果我理解正确的话 - 属于 FieldMask 类型: https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#google.protobuf.FieldMask

我只需要更新在“ipSubnetworks”字符串数组中找到的单个 IP 地址,该地址又位于“条件”对象数组中,该数组又嵌套在“基本”对象下。

在这种情况下,updateMask 的正确语法是什么?

updateMask 应该位于我的“PATCH”请求中的什么位置?

【问题讨论】:

    标签: google-apps-script google-cloud-platform google-api


    【解决方案1】:

    updateMask 中指定您要更新的主要字段

    如果您更新多个字段 - 指定所有字段以逗号分隔(中间没有空格)。

    在你的情况下:

    "updateMask" : "basic,title"

    另见:

    updateMask

    字符串(字段掩码格式)

    必填。用于控制更新哪些字段的掩码。不能为空。

    这是一个以逗号分隔的字段完全限定名称列表。示例:“user.displayName,photo”。

    示例 JSON:

    "name": "accessPolicies/12345678/accessLevels/User_A_Home_IP",
    "updateMask": "basic,title",
    "title": "User A Home IP",
    "resource": {
          "basic": {
              "combiningFunction": "OR",
              "conditions": [
                {
                  "ipSubnetworks": [
                    "11.12.13.14/32"
                  ]
                }
              ]
            }
          }
    

    更新:

    一个示例 Apps 脚本函数:

    function patchResource() {
        var options = 
      {
        method: 'PATCH',
        headers: {
          'Authorization': 'Bearer ' + ScriptApp.getOAuthToken(),
          'Content-Type' : 'application/json',
        },
        payload : JSON.stringify(payload),
        muteHttpExceptions : true
       }
        
        var payload=
      {
    "name": "accessPolicies/12345678/accessLevels/User_A_Home_IP",
    "updateMask": "basic,title",
    "title": "User A Home IP",
    "resource": {
          "basic": {
              "combiningFunction": "OR",
              "conditions": [
                {
                  "ipSubnetworks": [
                    "11.12.13.14/32"
                  ]
                }
              ]
            }
          }
      }
        
      var result = UrlFetchApp.fetch('https://accesscontextmanager.googleapis.com/v1/accessPolicies/12345678/accessLevels/User_A_Home_IP',options);
      console.log(result.getResponseCode())
      console.log(result.getContentText())
    }
    

    如果您确实想将 updateMask 作为 URL 参数而不是有效负载的一部分传递 - 请确保对逗号进行 URL 编码:

    ?updateMask=basic%2Ctitle

    【讨论】:

    • 谢谢我已经尝试过了,只有 updatemaske 字段上的“基本”,仍然得到相同的响应,我相信一些解决方案是确切地知道与根对象相关的位置我'正在尝试更新 - 放置 updateMask 字段,并以支持的语法进行(唉,在此 API 中找不到合适的文档)
    • 我用与您完全相同的请求对其进行了测试,它对我有用。也许您可以先使用Try This API 进行测试 - 以排除编码/语法错误?
    • 介意分享完整的解决方案吗?或者只是您在请求中发送的完整 JSON 对象,包括标头等?完整的 JSON 对我来说应该足够了,谢谢!
    • 很高兴您找到了适合您的解决方案!
    【解决方案2】:
    function updateAccessLevelIp(accessLevelName, ip) {
      var data = {"basic":{"conditions":[{"ipSubnetworks":[ip]}]}}
      var options =
      {
        method: 'PATCH',
        headers: {
          'Authorization': 'Bearer ' + ScriptApp.getOAuthToken(),
          'Content-Type' : 'application/json',
        },
        muteHttpExceptions : true,
        'payload' : JSON.stringify(data)
       }
      var result = UrlFetchApp.fetch("https://accesscontextmanager.googleapis.com/v1/accessPolicies/xxxxxxxxxxx/accessLevels/"+accessLevelName+"?updateMask=basic",options);
      console.log(result.getResponseCode())
      console.log(result.getContentText())
      if (result.getResponseCode() == 200)
        return ("Successfully updated the \"" + accessLevelName + "\" access level with ip address: \"" +  ip + "\"");
      else 
        return ("Failed to update \"" + accessLevelName + "\"! please talk to your friendly neighborhood DevOps team!\nResponse Code was:\n"+result.getResponseCode()+"\nResponse text was:\n"+result.getContentText());
    }
    

    这是 100% 的工作:它返回 http 200 并根据需要更新访问级别对象的 ip。

    • 不需要任何特殊的 json 字段作为“更新掩码”; 此 API 调用确实需要更新掩码,但只能作为 URL 参数(而不是 json 字段)

    【讨论】:

      猜你喜欢
      • 2020-03-29
      • 1970-01-01
      • 1970-01-01
      • 2017-05-20
      • 1970-01-01
      • 2023-02-17
      • 1970-01-01
      • 2019-05-22
      • 1970-01-01
      相关资源
      最近更新 更多