diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 46b07f26f5..d899acd0b3 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -4,6 +4,19 @@ All notable changes to this project will be documented in this file. The format is based on `Keep a Changelog `_. +==================== + 1.3.3 - 2017-06-09 +==================== + +------- + Added +------- + +* An UploadManager class to better support large object uploads though multipart and parallel operations. +* Support for object storage pre-authenticated requests and public buckets. +* Support for load balancing service. +* Support for nested instance metadata operations. + ==================== 1.3.2 - 2017-05-18 ==================== diff --git a/docs/api/index.rst b/docs/api/index.rst index 694fd104c9..c5c63a9550 100644 --- a/docs/api/index.rst +++ b/docs/api/index.rst @@ -57,6 +57,27 @@ Virtual Network .. automodule:: oraclebmc.identity.models :members: + :undoc-members: + :imported-members: + +============== +Load Balancer +============== + +-------- + Client +-------- + +.. autoclass:: oraclebmc.loadbalancer.load_balancer_client.LoadBalancerClient + :members: + +-------- + Models +-------- + +.. automodule:: oraclebmc.loadbalancer.models + :members: + :undoc-members: :imported-members: ================ @@ -76,6 +97,7 @@ Virtual Network .. automodule:: oraclebmc.object_storage.models :members: + :undoc-members: :imported-members: diff --git a/examples/multipart_object_upload.py b/examples/multipart_object_upload.py new file mode 100644 index 0000000000..ea27fb2fb6 --- /dev/null +++ b/examples/multipart_object_upload.py @@ -0,0 +1,57 @@ +# Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. + +from __future__ import print_function +import os +import oraclebmc +from oraclebmc.object_storage import UploadManager +from oraclebmc.object_storage.models import CreateBucketDetails +from oraclebmc.object_storage.transfer.constants import MEBIBYTE + + +def progress_callback(bytes_uploaded): + print("{} additional bytes uploaded".format(bytes_uploaded)) + + +config = oraclebmc.config.from_file() +compartment_id = config["tenancy"] +object_storage = oraclebmc.object_storage.ObjectStorageClient(config) + +namespace = object_storage.get_namespace().data +bucket_name = "python-sdk-example-bucket" +object_name = "python-sdk-example-object" + +print("Creating a new bucket {!r} in compartment {!r}".format(bucket_name, compartment_id)) +request = CreateBucketDetails() +request.compartment_id = compartment_id +request.name = bucket_name +bucket = object_storage.create_bucket(namespace, request) + +# create example file to upload +filename = 'multipart_object_content.txt' +file_size_in_mebibytes = 10 +sample_content = b'a' +with open(filename, 'wb') as f: + while f.tell() < MEBIBYTE * file_size_in_mebibytes: + f.write(sample_content * MEBIBYTE) + +print("Uploading new object {!r}".format(object_name)) + +# upload manager will automatically use mutlipart uploads if the part size is less than the file size +part_size = 2 * MEBIBYTE # part size (in bytes) +upload_manager = UploadManager(object_storage, allow_parallel_uploads=True, parallel_process_count=3) +response = upload_manager.upload_file( + namespace, bucket_name, object_name, filename, part_size=part_size, progress_callback=progress_callback) + +# To force single part uploads, set "allow_multipart_uploads=False" when creating the UploadManager. +# upload_manager = UploadManager(object_storage, allow_multipart_uploads=False) +# response = upload_manager.upload_file( +# namespace, bucket_name, object_name, filename, part_size=part_size, progress_callback=progress_callback) + +# remove file to clean up +os.remove(filename) + +print("Deleting object {}".format(object_name)) +object_storage.delete_object(namespace, bucket_name, object_name) + +print("Deleting bucket {}".format(bucket_name)) +object_storage.delete_bucket(namespace, bucket_name) diff --git a/examples/parallel_upload_to_object_storage.py b/examples/parallel_upload_to_object_storage.py index 1f9effa0bf..1af125c0e9 100644 --- a/examples/parallel_upload_to_object_storage.py +++ b/examples/parallel_upload_to_object_storage.py @@ -47,7 +47,7 @@ def upload_to_object_storage(config, namespace, bucket, path): "parallel. The example uses multiple processes.", "", "All the files in 'directory' will be uploaded to the object storage bucket", - "specified by 'bucket_name' The default profile will is used.", + "specified by 'bucket_name' The default profile is used.", "", "The bucket must already exist. See object_crud.py for a bucket creation", "example."]) diff --git a/oraclebmc/core/blockstorage_client.py b/oraclebmc/core/blockstorage_client.py index 740939077e..9a2f8a7aee 100644 --- a/oraclebmc/core/blockstorage_client.py +++ b/oraclebmc/core/blockstorage_client.py @@ -43,9 +43,9 @@ def create_volume(self, create_volume_details, **kwargs): You may optionally specify a *display name* for the volume, which is simply a friendly name or description. It does not have to be unique, and you can change it. - __ {{DOC_SERVER_URL}}/Content/Block/Concepts/overview.htm - __ {{DOC_SERVER_URL}}/Content/Identity/Concepts/overview.htm - __ {{DOC_SERVER_URL}}/Content/General/Concepts/regions.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/Block/Concepts/overview.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/overview.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/regions.htm :param CreateVolumeDetails create_volume_details: (required) @@ -97,7 +97,7 @@ def create_volume_backup(self, create_volume_backup_details, **kwargs): When the data is imaged, it goes into a CREATING state. After the backup is fully uploaded to the cloud, it goes into an AVAILABLE state. - __ {{DOC_SERVER_URL}}/Content/Block/Concepts/blockvolumebackups.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/Block/Concepts/blockvolumebackups.htm :param CreateVolumeBackupDetails create_volume_backup_details: (required) @@ -147,7 +147,7 @@ def delete_volume(self, volume_id, **kwargs): `Disconnecting From a Volume`__. **Warning:** All data on the volume will be permanently lost when the volume is deleted. - __ {{DOC_SERVER_URL}}/Content/Block/Tasks/disconnectingfromavolume.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/Block/Tasks/disconnectingfromavolume.htm :param str volume_id: (required) diff --git a/oraclebmc/core/compute_client.py b/oraclebmc/core/compute_client.py index e9aba03c5b..2a2ecc4b94 100644 --- a/oraclebmc/core/compute_client.py +++ b/oraclebmc/core/compute_client.py @@ -144,7 +144,7 @@ def create_image(self, create_image_details, **kwargs): You may optionally specify a *display name* for the image, which is simply a friendly name or description. It does not have to be unique, and you can change it. See :func:`update_image`. - __ {{DOC_SERVER_URL}}/Content/Compute/Tasks/managingcustomimages.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/Compute/Tasks/managingcustomimages.htm :param CreateImageDetails create_image_details: (required) @@ -679,9 +679,9 @@ def launch_instance(self, launch_instance_details, **kwargs): operation to get the VNIC ID for the instance, and then call :func:`get_vnic` with the VNIC ID. - __ {{DOC_SERVER_URL}}/Content/Compute/Concepts/computeoverview.htm - __ {{DOC_SERVER_URL}}/Content/Identity/Concepts/overview.htm - __ {{DOC_SERVER_URL}}/Content/General/Concepts/regions.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/Compute/Concepts/computeoverview.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/overview.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/regions.htm :param LaunchInstanceDetails launch_instance_details: (required) @@ -794,7 +794,7 @@ def list_images(self, compartment_id, **kwargs): information about images, see `Managing Custom Images`__. - __ {{DOC_SERVER_URL}}/Content/Compute/Tasks/managingcustomimages.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/Compute/Tasks/managingcustomimages.htm :param str compartment_id: (required) diff --git a/oraclebmc/core/models/create_subnet_details.py b/oraclebmc/core/models/create_subnet_details.py index 46345aee5a..7f934bdf71 100644 --- a/oraclebmc/core/models/create_subnet_details.py +++ b/oraclebmc/core/models/create_subnet_details.py @@ -195,7 +195,7 @@ def dns_label(self): Example: `subnet123` - __ {{DOC_SERVER_URL}}/Content/Network/Concepts/dns.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Concepts/dns.htm :return: The dns_label of this CreateSubnetDetails. @@ -222,7 +222,7 @@ def dns_label(self, dns_label): Example: `subnet123` - __ {{DOC_SERVER_URL}}/Content/Network/Concepts/dns.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Concepts/dns.htm :param dns_label: The dns_label of this CreateSubnetDetails. diff --git a/oraclebmc/core/models/create_vcn_details.py b/oraclebmc/core/models/create_vcn_details.py index 1d5d7993bf..614256ff8c 100644 --- a/oraclebmc/core/models/create_vcn_details.py +++ b/oraclebmc/core/models/create_vcn_details.py @@ -125,7 +125,7 @@ def dns_label(self): Example: `vcn1` - __ {{DOC_SERVER_URL}}/Content/Network/Concepts/dns.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Concepts/dns.htm :return: The dns_label of this CreateVcnDetails. @@ -154,7 +154,7 @@ def dns_label(self, dns_label): Example: `vcn1` - __ {{DOC_SERVER_URL}}/Content/Network/Concepts/dns.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Concepts/dns.htm :param dns_label: The dns_label of this CreateVcnDetails. diff --git a/oraclebmc/core/models/create_virtual_circuit_details.py b/oraclebmc/core/models/create_virtual_circuit_details.py index 0e1d09db3a..8ba58fb321 100644 --- a/oraclebmc/core/models/create_virtual_circuit_details.py +++ b/oraclebmc/core/models/create_virtual_circuit_details.py @@ -300,7 +300,7 @@ def type(self): means `RFC 1918`__ addresses (10.0.0.0/8, 172.16/12, and 192.168/16). Only PRIVATE is supported. - __ https://tools.ietf.org/html/rfc1918 + __ https://tools.ietf.org/html/rfc1918 Allowed values for this property are: "PUBLIC", "PRIVATE" @@ -318,7 +318,7 @@ def type(self, type): means `RFC 1918`__ addresses (10.0.0.0/8, 172.16/12, and 192.168/16). Only PRIVATE is supported. - __ https://tools.ietf.org/html/rfc1918 + __ https://tools.ietf.org/html/rfc1918 :param type: The type of this CreateVirtualCircuitDetails. diff --git a/oraclebmc/core/models/create_vnic_details.py b/oraclebmc/core/models/create_vnic_details.py index 2bb13aaebf..13d0330c41 100644 --- a/oraclebmc/core/models/create_vnic_details.py +++ b/oraclebmc/core/models/create_vnic_details.py @@ -119,9 +119,9 @@ def hostname_label(self): Example: `bminstance-1` - __ https://tools.ietf.org/html/rfc952 - __ https://tools.ietf.org/html/rfc1123 - __ {{DOC_SERVER_URL}}/Content/Network/Concepts/dns.htm + __ https://tools.ietf.org/html/rfc952 + __ https://tools.ietf.org/html/rfc1123 + __ https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Concepts/dns.htm :return: The hostname_label of this CreateVnicDetails. @@ -153,9 +153,9 @@ def hostname_label(self, hostname_label): Example: `bminstance-1` - __ https://tools.ietf.org/html/rfc952 - __ https://tools.ietf.org/html/rfc1123 - __ {{DOC_SERVER_URL}}/Content/Network/Concepts/dns.htm + __ https://tools.ietf.org/html/rfc952 + __ https://tools.ietf.org/html/rfc1123 + __ https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Concepts/dns.htm :param hostname_label: The hostname_label of this CreateVnicDetails. diff --git a/oraclebmc/core/models/dhcp_dns_option.py b/oraclebmc/core/models/dhcp_dns_option.py index c5095cc3a4..08ca0f4da7 100644 --- a/oraclebmc/core/models/dhcp_dns_option.py +++ b/oraclebmc/core/models/dhcp_dns_option.py @@ -71,7 +71,7 @@ def server_type(self): - **CustomDnsServer:** Instances use a DNS server of your choice (three maximum). - __ {{DOC_SERVER_URL}}/Content/Network/Concepts/dns.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Concepts/dns.htm Allowed values for this property are: "VcnLocal", "VcnLocalPlusInternet", "CustomDnsServer", 'UNKNOWN_ENUM_VALUE'. Any unrecognized values returned by a service will be mapped to 'UNKNOWN_ENUM_VALUE'. @@ -101,7 +101,7 @@ def server_type(self, server_type): - **CustomDnsServer:** Instances use a DNS server of your choice (three maximum). - __ {{DOC_SERVER_URL}}/Content/Network/Concepts/dns.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Concepts/dns.htm :param server_type: The server_type of this DhcpDnsOption. diff --git a/oraclebmc/core/models/dhcp_search_domain_option.py b/oraclebmc/core/models/dhcp_search_domain_option.py index 89bfe58045..612013162d 100644 --- a/oraclebmc/core/models/dhcp_search_domain_option.py +++ b/oraclebmc/core/models/dhcp_search_domain_option.py @@ -41,8 +41,8 @@ def search_domain_names(self): of search domain names, or with an empty string as the value for any search domain name. - __ https://tools.ietf.org/html/rfc952 - __ https://tools.ietf.org/html/rfc1123 + __ https://tools.ietf.org/html/rfc952 + __ https://tools.ietf.org/html/rfc1123 :return: The search_domain_names of this DhcpSearchDomainOption. @@ -68,8 +68,8 @@ def search_domain_names(self, search_domain_names): of search domain names, or with an empty string as the value for any search domain name. - __ https://tools.ietf.org/html/rfc952 - __ https://tools.ietf.org/html/rfc1123 + __ https://tools.ietf.org/html/rfc952 + __ https://tools.ietf.org/html/rfc1123 :param search_domain_names: The search_domain_names of this DhcpSearchDomainOption. diff --git a/oraclebmc/core/models/egress_security_rule.py b/oraclebmc/core/models/egress_security_rule.py index 0ba8509108..28f0895333 100644 --- a/oraclebmc/core/models/egress_security_rule.py +++ b/oraclebmc/core/models/egress_security_rule.py @@ -73,7 +73,7 @@ def icmp_options(self): Unreachable\") code 4 (\"Fragmentation Needed and Don't Fragment was Set\"). If you need to specify multiple codes for a single type, create a separate security list rule for each. - __ http://www.iana.org/assignments/icmp-parameters/icmp-parameters.xhtml + __ http://www.iana.org/assignments/icmp-parameters/icmp-parameters.xhtml :return: The icmp_options of this EgressSecurityRule. @@ -94,7 +94,7 @@ def icmp_options(self, icmp_options): Unreachable\") code 4 (\"Fragmentation Needed and Don't Fragment was Set\"). If you need to specify multiple codes for a single type, create a separate security list rule for each. - __ http://www.iana.org/assignments/icmp-parameters/icmp-parameters.xhtml + __ http://www.iana.org/assignments/icmp-parameters/icmp-parameters.xhtml :param icmp_options: The icmp_options of this EgressSecurityRule. @@ -143,7 +143,7 @@ def protocol(self): `Protocol Numbers`__. Options are supported only for ICMP (\"1\"), TCP (\"6\"), and UDP (\"17\"). - __ http://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml + __ http://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml :return: The protocol of this EgressSecurityRule. @@ -160,7 +160,7 @@ def protocol(self, protocol): `Protocol Numbers`__. Options are supported only for ICMP (\"1\"), TCP (\"6\"), and UDP (\"17\"). - __ http://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml + __ http://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml :param protocol: The protocol of this EgressSecurityRule. diff --git a/oraclebmc/core/models/ingress_security_rule.py b/oraclebmc/core/models/ingress_security_rule.py index 953412cfe3..695dd52e24 100644 --- a/oraclebmc/core/models/ingress_security_rule.py +++ b/oraclebmc/core/models/ingress_security_rule.py @@ -47,7 +47,7 @@ def icmp_options(self): Unreachable\") code 4 (\"Fragmentation Needed and Don't Fragment was Set\"). If you need to specify multiple codes for a single type, create a separate security list rule for each. - __ http://www.iana.org/assignments/icmp-parameters/icmp-parameters.xhtml + __ http://www.iana.org/assignments/icmp-parameters/icmp-parameters.xhtml :return: The icmp_options of this IngressSecurityRule. @@ -68,7 +68,7 @@ def icmp_options(self, icmp_options): Unreachable\") code 4 (\"Fragmentation Needed and Don't Fragment was Set\"). If you need to specify multiple codes for a single type, create a separate security list rule for each. - __ http://www.iana.org/assignments/icmp-parameters/icmp-parameters.xhtml + __ http://www.iana.org/assignments/icmp-parameters/icmp-parameters.xhtml :param icmp_options: The icmp_options of this IngressSecurityRule. @@ -117,7 +117,7 @@ def protocol(self): `Protocol Numbers`__. Options are supported only for ICMP (\"1\"), TCP (\"6\"), and UDP (\"17\"). - __ http://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml + __ http://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml :return: The protocol of this IngressSecurityRule. @@ -134,7 +134,7 @@ def protocol(self, protocol): `Protocol Numbers`__. Options are supported only for ICMP (\"1\"), TCP (\"6\"), and UDP (\"17\"). - __ http://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml + __ http://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml :param protocol: The protocol of this IngressSecurityRule. diff --git a/oraclebmc/core/models/instance.py b/oraclebmc/core/models/instance.py index ac82464659..4cfe684285 100644 --- a/oraclebmc/core/models/instance.py +++ b/oraclebmc/core/models/instance.py @@ -13,6 +13,7 @@ def __init__(self): 'availability_domain': 'str', 'compartment_id': 'str', 'display_name': 'str', + 'extended_metadata': 'dict(str, object)', 'id': 'str', 'image_id': 'str', 'ipxe_script': 'str', @@ -27,6 +28,7 @@ def __init__(self): 'availability_domain': 'availabilityDomain', 'compartment_id': 'compartmentId', 'display_name': 'displayName', + 'extended_metadata': 'extendedMetadata', 'id': 'id', 'image_id': 'imageId', 'ipxe_script': 'ipxeScript', @@ -40,6 +42,7 @@ def __init__(self): self._availability_domain = None self._compartment_id = None self._display_name = None + self._extended_metadata = None self._id = None self._image_id = None self._ipxe_script = None @@ -129,6 +132,38 @@ def display_name(self, display_name): """ self._display_name = display_name + @property + def extended_metadata(self): + """ + Gets the extended_metadata of this Instance. + Additional metadata key/value pairs that you provide. They serve a similar purpose and functionality from fields in the 'metadata' object. + + They are distinguished from 'metadata' fields in that these can be nested JSON objects (whereas 'metadata' fields are string/string maps only). + + If you don't need nested metadata values, it is strongly advised to avoid using this object and use the Metadata object instead. + + + :return: The extended_metadata of this Instance. + :rtype: dict(str, object) + """ + return self._extended_metadata + + @extended_metadata.setter + def extended_metadata(self, extended_metadata): + """ + Sets the extended_metadata of this Instance. + Additional metadata key/value pairs that you provide. They serve a similar purpose and functionality from fields in the 'metadata' object. + + They are distinguished from 'metadata' fields in that these can be nested JSON objects (whereas 'metadata' fields are string/string maps only). + + If you don't need nested metadata values, it is strongly advised to avoid using this object and use the Metadata object instead. + + + :param extended_metadata: The extended_metadata of this Instance. + :type: dict(str, object) + """ + self._extended_metadata = extended_metadata + @property def id(self): """ @@ -206,7 +241,7 @@ def ipxe_script(self): For more information about iPXE, see http://ipxe.org. - __ {{DOC_SERVER_URL}}/Content/Compute/References/bringyourownimage.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/Compute/References/bringyourownimage.htm :return: The ipxe_script of this Instance. @@ -241,7 +276,7 @@ def ipxe_script(self, ipxe_script): For more information about iPXE, see http://ipxe.org. - __ {{DOC_SERVER_URL}}/Content/Compute/References/bringyourownimage.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/Compute/References/bringyourownimage.htm :param ipxe_script: The ipxe_script of this Instance. diff --git a/oraclebmc/core/models/launch_instance_details.py b/oraclebmc/core/models/launch_instance_details.py index cf9182d157..3507507ee4 100644 --- a/oraclebmc/core/models/launch_instance_details.py +++ b/oraclebmc/core/models/launch_instance_details.py @@ -14,6 +14,7 @@ def __init__(self): 'compartment_id': 'str', 'create_vnic_details': 'CreateVnicDetails', 'display_name': 'str', + 'extended_metadata': 'dict(str, object)', 'hostname_label': 'str', 'image_id': 'str', 'ipxe_script': 'str', @@ -27,6 +28,7 @@ def __init__(self): 'compartment_id': 'compartmentId', 'create_vnic_details': 'createVnicDetails', 'display_name': 'displayName', + 'extended_metadata': 'extendedMetadata', 'hostname_label': 'hostnameLabel', 'image_id': 'imageId', 'ipxe_script': 'ipxeScript', @@ -39,6 +41,7 @@ def __init__(self): self._compartment_id = None self._create_vnic_details = None self._display_name = None + self._extended_metadata = None self._hostname_label = None self._image_id = None self._ipxe_script = None @@ -150,6 +153,38 @@ def display_name(self, display_name): """ self._display_name = display_name + @property + def extended_metadata(self): + """ + Gets the extended_metadata of this LaunchInstanceDetails. + Additional metadata key/value pairs that you provide. They serve a similar purpose and functionality from fields in the 'metadata' object. + + They are distinguished from 'metadata' fields in that these can be nested JSON objects (whereas 'metadata' fields are string/string maps only). + + If you don't need nested metadata values, it is strongly advised to avoid using this object and use the Metadata object instead. + + + :return: The extended_metadata of this LaunchInstanceDetails. + :rtype: dict(str, object) + """ + return self._extended_metadata + + @extended_metadata.setter + def extended_metadata(self, extended_metadata): + """ + Sets the extended_metadata of this LaunchInstanceDetails. + Additional metadata key/value pairs that you provide. They serve a similar purpose and functionality from fields in the 'metadata' object. + + They are distinguished from 'metadata' fields in that these can be nested JSON objects (whereas 'metadata' fields are string/string maps only). + + If you don't need nested metadata values, it is strongly advised to avoid using this object and use the Metadata object instead. + + + :param extended_metadata: The extended_metadata of this LaunchInstanceDetails. + :type: dict(str, object) + """ + self._extended_metadata = extended_metadata + @property def hostname_label(self): """ @@ -231,7 +266,7 @@ def ipxe_script(self): For more information about iPXE, see http://ipxe.org. - __ {{DOC_SERVER_URL}}/Content/Compute/References/bringyourownimage.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/Compute/References/bringyourownimage.htm :return: The ipxe_script of this LaunchInstanceDetails. @@ -268,7 +303,7 @@ def ipxe_script(self, ipxe_script): For more information about iPXE, see http://ipxe.org. - __ {{DOC_SERVER_URL}}/Content/Compute/References/bringyourownimage.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/Compute/References/bringyourownimage.htm :param ipxe_script: The ipxe_script of this LaunchInstanceDetails. @@ -292,34 +327,34 @@ def metadata(self): * Get information about the instance, including the custom metadata that you provide when you launch the instance. - __Providing Cloud-Init Metadata__ + **Providing Cloud-Init Metadata** You can use the following metadata key names to provide information to Cloud-Init: - __\"ssh_authorized_keys\"__ - Provide one or more public SSH keys to be + **\"ssh_authorized_keys\"** - Provide one or more public SSH keys to be included in the `~/.ssh/authorized_keys` file for the default user on the instance. Use a newline character to separate multiple keys. The SSH keys must be in the format necessary for the `authorized_keys` file, as shown in the example below. - __\"user_data\"__ - Provide your own base64-encoded data to be used by + **\"user_data\"** - Provide your own base64-encoded data to be used by Cloud-Init to run custom scripts or provide custom Cloud-Init configuration. For information about how to take advantage of user data, see the `Cloud-Init Documentation`__. - __Note:__ Cloud-Init does not pull this data from the `http://169.254.169.254/opc/v1/instance/metadata/` + **Note:** Cloud-Init does not pull this data from the `http://169.254.169.254/opc/v1/instance/metadata/` path. When the instance launches and either of these keys are provided, the key values are formatted as OpenStack metadata and copied to the following locations, which are recognized by Cloud-Init: `http://169.254.169.254/openstack/latest/meta_data.json` - This JSON blob contains, among other things, the SSH keys that you provided for - __\"ssh_authorized_keys\"__. + **\"ssh_authorized_keys\"**. `http://169.254.169.254/openstack/latest/user_data` - Contains the - base64-decoded data that you provided for __\"user_data\"__. + base64-decoded data that you provided for **\"user_data\"**. - __Metadata Example__ + **Metadata Example** \"metadata\" : { \"quake_bot_level\" : \"Severe\", @@ -327,7 +362,7 @@ def metadata(self): ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAQEAzJSAtwEPoB3Jmr58IXrDGzLuDYkWAYg8AsLYlo6JZvKpjY1xednIcfEVQJm4T2DhVmdWhRrwQ8DmayVZvBkLt+zs2LdoAJEVimKwXcJFD/7wtH8Lnk17HiglbbbNXsemjDY0hea4JUE5CfvkIdZBITuMrfqSmA4n3VNoorXYdvtTMoGG8fxMub46RPtuxtqi9bG9Zqenordkg5FJt2mVNfQRqf83CWojcOkklUWq4CjyxaeLf5i9gv1fRoBo4QhiA8I6NCSppO8GnoV/6Ox6TNoh9BiifqGKC9VGYuC89RvUajRBTZSK2TK4DPfaT+2R+slPsFrwiT/oPEhhEK1S5Q== rsa-key-20160227\", \"user_data\" : \"SWYgeW91IGNhbiBzZWUgdGhpcywgdGhlbiBpdCB3b3JrZWQgbWF5YmUuCg==\" } - __Getting Metadata on the Instance__ + **Getting Metadata on the Instance** To get information about your instance, connect to the instance using SSH and issue any of the following GET requests: @@ -339,8 +374,8 @@ def metadata(self): You'll get back a response that includes all the instance information; only the metadata information; or the metadata information for the specified key name, respectively. - __ https://cloudinit.readthedocs.org/en/latest/ - __ http://cloudinit.readthedocs.org/en/latest/topics/format.html + __ https://cloudinit.readthedocs.org/en/latest/ + __ http://cloudinit.readthedocs.org/en/latest/topics/format.html :return: The metadata of this LaunchInstanceDetails. @@ -364,34 +399,34 @@ def metadata(self, metadata): * Get information about the instance, including the custom metadata that you provide when you launch the instance. - __Providing Cloud-Init Metadata__ + **Providing Cloud-Init Metadata** You can use the following metadata key names to provide information to Cloud-Init: - __\"ssh_authorized_keys\"__ - Provide one or more public SSH keys to be + **\"ssh_authorized_keys\"** - Provide one or more public SSH keys to be included in the `~/.ssh/authorized_keys` file for the default user on the instance. Use a newline character to separate multiple keys. The SSH keys must be in the format necessary for the `authorized_keys` file, as shown in the example below. - __\"user_data\"__ - Provide your own base64-encoded data to be used by + **\"user_data\"** - Provide your own base64-encoded data to be used by Cloud-Init to run custom scripts or provide custom Cloud-Init configuration. For information about how to take advantage of user data, see the `Cloud-Init Documentation`__. - __Note:__ Cloud-Init does not pull this data from the `http://169.254.169.254/opc/v1/instance/metadata/` + **Note:** Cloud-Init does not pull this data from the `http://169.254.169.254/opc/v1/instance/metadata/` path. When the instance launches and either of these keys are provided, the key values are formatted as OpenStack metadata and copied to the following locations, which are recognized by Cloud-Init: `http://169.254.169.254/openstack/latest/meta_data.json` - This JSON blob contains, among other things, the SSH keys that you provided for - __\"ssh_authorized_keys\"__. + **\"ssh_authorized_keys\"**. `http://169.254.169.254/openstack/latest/user_data` - Contains the - base64-decoded data that you provided for __\"user_data\"__. + base64-decoded data that you provided for **\"user_data\"**. - __Metadata Example__ + **Metadata Example** \"metadata\" : { \"quake_bot_level\" : \"Severe\", @@ -399,7 +434,7 @@ def metadata(self, metadata): ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAQEAzJSAtwEPoB3Jmr58IXrDGzLuDYkWAYg8AsLYlo6JZvKpjY1xednIcfEVQJm4T2DhVmdWhRrwQ8DmayVZvBkLt+zs2LdoAJEVimKwXcJFD/7wtH8Lnk17HiglbbbNXsemjDY0hea4JUE5CfvkIdZBITuMrfqSmA4n3VNoorXYdvtTMoGG8fxMub46RPtuxtqi9bG9Zqenordkg5FJt2mVNfQRqf83CWojcOkklUWq4CjyxaeLf5i9gv1fRoBo4QhiA8I6NCSppO8GnoV/6Ox6TNoh9BiifqGKC9VGYuC89RvUajRBTZSK2TK4DPfaT+2R+slPsFrwiT/oPEhhEK1S5Q== rsa-key-20160227\", \"user_data\" : \"SWYgeW91IGNhbiBzZWUgdGhpcywgdGhlbiBpdCB3b3JrZWQgbWF5YmUuCg==\" } - __Getting Metadata on the Instance__ + **Getting Metadata on the Instance** To get information about your instance, connect to the instance using SSH and issue any of the following GET requests: @@ -411,8 +446,8 @@ def metadata(self, metadata): You'll get back a response that includes all the instance information; only the metadata information; or the metadata information for the specified key name, respectively. - __ https://cloudinit.readthedocs.org/en/latest/ - __ http://cloudinit.readthedocs.org/en/latest/topics/format.html + __ https://cloudinit.readthedocs.org/en/latest/ + __ http://cloudinit.readthedocs.org/en/latest/topics/format.html :param metadata: The metadata of this LaunchInstanceDetails. diff --git a/oraclebmc/core/models/subnet.py b/oraclebmc/core/models/subnet.py index 7d59e29f69..5c3bcaf60d 100644 --- a/oraclebmc/core/models/subnet.py +++ b/oraclebmc/core/models/subnet.py @@ -210,7 +210,7 @@ def dns_label(self): Example: `subnet123` - __ {{DOC_SERVER_URL}}/Content/Network/Concepts/dns.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Concepts/dns.htm :return: The dns_label of this Subnet. @@ -236,7 +236,7 @@ def dns_label(self, dns_label): Example: `subnet123` - __ {{DOC_SERVER_URL}}/Content/Network/Concepts/dns.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Concepts/dns.htm :param dns_label: The dns_label of this Subnet. @@ -400,7 +400,7 @@ def subnet_domain_name(self): Example: `subnet123.vcn1.oraclevcn.com` - __ {{DOC_SERVER_URL}}/Content/Network/Concepts/dns.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Concepts/dns.htm :return: The subnet_domain_name of this Subnet. @@ -420,7 +420,7 @@ def subnet_domain_name(self, subnet_domain_name): Example: `subnet123.vcn1.oraclevcn.com` - __ {{DOC_SERVER_URL}}/Content/Network/Concepts/dns.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Concepts/dns.htm :param subnet_domain_name: The subnet_domain_name of this Subnet. diff --git a/oraclebmc/core/models/vcn.py b/oraclebmc/core/models/vcn.py index 0ec74e40ee..5d7b63309b 100644 --- a/oraclebmc/core/models/vcn.py +++ b/oraclebmc/core/models/vcn.py @@ -215,7 +215,7 @@ def dns_label(self): Example: `vcn1` - __ {{DOC_SERVER_URL}}/Content/Network/Concepts/dns.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Concepts/dns.htm :return: The dns_label of this Vcn. @@ -241,7 +241,7 @@ def dns_label(self, dns_label): Example: `vcn1` - __ {{DOC_SERVER_URL}}/Content/Network/Concepts/dns.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Concepts/dns.htm :param dns_label: The dns_label of this Vcn. @@ -343,7 +343,7 @@ def vcn_domain_name(self): Example: `vcn1.oraclevcn.com` - __ {{DOC_SERVER_URL}}/Content/Network/Concepts/dns.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Concepts/dns.htm :return: The vcn_domain_name of this Vcn. @@ -363,7 +363,7 @@ def vcn_domain_name(self, vcn_domain_name): Example: `vcn1.oraclevcn.com` - __ {{DOC_SERVER_URL}}/Content/Network/Concepts/dns.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Concepts/dns.htm :param vcn_domain_name: The vcn_domain_name of this Vcn. diff --git a/oraclebmc/core/models/virtual_circuit.py b/oraclebmc/core/models/virtual_circuit.py index 73581d146b..4a6aa57d4c 100644 --- a/oraclebmc/core/models/virtual_circuit.py +++ b/oraclebmc/core/models/virtual_circuit.py @@ -287,7 +287,7 @@ def lifecycle_state(self): the different states, see `FastConnect Overview`__. - __ {{DOC_SERVER_URL}}/Content/Network/Concepts/fastconnect.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Concepts/fastconnect.htm Allowed values for this property are: "PENDING_PROVIDER", "VERIFYING", "PROVISIONING", "PROVISIONED", "FAILED", "INACTIVE", "TERMINATING", "TERMINATED", 'UNKNOWN_ENUM_VALUE'. Any unrecognized values returned by a service will be mapped to 'UNKNOWN_ENUM_VALUE'. @@ -306,7 +306,7 @@ def lifecycle_state(self, lifecycle_state): the different states, see `FastConnect Overview`__. - __ {{DOC_SERVER_URL}}/Content/Network/Concepts/fastconnect.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Concepts/fastconnect.htm :param lifecycle_state: The lifecycle_state of this VirtualCircuit. @@ -517,7 +517,7 @@ def type(self): `RFC 1918`__ addresses (10.0.0.0/8, 172.16/12, and 192.168/16). Only PRIVATE is supported. - __ https://tools.ietf.org/html/rfc1918 + __ https://tools.ietf.org/html/rfc1918 Allowed values for this property are: "PUBLIC", "PRIVATE", 'UNKNOWN_ENUM_VALUE'. Any unrecognized values returned by a service will be mapped to 'UNKNOWN_ENUM_VALUE'. @@ -536,7 +536,7 @@ def type(self, type): `RFC 1918`__ addresses (10.0.0.0/8, 172.16/12, and 192.168/16). Only PRIVATE is supported. - __ https://tools.ietf.org/html/rfc1918 + __ https://tools.ietf.org/html/rfc1918 :param type: The type of this VirtualCircuit. diff --git a/oraclebmc/core/models/vnic.py b/oraclebmc/core/models/vnic.py index 7c7ec81ae3..d3fc01abbd 100644 --- a/oraclebmc/core/models/vnic.py +++ b/oraclebmc/core/models/vnic.py @@ -140,9 +140,9 @@ def hostname_label(self): Example: `bminstance-1` - __ https://tools.ietf.org/html/rfc952 - __ https://tools.ietf.org/html/rfc1123 - __ {{DOC_SERVER_URL}}/Content/Network/Concepts/dns.htm + __ https://tools.ietf.org/html/rfc952 + __ https://tools.ietf.org/html/rfc1123 + __ https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Concepts/dns.htm :return: The hostname_label of this Vnic. @@ -168,9 +168,9 @@ def hostname_label(self, hostname_label): Example: `bminstance-1` - __ https://tools.ietf.org/html/rfc952 - __ https://tools.ietf.org/html/rfc1123 - __ {{DOC_SERVER_URL}}/Content/Network/Concepts/dns.htm + __ https://tools.ietf.org/html/rfc952 + __ https://tools.ietf.org/html/rfc1123 + __ https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Concepts/dns.htm :param hostname_label: The hostname_label of this Vnic. diff --git a/oraclebmc/core/virtual_network_client.py b/oraclebmc/core/virtual_network_client.py index dd0704b6f0..705bd49018 100644 --- a/oraclebmc/core/virtual_network_client.py +++ b/oraclebmc/core/virtual_network_client.py @@ -45,10 +45,10 @@ def create_cpe(self, create_cpe_details, **kwargs): You may optionally specify a *display name* for the CPE, otherwise a default is provided. It does not have to be unique, and you can change it. - __ {{DOC_SERVER_URL}}/Content/Network/Tasks/managingIPsec.htm - __ {{DOC_SERVER_URL}}/Content/Identity/Concepts/overview.htm - __ {{DOC_SERVER_URL}}/Content/General/Concepts/identifiers.htm - __ {{DOC_SERVER_URL}}/Content/Network/Tasks/configuringCPE.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Tasks/managingIPsec.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/overview.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Tasks/configuringCPE.htm :param CreateCpeDetails create_cpe_details: (required) @@ -113,9 +113,9 @@ def create_cross_connect(self, create_cross_connect_details, **kwargs): You may optionally specify a *display name* for the cross-connect. It does not have to be unique, and you can change it. - __ {{DOC_SERVER_URL}}/Content/Network/Concepts/fastconnect.htm - __ {{DOC_SERVER_URL}}/Content/Identity/Concepts/overview.htm - __ {{DOC_SERVER_URL}}/Content/General/Concepts/identifiers.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Concepts/fastconnect.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/overview.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm :param CreateCrossConnectDetails create_cross_connect_details: (required) @@ -176,9 +176,9 @@ def create_cross_connect_group(self, create_cross_connect_group_details, **kwarg You may optionally specify a *display name* for the cross-connect group. It does not have to be unique, and you can change it. - __ {{DOC_SERVER_URL}}/Content/Network/Concepts/fastconnect.htm - __ {{DOC_SERVER_URL}}/Content/Identity/Concepts/overview.htm - __ {{DOC_SERVER_URL}}/Content/General/Concepts/identifiers.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Concepts/fastconnect.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/overview.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm :param CreateCrossConnectGroupDetails create_cross_connect_group_details: (required) @@ -236,8 +236,8 @@ def create_dhcp_options(self, create_dhcp_details, **kwargs): You may optionally specify a *display name* for the set of DHCP options, otherwise a default is provided. It does not have to be unique, and you can change it. - __ {{DOC_SERVER_URL}}/Content/Identity/Concepts/overview.htm - __ {{DOC_SERVER_URL}}/Content/General/Concepts/identifiers.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/overview.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm :param CreateDhcpDetails create_dhcp_details: (required) @@ -295,9 +295,9 @@ def create_drg(self, create_drg_details, **kwargs): You may optionally specify a *display name* for the DRG, otherwise a default is provided. It does not have to be unique, and you can change it. - __ {{DOC_SERVER_URL}}/Content/Network/Tasks/managingDRGs.htm - __ {{DOC_SERVER_URL}}/Content/Identity/Concepts/overview.htm - __ {{DOC_SERVER_URL}}/Content/General/Concepts/identifiers.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Tasks/managingDRGs.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/overview.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm :param CreateDrgDetails create_drg_details: (required) @@ -354,8 +354,8 @@ def create_drg_attachment(self, create_drg_attachment_details, **kwargs): as the VCN. For more information about compartments and access control, see `Overview of the IAM Service`__. - __ {{DOC_SERVER_URL}}/Content/Network/Tasks/managingDRGs.htm - __ {{DOC_SERVER_URL}}/Content/Identity/Concepts/overview.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Tasks/managingDRGs.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/overview.htm :param CreateDrgAttachmentDetails create_drg_attachment_details: (required) @@ -422,9 +422,9 @@ def create_internet_gateway(self, create_internet_gateway_details, **kwargs): use :func:`update_internet_gateway` to easily disable/enable the gateway without changing the route rule. - __ {{DOC_SERVER_URL}}/Content/Network/Tasks/managingIGs.htm - __ {{DOC_SERVER_URL}}/Content/Identity/Concepts/overview.htm - __ {{DOC_SERVER_URL}}/Content/General/Concepts/identifiers.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Tasks/managingIGs.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/overview.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm :param CreateInternetGatewayDetails create_internet_gateway_details: (required) @@ -496,10 +496,10 @@ def create_ip_sec_connection(self, create_ip_sec_connection_details, **kwargs): To get the status of the tunnels (whether they're up or down), use :func:`get_ip_sec_connection_device_status`. - __ {{DOC_SERVER_URL}}/Content/Network/Tasks/managingIPsec.htm - __ {{DOC_SERVER_URL}}/Content/Identity/Concepts/overview.htm - __ {{DOC_SERVER_URL}}/Content/General/Concepts/identifiers.htm - __ {{DOC_SERVER_URL}}/Content/Network/Tasks/configuringCPE.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Tasks/managingIPsec.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/overview.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Tasks/configuringCPE.htm :param CreateIPSecConnectionDetails create_ip_sec_connection_details: (required) @@ -559,10 +559,10 @@ def create_route_table(self, create_route_table_details, **kwargs): You may optionally specify a *display name* for the route table, otherwise a default is provided. It does not have to be unique, and you can change it. - __ {{DOC_SERVER_URL}}/Content/General/Concepts/servicelimits.htm - __ {{DOC_SERVER_URL}}/Content/Network/Tasks/managingroutetables.htm - __ {{DOC_SERVER_URL}}/Content/Identity/Concepts/overview.htm - __ {{DOC_SERVER_URL}}/Content/General/Concepts/identifiers.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/servicelimits.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Tasks/managingroutetables.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/overview.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm :param CreateRouteTableDetails create_route_table_details: (required) @@ -622,10 +622,10 @@ def create_security_list(self, create_security_list_details, **kwargs): You may optionally specify a *display name* for the security list, otherwise a default is provided. It does not have to be unique, and you can change it. - __ {{DOC_SERVER_URL}}/Content/Network/Concepts/securitylists.htm - __ {{DOC_SERVER_URL}}/Content/General/Concepts/servicelimits.htm - __ {{DOC_SERVER_URL}}/Content/Identity/Concepts/overview.htm - __ {{DOC_SERVER_URL}}/Content/General/Concepts/identifiers.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Concepts/securitylists.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/servicelimits.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/overview.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm :param CreateSecurityListDetails create_security_list_details: (required) @@ -702,14 +702,14 @@ def create_subnet(self, create_subnet_details, **kwargs): VCN Resolver to resolve hostnames for instances in the subnet. For more information, see `DNS in Your Virtual Cloud Network`__. - __ {{DOC_SERVER_URL}}/Content/Network/Tasks/managingsubnets.htm - __ {{DOC_SERVER_URL}}/Content/General/Concepts/servicelimits.htm - __ {{DOC_SERVER_URL}}/Content/Identity/Concepts/overview.htm - __ {{DOC_SERVER_URL}}/Content/General/Concepts/identifiers.htm - __ {{DOC_SERVER_URL}}/Content/Network/Tasks/managingroutetables.htm - __ {{DOC_SERVER_URL}}/Content/Network/Concepts/securitylists.htm - __ {{DOC_SERVER_URL}}/Content/Network/Tasks/managingDHCP.htm - __ {{DOC_SERVER_URL}}/Content/Network/Concepts/dns.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Tasks/managingsubnets.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/servicelimits.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/overview.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Tasks/managingroutetables.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Concepts/securitylists.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Tasks/managingDHCP.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Concepts/dns.htm :param CreateSubnetDetails create_subnet_details: (required) @@ -784,12 +784,12 @@ def create_vcn(self, create_vcn_details, **kwargs): or FastConnect. For more information, see `Overview of the Networking Service`__. - __ {{DOC_SERVER_URL}}/Content/Network/Tasks/managingVCNs.htm - __ https://tools.ietf.org/html/rfc1918 - __ {{DOC_SERVER_URL}}/Content/Identity/Concepts/overview.htm - __ {{DOC_SERVER_URL}}/Content/General/Concepts/identifiers.htm - __ {{DOC_SERVER_URL}}/Content/Network/Concepts/dns.htm - __ {{DOC_SERVER_URL}}/Content/Network/Concepts/overview.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Tasks/managingVCNs.htm + __ https://tools.ietf.org/html/rfc1918 + __ https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/overview.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Concepts/dns.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Concepts/overview.htm :param CreateVcnDetails create_vcn_details: (required) @@ -856,10 +856,10 @@ def create_virtual_circuit(self, create_virtual_circuit_details, **kwargs): traffic will not flow. For more information, see `Managing Route Tables`__. - __ {{DOC_SERVER_URL}}/Content/Network/Concepts/fastconnect.htm - __ {{DOC_SERVER_URL}}/Content/Identity/Concepts/overview.htm - __ {{DOC_SERVER_URL}}/Content/General/Concepts/identifiers.htm - __ {{DOC_SERVER_URL}}/Content/Network/Tasks/managingroutetables.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Concepts/fastconnect.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/overview.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Tasks/managingroutetables.htm :param CreateVirtualCircuitDetails create_virtual_circuit_details: (required) @@ -2659,7 +2659,7 @@ def list_fast_connect_provider_services(self, compartment_id, **kwargs): For more information, see `FastConnect Overview`__. - __ {{DOC_SERVER_URL}}/Content/Network/Concepts/fastconnect.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Concepts/fastconnect.htm :param str compartment_id: (required) @@ -3061,7 +3061,7 @@ def list_virtual_circuit_bandwidth_shapes(self, compartment_id, **kwargs): For more information about virtual circuits, see `FastConnect Overview`__. - __ {{DOC_SERVER_URL}}/Content/Network/Concepts/fastconnect.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Concepts/fastconnect.htm :param str compartment_id: (required) @@ -3813,7 +3813,7 @@ def update_virtual_circuit(self, virtual_circuit_id, update_virtual_circuit_deta about the various states and how to test connectivity, see `FastConnect Overview`__. - __ {{DOC_SERVER_URL}}/Content/Network/Concepts/fastconnect.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Concepts/fastconnect.htm :param str virtual_circuit_id: (required) diff --git a/oraclebmc/identity/identity_client.py b/oraclebmc/identity/identity_client.py index 579093e506..83bca1d585 100644 --- a/oraclebmc/identity/identity_client.py +++ b/oraclebmc/identity/identity_client.py @@ -97,8 +97,8 @@ def create_compartment(self, create_compartment_details, **kwargs): After you send your request, the new object's `lifecycleState` will temporarily be CREATING. Before using the object, first make sure its `lifecycleState` has changed to ACTIVE. - __ {{DOC_SERVER_URL}}/Content/General/Concepts/identifiers.htm - __ {{DOC_SERVER_URL}}/Content/Identity/Concepts/policies.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/policies.htm :param CreateCompartmentDetails create_compartment_details: (required) @@ -165,8 +165,8 @@ def create_group(self, create_group_details, **kwargs): See :func:`add_user_to_group` and :func:`create_policy`. - __ {{DOC_SERVER_URL}}/Content/General/Concepts/identifiers.htm - __ {{DOC_SERVER_URL}}/Content/Identity/Concepts/policies.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/policies.htm :param CreateGroupDetails create_group_details: (required) @@ -230,8 +230,8 @@ def create_identity_provider(self, create_identity_provider_details, **kwargs): be CREATING. Before using the object, first make sure its `lifecycleState` has changed to ACTIVE. - __ {{DOC_SERVER_URL}}/Content/Identity/Concepts/federation.htm - __ {{DOC_SERVER_URL}}/Content/General/Concepts/identifiers.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/federation.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm :param CreateIdentityProviderDetails create_identity_provider_details: (required) @@ -343,7 +343,7 @@ def create_or_reset_ui_password(self, user_id, **kwargs): **Note:** The user's Console login is the unique name you specified when you created the user (see :func:`create_user`). - __ {{DOC_SERVER_URL}}/Content/Identity/Concepts/usercredentials.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/usercredentials.htm :param str user_id: (required) @@ -411,9 +411,9 @@ def create_policy(self, create_policy_details, **kwargs): New policies take effect typically within 10 seconds. - __ {{DOC_SERVER_URL}}/Content/Identity/Concepts/policygetstarted.htm - __ {{DOC_SERVER_URL}}/Content/Identity/Concepts/policies.htm - __ {{DOC_SERVER_URL}}/Content/Identity/Concepts/commonpolicies.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/policygetstarted.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/policies.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/commonpolicies.htm :param CreatePolicyDetails create_policy_details: (required) @@ -523,7 +523,7 @@ def create_swift_password(self, create_swift_password_details, user_id, **kwargs does not need to write a policy to give users this ability. To compare, administrators who have permission to the tenancy can use this operation to create a Swift password for any user, including themselves. - __ {{DOC_SERVER_URL}}/Content/Identity/Tasks/managingcredentials.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Tasks/managingcredentials.htm :param CreateSwiftPasswordDetails create_swift_password_details: (required) @@ -613,9 +613,9 @@ def create_user(self, create_user_details, **kwargs): **Important:** Make sure to inform the new user which compartment(s) they have access to. - __ {{DOC_SERVER_URL}}/Content/Identity/Concepts/overview.htm - __ {{DOC_SERVER_URL}}/Content/General/Concepts/identifiers.htm - __ {{DOC_SERVER_URL}}/Content/API/Concepts/apisigningkey.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/overview.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/API/Concepts/apisigningkey.htm :param CreateUserDetails create_user_details: (required) @@ -1353,7 +1353,7 @@ def list_availability_domains(self, compartment_id, **kwargs): of your compartments as the value for the compartment ID (remember that the tenancy is simply the root compartment). See `Where to Get the Tenancy's OCID and User's OCID`__. - __ {{DOC_SERVER_URL}}/Content/API/Concepts/apisigningkey.htm#five + __ https://docs.us-phoenix-1.oraclecloud.com/Content/API/Concepts/apisigningkey.htm#five :param str compartment_id: (required) @@ -1393,7 +1393,7 @@ def list_compartments(self, compartment_id, **kwargs): for the compartment ID (remember that the tenancy is simply the root compartment). See `Where to Get the Tenancy's OCID and User's OCID`__. - __ {{DOC_SERVER_URL}}/Content/API/Concepts/apisigningkey.htm#five + __ https://docs.us-phoenix-1.oraclecloud.com/Content/API/Concepts/apisigningkey.htm#five :param str compartment_id: (required) @@ -1447,7 +1447,7 @@ def list_groups(self, compartment_id, **kwargs): the compartment ID (remember that the tenancy is simply the root compartment). See `Where to Get the Tenancy's OCID and User's OCID`__. - __ {{DOC_SERVER_URL}}/Content/API/Concepts/apisigningkey.htm#five + __ https://docs.us-phoenix-1.oraclecloud.com/Content/API/Concepts/apisigningkey.htm#five :param str compartment_id: (required) @@ -1502,7 +1502,7 @@ def list_identity_providers(self, protocol, compartment_id, **kwargs): compartment ID (remember that the tenancy is simply the root compartment). See `Where to Get the Tenancy's OCID and User's OCID`__. - __ {{DOC_SERVER_URL}}/Content/API/Concepts/apisigningkey.htm#five + __ https://docs.us-phoenix-1.oraclecloud.com/Content/API/Concepts/apisigningkey.htm#five :param str protocol: (required) @@ -1617,7 +1617,7 @@ def list_policies(self, compartment_id, **kwargs): To determine which policies apply to a particular group or compartment, you must view the individual statements inside all your policies. There isn't a way to automatically obtain that information via the API. - __ {{DOC_SERVER_URL}}/Content/API/Concepts/apisigningkey.htm#five + __ https://docs.us-phoenix-1.oraclecloud.com/Content/API/Concepts/apisigningkey.htm#five :param str compartment_id: (required) @@ -1777,7 +1777,7 @@ def list_user_group_memberships(self, compartment_id, **kwargs): - You can set both the `userId` and `groupId` to determine if the specified user is in the specified group. If the answer is no, the response is an empty list. - __ {{DOC_SERVER_URL}}/Content/API/Concepts/apisigningkey.htm#five + __ https://docs.us-phoenix-1.oraclecloud.com/Content/API/Concepts/apisigningkey.htm#five :param str compartment_id: (required) @@ -1841,7 +1841,7 @@ def list_users(self, compartment_id, **kwargs): compartment ID (remember that the tenancy is simply the root compartment). See `Where to Get the Tenancy's OCID and User's OCID`__. - __ {{DOC_SERVER_URL}}/Content/API/Concepts/apisigningkey.htm#five + __ https://docs.us-phoenix-1.oraclecloud.com/Content/API/Concepts/apisigningkey.htm#five :param str compartment_id: (required) diff --git a/oraclebmc/identity/models/create_policy_details.py b/oraclebmc/identity/models/create_policy_details.py index a64fa86cbb..6cfbd9cf94 100644 --- a/oraclebmc/identity/models/create_policy_details.py +++ b/oraclebmc/identity/models/create_policy_details.py @@ -89,8 +89,8 @@ def statements(self): `How Policies Work`__ and `Common Policies`__. - __ {{DOC_SERVER_URL}}/Content/Identity/Concepts/policies.htm - __ {{DOC_SERVER_URL}}/Content/Identity/Concepts/commonpolicies.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/policies.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/commonpolicies.htm :return: The statements of this CreatePolicyDetails. @@ -106,8 +106,8 @@ def statements(self, statements): `How Policies Work`__ and `Common Policies`__. - __ {{DOC_SERVER_URL}}/Content/Identity/Concepts/policies.htm - __ {{DOC_SERVER_URL}}/Content/Identity/Concepts/commonpolicies.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/policies.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/commonpolicies.htm :param statements: The statements of this CreatePolicyDetails. diff --git a/oraclebmc/identity/models/update_policy_details.py b/oraclebmc/identity/models/update_policy_details.py index 120c6253f1..fa236e5064 100644 --- a/oraclebmc/identity/models/update_policy_details.py +++ b/oraclebmc/identity/models/update_policy_details.py @@ -57,8 +57,8 @@ def statements(self): `How Policies Work`__ and `Common Policies`__. - __ {{DOC_SERVER_URL}}/Content/Identity/Concepts/policies.htm - __ {{DOC_SERVER_URL}}/Content/Identity/Concepts/commonpolicies.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/policies.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/commonpolicies.htm :return: The statements of this UpdatePolicyDetails. @@ -74,8 +74,8 @@ def statements(self, statements): `How Policies Work`__ and `Common Policies`__. - __ {{DOC_SERVER_URL}}/Content/Identity/Concepts/policies.htm - __ {{DOC_SERVER_URL}}/Content/Identity/Concepts/commonpolicies.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/policies.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/commonpolicies.htm :param statements: The statements of this UpdatePolicyDetails. diff --git a/oraclebmc/object_storage/__init__.py b/oraclebmc/object_storage/__init__.py index 0b17c3e821..f24161356c 100644 --- a/oraclebmc/object_storage/__init__.py +++ b/oraclebmc/object_storage/__init__.py @@ -3,8 +3,10 @@ from __future__ import absolute_import - -from .object_storage_client import ObjectStorageClient +from .transfer.internal.multipart_object_assembler import MultipartObjectAssembler from . import models +from .object_storage_client import ObjectStorageClient +from .transfer.upload_manager import UploadManager -__all__ = ["ObjectStorageClient", "models"] +__all__ = ["ObjectStorageClient", "models", "MultipartObjectAssembler", + "UploadManager"] diff --git a/oraclebmc/object_storage/models/__init__.py b/oraclebmc/object_storage/models/__init__.py index 040a6172a1..b9e3ef6e62 100644 --- a/oraclebmc/object_storage/models/__init__.py +++ b/oraclebmc/object_storage/models/__init__.py @@ -5,17 +5,33 @@ from .bucket import Bucket from .bucket_summary import BucketSummary +from .commit_multipart_upload_details import CommitMultipartUploadDetails +from .commit_multipart_upload_part_details import CommitMultipartUploadPartDetails from .create_bucket_details import CreateBucketDetails +from .create_multipart_upload_details import CreateMultipartUploadDetails +from .create_preauthenticated_request_details import CreatePreauthenticatedRequestDetails from .list_objects import ListObjects +from .multipart_upload import MultipartUpload +from .multipart_upload_part_summary import MultipartUploadPartSummary from .object_summary import ObjectSummary +from .preauthenticated_request import PreauthenticatedRequest +from .preauthenticated_request_summary import PreauthenticatedRequestSummary from .update_bucket_details import UpdateBucketDetails # Maps type names to classes for object_storage services. object_storage_type_mapping = { "Bucket": Bucket, "BucketSummary": BucketSummary, + "CommitMultipartUploadDetails": CommitMultipartUploadDetails, + "CommitMultipartUploadPartDetails": CommitMultipartUploadPartDetails, "CreateBucketDetails": CreateBucketDetails, + "CreateMultipartUploadDetails": CreateMultipartUploadDetails, + "CreatePreauthenticatedRequestDetails": CreatePreauthenticatedRequestDetails, "ListObjects": ListObjects, + "MultipartUpload": MultipartUpload, + "MultipartUploadPartSummary": MultipartUploadPartSummary, "ObjectSummary": ObjectSummary, + "PreauthenticatedRequest": PreauthenticatedRequest, + "PreauthenticatedRequestSummary": PreauthenticatedRequestSummary, "UpdateBucketDetails": UpdateBucketDetails } diff --git a/oraclebmc/object_storage/models/bucket.py b/oraclebmc/object_storage/models/bucket.py index ca903b3b38..6db1087a9b 100644 --- a/oraclebmc/object_storage/models/bucket.py +++ b/oraclebmc/object_storage/models/bucket.py @@ -16,7 +16,8 @@ def __init__(self): 'metadata': 'dict(str, str)', 'created_by': 'str', 'time_created': 'datetime', - 'etag': 'str' + 'etag': 'str', + 'public_access_type': 'str' } self.attribute_map = { @@ -26,7 +27,8 @@ def __init__(self): 'metadata': 'metadata', 'created_by': 'createdBy', 'time_created': 'timeCreated', - 'etag': 'etag' + 'etag': 'etag', + 'public_access_type': 'publicAccessType' } self._namespace = None @@ -36,6 +38,7 @@ def __init__(self): self._created_by = None self._time_created = None self._etag = None + self._public_access_type = None @property def namespace(self): @@ -205,6 +208,42 @@ def etag(self, etag): """ self._etag = etag + @property + def public_access_type(self): + """ + Gets the public_access_type of this Bucket. + The type of public access available on this bucket. Allows authenticated caller to access the bucket or + contents of this bucket. By default a bucket is set to NoPublicAccess. It is treated as NoPublicAccess + when this value is not specified. When the type is NoPublicAccess the bucket does not allow any public access. + When the type is ObjectRead the bucket allows public access to the GetObject, HeadObject, ListObjects. + + Allowed values for this property are: "NoPublicAccess", "ObjectRead", 'UNKNOWN_ENUM_VALUE'. + Any unrecognized values returned by a service will be mapped to 'UNKNOWN_ENUM_VALUE'. + + + :return: The public_access_type of this Bucket. + :rtype: str + """ + return self._public_access_type + + @public_access_type.setter + def public_access_type(self, public_access_type): + """ + Sets the public_access_type of this Bucket. + The type of public access available on this bucket. Allows authenticated caller to access the bucket or + contents of this bucket. By default a bucket is set to NoPublicAccess. It is treated as NoPublicAccess + when this value is not specified. When the type is NoPublicAccess the bucket does not allow any public access. + When the type is ObjectRead the bucket allows public access to the GetObject, HeadObject, ListObjects. + + + :param public_access_type: The public_access_type of this Bucket. + :type: str + """ + allowed_values = ["NoPublicAccess", "ObjectRead"] + if public_access_type not in allowed_values: + public_access_type = 'UNKNOWN_ENUM_VALUE' + self._public_access_type = public_access_type + def __repr__(self): return formatted_flat_dict(self) diff --git a/oraclebmc/object_storage/models/commit_multipart_upload_details.py b/oraclebmc/object_storage/models/commit_multipart_upload_details.py new file mode 100644 index 0000000000..59d398cb3b --- /dev/null +++ b/oraclebmc/object_storage/models/commit_multipart_upload_details.py @@ -0,0 +1,85 @@ +# coding: utf-8 +# Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. + + +from ...util import formatted_flat_dict + + +class CommitMultipartUploadDetails(object): + + def __init__(self): + + self.swagger_types = { + 'parts_to_commit': 'list[CommitMultipartUploadPartDetails]', + 'parts_to_exclude': 'list[int]' + } + + self.attribute_map = { + 'parts_to_commit': 'partsToCommit', + 'parts_to_exclude': 'partsToExclude' + } + + self._parts_to_commit = None + self._parts_to_exclude = None + + @property + def parts_to_commit(self): + """ + Gets the parts_to_commit of this CommitMultipartUploadDetails. + The part numbers and ETags for the parts to be committed. + + + :return: The parts_to_commit of this CommitMultipartUploadDetails. + :rtype: list[CommitMultipartUploadPartDetails] + """ + return self._parts_to_commit + + @parts_to_commit.setter + def parts_to_commit(self, parts_to_commit): + """ + Sets the parts_to_commit of this CommitMultipartUploadDetails. + The part numbers and ETags for the parts to be committed. + + + :param parts_to_commit: The parts_to_commit of this CommitMultipartUploadDetails. + :type: list[CommitMultipartUploadPartDetails] + """ + self._parts_to_commit = parts_to_commit + + @property + def parts_to_exclude(self): + """ + Gets the parts_to_exclude of this CommitMultipartUploadDetails. + The part numbers for the parts to be excluded from the completed object. + Each part created for this upload must be in either partsToExclude or partsToCommit, but cannot be in both. + + + :return: The parts_to_exclude of this CommitMultipartUploadDetails. + :rtype: list[int] + """ + return self._parts_to_exclude + + @parts_to_exclude.setter + def parts_to_exclude(self, parts_to_exclude): + """ + Sets the parts_to_exclude of this CommitMultipartUploadDetails. + The part numbers for the parts to be excluded from the completed object. + Each part created for this upload must be in either partsToExclude or partsToCommit, but cannot be in both. + + + :param parts_to_exclude: The parts_to_exclude of this CommitMultipartUploadDetails. + :type: list[int] + """ + self._parts_to_exclude = parts_to_exclude + + def __repr__(self): + return formatted_flat_dict(self) + + def __eq__(self, other): + if other is None: + return False + + return self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not self == other diff --git a/oraclebmc/object_storage/models/commit_multipart_upload_part_details.py b/oraclebmc/object_storage/models/commit_multipart_upload_part_details.py new file mode 100644 index 0000000000..26849eb511 --- /dev/null +++ b/oraclebmc/object_storage/models/commit_multipart_upload_part_details.py @@ -0,0 +1,83 @@ +# coding: utf-8 +# Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. + + +from ...util import formatted_flat_dict + + +class CommitMultipartUploadPartDetails(object): + + def __init__(self): + + self.swagger_types = { + 'part_num': 'int', + 'etag': 'str' + } + + self.attribute_map = { + 'part_num': 'partNum', + 'etag': 'etag' + } + + self._part_num = None + self._etag = None + + @property + def part_num(self): + """ + Gets the part_num of this CommitMultipartUploadPartDetails. + The part number for this part. + + + :return: The part_num of this CommitMultipartUploadPartDetails. + :rtype: int + """ + return self._part_num + + @part_num.setter + def part_num(self, part_num): + """ + Sets the part_num of this CommitMultipartUploadPartDetails. + The part number for this part. + + + :param part_num: The part_num of this CommitMultipartUploadPartDetails. + :type: int + """ + self._part_num = part_num + + @property + def etag(self): + """ + Gets the etag of this CommitMultipartUploadPartDetails. + The ETag returned when this part was uploaded. + + + :return: The etag of this CommitMultipartUploadPartDetails. + :rtype: str + """ + return self._etag + + @etag.setter + def etag(self, etag): + """ + Sets the etag of this CommitMultipartUploadPartDetails. + The ETag returned when this part was uploaded. + + + :param etag: The etag of this CommitMultipartUploadPartDetails. + :type: str + """ + self._etag = etag + + def __repr__(self): + return formatted_flat_dict(self) + + def __eq__(self, other): + if other is None: + return False + + return self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not self == other diff --git a/oraclebmc/object_storage/models/create_bucket_details.py b/oraclebmc/object_storage/models/create_bucket_details.py index 49b9ff0e38..957676116a 100644 --- a/oraclebmc/object_storage/models/create_bucket_details.py +++ b/oraclebmc/object_storage/models/create_bucket_details.py @@ -12,25 +12,28 @@ def __init__(self): self.swagger_types = { 'name': 'str', 'compartment_id': 'str', - 'metadata': 'dict(str, str)' + 'metadata': 'dict(str, str)', + 'public_access_type': 'str' } self.attribute_map = { 'name': 'name', 'compartment_id': 'compartmentId', - 'metadata': 'metadata' + 'metadata': 'metadata', + 'public_access_type': 'publicAccessType' } self._name = None self._compartment_id = None self._metadata = None + self._public_access_type = None @property def name(self): """ Gets the name of this CreateBucketDetails. - The name of the bucket. Valid characters are letters (upper or lower case), - numbers and dashes. Bucket names must be unique within the namespace. + The name of the bucket. Valid characters are uppercase or lowercase letters, + numbers, and dashes. Bucket names must be unique within the namespace. :return: The name of this CreateBucketDetails. @@ -42,8 +45,8 @@ def name(self): def name(self, name): """ Sets the name of this CreateBucketDetails. - The name of the bucket. Valid characters are letters (upper or lower case), - numbers and dashes. Bucket names must be unique within the namespace. + The name of the bucket. Valid characters are uppercase or lowercase letters, + numbers, and dashes. Bucket names must be unique within the namespace. :param name: The name of this CreateBucketDetails. @@ -79,7 +82,7 @@ def compartment_id(self, compartment_id): def metadata(self): """ Gets the metadata of this CreateBucketDetails. - Arbitrary string keys and values for user-defined metadata. + Arbitrary string, up to 4KB, of keys and values for user-defined metadata. :return: The metadata of this CreateBucketDetails. @@ -91,7 +94,7 @@ def metadata(self): def metadata(self, metadata): """ Sets the metadata of this CreateBucketDetails. - Arbitrary string keys and values for user-defined metadata. + Arbitrary string, up to 4KB, of keys and values for user-defined metadata. :param metadata: The metadata of this CreateBucketDetails. @@ -99,6 +102,44 @@ def metadata(self, metadata): """ self._metadata = metadata + @property + def public_access_type(self): + """ + Gets the public_access_type of this CreateBucketDetails. + The type of public access available on this bucket. Allows authenticated caller to access the bucket or + contents of this bucket. By default a bucket is set to NoPublicAccess. It is treated as NoPublicAccess + when this value is not specified. When the type is NoPublicAccess the bucket does not allow any public access. + When the type is ObjectRead the bucket allows public access to the GetObject, HeadObject, ListObjects. + + Allowed values for this property are: "NoPublicAccess", "ObjectRead" + + + :return: The public_access_type of this CreateBucketDetails. + :rtype: str + """ + return self._public_access_type + + @public_access_type.setter + def public_access_type(self, public_access_type): + """ + Sets the public_access_type of this CreateBucketDetails. + The type of public access available on this bucket. Allows authenticated caller to access the bucket or + contents of this bucket. By default a bucket is set to NoPublicAccess. It is treated as NoPublicAccess + when this value is not specified. When the type is NoPublicAccess the bucket does not allow any public access. + When the type is ObjectRead the bucket allows public access to the GetObject, HeadObject, ListObjects. + + + :param public_access_type: The public_access_type of this CreateBucketDetails. + :type: str + """ + allowed_values = ["NoPublicAccess", "ObjectRead"] + if public_access_type not in allowed_values: + raise ValueError( + "Invalid value for `public_access_type`, must be one of {0}" + .format(allowed_values) + ) + self._public_access_type = public_access_type + def __repr__(self): return formatted_flat_dict(self) diff --git a/oraclebmc/object_storage/models/create_multipart_upload_details.py b/oraclebmc/object_storage/models/create_multipart_upload_details.py new file mode 100644 index 0000000000..ccbd0a6fa4 --- /dev/null +++ b/oraclebmc/object_storage/models/create_multipart_upload_details.py @@ -0,0 +1,166 @@ +# coding: utf-8 +# Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. + + +from ...util import formatted_flat_dict + + +class CreateMultipartUploadDetails(object): + + def __init__(self): + + self.swagger_types = { + 'object': 'str', + 'content_type': 'str', + 'content_language': 'str', + 'content_encoding': 'str', + 'metadata': 'dict(str, str)' + } + + self.attribute_map = { + 'object': 'object', + 'content_type': 'contentType', + 'content_language': 'contentLanguage', + 'content_encoding': 'contentEncoding', + 'metadata': 'metadata' + } + + self._object = None + self._content_type = None + self._content_language = None + self._content_encoding = None + self._metadata = None + + @property + def object(self): + """ + Gets the object of this CreateMultipartUploadDetails. + the name of the object to which this multi-part upload is targetted. + + + :return: The object of this CreateMultipartUploadDetails. + :rtype: str + """ + return self._object + + @object.setter + def object(self, object): + """ + Sets the object of this CreateMultipartUploadDetails. + the name of the object to which this multi-part upload is targetted. + + + :param object: The object of this CreateMultipartUploadDetails. + :type: str + """ + self._object = object + + @property + def content_type(self): + """ + Gets the content_type of this CreateMultipartUploadDetails. + the content type of the object to upload. + + + :return: The content_type of this CreateMultipartUploadDetails. + :rtype: str + """ + return self._content_type + + @content_type.setter + def content_type(self, content_type): + """ + Sets the content_type of this CreateMultipartUploadDetails. + the content type of the object to upload. + + + :param content_type: The content_type of this CreateMultipartUploadDetails. + :type: str + """ + self._content_type = content_type + + @property + def content_language(self): + """ + Gets the content_language of this CreateMultipartUploadDetails. + the content language of the object to upload. + + + :return: The content_language of this CreateMultipartUploadDetails. + :rtype: str + """ + return self._content_language + + @content_language.setter + def content_language(self, content_language): + """ + Sets the content_language of this CreateMultipartUploadDetails. + the content language of the object to upload. + + + :param content_language: The content_language of this CreateMultipartUploadDetails. + :type: str + """ + self._content_language = content_language + + @property + def content_encoding(self): + """ + Gets the content_encoding of this CreateMultipartUploadDetails. + the content encoding of the object to upload. + + + :return: The content_encoding of this CreateMultipartUploadDetails. + :rtype: str + """ + return self._content_encoding + + @content_encoding.setter + def content_encoding(self, content_encoding): + """ + Sets the content_encoding of this CreateMultipartUploadDetails. + the content encoding of the object to upload. + + + :param content_encoding: The content_encoding of this CreateMultipartUploadDetails. + :type: str + """ + self._content_encoding = content_encoding + + @property + def metadata(self): + """ + Gets the metadata of this CreateMultipartUploadDetails. + Arbitrary string keys and values for the user-defined metadata for the object. + Keys must be in \"opc-meta-*\" format. + + + :return: The metadata of this CreateMultipartUploadDetails. + :rtype: dict(str, str) + """ + return self._metadata + + @metadata.setter + def metadata(self, metadata): + """ + Sets the metadata of this CreateMultipartUploadDetails. + Arbitrary string keys and values for the user-defined metadata for the object. + Keys must be in \"opc-meta-*\" format. + + + :param metadata: The metadata of this CreateMultipartUploadDetails. + :type: dict(str, str) + """ + self._metadata = metadata + + def __repr__(self): + return formatted_flat_dict(self) + + def __eq__(self, other): + if other is None: + return False + + return self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not self == other diff --git a/oraclebmc/object_storage/models/create_preauthenticated_request_details.py b/oraclebmc/object_storage/models/create_preauthenticated_request_details.py new file mode 100644 index 0000000000..1ec0dfdde7 --- /dev/null +++ b/oraclebmc/object_storage/models/create_preauthenticated_request_details.py @@ -0,0 +1,151 @@ +# coding: utf-8 +# Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. + + +from ...util import formatted_flat_dict + + +class CreatePreauthenticatedRequestDetails(object): + + def __init__(self): + + self.swagger_types = { + 'name': 'str', + 'object_name': 'str', + 'access_type': 'str', + 'time_expires': 'datetime' + } + + self.attribute_map = { + 'name': 'name', + 'object_name': 'objectName', + 'access_type': 'accessType', + 'time_expires': 'timeExpires' + } + + self._name = None + self._object_name = None + self._access_type = None + self._time_expires = None + + @property + def name(self): + """ + Gets the name of this CreatePreauthenticatedRequestDetails. + user specified name for pre-authenticated request. Helpful for management purposes. + + + :return: The name of this CreatePreauthenticatedRequestDetails. + :rtype: str + """ + return self._name + + @name.setter + def name(self, name): + """ + Sets the name of this CreatePreauthenticatedRequestDetails. + user specified name for pre-authenticated request. Helpful for management purposes. + + + :param name: The name of this CreatePreauthenticatedRequestDetails. + :type: str + """ + self._name = name + + @property + def object_name(self): + """ + Gets the object_name of this CreatePreauthenticatedRequestDetails. + Name of object that is being granted access to by the pre-authenticated request. This can be null and that would mean that the pre-authenticated request is granting access to the entire bucket + + + :return: The object_name of this CreatePreauthenticatedRequestDetails. + :rtype: str + """ + return self._object_name + + @object_name.setter + def object_name(self, object_name): + """ + Sets the object_name of this CreatePreauthenticatedRequestDetails. + Name of object that is being granted access to by the pre-authenticated request. This can be null and that would mean that the pre-authenticated request is granting access to the entire bucket + + + :param object_name: The object_name of this CreatePreauthenticatedRequestDetails. + :type: str + """ + self._object_name = object_name + + @property + def access_type(self): + """ + Gets the access_type of this CreatePreauthenticatedRequestDetails. + the operation that can be performed on this resource e.g PUT or GET. + + Allowed values for this property are: "ObjectRead", "ObjectWrite", "ObjectReadWrite", "AnyObjectWrite" + + + :return: The access_type of this CreatePreauthenticatedRequestDetails. + :rtype: str + """ + return self._access_type + + @access_type.setter + def access_type(self, access_type): + """ + Sets the access_type of this CreatePreauthenticatedRequestDetails. + the operation that can be performed on this resource e.g PUT or GET. + + + :param access_type: The access_type of this CreatePreauthenticatedRequestDetails. + :type: str + """ + allowed_values = ["ObjectRead", "ObjectWrite", "ObjectReadWrite", "AnyObjectWrite"] + if access_type not in allowed_values: + raise ValueError( + "Invalid value for `access_type`, must be one of {0}" + .format(allowed_values) + ) + self._access_type = access_type + + @property + def time_expires(self): + """ + Gets the time_expires of this CreatePreauthenticatedRequestDetails. + The expiration date after which the pre-authenticated request will no longer be valid per spec + `RFC 3339`__ + + __ https://tools.ietf.org/rfc/rfc3339 + + + :return: The time_expires of this CreatePreauthenticatedRequestDetails. + :rtype: datetime + """ + return self._time_expires + + @time_expires.setter + def time_expires(self, time_expires): + """ + Sets the time_expires of this CreatePreauthenticatedRequestDetails. + The expiration date after which the pre-authenticated request will no longer be valid per spec + `RFC 3339`__ + + __ https://tools.ietf.org/rfc/rfc3339 + + + :param time_expires: The time_expires of this CreatePreauthenticatedRequestDetails. + :type: datetime + """ + self._time_expires = time_expires + + def __repr__(self): + return formatted_flat_dict(self) + + def __eq__(self, other): + if other is None: + return False + + return self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not self == other diff --git a/oraclebmc/object_storage/models/list_objects.py b/oraclebmc/object_storage/models/list_objects.py index 0a82adda7b..2c51485ce7 100644 --- a/oraclebmc/object_storage/models/list_objects.py +++ b/oraclebmc/object_storage/models/list_objects.py @@ -29,6 +29,8 @@ def __init__(self): def objects(self): """ Gets the objects of this ListObjects. + An array of object summaries. + :return: The objects of this ListObjects. :rtype: list[ObjectSummary] @@ -39,6 +41,8 @@ def objects(self): def objects(self, objects): """ Sets the objects of this ListObjects. + An array of object summaries. + :param objects: The objects of this ListObjects. :type: list[ObjectSummary] @@ -49,6 +53,8 @@ def objects(self, objects): def prefixes(self): """ Gets the prefixes of this ListObjects. + Prefixes that are common to the results returned by the request if the request specified a delimiter. + :return: The prefixes of this ListObjects. :rtype: list[str] @@ -59,6 +65,8 @@ def prefixes(self): def prefixes(self, prefixes): """ Sets the prefixes of this ListObjects. + Prefixes that are common to the results returned by the request if the request specified a delimiter. + :param prefixes: The prefixes of this ListObjects. :type: list[str] @@ -69,8 +77,8 @@ def prefixes(self, prefixes): def next_start_with(self): """ Gets the next_start_with of this ListObjects. - The name of the object to be used in startWith parameter to obtain next page of - a truncated list objects response. + The name of the object to use in the 'startWith' parameter to obtain the next page of + a truncated ListObjects response. :return: The next_start_with of this ListObjects. @@ -82,8 +90,8 @@ def next_start_with(self): def next_start_with(self, next_start_with): """ Sets the next_start_with of this ListObjects. - The name of the object to be used in startWith parameter to obtain next page of - a truncated list objects response. + The name of the object to use in the 'startWith' parameter to obtain the next page of + a truncated ListObjects response. :param next_start_with: The next_start_with of this ListObjects. diff --git a/oraclebmc/object_storage/models/multipart_upload.py b/oraclebmc/object_storage/models/multipart_upload.py new file mode 100644 index 0000000000..b1c2ff8a22 --- /dev/null +++ b/oraclebmc/object_storage/models/multipart_upload.py @@ -0,0 +1,164 @@ +# coding: utf-8 +# Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. + + +from ...util import formatted_flat_dict + + +class MultipartUpload(object): + + def __init__(self): + + self.swagger_types = { + 'namespace': 'str', + 'bucket': 'str', + 'object': 'str', + 'upload_id': 'str', + 'time_created': 'datetime' + } + + self.attribute_map = { + 'namespace': 'namespace', + 'bucket': 'bucket', + 'object': 'object', + 'upload_id': 'uploadId', + 'time_created': 'timeCreated' + } + + self._namespace = None + self._bucket = None + self._object = None + self._upload_id = None + self._time_created = None + + @property + def namespace(self): + """ + Gets the namespace of this MultipartUpload. + The namespace in which the in-progress multipart upload is stored. + + + :return: The namespace of this MultipartUpload. + :rtype: str + """ + return self._namespace + + @namespace.setter + def namespace(self, namespace): + """ + Sets the namespace of this MultipartUpload. + The namespace in which the in-progress multipart upload is stored. + + + :param namespace: The namespace of this MultipartUpload. + :type: str + """ + self._namespace = namespace + + @property + def bucket(self): + """ + Gets the bucket of this MultipartUpload. + The bucket in which the in-progress multipart upload is stored. + + + :return: The bucket of this MultipartUpload. + :rtype: str + """ + return self._bucket + + @bucket.setter + def bucket(self, bucket): + """ + Sets the bucket of this MultipartUpload. + The bucket in which the in-progress multipart upload is stored. + + + :param bucket: The bucket of this MultipartUpload. + :type: str + """ + self._bucket = bucket + + @property + def object(self): + """ + Gets the object of this MultipartUpload. + The object name of the in-progress multipart upload. + + + :return: The object of this MultipartUpload. + :rtype: str + """ + return self._object + + @object.setter + def object(self, object): + """ + Sets the object of this MultipartUpload. + The object name of the in-progress multipart upload. + + + :param object: The object of this MultipartUpload. + :type: str + """ + self._object = object + + @property + def upload_id(self): + """ + Gets the upload_id of this MultipartUpload. + The unique identifier for the in-progress multipart upload. + + + :return: The upload_id of this MultipartUpload. + :rtype: str + """ + return self._upload_id + + @upload_id.setter + def upload_id(self, upload_id): + """ + Sets the upload_id of this MultipartUpload. + The unique identifier for the in-progress multipart upload. + + + :param upload_id: The upload_id of this MultipartUpload. + :type: str + """ + self._upload_id = upload_id + + @property + def time_created(self): + """ + Gets the time_created of this MultipartUpload. + The date and time when the upload was created. + + + :return: The time_created of this MultipartUpload. + :rtype: datetime + """ + return self._time_created + + @time_created.setter + def time_created(self, time_created): + """ + Sets the time_created of this MultipartUpload. + The date and time when the upload was created. + + + :param time_created: The time_created of this MultipartUpload. + :type: datetime + """ + self._time_created = time_created + + def __repr__(self): + return formatted_flat_dict(self) + + def __eq__(self, other): + if other is None: + return False + + return self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not self == other diff --git a/oraclebmc/object_storage/models/multipart_upload_part_summary.py b/oraclebmc/object_storage/models/multipart_upload_part_summary.py new file mode 100644 index 0000000000..af18a7e0cf --- /dev/null +++ b/oraclebmc/object_storage/models/multipart_upload_part_summary.py @@ -0,0 +1,137 @@ +# coding: utf-8 +# Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. + + +from ...util import formatted_flat_dict + + +class MultipartUploadPartSummary(object): + + def __init__(self): + + self.swagger_types = { + 'etag': 'str', + 'md5': 'str', + 'size': 'int', + 'part_number': 'int' + } + + self.attribute_map = { + 'etag': 'etag', + 'md5': 'md5', + 'size': 'size', + 'part_number': 'partNumber' + } + + self._etag = None + self._md5 = None + self._size = None + self._part_number = None + + @property + def etag(self): + """ + Gets the etag of this MultipartUploadPartSummary. + the current entity tag for the part. + + + :return: The etag of this MultipartUploadPartSummary. + :rtype: str + """ + return self._etag + + @etag.setter + def etag(self, etag): + """ + Sets the etag of this MultipartUploadPartSummary. + the current entity tag for the part. + + + :param etag: The etag of this MultipartUploadPartSummary. + :type: str + """ + self._etag = etag + + @property + def md5(self): + """ + Gets the md5 of this MultipartUploadPartSummary. + the MD5 hash of the bytes of the part. + + + :return: The md5 of this MultipartUploadPartSummary. + :rtype: str + """ + return self._md5 + + @md5.setter + def md5(self, md5): + """ + Sets the md5 of this MultipartUploadPartSummary. + the MD5 hash of the bytes of the part. + + + :param md5: The md5 of this MultipartUploadPartSummary. + :type: str + """ + self._md5 = md5 + + @property + def size(self): + """ + Gets the size of this MultipartUploadPartSummary. + the size of the part in bytes. + + + :return: The size of this MultipartUploadPartSummary. + :rtype: int + """ + return self._size + + @size.setter + def size(self, size): + """ + Sets the size of this MultipartUploadPartSummary. + the size of the part in bytes. + + + :param size: The size of this MultipartUploadPartSummary. + :type: int + """ + self._size = size + + @property + def part_number(self): + """ + Gets the part_number of this MultipartUploadPartSummary. + the part number for this part. + + + :return: The part_number of this MultipartUploadPartSummary. + :rtype: int + """ + return self._part_number + + @part_number.setter + def part_number(self, part_number): + """ + Sets the part_number of this MultipartUploadPartSummary. + the part number for this part. + + + :param part_number: The part_number of this MultipartUploadPartSummary. + :type: int + """ + self._part_number = part_number + + def __repr__(self): + return formatted_flat_dict(self) + + def __eq__(self, other): + if other is None: + return False + + return self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not self == other diff --git a/oraclebmc/object_storage/models/object_summary.py b/oraclebmc/object_storage/models/object_summary.py index 15152f1575..435b420073 100644 --- a/oraclebmc/object_storage/models/object_summary.py +++ b/oraclebmc/object_storage/models/object_summary.py @@ -80,7 +80,7 @@ def size(self, size): def md5(self): """ Gets the md5 of this ObjectSummary. - Base64 encoded MD5 hash of the object data. + Base64-encoded MD5 hash of the object data. :return: The md5 of this ObjectSummary. @@ -92,7 +92,7 @@ def md5(self): def md5(self, md5): """ Sets the md5 of this ObjectSummary. - Base64 encoded MD5 hash of the object data. + Base64-encoded MD5 hash of the object data. :param md5: The md5 of this ObjectSummary. diff --git a/oraclebmc/object_storage/models/preauthenticated_request.py b/oraclebmc/object_storage/models/preauthenticated_request.py new file mode 100644 index 0000000000..3f99b72f7e --- /dev/null +++ b/oraclebmc/object_storage/models/preauthenticated_request.py @@ -0,0 +1,236 @@ +# coding: utf-8 +# Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. + + +from ...util import formatted_flat_dict + + +class PreauthenticatedRequest(object): + + def __init__(self): + + self.swagger_types = { + 'id': 'str', + 'name': 'str', + 'access_uri': 'str', + 'object_name': 'str', + 'access_type': 'str', + 'time_expires': 'datetime', + 'time_created': 'datetime' + } + + self.attribute_map = { + 'id': 'id', + 'name': 'name', + 'access_uri': 'accessUri', + 'object_name': 'objectName', + 'access_type': 'accessType', + 'time_expires': 'timeExpires', + 'time_created': 'timeCreated' + } + + self._id = None + self._name = None + self._access_uri = None + self._object_name = None + self._access_type = None + self._time_expires = None + self._time_created = None + + @property + def id(self): + """ + Gets the id of this PreauthenticatedRequest. + the unique identifier to use when directly addressing the pre-authenticated request + + + :return: The id of this PreauthenticatedRequest. + :rtype: str + """ + return self._id + + @id.setter + def id(self, id): + """ + Sets the id of this PreauthenticatedRequest. + the unique identifier to use when directly addressing the pre-authenticated request + + + :param id: The id of this PreauthenticatedRequest. + :type: str + """ + self._id = id + + @property + def name(self): + """ + Gets the name of this PreauthenticatedRequest. + the user supplied name of the pre-authenticated request. + + + :return: The name of this PreauthenticatedRequest. + :rtype: str + """ + return self._name + + @name.setter + def name(self, name): + """ + Sets the name of this PreauthenticatedRequest. + the user supplied name of the pre-authenticated request. + + + :param name: The name of this PreauthenticatedRequest. + :type: str + """ + self._name = name + + @property + def access_uri(self): + """ + Gets the access_uri of this PreauthenticatedRequest. + the uri to embed in the url when using the pre-authenticated request. + + + :return: The access_uri of this PreauthenticatedRequest. + :rtype: str + """ + return self._access_uri + + @access_uri.setter + def access_uri(self, access_uri): + """ + Sets the access_uri of this PreauthenticatedRequest. + the uri to embed in the url when using the pre-authenticated request. + + + :param access_uri: The access_uri of this PreauthenticatedRequest. + :type: str + """ + self._access_uri = access_uri + + @property + def object_name(self): + """ + Gets the object_name of this PreauthenticatedRequest. + Name of object that is being granted access to by the pre-authenticated request. This can be null and that would mean that the pre-authenticated request is granting access to the entire bucket + + + :return: The object_name of this PreauthenticatedRequest. + :rtype: str + """ + return self._object_name + + @object_name.setter + def object_name(self, object_name): + """ + Sets the object_name of this PreauthenticatedRequest. + Name of object that is being granted access to by the pre-authenticated request. This can be null and that would mean that the pre-authenticated request is granting access to the entire bucket + + + :param object_name: The object_name of this PreauthenticatedRequest. + :type: str + """ + self._object_name = object_name + + @property + def access_type(self): + """ + Gets the access_type of this PreauthenticatedRequest. + the operation that can be performed on this resource e.g PUT or GET. + + Allowed values for this property are: "ObjectRead", "ObjectWrite", "ObjectReadWrite", "AnyObjectWrite", 'UNKNOWN_ENUM_VALUE'. + Any unrecognized values returned by a service will be mapped to 'UNKNOWN_ENUM_VALUE'. + + + :return: The access_type of this PreauthenticatedRequest. + :rtype: str + """ + return self._access_type + + @access_type.setter + def access_type(self, access_type): + """ + Sets the access_type of this PreauthenticatedRequest. + the operation that can be performed on this resource e.g PUT or GET. + + + :param access_type: The access_type of this PreauthenticatedRequest. + :type: str + """ + allowed_values = ["ObjectRead", "ObjectWrite", "ObjectReadWrite", "AnyObjectWrite"] + if access_type not in allowed_values: + access_type = 'UNKNOWN_ENUM_VALUE' + self._access_type = access_type + + @property + def time_expires(self): + """ + Gets the time_expires of this PreauthenticatedRequest. + the expiration date after which the pre authenticated request will no longer be valid as per spec + `RFC 3339`__ + + __ https://tools.ietf.org/rfc/rfc3339 + + + :return: The time_expires of this PreauthenticatedRequest. + :rtype: datetime + """ + return self._time_expires + + @time_expires.setter + def time_expires(self, time_expires): + """ + Sets the time_expires of this PreauthenticatedRequest. + the expiration date after which the pre authenticated request will no longer be valid as per spec + `RFC 3339`__ + + __ https://tools.ietf.org/rfc/rfc3339 + + + :param time_expires: The time_expires of this PreauthenticatedRequest. + :type: datetime + """ + self._time_expires = time_expires + + @property + def time_created(self): + """ + Gets the time_created of this PreauthenticatedRequest. + the date when the pre-authenticated request was created as per spec + `RFC 3339`__ + + __ https://tools.ietf.org/rfc/rfc3339 + + + :return: The time_created of this PreauthenticatedRequest. + :rtype: datetime + """ + return self._time_created + + @time_created.setter + def time_created(self, time_created): + """ + Sets the time_created of this PreauthenticatedRequest. + the date when the pre-authenticated request was created as per spec + `RFC 3339`__ + + __ https://tools.ietf.org/rfc/rfc3339 + + + :param time_created: The time_created of this PreauthenticatedRequest. + :type: datetime + """ + self._time_created = time_created + + def __repr__(self): + return formatted_flat_dict(self) + + def __eq__(self, other): + if other is None: + return False + + return self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not self == other diff --git a/oraclebmc/object_storage/models/preauthenticated_request_summary.py b/oraclebmc/object_storage/models/preauthenticated_request_summary.py new file mode 100644 index 0000000000..bdf95917c9 --- /dev/null +++ b/oraclebmc/object_storage/models/preauthenticated_request_summary.py @@ -0,0 +1,209 @@ +# coding: utf-8 +# Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. + + +from ...util import formatted_flat_dict + + +class PreauthenticatedRequestSummary(object): + + def __init__(self): + + self.swagger_types = { + 'id': 'str', + 'name': 'str', + 'object_name': 'str', + 'access_type': 'str', + 'time_expires': 'datetime', + 'time_created': 'datetime' + } + + self.attribute_map = { + 'id': 'id', + 'name': 'name', + 'object_name': 'objectName', + 'access_type': 'accessType', + 'time_expires': 'timeExpires', + 'time_created': 'timeCreated' + } + + self._id = None + self._name = None + self._object_name = None + self._access_type = None + self._time_expires = None + self._time_created = None + + @property + def id(self): + """ + Gets the id of this PreauthenticatedRequestSummary. + the unique identifier to use when directly addressing the pre-authenticated request + + + :return: The id of this PreauthenticatedRequestSummary. + :rtype: str + """ + return self._id + + @id.setter + def id(self, id): + """ + Sets the id of this PreauthenticatedRequestSummary. + the unique identifier to use when directly addressing the pre-authenticated request + + + :param id: The id of this PreauthenticatedRequestSummary. + :type: str + """ + self._id = id + + @property + def name(self): + """ + Gets the name of this PreauthenticatedRequestSummary. + the user supplied name of the pre-authenticated request + + + :return: The name of this PreauthenticatedRequestSummary. + :rtype: str + """ + return self._name + + @name.setter + def name(self, name): + """ + Sets the name of this PreauthenticatedRequestSummary. + the user supplied name of the pre-authenticated request + + + :param name: The name of this PreauthenticatedRequestSummary. + :type: str + """ + self._name = name + + @property + def object_name(self): + """ + Gets the object_name of this PreauthenticatedRequestSummary. + Name of object that is being granted access to by the pre-authenticated request. This can be null and that would mean that the pre-authenticated request is granting access to the entire bucket + + + :return: The object_name of this PreauthenticatedRequestSummary. + :rtype: str + """ + return self._object_name + + @object_name.setter + def object_name(self, object_name): + """ + Sets the object_name of this PreauthenticatedRequestSummary. + Name of object that is being granted access to by the pre-authenticated request. This can be null and that would mean that the pre-authenticated request is granting access to the entire bucket + + + :param object_name: The object_name of this PreauthenticatedRequestSummary. + :type: str + """ + self._object_name = object_name + + @property + def access_type(self): + """ + Gets the access_type of this PreauthenticatedRequestSummary. + the operation that can be performed on this resource e.g PUT or GET. + + Allowed values for this property are: "ObjectRead", "ObjectWrite", "ObjectReadWrite", "AnyObjectWrite", 'UNKNOWN_ENUM_VALUE'. + Any unrecognized values returned by a service will be mapped to 'UNKNOWN_ENUM_VALUE'. + + + :return: The access_type of this PreauthenticatedRequestSummary. + :rtype: str + """ + return self._access_type + + @access_type.setter + def access_type(self, access_type): + """ + Sets the access_type of this PreauthenticatedRequestSummary. + the operation that can be performed on this resource e.g PUT or GET. + + + :param access_type: The access_type of this PreauthenticatedRequestSummary. + :type: str + """ + allowed_values = ["ObjectRead", "ObjectWrite", "ObjectReadWrite", "AnyObjectWrite"] + if access_type not in allowed_values: + access_type = 'UNKNOWN_ENUM_VALUE' + self._access_type = access_type + + @property + def time_expires(self): + """ + Gets the time_expires of this PreauthenticatedRequestSummary. + the expiration date after which the pre authenticated request will no longer be valid as per spec + `RFC 3339`__ + + __ https://tools.ietf.org/rfc/rfc3339 + + + :return: The time_expires of this PreauthenticatedRequestSummary. + :rtype: datetime + """ + return self._time_expires + + @time_expires.setter + def time_expires(self, time_expires): + """ + Sets the time_expires of this PreauthenticatedRequestSummary. + the expiration date after which the pre authenticated request will no longer be valid as per spec + `RFC 3339`__ + + __ https://tools.ietf.org/rfc/rfc3339 + + + :param time_expires: The time_expires of this PreauthenticatedRequestSummary. + :type: datetime + """ + self._time_expires = time_expires + + @property + def time_created(self): + """ + Gets the time_created of this PreauthenticatedRequestSummary. + the date when the pre-authenticated request was created as per spec + `RFC 3339`__ + + __ https://tools.ietf.org/rfc/rfc3339 + + + :return: The time_created of this PreauthenticatedRequestSummary. + :rtype: datetime + """ + return self._time_created + + @time_created.setter + def time_created(self, time_created): + """ + Sets the time_created of this PreauthenticatedRequestSummary. + the date when the pre-authenticated request was created as per spec + `RFC 3339`__ + + __ https://tools.ietf.org/rfc/rfc3339 + + + :param time_created: The time_created of this PreauthenticatedRequestSummary. + :type: datetime + """ + self._time_created = time_created + + def __repr__(self): + return formatted_flat_dict(self) + + def __eq__(self, other): + if other is None: + return False + + return self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not self == other diff --git a/oraclebmc/object_storage/models/update_bucket_details.py b/oraclebmc/object_storage/models/update_bucket_details.py index 882d2d031d..d7c3d96ba2 100644 --- a/oraclebmc/object_storage/models/update_bucket_details.py +++ b/oraclebmc/object_storage/models/update_bucket_details.py @@ -12,18 +12,21 @@ def __init__(self): self.swagger_types = { 'namespace': 'str', 'name': 'str', - 'metadata': 'dict(str, str)' + 'metadata': 'dict(str, str)', + 'public_access_type': 'str' } self.attribute_map = { 'namespace': 'namespace', 'name': 'name', - 'metadata': 'metadata' + 'metadata': 'metadata', + 'public_access_type': 'publicAccessType' } self._namespace = None self._name = None self._metadata = None + self._public_access_type = None @property def namespace(self): @@ -77,7 +80,7 @@ def name(self, name): def metadata(self): """ Gets the metadata of this UpdateBucketDetails. - Arbitrary string keys and values for the user-defined metadata. + Arbitrary string, up to 4KB, of keys and values for user-defined metadata. :return: The metadata of this UpdateBucketDetails. @@ -89,7 +92,7 @@ def metadata(self): def metadata(self, metadata): """ Sets the metadata of this UpdateBucketDetails. - Arbitrary string keys and values for the user-defined metadata. + Arbitrary string, up to 4KB, of keys and values for user-defined metadata. :param metadata: The metadata of this UpdateBucketDetails. @@ -97,6 +100,44 @@ def metadata(self, metadata): """ self._metadata = metadata + @property + def public_access_type(self): + """ + Gets the public_access_type of this UpdateBucketDetails. + The type of public access available on this bucket. Allows authenticated caller to access the bucket or + contents of this bucket. By default a bucket is set to NoPublicAccess. It is treated as NoPublicAccess + when this value is not specified. When the type is NoPublicAccess the bucket does not allow any public access. + When the type is ObjectRead the bucket allows public access to the GetObject, HeadObject, ListObjects. + + Allowed values for this property are: "NoPublicAccess", "ObjectRead" + + + :return: The public_access_type of this UpdateBucketDetails. + :rtype: str + """ + return self._public_access_type + + @public_access_type.setter + def public_access_type(self, public_access_type): + """ + Sets the public_access_type of this UpdateBucketDetails. + The type of public access available on this bucket. Allows authenticated caller to access the bucket or + contents of this bucket. By default a bucket is set to NoPublicAccess. It is treated as NoPublicAccess + when this value is not specified. When the type is NoPublicAccess the bucket does not allow any public access. + When the type is ObjectRead the bucket allows public access to the GetObject, HeadObject, ListObjects. + + + :param public_access_type: The public_access_type of this UpdateBucketDetails. + :type: str + """ + allowed_values = ["NoPublicAccess", "ObjectRead"] + if public_access_type not in allowed_values: + raise ValueError( + "Invalid value for `public_access_type`, must be one of {0}" + .format(allowed_values) + ) + self._public_access_type = public_access_type + def __repr__(self): return formatted_flat_dict(self) diff --git a/oraclebmc/object_storage/object_storage_client.py b/oraclebmc/object_storage/object_storage_client.py index 957dd61efe..6fed57e6b2 100644 --- a/oraclebmc/object_storage/object_storage_client.py +++ b/oraclebmc/object_storage/object_storage_client.py @@ -26,16 +26,165 @@ def __init__(self, config): ) self.base_client = BaseClient("object_storage", config, signer, object_storage_type_mapping) + def abort_multipart_upload(self, namespace_name, bucket_name, object_name, upload_id, **kwargs): + """ + AbortMultipartUpload + Aborts an in-progress multipart upload and deletes all parts that have been uploaded. + + + :param str namespace_name: (required) + The top-level namespace used for the request. + + :param str bucket_name: (required) + The name of the bucket. + + Example: `my-new-bucket1` + + :param str object_name: (required) + The name of the object. + + Example: `test/object1.log` + + :param str upload_id: (required) + The upload ID for a multipart upload. + + :param str opc_client_request_id: (optional) + The client request ID for tracing. + + :return: A Response object with data of type None + :rtype: None + """ + resource_path = "/n/{namespaceName}/b/{bucketName}/u/{objectName}" + method = "DELETE" + + # Don't accept unknown kwargs + expected_kwargs = [ + "opc_client_request_id" + ] + extra_kwargs = [key for key in six.iterkeys(kwargs) if key not in expected_kwargs] + if extra_kwargs: + raise ValueError( + "abort_multipart_upload got unknown kwargs: {!r}".format(extra_kwargs)) + + path_params = { + "namespaceName": namespace_name, + "bucketName": bucket_name, + "objectName": object_name + } + path_params = {k: v for (k, v) in six.iteritems(path_params) if v is not missing} + + query_params = { + "uploadId": upload_id + } + query_params = {k: v for (k, v) in six.iteritems(query_params) if v is not missing} + + header_params = { + "accept": "application/json", + "content-type": "application/json", + "opc-client-request-id": kwargs.get("opc_client_request_id", missing) + } + header_params = {k: v for (k, v) in six.iteritems(header_params) if v is not missing} + + return self.base_client.call_api( + resource_path=resource_path, + method=method, + path_params=path_params, + query_params=query_params, + header_params=header_params) + + def commit_multipart_upload(self, namespace_name, bucket_name, object_name, upload_id, commit_multipart_upload_details, **kwargs): + """ + CommitMultipartUpload + Commits a multipart upload, which involves checking part numbers and ETags of the parts, to create an aggregate object. + + + :param str namespace_name: (required) + The top-level namespace used for the request. + + :param str bucket_name: (required) + The name of the bucket. + + Example: `my-new-bucket1` + + :param str object_name: (required) + The name of the object. + + Example: `test/object1.log` + + :param str upload_id: (required) + The upload ID for a multipart upload. + + :param CommitMultipartUploadDetails commit_multipart_upload_details: (required) + The part numbers and ETags for the parts you want to commit. + + :param str if_match: (optional) + The entity tag to match. For creating and committing a multipart upload to an object, this is the entity tag of the target object. + For uploading a part, this is the entity tag of the target part. + + :param str if_none_match: (optional) + The entity tag to avoid matching. The only valid value is \u2018*\u2019, which indicates that the request should fail if the object already exists. + For creating and committing a multipart upload, this is the entity tag of the target object. For uploading a part, this is the entity tag + of the target part. + + :param str opc_client_request_id: (optional) + The client request ID for tracing. + + :return: A Response object with data of type None + :rtype: None + """ + resource_path = "/n/{namespaceName}/b/{bucketName}/u/{objectName}" + method = "POST" + + # Don't accept unknown kwargs + expected_kwargs = [ + "if_match", + "if_none_match", + "opc_client_request_id" + ] + extra_kwargs = [key for key in six.iterkeys(kwargs) if key not in expected_kwargs] + if extra_kwargs: + raise ValueError( + "commit_multipart_upload got unknown kwargs: {!r}".format(extra_kwargs)) + + path_params = { + "namespaceName": namespace_name, + "bucketName": bucket_name, + "objectName": object_name + } + path_params = {k: v for (k, v) in six.iteritems(path_params) if v is not missing} + + query_params = { + "uploadId": upload_id + } + query_params = {k: v for (k, v) in six.iteritems(query_params) if v is not missing} + + header_params = { + "accept": "application/json", + "content-type": "application/json", + "if-match": kwargs.get("if_match", missing), + "if-none-match": kwargs.get("if_none_match", missing), + "opc-client-request-id": kwargs.get("opc_client_request_id", missing) + } + header_params = {k: v for (k, v) in six.iteritems(header_params) if v is not missing} + + return self.base_client.call_api( + resource_path=resource_path, + method=method, + path_params=path_params, + query_params=query_params, + header_params=header_params, + body=commit_multipart_upload_details) + def create_bucket(self, namespace_name, create_bucket_details, **kwargs): """ CreateBucket Creates a bucket in the given namespace with a bucket name and optional user-defined metadata. To use this and other API operations, you must be authorized in an IAM policy. If you're not authorized, - talk to an administrator. If you're an admin who needs to write policies to give users access, see + talk to an administrator. If you're an administrator who needs to write policies to give users access, see `Getting Started with Policies`__. - __ {{DOC_SERVER_URL}}/Content/Identity/Concepts/policygetstarted.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/policygetstarted.htm :param str namespace_name: (required) @@ -45,7 +194,7 @@ def create_bucket(self, namespace_name, create_bucket_details, **kwargs): Request object for creating a bucket. :param str opc_client_request_id: (optional) - The client request ID for tracing + The client request ID for tracing. :return: A Response object with data of type Bucket :rtype: Bucket @@ -82,10 +231,135 @@ def create_bucket(self, namespace_name, create_bucket_details, **kwargs): body=create_bucket_details, response_type="Bucket") + def create_multipart_upload(self, namespace_name, bucket_name, create_multipart_upload_details, **kwargs): + """ + CreateMultipartUpload + Starts a new multipart upload to a specific object in the given bucket in the given namespace. + + + :param str namespace_name: (required) + The top-level namespace used for the request. + + :param str bucket_name: (required) + The name of the bucket. + + Example: `my-new-bucket1` + + :param CreateMultipartUploadDetails create_multipart_upload_details: (required) + Request object for creating a multi-part upload. + + :param str if_match: (optional) + The entity tag to match. For creating and committing a multipart upload to an object, this is the entity tag of the target object. + For uploading a part, this is the entity tag of the target part. + + :param str if_none_match: (optional) + The entity tag to avoid matching. The only valid value is \u2018*\u2019, which indicates that the request should fail if the object already exists. + For creating and committing a multipart upload, this is the entity tag of the target object. For uploading a part, this is the entity tag + of the target part. + + :param str opc_client_request_id: (optional) + The client request ID for tracing. + + :return: A Response object with data of type MultipartUpload + :rtype: MultipartUpload + """ + resource_path = "/n/{namespaceName}/b/{bucketName}/u" + method = "POST" + + # Don't accept unknown kwargs + expected_kwargs = [ + "if_match", + "if_none_match", + "opc_client_request_id" + ] + extra_kwargs = [key for key in six.iterkeys(kwargs) if key not in expected_kwargs] + if extra_kwargs: + raise ValueError( + "create_multipart_upload got unknown kwargs: {!r}".format(extra_kwargs)) + + path_params = { + "namespaceName": namespace_name, + "bucketName": bucket_name + } + path_params = {k: v for (k, v) in six.iteritems(path_params) if v is not missing} + + header_params = { + "accept": "application/json", + "content-type": "application/json", + "if-match": kwargs.get("if_match", missing), + "if-none-match": kwargs.get("if_none_match", missing), + "opc-client-request-id": kwargs.get("opc_client_request_id", missing) + } + header_params = {k: v for (k, v) in six.iteritems(header_params) if v is not missing} + + return self.base_client.call_api( + resource_path=resource_path, + method=method, + path_params=path_params, + header_params=header_params, + body=create_multipart_upload_details, + response_type="MultipartUpload") + + def create_preauthenticated_request(self, namespace_name, bucket_name, create_preauthenticated_request_details, **kwargs): + """ + CreatePreauthenticatedRequest + Create a pre-authenticated request specific to the bucket + + + :param str namespace_name: (required) + The top-level namespace used for the request. + + :param str bucket_name: (required) + The name of the bucket. + + Example: `my-new-bucket1` + + :param CreatePreauthenticatedRequestDetails create_preauthenticated_request_details: (required) + details for creating the pre-authenticated request. + + :param str opc_client_request_id: (optional) + The client request ID for tracing. + + :return: A Response object with data of type PreauthenticatedRequest + :rtype: PreauthenticatedRequest + """ + resource_path = "/n/{namespaceName}/b/{bucketName}/p/" + method = "POST" + + # Don't accept unknown kwargs + expected_kwargs = [ + "opc_client_request_id" + ] + extra_kwargs = [key for key in six.iterkeys(kwargs) if key not in expected_kwargs] + if extra_kwargs: + raise ValueError( + "create_preauthenticated_request got unknown kwargs: {!r}".format(extra_kwargs)) + + path_params = { + "namespaceName": namespace_name, + "bucketName": bucket_name + } + path_params = {k: v for (k, v) in six.iteritems(path_params) if v is not missing} + + header_params = { + "accept": "application/json", + "content-type": "application/json", + "opc-client-request-id": kwargs.get("opc_client_request_id", missing) + } + header_params = {k: v for (k, v) in six.iteritems(header_params) if v is not missing} + + return self.base_client.call_api( + resource_path=resource_path, + method=method, + path_params=path_params, + header_params=header_params, + body=create_preauthenticated_request_details, + response_type="PreauthenticatedRequest") + def delete_bucket(self, namespace_name, bucket_name, **kwargs): """ DeleteBucket - Deletes a bucket if it is already empty. If the bucket is not empty, use DeleteObject first. + Deletes a bucket if it is already empty. If the bucket is not empty, use :func:`delete_object` first. :param str namespace_name: (required) @@ -97,10 +371,11 @@ def delete_bucket(self, namespace_name, bucket_name, **kwargs): Example: `my-new-bucket1` :param str if_match: (optional) - The entity tag to match. + The entity tag to match. For creating and committing a multipart upload to an object, this is the entity tag of the target object. + For uploading a part, this is the entity tag of the target part. :param str opc_client_request_id: (optional) - The client request ID for tracing + The client request ID for tracing. :return: A Response object with data of type None :rtype: None @@ -141,7 +416,7 @@ def delete_bucket(self, namespace_name, bucket_name, **kwargs): def delete_object(self, namespace_name, bucket_name, object_name, **kwargs): """ DeleteObject - Delete an object. + Deletes an object. :param str namespace_name: (required) @@ -155,13 +430,14 @@ def delete_object(self, namespace_name, bucket_name, object_name, **kwargs): :param str object_name: (required) The name of the object. - Example: `test/test1` + Example: `test/object1.log` :param str if_match: (optional) - The entity tag to match. + The entity tag to match. For creating and committing a multipart upload to an object, this is the entity tag of the target object. + For uploading a part, this is the entity tag of the target part. :param str opc_client_request_id: (optional) - The client request ID for tracing + The client request ID for tracing. :return: A Response object with data of type None :rtype: None @@ -200,6 +476,62 @@ def delete_object(self, namespace_name, bucket_name, object_name, **kwargs): path_params=path_params, header_params=header_params) + def delete_preauthenticated_request(self, namespace_name, bucket_name, par_id, **kwargs): + """ + DeletePreauthenticatedRequest + Deletes the bucket level pre-authenticateted request + + + :param str namespace_name: (required) + The top-level namespace used for the request. + + :param str bucket_name: (required) + The name of the bucket. + + Example: `my-new-bucket1` + + :param str par_id: (required) + The unique identifier for the pre-authenticated request (PAR). This can be used to manage the PAR + such as GET or DELETE the PAR + + :param str opc_client_request_id: (optional) + The client request ID for tracing. + + :return: A Response object with data of type None + :rtype: None + """ + resource_path = "/n/{namespaceName}/b/{bucketName}/p/{parId}" + method = "DELETE" + + # Don't accept unknown kwargs + expected_kwargs = [ + "opc_client_request_id" + ] + extra_kwargs = [key for key in six.iterkeys(kwargs) if key not in expected_kwargs] + if extra_kwargs: + raise ValueError( + "delete_preauthenticated_request got unknown kwargs: {!r}".format(extra_kwargs)) + + path_params = { + "namespaceName": namespace_name, + "bucketName": bucket_name, + "parId": par_id + } + path_params = {k: v for (k, v) in six.iteritems(path_params) if v is not missing} + + header_params = { + "accept": "application/json", + "content-type": "application/json", + "opc-client-request-id": kwargs.get("opc_client_request_id", missing) + } + header_params = {k: v for (k, v) in six.iteritems(header_params) if v is not missing} + + return self.base_client.call_api( + resource_path=resource_path, + method=method, + path_params=path_params, + header_params=header_params) + def get_bucket(self, namespace_name, bucket_name, **kwargs): """ GetBucket @@ -215,13 +547,16 @@ def get_bucket(self, namespace_name, bucket_name, **kwargs): Example: `my-new-bucket1` :param str if_match: (optional) - The entity tag to match. + The entity tag to match. For creating and committing a multipart upload to an object, this is the entity tag of the target object. + For uploading a part, this is the entity tag of the target part. :param str if_none_match: (optional) The entity tag to avoid matching. The only valid value is \u2018*\u2019, which indicates that the request should fail if the object already exists. + For creating and committing a multipart upload, this is the entity tag of the target object. For uploading a part, this is the entity tag + of the target part. :param str opc_client_request_id: (optional) - The client request ID for tracing + The client request ID for tracing. :return: A Response object with data of type Bucket :rtype: Bucket @@ -265,12 +600,12 @@ def get_bucket(self, namespace_name, bucket_name, **kwargs): def get_namespace(self, **kwargs): """ GetNamespace - Get the name of the namespace for the user making the request. An account name must be unique, must start with a - letter, and can have up to 15 lower case letters and numbers. You cannot use spaces and special characters. + Gets the name of the namespace for the user making the request. An account name must be unique, must start with a + letter, and can have up to 15 lowercase letters and numbers. You cannot use spaces or special characters. :param str opc_client_request_id: (optional) - The client request ID for tracing + The client request ID for tracing. :return: A Response object with data of type str :rtype: str @@ -317,20 +652,25 @@ def get_object(self, namespace_name, bucket_name, object_name, **kwargs): :param str object_name: (required) The name of the object. - Example: `test/test1` + Example: `test/object1.log` :param str if_match: (optional) - The entity tag to match. + The entity tag to match. For creating and committing a multipart upload to an object, this is the entity tag of the target object. + For uploading a part, this is the entity tag of the target part. :param str if_none_match: (optional) The entity tag to avoid matching. The only valid value is \u2018*\u2019, which indicates that the request should fail if the object already exists. + For creating and committing a multipart upload, this is the entity tag of the target object. For uploading a part, this is the entity tag + of the target part. :param str opc_client_request_id: (optional) - The client request ID for tracing + The client request ID for tracing. :param str range: (optional) - Optional byte range to fetch. Follows https://tools.ietf.org/html/rfc7233#section-2.1. - Note, only one byte range is supported. + Optional byte range to fetch, as described in `RFC 7233`__, section 2.1. + Note, only a single range of bytes is supported. + + __ https://tools.ietf.org/rfc/rfc7233 :return: A Response object with data of type stream :rtype: stream @@ -342,13 +682,206 @@ def get_object(self, namespace_name, bucket_name, object_name, **kwargs): expected_kwargs = [ "if_match", "if_none_match", - "opc_client_request_id", - "range" + "opc_client_request_id", + "range" + ] + extra_kwargs = [key for key in six.iterkeys(kwargs) if key not in expected_kwargs] + if extra_kwargs: + raise ValueError( + "get_object got unknown kwargs: {!r}".format(extra_kwargs)) + + path_params = { + "namespaceName": namespace_name, + "bucketName": bucket_name, + "objectName": object_name + } + path_params = {k: v for (k, v) in six.iteritems(path_params) if v is not missing} + + header_params = { + "accept": "application/json", + "content-type": "application/json", + "if-match": kwargs.get("if_match", missing), + "if-none-match": kwargs.get("if_none_match", missing), + "opc-client-request-id": kwargs.get("opc_client_request_id", missing), + "range": kwargs.get("range", missing) + } + header_params = {k: v for (k, v) in six.iteritems(header_params) if v is not missing} + + return self.base_client.call_api( + resource_path=resource_path, + method=method, + path_params=path_params, + header_params=header_params, + response_type="stream") + + def get_preauthenticated_request(self, namespace_name, bucket_name, par_id, **kwargs): + """ + GetPreauthenticatedRequest + Get the bucket level pre-authenticateted request + + + :param str namespace_name: (required) + The top-level namespace used for the request. + + :param str bucket_name: (required) + The name of the bucket. + + Example: `my-new-bucket1` + + :param str par_id: (required) + The unique identifier for the pre-authenticated request (PAR). This can be used to manage the PAR + such as GET or DELETE the PAR + + :param str opc_client_request_id: (optional) + The client request ID for tracing. + + :return: A Response object with data of type PreauthenticatedRequestSummary + :rtype: PreauthenticatedRequestSummary + """ + resource_path = "/n/{namespaceName}/b/{bucketName}/p/{parId}" + method = "GET" + + # Don't accept unknown kwargs + expected_kwargs = [ + "opc_client_request_id" + ] + extra_kwargs = [key for key in six.iterkeys(kwargs) if key not in expected_kwargs] + if extra_kwargs: + raise ValueError( + "get_preauthenticated_request got unknown kwargs: {!r}".format(extra_kwargs)) + + path_params = { + "namespaceName": namespace_name, + "bucketName": bucket_name, + "parId": par_id + } + path_params = {k: v for (k, v) in six.iteritems(path_params) if v is not missing} + + header_params = { + "accept": "application/json", + "content-type": "application/json", + "opc-client-request-id": kwargs.get("opc_client_request_id", missing) + } + header_params = {k: v for (k, v) in six.iteritems(header_params) if v is not missing} + + return self.base_client.call_api( + resource_path=resource_path, + method=method, + path_params=path_params, + header_params=header_params, + response_type="PreauthenticatedRequestSummary") + + def head_bucket(self, namespace_name, bucket_name, **kwargs): + """ + HeadBucket + Efficiently checks if a bucket exists and gets the current ETag for the bucket. + + + :param str namespace_name: (required) + The top-level namespace used for the request. + + :param str bucket_name: (required) + The name of the bucket. + + Example: `my-new-bucket1` + + :param str if_match: (optional) + The entity tag to match. For creating and committing a multipart upload to an object, this is the entity tag of the target object. + For uploading a part, this is the entity tag of the target part. + + :param str if_none_match: (optional) + The entity tag to avoid matching. The only valid value is \u2018*\u2019, which indicates that the request should fail if the object already exists. + For creating and committing a multipart upload, this is the entity tag of the target object. For uploading a part, this is the entity tag + of the target part. + + :param str opc_client_request_id: (optional) + The client request ID for tracing. + + :return: A Response object with data of type None + :rtype: None + """ + resource_path = "/n/{namespaceName}/b/{bucketName}/" + method = "HEAD" + + # Don't accept unknown kwargs + expected_kwargs = [ + "if_match", + "if_none_match", + "opc_client_request_id" + ] + extra_kwargs = [key for key in six.iterkeys(kwargs) if key not in expected_kwargs] + if extra_kwargs: + raise ValueError( + "head_bucket got unknown kwargs: {!r}".format(extra_kwargs)) + + path_params = { + "namespaceName": namespace_name, + "bucketName": bucket_name + } + path_params = {k: v for (k, v) in six.iteritems(path_params) if v is not missing} + + header_params = { + "accept": "application/json", + "content-type": "application/json", + "if-match": kwargs.get("if_match", missing), + "if-none-match": kwargs.get("if_none_match", missing), + "opc-client-request-id": kwargs.get("opc_client_request_id", missing) + } + header_params = {k: v for (k, v) in six.iteritems(header_params) if v is not missing} + + return self.base_client.call_api( + resource_path=resource_path, + method=method, + path_params=path_params, + header_params=header_params) + + def head_object(self, namespace_name, bucket_name, object_name, **kwargs): + """ + HeadObject + Gets the user-defined metadata and entity tag for an object. + + + :param str namespace_name: (required) + The top-level namespace used for the request. + + :param str bucket_name: (required) + The name of the bucket. + + Example: `my-new-bucket1` + + :param str object_name: (required) + The name of the object. + + Example: `test/object1.log` + + :param str if_match: (optional) + The entity tag to match. For creating and committing a multipart upload to an object, this is the entity tag of the target object. + For uploading a part, this is the entity tag of the target part. + + :param str if_none_match: (optional) + The entity tag to avoid matching. The only valid value is \u2018*\u2019, which indicates that the request should fail if the object already exists. + For creating and committing a multipart upload, this is the entity tag of the target object. For uploading a part, this is the entity tag + of the target part. + + :param str opc_client_request_id: (optional) + The client request ID for tracing. + + :return: A Response object with data of type None + :rtype: None + """ + resource_path = "/n/{namespaceName}/b/{bucketName}/o/{objectName}" + method = "HEAD" + + # Don't accept unknown kwargs + expected_kwargs = [ + "if_match", + "if_none_match", + "opc_client_request_id" ] extra_kwargs = [key for key in six.iterkeys(kwargs) if key not in expected_kwargs] if extra_kwargs: raise ValueError( - "get_object got unknown kwargs: {!r}".format(extra_kwargs)) + "head_object got unknown kwargs: {!r}".format(extra_kwargs)) path_params = { "namespaceName": namespace_name, @@ -362,8 +895,7 @@ def get_object(self, namespace_name, bucket_name, object_name, **kwargs): "content-type": "application/json", "if-match": kwargs.get("if_match", missing), "if-none-match": kwargs.get("if_none_match", missing), - "opc-client-request-id": kwargs.get("opc_client_request_id", missing), - "range": kwargs.get("range", missing) + "opc-client-request-id": kwargs.get("opc_client_request_id", missing) } header_params = {k: v for (k, v) in six.iteritems(header_params) if v is not missing} @@ -371,60 +903,68 @@ def get_object(self, namespace_name, bucket_name, object_name, **kwargs): resource_path=resource_path, method=method, path_params=path_params, - header_params=header_params, - response_type="stream") + header_params=header_params) - def head_bucket(self, namespace_name, bucket_name, **kwargs): + def list_buckets(self, namespace_name, compartment_id, **kwargs): """ - HeadBucket - An efficient method to check if a bucket exists, and to get the current ETag for the bucket. + ListBuckets + Gets a list of all `BucketSummary`s in a compartment. A `BucketSummary` contains only summary fields for the bucket + and does not contain fields like the user-defined metadata. + + To use this and other API operations, you must be authorized in an IAM policy. If you're not authorized, + talk to an administrator. If you're an administrator who needs to write policies to give users access, see + `Getting Started with Policies`__. + + __ https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/policygetstarted.htm :param str namespace_name: (required) The top-level namespace used for the request. - :param str bucket_name: (required) - The name of the bucket. - - Example: `my-new-bucket1` + :param str compartment_id: (required) + The ID of the compartment in which to create the bucket. - :param str if_match: (optional) - The entity tag to match. + :param int limit: (optional) + The maximum number of items to return. - :param str if_none_match: (optional) - The entity tag to avoid matching. The only valid value is \u2018*\u2019, which indicates that the request should fail if the object already exists. + :param str page: (optional) + The page at which to start retrieving results. :param str opc_client_request_id: (optional) - The client request ID for tracing + The client request ID for tracing. - :return: A Response object with data of type None - :rtype: None + :return: A Response object with data of type list[BucketSummary] + :rtype: list[BucketSummary] """ - resource_path = "/n/{namespaceName}/b/{bucketName}/" - method = "HEAD" + resource_path = "/n/{namespaceName}/b/" + method = "GET" # Don't accept unknown kwargs expected_kwargs = [ - "if_match", - "if_none_match", + "limit", + "page", "opc_client_request_id" ] extra_kwargs = [key for key in six.iterkeys(kwargs) if key not in expected_kwargs] if extra_kwargs: raise ValueError( - "head_bucket got unknown kwargs: {!r}".format(extra_kwargs)) + "list_buckets got unknown kwargs: {!r}".format(extra_kwargs)) path_params = { - "namespaceName": namespace_name, - "bucketName": bucket_name + "namespaceName": namespace_name } path_params = {k: v for (k, v) in six.iteritems(path_params) if v is not missing} + query_params = { + "compartmentId": compartment_id, + "limit": kwargs.get("limit", missing), + "page": kwargs.get("page", missing) + } + query_params = {k: v for (k, v) in six.iteritems(query_params) if v is not missing} + header_params = { "accept": "application/json", "content-type": "application/json", - "if-match": kwargs.get("if_match", missing), - "if-none-match": kwargs.get("if_none_match", missing), "opc-client-request-id": kwargs.get("opc_client_request_id", missing) } header_params = {k: v for (k, v) in six.iteritems(header_params) if v is not missing} @@ -433,12 +973,14 @@ def head_bucket(self, namespace_name, bucket_name, **kwargs): resource_path=resource_path, method=method, path_params=path_params, - header_params=header_params) + query_params=query_params, + header_params=header_params, + response_type="list[BucketSummary]") - def head_object(self, namespace_name, bucket_name, object_name, **kwargs): + def list_multipart_upload_parts(self, namespace_name, bucket_name, object_name, upload_id, **kwargs): """ - HeadObject - Gets the user-defined metadata and entity tag for an object. + ListMultipartUploadParts + Lists the parts of an in-progress multipart upload. :param str namespace_name: (required) @@ -452,33 +994,36 @@ def head_object(self, namespace_name, bucket_name, object_name, **kwargs): :param str object_name: (required) The name of the object. - Example: `test/test1` + Example: `test/object1.log` - :param str if_match: (optional) - The entity tag to match. + :param str upload_id: (required) + The upload ID for a multipart upload. - :param str if_none_match: (optional) - The entity tag to avoid matching. The only valid value is \u2018*\u2019, which indicates that the request should fail if the object already exists. + :param int limit: (optional) + The maximum number of items to return. + + :param str page: (optional) + The page at which to start retrieving results. :param str opc_client_request_id: (optional) - The client request ID for tracing + The client request ID for tracing. - :return: A Response object with data of type None - :rtype: None + :return: A Response object with data of type list[MultipartUploadPartSummary] + :rtype: list[MultipartUploadPartSummary] """ - resource_path = "/n/{namespaceName}/b/{bucketName}/o/{objectName}" - method = "HEAD" + resource_path = "/n/{namespaceName}/b/{bucketName}/u/{objectName}" + method = "GET" # Don't accept unknown kwargs expected_kwargs = [ - "if_match", - "if_none_match", + "limit", + "page", "opc_client_request_id" ] extra_kwargs = [key for key in six.iterkeys(kwargs) if key not in expected_kwargs] if extra_kwargs: raise ValueError( - "head_object got unknown kwargs: {!r}".format(extra_kwargs)) + "list_multipart_upload_parts got unknown kwargs: {!r}".format(extra_kwargs)) path_params = { "namespaceName": namespace_name, @@ -487,11 +1032,16 @@ def head_object(self, namespace_name, bucket_name, object_name, **kwargs): } path_params = {k: v for (k, v) in six.iteritems(path_params) if v is not missing} + query_params = { + "uploadId": upload_id, + "limit": kwargs.get("limit", missing), + "page": kwargs.get("page", missing) + } + query_params = {k: v for (k, v) in six.iteritems(query_params) if v is not missing} + header_params = { "accept": "application/json", "content-type": "application/json", - "if-match": kwargs.get("if_match", missing), - "if-none-match": kwargs.get("if_none_match", missing), "opc-client-request-id": kwargs.get("opc_client_request_id", missing) } header_params = {k: v for (k, v) in six.iteritems(header_params) if v is not missing} @@ -500,26 +1050,23 @@ def head_object(self, namespace_name, bucket_name, object_name, **kwargs): resource_path=resource_path, method=method, path_params=path_params, - header_params=header_params) + query_params=query_params, + header_params=header_params, + response_type="list[MultipartUploadPartSummary]") - def list_buckets(self, namespace_name, compartment_id, **kwargs): + def list_multipart_uploads(self, namespace_name, bucket_name, **kwargs): """ - ListBuckets - Get a list of all `BucketSummary`s in a namespace. A `BucketSummary` contains only summary fields for the bucket - and does not contain fields like the user-defined metadata. - - To use this and other API operations, you must be authorized in an IAM policy. If you're not authorized, - talk to an administrator. If you're an admin who needs to write policies to give users access, see - `Getting Started with Policies`__. - - __ {{DOC_SERVER_URL}}/Content/Identity/Concepts/policygetstarted.htm + ListMultipartUploads + Lists all in-progress multipart uploads for the given bucket in the given namespace. :param str namespace_name: (required) The top-level namespace used for the request. - :param str compartment_id: (required) - The compartment ID in which to create the bucket. + :param str bucket_name: (required) + The name of the bucket. + + Example: `my-new-bucket1` :param int limit: (optional) The maximum number of items to return. @@ -528,12 +1075,12 @@ def list_buckets(self, namespace_name, compartment_id, **kwargs): The page at which to start retrieving results. :param str opc_client_request_id: (optional) - The client request ID for tracing + The client request ID for tracing. - :return: A Response object with data of type list[BucketSummary] - :rtype: list[BucketSummary] + :return: A Response object with data of type list[MultipartUpload] + :rtype: list[MultipartUpload] """ - resource_path = "/n/{namespaceName}/b/" + resource_path = "/n/{namespaceName}/b/{bucketName}/u" method = "GET" # Don't accept unknown kwargs @@ -545,15 +1092,15 @@ def list_buckets(self, namespace_name, compartment_id, **kwargs): extra_kwargs = [key for key in six.iterkeys(kwargs) if key not in expected_kwargs] if extra_kwargs: raise ValueError( - "list_buckets got unknown kwargs: {!r}".format(extra_kwargs)) + "list_multipart_uploads got unknown kwargs: {!r}".format(extra_kwargs)) path_params = { - "namespaceName": namespace_name + "namespaceName": namespace_name, + "bucketName": bucket_name } path_params = {k: v for (k, v) in six.iteritems(path_params) if v is not missing} query_params = { - "compartmentId": compartment_id, "limit": kwargs.get("limit", missing), "page": kwargs.get("page", missing) } @@ -572,7 +1119,7 @@ def list_buckets(self, namespace_name, compartment_id, **kwargs): path_params=path_params, query_params=query_params, header_params=header_params, - response_type="list[BucketSummary]") + response_type="list[MultipartUpload]") def list_objects(self, namespace_name, bucket_name, **kwargs): """ @@ -580,10 +1127,10 @@ def list_objects(self, namespace_name, bucket_name, **kwargs): Lists the objects in a bucket. To use this and other API operations, you must be authorized in an IAM policy. If you're not authorized, - talk to an administrator. If you're an admin who needs to write policies to give users access, see + talk to an administrator. If you're an administrator who needs to write policies to give users access, see `Getting Started with Policies`__. - __ {{DOC_SERVER_URL}}/Content/Identity/Concepts/policygetstarted.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/policygetstarted.htm :param str namespace_name: (required) @@ -595,13 +1142,13 @@ def list_objects(self, namespace_name, bucket_name, **kwargs): Example: `my-new-bucket1` :param str prefix: (optional) - Object names returned by a list query must start with prefix + The string to use for matching against the start of object names in a list query. :param str start: (optional) - Object names returned by a list query must be greater or equal to this parameter + Object names returned by a list query must be greater or equal to this parameter. :param str end: (optional) - Object names returned by a list query must be strictly less than this parameter + Object names returned by a list query must be strictly less than this parameter. :param int limit: (optional) The maximum number of items to return. @@ -614,13 +1161,13 @@ def list_objects(self, namespace_name, bucket_name, **kwargs): this time. :param str fields: (optional) - Object summary in list of objects includes the 'name' field. This parameter may also include 'size' + Object summary in list of objects includes the 'name' field. This parameter can also include 'size' (object size in bytes), 'md5', and 'timeCreated' (object creation date and time) fields. - Value of this parameter should be a comma separated, case-insensitive list of those field names. - For example 'name,timeCreated,md5' + Value of this parameter should be a comma-separated, case-insensitive list of those field names. + For example 'name,timeCreated,md5'. :param str opc_client_request_id: (optional) - The client request ID for tracing + The client request ID for tracing. :return: A Response object with data of type ListObjects :rtype: ListObjects @@ -674,16 +1221,88 @@ def list_objects(self, namespace_name, bucket_name, **kwargs): header_params=header_params, response_type="ListObjects") + def list_preauthenticated_requests(self, namespace_name, bucket_name, **kwargs): + """ + ListPreauthenticatedRequests + List pre-authenticated requests for the bucket + + + :param str namespace_name: (required) + The top-level namespace used for the request. + + :param str bucket_name: (required) + The name of the bucket. + + Example: `my-new-bucket1` + + :param str object_name_prefix: (optional) + Pre-authenticated requests returned by the list must have object names starting with prefix + + :param int limit: (optional) + The maximum number of items to return. + + :param str page: (optional) + The page at which to start retrieving results. + + :param str opc_client_request_id: (optional) + The client request ID for tracing. + + :return: A Response object with data of type list[PreauthenticatedRequestSummary] + :rtype: list[PreauthenticatedRequestSummary] + """ + resource_path = "/n/{namespaceName}/b/{bucketName}/p/" + method = "GET" + + # Don't accept unknown kwargs + expected_kwargs = [ + "object_name_prefix", + "limit", + "page", + "opc_client_request_id" + ] + extra_kwargs = [key for key in six.iterkeys(kwargs) if key not in expected_kwargs] + if extra_kwargs: + raise ValueError( + "list_preauthenticated_requests got unknown kwargs: {!r}".format(extra_kwargs)) + + path_params = { + "namespaceName": namespace_name, + "bucketName": bucket_name + } + path_params = {k: v for (k, v) in six.iteritems(path_params) if v is not missing} + + query_params = { + "objectNamePrefix": kwargs.get("object_name_prefix", missing), + "limit": kwargs.get("limit", missing), + "page": kwargs.get("page", missing) + } + query_params = {k: v for (k, v) in six.iteritems(query_params) if v is not missing} + + header_params = { + "accept": "application/json", + "content-type": "application/json", + "opc-client-request-id": kwargs.get("opc_client_request_id", missing) + } + header_params = {k: v for (k, v) in six.iteritems(header_params) if v is not missing} + + return self.base_client.call_api( + resource_path=resource_path, + method=method, + path_params=path_params, + query_params=query_params, + header_params=header_params, + response_type="list[PreauthenticatedRequestSummary]") + def put_object(self, namespace_name, bucket_name, object_name, put_object_body, **kwargs): """ PutObject - Create a new object or overwrite an existing one. + Creates a new object or overwrites an existing one. To use this and other API operations, you must be authorized in an IAM policy. If you're not authorized, - talk to an administrator. If you're an admin who needs to write policies to give users access, see + talk to an administrator. If you're an administrator who needs to write policies to give users access, see `Getting Started with Policies`__. - __ {{DOC_SERVER_URL}}/Content/Identity/Concepts/policygetstarted.htm + __ https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/policygetstarted.htm :param str namespace_name: (required) @@ -697,22 +1316,25 @@ def put_object(self, namespace_name, bucket_name, object_name, put_object_body, :param str object_name: (required) The name of the object. - Example: `test/test1` + Example: `test/object1.log` :param stream put_object_body: (required) - The object being put to the object store. + The object to upload to the object store. :param int content_length: (optional) The content length of the body. :param str if_match: (optional) - The entity tag to match. + The entity tag to match. For creating and committing a multipart upload to an object, this is the entity tag of the target object. + For uploading a part, this is the entity tag of the target part. :param str if_none_match: (optional) The entity tag to avoid matching. The only valid value is \u2018*\u2019, which indicates that the request should fail if the object already exists. + For creating and committing a multipart upload, this is the entity tag of the target object. For uploading a part, this is the entity tag + of the target part. :param str opc_client_request_id: (optional) - The client request ID for tracing + The client request ID for tracing. :param str expect: (optional) 100-continue @@ -795,7 +1417,7 @@ def put_object(self, namespace_name, bucket_name, object_name, put_object_body, def update_bucket(self, namespace_name, bucket_name, update_bucket_details, **kwargs): """ UpdateBucket - Performs a partial (or full) update of a bucket, currently including just the user-defined metadata. + Performs a partial or full update of a bucket's user-defined metadata. :param str namespace_name: (required) @@ -810,10 +1432,11 @@ def update_bucket(self, namespace_name, bucket_name, update_bucket_details, **kw Request object for updating a bucket. :param str if_match: (optional) - The entity tag to match. + The entity tag to match. For creating and committing a multipart upload to an object, this is the entity tag of the target object. + For uploading a part, this is the entity tag of the target part. :param str opc_client_request_id: (optional) - The client request ID for tracing + The client request ID for tracing. :return: A Response object with data of type Bucket :rtype: Bucket @@ -852,3 +1475,109 @@ def update_bucket(self, namespace_name, bucket_name, update_bucket_details, **kw header_params=header_params, body=update_bucket_details, response_type="Bucket") + + def upload_part(self, namespace_name, bucket_name, object_name, upload_id, upload_part_num, upload_part_body, **kwargs): + """ + UploadPart + Uploads a single part of a multipart upload. + + + :param str namespace_name: (required) + The top-level namespace used for the request. + + :param str bucket_name: (required) + The name of the bucket. + + Example: `my-new-bucket1` + + :param str object_name: (required) + The name of the object. + + Example: `test/object1.log` + + :param str upload_id: (required) + The upload ID for a multipart upload. + + :param int upload_part_num: (required) + The part number that identifies the object part currently being uploaded. + + :param stream upload_part_body: (required) + The part being uploaded to the Object Storage Service. + + :param int content_length: (optional) + The content length of the body. + + :param str opc_client_request_id: (optional) + The client request ID for tracing. + + :param str if_match: (optional) + The entity tag to match. For creating and committing a multipart upload to an object, this is the entity tag of the target object. + For uploading a part, this is the entity tag of the target part. + + :param str if_none_match: (optional) + The entity tag to avoid matching. The only valid value is \u2018*\u2019, which indicates that the request should fail if the object already exists. + For creating and committing a multipart upload, this is the entity tag of the target object. For uploading a part, this is the entity tag + of the target part. + + :param str expect: (optional) + 100-continue + + :param str content_md5: (optional) + The base-64 encoded MD5 hash of the body. + + :return: A Response object with data of type None + :rtype: None + """ + resource_path = "/n/{namespaceName}/b/{bucketName}/u/{objectName}" + method = "PUT" + + # Don't accept unknown kwargs + expected_kwargs = [ + "content_length", + "opc_client_request_id", + "if_match", + "if_none_match", + "expect", + "content_md5" + ] + extra_kwargs = [key for key in six.iterkeys(kwargs) if key not in expected_kwargs] + if extra_kwargs: + raise ValueError( + "upload_part got unknown kwargs: {!r}".format(extra_kwargs)) + + path_params = { + "namespaceName": namespace_name, + "bucketName": bucket_name, + "objectName": object_name + } + path_params = {k: v for (k, v) in six.iteritems(path_params) if v is not missing} + + query_params = { + "uploadId": upload_id, + "uploadPartNum": upload_part_num + } + query_params = {k: v for (k, v) in six.iteritems(query_params) if v is not missing} + + header_params = { + "accept": "application/json", + "opc-client-request-id": kwargs.get("opc_client_request_id", missing), + "if-match": kwargs.get("if_match", missing), + "if-none-match": kwargs.get("if_none_match", missing), + "Expect": kwargs.get("expect", missing), + "Content-Length": kwargs.get("content_length", missing), + "Content-MD5": kwargs.get("content_md5", missing) + } + header_params = {k: v for (k, v) in six.iteritems(header_params) if v is not missing} + + if (not isinstance(upload_part_body, (six.binary_type, six.string_types)) and + not hasattr(upload_part_body, "read")): + raise TypeError('The body must be a string, bytes, or provide a read() method.') + + return self.base_client.call_api( + resource_path=resource_path, + method=method, + path_params=path_params, + query_params=query_params, + header_params=header_params, + body=upload_part_body, + enforce_content_headers=False) diff --git a/oraclebmc/object_storage/transfer/__init__.py b/oraclebmc/object_storage/transfer/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/oraclebmc/object_storage/transfer/constants.py b/oraclebmc/object_storage/transfer/constants.py new file mode 100644 index 0000000000..d495317a09 --- /dev/null +++ b/oraclebmc/object_storage/transfer/constants.py @@ -0,0 +1,6 @@ +# coding: utf-8 +# Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. + +MEBIBYTE = 1024 * 1024 +DEFAULT_PART_SIZE = 128 * MEBIBYTE +OBJECT_USE_MULTIPART_SIZE = 128 * MEBIBYTE diff --git a/oraclebmc/object_storage/transfer/internal/__init__.py b/oraclebmc/object_storage/transfer/internal/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/oraclebmc/object_storage/transfer/internal/buffered_part_reader.py b/oraclebmc/object_storage/transfer/internal/buffered_part_reader.py new file mode 100644 index 0000000000..8d658e8bb2 --- /dev/null +++ b/oraclebmc/object_storage/transfer/internal/buffered_part_reader.py @@ -0,0 +1,76 @@ +# coding: utf-8 +# Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. + +import io + + +class BufferedPartReader(io.IOBase): + def __init__(self, file_object, start, size): + """ + Build an object that will act like a BufferedReader object, + but constrained to a predetermined part of the file_object. + + :param file_object: A file opened for reading in binary mode. + :param start: Start of the part within the file_object + :param size: Ideal size of the part. This will be set + to the number of bytes remaining in the + file if there aren't enough bytes remaining. + """ + self.file = file_object + self.bytes_read = 0 + self.start = start + + # Seek to the end of the file to see how many bytes remain + # from the start of the part. + self.file.seek(0, io.SEEK_END) + self.size = min(self.file.tell() - self.start, size) + + # Reset the pointer to the start of the part. + self.file.seek(start, io.SEEK_SET) + + def seek(self, offset, whence): + """ + Seek within the part. This is similar to the standard seek, except + that io.SEEK_SET is the start of the part and io.SEEK_END is the + end of the part. + + :param offset: Offset in bytes from location determined by the whence value + :param whence: io.SEEK_END and io.SEEK_SET are supported. + """ + if whence == io.SEEK_END: + self.file.seek(self.start + self.size + offset, io.SEEK_SET) + elif whence == io.SEEK_SET: + self.file.seek(self.start + offset, io.SEEK_SET) + else: + raise RuntimeError("Unhandled whence value: {}".format(whence)) + + def tell(self): + """ + Determine where the file pointer is relative to the start of the part. + + :return: Relative position in the part + """ + return self.file.tell() - self.start + + def read(self, n): + """ + Read data from the part, but make the end of the part look like + the end of file has been reached. + + :param n: Bytes to read + :return: Memoryview of the bytes read from the part + """ + buf = bytearray(n) + read = 0 + if self.bytes_read < self.size: + read = self.file.readinto(buf) + self.bytes_read += read + # Check to see if the current buffer contains bytes that come from + # the next part. + if self.bytes_read > self.size: + # Subtract the number of excess bytes from the bytes read. + read -= self.bytes_read - self.size + + # Wrap the bytearray in a memoryview because the Python 2.7 implementation + # of Requests needs a memoryview, buffer or byte string. + return memoryview(buf[:read]) diff --git a/oraclebmc/object_storage/transfer/internal/file_read_callback_stream.py b/oraclebmc/object_storage/transfer/internal/file_read_callback_stream.py new file mode 100644 index 0000000000..c416294899 --- /dev/null +++ b/oraclebmc/object_storage/transfer/internal/file_read_callback_stream.py @@ -0,0 +1,17 @@ +# coding: utf-8 +# Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. + + +class FileReadCallbackStream: + def __init__(self, file, progress_callback): + self.progress_callback = progress_callback + self.file = file + self.mode = file.mode + + # this is used by 'requests' to determine the Content-Length header using fstat + def fileno(self): + return self.file.fileno() + + def read(self, n): + self.progress_callback(n) + return self.file.read(n) diff --git a/oraclebmc/object_storage/transfer/internal/multipart_object_assembler.py b/oraclebmc/object_storage/transfer/internal/multipart_object_assembler.py new file mode 100644 index 0000000000..e57035a18c --- /dev/null +++ b/oraclebmc/object_storage/transfer/internal/multipart_object_assembler.py @@ -0,0 +1,441 @@ +# coding: utf-8 +# Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. + +import io +import hashlib +import base64 +from multiprocessing.dummy import Pool +from os import stat +from ..constants import DEFAULT_PART_SIZE +from ..constants import MEBIBYTE +from .buffered_part_reader import BufferedPartReader +from ... import models +from ....exceptions import ServiceError +from requests.exceptions import Timeout +from requests.exceptions import ConnectionError +import six + +READ_BUFFER_SIZE = 8 * 1024 +DEFAULT_PARALLEL_PROCESS_COUNT = 3 +DEFAULT_MAX_RETRIES = 3 + + +class MultipartObjectAssembler: + def __init__(self, + object_storage_client, + namespace_name, + bucket_name, + object_name, + **kwargs + ): + """ + MultipartObjectAssembler provides a simplified interaction when uploading large + objects using multi-part uploads. + + An assembler can be used to begin a new upload, or resume a previous one. + + :param ObjectStorageClient object_storage_client: + A configured Object Storage client. + + :param str namespace_name: + The namespace containing the bucket in which to store the object. + + :param str bucket_name: + The name of the bucket in which to store the object. + + :param str object_name: + The name to use for the object in Object Storage, or existing object name if resuming. + + :param int part_size (optional): + Override the default part size of 128 MiB, value is in bytes. + + :param str if_match (optional): + The entity tag of the object to match. + + :param str if_none_match (optional): + The entity tag of the object to avoid matching. The only valid value is ‘*’, + which indicates that the request should fail if the object + already exists. + + :param str content_type (optional): + The content type of the object to upload. + + :param str content_language (optional): + The content language of the object to upload. + + :param str content_encoding (optional): + The content encoding of the object to upload. + + :param dict metadata (optional): + A dictionary of string to string values to associate with the object to upload + + :param bool allow_parallel_uploads (optional): + Whether or not this MultipartObjectAssembler supports uploading parts in parallel. Defaults to True. + + :param int parallel_process_count (optional): + The number of worker processes to use in parallel for performing a multipart upload. Default is 3. + """ + self.object_storage_client = object_storage_client + + self.part_size = DEFAULT_PART_SIZE + if 'part_size' in kwargs: + self.part_size = kwargs['part_size'] + self.if_match = None + if 'if_match' in kwargs: + self.if_match = kwargs['if_match'] + self.if_none_match = None + if 'if_none_match' in kwargs: + self.if_none_match = kwargs['if_none_match'] + self.content_type = None + if 'content_type' in kwargs: + self.content_type = kwargs['content_type'] + self.content_language = None + if 'content_language' in kwargs: + self.content_language = kwargs['content_language'] + self.content_encoding = None + if 'content_encoding' in kwargs: + self.content_encoding = kwargs['content_encoding'] + self.metadata = None + if 'metadata' in kwargs: + self.metadata = kwargs['metadata'] + + self.parallel_process_count = DEFAULT_PARALLEL_PROCESS_COUNT + if 'parallel_process_count' in kwargs: + if kwargs['parallel_process_count'] == 0: + raise ValueError('parallel_process_count must be at least one.') + + self.parallel_process_count = kwargs['parallel_process_count'] + + if 'allow_parallel_uploads' in kwargs and kwargs['allow_parallel_uploads'] is False: + # if parallel uploads are disabled, use only a single process + self.parallel_process_count = 1 + + self.max_retries = DEFAULT_MAX_RETRIES + self.manifest = {"uploadId": None, + "namespace": namespace_name, + "bucketName": bucket_name, + "objectName": object_name, + "parts": []} + + @staticmethod + def calculate_md5(file_path, offset, chunk): + """ + Calculate the base64 encoded MD5 hash for a part of a file. + + :param str file_path: Path to the file + :param int offset: Offset where the part starts in the file + :param int chunk: Number of bytes in the part + :return: Base64 encoded MD5 hash + :rtype: str + """ + m = hashlib.md5() + with io.open(file_path, mode='rb') as f: + bpr = BufferedPartReader(f, offset, chunk) + while True: + part = bpr.read(READ_BUFFER_SIZE) + if part == b'': + break + m.update(part) + return base64.b64encode(m.digest()).decode("utf-8") + + @staticmethod + def _is_exception_retryable(e): + """ + Determines if the service should attempt to retry an operation based + on the type of exception + + retry if + timeout + Connection error + unknown client exception: status == -1 + server exception: status >= 500 + Potential edge case: status == 409 + + :param e: Exception + :return: Boolean + """ + retryable = False + if isinstance(e, Timeout): + retryable = True + elif isinstance(e, ConnectionError): + retryable = True + elif isinstance(e, ServiceError): + if e.status >= 500 or e.status == -1 or (e.status == 409 and e.code == "ConcurrentObjectUpdate"): + retryable = True + + return retryable + + def add_parts_from_file(self, file_path): + """ + Splits a file into parts and adds all parts to an internal list of parts to upload. The parts will not be uploaded to the server until upload is called. + + :param string file_path: Path of file to upload in parts + """ + with io.open(file_path, mode='rb') as file_object: + file_object.seek(0, io.SEEK_END) + end = file_object.tell() + file_object.seek(0, io.SEEK_SET) + offset = 0 + while file_object.tell() < end: + self.add_part_from_file(file_path, offset=offset, size=self.part_size) + offset += self.part_size + file_object.seek(offset, io.SEEK_SET) + + def add_part_from_file(self, + file_path, + offset=0, + size=None, + part_hash=None): + """ + Add a part to internal list of parts to upload. The part will not be uploaded to the server until upload is called. + + :param str file_path: Path to file + :param offset: Offset of part in file + :param size: Size of the part in bytes + :param part_hash: Base64 encoded MD5 hash of the part + """ + if size is None: + size = stat(file_path).st_size + + self.manifest["parts"].append({"file_path": file_path, + "offset": offset, + "size": size, + "hash": part_hash}) + + def abort(self, **kwargs): + """ + Abort the multipart upload + + :param str upload_id (optional): The upload id to abort. If not provided, will attempt to abort the upload created internally by new_upload. + + :param str opc_client_request_id: (optional) + The client request ID for tracing + """ + if 'upload_id' in kwargs: + self.manifest["uploadId"] = kwargs['upload_id'] + kwargs.pop('upload_id') + + if not self.manifest["uploadId"]: + raise ValueError("Cannot abort without an upload id.") + + self.object_storage_client.abort_multipart_upload(self.manifest["namespace"], + self.manifest["bucketName"], + self.manifest["objectName"], + self.manifest["uploadId"], + **kwargs) + + def resume(self, **kwargs): + """ + Resume uploading a multipart object to Object Storage + + :param str upload_id (optional): The upload id to resume. If not provided, will attempt to resume the upload created internally by new_upload. + + :param function progress_callback (optional): + Callback function to receive the number of bytes uploaded since + the last call to the callback function. + + :param str opc_client_request_id: (optional) + The client request ID for tracing + """ + if 'upload_id' in kwargs: + self.manifest["uploadId"] = kwargs['upload_id'] + kwargs.pop('upload_id') + + # Verify that the upload id is valid + if self.manifest["uploadId"] is None: + raise ValueError("Cannot resume without an upload id.") + + upload_kwargs = {} + if 'progress_callback' in kwargs: + upload_kwargs['progress_callback'] = kwargs['progress_callback'] + kwargs.pop('progress_callback') + + # Get parts details from object storage to see which parts didn't complete + has_next_page = True + while has_next_page: + response = self.object_storage_client.list_multipart_upload_parts(self.manifest["namespace"], + self.manifest["bucketName"], + self.manifest["objectName"], + self.manifest["uploadId"], + **kwargs) + # Update manifest with information from object storage + parts = self.manifest["parts"] + for part in response.data: + part_index = part.part_number - 1 + if -1 < part_index < len(parts): + manifest_part = parts[part_index] + if manifest_part["size"] != part.size: + raise ValueError('Cannot resume upload with different part size. Parts were uploaded with a part size of {} MiB'.format(part.size / MEBIBYTE)) + manifest_part["etag"] = part.etag + manifest_part["opc_md5"] = part.md5 + elif part_index >= len(parts): + raise ValueError('There are more parts on the server than parts to resume, please check the upload ID.') + has_next_page = response.has_next_page + kwargs['page'] = response.next_page + + # Upload parts that are missing or incomplete + self.upload(**upload_kwargs) + + def new_upload(self, **kwargs): + """ + Create a new multipart upload in Object Storage and add the upload + id to the manifest + + :param str opc_client_request_id: (optional) + The client request ID for tracing. + """ + if self.manifest['uploadId']: + raise RuntimeError('Cannot call new_upload again once an upload has already been created.') + + request = models.CreateMultipartUploadDetails() + request.object = self.manifest["objectName"] + if self.content_type: + request.content_type = self.content_type + if self.content_language: + request.content_language = self.content_language + if self.content_encoding: + request.content_encoding = self.content_encoding + if self.metadata: + # TODO: look into moving this into codegen for create_multipart_upload like it is for put_object + processed_metadata = {} + for key, value in six.iteritems(self.metadata): + if not key.startswith('opc-meta-'): + processed_metadata["opc-meta-" + key] = value + else: + processed_metadata[key] = value + self.metadata = processed_metadata + + request.metadata = self.metadata + + client_request_id = None + if 'opc_client_request_id' in kwargs: + client_request_id = kwargs['opc_client_request_id'] + + kwargs = {} + if client_request_id: + kwargs['opc_client_request_id'] = client_request_id + if self.if_match: + kwargs['if_match'] = self.if_match + if self.if_none_match: + kwargs['if_none_match'] = self.if_none_match + + response = self.object_storage_client.create_multipart_upload(self.manifest["namespace"], + self.manifest["bucketName"], + request, + **kwargs) + + self.manifest["uploadId"] = response.data.upload_id + + def _upload_part(self, part_num, part, **kwargs): + """ + Upload a part to Object Storage + + :param int part_num: Sequence number for where this part belongs in the + multipart object. + :param dict part: Part dictionary containing the following keys: "file_path" (str), "hash" (str), "offset" (int), and "size" (int) + :param str opc_client_request_id: (optional) + The client request ID for tracing. + :param function progress_callback (optional): + Callback function to receive the number of bytes uploaded since + the last call to the callback function. + """ + new_kwargs = {'content_md5': part["hash"]} + if 'opc_client_request_id' in kwargs: + new_kwargs['opc_client_request_id'] = kwargs['opc_client_request_id'] + + # TODO: Calculate the hash without needing to read the file chunk twice. + # Calculate the hash before uploading. The hash will be used + # to determine if the part needs to be uploaded. It will also + # be used to determine if there is a conflict between parts that + # have previously been uploaded. + if part["hash"] is None: + part["hash"] = self.calculate_md5(part["file_path"], part["offset"], part["size"]) + + if "opc_md5" not in part: + remaining_tries = self.max_retries + while remaining_tries > 0: + with io.open(part["file_path"], mode='rb') as file_object: + bpr = BufferedPartReader(file_object, part["offset"], part["size"]) + try: + response = self.object_storage_client.upload_part(self.manifest["namespace"], + self.manifest["bucketName"], + self.manifest["objectName"], + self.manifest["uploadId"], + part_num, + bpr, + **new_kwargs) + except Exception as e: + if self._is_exception_retryable(e) and remaining_tries > 1: + remaining_tries -= 1 + else: + raise + else: + break + + if response.status == 200: + part["etag"] = response.headers['etag'] + part["opc_md5"] = str(response.headers['opc-content-md5']) + + if 'progress_callback' in kwargs: + kwargs['progress_callback'](part["size"]) + + def upload(self, **kwargs): + """ + Upload an object to Object Storage + + :param function progress_callback (optional): + Callback function to receive the number of bytes uploaded since + the last call to the callback function. + :param str opc_client_request_id: (optional) + The client request ID for tracing. + """ + if self.manifest["uploadId"] is None: + raise RuntimeError('Cannot call upload before initializing an upload using new_upload.') + + pool = Pool(processes=self.parallel_process_count) + pool.map(lambda part_tuple: self._upload_part(part_num=part_tuple[0] + 1, part=part_tuple[1], **kwargs), + enumerate(self.manifest["parts"])) + + def commit(self, **kwargs): + """ + Commit the multipart upload. + + :return: A Response object with data of type None + :rtype: None + """ + if self.manifest["uploadId"] is None: + raise RuntimeError('Cannot call commit before initializing an upload using new_upload or resuming an upload using resume.') + + client_request_id = None + if 'opc_client_request_id' in kwargs: + client_request_id = kwargs['opc_client_request_id'] + + commit_details = models.CommitMultipartUploadDetails() + + # Determine which parts to commit and which parts to exclude. + parts_to_commit = [] + parts_to_exclude = [] + for partNum, part in enumerate(self.manifest["parts"]): + detail = models.CommitMultipartUploadPartDetails() + detail.part_num = partNum + 1 + if "etag" in part: + detail.etag = part["etag"] + parts_to_commit.append(detail) + else: + parts_to_exclude.append(partNum + 1) + + commit_details.parts_to_commit = parts_to_commit + commit_details.parts_to_exclude = parts_to_exclude + + kwargs = {} + if client_request_id: + kwargs['opc_client_request_id'] = client_request_id + + # Commit the multipart upload + response = self.object_storage_client.commit_multipart_upload(self.manifest["namespace"], + self.manifest["bucketName"], + self.manifest["objectName"], + self.manifest["uploadId"], + commit_details, + **kwargs) + return response diff --git a/oraclebmc/object_storage/transfer/upload_manager.py b/oraclebmc/object_storage/transfer/upload_manager.py new file mode 100644 index 0000000000..a4dacd7ae3 --- /dev/null +++ b/oraclebmc/object_storage/transfer/upload_manager.py @@ -0,0 +1,229 @@ +# coding: utf-8 +# Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. + +from __future__ import print_function +import os +from .internal.multipart_object_assembler import MultipartObjectAssembler +from .constants import DEFAULT_PART_SIZE +from .internal.file_read_callback_stream import FileReadCallbackStream + + +class UploadManager: + def __init__(self, object_storage_client, **kwargs): + """ + UploadManager simplifies interaction with the Object Storage service by abstracting away the method used + to upload objects. Depending on the configuration parameters, UploadManager may choose to do a single + put_object request, or break up the upload into multiple parts and utilize multi-part uploads. + + An advantage of using multi-part uploads is the ability to retry individual failed parts, as well as being + able to upload parts in parallel to reduce upload time. + + :param ObjectStorageClient object_storage_client: + A configured object storage client to use for interacting with the Object Storage service. + + :param bool allow_multipart_uploads (optional): + Whether or not this UploadManager supports performing mulitpart uploads. Defaults to True. + + :param bool allow_parallel_uploads (optional): + Whether or not this UploadManager supports uploading individual parts of a multipart upload in parallel. + This setting has no effect on uploads that are performed using a single put_object call. Defaults to True. + + :param int parallel_process_count (optional): + The number of worker processes to use in parallel for uploading individual parts of a multipart upload. + This setting is only used if allow_parallel_uploads is set to True. Defaults to 3. + """ + self.object_storage_client = object_storage_client + self.allow_multipart_uploads = kwargs['allow_multipart_uploads'] if 'allow_multipart_uploads' in kwargs else True + self.allow_parallel_uploads = kwargs['allow_parallel_uploads'] if 'allow_parallel_uploads' in kwargs else True + self.parallel_process_count = kwargs['parallel_process_count'] if 'parallel_process_count' in kwargs else None + + def upload_file(self, + namespace_name, + bucket_name, + object_name, + file_path, + **kwargs): + """ + Uploads an object to Object Storage. Depending on the options provided and the + size of the object, the object may be uploaded in multiple parts. + + :param str namespace_name: + The namespace containing the bucket in which to store the object. + + :param str bucket_name: + The name of the bucket in which to store the object. + + :param str object_name: + The name of the object in Object Storage. + + :param file_path: + The path to the file to upload. + + :param int part_size (optional): + Override the default part size of 128 MiB, value is in bytes. + + :param function progress_callback (optional): + Callback function to receive the number of bytes uploaded since + the last call to the callback function. + + :param str if_match (optional): + The entity tag of the object to match. + + :param str if_none_match (optional): + The entity tag of the object to avoid matching. The only valid value is ‘*’, + which indicates that the request should fail if the object + already exists. + + :param str content_md5: (optional) + The base-64 encoded MD5 hash of the body. This parameter is only used if the object is uploaded in a single part. + + :param str content_type (optional): + The content type of the object to upload. + + :param str content_language (optional): + The content language of the object to upload. + + :param str content_encoding (optional): + The content encoding of the object to upload. + + :param dict metadata (optional): + A dictionary of string to string values to associate with the object to upload + + :return: + The response from multipart commit operation or the put operation. In both cases this will be a Response object with data of type None. For a multipart upload the Response will contain the opc-multipart-md5 header and for a non-multipart upload it will contain the opc-content-md5 header. + """ + part_size = DEFAULT_PART_SIZE + if 'part_size' in kwargs: + part_size = kwargs['part_size'] + kwargs.pop('part_size') + + with open(file_path, 'rb') as file_object: + file_size = os.fstat(file_object.fileno()).st_size + if not self.allow_multipart_uploads or not UploadManager._use_multipart(file_size, part_size=part_size): + return self._upload_singlepart(namespace_name, bucket_name, object_name, file_path, **kwargs) + else: + if 'content_md5' in kwargs: + kwargs.pop('content_md5') + + kwargs['part_size'] = part_size + kwargs['allow_parallel_uploads'] = self.allow_parallel_uploads + if self.parallel_process_count is not None: + kwargs['parallel_process_count'] = self.parallel_process_count + + ma = MultipartObjectAssembler(self.object_storage_client, + namespace_name, + bucket_name, + object_name, + **kwargs) + + upload_kwargs = {} + if 'progress_callback' in kwargs: + upload_kwargs['progress_callback'] = kwargs['progress_callback'] + + ma.new_upload() + ma.add_parts_from_file(file_path) + ma.upload(**upload_kwargs) + response = ma.commit() + + return response + + def resume_upload_file(self, + namespace_name, + bucket_name, + object_name, + file_path, + upload_id, + **kwargs): + + """ + Resume a multipart upload. + + :param str namespace_name: + The namespace containing the bucket and multipart upload to resume. + + :param str bucket_name: + The name of the bucket that contains the multipart upload to resume. + + :param str object_name: + The name of the object in Object Storage. + + :param file_path: + The path to the file to upload. + + :param str upload_id: + The upload id for the multipart upload to resume. + + :param int part_size (optional): + Part size, in bytes, to use when resuming the transfer. The + default is 128 mebibytes. If this value is supplied, it must + be the same value as the one used when the original upload + was started. + + :param function progress_callback (optional): + Callback function to receive the number of bytes uploaded since + the last call to the callback function. + + :return: + The response from the multipart commit operation. + """ + resume_kwargs = {} + if 'progress_callback' in kwargs: + resume_kwargs['progress_callback'] = kwargs['progress_callback'] + kwargs.pop('progress_callback') + + kwargs['allow_parallel_uploads'] = self.allow_parallel_uploads + if self.parallel_process_count is not None: + kwargs['parallel_process_count'] = self.parallel_process_count + + ma = MultipartObjectAssembler(self.object_storage_client, + namespace_name, + bucket_name, + object_name, + **kwargs) + ma.add_parts_from_file(file_path) + ma.resume(upload_id=upload_id, **resume_kwargs) + response = ma.commit() + + return response + + def _upload_singlepart(self, + namespace_name, + bucket_name, + object_name, + file_path, + **kwargs): + # put_object expects 'opc_meta' not metadata + if 'metadata' in kwargs: + kwargs['opc_meta'] = kwargs['metadata'] + kwargs.pop('metadata') + + # remove unrecognized kwargs for put_object + progress_callback = None + if 'progress_callback' in kwargs: + progress_callback = kwargs['progress_callback'] + kwargs.pop('progress_callback') + + with open(file_path, 'rb') as file_object: + # progress_callback is not supported for files of zero bytes + # FileReadCallbackStream will not be handled properly by requests in this case + file_size = os.fstat(file_object.fileno()).st_size + if file_size != 0 and progress_callback: + wrapped_file = FileReadCallbackStream(file_object, + lambda bytes_read: progress_callback(bytes_read)) + + response = self.object_storage_client.put_object(namespace_name, + bucket_name, + object_name, + wrapped_file, + **kwargs) + else: + response = self.object_storage_client.put_object(namespace_name, + bucket_name, + object_name, + file_object, + **kwargs) + return response + + @staticmethod + def _use_multipart(content_length, part_size=DEFAULT_PART_SIZE): + return part_size < content_length diff --git a/oraclebmc/version.py b/oraclebmc/version.py index 2519a5ec8e..cfcff6732d 100644 --- a/oraclebmc/version.py +++ b/oraclebmc/version.py @@ -1,4 +1,4 @@ # coding: utf-8 # Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. -__version__ = "1.3.2" +__version__ = "1.3.3"