1# Licensed under the Apache License, Version 2.0 (the "License"); you may 2# not use this file except in compliance with the License. You may obtain 3# a copy of the License at 4# 5# http://www.apache.org/licenses/LICENSE-2.0 6# 7# Unless required by applicable law or agreed to in writing, software 8# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 9# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10# License for the specific language governing permissions and limitations 11# under the License. 12 13from openstack import format 14from openstack import resource 15from openstack import utils 16 17 18class Volume(resource.Resource): 19 resource_key = "volume" 20 resources_key = "volumes" 21 base_path = "/volumes" 22 23 _query_mapping = resource.QueryParameters( 24 'name', 'status', 'project_id', all_projects='all_tenants') 25 26 # capabilities 27 allow_fetch = True 28 allow_create = True 29 allow_delete = True 30 allow_commit = True 31 allow_list = True 32 33 # Properties 34 #: A ID representing this volume. 35 id = resource.Body("id") 36 #: The name of this volume. 37 name = resource.Body("name") 38 #: A list of links associated with this volume. *Type: list* 39 links = resource.Body("links", type=list) 40 41 #: The availability zone. 42 availability_zone = resource.Body("availability_zone") 43 #: To create a volume from an existing volume, specify the ID of 44 #: the existing volume. If specified, the volume is created with 45 #: same size of the source volume. 46 source_volume_id = resource.Body("source_volid") 47 #: The volume description. 48 description = resource.Body("description") 49 #: To create a volume from an existing snapshot, specify the ID of 50 #: the existing volume snapshot. If specified, the volume is created 51 #: in same availability zone and with same size of the snapshot. 52 snapshot_id = resource.Body("snapshot_id") 53 #: The size of the volume, in GBs. *Type: int* 54 size = resource.Body("size", type=int) 55 #: The ID of the image from which you want to create the volume. 56 #: Required to create a bootable volume. 57 image_id = resource.Body("imageRef") 58 #: The name of the associated volume type. 59 volume_type = resource.Body("volume_type") 60 #: Enables or disables the bootable attribute. You can boot an 61 #: instance from a bootable volume. *Type: bool* 62 is_bootable = resource.Body("bootable", type=format.BoolStr) 63 #: One or more metadata key and value pairs to associate with the volume. 64 metadata = resource.Body("metadata") 65 #: One or more metadata key and value pairs about image 66 volume_image_metadata = resource.Body("volume_image_metadata") 67 68 #: One of the following values: creating, available, attaching, in-use 69 #: deleting, error, error_deleting, backing-up, restoring-backup, 70 #: error_restoring. For details on these statuses, see the 71 #: Block Storage API documentation. 72 status = resource.Body("status") 73 #: TODO(briancurtin): This is currently undocumented in the API. 74 attachments = resource.Body("attachments") 75 #: The timestamp of this volume creation. 76 created_at = resource.Body("created_at") 77 78 #: The volume's current back-end. 79 host = resource.Body("os-vol-host-attr:host") 80 #: The project ID associated with current back-end. 81 project_id = resource.Body("os-vol-tenant-attr:tenant_id") 82 #: The user ID associated with the volume 83 user_id = resource.Body("user_id") 84 #: The status of this volume's migration (None means that a migration 85 #: is not currently in progress). 86 migration_status = resource.Body("os-vol-mig-status-attr:migstat") 87 #: The volume ID that this volume's name on the back-end is based on. 88 migration_id = resource.Body("os-vol-mig-status-attr:name_id") 89 #: Status of replication on this volume. 90 replication_status = resource.Body("replication_status") 91 #: Extended replication status on this volume. 92 extended_replication_status = resource.Body( 93 "os-volume-replication:extended_status") 94 #: ID of the consistency group. 95 consistency_group_id = resource.Body("consistencygroup_id") 96 #: Data set by the replication driver 97 replication_driver_data = resource.Body( 98 "os-volume-replication:driver_data") 99 #: ``True`` if this volume is encrypted, ``False`` if not. 100 #: *Type: bool* 101 is_encrypted = resource.Body("encrypted", type=format.BoolStr) 102 103 def _action(self, session, body): 104 """Preform volume actions given the message body.""" 105 # NOTE: This is using Volume.base_path instead of self.base_path 106 # as both Volume and VolumeDetail instances can be acted on, but 107 # the URL used is sans any additional /detail/ part. 108 url = utils.urljoin(Volume.base_path, self.id, 'action') 109 headers = {'Accept': ''} 110 return session.post(url, json=body, headers=headers) 111 112 def extend(self, session, size): 113 """Extend a volume size.""" 114 body = {'os-extend': {'new_size': size}} 115 self._action(session, body) 116 117 def set_readonly(self, session, readonly): 118 """Set volume readonly flag""" 119 body = {'os-update_readonly_flag': {'readonly': readonly}} 120 self._action(session, body) 121 122 def retype(self, session, new_type, migration_policy): 123 """Retype volume considering the migration policy""" 124 body = { 125 'os-retype': { 126 'new_type': new_type, 127 'migration_policy': migration_policy 128 } 129 } 130 self._action(session, body) 131 132 133VolumeDetail = Volume 134