API ใƒชใ‚ฏใ‚จใ‚นใƒˆใฎไฝœๆˆใจใƒฌใ‚นใƒใƒณใ‚นใฎๅ‡ฆ็†


ใ“ใฎใƒ‰ใ‚ญใƒฅใƒกใƒณใƒˆใงใฏใ€API ใƒชใ‚ฏใ‚จใ‚นใƒˆใ‚’ไฝœๆˆใ—ใฆใ€Compute Engine API ใ‹ใ‚‰ใฎ API ใƒฌใ‚นใƒใƒณใ‚นใ‚’ๅ‡ฆ็†ใ™ใ‚‹ๆ–นๆณ•ใซใคใ„ใฆ่ชฌๆ˜Žใ—ใพใ™ใ€‚ใ“ใฎใƒ‰ใ‚ญใƒฅใƒกใƒณใƒˆใง่ชฌๆ˜Žใ™ใ‚‹ๅ†…ๅฎนใฏไปฅไธ‹ใฎใจใŠใ‚Šใงใ™ใ€‚

  • ใƒชใ‚ฏใ‚จใ‚นใƒˆๆœฌๆ–‡ใ‚’ไฝœๆˆใ™ใ‚‹ใ€‚
  • ใƒชใ‚ฏใ‚จใ‚นใƒˆใซๅฟ…่ฆใชใƒชใ‚ฝใƒผใ‚น URI ใ‚’็ขบ่ชใ™ใ‚‹ใ€‚
  • API ใƒฌใ‚นใƒใƒณใ‚นใ‚’ๅ‡ฆ็†ใ™ใ‚‹ใ€‚
  • API ใƒชใ‚ฏใ‚จใ‚นใƒˆใŒๆˆๅŠŸใ—ใŸใ‹ใฉใ†ใ‹ใ‚’็ขบ่ชใ™ใ‚‹ใ€‚

ใ“ใฎใƒ‰ใ‚ญใƒฅใƒกใƒณใƒˆใงใฏใ€API ใฎ่ช่จผๆ–นๆณ•ใซใคใ„ใฆใฏ่ชฌๆ˜Žใ—ใพใ›ใ‚“ใ€‚API ใฎ่ช่จผๆ–นๆณ•ใซใคใ„ใฆใฏใ€Compute Engine ใธใฎ่ช่จผใ‚’ใ”่ฆงใใ ใ•ใ„ใ€‚

ๅง‹ใ‚ใ‚‹ๅ‰ใซ

  • REST API ใซใคใ„ใฆ็†่งฃใ‚’ๆทฑใ‚ใพใ™ใ€‚
  • Compute Engine API ใซๅฏพใ™ใ‚‹่ช่จผใฎๆ–นๆณ•ใ‚’ๅญฆ็ฟ’ใ—ใพใ™ใ€‚

API ใƒชใ‚ฏใ‚จใ‚นใƒˆใฎไฝœๆˆ

Compute Engine API ใฏใ€API ใƒชใ‚ฏใ‚จใ‚นใƒˆใŒ JSON ๅฝขๅผใง่จ˜่ฟฐใ•ใ‚Œใฆใ„ใ‚‹ใ‚‚ใฎใจใ—ใฆๅ‡ฆ็†ใ‚’้€ฒใ‚ใพใ™ใ€‚API ใƒชใ‚ฏใ‚จใ‚นใƒˆใ‚’ไฝœๆˆใ™ใ‚‹ใซใฏใ€curl ใพใŸใฏ httplib2 ใฎใ‚ˆใ†ใชใƒ„ใƒผใƒซใ‚’ไฝฟ็”จใ—ใฆ็›ดๆŽฅ HTTP ใƒชใ‚ฏใ‚จใ‚นใƒˆใ‚’่กŒใ†ใ‹ใ€ๅˆฉ็”จๅฏ่ƒฝใชใ‚ฏใƒฉใ‚คใ‚ขใƒณใƒˆ ใƒฉใ‚คใƒ–ใƒฉใƒชใฎไธ€ใคใ‚’ไฝฟ็”จใ—ใพใ™ใ€‚

ใƒชใ‚ฏใ‚จใ‚นใƒˆๆœฌๆ–‡ใ‚’ๅฟ…่ฆใจใ™ใ‚‹ API ใƒชใ‚ฏใ‚จใ‚นใƒˆ๏ผˆPOSTใ€UPDATEใ€PATCH ใƒชใ‚ฏใ‚จใ‚นใƒˆใชใฉ๏ผ‰ใ‚’่กŒใ†ๅ ดๅˆใ€ใƒชใ‚ฏใ‚จใ‚นใƒˆใฎๆœฌๆ–‡ใซใฏใ€ใ“ใฎใƒชใ‚ฏใ‚จใ‚นใƒˆใง่จญๅฎšใ™ใ‚‹ใƒชใ‚ฝใƒผใ‚น ใƒ—ใƒญใƒ‘ใƒ†ใ‚ฃใ‚’ๅซใ‚ใพใ™ใ€‚ใŸใจใˆใฐใ€ๆฌกใฎ curl ใ‚ณใƒžใƒณใƒ‰ใฏใ€ใ‚คใƒณใ‚นใ‚ฟใƒณใ‚น ใƒชใ‚ฝใƒผใ‚น URI ใซๅฏพใ—ใฆ POST ใƒชใ‚ฏใ‚จใ‚นใƒˆใ‚’่กŒใ„ใพใ™ใ€‚ใ“ใฎใƒชใ‚ฏใ‚จใ‚นใƒˆใงใฏใ€ใƒชใ‚ฏใ‚จใ‚นใƒˆใฎๆœฌๆ–‡ใซๅฎš็พฉใ•ใ‚ŒใŸใƒ—ใƒญใƒ‘ใƒ†ใ‚ฃใ‚’ๆŒใคใ‚คใƒณใ‚นใ‚ฟใƒณใ‚นใŒไฝœๆˆใ•ใ‚Œใพใ™ใ€‚ใƒชใ‚ฏใ‚จใ‚นใƒˆใฎๆœฌๆ–‡ใฏใ€-d ใƒ•ใƒฉใ‚ฐใงๆŒ‡ๅฎšใ—ใพใ™ใ€‚

curl -X POST -H "Authorization: Bearer [OAUTH_TOKEN]" -H "Content-Type: application/json" \
https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/instances -d \
'{
  "disks":[
    {
      "boot":"true",
      "initializeParams":{
        "sourceImage":"https://www.googleapis.com/compute/v1/projects/debian-cloud/global/images/debian-10-buster-v20210122"
      }
    }
  ],
  "machineType":"https://www.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/machineTypes/e2-standard-2",
  "name":"VM_NAME",
  "networkInterfaces":[
    {
      "accessConfigs":[
        {
          "name":"external-nat",
          "type":"ONE_TO_ONE_NAT"
        }
      ],
      "network":"https://www.googleapis.com/compute/v1/projects/PROJECT_ID/global/networks/default"
    }
  ]
}'

ใ‚คใƒกใƒผใ‚ธ URI ใฎใƒ—ใƒญใ‚ธใ‚งใ‚ฏใƒˆ ID๏ผˆdebian-cloud๏ผ‰ใŒใ€ใƒฆใƒผใ‚ถใƒผใฎใƒ—ใƒญใ‚ธใ‚งใ‚ฏใƒˆ ID ใจ็•ฐใชใฃใฆใ„ใพใ™ใ€‚ใ“ใ‚Œใฏใ‚คใƒกใƒผใ‚ธใŒใใฎใ‚ฟใ‚คใƒ—ใซๅฟœใ˜ใฆใ€็•ฐใชใ‚‹ใƒ—ใƒญใ‚ธใ‚งใ‚ฏใƒˆใซๅฑžใ™ใ‚‹ใŸใ‚ใงใ™ใ€‚ใŸใจใˆใฐใ€Compute Engine ใซใ‚ˆใฃใฆๆไพ›ใ•ใ‚Œใฆใ„ใ‚‹ใ™ในใฆใฎไธ€่ˆฌๅ…ฌ้–‹ Debian ใ‚คใƒกใƒผใ‚ธใฏใ€debian-cloud ใƒ—ใƒญใ‚ธใ‚งใ‚ฏใƒˆใงใƒ›ใ‚นใƒˆใ•ใ‚Œใฆใ„ใพใ™ใ€‚

ๅˆฅใฎใƒชใ‚ฝใƒผใ‚นใ‚’ๅ‚็…งใ™ใ‚‹ๅ ดๅˆใฏใ€ๅฎŒๅ…จไฟฎ้ฃพใƒชใ‚ฝใƒผใ‚น URI ใ‚’ไฝฟ็”จใ—ใพใ™ใ€‚ใŸใจใˆใฐใ€network ใƒ—ใƒญใƒ‘ใƒ†ใ‚ฃใงใฏใ€default ใƒใƒƒใƒˆใƒฏใƒผใ‚ฏใธใฎๅฎŒๅ…จไฟฎ้ฃพ URI ใ‚’ไฝฟ็”จใ—ใพใ™ใ€‚

API ใƒชใ‚ฏใ‚จใ‚นใƒˆใฎไพ‹

Python

def create_instance(
    compute: object,
    project: str,
    zone: str,
    name: str,
    bucket: str,
) -> str:
    """Creates an instance in the specified zone.

    Args:
      compute: an initialized compute service object.
      project: the Google Cloud project ID.
      zone: the name of the zone in which the instances should be created.
      name: the name of the instance.
      bucket: the name of the bucket in which the image should be written.

    Returns:
      The instance object.
    """
    # Get the latest Debian Jessie image.
    image_response = (
        compute.images()
        .getFromFamily(project="debian-cloud", family="debian-11")
        .execute()
    )
    source_disk_image = image_response["selfLink"]

    # Configure the machine
    machine_type = "zones/%s/machineTypes/n1-standard-1" % zone
    startup_script = open(
        os.path.join(os.path.dirname(__file__), "startup-script.sh")
    ).read()
    image_url = "http://storage.googleapis.com/gce-demo-input/photo.jpg"
    image_caption = "Ready for dessert?"

    config = {
        "name": name,
        "machineType": machine_type,
        # Specify the boot disk and the image to use as a source.
        "disks": [
            {
                "boot": True,
                "autoDelete": True,
                "initializeParams": {
                    "sourceImage": source_disk_image,
                },
            }
        ],
        # Specify a network interface with NAT to access the public
        # internet.
        "networkInterfaces": [
            {
                "network": "global/networks/default",
                "accessConfigs": [{"type": "ONE_TO_ONE_NAT", "name": "External NAT"}],
            }
        ],
        # Allow the instance to access cloud storage and logging.
        "serviceAccounts": [
            {
                "email": "default",
                "scopes": [
                    "https://www.googleapis.com/auth/devstorage.read_write",
                    "https://www.googleapis.com/auth/logging.write",
                ],
            }
        ],
        # Metadata is readable from the instance and allows you to
        # pass configuration from deployment scripts to instances.
        "metadata": {
            "items": [
                {
                    # Startup script is automatically executed by the
                    # instance upon startup.
                    "key": "startup-script",
                    "value": startup_script,
                },
                {"key": "url", "value": image_url},
                {"key": "text", "value": image_caption},
                {"key": "bucket", "value": bucket},
            ]
        },
    }

    return compute.instances().insert(project=project, zone=zone, body=config).execute()

Java

public static Operation startInstance(Compute compute, String instanceName) throws IOException {
  System.out.println("================== Starting New Instance ==================");

  // Create VM Instance object with the required properties.
  Instance instance = new Instance();
  instance.setName(instanceName);
  instance.setMachineType(
      String.format(
          "https://www.googleapis.com/compute/v1/projects/%s/zones/%s/machineTypes/e2-standard-1",
          PROJECT_ID, ZONE_NAME));
  // Add Network Interface to be used by VM Instance.
  NetworkInterface ifc = new NetworkInterface();
  ifc.setNetwork(
      String.format(
          "https://www.googleapis.com/compute/v1/projects/%s/global/networks/default",
          PROJECT_ID));
  List<AccessConfig> configs = new ArrayList<>();
  AccessConfig config = new AccessConfig();
  config.setType(NETWORK_INTERFACE_CONFIG);
  config.setName(NETWORK_ACCESS_CONFIG);
  configs.add(config);
  ifc.setAccessConfigs(configs);
  instance.setNetworkInterfaces(Collections.singletonList(ifc));

  // Add attached Persistent Disk to be used by VM Instance.
  AttachedDisk disk = new AttachedDisk();
  disk.setBoot(true);
  disk.setAutoDelete(true);
  disk.setType("PERSISTENT");
  AttachedDiskInitializeParams params = new AttachedDiskInitializeParams();
  // Assign the Persistent Disk the same name as the VM Instance.
  params.setDiskName(instanceName);
  // Specify the source operating system machine image to be used by the VM Instance.
  params.setSourceImage(SOURCE_IMAGE_PREFIX + SOURCE_IMAGE_PATH);
  // Specify the disk type as Standard Persistent Disk
  params.setDiskType(
      String.format(
          "https://www.googleapis.com/compute/v1/projects/%s/zones/%s/diskTypes/pd-standard",
          PROJECT_ID, ZONE_NAME));
  disk.setInitializeParams(params);
  instance.setDisks(Collections.singletonList(disk));

  // Initialize the service account to be used by the VM Instance and set the API access scopes.
  ServiceAccount account = new ServiceAccount();
  account.setEmail("default");
  List<String> scopes = new ArrayList<>();
  scopes.add("https://www.googleapis.com/auth/devstorage.full_control");
  scopes.add("https://www.googleapis.com/auth/compute");
  account.setScopes(scopes);
  instance.setServiceAccounts(Collections.singletonList(account));

  // Optional - Add a startup script to be used by the VM Instance.
  Metadata meta = new Metadata();
  Metadata.Items item = new Metadata.Items();
  item.setKey("startup-script-url");
  // If you put a script called "vm-startup.sh" in this Google Cloud Storage
  // bucket, it will execute on VM startup.  This assumes you've created a
  // bucket named the same as your PROJECT_ID.
  // For info on creating buckets see:
  // https://cloud.google.com/storage/docs/cloud-console#_creatingbuckets
  item.setValue(String.format("gs://%s/vm-startup.sh", PROJECT_ID));
  meta.setItems(Collections.singletonList(item));
  instance.setMetadata(meta);

  System.out.println(instance.toPrettyString());
  Compute.Instances.Insert insert = compute.instances().insert(PROJECT_ID, ZONE_NAME, instance);
  return insert.execute();
}

URI ใƒชใ‚ฝใƒผใ‚นใฎไฝœๆˆ

Compute Engine API ใงใฏใ€ๅˆฅใฎ Google Cloud ใƒชใ‚ฝใƒผใ‚นใธใฎๅ‚็…งใ‚’ๅฎŒๅ…จไฟฎ้ฃพ URI ใจใ—ใฆๆŒ‡ๅฎšใ—ใพใ™ใ€‚

https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/RESOURCE_TYPE/SPECIFIC_RESOURCE

API ใ‚’ไฝฟ็”จใ™ใ‚‹ๅ ดๅˆใ€ใ‚คใƒกใƒผใ‚ธใ€ใƒžใ‚ทใƒณใ‚ฟใ‚คใƒ—ใ€ใƒใƒƒใƒˆใƒฏใƒผใ‚ฏใ€ใใฎไป–ใฎใƒชใ‚ฝใƒผใ‚นใ‚’ๆŒ‡ๅฎšใ™ใ‚‹้š›ใซใฏๅธธใซใ€ใใฎใƒชใ‚ฝใƒผใ‚นใฎ URI ใ‚’ๆŒ‡ๅฎšใ™ใ‚‹ๅฟ…่ฆใŒใ‚ใ‚Šใพใ™ใ€‚Google Cloud CLI ใ‚„ Google Cloud ใ‚ณใƒณใ‚ฝใƒผใƒซใชใฉใฎใ‚ฏใƒฉใ‚คใ‚ขใƒณใƒˆ ใƒ„ใƒผใƒซใ‚’ไฝฟ็”จใ™ใ‚Œใฐใ€ใ“ใ‚Œใ‚‰ใฎใƒชใ‚ฝใƒผใ‚น URI ใฎไฝœๆˆใจใ„ใ†้ขๅ€’ใชไฝœๆฅญใ‚’ใ™ในใฆ่‚ฉไปฃใ‚ใ‚Šใ—ใฆใใ‚Œใพใ™ใŒใ€API ใ‚’็›ดๆŽฅๆ“ไฝœใ™ใ‚‹ๅ ดๅˆใฏใ€ใ“ใ‚Œใ‚‰ใฎใƒชใ‚ฝใƒผใ‚น URI ใ‚’่‡ชๅˆ†ใงไฝœๆˆใ™ใ‚‹ๅฟ…่ฆใŒใ‚ใ‚Šใพใ™ใ€‚

ใƒชใ‚ฝใƒผใ‚น URI ใฏใ€ใƒชใ‚ฝใƒผใ‚นใฎใ‚ฟใ‚คใƒ—ใซๅฟœใ˜ใฆ่‹ฅๅนฒ็•ฐใชใ‚Šใพใ™ใ€‚ใŸใจใˆใฐใ€ใ‚พใƒผใƒณใƒชใ‚ฝใƒผใ‚นใซใฏใ€URI ใซ zone ไป•ๆง˜ใŒใ‚ใ‚Šใพใ™ใ€‚

https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/machineTypes/e2-standard-2

ใƒชใƒผใ‚ธใƒงใƒณ ใƒชใ‚ฝใƒผใ‚นใงใฏใ€zone ไป•ๆง˜ใŒ region ไป•ๆง˜ใซ็ฝฎใๆ›ใ‚ใ‚Šใพใ™ใ€‚

https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/regions/REGION/addresses/ADDRESS_NAME

ๅŒๆง˜ใซใ€ใ‚ฐใƒญใƒผใƒใƒซ ใƒชใ‚ฝใƒผใ‚นใงใฏใ€global ไป•ๆง˜ใซใชใ‚Šใพใ™ใ€‚

https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/global/images/VM_NAME

Compute Engine API ใงใฏใ€ใƒ—ใƒญใ‚ธใ‚งใ‚ฏใƒˆ ID ใชใฉใฎๆƒ…ๅ ฑใ‚’ๆŽจๆธฌใงใใ‚‹ใŸใ‚ใ€้ƒจๅˆ† URI ใ‚‚ไฝฟ็”จใงใใพใ™ใ€‚ใใฎใŸใ‚ใ€ๆฌกใฎใ‚ˆใ†ใซใ€ไธŠ่จ˜ URI ใฎ้ƒจๅˆ† URI ใƒใƒผใ‚ธใƒงใƒณใ‚‚ไฝฟ็”จใงใใพใ™ใ€‚

zones/ZONE/machineTypes/e2-standard-2
regions/REGION/addresses/ADDRESS_NAME
project/PROJECT_ID/global/images/VM_NAME

้ƒจๅˆ† URI ใงใฏใ€ใ‚พใƒผใƒณ URI ใจใƒชใƒผใ‚ธใƒงใƒณ URI ใฎไธกๆ–นใงใƒ—ใƒญใ‚ธใ‚งใ‚ฏใƒˆ ID ใŒ็œ็•ฅใ•ใ‚Œใฆใ„ใพใ™ใŒใ€ใ‚คใƒกใƒผใ‚ธ URI ใงใฏ็œ็•ฅใ•ใ‚Œใฆใ„ใพใ›ใ‚“ใ€‚ใ“ใ‚Œใฏใ€Compute Engine ใซใ‚ˆใฃใฆไธ€่ˆฌๅ…ฌ้–‹ใ•ใ‚Œใฆใ„ใ‚‹ใ‚คใƒกใƒผใ‚ธใŒไป–ใฎใƒ—ใƒญใ‚ธใ‚งใ‚ฏใƒˆ๏ผˆใ™ในใฆใฎ Debian ใ‚คใƒกใƒผใ‚ธใฏ debian-cloudใ€ใ™ในใฆใฎ Ubuntu ใ‚คใƒกใƒผใ‚ธใฏ ubuntu-os-cloud ใชใฉ๏ผ‰ใงใƒ›ใ‚นใƒˆใ•ใ‚Œใฆใ„ใ‚‹ใŸใ‚ใงใ™ใ€‚ใ“ใ†ใ—ใŸใ‚คใƒกใƒผใ‚ธใ‚’ไฝฟ็”จใ™ใ‚‹ๅ‰ใซใ€้ฉๅˆ‡ใชใƒ—ใƒญใ‚ธใ‚งใ‚ฏใƒˆ ID ใ‚’ๆŒ‡ๅฎšใ™ใ‚‹ๅฟ…่ฆใŒใ‚ใ‚Šใพใ™ใ€‚ใ‚คใƒกใƒผใ‚ธใฎใƒ—ใƒญใ‚ธใ‚งใ‚ฏใƒˆ ID ใ‚’็œ็•ฅใ™ใ‚‹ใจใ€Compute Engine ใฏ็พๅœจใฎใƒ—ใƒญใ‚ธใ‚งใ‚ฏใƒˆๅ†…ใฎใ‚คใƒกใƒผใ‚ธใ‚’่ฆ‹ใคใ‘ใ‚ˆใ†ใจใ—ใพใ™ใŒใ€ใ‚คใƒกใƒผใ‚ธใŒๅญ˜ๅœจใ—ใชใ„ใŸใ‚ใ€ใƒชใ‚ฏใ‚จใ‚นใƒˆใฏๅคฑๆ•—ใ—ใพใ™ใ€‚

ใŸใ ใ—ใ€ใƒ—ใƒญใ‚ธใ‚งใ‚ฏใƒˆ๏ผˆใ“ใฎใƒชใ‚ฝใƒผใ‚นใ‚’ไฝœๆˆใ—ใฆใ„ใ‚‹ใƒ—ใƒญใ‚ธใ‚งใ‚ฏใƒˆ๏ผ‰ใซๅฑžใ™ใ‚‹ใ‚ซใ‚นใ‚ฟใƒ  ใ‚คใƒกใƒผใ‚ธใ‚’ไฝฟ็”จใ™ใ‚‹ๅ ดๅˆใฏใ€ใ‚คใƒกใƒผใ‚ธ URI ใ‚’ๆŒ‡ๅฎšใ™ใ‚‹้š›ใซใƒ—ใƒญใ‚ธใ‚งใ‚ฏใƒˆใฎๆŒ‡ๅฎšใ‚’็œ็•ฅใงใใพใ™ใ€‚

ๅฟ…่ฆใชใƒ—ใƒญใƒ‘ใƒ†ใ‚ฃใฎ็ขบ่ช

v1 API ใจใƒ™ใƒผใ‚ฟ็‰ˆ API ใงๅˆฉ็”จๅฏ่ƒฝใช Compute Engine API ใƒชใƒ•ใ‚กใƒฌใƒณใ‚น ใƒ‰ใ‚ญใƒฅใƒกใƒณใƒˆใงใฏใ€็‰นๅฎšใฎใƒชใ‚ฝใƒผใ‚นใซ่จญๅฎšๅฏ่ƒฝใชใ™ในใฆใฎใƒ—ใƒญใƒ‘ใƒ†ใ‚ฃใซใคใ„ใฆ่ชฌๆ˜Žใ—ใฆใ„ใพใ™ใ€‚ใ“ใฎใƒชใƒ•ใ‚กใƒฌใƒณใ‚น ใƒ‰ใ‚ญใƒฅใƒกใƒณใƒˆใงใฏใ€ๅค‰ๆ›ดๅฏ่ƒฝใชใƒ—ใƒญใƒ‘ใƒ†ใ‚ฃใจๅค‰ๆ›ดไธๅฏใฎใƒ—ใƒญใƒ‘ใƒ†ใ‚ฃ๏ผˆใƒ—ใƒญใƒ‘ใƒ†ใ‚ฃใฎ่ชฌๆ˜Žใง [Output Only] ใจใƒžใƒผใ‚ฏใ•ใ‚Œใฆใ„ใ‚‹๏ผ‰ใ‚’ๅŒบๅˆฅใ—ใฆใ„ใพใ™ใŒใ€ใƒชใ‚ฝใƒผใ‚นใฎๅฟ…้ ˆใƒ—ใƒญใƒ‘ใƒ†ใ‚ฃใ‚’็ขบ่ชใ™ใ‚‹ใซใฏใ€ใใฎใ‚ฟใ‚นใ‚ฏใซๅ›บๆœ‰ใฎใƒ‰ใ‚ญใƒฅใƒกใƒณใƒˆใ‚’ๅ‚็…งใ™ใ‚‹ๅฟ…่ฆใŒใ‚ใ‚Šใพใ™ใ€‚

ใŸใจใˆใฐใ€ใ‚คใƒณใ‚นใ‚ฟใƒณใ‚นใ‚’ไฝœๆˆใ™ใ‚‹ๅ ดๅˆใฏใ€ใ‚คใƒกใƒผใ‚ธใ‹ใ‚‰ใฎใ‚คใƒณใ‚นใ‚ฟใƒณใ‚นใฎไฝœๆˆใฎใƒ‰ใ‚ญใƒฅใƒกใƒณใƒˆใงใ€ใƒชใ‚ฏใ‚จใ‚นใƒˆใซๅฟ…่ฆใช API ใƒ—ใƒญใƒ‘ใƒ†ใ‚ฃใ‚’็ขบ่ชใ—ใฆใใ ใ•ใ„ใ€‚API ใง้™็š„ๅค–้ƒจ IP ใ‚ขใƒ‰ใƒฌใ‚นใ‚’ไฝœๆˆใ™ใ‚‹ๅ ดๅˆใฏใ€้™็š„ๅค–้ƒจ IP ใ‚ขใƒ‰ใƒฌใ‚นใฎใƒ‰ใ‚ญใƒฅใƒกใƒณใƒˆใ‚’ใ”่ฆงใใ ใ•ใ„ใ€‚

API ใƒชใ‚ฏใ‚จใ‚นใƒˆใฎๆคœ่จผ

API ใƒชใ‚ฏใ‚จใ‚นใƒˆใ‚’ๆคœ่จผใ™ใ‚‹ใซใฏ:

  1. Compute Engine API ใƒชใƒ•ใ‚กใƒฌใƒณใ‚นใงใ€ใ‚ณใƒผใƒ‰ใŒๅ‘ผใณๅ‡บใ™ใƒกใ‚ฝใƒƒใƒ‰ใ‚’็ขบ่ชใ—ใพใ™ใ€‚ใŸใจใˆใฐใ€v1/compute.instances.insert ใงใ™ใ€‚
  2. ใ‚ณใƒณใƒ†ใƒณใƒ„ ใƒกใƒ‹ใƒฅใƒผใ‹ใ‚‰ [่ฉฆใ—ใฆใฟใ‚‹] ใ‚’ใ‚ฏใƒชใƒƒใ‚ฏใ—ใพใ™ใ€‚[ใ“ใฎ API ใ‚’่ฉฆใ™] ใ‚ฆใ‚ฃใƒณใƒ‰ใ‚ฆใŒ้–‹ใใพใ™ใ€‚

    ใ‚ณใƒณใƒ†ใƒณใƒ„ ใƒกใƒ‹ใƒฅใƒผใซใ‚ใ‚‹ [่ฉฆใ—ใฆใฟใ‚‹] ใƒœใ‚ฟใƒณใ€‚

  3. ๆคœ่จผใงใฏใƒชใ‚ฏใ‚จใ‚นใƒˆใ‚’้€ไฟกใ™ใ‚‹ๅฟ…่ฆใŒใชใ„ใŸใ‚ใ€[ใƒชใ‚ฏใ‚จใ‚นใƒˆ ใƒ‘ใƒฉใƒกใƒผใ‚ฟ] ใงใƒ—ใƒญใ‚ธใ‚งใ‚ฏใƒˆใ‚„ใ‚พใƒผใƒณใ‚’ๆŒ‡ๅฎšใ™ใ‚‹ๅฟ…่ฆใฏใ‚ใ‚Šใพใ›ใ‚“ใ€‚

  4. [ใƒชใ‚ฏใ‚จใ‚นใƒˆๆœฌๆ–‡] ใซใ€ใƒชใ‚ฏใ‚จใ‚นใƒˆใ‚’่ฒผใ‚Šไป˜ใ‘ใพใ™ใ€‚

    ๆคœ่จผ็”จใฎใƒชใ‚ฏใ‚จใ‚นใƒˆใฎ่ฒผใ‚Šไป˜ใ‘ๅ…ˆใ‚’็คบใ™ [Request body] ใƒ•ใ‚ฃใƒผใƒซใƒ‰ใ‚’่กจ็คบใ—ใฆใ„ใ‚‹ [ใ“ใฎ API ใ‚’่ฉฆใ™] ใ‚ฆใ‚ฃใƒณใƒ‰ใ‚ฆใ€‚

ใƒชใ‚ฏใ‚จใ‚นใƒˆใฎๅฝขๅผใŒๆญฃใ—ใใชใ„่ฆ็ด ใซใ€ไธ‹็ทšใŒๅผ•ใ‹ใ‚Œใพใ™ใ€‚ๅฏพๅ‡ฆใ™ในใๅ•้กŒใฎ่ฉณ็ดฐใซใคใ„ใฆใฏใ€ไธ‹็ทšไป˜ใใฎใ‚ปใ‚ฏใ‚ทใƒงใƒณใ‚’ใ‚ฏใƒชใƒƒใ‚ฏใ—ใฆใใ ใ•ใ„ใ€‚

API ใƒฌใ‚นใƒใƒณใ‚นใฎๅ‡ฆ็†

ใƒ‡ใƒผใ‚ฟใ‚’ๅค‰ๅŒ–ใ•ใ›ใ‚‹๏ผˆๅค‰ๆ›ดใ™ใ‚‹๏ผ‰ใƒชใ‚ฏใ‚จใ‚นใƒˆใ‚’ไฝœๆˆใ™ใ‚‹ใจใ€Compute Engine ใฏ Operation ใ‚ชใƒ–ใ‚ธใ‚งใ‚ฏใƒˆใ‚’่ฟ”ใ—ใพใ™ใ€‚ใƒชใ‚ฏใ‚จใ‚นใƒˆใฎใ‚ชใƒšใƒฌใƒผใ‚ทใƒงใƒณใฎใ‚นใƒ†ใƒผใ‚ฟใ‚นใฏใ€ใ“ใฎใ‚ชใƒ–ใ‚ธใ‚งใ‚ฏใƒˆใ‚’ใƒใƒผใƒชใƒณใ‚ฐใ™ใ‚‹ใ“ใจใงๅ–ๅพ—ใงใใพใ™ใ€‚Operation ใƒชใ‚ฝใƒผใ‚นใฏใ€ๆฌกใฎใ‚ˆใ†ใชๅฝขใซใชใ‚Šใพใ™ใ€‚

{
 "kind": "compute#operation",
 "id": "7127550864823803662",
 "name": "operation-1458856416788-52ed27a803e22-1c3bd86a-9e95017b",
 "zone": "https://www.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE",
 "operationType": "insert",
 "targetLink": "https://www.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/instances/EXAMPLE_VM",
 "targetId": "4132355614508179214",
 "status": "PENDING",
 "user": "user@example.com",
 "progress": 0,
 "insertTime": "2016-03-24T14:53:37.788-07:00",
 "selfLink": "https://www.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/operations/operation-1458856416788-52ed27a803e22-1c3bd86a-9e95017b"
}

ๅ…ƒใฎใƒชใ‚ฏใ‚จใ‚นใƒˆใŒใ‚พใƒผใƒณใƒชใ‚ฝใƒผใ‚นใ‚’ๅค‰ๆ›ดใ™ใ‚‹ๅ ดๅˆ๏ผˆใƒ‡ใ‚ฃใ‚นใ‚ฏใฎใ‚นใƒŠใƒƒใƒ—ใ‚ทใƒงใƒƒใƒˆใ‚„ใ‚คใƒณใ‚นใ‚ฟใƒณใ‚นใฎๅœๆญขใชใฉ๏ผ‰ใ€Compute Engine ใฏ zoneOperations ใ‚ชใƒ–ใ‚ธใ‚งใ‚ฏใƒˆใ‚’่ฟ”ใ—ใพใ™ใ€‚ๅŒๆง˜ใซใ€ใƒชใƒผใ‚ธใƒงใƒณ ใƒชใ‚ฝใƒผใ‚นใจใ‚ฐใƒญใƒผใƒใƒซ ใƒชใ‚ฝใƒผใ‚นใฏใ€ใใ‚Œใžใ‚Œ regionOperations ใ‚ชใƒ–ใ‚ธใ‚งใ‚ฏใƒˆใพใŸใฏ globalOperations ใ‚ชใƒ–ใ‚ธใ‚งใ‚ฏใƒˆใ‚’่ฟ”ใ—ใพใ™ใ€‚ใ‚ชใƒšใƒฌใƒผใ‚ทใƒงใƒณใฎใ‚นใƒ†ใƒผใ‚ฟใ‚นใ‚’ๅ–ๅพ—ใ™ใ‚‹ใซใฏใ€็‰นๅฎšใฎ Operation ใƒชใ‚ฝใƒผใ‚นใซๅฏพใ—ใฆ get ใƒกใ‚ฝใƒƒใƒ‰ใพใŸใฏ wait ใƒกใ‚ฝใƒƒใƒ‰ใ‚’ไฝฟ็”จใ™ใ‚‹ใƒชใ‚ฏใ‚จใ‚นใƒˆใ‚’่กŒใ„ใ€ใ‚ชใƒšใƒฌใƒผใ‚ทใƒงใƒณใฎ name ใ‚’ๆŒ‡ๅฎšใ—ใพใ™ใ€‚

Operation ใƒชใ‚ฝใƒผใ‚นใฎใ‚นใƒ†ใƒผใ‚ฟใ‚นใŒ DONE ใจ่ฟ”ใ•ใ‚Œใ‚‹ใพใงใƒชใ‚ฏใ‚จใ‚นใƒˆใฏๅฎŒไบ†ใ—ใฆใ„ใพใ›ใ‚“ใ€‚ใƒชใ‚ฏใ‚จใ‚นใƒˆใฎๆ€ง่ณชใซใ‚ˆใฃใฆใฏใ€ๅฎŒไบ†ใพใงใซๆ™‚้–“ใ‚’่ฆใ™ใ‚‹ใ“ใจใ‚‚ใ‚ใ‚Šใพใ™ใ€‚Operation ใƒชใ‚ฝใƒผใ‚นใฎใ‚นใƒ†ใƒผใ‚ฟใ‚นใŒ DONE ใจใ—ใฆ่ฟ”ใ•ใ‚ŒใŸใ‚‰ใ€ใ‚ชใƒšใƒฌใƒผใ‚ทใƒงใƒณใŒๆˆๅŠŸใ—ใŸใ‹ใฉใ†ใ‹ใ€ใ‚จใƒฉใƒผใŒ็™บ็”Ÿใ—ใฆใ„ใชใ„ใ‹ใฉใ†ใ‹ใ‚’็ขบ่ชใงใใพใ™ใ€‚

ใŸใจใˆใฐใ€ๆฌกใฎใƒฌใ‚นใƒใƒณใ‚นใฏใ€ไธŠ่จ˜ใฎใ‚ชใƒšใƒฌใƒผใ‚ทใƒงใƒณใŒๅฎŒไบ†ใ—ใŸใ“ใจ่กจใ—ใฆใŠใ‚Šใ€DONE ใ‚นใƒ†ใƒผใ‚ฟใ‚นใซใ‚ˆใ‚Š็คบใ•ใ‚Œใฆใ„ใพใ™ใ€‚

endTime: '2016-03-24T14:54:07.119-07:00'
id: '7127550864823803662'
insertTime: '2016-03-24T14:53:37.788-07:00'
kind: compute#operation
name: operation-1458856416788-52ed27a803e22-1c3bd86a-9e95017b
operationType: insert
progress: 100
selfLink: https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/operations/operation-1458856416788-52ed27a803e22-1c3bd86a-9e95017b
startTime: '2016-03-24T14:53:38.397-07:00'
status: DONE
targetId: '4132355614508179214'
targetLink: https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/instances/EXAMPLE_VM
user: user@example.com
zone: https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE

็ขบ่ชใ™ใ‚‹ใซใฏใ€ใƒชใ‚ฝใƒผใ‚นใซๅฏพใ—ใฆ get ใƒชใ‚ฏใ‚จใ‚นใƒˆใ‚’่กŒใ„ใ€ใƒชใ‚ฝใƒผใ‚นใŒๅญ˜ๅœจใ—ใ€ๅฎŸ่กŒไธญใงใ‚ใ‚‹ใ“ใจใ‚’็ขบใ‹ใ‚ใพใ™ใ€‚ๆฌกใซไพ‹ใ‚’็คบใ—ใพใ™ใ€‚

GET /compute/v1/projects/PROJECT_ID/zones/ZONE/instances/EXAMPLE_VM

{
  "cpuPlatform": "Intel Haswell",
  "creationTimestamp": "2016-03-24T14:53:37.170-07:00",
  "disks": [
    ..[snip]..
  "selfLink": "https://www.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/instances/EXAMPLE_VM",
  "status": "RUNNING",
  "tags": {
    "fingerprint": "42WmSpB8rSM="
  },
  "zone": "https://www.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE"
}

ใ‚ชใƒšใƒฌใƒผใ‚ทใƒงใƒณใฎใƒใƒผใƒชใƒณใ‚ฐ

ใ‚ชใƒšใƒฌใƒผใ‚ทใƒงใƒณใ‚’ๅฎšๆœŸ็š„ใซใƒใƒผใƒชใƒณใ‚ฐใ™ใ‚‹ใ‚ณใƒผใƒ‰ใฏใ€get ใƒชใ‚ฏใ‚จใ‚นใƒˆใ‹ใ€ใ‚ชใƒšใƒฌใƒผใ‚ทใƒงใƒณใฎใ‚นใƒ†ใƒผใ‚ฟใ‚นใŒ DONE ใซใชใฃใŸใจใใซๆˆปใฃใฆใใ‚‹ wait ใƒชใ‚ฏใ‚จใ‚นใƒˆใ‚’ไฝฟ็”จใ—ใฆไฝœๆˆใงใใพใ™ใ€‚

get ใƒชใ‚ฏใ‚จใ‚นใƒˆใ‚’ไฝฟ็”จใ™ใ‚‹ใจใ€ใ‚ชใƒšใƒฌใƒผใ‚ทใƒงใƒณใฎใ‚นใƒ†ใƒผใ‚ฟใ‚นใซ้–ขไฟ‚ใชใใ€ใ‚ชใƒšใƒฌใƒผใ‚ทใƒงใƒณใŒใ™ใใซ่ฟ”ใ•ใ‚Œใพใ™ใ€‚ใ‚ชใƒšใƒฌใƒผใ‚ทใƒงใƒณใŒๅฎŒไบ†ใ—ใŸใ‹ใฉใ†ใ‹ใ‚’็Ÿฅใ‚‹ใŸใ‚ใซใฏใ€ใ‚ชใƒšใƒฌใƒผใ‚ทใƒงใƒณใ‚’ๅฎšๆœŸ็š„ใซใƒใƒผใƒชใƒณใ‚ฐใ™ใ‚‹ๅฟ…่ฆใŒใ‚ใ‚Šใพใ™ใ€‚

wait ใƒชใ‚ฏใ‚จใ‚นใƒˆใ‚’ไฝฟ็”จใ™ใ‚‹ใจใ€ใ‚ชใƒšใƒฌใƒผใ‚ทใƒงใƒณใŒ DONE ใซใชใ‚‹ใ‹ใ€ใƒชใ‚ฏใ‚จใ‚นใƒˆใŒ 2 ๅˆ†้–“ใฎๆœŸ้™ใซ่ฟ‘ใฅใใจใƒชใ‚ฏใ‚จใ‚นใƒˆใŒๆˆปใ‚Šใพใ™ใ€‚ใ‚ชใƒšใƒฌใƒผใ‚ทใƒงใƒณใ‚’ใƒใƒผใƒชใƒณใ‚ฐใ™ใ‚‹ใซใฏใ€wait ใ‹ get ใ‚’ไฝฟ็”จใ—ใพใ™ใŒใ€wait ใƒกใ‚ฝใƒƒใƒ‰ใฎๆ–นใŒ get ใƒกใ‚ฝใƒƒใƒ‰ใ‚ˆใ‚Šๆ˜Žใ‚‰ใ‹ใชใƒกใƒชใƒƒใƒˆใŒใ‚ใ‚Šใพใ™ใ€‚

  • ใ‚ฏใƒฉใ‚คใ‚ขใƒณใƒˆใงใ‚ชใƒšใƒฌใƒผใ‚ทใƒงใƒณ ใ‚นใƒ†ใƒผใ‚ฟใ‚นใ‚’ใƒใƒผใƒชใƒณใ‚ฐใ™ใ‚‹้ ปๅบฆใ‚’ไธ‹ใ’ใ‚‹ใ“ใจใงใ€Compute Engine API ใฎ QPS ไฝฟ็”จ้‡ใ‚’ๅ‰Šๆธ›ใงใใพใ™ใ€‚
  • ใ‚ชใƒšใƒฌใƒผใ‚ทใƒงใƒณใŒๅฎŒไบ†ใ—ใฆใ‹ใ‚‰ใ‚ฏใƒฉใ‚คใ‚ขใƒณใƒˆใซใ‚ชใƒšใƒฌใƒผใ‚ทใƒงใƒณใฎๅฎŒไบ†ใŒ้€š็Ÿฅใ•ใ‚Œใ‚‹ใพใงใฎๅนณๅ‡ใƒฌใ‚คใƒ†ใƒณใ‚ทใฏใ€ใ‚ชใƒšใƒฌใƒผใ‚ทใƒงใƒณใŒๅฎŒไบ†ใ—ใŸใ‚‰ใ™ใใซใ‚ตใƒผใƒใƒผใŒๅฟœ็ญ”ใ™ใ‚‹ใŸใ‚ใ€ๅคงๅน…ใซๅ‰Šๆธ›ใ•ใ‚Œใพใ™ใ€‚
  • ใ“ใฎใƒกใ‚ฝใƒƒใƒ‰ใฏๆœŸ้™ไป˜ใใงๅพ…ๆฉŸใ—ใพใ™ใ€‚ใ“ใฎใƒกใ‚ฝใƒƒใƒ‰ใฏใ€ใƒ‡ใƒ•ใ‚ฉใƒซใƒˆใฎ HTTP ใ‚ฟใ‚คใƒ ใ‚ขใ‚ฆใƒˆ๏ผˆ2 ๅˆ†๏ผ‰ใพใงๅพ…ๆฉŸใ™ใ‚‹ใจใ€ใ‚ชใƒšใƒฌใƒผใ‚ทใƒงใƒณใฎ็พๅœจใฎ็Šถๆ…‹๏ผˆDONE ใพใŸใฏ้€ฒ่กŒไธญ๏ผ‰ใ‚’่ฟ”ใ—ใพใ™ใ€‚

wait ใƒกใ‚ฝใƒƒใƒ‰ใฏใ€ใƒ™ใ‚นใƒˆ ใ‚จใƒ•ใ‚ฉใƒผใƒˆใฎ API ใงใ™ใ€‚ใ‚ตใƒผใƒใƒผใŒ้Ž่ฒ ่ท็Šถๆ…‹ใซใชใ‚‹ใจใ€ใƒ‡ใƒ•ใ‚ฉใƒซใƒˆใฎๆœŸ้™ใซ้”ใ™ใ‚‹ๅ‰ใ‚„ใ€0 ็ง’้–“ใฎๅพ…ๆฉŸใงใƒชใ‚ฏใ‚จใ‚นใƒˆใŒๆˆปใ‚‹ใ“ใจใŒใ‚ใ‚Šใพใ™ใ€‚ใพใŸใ€ใ‚ชใƒšใƒฌใƒผใ‚ทใƒงใƒณใŒ DONE ใฎๅ ดๅˆใซใฎใฟใƒกใ‚ฝใƒƒใƒ‰ใŒๆˆปใ‚‹ใ“ใจใฏไฟ่จผใ—ใพใ›ใ‚“ใ€‚ใŸใจใˆใฐใ€ใƒชใ‚ฏใ‚จใ‚นใƒˆใŒ 2 ๅˆ†้–“ใฎๆœŸ้™ใซ่ฟ‘ใฅใใจใ€ใ‚ชใƒšใƒฌใƒผใ‚ทใƒงใƒณใŒๅฎŒไบ†ใ—ใฆใ„ใชใใฆใ‚‚ใƒกใ‚ฝใƒƒใƒ‰ใŒๆˆปใ‚Šใพใ™ใ€‚ใ‚ชใƒšใƒฌใƒผใ‚ทใƒงใƒณใ‚’็ขบ่ชใ™ใ‚‹ใซใฏใ€wait ใƒกใ‚ฝใƒƒใƒ‰ใพใŸใฏ get ใƒกใ‚ฝใƒƒใƒ‰ใ‚’๏ผˆใ‚นใƒชใƒผใƒ—ใ‚’้–“ใซๆŒŸใ‚“ใ ๅ†่ฉฆ่กŒใƒซใƒผใƒ—ใง๏ผ‰ไฝฟ็”จใ—ใ€ใ‚ชใƒšใƒฌใƒผใ‚ทใƒงใƒณใฎใ‚นใƒ†ใƒผใ‚ฟใ‚นใ‚’ๅฎšๆœŸ็š„ใซใƒใƒผใƒชใƒณใ‚ฐใ™ใ‚‹ใ“ใจใ‚’ใŠใ™ใ™ใ‚ใ—ใพใ™ใ€‚ๆœ€ๅคงๅ†่ฉฆ่กŒ้–“้š”ใฏใ€ๆœ€ๅฐใ‚ชใƒšใƒฌใƒผใ‚ทใƒงใƒณไฟๆŒๆœŸ้–“ใ‚’่ถ…ใˆใชใ„ใ‚ˆใ†ใซใ—ใฆใใ ใ•ใ„ใ€‚

ใƒใƒผใƒชใƒณใ‚ฐใฎไพ‹

ๆฌกใฎไพ‹ใงใฏใ€get ใƒกใ‚ฝใƒƒใƒ‰ใ‚’ไฝฟ็”จใ—ใพใ™ใ€‚get ใƒกใ‚ฝใƒƒใƒ‰ใฏ wait ใƒกใ‚ฝใƒƒใƒ‰ใซ็ฝฎใๆ›ใˆใ‚‹ใ“ใจใŒใงใใพใ™ใ€‚

Python

def wait_for_operation(
    compute: object,
    project: str,
    zone: str,
    operation: str,
) -> dict:
    """Waits for the given operation to complete.

    Args:
      compute: an initialized compute service object.
      project: the Google Cloud project ID.
      zone: the name of the zone in which the operation should be executed.
      operation: the operation ID.

    Returns:
      The result of the operation.
    """
    print("Waiting for operation to finish...")
    while True:
        result = (
            compute.zoneOperations()
            .get(project=project, zone=zone, operation=operation)
            .execute()
        )

        if result["status"] == "DONE":
            print("done.")
            if "error" in result:
                raise Exception(result["error"])
            return result

        time.sleep(1)

Java

/**
 * Wait until {@code operation} is completed.
 *
 * @param compute the {@code Compute} object
 * @param operation the operation returned by the original request
 * @param timeout the timeout, in millis
 * @return the error, if any, else {@code null} if there was no error
 * @throws InterruptedException if we timed out waiting for the operation to complete
 * @throws IOException if we had trouble connecting
 */
public static Operation.Error blockUntilComplete(
    Compute compute, Operation operation, long timeout) throws Exception {
  long start = System.currentTimeMillis();
  final long pollInterval = 5 * 1000;
  String zone = getLastWordFromUrl(operation.getZone()); // null for global/regional operations
  String region = getLastWordFromUrl(operation.getRegion());
  String status = operation.getStatus();
  String opId = operation.getName();
  while (operation != null && !status.equals("DONE")) {
    Thread.sleep(pollInterval);
    long elapsed = System.currentTimeMillis() - start;
    if (elapsed >= timeout) {
      throw new InterruptedException("Timed out waiting for operation to complete");
    }
    System.out.println("waiting...");
    if (zone != null) {
      Compute.ZoneOperations.Get get = compute.zoneOperations().get(PROJECT_ID, zone, opId);
      operation = get.execute();
    } else if (region != null) {
      Compute.RegionOperations.Get get = compute.regionOperations().get(PROJECT_ID, region, opId);
      operation = get.execute();
    } else {
      Compute.GlobalOperations.Get get = compute.globalOperations().get(PROJECT_ID, opId);
      operation = get.execute();
    }
    if (operation != null) {
      status = operation.getStatus();
    }
  }
  return operation == null ? null : operation.getError();
}