无效 update_mask。 - 如何为 googleapis 正确指定 JSON 更新掩码​​?

Invalid update_mask. - how to specify a JSON update mask correctly for googleapis?

我正在尝试使用以下 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"
  }
}

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

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

我只需要更新在“ipSubnetworks”字符串数组中找到的单个 IP 地址,它又位于“conditions”对象数组中,而“conditions”对象数组又嵌套在“basic”对象下。

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

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

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

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

你的情况:

"updateMask" : "basic,title"

另请参阅:

updateMask

string (FieldMask format)

Required. Mask to control which fields get updated. Must be non-empty.

This is a comma-separated list of fully qualified names of fields. Example: "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

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% 的工作:它 returns http 200 并根据需要更新访问级别对象的 ip。

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