Hinweis:

Oracle Cloud Infrastructure Object Storage Service mit der Swift-API OpenStack verwenden

Einführung

Oracle Cloud Infrastructure (OCI) Object Storage ist eine Datenspeicherarchitektur, die digitale Informationen als Objekte verwaltet und organisiert, die jeweils Daten, Metadaten und eine eindeutige ID umfassen. Im Gegensatz zu herkömmlichem Datei- oder Blockspeicher basiert OCI Object Storage nicht auf einer hierarchischen Struktur, die eine effiziente und skalierbare Verarbeitung großer Mengen unstrukturierter Daten ermöglicht. Objekte werden in einem flachen Adressraum gespeichert, was den Datenabruf vereinfacht und eine nahtlose Skalierbarkeit ermöglicht. Diese Lösung eignet sich ideal für verschiedene Datentypen wie Multimedia-Inhalte und Backups und ist aufgrund ihrer Flexibilität, Dauerhaftigkeit und Benutzerfreundlichkeit eine robuste Wahl für Cloud-Umgebungen, Archivspeicher und verteilte Systeme. Benutzer interagieren mit dem Objektspeicherservice über eine REST-Schnittstelle über das HTTP-Protokoll.

Der OCI Object Storage-Service ist eine cloudbasierte Speicherlösung, bei der Oracle die Managementkomplexität bewältigt und eine zuverlässige und kostengünstige Dauerhaftigkeit der Daten gewährleistet. Die Elastizität der Plattform ermöglicht einen schrittweisen Start mit der Fähigkeit, nahtlos zu skalieren, ohne die Leistung oder die Service-Zuverlässigkeit zu beeinträchtigen.

OCI Object Storage bietet API-Kompatibilität mit der OpenStack Swift-API und dem Amazon Simple Storage Service (Amazon S3) über die Amazon S3-Kompatibilitäts-API. Auf diese Weise können Kunden ihre vorhandenen Tools (z. B. SDK-Clients) weiterhin verwenden und so die Notwendigkeit minimieren, Änderungen an ihren Anwendungen vorzunehmen. Weitere Informationen finden Sie unter Amazon S3-Kompatibilitäts-API. In diesem Tutorial wird der Schwerpunkt auf der OCI OpenStack Swift-kompatiblen API-Nutzung gelegt.

Bevor wir mit der Diskussion über die Swift-API OpenStack beginnen, müssen wir einige der in OCI Object Storage verwendeten Konstrukte klären.

Der OpenStack Swift definiert drei Konstrukte: Account, Container und Object.

Jetzt können wir äquivalente Ressourcen zwischen OCI Object Storage und der OpenStack Swift-API identifizieren.

Ziele

Voraussetzungen

OCI Swift-API verwenden

Die regionalen OCI Swift-API-Endpunkte verwenden ein konsistentes URL-Format von https://swiftobjectstorage.<region-identifier>.oraclecloud.com. Beispiel: Der native OCI Swift-API-Endpunkt in der Region "US East" (us-ashburn-1) lautet https://swiftobjectstorage.us-ashburn-1.oraclecloud.com.

Angesichts der Isolation auf Mandantenebene auf Regionsebene wird der OCI-Swift-API-Endpunkt zu https://swiftobjectstorage.<region-identifier>.oraclecloud.com/<tenancy-namespace>, wobei <tenancy-namespace> die automatisch generierte Object Storage-Namespace-Zeichenfolge des Mandanten ist, in dem Repositorys erstellt werden sollen. Weitere Informationen finden Sie unter Seite "Mandanteninformationen".

OCI Swift-API fehlt das Konzept des Compartments. Standardmäßig werden Buckets, die mit der OCI-Amazon S3-Kompatibilitäts-API oder der OCI-Swift-API erstellt werden, im root-Compartment des Oracle Cloud Infrastructure-Mandanten erstellt. Sie können ein anderes Compartment für die OCI-Amazon S3-Kompatibilitäts-API oder die OCI Swift-API zum Erstellen von Buckets festlegen. Weitere Informationen finden Sie unter Bezeichnungen der Amazon S3-Kompatibilitäts-API und der Swift-API-Compartments des Mandanten bearbeiten.

Die OCI Swift-API unterstützt drei Ansätze zur Authentifizierung von Anforderungen.

Ansatz 1: Basisauthentifizierungsheader verwenden

Der Benutzername hat das Format <username>. Beispiel: john.doe@acme.com. Wenn Ihr Mandant mit Oracle Identity Cloud Service föderiert ist, verwenden Sie das Format oracleidentitycloudservice/<username>.

Das Kennwort ist das Authentifizierungstoken, das für den Benutzer generiert wurde. Beispiel: my-auth-token. Weitere Informationen finden Sie unter Authentifizierungstoken abrufen.

Jede Anforderung an die OCI Swift-API muss den folgenden Header enthalten.

Beispiel: Wenn der Benutzername oracleidentitycloudservice/john.doe@acme.com und das Kennwort my-auth-token lautet, sieht der Header wie folgt aus:

Wir verwenden einige der in der offiziellen Dokumentation beschriebenen API-Aufrufe, siehe OpenStack Swift API.

Beispiel:

  1. Initialisieren Sie die folgenden erforderlichen Umgebungsvariablen.

    user='<username>'
    password='<password>'
    region='<oci-region>'
    tenancy_namespace='<tenancy-namespace>'
    bucket_name='tutorial-bucket'
    object_name='sample.txt'
    
  2. Listen Sie Buckets im Account auf. Nur Buckets aus den ausgewählten OCI Swift-API-Compartments werden aufgelistet.

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

    curl -sS -i "https://swiftobjectstorage.${region}.oraclecloud.com/v1/${tenancy_namespace}/${bucket_name}" -X PUT -u "${user}:${password}"
    
  4. Laden Sie eine Datei in den Bucket hoch.

    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. Listen Sie den Bucket-Inhalt auf.

    curl -sS -D /dev/stderr "https://swiftobjectstorage.${region}.oraclecloud.com/v1/${tenancy_namespace}/${bucket_name}" -u "${user}:${password}" | jq
    
  6. Rufen Sie eine Datei aus dem Bucket ab.

    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. Löschen Sie die Datei aus dem Bucket.

    curl -sS -i "https://swiftobjectstorage.${region}.oraclecloud.com/v1/${tenancy_namespace}/${bucket_name}/${object_name}" -X DELETE -u "${user}:${password}"
    
  8. Löschen Sie den Bucket.

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

Ansatz 2: Tokenbasierte Authentifizierung mit der v1-Authentifizierung

Sie müssen den OCI Swift-API-Autorisierungsendpunkt für die Region aufrufen und die Header X-Storage-User und X-Storage-Pass in die Anforderung aufnehmen. Wenn die Authentifizierungsanforderung erfolgreich ist, erhalten Sie eine Antwort mit dem Header X-Storage-Token, der für die Anforderungsautorisierung verwendet werden kann, und einen Header X-Storage-Url mit dem OCI Swift-API-Endpunkt für den Account.

Der X-Storage-User-Header hat das Format <tenancy-namespace>:<username>.

Beispiel: Wenn tenancy-namespace axaxnpcrorw5 ist und der Benutzername mit Ansatz 1 identisch ist, lautet der Wert des Headers axaxnpcrorw5:oracleidentitycloudservice/john.doe@acme.com.

X-Storage-Pass ist das generierte Authentifizierungstoken.

Beispiel:

  1. Initialisieren Sie die folgenden erforderlichen Umgebungsvariablen.

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

    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. Listen Sie Buckets im Account auf. Nur Buckets aus den ausgewählten OCI Swift-API-Compartments werden aufgelistet.

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

    curl -s -i "https://swiftobjectstorage.${region}.oraclecloud.com/v1/${tenancy_namespace}/${bucket_name}" -X PUT -H "X-Auth-Token: ${X_Auth_Token}"
    
  5. Laden Sie eine Datei in den Bucket hoch.

    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. Listen Sie den Bucket-Inhalt auf.

    curl -s -D /dev/stderr "https://swiftobjectstorage.${region}.oraclecloud.com/v1/${tenancy_namespace}/${bucket_name}" -H "X-Auth-Token: ${X_Auth_Token}" | jq
    
  7. Rufen Sie eine Datei aus dem Bucket ab.

    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. Löschen Sie die Datei aus dem 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. Löschen Sie den Bucket.

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

Ansatz 3: Tokenbasierte Authentifizierung mit der v2-Authentifizierung

Zur Veranschaulichung der Autorisierungsprozedur der OCI Swift-API v2 verwenden wir das offizielle OpenStack Swift API Python-Package python-swiftclient 4.5.0 und die erforderlichen Abhängigkeiten für die v2-Authentifizierung python-keystoneclient 5.4.0.

Beispiel:

  1. Führen Sie den folgenden Befehl aus, um sicherzustellen, dass Sie Zugriff auf eine Python-Version über 3.6 haben. Weitere Informationen finden Sie unter Python herunterladen.

    python3 --version
    
  2. Installieren Sie die erforderlichen Python-Module.

    python3 -m pip install python-swiftclient python-keystoneclient click
    
  3. Sie können den folgenden Code für die Interaktion mit der OCI Swift-API v2 verwenden. Stellen Sie sicher, dass Sie die Platzhalter für <user>, <password>, <region> und <tenancy-namespace> im folgenden Code vor der Ausführung ersetzen.

    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()
    

Danksagungen

Weitere Lernressourcen

Lernen Sie andere Übungen auf docs.oracle.com/learn kennen, oder greifen Sie auf weitere kostenlose Lerninhalte im Oracle Learning YouTube Channel zu. Außerdem können Sie education.oracle.com/learning-explorer besuchen, um Oracle Learning Explorer zu werden.

Die Produktdokumentation finden Sie im Oracle Help Center.