Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 085a974

Browse files
sample fn to copy objstore objects between buckets
1 parent 12da04a commit 085a974

File tree

7 files changed

+211
-0
lines changed

7 files changed

+211
-0
lines changed

‎README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ This repository provides examples demonstrating how to use Oracle Functions.
2323
| Read an object in OCI Object Storage |[sample](./samples/oci-objectstorage-get-object-python)|[sample](./samples/oci-objectstorage-get-object-java)|
2424
| Create an object in OCI Object Storage |[sample](./samples/oci-objectstorage-put-object-python)|[sample](./samples/oci-objectstorage-put-object-java)|
2525
| Create a PAR in OCI Object Storage |[sample](./samples/oci-objectstorage-create-par-python)||
26+
| Copy Objects between Object Storage |[sample](./samples/oci-objectstorage-copy-objects-python)||
2627
| Display an OCI Cloud Event |[sample](./samples/oci-event-display-python)|
2728
| Invoke another Function using the OCI SDK |[sample](./samples/oci-invoke-function-python)|||
2829
| Run a SQL statement against Autonomous DB using ORDS | [sample](./samples/oci-adb-ords-runsql-python) |
Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
# Function that copies an object in an OCI Object Storage bucket to another bucket using the OCI Python SDK
2+
This function can be used to create *"Immutable Copies"* of objects in an OCI bucket by copying them, during creation/update, to another bucket with defined retention policies. This is especially useful when using the [Oracle Backup Cloud Service](https://docs.oracle.com/en/cloud/paas/db-backup-cloud/csdbb/oracle-database-backup-cloud-service.html) to ensure backups are maintained for a specified amount of time.
3+
4+
5+
The function uses Resource Principals to securely authorize a function to make
6+
API calls to OCI services using the [OCI Python SDK](https://oracle-cloud-infrastructure-python-sdk.readthedocs.io/en/latest/index.html).
7+
It creates an object in a bucket in Object Storage and returns a message with a status.
8+
9+
10+
The function calls the following OCI Python SDK classes:
11+
* [Resource Principals Signer](https://oracle-cloud-infrastructure-python-sdk.readthedocs.io/en/latest/api/signing.html#resource-principals-signer) to authenticate
12+
* [Object Storage Client](https://oracle-cloud-infrastructure-python-sdk.readthedocs.io/en/latest/api/object_storage/client/oci.object_storage.ObjectStorageClient.html) to interact with Object Storage
13+
14+
As you make your way through this tutorial, look out for this icon ![user input icon](./images/userinput.png).
15+
Whenever you see it, it's time for you to perform an action.
16+
17+
18+
## Prerequisites
19+
20+
1. Before you deploy this sample function, make sure you have run steps A, B
21+
and C of the [Oracle Functions Quick Start Guide for Cloud Shell](https://www.oracle.com/webfolder/technetwork/tutorials/infographics/oci_functions_cloudshell_quickview/functions_quickview_top/functions_quickview/index.html)
22+
* A - Set up your tenancy
23+
* B - Create application
24+
* C - Set up your Cloud Shell dev environment
25+
26+
2. Have your Oracle Object Storage Namespace available. This can be found by
27+
logging into your [cloud account](https://console.us-ashburn-1.oraclecloud.com/),
28+
under your user profile, click on your Tenancy. Your Object Storage Namespace
29+
is shown there.
30+
31+
32+
## List Applications
33+
34+
Assuming you have successfully completed the prerequisites, you should see your
35+
application in the list of applications.
36+
37+
```
38+
fn ls apps
39+
```
40+
41+
42+
## Create or Update your Dynamic Group
43+
44+
In order to use other OCI Services, your function must be part of a dynamic
45+
group. For information on how to create a dynamic group, refer to the
46+
[documentation](https://docs.cloud.oracle.com/iaas/Content/Identity/Tasks/managingdynamicgroups.htm#To).
47+
48+
When specifying the *Matching Rules*, we suggest matching all functions in a compartment with:
49+
50+
```
51+
ALL {resource.type = 'fnfunc', resource.compartment.id = 'ocid1.compartment.oc1..aaaaaxxxxx'}
52+
```
53+
54+
55+
## Create or Update IAM Policies
56+
57+
Create a new policy that allows the dynamic group to `manage objects` and `manage buckets` in the functions related compartment.
58+
59+
![user input icon](./images/userinput.png)
60+
61+
Your policy should look something like this:
62+
```
63+
Allow service objectstorage-<region> to manage object-family in compartment <compartment-name>
64+
Allow dynamic-group <dynamic-group-name> to manage objects in compartment <compartment-name>
65+
Allow dynamic-group <dynamic-group-name> to manage buckets in compartment <compartment-name>
66+
```
67+
e.g.
68+
```
69+
Allow service objectstorage-eu-frankfurt-1 to manage object-family in compartment demo-func-compartment
70+
Allow dynamic-group demo-func-dyn-group to manage objects in compartment demo-func-compartment
71+
Allow dynamic-group demo-func-dyn-group to manage buckets in compartment demo-func-compartment
72+
```
73+
For more information on how to create policies, go [here](https://docs.cloud.oracle.com/iaas/Content/Identity/Concepts/policysyntax.htm).
74+
75+
76+
## Review and customize the function
77+
78+
Review the following files in the current folder:
79+
80+
- [requirements.txt](./requirements.txt) specifies all the dependencies for your function
81+
- [func.yaml](./func.yaml) that contains metadata about your function and declares properties
82+
- [func.py](./func.py) which is your actual Python function
83+
84+
The name of your function *oci-objectstorage-copy-objects-python* is specified in [func.yaml](./func.yaml).
85+
86+
87+
## Deploy the function
88+
89+
In Cloud Shell, run the `fn deploy` command to build the function and its dependencies as a Docker image,
90+
push the image to the specified Docker registry, and deploy the function to Oracle Functions
91+
in the application created earlier:
92+
93+
![user input icon](./images/userinput.png)
94+
95+
```
96+
fn -v deploy --app <app-name>
97+
```
98+
e.g.
99+
```
100+
fn -v deploy --app myapp
101+
```
102+
103+
## Create Object Store Buckets
104+
105+
![user input icon](./images/userinput.png)
106+
107+
From the OCI Console > Storage > Object Storage > Create Bucket with bucket name = "TEST" and enable "Emit Object Events"
108+
109+
From the OCI Console > Storage > Object Storage > Create Bucket with bucket name = "TEST_IMMUTABLE" and apply a retention policy
110+
111+
## Create an Event Rule on Bucket
112+
113+
![user input icon](./images/userinput.png)
114+
115+
From the OCI Console > Observability & Management > Event Service > Create Rule:
116+
117+
Display Name: IMMUTABLE-OBJECT_STORE
118+
Rule Conditions:
119+
Event Type: Object Storage: Object - Create; Object - Update
120+
Attribute: bucketName: TEST
121+
Actions (<app-name> as per the `fn -v deploy --app <app-name>`) :
122+
Function: (root): <app-name>
123+
124+
![event](./images/create_rule.png)
125+
126+
## Test
127+
128+
![user input icon](./images/userinput.png)
129+
130+
From the OCI Console > Storage > Object Storage > TEST
131+
132+
Objects -> Upload; Drop file to upload
133+
134+
From the OCI Console > Storage > Object Storage > TEST_IMMUTABLE
135+
136+
__The file uploaded to the TEST bucket should now be present in the TEST_IMMUTABLE bucket.__
137+
138+
139+
## Monitoring Functions
140+
141+
Learn how to configure basic observability for your function using metrics, alarms and email alerts:
142+
* [Basic Guidance for Monitoring your Functions](../basic-observability/functions.md)
143+
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
#
2+
# oci-objectstorage-copy-objects-python version 1.0.
3+
#
4+
# Copyright (c) 2020 Oracle, Inc.
5+
# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl.
6+
#
7+
import io
8+
import json
9+
import logging
10+
11+
import oci.object_storage
12+
from fdk import response
13+
14+
def copy_object(signer, namespace, src_bucket, dst_bucket, object_name):
15+
try:
16+
objstore = oci.object_storage.ObjectStorageClient(config={}, signer=signer)
17+
objstore_composite_ops = oci.object_storage.ObjectStorageClientCompositeOperations(objstore)
18+
resp = objstore_composite_ops.copy_object_and_wait_for_state(
19+
namespace,
20+
src_bucket,
21+
oci.object_storage.models.CopyObjectDetails(
22+
destination_bucket=dst_bucket,
23+
destination_namespace=namespace,
24+
destination_object_name=object_name,
25+
destination_region=signer.region,
26+
source_object_name=object_name
27+
)
28+
)
29+
except (Exception, ValueError) as ex:
30+
logging.getLogger().error(str(ex))
31+
return {"response": str(ex)}
32+
33+
return {"response": str(response)}
34+
35+
36+
def handler(ctx, data: io.BytesIO=None):
37+
signer = oci.auth.signers.get_resource_principals_signer()
38+
resp = ""
39+
try:
40+
body = json.loads(data.getvalue())
41+
#logging.getLogger().info(json.dumps(body))
42+
namespace = body["data"]["additionalDetails"]["namespace"]
43+
src_bucket = body["data"]["additionalDetails"]["bucketName"]
44+
object_name = body["data"]["resourceName"]
45+
dst_bucket = body["data"]["additionalDetails"]["bucketName"]+"_IMMUTABLE"
46+
47+
logging.getLogger().info(f'Copying {object_name} from {src_bucket} to {dst_bucket}')
48+
49+
resp = copy_object(signer, namespace, src_bucket, dst_bucket, object_name)
50+
except (Exception, ValueError) as ex:
51+
logging.getLogger().error(str(ex))
52+
53+
return response.Response(
54+
ctx,
55+
response_data=json.dumps(resp),
56+
headers={"Content-Type": "application/json"}
57+
)
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
schema_version: 20180708
2+
name: oci-objectstorage-copy-objects-python
3+
version: 0.0.1
4+
runtime: python
5+
build_image: fnproject/python:3.8-dev
6+
run_image: fnproject/python:3.8
7+
entrypoint: /python/bin/fdk /function/func.py handler
8+
memory: 256
123 KB
Loading[フレーム]
2.96 KB
Loading[フレーム]
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
fdk>=0.1.40
2+
oci>=2.49.1

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /