Skip to content

Commit 20201e0

Browse files
authored
Merge pull request #50 from oracle/release_2018-03-08
Releasing version 1.3.16
2 parents 974852b + 674bed9 commit 20201e0

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+3807
-391
lines changed

CHANGELOG.rst

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,26 @@ All notable changes to this project will be documented in this file.
44

55
The format is based on `Keep a Changelog <http://keepachangelog.com/>`_.
66

7+
====================
8+
1.3.16 - 2018-03-08
9+
====================
10+
11+
Added
12+
-----
13+
* Added support for the Email Service
14+
15+
* An example on using the Email Service can be found on `GitHub <https://github.com/oracle/oci-python-sdk/blob/master/examples/email_service_example.py>`__.
16+
17+
* Added support for SMTP credentials in the Identity Service
18+
19+
* An example on managing SMTP credentials can be found on `GitHub <https://github.com/oracle/oci-python-sdk/blob/master/examples/email_service_example.py>`__.
20+
21+
* Added support for paravirtualized volume attachments in Core Services
22+
23+
* An example on using volume attachments can be found on `GitHub <https://github.com/oracle/oci-python-sdk/blob/master/examples/volume_attachment_example.py>`__.
24+
25+
* Added support for variable size boot volumes in Core Services
26+
727
====================
828
1.3.15 - 2018-02-22
929
====================

docs/api/index.rst

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,28 @@ Virtual Network
117117
:imported-members:
118118
:inherited-members:
119119

120+
==========
121+
Email
122+
==========
123+
124+
--------
125+
Client
126+
--------
127+
128+
.. autoclass:: oci.email.email_client.EmailClient
129+
:members:
130+
131+
--------
132+
Models
133+
--------
134+
135+
.. automodule:: oci.email.models
136+
:special-members: __init__
137+
:members:
138+
:undoc-members:
139+
:imported-members:
140+
:inherited-members:
141+
120142
==============
121143
File Storage
122144
==============

docs/index.rst

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,14 +48,13 @@ To get started, head over to the :ref:`installation instructions <install>` or s
4848
backward-compatibility
4949
quickstart
5050
logging
51-
parallel-ops
52-
pass-explicit-null
5351
upload-manager
5452
raw-requests
5553
waiters
5654
pagination
5755
api/index
5856
customize_service_client/index
57+
sdk_behaviors/index
5958
contributions
6059
notifications
6160
license
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
.. _handle-naive-datetime:
2+
3+
Handling naive datetimes
4+
~~~~~~~~~~~~~~~~~~~~~~~~~~
5+
For operations and models which accept a `datetime <https://docs.python.org/3.6/library/datetime.html>`__ object, if a naive
6+
``datetime`` is passed (i.e. one without any ``tzinfo``) then the SDK will interpret the date and time as being UTC. This is
7+
the equivalent of running the following code on the naive ``datetime``:
8+
9+
.. code-block:: pycon
10+
11+
>>> import datetime
12+
>>> import pytz
13+
>>> my_naive_datetime = datetime.datetime(2001, 1, 1, 12, 30)
14+
>>> my_naive_datetime
15+
datetime.datetime(2001, 1, 1, 12, 30)
16+
>>> pytz.utc.localize(my_naive_datetime)
17+
datetime.datetime(2001, 1, 1, 12, 30, tzinfo=<UTC>)
18+
19+
20+
For aware ``datetime`` objects (i.e. those with a ``tzinfo``), their timezone information will be used as-is.

docs/sdk_behaviors/index.rst

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
.. sdk-behaviors:
2+
3+
SDK Behaviors
4+
~~~~~~~~~~~~~~
5+
This section describes SDK-specific behaviors:
6+
7+
* :doc:`Handling naive datetimes </sdk_behaviors/handle_naive_datetime>`
8+
* :doc:`Parallel operations </parallel-ops>`
9+
* :doc:`Passing explicit null/None values </pass-explicit-null>`
10+
11+
.. toctree::
12+
:hidden:
13+
:maxdepth: 2
14+
15+
handle_naive_datetime
16+
/parallel-ops
17+
/pass-explicit-null

examples/email_service_example.py

Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
# coding: utf-8
2+
# Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
3+
4+
# This script provides a basic example of how to use the Email Service in the Python SDK. This script accepts two
5+
# will demonstrate:
6+
#
7+
# * Creating, retrieving, listing and deleting email senders
8+
# * Creating, retrieving, listing and deleting email suppressions
9+
# * Obtaining SMTP credentials for your IAM user so that you can send emails.
10+
# See https://docs.us-phoenix-1.oraclecloud.com/Content/Email/Tasks/configuresmtpconnection.htm for more
11+
# information on sending emails
12+
#
13+
# This script accepts three arguments:
14+
#
15+
# * The compartment ID where email senders will be created
16+
# * The address of the email sender
17+
# * The address of the email suppression
18+
#
19+
# Note that email senders are created in the compartment which you specify, but the suppressions are always created at the tenancy
20+
# level. The tenancy will be read from your configuration file.
21+
22+
import oci
23+
import sys
24+
25+
# Default config file and profile
26+
config = oci.config.from_file()
27+
email_client = oci.email.EmailClient(config)
28+
identity_client = oci.identity.IdentityClient(config)
29+
30+
if len(sys.argv) != 4:
31+
raise RuntimeError('This script expects an argument of a compartment OCID, sender email address and suppression email address')
32+
33+
# The first argument is the name of the script, so start the index at 1
34+
compartment_id = sys.argv[1]
35+
sender_address = sys.argv[2]
36+
suppression_address = sys.argv[3]
37+
38+
create_sender_response = email_client.create_sender(
39+
oci.email.models.CreateSenderDetails(
40+
compartment_id=compartment_id,
41+
email_address=sender_address
42+
)
43+
)
44+
print('Created sender:\n{}'.format(create_sender_response.data))
45+
print('\n=========================\n')
46+
47+
# A sender has a lifecycle state, so we can wait for it to become available
48+
get_sender_response = oci.wait_until(email_client, email_client.get_sender(create_sender_response.data.id), 'lifecycle_state', 'ACTIVE')
49+
print('Waited for sender to become available:\n{}'.format(get_sender_response.data))
50+
print('\n=========================\n')
51+
52+
# We can list all senders, and also provide optional filters and sorts. Here we'll list all
53+
# senders sorted by their email address, and also demonstrate filtering by sender email
54+
# address (an exact match filter)
55+
#
56+
# Listing senders is a paginated operation, so we can use the functions in oci.pagination
57+
senders = oci.pagination.list_call_get_all_results(
58+
email_client.list_senders,
59+
compartment_id,
60+
sort_by='EMAILADDRESS',
61+
sort_order='ASC'
62+
).data
63+
print('Listing senders sorted by email address:')
64+
for s in senders:
65+
print(s)
66+
print('\n=========================\n')
67+
68+
senders = oci.pagination.list_call_get_all_results(
69+
email_client.list_senders,
70+
compartment_id,
71+
email_address='fake-{}'.format(sender_address)
72+
).data
73+
print('Listing senders filtered by email address - no data expected:')
74+
for s in senders:
75+
print(s)
76+
print('\n=========================\n')
77+
78+
# Suppressions do not have a lifecycle state, so we don't have to wait on anything after creation
79+
create_suppression_response = email_client.create_suppression(
80+
oci.email.models.CreateSuppressionDetails(
81+
compartment_id=config['tenancy'],
82+
email_address=suppression_address
83+
)
84+
)
85+
print('Created suppression:\n{}'.format(create_suppression_response.data))
86+
print('\n=========================\n')
87+
88+
# We can list all suppressions, and also provide optional filters and sorts. Here we'll list all
89+
# suppressions sorted by their time created, and also demonstrate filtering by suppression email
90+
# address (an exact match filter)
91+
#
92+
# Listing senders is a paginated operation, so we can use the functions in oci.pagination
93+
suppressions = oci.pagination.list_call_get_all_results(
94+
email_client.list_suppressions,
95+
config['tenancy'],
96+
sort_by='TIMECREATED',
97+
sort_order='DESC'
98+
).data
99+
print('Listing suppressions sorted by time created:')
100+
for s in suppressions:
101+
print(s)
102+
print('\n=========================\n')
103+
104+
suppressions = oci.pagination.list_call_get_all_results(
105+
email_client.list_suppressions,
106+
config['tenancy'],
107+
email_address='fake-{}'.format(suppression_address)
108+
).data
109+
print('Listing suppressions filtered by email address - no data expected:')
110+
for s in suppressions:
111+
print(s)
112+
print('\n=========================\n')
113+
114+
# We can also delete a sender and then wait for it to be deleted. The sender may already be deleted
115+
# by the time we call oci.wait_until, so pass the get_sender_response to the waiter. It is recommended that
116+
# you have a get response prior to calling the delete, INSTEAD OF doing:
117+
#
118+
# oci.wait_until(email_client, email_client.get_sender(sender_id), ...)
119+
#
120+
# When deleting, since the resource may be gone, we set succeed_on_not_found on the waiter so that we consider
121+
# receiving a 404 back from the service as a successful delete
122+
email_client.delete_sender(get_sender_response.data.id)
123+
oci.wait_until(email_client, get_sender_response, 'lifecycle_state', 'DELETED', succeed_on_not_found=True)
124+
print('Deleted sender')
125+
126+
# Suppressions do not have a lifecycle state, so we don't have to wait on anything after deletion
127+
email_client.delete_suppression(create_suppression_response.data.id)
128+
print('Deleted suppression')
129+
130+
# In order to send email, we'll need to create an SMTP credential associated with an IAM user. More
131+
# information on sending email can be found here:
132+
# https://docs.us-phoenix-1.oraclecloud.com/Content/Email/Tasks/configuresmtpconnection.htm
133+
#
134+
# Note, also, that an IAM user can only have two active SMTP credentials at any time
135+
#
136+
# Also the password for the SMTP credential is ONLY available in the create response, so you
137+
# should store/save this as it won't be retrievable later
138+
create_smtp_credential_response = identity_client.create_smtp_credential(
139+
oci.identity.models.CreateSmtpCredentialDetails(
140+
description='new credential'
141+
),
142+
user_id=config['user']
143+
)
144+
print('Created SMTP credential:\n{}'.format(create_smtp_credential_response.data))
145+
print('\n=========================\n')
146+
147+
# We can update the description of an SMTP credential
148+
update_smtp_credential_response = identity_client.update_smtp_credential(
149+
config['user'],
150+
create_smtp_credential_response.data.id,
151+
oci.identity.models.UpdateSmtpCredentialDetails(
152+
description='updated credential description'
153+
)
154+
)
155+
print('Updated SMTP credential:\n{}'.format(update_smtp_credential_response.data))
156+
print('\n=========================\n')
157+
158+
# We can list the credentials for a user. Note that this is not a paginated operation
159+
list_smtp_credentials_response = identity_client.list_smtp_credentials(config['user'])
160+
print('SMTP credentials for user:\n{}'.format(list_smtp_credentials_response.data))
161+
print('\n=========================\n')
162+
163+
identity_client.delete_smtp_credential(config['user'], create_smtp_credential_response.data.id)
164+
print('Deleted SMTP credential')
165+
166+
print('\nScript Finished')

examples/retrieve_audit_events.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
#!/usr/bin/env python
2-
# coding: utf-8
3-
# Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
1+
# coding: utf-8
2+
# Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
43

54
# This script retrieves all audit logs across an OCI Tenancy.
65
# for a timespan defined by start_time and end_time.
@@ -95,4 +94,4 @@ def get_audit_events(audit, compartment_ocids, start_time, end_time):
9594

9695
# Results for a region 'r' for each compartment.
9796
if audit_events:
98-
print audit_events
97+
print(audit_events)

0 commit comments

Comments
 (0)