class Domain(resource.Resource): resource_key = 'domain' resources_key = 'domains' base_path = '/domains' service = identity_service.IdentityService() # capabilities allow_create = True allow_retrieve = True allow_update = True allow_delete = True allow_list = True patch_update = True # Properties #: The description of this domain. *Type: string* description = resource.prop('description') #: Setting this attribute to ``False`` prevents users from authorizing #: against this domain or any projects owned by this domain, and prevents #: users owned by this domain from authenticating or receiving any other #: authorization. Additionally, all pre-existing tokens applicable #: to the above entities are immediately invalidated. #: Re-enabling a domain does not re-enable pre-existing tokens. #: *Type: bool* is_enabled = resource.prop('enabled', type=bool) #: The globally unique name of this domain. *Type: string* name = resource.prop('name')
class Service(resource.Resource): resource_key = 'service' resources_key = 'services' base_path = '/services' service = identity_service.IdentityService() # capabilities allow_create = True allow_retrieve = True allow_update = True allow_delete = True allow_list = True patch_update = True # Properties #: User-facing description of the service. *Type: string* description = resource.prop('description') #: Setting this value to ``False`` prevents the service and #: its endpoints from appearing in the service catalog. *Type: bool* is_enabled = resource.prop('enabled', type=bool) #: User-facing name of the service. *Type: string* name = resource.prop('name') #: Describes the API implemented by the service. The following values are #: recognized within the OpenStack ecosystem: ``compute``, ``image``, #: ``ec2``, ``identity``, ``volume``, ``network``. To support non-core and #: future projects, the value should not be validated against this list. #: *Type: string* type = resource.prop('type')
class Project(resource.Resource): resource_key = 'project' resources_key = 'projects' base_path = '/projects' service = identity_service.IdentityService() # capabilities allow_create = True allow_retrieve = True allow_update = True allow_delete = True allow_list = True patch_update = True # Properties #: The description of the project. *Type: string* description = resource.prop('description') #: References the domain ID which owns the project; if a domain ID is not #: specified by the client, the Identity service implementation will #: default it to the domain ID to which the client's token is scoped. #: *Type: string* domain_id = resource.prop('domain_id') #: Setting this attribute to ``False`` prevents users from authorizing #: against this project. Additionally, all pre-existing tokens authorized #: for the project are immediately invalidated. Re-enabling a project #: does not re-enable pre-existing tokens. *Type: bool* is_enabled = resource.prop('enabled', type=bool) #: Unique project name, within the owning domain. *Type: string* name = resource.prop('name')
class VolumeDetail(Volume): base_path = "/volumes/detail" #: The volume's current back-end. host = resource.prop("os-vol-host-attr:host") #: The project ID associated with current back-end. project_id = resource.prop("os-vol-tenant-attr:tenant_id") #: The status of this volume's migration (None means that a migration #: is not currently in progress). migration_status = resource.prop("os-vol-mig-status-attr:migstat") #: The volume ID that this volume's name on the back-end is based on. migration_id = resource.prop("os-vol-mig-status-attr:name_id") #: Status of replication on this volume. replication_status = resource.prop("replication_status") #: Extended replication status on this volume. extended_replication_status = resource.prop( "os-volume-replication:extended_status") #: ID of the consistency group. consistency_group_id = resource.prop("consistencygroup_id") #: Data set by the replication driver replication_driver_data = resource.prop( "os-volume-replication:driver_data") #: ``True`` if this volume is encrypted, ``False`` if not. #: *Type: bool* is_encrypted = resource.prop("encrypted", type=format.BoolStr)
class Version(resource.Resource): resource_key = 'version' resources_key = 'versions' base_path = '/' service = network_service.NetworkService( version=network_service.NetworkService.UNVERSIONED) # capabilities allow_list = True # Properties links = resource.prop('links') status = resource.prop('status')
class Version(resource.Resource): resource_key = 'version' resources_key = 'versions' base_path = '/' service = compute_service.ComputeService( version=compute_service.ComputeService.UNVERSIONED) # capabilities allow_list = True # Properties links = resource.prop('links') status = resource.prop('status') updated = resource.prop('updated')
class AlarmChange(resource.Resource): """.. caution:: This API is a work in progress and is subject to change.""" id_attribute = 'event_id' resource_key = 'alarm_change' base_path = '/alarms/%(alarm_id)s/history' service = telemetry_service.TelemetryService() # Supported Operations allow_list = True # Properties #: The ID of the alarm alarm_id = resource.prop('alarm_id') #: Data describing the change detail = resource.prop('detail') #: The ID of the change event event_id = resource.prop('event_id') #: The project ID on behalf of which the change is being made on_behalf_of_id = resource.prop('on_behalf_of') #: The project ID of the initiating identity project_id = resource.prop('project_id') #: The time/date of the alarm change. triggered_at = resource.prop('timestamp') #: The type of change type = resource.prop('type') #: The user ID of the initiating identity user_id = resource.prop('user_id') @classmethod def list(cls, session, limit=None, marker=None, path_args=None, paginated=False, **params): url = cls._get_url(path_args) resp = session.get(url, endpoint_filter=cls.service, params=params) for item in resp.json(): yield cls.existing(**item)
class Resource(resource.Resource): """.. caution:: This API is a work in progress and is subject to change.""" id_attribute = 'resource_id' base_path = '/resources' service = telemetry_service.TelemetryService() # Supported Operations allow_retrieve = True allow_list = True # Properties #: UTC date & time not later than the first sample known #: for this resource. first_sample_at = resource.prop('first_sample_timestamp') #: UTC date & time not earlier than the last sample known #: for this resource. last_sample_at = resource.prop('last_sample_timestamp') #: A list containing a self link and associated meter links links = resource.prop('links') #: Arbitrary metadata associated with the resource metadata = resource.prop('metadata') #: The ID of the owning project project_id = resource.prop('project_id') #: The ID for the resource resource_id = resource.prop('resource_id') #: The name of the source where the resource comes from source = resource.prop('source') #: The ID of the user who created the resource or updated it last user_id = resource.prop('user_id')
class Limit(resource.Resource): resource_key = "limits" resources_key = "limits" base_path = "/limits" service = block_store_service.BlockStoreService() # capabilities allow_retrieve = True # Properties #: A rate representing this Limit. rate = resource.prop("rate") #: A list of absolute props of the Limit. absolute = resource.prop("absolute")
class Meter(resource.Resource): """.. caution:: This API is a work in progress and is subject to change.""" id_attribute = 'meter_id' resource_key = 'meter' base_path = '/meters' service = telemetry_service.TelemetryService() # Supported Operations allow_list = True # Properties #: The ID of the meter meter_id = resource.prop('meter_id') #: The unique name for the meter name = resource.prop('name') #: The ID of the project that owns the resource project_id = resource.prop('project_id') #: The ID of the resource for which the measurements are taken resource_id = resource.prop('resource_id') #: The name of the source where the meter comes from source = resource.prop('source') #: The meter type type = resource.prop('type') #: The unit of measure unit = resource.prop('unit') #: The ID of the user who last triggered an update to the resource user_id = resource.prop('user_id')
class Capability(resource.Resource): """.. caution:: This API is a work in progress and is subject to change.""" resource_key = 'capability' resources_key = 'capabilities' base_path = '/capabilities' service = telemetry_service.TelemetryService() # Supported Operations allow_list = True # Properties is_enabled = resource.prop('enabled', type=bool) @classmethod def list(cls, session, limit=None, marker=None, path_args=None, paginated=False, **params): resp = session.get(cls.base_path, endpoint_filter=cls.service, params=params) resp = resp.json() for key, value in six.iteritems(resp['api']): yield cls.existing(id=key, enabled=value)
class Type(resource.Resource): resource_key = "volume_type" resources_key = "volume_types" base_path = "/types" service = block_store_service.BlockStoreService() # capabilities allow_list = True # Properties #: A ID representing this type. id = resource.prop("id") #: Name of the type. name = resource.prop("name") #: A dict of extra specifications. "capabilities" is a usual key. extra_specs = resource.prop("extra_specs", type=dict)
class AvailabilityZone(resource.Resource): resources_key = 'availabilityZoneInfo' base_path = '/os-availability-zone' service = block_store_service.BlockStoreService() # capabilities allow_list = True id_attribute = "name" # Properties #: name of availability zone name = resource.prop('zoneName') #: state of availability zone state = resource.prop('zoneState') #: hosts of availability zone hosts = resource.prop('hosts')
class Quota(resource.Resource): resource_key = "quota_set" resources_key = "quota_sets" base_path = '/os-quota-sets' service = block_store_service.BlockStoreService() # capabilities allow_retrieve = True id = resource.prop("id")
class Region(resource.Resource): resource_key = 'region' resources_key = 'regions' base_path = '/regions' service = identity_service.IdentityService() # capabilities allow_create = True allow_retrieve = True allow_update = True allow_delete = True allow_list = True patch_update = True # Properties #: User-facing description of the region. *Type: string* description = resource.prop('description') #: ID of parent region, if any. *Type: string* parent_region_id = resource.prop('parent_region_id')
class Policy(resource.Resource): resource_key = 'policy' resources_key = 'policies' base_path = '/policies' service = identity_service.IdentityService() # capabilities allow_create = True allow_retrieve = True allow_update = True allow_delete = True allow_list = True patch_update = True # Properties #: The policy rule set itself, as a serialized blob. *Type: string* blob = resource.prop('blob') #: The MIME Media Type of the serialized policy blob. *Type: string* type = resource.prop('type')
class DefaultQuota(resource.Resource): resource_key = "quota_set" resources_key = "quota_sets" base_path = '/os-quota-sets/%(tenant_id)s/defaults' service = block_store_service.BlockStoreService() allow_retrieve = True id = resource.prop("id")
class Role(resource.Resource): resource_key = 'role' resources_key = 'roles' base_path = '/OS-KSADM/roles' service = identity_service.IdentityService() # capabilities allow_create = True allow_retrieve = True allow_update = True allow_delete = True allow_list = True # Properties #: The description of the role. *Type: string* description = resource.prop('description') #: Setting this attribute to ``False`` prevents this role from being #: available in the role list. *Type: bool* is_enabled = resource.prop('enabled', type=format.BoolStr) #: Unique role name. *Type: string* name = resource.prop('name')
class Version(resource.Resource): resource_key = 'version' resources_key = 'versions' base_path = '/' service = identity_service.IdentityService( version=identity_service.IdentityService.UNVERSIONED) # capabilities allow_list = True # Properties media_types = resource.prop('media-types') status = resource.prop('status') updated = resource.prop('updated') @classmethod def list(cls, session, **params): resp = session.get(cls.base_path, endpoint_filter=cls.service, params=params) resp = resp.json() for data in resp[cls.resources_key]['values']: yield cls.existing(**data)
class Tenant(resource.Resource): resource_key = 'tenant' resources_key = 'tenants' base_path = '/tenants' service = identity_service.AdminService() # capabilities allow_create = True allow_retrieve = True allow_update = True allow_delete = True allow_list = True # Properties #: The description of the tenant. *Type: string* description = resource.prop('description') #: Setting this attribute to ``False`` prevents users from authorizing #: against this tenant. Additionally, all pre-existing tokens authorized #: for the tenant are immediately invalidated. Re-enabling a tenant #: does not re-enable pre-existing tokens. *Type: bool* is_enabled = resource.prop('enabled', type=bool) #: Unique tenant name. *Type: string* name = resource.prop('name')
class User(resource.Resource): resource_key = 'user' resources_key = 'users' base_path = '/users' service = identity_service.AdminService() # capabilities allow_create = True allow_retrieve = True allow_update = True allow_delete = True allow_list = True # Properties #: The email of this user. *Type: string* email = resource.prop('email') #: Setting this value to ``False`` prevents the user from authenticating or #: receiving authorization. Additionally, all pre-existing tokens held by #: the user are immediately invalidated. Re-enabling a user does not #: re-enable pre-existing tokens. *Type: bool* is_enabled = resource.prop('enabled', type=bool) #: The name of this user. *Type: string* name = resource.prop('name')
class Group(resource.Resource): resource_key = 'group' resources_key = 'groups' base_path = '/groups' service = identity_service.IdentityService() # capabilities allow_create = True allow_retrieve = True allow_update = True allow_delete = True allow_list = True patch_update = True # Properties #: The description of this group. *Type: string* description = resource.prop('description') #: References the domain ID which owns the group; if a domain ID is not #: specified by the client, the Identity service implementation will #: default it to the domain ID to which the client's token is scoped. #: *Type: string* domain_id = resource.prop('domain_id') #: Unique group name, within the owning domain. *Type: string* name = resource.prop('name')
class Trust(resource.Resource): resource_key = 'trust' resources_key = 'trusts' base_path = '/OS-TRUST/trusts' service = identity_service.IdentityService() # capabilities allow_create = True allow_delete = True allow_list = True allow_retrieve = True # Properties #: ID of the project upon which the trustor is #: delegating authorization. *Type: string* project_id = resource.prop('project_id') #: Specifies the expiration time of the trust. A trust may be revoked #: ahead of expiration. If the value represents a time in the past, #: the trust is deactivated. expires_at = resource.prop('expires_at') #: ID of the trust object. *Type: string* id = resource.prop('id') #: If ``impersonation`` is set to true, then the ``user`` attribute #: of tokens that are generated based on the trust will represent #: that of the trustor rather than the trustee, thus allowing the trustee #: to impersonate the trustor. #: If ``impersonation`` is set to ``False``, then the token's ``user`` #: attribute will represent that of the trustee. *Type: bool* is_impersonation = resource.prop('impersonation', type=bool) #: Represents the user ID who is capable of consuming the trust. #: *Type: string* trustee_user_id = resource.prop('trustee_user_id') #: Represents the user ID who created the trust, and who's authorization is #: being delegated. *Type: string* trustor_user_id = resource.prop('trustor_user_id') #: Specifies the subset of the trustor's roles on the ``project_id`` #: to be granted to the trustee when the token in consumed. The #: trustor must already be granted these roles in the project referenced #: by the ``project_id`` attribute. *Type: list* roles = resource.prop('roles') #: Redelegation count redelegation_count = resource.prop('redelegation_count')
class User(resource.Resource): resource_key = 'user' resources_key = 'users' base_path = '/users' service = identity_service.IdentityService() # capabilities allow_create = True allow_retrieve = True allow_update = True allow_delete = True allow_list = True patch_update = True # Properties #: References the user's default project ID against which to authorize, #: if the API user does not explicitly specify one when creating a token. #: Setting this attribute does not grant any actual authorization on the #: project, and is merely provided for the user's convenience. #: Therefore, the referenced project does not need to exist within the #: user's domain. #: #: *New in version 3.1* If the user does not have authorization to #: their default project, the default project will be ignored at token #: creation. *Type: string* default_project_id = resource.prop('default_project_id') #: The description of this user. *Type: string* description = resource.prop('description') #: References the domain ID which owns the user; if a domain ID is not #: specified by the client, the Identity service implementation will #: default it to the domain ID to which the client's token is scoped. #: *Type: string* domain_id = resource.prop('domain_id') #: The email of this user. *Type: string* email = resource.prop('email') #: Setting this value to ``False`` prevents the user from authenticating or #: receiving authorization. Additionally, all pre-existing tokens held by #: the user are immediately invalidated. Re-enabling a user does not #: re-enable pre-existing tokens. *Type: bool* is_enabled = resource.prop('enabled', type=bool) #: Unique user name, within the owning domain. *Type: string* name = resource.prop('name') #: The default form of credential used during authentication. #: *Type: string* password = resource.prop('password')
class Extension(resource.Resource): resource_key = "extension" resources_key = "extensions" base_path = "/extensions" service = block_store_service.BlockStoreService() # capabilities allow_list = True # Properties #: A updated representing this Extension. updated = resource.prop("updated") #: Name of the extension. name = resource.prop("name") #: A list of links. links = resource.prop("links", type=list) #: Namespace of the extension. namespace = resource.prop("namespace") #: Alias of the extension. alias = resource.prop("alias") #: Description of the extension. description = resource.prop("description")
class Extension(resource.Resource): resource_key = 'extension' resources_key = 'extensions' base_path = '/extensions' service = identity_service.IdentityService() # capabilities allow_list = True # Properties #: A unique identifier, which will be used for accessing the extension #: through a dedicated url ``/extensions/*alias*``. The extension #: alias uniquely identifies an extension and is prefixed by a vendor #: identifier. *Type: string* alias = resource.prop('alias') #: A description of the extension. *Type: string* description = resource.prop('description') #: Links to the documentation in various format. *Type: string* links = resource.prop('links') #: The name of the extension. *Type: string* name = resource.prop('name') #: The second unique identifier of the extension after the alias. #: It is usually a URL which will be used. Example: #: "http://docs.ecl.org/identity/api/ext/s3tokens/v1.0" #: *Type: string* namespace = resource.prop('namespace') #: The last time the extension has been modified (update date). updated_at = resource.prop('updated') @classmethod def list(cls, session, **params): resp = session.get(cls.base_path, endpoint_filter=cls.service, params=params) resp = resp.json() for data in resp[cls.resources_key]['values']: yield cls.existing(**data)
class Statistics(resource.Resource): """.. caution:: This API is a work in progress and is subject to change.""" id_attribute = 'meter_name' resource_key = 'statistics' base_path = '/meters/%(meter_name)s/statistics' service = telemetry_service.TelemetryService() # Supported Operations allow_list = True # Path Parameter meter_name = resource.prop('meter_name') # Properties #: The selectable aggregate value(s) aggregate = resource.prop('aggregate') #: The average of all of the volume values seen in the data avg = resource.prop('avg') #: The number of samples seen count = resource.prop('count') #: The difference, in seconds, between the oldest and newest timestamp duration = resource.prop('duration') #: UTC date and time of the oldest timestamp, or the query end time. duration_end_at = resource.prop('duration_end') #: UTC date and time of the earliest timestamp, or the query start time. duration_start_at = resource.prop('duration_start') #: Dictionary of field names for group, if groupby statistics are requested group_by = resource.prop('groupby') #: The maximum volume seen in the data max = resource.prop('max') #: The minimum volume seen in the data min = resource.prop('min') #: The difference, in seconds, between the period start and end period = resource.prop('period') #: UTC date and time of the period end. period_end_at = resource.prop('period_end') #: UTC date and time of the period start. period_start_at = resource.prop('period_start') #: The total of all of the volume values seen in the data sum = resource.prop('sum') #: The unit type of the data set unit = resource.prop('unit') @classmethod def list(cls, session, limit=None, marker=None, path_args=None, paginated=False, **params): url = cls._get_url(path_args) resp = session.get(url, endpoint_filter=cls.service, params=params) for stat in resp.json(): yield cls.existing(**stat)
class Alarm(resource.Resource): """.. caution:: This API is a work in progress and is subject to change.""" id_attribute = 'alarm_id' base_path = '/alarms' service = telemetry_service.TelemetryService() # Supported Operations allow_create = True allow_retrieve = True allow_update = True allow_delete = True allow_list = True # Properties #: The actions to do when alarm state changes to alarm alarm_actions = resource.prop('alarm_actions') #: The ID of the alarm alarm_id = resource.prop('alarm_id') # TODO(briancurtin): undocumented combination_rule = resource.prop('combination_rule') #: The description of the alarm description = resource.prop('description') #: ``True`` if this alarm is enabled. *Type: bool* is_enabled = resource.prop('enabled', type=bool) #: The actions to do when alarm state changes to insufficient data insufficient_data_actions = resource.prop('insufficient_data_actions') #: The actions should be re-triggered on each evaluation cycle. #: *Type: bool* is_repeat_actions = resource.prop('repeat_actions', type=bool) #: The name for the alarm name = resource.prop('name') #: The actions to do when alarm state change to ok ok_actions = resource.prop('ok_actions') #: The ID of the project that owns the alarm project_id = resource.prop('project_id') #: The severity of the alarm severity = resource.prop('severity') #: The state off the alarm state = resource.prop('state') #: The timestamp of the last alarm state change. state_changed_at = resource.prop('state_timestamp') # TODO(briancurtin): undocumented threshold_rule = resource.prop('threshold_rule', type=dict) #: Describe time constraints for the alarm time_constraints = resource.prop('time_constraints') #: Explicit type specifier to select which rule to follow type = resource.prop('type') #: The timestamp of the last alarm definition update. updated_at = resource.prop('timestamp') #: The ID of the user who created the alarm user_id = resource.prop('user_id') def change_state(self, session, next_state): """Set the state of an alarm. The next_state may be one of: 'ok' 'insufficient data' 'alarm' """ url = utils.urljoin(self.base_path, self.id, 'state') resp = session.put(url, endpoint_filter=self.service, json=next_state) return resp.json() def check_state(self, session): """Retrieve the current state of an alarm from the service. The properties of the alarm are not modified. """ url = utils.urljoin(self.base_path, self.id, 'state') resp = session.get(url, endpoint_filter=self.service) resp = resp.json() current_state = resp.replace('\"', '') return current_state
class Sample(resource.Resource): """.. caution:: This API is a work in progress and is subject to change.""" id_attribute = 'sample_id' base_path = '/meters/%(counter_name)s' service = telemetry_service.TelemetryService() # Supported Operations allow_create = True allow_list = True # Properties #: The meter name this sample is for counter_name = resource.prop('meter', alias='counter_name') #: When the sample has been generated. generated_at = resource.prop('timestamp') #: Arbitrary metadata associated with the sample metadata = resource.prop('metadata', alias='resource_metadata') #: The ID of the project this sample was taken for project_id = resource.prop('project_id') #: When the sample has been recorded. recorded_at = resource.prop('recorded_at') #: The ID of the resource this sample was taken for resource_id = resource.prop('resource_id') #: The name of the source that identifies where the sample comes from source = resource.prop('source') #: The meter type type = resource.prop('type', alias='counter_type') #: The unit of measure unit = resource.prop('unit', alias='counter_unit') #: The ID of the user this sample was taken for user_id = resource.prop('user_id') #: The metered value volume = resource.prop('volume', alias='counter_volume') @classmethod def list(cls, session, limit=None, marker=None, path_args=None, paginated=False, **params): url = cls._get_url(path_args) resp = session.get(url, endpoint_filter=cls.service, params=params) for item in resp.json(): yield cls.existing(**item) def create(self, session): url = self._get_url(self) # telemetry expects a list of samples attrs = self._attrs.copy() attrs.pop('meter', None) resp = session.post(url, endpoint_filter=self.service, json=[attrs]) resp = resp.json() self.update_attrs(**resp.pop()) self._reset_dirty() return self
class Object(_base.BaseResource): _custom_metadata_prefix = "X-Object-Meta-" _system_metadata = { "content_disposition": "content-disposition", "content_encoding": "content-encoding", "content_type": "content-type", "delete_after": "x-delete-after", "delete_at": "x-delete-at", "is_content_type_detected": "x-detect-content-type", } base_path = "/%(container)s" service = object_store_service.ObjectStoreService() id_attribute = "name" allow_create = True allow_retrieve = True allow_update = True allow_delete = True allow_list = True allow_head = True # Data to be passed during a POST call to create an object on the server. data = None # URL parameters #: The unique name for the container. container = resource.prop("container") #: The unique name for the object. name = resource.prop("name") # Object details hash = resource.prop("hash") bytes = resource.prop("bytes") # Headers for HEAD and GET requests #: If set to True, Object Storage queries all replicas to return #: the most recent one. If you omit this header, Object Storage #: responds faster after it finds one valid replica. Because #: setting this header to True is more expensive for the back end, #: use it only when it is absolutely needed. *Type: bool* is_newest = resource.header("x-newest", type=bool) #: TODO(briancurtin) there's a lot of content here... range = resource.header("range", type=dict) #: See http://www.ietf.org/rfc/rfc2616.txt. if_match = resource.header("if-match", type=dict) #: In combination with Expect: 100-Continue, specify an #: "If-None-Match: \*" header to query whether the server already #: has a copy of the object before any data is sent. if_none_match = resource.header("if-none-match", type=dict) #: See http://www.ietf.org/rfc/rfc2616.txt. if_modified_since = resource.header("if-modified-since", type=dict) #: See http://www.ietf.org/rfc/rfc2616.txt. if_unmodified_since = resource.header("if-unmodified-since", type=dict) # Query parameters #: Used with temporary URLs to sign the request. For more #: information about temporary URLs, see OpenStack Object Storage #: API v1 Reference. signature = resource.header("signature") #: Used with temporary URLs to specify the expiry time of the #: signature. For more information about temporary URLs, see #: OpenStack Object Storage API v1 Reference. expires_at = resource.header("expires") #: If you include the multipart-manifest=get query parameter and #: the object is a large object, the object contents are not #: returned. Instead, the manifest is returned in the #: X-Object-Manifest response header for dynamic large objects #: or in the response body for static large objects. multipart_manifest = resource.header("multipart-manifest") # Response headers from HEAD and GET #: HEAD operations do not return content. However, in this #: operation the value in the Content-Length header is not the #: size of the response body. Instead it contains the size of #: the object, in bytes. content_length = resource.header("content-length") #: The MIME type of the object. content_type = resource.header("content-type") #: The type of ranges that the object accepts. accept_ranges = resource.header("accept-ranges") #: For objects smaller than 5 GB, this value is the MD5 checksum #: of the object content. The value is not quoted. #: For manifest objects, this value is the MD5 checksum of the #: concatenated string of MD5 checksums and ETags for each of #: the segments in the manifest, and not the MD5 checksum of #: the content that was downloaded. Also the value is enclosed #: in double-quote characters. #: You are strongly recommended to compute the MD5 checksum of #: the response body as it is received and compare this value #: with the one in the ETag header. If they differ, the content #: was corrupted, so retry the operation. etag = resource.header("etag") #: Set to True if this object is a static large object manifest object. #: *Type: bool* is_static_large_object = resource.header("x-static-large-object", type=bool) #: If set, the value of the Content-Encoding metadata. #: If not set, this header is not returned by this operation. content_encoding = resource.header("content-encoding") #: If set, specifies the override behavior for the browser. #: For example, this header might specify that the browser use #: a download program to save this file rather than show the file, #: which is the default. #: If not set, this header is not returned by this operation. content_disposition = resource.header("content-disposition") #: Specifies the number of seconds after which the object is #: removed. Internally, the Object Storage system stores this #: value in the X-Delete-At metadata item. delete_after = resource.header("x-delete-after") #: If set, the time when the object will be deleted by the system #: in the format of a UNIX Epoch timestamp. #: If not set, this header is not returned by this operation. delete_at = resource.header("x-delete-at") #: If set, to this is a dynamic large object manifest object. #: The value is the container and object name prefix of the #: segment objects in the form container/prefix. object_manifest = resource.header("x-object-manifest") #: The timestamp of the transaction. timestamp = resource.header("x-timestamp") #: The date and time that the object was created or the last #: time that the metadata was changed. last_modified_at = resource.header("last_modified", alias="last-modified") # Headers for PUT and POST requests #: Set to chunked to enable chunked transfer encoding. If used, #: do not set the Content-Length header to a non-zero value. transfer_encoding = resource.header("transfer-encoding") #: If set to true, Object Storage guesses the content type based #: on the file extension and ignores the value sent in the #: Content-Type header, if present. *Type: bool* is_content_type_detected = resource.header("x-detect-content-type", type=bool) #: If set, this is the name of an object used to create the new #: object by copying the X-Copy-From object. The value is in form #: {container}/{object}. You must UTF-8-encode and then URL-encode #: the names of the container and object before you include them #: in the header. #: Using PUT with X-Copy-From has the same effect as using the #: COPY operation to copy an object. copy_from = resource.header("x-copy-from") # The Object Store treats the metadata for its resources inconsistently so # Object.set_metadata must override the BaseResource.set_metadata to # account for it. def set_metadata(self, session, metadata): # Filter out items with empty values so the create metadata behaviour # is the same as account and container filtered_metadata = \ {key: value for key, value in metadata.iteritems() if value} # Get a copy of the original metadata so it doesn't get erased on POST # and update it with the new metadata values. obj = self.head(session) metadata2 = copy.deepcopy(obj.metadata) metadata2.update(filtered_metadata) # Include any original system metadata so it doesn't get erased on POST for key in self._system_metadata: value = getattr(obj, key) if value and key not in metadata2: metadata2[key] = value super(Object, self).set_metadata(session, metadata2) # The Object Store treats the metadata for its resources inconsistently so # Object.delete_metadata must override the BaseResource.delete_metadata to # account for it. def delete_metadata(self, session, keys): # Get a copy of the original metadata so it doesn't get erased on POST # and update it with the new metadata values. obj = self.head(session) metadata = copy.deepcopy(obj.metadata) # Include any original system metadata so it doesn't get erased on POST for key in self._system_metadata: value = getattr(obj, key) if value: metadata[key] = value # Remove the metadata for key in keys: if key == 'delete_after': del (metadata['delete_at']) else: del (metadata[key]) url = self._get_url(self, self.id) session.post(url, endpoint_filter=self.service, headers=self._calculate_headers(metadata)) def get(self, session, include_headers=False, args=None): url = self._get_url(self, self.id) headers = {'Accept': 'bytes'} resp = session.get(url, endpoint_filter=self.service, headers=headers) resp = resp.content self._set_metadata() return resp def create(self, session): url = self._get_url(self, self.id) headers = self.get_headers() headers['Accept'] = '' if self.data is not None: resp = session.put(url, endpoint_filter=self.service, data=self.data, headers=headers).headers else: resp = session.post(url, endpoint_filter=self.service, data=None, headers=headers).headers self.set_headers(resp) return self