279 lines
9.2 KiB
Python
279 lines
9.2 KiB
Python
# -*- coding: utf-8 -*- #
|
|
# Copyright 2018 Google LLC. All Rights Reserved.
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
"""Utilities for handling Compute DisksService and RegionDisksService."""
|
|
|
|
from __future__ import absolute_import
|
|
from __future__ import division
|
|
from __future__ import unicode_literals
|
|
|
|
from typing import Any
|
|
|
|
from googlecloudsdk.api_lib.compute import utils as compute_utils
|
|
from googlecloudsdk.core.exceptions import Error
|
|
|
|
_SUPPORTED_DISK_TYPES_IOPS = frozenset([
|
|
'pd-extreme',
|
|
'cs-extreme',
|
|
'hyperdisk-extreme',
|
|
'hyperdisk-balanced',
|
|
'hyperdisk-balanced-high-availability',
|
|
])
|
|
_SUPPORTED_DISK_TYPES_THROUGHPUT = frozenset([
|
|
'cs-throughput',
|
|
'hyperdisk-throughput',
|
|
'hyperdisk-balanced',
|
|
'hyperdisk-ml',
|
|
'hyperdisk-balanced-high-availability',
|
|
])
|
|
|
|
|
|
class UnknownDiskResourceError(Error):
|
|
"""Raised when a disk resource argument is neither regional nor zonal."""
|
|
|
|
|
|
class _ZonalDisk(object):
|
|
"""A wrapper for Compute Engine DisksService API client."""
|
|
|
|
def __init__(self, client, disk_ref, messages):
|
|
self._disk_ref = disk_ref
|
|
self._client = client
|
|
self._service = client.disks or client.apitools_client.disks
|
|
self._messages = messages
|
|
|
|
@classmethod
|
|
def GetOperationCollection(cls):
|
|
"""Gets the zonal operation collection of a compute disk reference."""
|
|
return 'compute.zoneOperations'
|
|
|
|
def GetService(self):
|
|
return self._service
|
|
|
|
def GetDiskRequestMessage(self):
|
|
"""Gets the zonal compute disk get request message."""
|
|
return self._messages.ComputeDisksGetRequest(**self._disk_ref.AsDict())
|
|
|
|
def GetDiskResource(self):
|
|
request_msg = self.GetDiskRequestMessage()
|
|
return self._service.Get(request_msg)
|
|
|
|
def GetSetLabelsRequestMessage(self):
|
|
return self._messages.ZoneSetLabelsRequest
|
|
|
|
def GetSetDiskLabelsRequestMessage(self, disk, labels):
|
|
req = self._messages.ComputeDisksSetLabelsRequest
|
|
return req(
|
|
project=self._disk_ref.project,
|
|
resource=self._disk_ref.disk,
|
|
zone=self._disk_ref.zone,
|
|
zoneSetLabelsRequest=self._messages.ZoneSetLabelsRequest(
|
|
labelFingerprint=disk.labelFingerprint, labels=labels))
|
|
|
|
def GetDiskRegionName(self):
|
|
return compute_utils.ZoneNameToRegionName(self._disk_ref.zone)
|
|
|
|
def MakeAddResourcePoliciesRequest(self, resource_policies,
|
|
client_to_make_request):
|
|
add_request = self._messages.ComputeDisksAddResourcePoliciesRequest(
|
|
disk=self._disk_ref.Name(),
|
|
project=self._disk_ref.project,
|
|
zone=self._disk_ref.zone,
|
|
disksAddResourcePoliciesRequest=self._messages
|
|
.DisksAddResourcePoliciesRequest(resourcePolicies=resource_policies))
|
|
return client_to_make_request.MakeRequests(
|
|
[(self._client.disks, 'AddResourcePolicies', add_request)])
|
|
|
|
def MakeRemoveResourcePoliciesRequest(self, resource_policies,
|
|
client_to_make_request):
|
|
remove_request = self._messages.ComputeDisksRemoveResourcePoliciesRequest(
|
|
disk=self._disk_ref.Name(),
|
|
project=self._disk_ref.project,
|
|
zone=self._disk_ref.zone,
|
|
disksRemoveResourcePoliciesRequest=self._messages
|
|
.DisksRemoveResourcePoliciesRequest(resourcePolicies=resource_policies))
|
|
return client_to_make_request.MakeRequests(
|
|
[(self._client.disks, 'RemoveResourcePolicies', remove_request)])
|
|
|
|
|
|
class _RegionalDisk(object):
|
|
"""A wrapper for Compute Engine RegionDisksService API client."""
|
|
|
|
def __init__(self, client, disk_ref, messages):
|
|
self._disk_ref = disk_ref
|
|
self._client = client
|
|
self._service = client.regionDisks
|
|
self._messages = messages
|
|
|
|
@classmethod
|
|
def GetOperationCollection(cls):
|
|
return 'compute.regionOperations'
|
|
|
|
def GetService(self):
|
|
return self._service
|
|
|
|
def GetDiskRequestMessage(self):
|
|
return self._messages.ComputeRegionDisksGetRequest(
|
|
**self._disk_ref.AsDict())
|
|
|
|
def GetDiskResource(self):
|
|
request_msg = self.GetDiskRequestMessage()
|
|
return self._service.Get(request_msg)
|
|
|
|
def GetSetLabelsRequestMessage(self):
|
|
return self._messages.RegionSetLabelsRequest
|
|
|
|
def GetSetDiskLabelsRequestMessage(self, disk, labels):
|
|
req = self._messages.ComputeRegionDisksSetLabelsRequest
|
|
return req(
|
|
project=self._disk_ref.project,
|
|
resource=self._disk_ref.disk,
|
|
region=self._disk_ref.region,
|
|
regionSetLabelsRequest=self._messages.RegionSetLabelsRequest(
|
|
labelFingerprint=disk.labelFingerprint, labels=labels))
|
|
|
|
def GetDiskRegionName(self):
|
|
return self._disk_ref.region
|
|
|
|
def MakeAddResourcePoliciesRequest(self, resource_policies,
|
|
client_to_make_request):
|
|
add_request = self._messages.ComputeRegionDisksAddResourcePoliciesRequest(
|
|
disk=self._disk_ref.Name(),
|
|
project=self._disk_ref.project,
|
|
region=self._disk_ref.region,
|
|
regionDisksAddResourcePoliciesRequest=self._messages
|
|
.RegionDisksAddResourcePoliciesRequest(
|
|
resourcePolicies=resource_policies))
|
|
return client_to_make_request.MakeRequests(
|
|
[(self._client.regionDisks, 'AddResourcePolicies', add_request)])
|
|
|
|
def MakeRemoveResourcePoliciesRequest(self, resource_policies,
|
|
client_to_make_request):
|
|
remove_request = self._messages.ComputeRegionDisksRemoveResourcePoliciesRequest( # pylint:disable=line-too-long
|
|
disk=self._disk_ref.Name(),
|
|
project=self._disk_ref.project,
|
|
region=self._disk_ref.region,
|
|
regionDisksRemoveResourcePoliciesRequest=self._messages
|
|
.RegionDisksRemoveResourcePoliciesRequest(
|
|
resourcePolicies=resource_policies))
|
|
return client_to_make_request.MakeRequests(
|
|
[(self._client.regionDisks, 'RemoveResourcePolicies', remove_request)])
|
|
|
|
|
|
def IsZonal(disk_ref):
|
|
"""Checks if a compute disk is zonal or regional.
|
|
|
|
Args:
|
|
disk_ref: the disk resource reference that is parsed from resource arguments
|
|
to modify.
|
|
|
|
Returns:
|
|
Boolean, true when the compute disk resource to modify is a zonal compute
|
|
disk resource, false when a regional compute disk resource.
|
|
|
|
Raises:
|
|
UnknownDiskResourceError: when the compute disk resource is not in the
|
|
correct format.
|
|
"""
|
|
# There are 2 types of disk services, DisksService (by zone) and
|
|
# RegionDisksService (by region).
|
|
if disk_ref.Collection() == 'compute.disks':
|
|
return True
|
|
elif disk_ref.Collection() == 'compute.regionDisks':
|
|
return False
|
|
else:
|
|
raise UnknownDiskResourceError(
|
|
'Unexpected disk resource argument of {}'.format(disk_ref.Collection()))
|
|
|
|
|
|
def GetDiskInfo(disk_ref, client, messages):
|
|
"""Gets the zonal or regional disk api info.
|
|
|
|
Args:
|
|
disk_ref: the disk resource reference that is parsed from resource
|
|
arguments.
|
|
client: the compute api_tools_client.
|
|
messages: the compute message module.
|
|
|
|
Returns:
|
|
_ZonalDisk or _RegionalDisk.
|
|
"""
|
|
if IsZonal(disk_ref):
|
|
return _ZonalDisk(client, disk_ref, messages)
|
|
else:
|
|
return _RegionalDisk(client, disk_ref, messages)
|
|
|
|
|
|
def IsProvisioningTypeIops(disk_type):
|
|
"""Check if the given disk type (name or URI) supports IOPS provisioning.
|
|
|
|
Args:
|
|
disk_type: name of URI of the disk type to be checked.
|
|
|
|
Returns:
|
|
Whether the disk_type supports IOPS provisioning.
|
|
"""
|
|
disk_type_name = disk_type.split('/')[-1]
|
|
return disk_type_name in _SUPPORTED_DISK_TYPES_IOPS
|
|
|
|
|
|
def IsProvisioningTypeThroughput(disk_type):
|
|
"""Check if the given disk type (name or URI) supports throughput provisioning.
|
|
|
|
Args:
|
|
disk_type: name of URI of the disk type to be checked.
|
|
|
|
Returns:
|
|
Boolean, true if the disk_type supports throughput provisioning, false
|
|
otherwise.
|
|
"""
|
|
disk_type_name = disk_type.split('/')[-1]
|
|
return disk_type_name in _SUPPORTED_DISK_TYPES_THROUGHPUT
|
|
|
|
|
|
def GetDiskTypeUri(
|
|
disk_type: str, disk_ref: Any, compute_holder: Any
|
|
):
|
|
"""Get the disk type URI for a given disk type name and disk reference.
|
|
|
|
Args:
|
|
disk_type: name of the disk type.
|
|
disk_ref: the disk resource reference that is parsed from resource
|
|
arguments.
|
|
compute_holder: the compute api_tools_client.
|
|
|
|
Returns:
|
|
The disk type URI.
|
|
"""
|
|
type_ref = None
|
|
if disk_type:
|
|
if disk_ref.Collection() == 'compute.disks':
|
|
type_ref = compute_holder.resources.Parse(
|
|
disk_type,
|
|
collection='compute.diskTypes',
|
|
params={
|
|
'project': disk_ref.project,
|
|
'zone': disk_ref.zone
|
|
})
|
|
elif disk_ref.Collection() == 'compute.regionDisks':
|
|
type_ref = compute_holder.resources.Parse(
|
|
disk_type,
|
|
collection='compute.regionDiskTypes',
|
|
params={
|
|
'project': disk_ref.project,
|
|
'region': disk_ref.region
|
|
})
|
|
if type_ref:
|
|
return type_ref.SelfLink()
|
|
return None
|