Nota

Utilizza Oracle Cloud Infrastructure Object Storage Service con OpenStack Swift API

Introduzione

Lo storage degli oggetti Oracle Cloud Infrastructure (OCI) è un'architettura di storage dei dati che gestisce e organizza le informazioni digitali come oggetti, ognuno composto da dati, metadati e un identificativo univoco. A differenza dello storage tradizionale di file o blocchi, lo storage degli oggetti OCI non si basa su una struttura gerarchica, consentendo una gestione efficiente e scalabile di grandi quantità di dati non strutturati. Gli oggetti vengono memorizzati in uno spazio di indirizzamento semplice, semplificando il recupero dei dati e consentendo una perfetta scalabilità. Questa soluzione è ideale per diversi tipi di dati, come contenuti multimediali e backup, rendendola una scelta affidabile per ambienti cloud, storage di archivio e sistemi distribuiti grazie alla sua flessibilità, durata e facilità di accesso. Gli utenti interagiscono con il servizio di storage degli oggetti utilizzando un'interfaccia REST tramite il protocollo HTTP.

Il servizio di storage degli oggetti OCI è una soluzione di storage basata su cloud in cui Oracle gestisce la complessità di gestione, garantendo durabilità dei dati affidabile e a costi contenuti. L'elasticità della piattaforma consente un avvio graduale con la possibilità di scalare senza problemi, il tutto senza compromettere le prestazioni o l'affidabilità del servizio.

OCI Object Storage fornisce la compatibilità delle API con OpenStack Swift API e Amazon Simple Storage Service (Amazon S3) tramite l'API di compatibilità di Amazon S3. Ciò consente ai clienti di continuare a utilizzare gli strumenti esistenti (ad esempio, i client SDK), riducendo al minimo la necessità di apportare modifiche alle proprie applicazioni. Per ulteriori informazioni, vedere API di compatibilità Amazon S3. Questa esercitazione si concentrerà sul consumo delle API compatibili con OCI OpenStack Swift.

Prima di iniziare a discutere dell'API OpenStack Swift, dobbiamo chiarire alcuni dei costrutti utilizzati nello storage degli oggetti OCI.

Lo Swift OpenStack definisce tre costrutti: Account, Container e Object.

Ora possiamo identificare risorse equivalenti tra OCI Object Storage e OpenStack Swift API.

Obiettivi

Prerequisiti

Utilizza API OCI Swift

Gli endpoint regionali dell'API OCI Swift utilizzano un formato URL coerente https://swiftobjectstorage.<region-identifier>.oraclecloud.com. Ad esempio, l'endpoint API OCI Swift nativo nell'area orientale degli Stati Uniti (US-ashburn-1) è https://swiftobjectstorage.US-ashburn-1.oraclecloud.com.

Considerando l'isolamento a livello di tenant a livello di area, l'endpoint API Swift OCI diventa: https://swiftobjectstorage.<region-identifier>.oraclecloud.com/<tenancy-namespace>, dove <tenancy-namespace> è la stringa spazio di nomi dello storage degli oggetti generata automaticamente della tenancy in cui creare i repository. Per ulteriori informazioni, vedere Pagina Informazioni sulla tenancy.

L'API OCI Swift non ha il concetto di compartimento. Per impostazione predefinita, i bucket creati mediante l'API di compatibilità Amazon S3 OCI o l'API Swift OCI vengono creati nel compartimento root della tenancy Oracle Cloud Infrastructure. Puoi designare un compartimento diverso per l'API di compatibilità Amazon S3 OCI o l'API Swift OCI per creare bucket. Per ulteriori informazioni, vedere Modifica delle designazioni del compartimento API di compatibilità Amazon S3 della tenancy e Swift API.

OCI Swift API supporta tre approcci per autenticare le richieste.

Metodo 1: Usa intestazione autenticazione di base

Il nome utente ha il formato <username>. Ad esempio, john.doe@acme.com. Se la tenancy è federata con Oracle Identity Cloud Service, utilizzare il formato oracleidentitycloudservice/<username>.

La password è il token di autenticazione generato per l'utente. Ad esempio, my-auth-token. Per ulteriori informazioni, vedere Recupero di un token di autenticazione.

Ogni richiesta all'API OCI Swift deve includere la seguente intestazione.

Ad esempio, se il nome utente è oracleidentitycloudservice/john.doe@acme.com e la password è my-auth-token, l'intestazione avrà l'aspetto seguente:

Utilizzeremo alcune delle chiamate API descritte nella documentazione ufficiale, vedere OpenStack API Swift.

Esempio:

  1. Inizializzare le variabili di ambiente richieste riportate di seguito.

    user='<username>'
    password='<password>'
    region='<oci-region>'
    tenancy_namespace='<tenancy-namespace>'
    bucket_name='tutorial-bucket'
    object_name='sample.txt'
    
  2. Elenca i bucket nell'account. Verranno elencati solo i bucket dei compartimenti API OCI Swift selezionati.

    curl -sS -D /dev/stderr "https://swiftobjectstorage.${region}.oraclecloud.com/v1/${tenancy_namespace}" -u "${user}:${password}" | jq
    
  3. Creare un bucket.

    curl -sS -i "https://swiftobjectstorage.${region}.oraclecloud.com/v1/${tenancy_namespace}/${bucket_name}" -X PUT -u "${user}:${password}"
    
  4. Caricare un file nel bucket.

    echo 'sample file' > ${object_name}
    curl -s -i "https://swiftobjectstorage.${region}.oraclecloud.com/v1/${tenancy_namespace}/${bucket_name}/${object_name}" -X PUT --data-binary "@${object_name}" -u "${user}:${password}"
    
  5. Elenca il contenuto del bucket.

    curl -sS -D /dev/stderr "https://swiftobjectstorage.${region}.oraclecloud.com/v1/${tenancy_namespace}/${bucket_name}" -u "${user}:${password}" | jq
    
  6. Recupera un file dal bucket.

    curl -s -D /dev/stderr "https://swiftobjectstorage.${region}.oraclecloud.com/v1/${tenancy_namespace}/${bucket_name}/${object_name}" -u "${user}:${password}" -o downloaded_file.txt
    cat downloaded_file.txt
    
  7. Eliminare il file dal bucket.

    curl -sS -i "https://swiftobjectstorage.${region}.oraclecloud.com/v1/${tenancy_namespace}/${bucket_name}/${object_name}" -X DELETE -u "${user}:${password}"
    
  8. Eliminare il bucket.

    curl -s -i "https://swiftobjectstorage.${region}.oraclecloud.com/v1/${tenancy_namespace}/${bucket_name}" -X DELETE -u "${user}:${password}"
    

Approccio 2: autenticazione basata su token mediante l'autenticazione v1

Dovrai chiamare l'endpoint di autorizzazione API Swift OCI per l'area e includere le intestazioni X-Storage-User e X-Storage-Pass nella richiesta. Se la richiesta di autenticazione riesce, si riceverà una risposta con l'intestazione X-Storage-Token che può essere utilizzata per l'autorizzazione della richiesta e l'intestazione X-Storage-Url con l'endpoint API Swift OCI per l'account.

L'intestazione X-Storage-User ha il formato <tenancy-namespace>:<username>.

Ad esempio, se tenancy-namespace è axaxnpcrorw5 e il nome utente è uguale all'approccio 1, il valore dell'intestazione è axaxnpcrorw5:oracleidentitycloudservice/john.doe@acme.com.

X-Storage-Pass è il token di autenticazione generato.

Esempio:

  1. Inizializzare le variabili di ambiente richieste riportate di seguito.

    user='<username>'
    password='<password>'
    region='<oci-region>'
    tenancy_namespace='<tenancy-namespace>'
    bucket_name='tutorial-bucket'
    object_name='sample.txt'
    
  2. Genera un token.

    curl -sS -D swift_headers.txt https://swiftobjectstorage.eu-frankfurt-1.oraclecloud.com/auth/v1.0 -H "X-Storage-User: ${tenancy_namespace}:${user}" -H "X-Storage-Pass: ${password}"
    X_Auth_Token=$(cat swift_headers.txt | grep X-Auth-Token | cut -d":" -f 2)
    
  3. Elenca i bucket nell'account. Verranno elencati solo i bucket dei compartimenti API OCI Swift selezionati.

    curl -s -D /dev/stderr "https://swiftobjectstorage.${region}.oraclecloud.com/v1/${tenancy_namespace}" -H "X-Auth-Token: ${X_Auth_Token}" | jq
    
  4. Creare un bucket.

    curl -s -i "https://swiftobjectstorage.${region}.oraclecloud.com/v1/${tenancy_namespace}/${bucket_name}" -X PUT -H "X-Auth-Token: ${X_Auth_Token}"
    
  5. Caricare un file nel bucket.

    echo 'sample file' > ${object_name}
    curl -s -i "https://swiftobjectstorage.${region}.oraclecloud.com/v1/${tenancy_namespace}/${bucket_name}/${object_name}" -X PUT --data-binary "@${object_name}" -H "X-Auth-Token: ${X_Auth_Token}"
    
  6. Elenca il contenuto del bucket.

    curl -s -D /dev/stderr "https://swiftobjectstorage.${region}.oraclecloud.com/v1/${tenancy_namespace}/${bucket_name}" -H "X-Auth-Token: ${X_Auth_Token}" | jq
    
  7. Recupera un file dal bucket.

    curl -s -D /dev/stderr "https://swiftobjectstorage.${region}.oraclecloud.com/v1/${tenancy_namespace}/${bucket_name}/${object_name}" -H "X-Auth-Token: ${X_Auth_Token}" -o downloaded_file.txt
    cat downloaded_file.txt
    
  8. Eliminare il file dal bucket.

    curl -s -i "https://swiftobjectstorage.${region}.oraclecloud.com/v1/${tenancy_namespace}/${bucket_name}/${object_name}" -X DELETE -H "X-Auth-Token: ${X_Auth_Token}"
    
  9. Eliminare il bucket.

    curl -s -i "https://swiftobjectstorage.${region}.oraclecloud.com/v1/${tenancy_namespace}/${bucket_name}" -X DELETE -H "X-Auth-Token: ${X_Auth_Token}"
    

Approccio 3: autenticazione basata su token mediante l'autenticazione v2

Per illustrare la procedura di autorizzazione OCI Swift API v2, utilizzeremo il pacchetto ufficiale OpenStack Swift API Python python-swiftclient 4.5.0 e le dipendenze richieste per l'autenticazione v2 python-keystoneclient 5.4.0.

Esempio:

  1. Eseguire il comando seguente per assicurarsi di avere accesso a una versione di Python superiore a 3.6. Per ulteriori informazioni, vedere Download di Python.

    python3 --version
    
  2. Installare i moduli Python necessari.

    python3 -m pip install python-swiftclient python-keystoneclient click
    
  3. Puoi utilizzare il codice seguente per interagire con l'API OCI Swift v2. Prima di eseguire, assicurarsi di sostituire i segnaposto per <user>, <password>, <region> e <tenancy-namespace> nel codice seguente.

    import click
    import os
    
    from swiftclient.client import Connection
    from swiftclient.exceptions import ClientException
    
    user='<username>'
    password='<password>'
    region='<oci-region>'
    tenancy_namespace='<tenancy-namespace>'
    bucket_name='tutorial-bucket'
    object_name='sample.txt'
    
    _authurl = f'https://swiftobjectstorage.{region}.oraclecloud.com/auth/v2.0/'
    _auth_version = '2'
    _user = f'{user}'
    _key = f'{password}'
    _tenant_name = f'{tenancy_namespace}'
    
    conn = Connection(
        authurl=_authurl,
        user=_user,
        key=_key,
        tenant_name=_tenant_name,
        auth_version=_auth_version
    )
    
    @click.group(invoke_without_command=True)
    @click.pass_context
    def main(ctx):
        available_commands = {
            "a": ("List buckets in the account", get_account),
            "b": ("Create a new bucket", put_container),
            "c": ("Upload an object to the bucket", put_object),
            "d": ("List objects in the bucket", get_container),
            "e": ("Download object from the bucket", get_object),
            "f": ("Delete object from the bucket", delete_object),
            "g": ("Delete bucket from the account", delete_container)
        }
        while True:
            click.echo("Available actions")
            for index, command in available_commands.items():
                click.echo(f"{index} - {command[0]}")
            action = click.prompt("Please select an option from the list")
            if action in available_commands.keys():
                ctx.invoke(available_commands[action][1])
            print("###"*10)
    
    @main.command()
    def get_account(conn=conn):
        print("Listing buckets in the account.")
        try:
            resp_headers = conn.get_account()
            for entry in resp_headers[1]:
                print(entry["name"])
        except ClientException as e:
            print(f"Failed to get the buckets in the tenancy. Error: {e}")
            raise
        else:
            print(f"Successfuly listed bucket in the '{_tenant_name}' account.")
    
    @main.command()
    def put_container(conn=conn, bucket_name=bucket_name):
        print(f"Creating a new bucket named {bucket_name}.")
        try:
            resp_headers = conn.put_container(container=bucket_name)
        except ClientException as e:
            print(f"Failed to create the new bucket named {bucket_name} in the tenancy. Error: {e}")
            raise
        else:
            print(f"The '{bucket_name}' was successfuly created.")
    
    @main.command()
    def put_object(conn=conn, bucket_name=bucket_name, object_name=object_name):
        print(f"Uploading a new file, '{object_name}' to the new bucket '{bucket_name}'.")
        try:
            if not os.path.isfile(object_name):
                with open(object_name, "w") as f:
                    f.write("sample file")
            with open(object_name) as f:
                resp_headers = conn.put_object(container=bucket_name, obj=object_name, contents=object_name)
        except ClientException as e:
            print(f"Failed to create a new object named '{object_name}' in the bucket '{bucket_name}'. Error: {e}")
            raise
        else:
            print(f"The '{object_name}' file was successfuly uploaded to '{bucket_name}' bucket.")
    
    @main.command()
    def get_container(conn=conn, bucket_name=bucket_name):
        print(f"List {bucket_name} bucket contents.")
        try:
            resp_headers = conn.get_container(container=bucket_name)
            for entry in resp_headers[1]:
                print(entry["name"])
        except ClientException as e:
            print(f"Failed to list objects in the bucket {bucket_name}. Error: {e}")
            raise
        else:
            print(f"The '{bucket_name}' content was successfuly listed.")
    
    @main.command()
    def get_object(conn=conn, bucket_name=bucket_name, object_name=object_name, dest_file="downloaded_file.txt"):
        print(f"Fetch {object_name} object from the bucket {bucket_name}.")
        try:
            resp_headers = conn.get_object(container=bucket_name, obj=object_name)
            with open(dest_file, "wb") as f:
                f.write(resp_headers[1])
        except ClientException as e:
            print(f"Failed to download {object_name} from {bucket_name} to local file named '{dest_file}'. Error: {e}")
            raise
        else:
            print(f"The '{object_name}' object was saved locally to '{dest_file}'.")
    
    @main.command()
    def delete_object(conn=conn, bucket_name=bucket_name, object_name=object_name):
        print(f"Deleting {object_name} object from the bucket {bucket_name}.")
        try:
            resp_headers = conn.delete_object(container=bucket_name, obj=object_name)
        except ClientException as e:
            print(f"Failed to delete {object_name} from {bucket_name}. Error: {e}")
            raise
        else:
            print(f"The '{object_name}' object was deleted.")
    
    @main.command()
    def delete_container(conn=conn, bucket_name=bucket_name):
        print(f"Deleting the bucket {bucket_name}.")
        try:
            resp_headers = conn.delete_container(container=bucket_name)
        except ClientException as e:
            print(f"Failed to delete {object_name} from {bucket_name}. Error: {e}")
            raise
        else:
            print(f"The '{bucket_name}' bucket was deleted.")
    
    
    if __name__ == "__main__":
        main()
    

Conferme

Altre risorse di apprendimento

Esplora altri laboratori su docs.oracle.com/learn o accedi a più contenuti gratuiti sulla formazione su Oracle Learning YouTube channel. Inoltre, visita education.oracle.com/learning-explorer per diventare un Oracle Learning Explorer.

Per la documentazione del prodotto, visita l'Oracle Help Center.