Beispiele für externen Netzwerkzugriff

Dieses Thema enthält Beispiele für den Zugriff auf externe Netzwerkstandorte über benutzerdefinierte Funktionen und Prozeduren.

Zugriff auf die Google Translate API mit OAuth

Die folgenden Schritte umfassen Code zum Erstellen einer Integration für den externen Zugriff für den Zugriff auf die Google Translate-API. Die Schritte fügen die Sicherheitsintegration und die für die Ausführung der Anweisungen erforderlichen Berechtigungen hinzu.

  1. Erstellen Sie eine Netzwerkregel, die den externen Standort repräsentiert.

    Weitere Informationen zur Rolle einer Netzwerkregel beim externen Zugriff, einschließlich der erforderlichen Berechtigungen, finden Sie unter Erstellen einer Netzwerkregel zur Darstellung des externen Netzwerkstandorts.

    CREATE OR REPLACE NETWORK RULE google_apis_network_rule
      MODE = EGRESS
      TYPE = HOST_PORT
      VALUE_LIST = ('translation.googleapis.com');
    
    Copy
  2. Erstellen Sie eine Sicherheitsintegration, die die OAuth-Anmeldeinformationen enthält, die für die Authentifizierung bei dem durch die Netzwerkregel google_apis_network_rule angegebenen externen Netzwerkstandort erforderlich sind.

    Referenzinformationen zu diesem Befehl, einschließlich der erforderlichen Berechtigungen, finden Sie unter CREATE SECURITY INTEGRATION (Externe API-Authentifizierung).

    CREATE OR REPLACE SECURITY INTEGRATION google_translate_oauth
      TYPE = API_AUTHENTICATION
      AUTH_TYPE = OAUTH2
      OAUTH_CLIENT_ID = 'my-client-id'
      OAUTH_CLIENT_SECRET = 'my-client-secret'
      OAUTH_TOKEN_ENDPOINT = 'https://oauth2.googleapis.com/token'
      OAUTH_AUTHORIZATION_ENDPOINT = 'https://accounts.google.com/o/oauth2/auth'
      OAUTH_ALLOWED_SCOPES = ('https://www.googleapis.com/auth/cloud-platform')
      ENABLED = TRUE;
    
    Copy
  3. Erstellen Sie ein Geheimnis, das die in der Sicherheitsintegration google_translate_oauth enthaltenen Anmeldeinformationen darstellt.

    Weitere Informationen zur Rolle des Geheimnisses beim externen Zugriff, einschließlich der erforderlichen Berechtigungen, finden Sie unter Erstellen eines Geheimnisses zur Darstellung von Anmeldeinformationen.

    Das Geheimnis muss mit seinem Parameter OAUTH_REFRESH_TOKEN ein Aktualisierungstoken angeben. Um einen Aktualisierungstoken vom Dienstanbieter (in diesem Fall vom Google Cloud Translation API-Dienst) zu erhalten, können Sie eine vom Anbieter angebotene Methode oder die Snowflake-Systemfunktionen verwenden.

    Um ein Geheimnis mit einem Aktualisierungstoken zu erstellen, verwenden Sie entweder Google OAuth Playground- oder Snowflake-Systemfunktionen, wie im Folgenden beschrieben:

    • Snowflake-Systemfunktionen

      1. Führen Sie CREATE SECRET aus, um ein Geheimnis zu erstellen. Sie werden es in einem späteren Schritt mit dem Aktualisierungstoken aktualisieren.

        USE DATABASE my_db;
        USE SCHEMA secret_schema;
        
        CREATE OR REPLACE SECRET oauth_token
          TYPE = oauth2
          API_AUTHENTICATION = google_translate_oauth;
        
        Copy
      2. Führen Sie die Funktion SYSTEM$START_OAUTH_FLOW aus, um eine URL abzurufen, mit der Sie ein Aktualisierungstoken erhalten können, und geben Sie als Argument den Namen des zuvor erstellten Geheimnisses an.

        CALL SYSTEM$START_OAUTH_FLOW( 'my_db.secret_schema.oauth_token' );
        
        Copy

        Die Funktion generiert eine URL, die Sie verwenden können, um den OAuth-Zustimmungsprozess abzuschließen.

      3. Wechseln Sie in einem Browser zu der generierten URL, und schließen Sie den OAuth2-Zustimmungsprozess ab. Wenn Sie fertig sind, lassen Sie den Browser auf der letzten Seite des Prozesses geöffnet.

      4. Kopieren Sie in der Adressleiste des Browsers von der URL der letzten Seite des Zustimmungsprozesses den gesamten Text, der nach dem Fragezeichen folgt.

      5. Führen Sie die Funktion SYSTEM$FINISH_OAUTH_FLOW aus und geben Sie als Argument die Parameter an, die Sie soeben aus der Adressleiste des Browsers kopiert haben, um das Geheimnis mit einem Refresh-Token zu aktualisieren.

        Achten Sie darauf, SYSTEM$FINISH_OAUTH_FLOW in der gleichen Sitzung wie SYSTEM$START_OAUTH_FLOW auszuführen. SYSTEM$FINISH_OAUTH_FLOW aktualisiert das Geheimnis, das Sie in SYSTEMangegeben haben $START_OAUTH_FLOW mit dem Zugriffstoken und dem Refresh-Token, die es vom OAuth-Server erhalten hat.

        CALL SYSTEM$FINISH_OAUTH_FLOW( 'state=<remaining_url_text>' );
        
        Copy
    • Google OAuth Playground

      1. Wählen Sie in Google OAuth Playground wie in Schritt 1 angegeben die Cloud Translation API aus, und autorisieren Sie sie.

      2. Klicken Sie in Schritt 2 auf exchange authorization code for tokens und kopieren Sie dann den Wert des Tokens refresh token.

      3. Führen Sie CREATE SECRET aus, um ein Geheimnis zu erstellen, das den von Ihnen kopierten Wert des Aktualisierungstokens angibt.

        Weitere Informationen zur Rolle eines Geheimnisses beim externen Zugriff, einschließlich der erforderlichen Berechtigungen, finden Sie unter Erstellen eines Geheimnisses zur Darstellung von Anmeldeinformationen.

        CREATE OR REPLACE SECRET oauth_token
          TYPE = oauth2
          API_AUTHENTICATION = google_translate_oauth
          OAUTH_REFRESH_TOKEN = 'my-refresh-token';
        
        Copy
  4. Erstellen Sie eine Integration für den externen Zugriff unter Verwendung der Netzwerkregel und des Geheimnisses.

    Weitere Informationen zur Rolle einer Integration für den externen Zugriff, einschließlich der erforderlichen Berechtigungen, finden Sie unter Erstellen einer Integration für den externen Zugriff.

    CREATE OR REPLACE EXTERNAL ACCESS INTEGRATION google_apis_access_integration
      ALLOWED_NETWORK_RULES = (google_apis_network_rule)
      ALLOWED_AUTHENTICATION_SECRETS = (oauth_token)
      ENABLED = TRUE;
    
    Copy
  5. Erstellen Sie eine Rolle developer, die Benutzern zugewiesen wird, die eine UDF oder Prozedur erstellen müssen, die die Integration verwendet.

    CREATE OR REPLACE ROLE developer;
    CREATE OR REPLACE ROLE user;
    
    Copy
  6. Erteilen Sie der Rolle developer die erforderlichen Berechtigungen, um eine UDF zu erstellen, die die Objekte für den externen Zugriff verwendet. Dazu zählen:

    • READ-Berechtigungen für das Geheimnis.

    • USAGE-Berechtigung für das Schema, das das Geheimnis enthält.

    • USAGE-Berechtigungen für die Integration.

      GRANT READ ON SECRET oauth_token TO ROLE developer;
      GRANT USAGE ON SCHEMA secret_schema TO ROLE developer;
      GRANT USAGE ON INTEGRATION google_apis_access_integration TO ROLE developer;
      
      Copy
  7. Erstellen Sie einer UDF google_translate_python, die den angegebenen Text in einen Ausdruck in der angegebenen Sprache übersetzt. Weitere Informationen dazu finden Sie unter Verwendung der Integration für den externen Zugriff in einer Funktion oder Prozedur.

    USE ROLE developer;
    
    CREATE OR REPLACE FUNCTION google_translate_python(sentence STRING, language STRING)
    RETURNS STRING
    LANGUAGE PYTHON
    RUNTIME_VERSION = 3.9
    HANDLER = 'get_translation'
    EXTERNAL_ACCESS_INTEGRATIONS = (google_apis_access_integration)
    PACKAGES = ('snowflake-snowpark-python','requests')
    SECRETS = ('cred' = oauth_token )
    AS
    $$
    import _snowflake
    import requests
    import json
    session = requests.Session()
    def get_translation(sentence, language):
      token = _snowflake.get_oauth_access_token('cred')
      url = "https://translation.googleapis.com/language/translate/v2"
      data = {'q': sentence,'target': language}
      response = session.post(url, json = data, headers = {"Authorization": "Bearer " + token})
      return response.json()['data']['translations'][0]['translatedText']
    $$;
    
    Copy
  8. Erteilen Sie die USAGE-Berechtigung an die Funktion google_translate_python, damit Personen mit der Rolle user sie aufrufen können.

    GRANT USAGE ON FUNCTION google_translate_python(string, string) TO ROLE user;
    
    Copy
  9. Führen Sie die Funktion google_translate_python aus, um einen Ausdruck zu übersetzen.

    USE ROLE user;
    
    SELECT google_translate_python('Happy Thursday!', 'zh-CN');
    
    Copy

    Dies erzeugt die folgende Ausgabe.

    -------------------------------------------------------
    | GOOGLE_TRANSLATE_PYTHON('HAPPY THURSDAY!', 'ZH-CN') |
    -------------------------------------------------------
    | 快乐星期四!                                          |
    -------------------------------------------------------
    

Zugriff auf eine externe Lambda-Funktion mit einfacher Authentifizierung

Die folgenden Schritte umfassen Beispielcode zum Erstellen einer Integration für den externen Zugriff auf eine Lambda-Funktion außerhalb von Snowflake. Im Beispiel wird ein Platzhalter für den externen Endpunkt selbst verwendet, es könnte sich aber auch um eine Funktion handeln, die z. B. an einem REST-Dienstendpunkt verfügbar ist.

Der externe Zugriff wird in einer vektorisierten Python-UDF verwendet, die ein Pandas-DataFrame mit den Daten erhält.

  1. Erstellen Sie eine Netzwerkregel lambda_network_rule, die den externen Standort my_external_service repräsentiert (hier ein Platzhalterwert für den Standort eines externen Endpunkts).

    Weitere Informationen zur Rolle einer Netzwerkregel beim externen Zugriff finden Sie unter Erstellen einer Netzwerkregel zur Darstellung des externen Netzwerkstandorts.

    CREATE OR REPLACE NETWORK RULE lambda_network_rule
      MODE = EGRESS
      TYPE = HOST_PORT
      VALUE_LIST = ('my_external_service');
    
    Copy
  2. Erstellen Sie ein Geheimnis, das die für den externen Dienst erforderlichen Anmeldeinformationen darstellt.

    Der Handler-Code später in diesem Beispiel ruft die Anmeldeinformationen aus dem Geheimnis mit einer Snowflake-API für Python ab.

    Weitere Informationen zur Rolle des Geheimnisses beim externen Zugriff finden Sie unter Erstellen eines Geheimnisses zur Darstellung von Anmeldeinformationen.

    CREATE OR REPLACE SECRET secret_password
      TYPE = PASSWORD
      USERNAME = 'my_user_name'
      PASSWORD = 'my_password';
    
    Copy
  3. Erstellen Sie eine Rolle developer und erteilen Sie ihr READ-Berechtigungen für das Geheimnis. Diese Rolle wird Benutzern zugewiesen, die eine UDF oder Prozedur erstellen müssen, die das Geheimnis verwendet.

    Erstellen Sie außerdem die Rolle, mit der die Benutzer die Funktion aufrufen werden.

    CREATE OR REPLACE ROLE developer;
    CREATE OR REPLACE ROLE user;
    
    Copy
  4. Erteilen Sie der Rolle developer die erforderlichen Berechtigungen, um eine UDF zu erstellen, die die Objekte für den externen Zugriff verwendet. Dazu zählen:

    • READ-Berechtigungen für das Geheimnis.

    • USAGE-Berechtigung für das Schema, das das Geheimnis enthält.

    GRANT READ ON SECRET secret_password TO ROLE developer;
    GRANT USAGE ON SCHEMA secret_schema TO ROLE developer;
    
    Copy
  5. Erstellen Sie eine Integration für den externen Zugriff, um den externen Endpunkt und die Anmeldeinformationen über die von Ihnen erstellte Netzwerkregel und das Geheimnis anzugeben.

    Weitere Informationen zur Rolle einer Integration für den externen Zugriff, einschließlich der erforderlichen Berechtigungen, finden Sie unter Erstellen einer Integration für den externen Zugriff.

    CREATE OR REPLACE EXTERNAL ACCESS INTEGRATION lambda_external_access_integration
      ALLOWED_NETWORK_RULES = (lambda_network_rule)
      ALLOWED_AUTHENTICATION_SECRETS = (secret_password)
      ENABLED = TRUE;
    
    Copy
  6. Erstellen Sie eine vektorisiertes Python-UDF return_double_column, die auf einen externen Netzwerkstandort zugreift, um als Pandas-DataFrame empfangene Daten zu verarbeiten.

    Weitere Informationen zur Verwendung des externen Zugriffs in einer UDF finden Sie unter Verwendung der Integration für den externen Zugriff in einer Funktion oder Prozedur.

    CREATE OR REPLACE FUNCTION return_double_column(x int)
    RETURNS INT
    LANGUAGE PYTHON
    EXTERNAL_ACCESS_INTEGRATIONS = (lambda_external_access_integration)
    SECRETS = ('cred' = secret_password)
    RUNTIME_VERSION = 3.9
    HANDLER = 'return_first_column'
    PACKAGES = ('pandas', 'requests')
    AS $$
    import pandas
    import numpy as np
    import json
    import requests
    import base64
    import _snowflake
    from _snowflake import vectorized
    from requests.auth import HTTPBasicAuth
    from requests.adapters import HTTPAdapter
    from requests.packages.urllib3.util.retry import Retry
    
    session = requests.Session()
    retries = Retry(total=10, backoff_factor=1, status_forcelist=[429, 500, 502, 503, 504], allowed_methods = None)
    
    session.mount('https://', HTTPAdapter(max_retries=retries))
    
    @vectorized(input=pandas.DataFrame)
    def return_first_column(df):
      request_rows = []
    
      df.iloc[:,0] = df.iloc[:,0].astype(int)
      request_rows = np.column_stack([df.index, df.iloc[:,0]]).tolist()
    
      request_payload = {"data" : request_rows}
    
      username_password_object = _snowflake.get_username_password('cred');
      basic = HTTPBasicAuth(username_password_object.username, username_password_object.password)
    
      url = 'my_external_service'
    
      response = session.post(url, json=request_payload, auth=basic)
    
      response.raise_for_status()
      response_payload = json.loads(response.text)
    
      response_rows = response_payload["data"]
    
      return pandas.DataFrame(response_rows)[1]
    $$;
    
    Copy
  7. Erteilen Sie die USAGE-Berechtigung an die Funktion return_double_column, damit Personen mit der Rolle user sie aufrufen können.

    GRANT USAGE ON FUNCTION return_double_column(int) TO ROLE user;
    
    Copy
  8. Führen Sie die Funktion return_double_column aus und stellen Sie eine Anfrage an den externen Endpunkt.

    Der Code im folgenden Beispiel erstellt eine zweispaltige Tabelle und fügt 100.000.000 Zeilen mit 4-Byte-Ganzzahlen ein. Der Code führt dann die Funktion return_double_column aus und übergibt Werte aus Spalte a zur Verarbeitung durch den externen Endpunkt.

    CREATE OR REPLACE TABLE t1 (a INT, b INT);
    INSERT INTO t1 SELECT SEQ4(), SEQ4() FROM TABLE(GENERATOR(ROWCOUNT => 100000000));
    
    SELECT return_double_column(a) AS retval FROM t1 ORDER BY retval;
    
    Copy

Zugriff auf Amazon S3 mit AWS IAM

Die folgenden Schritte umfassen einen Beispielcode zur Verbindung mit einem AWS S3 Bucket über IAM.

Weitere Informationen über AWS IAM finden Sie in der AWS IAM-Dokumentation.

  1. Erstellen Sie eine Netzwerkregel, aws_s3_network_rule, die den AWS S3 Bucket an dem durch den VALUE_LIST-Parameter angegebenen Speicherort darstellt.

    Weitere Informationen zur Rolle einer Netzwerkregel beim externen Zugriff finden Sie unter Erstellen einer Netzwerkregel zur Darstellung des externen Netzwerkstandorts.

    CREATE OR REPLACE NETWORK RULE aws_s3_network_rule
      MODE = EGRESS
      TYPE = PRIVATE_HOST_PORT
      VALUE_LIST = ('external-access-iam-bucket.s3.us-west-2.amazonaws.com');
    
    Copy
  2. Erstellen Sie eine Sicherheitsintegration, um die AWS IAM Amazon Resource Name (ARN) Anmeldeinformationen zu speichern, die für die Authentifizierung mit dem externen Speicherort des Netzwerks erforderlich sind, der in der aws_s3_network_rule-Netzwerkregel angegeben ist.

    Referenzinformationen zu diesem Befehl, einschließlich der erforderlichen Berechtigungen, finden Sie unter CREATE SECURITY INTEGRATION (AWS IAM-Authentifizierung).

    CREATE OR REPLACE SECURITY INTEGRATION aws_s3_security_integration
      TYPE = API_AUTHENTICATION
      AUTH_TYPE = AWS_IAM
      ENABLED = TRUE
      AWS_ROLE_ARN = 'arn:aws:iam::736112632310:role/external-access-iam-bucket';
    
    Copy
  3. Holen Sie sich die ARN und ID für die IAM USER.

    1. Führen Sie den DESC-Befehl für die von Ihnen erstellte Integration der Sicherheit aus.

      DESC SECURITY INTEGRATION aws_s3_security_integration;
      
      Copy
    2. Kopieren Sie aus der angezeigten Ausgabe die Werte der folgenden Eigenschaften zur Verwendung im nächsten Schritt:

      • API_AWS_IAM_USER_ARN

      • API_AWS_EXTERNAL_ID

  4. Erteilen Sie dem IAM-Benutzer Berechtigungen, die für den Zugriff auf den Bucket erforderlich sind.

    Verwenden Sie die Werte ARN und ID, wenn Sie eine Vertrauensrichtlinie konfigurieren, wie in Schritt 5 von Option 1: Konfigurieren einer Snowflake-Speicherintegration für Zugriff auf Amazon S3 beschrieben.

  5. Erstellen Sie ein secret vom Typ CLOUD_PROVIDER_TOKEN, um die Anmeldeinformationen darzustellen, die für den externen Dienst erforderlich sind.

    Der Handler-Code später in diesem Beispiel ruft die Anmeldeinformationen aus dem Geheimnis mit einer Snowflake-API ab.

    Weitere Informationen zur Rolle des Geheimnisses beim externen Zugriff finden Sie unter Erstellen eines Geheimnisses zur Darstellung von Anmeldeinformationen.

    CREATE OR REPLACE SECRET aws_s3_access_token
      TYPE = CLOUD_PROVIDER_TOKEN
      API_AUTHENTICATION = aws_s3_security_integration;
    
    Copy
  6. Erstellen Sie eine Rolle developer und erteilen Sie ihr READ-Berechtigungen für das Geheimnis. Diese Rolle wird Benutzern zugewiesen, die eine UDF oder Prozedur erstellen müssen, die das Geheimnis verwendet.

    Erstellen Sie außerdem die Rolle, mit der die Benutzer die Funktion aufrufen werden.

    CREATE OR REPLACE ROLE developer;
    CREATE OR REPLACE ROLE user;
    
    Copy
  7. Gewähren Sie der developer-Rolle die Berechtigungen, die erforderlich sind, um eine UDF zu erstellen, die die Objekte für den externen Zugriff verwendet. Dazu zählen:

    • READ-Berechtigungen für das Geheimnis.

    • USAGE-Berechtigung für das Schema, das das Geheimnis enthält.

    GRANT READ ON SECRET aws_s3_access_token TO ROLE developer;
    GRANT USAGE ON SCHEMA secret_schema TO ROLE developer;
    
    Copy
  8. Erstellen Sie eine Integration für den externen Zugriff, um den externen Endpunkt und die Anmeldeinformationen über die von Ihnen erstellte Netzwerkregel und das Geheimnis anzugeben.

    Weitere Informationen zur Rolle einer Integration für den externen Zugriff, einschließlich der erforderlichen Berechtigungen, finden Sie unter Erstellen einer Integration für den externen Zugriff.

    CREATE OR REPLACE EXTERNAL ACCESS INTEGRATION aws_s3_external_access_integration
      ALLOWED_NETWORK_RULES = (aws_s3_network_rule)
      ALLOWED_AUTHENTICATION_SECRETS = (aws_s3_access_token)
      ENABLED = TRUE
      COMMENT = 'Testing S3 connectivity';
    
    Copy
  9. Erstellen Sie eine UDF, die die Integration des externen Zugriffs verwendet, um eine Verbindung mit dem Amazon S3 Bucket herzustellen, der in der von Ihnen erstellten Netzwerkregel angegeben ist.

    Der Code des Handlers verwendet Snowflake APIs, um ein Token aus dem von Ihnen erstellten Geheimnis abzurufen. Von diesem Token können Sie mit Snowflake-APIs die Werte abrufen, die zum Erstellen einer Sitzung für die Verbindung mit Amazon S3 benötigt werden, einschließlich einer Zugriffsschlüssel-ID, eines geheimen Zugriffsschlüssels und eines Tokens für die Sitzung.

    Weitere Informationen zur Verwendung des externen Zugriffs in einer UDF finden Sie unter Verwendung der Integration für den externen Zugriff in einer Funktion oder Prozedur.

    CREATE OR REPLACE FUNCTION aws_s3_python_function()
      RETURNS VARCHAR
      LANGUAGE PYTHON
      EXTERNAL_ACCESS_INTEGRATIONS = (aws_s3_external_access_integration)
      RUNTIME_VERSION = '3.9'
      SECRETS = ('cred' = aws_s3_access_token)
      PACKAGES = ('boto3')
      HANDLER = 'main_handler'
    AS
    $$
    import boto3
    import _snowflake
    from botocore.config import Config
    
    def main_handler():
      # Get token object
      cloud_provider_object = _snowflake.get_cloud_provider_token('cred')
    
      # Boto3 configuration
      config = Config(
        retries=dict(total_max_attempts=9),
        connect_timeout=30,
        read_timeout=30,
        max_pool_connections=50
      )
    
      # Connect to S3 using boto3
      s3 = boto3.client(
        's3',
        region_name='us-west-2',
        aws_access_key_id=cloud_provider_object.access_key_id,
        aws_secret_access_key=cloud_provider_object.secret_access_key,
        aws_session_token=cloud_provider_object.token,
        config=config
      )
    
      # Use S3 object to upload/download
      return 'Successfully connected with S3'
    $$;
    
    Copy
  10. Gewähren Sie die Berechtigung USAGE auf UDF, damit diejenigen mit der Rolle user diese aufrufen können.

    GRANT USAGE ON FUNCTION return_double_column(int) TO ROLE user;
    
    Copy
  11. Führen Sie die Funktion zur Verbindung mit dem externen Endpunkt aus.

    SELECT aws_s3_python_function();
    
    Copy