Viele Looker-Kunden möchten, dass ihre Nutzer nicht nur Berichte zu Daten in ihrem Data Warehouse erstellen, sondern diese Daten auch zurückschreiben und aktualisieren können.
Über die Action API unterstützt Looker diesen Anwendungsfall für jedes Datenlager oder Ziel. Auf dieser Dokumentationsseite wird Kunden, die Google Cloud Infrastruktur verwenden, gezeigt, wie sie eine Lösung mit Cloud Run-Funktionen bereitstellen, um Daten zurück in BigQuery zu schreiben. Auf dieser Seite werden die folgenden Themen behandelt:
Lösungsüberlegungen
Anhand dieser Liste können Sie prüfen, ob diese Lösung Ihren Anforderungen entspricht.
- Cloud Run-Funktionen
- Warum Cloud Run-Funktionen? Cloud Run-Funktionen sind das serverlose Angebot von Google und eignen sich hervorragend für eine einfache Bedienung und Wartung. Beachten Sie, dass die Latenz, insbesondere bei der ersten Aufrufung, länger sein kann als bei einer Lösung, die auf einem dedizierten Server basiert.
- Sprache und Laufzeit: Cloud Run-Funktionen unterstützen mehrere Sprachen und Laufzeiten. Auf dieser Dokumentationsseite liegt der Schwerpunkt auf einem Beispiel in JavaScript und Node.js. Die Konzepte lassen sich jedoch direkt auf die anderen unterstützten Sprachen und Laufzeiten übertragen.
- BigQuery
- Warum BigQuery? Auf dieser Dokumentationsseite wird davon ausgegangen, dass Sie BigQuery bereits verwenden. BigQuery ist jedoch eine gute Wahl für ein Data Warehouse im Allgemeinen. Beachten Sie dabei Folgendes:
- BigQuery Storage Write API:BigQuery bietet mehrere Schnittstellen zum Aktualisieren von Daten in Ihrem Data Warehouse, z. B. DML-Anweisungen (Data Manipulation Language) in SQL-basierten Jobs. Die beste Option für Schreibvorgänge mit hohem Volumen ist jedoch die BigQuery Storage Write API.
- Anfügen statt Aktualisieren:Bei dieser Lösung werden nur Zeilen angehängt, nicht aktualisiert. Sie können aber jederzeit Tabellen mit dem „aktuellen Status“ bei der Abfrage aus einem Protokoll mit Anfügezugriff ableiten und so Aktualisierungen simulieren.
- Warum BigQuery? Auf dieser Dokumentationsseite wird davon ausgegangen, dass Sie BigQuery bereits verwenden. BigQuery ist jedoch eine gute Wahl für ein Data Warehouse im Allgemeinen. Beachten Sie dabei Folgendes:
- Unterstützende Dienste
- Secret Manager:Der Secret Manager speichert geheime Werte, damit sie nicht an zu leicht zugänglichen Orten wie direkt in der Funktion gespeichert werden.
- Identity and Access Management (IAM): IAM autorisiert die Funktion, zur Laufzeit auf das erforderliche Geheimnis zuzugreifen und in die beabsichtigte BigQuery-Tabelle zu schreiben.
- Cloud Build:Cloud Build wird auf dieser Seite nicht ausführlich behandelt, wird aber im Hintergrund von Cloud Run-Funktionen verwendet. Mit Cloud Build können Sie kontinuierlich bereitgestellte Updates für Ihre Funktionen aufgrund von Änderungen am Quellcode in einem Git-Repository automatisieren.
- Aktion und Nutzerauthentifizierung
- Cloud Run-Dienstkonto: Die primäre und einfachste Möglichkeit, Looker-Aktionen für die Einbindung in die selbst erhobenen Assets und Ressourcen Ihrer Organisation zu verwenden, besteht darin, Anfragen mithilfe des tokenbasierten Authentifizierungsmechanismus der Looker Action API als von Ihrer Looker-Instanz stammend zu authentifizieren und die Funktion dann mit einem Dienstkonto zum Aktualisieren von Daten in BigQuery zu autorisieren.
- OAuth:Eine weitere Option, die auf dieser Seite nicht behandelt wird, ist die Verwendung der OAuth-Funktion der Looker Action API. Dieser Ansatz ist komplexer und im Allgemeinen nicht erforderlich. Er kann jedoch verwendet werden, wenn Sie den Zugriff von Endnutzern zum Schreiben in die Tabelle mit IAM definieren müssen, anstatt ihren Zugriff in Looker oder mithilfe von Ad-hoc-Logik in Ihrem Funktionscode zu verwenden.
Democode – Schritt-für-Schritt-Anleitung
Die gesamte Logik unserer Demoaktion ist in einer einzigen Datei enthalten, die auf GitHub verfügbar ist. In diesem Abschnitt gehen wir die wichtigsten Elemente des Codes durch.
Einrichtungscode
Der erste Abschnitt enthält einige Demokonstanten, die die Tabelle angeben, in die die Aktion schreibt. Im Abschnitt Deployment-Anleitung weiter unten auf dieser Seite werden Sie aufgefordert, die Projekt-ID durch Ihre eigene zu ersetzen. Das ist die einzige erforderliche Änderung am Code.
/*** Demo constants */
const projectId = "your-project-id"
const datasetId = "demo_dataset"
const tableId = "demo_table"
Im nächsten Abschnitt werden einige Codeabhängigkeiten deklariert und initialisiert, die von Ihrer Aktion verwendet werden. Wir stellen ein Beispiel bereit, bei dem über das Secret Manager-Node.js-Modul „in-code“ auf Secret Manager zugegriffen wird. Sie können diese Codeabhängigkeit jedoch auch beseitigen, indem Sie die eingebaute Funktion von Cloud Run-Funktionen verwenden, um bei der Initialisierung ein Secret abzurufen.
/*** Code Dependencies ***/
const crypto = require("crypto")
const {SecretManagerServiceClient} = require('@google-cloud/secret-manager')
const secrets = new SecretManagerServiceClient()
const BigqueryStorage = require('@google-cloud/bigquery-storage')
const BQSManagedWriter = BigqueryStorage.managedwriter
Die referenzierten @google-cloud
-Abhängigkeiten sind auch in der Datei package.json
deklariert, damit sie vorab geladen und für die Node.js-Laufzeit verfügbar sind. crypto
ist ein integriertes Node.js-Modul und wird nicht in package.json
deklariert.
HTTP-Anfrageverarbeitung und -Routing
Die Hauptoberfläche, die Ihr Code der Cloud Run-Funktionslaufzeit zur Verfügung stellt, ist eine exportierte JavaScript-Funktion, die den Konventionen des Node.js Express-Webservers folgt. Ihre Funktion empfängt insbesondere zwei Argumente: Das erste steht für die HTTP-Anfrage, aus der Sie verschiedene Anfrageparameter und ‑werte ablesen können. Das zweite steht für ein Antwortobjekt, an das Sie Ihre Antwortdaten senden. Der Name der Funktion kann beliebig sein. Sie müssen ihn jedoch später für Cloud Run-Funktionen angeben, wie im Abschnitt Bereitstellungsanleitung beschrieben.
/*** Entry-point for requests ***/
exports.httpHandler = async function httpHandler(req,res) {
Im ersten Abschnitt der httpHandler
-Funktion werden die verschiedenen Routen deklariert, die von unserer Aktion erkannt werden. Dabei werden die erforderlichen Endpunkte der Action API für eine einzelne Aktion genau nachgebildet. Außerdem werden die Funktionen definiert, die für jede Route zuständig sind.
In einigen Beispielen für Aktionen und Cloud Run-Funktionen wird für jede solche Route eine separate Funktion bereitgestellt, um eine Eins-zu-eins-Übereinstimmung mit der Standard-Routing-Funktion von Cloud Run-Funktionen zu erzielen. Funktionen können jedoch auch zusätzliches „Unter-Routing“ in ihrem Code anwenden, wie hier gezeigt. Das ist letztendlich eine Frage der Präferenz. Durch diese zusätzliche Routing-Funktion im Code wird jedoch die Anzahl der Funktionen minimiert, die wir bereitstellen müssen, und wir können einen einheitlichen Codestatus für alle Endpunkte der Aktionen beibehalten.
const routes = {
"/": [hubListing],
"/status": [hubStatus], // Debugging endpoint. Not required.
"/action-0/form": [
requireInstanceAuth,
action0Form
],
"/action-0/execute": [
requireInstanceAuth,
processRequestBody,
action0Execute
]
}
Im Rest der HTTP-Handler-Funktion wird die Verarbeitung der HTTP-Anfrage anhand der vorherigen Routendeklarationen implementiert und die Rückgabewerte dieser Handler mit dem Antwortobjekt verknüpft.
try {
const routeHandlerSequence = routes[req.path] || [routeNotFound]
for(let handler of routeHandlerSequence) {
let handlerResponse = await handler(req)
if (!handlerResponse) continue
return res
.status(handlerResponse.status || 200)
.json(handlerResponse.body || handlerResponse)
}
}
catch(err) {
console.error(err)
res.status(500).json("Unhandled error. See logs for details.")
}
}
Nachdem wir die HTTP-Handler- und Routendeklarationen geklärt haben, sehen wir uns die drei Haupt-Action-Endpunkte an, die wir implementieren müssen:
Endpunkt für die Aktionsliste
Wenn ein Looker-Administrator zum ersten Mal eine Looker-Instanz mit einem Action-Server verbindet, ruft Looker die angegebene URL auf, die als Endpunkt der Aktionsliste bezeichnet wird, um Informationen zu den über den Server verfügbaren Aktionen abzurufen.
In unseren zuvor gezeigten Routendeklarationen haben wir diesen Endpunkt unter dem Stammpfad (/
) unter der URL unserer Funktion verfügbar gemacht und angegeben, dass er von der Funktion hubListing
verarbeitet wird.
Wie Sie an der folgenden Funktionsdefinition sehen, ist der Code nicht sehr umfangreich. Es werden einfach jedes Mal dieselben JSON-Daten zurückgegeben. Beachten Sie, dass in einigen Feldern dynamisch die „eigene“ URL eingefügt wird. So kann die Looker-Instanz spätere Anfragen an dieselbe Funktion zurücksenden.
async function hubListing(req){
return {
integrations: [
{
name: "demo-bq-insert",
label: "Demo BigQuery Insert",
supported_action_types: ["cell", "query", "dashboard"],
form_url:`${process.env.CALLBACK_URL_PREFIX}/action-0/form`,
url: `${process.env.CALLBACK_URL_PREFIX}/action-0/execute`,
icon_data_uri: "data:image/png;base64,...",
supported_formats:["inline_json"],
supported_formattings:["unformatted"],
required_fields:[
// You can use this to make your action available
// for specific queries/fields
// {tag:"user_id"}
],
params: [
// You can use this to require parameters, either
// from the Action's administrative configuration,
// or from the invoking user's user attributes.
// A common use case might be to have the Looker
// instance pass along the user's identification to
// allow you to conditionally authorize the action:
{name: "email", label: "Email", user_attribute_name: "email", required: true}
]
}
]
}
}
Für Demonstrationszwecke war für unseren Code keine Authentifizierung erforderlich, um diesen Eintrag abzurufen. Wenn Sie Ihre Aktionsmetadaten jedoch als vertraulich betrachten, können Sie auch für diesen Pfad eine Authentifizierung verlangen, wie im nächsten Abschnitt beschrieben.
Beachten Sie auch, dass unsere Cloud Run-Funktion mehrere Aktionen bereitstellen und verarbeiten kann. Daher verwenden wir die Routenkonvention /action-X/...
. Unsere Demo-Cloud Run-Funktion implementiert jedoch nur eine Aktion.
Endpunkt für Aktionsformulare
Für alle Anwendungsfälle ist zwar kein Formular erforderlich, aber für den Anwendungsfall von Datenbank-Writebacks eignet es sich gut, da Nutzer Daten in Looker prüfen und dann Werte angeben können, die in die Datenbank eingefügt werden sollen. Da unsere Aktionsliste einen form_url
-Parameter enthält, ruft Looker diesen Endpunkt für das Aktionsformular auf, wenn ein Nutzer mit Ihrer Aktion interagiert, um zu ermitteln, welche zusätzlichen Daten vom Nutzer erfasst werden sollen.
In unseren Routendeklarationen haben wir diesen Endpunkt unter dem Pfad /action-0/form
verfügbar gemacht und ihm zwei Handler zugewiesen: requireInstanceAuth
und action0Form
.
Wir haben unsere Routendeklarationen so eingerichtet, dass mehrere Handler wie dieser zulässig sind, da einige Logik für mehrere Endpunkte wiederverwendet werden kann.
So sehen wir beispielsweise, dass requireInstanceAuth
für mehrere Routen verwendet wird. Wir verwenden diesen Handler überall dort, wo eine Anfrage von unserer Looker-Instanz stammen muss. Der Handler ruft den erwarteten Tokenwert des Secrets aus Secret Manager ab und lehnt alle Anfragen ab, die diesen erwarteten Tokenwert nicht haben.
async function requireInstanceAuth(req) {
const lookerSecret = await getLookerSecret()
if(!lookerSecret){return}
const expectedAuthHeader = `Token token="${lookerSecret}"`
if(!timingSafeEqual(req.headers.authorization,expectedAuthHeader)){
return {
status:401,
body: {error: "Looker instance authentication is required"}
}
}
return
function timingSafeEqual(a, b) {
if(typeof a !== "string"){return}
if(typeof b !== "string"){return}
var aLen = Buffer.byteLength(a)
var bLen = Buffer.byteLength(b)
const bufA = Buffer.allocUnsafe(aLen)
bufA.write(a)
const bufB = Buffer.allocUnsafe(aLen) //Yes, aLen
bufB.write(b)
return crypto.timingSafeEqual(bufA, bufB) && aLen === bLen;
}
}
Hinweis: Wir verwenden eine timingSafeEqual
-Implementierung anstelle der standardmäßigen Gleichheitsprüfung (==
), um das Austreten von Nebenkanal-Timing-Informationen zu verhindern, mit denen ein Angreifer schnell den Wert unseres Geheimnisses herausfinden könnte.
Wenn eine Anfrage die Instanzauthentifizierung besteht, wird sie vom action0Form
-Handler verarbeitet.
async function action0Form(req){
return [
{name: "choice", label: "Choose", type:"select", options:[
{name:"Yes", label:"Yes"},
{name:"No", label:"No"},
{name:"Maybe", label:"Maybe"}
]},
{name: "note", label: "Note", type: "textarea"}
]
}
Unser Demobeispiel ist zwar sehr statisch, der Formularcode kann für bestimmte Anwendungsfälle aber interaktiver sein. Je nach Auswahl eines Nutzers in einem ersten Drop-down-Menü können beispielsweise unterschiedliche Felder angezeigt werden.
Endpunkt für die Aktionsausführung
Der Endpunkt „Action Execute“ enthält den Großteil der Logik einer Aktion. Dort gehen wir auf die Logik ein, die speziell für den BigQuery-Einsatzfall „insert“ (einfügen) gilt.
In unseren Routendeklarationen haben wir diesen Endpunkt unter dem Pfad /action-0/execute
verfügbar gemacht und ihm drei Handler zugewiesen: requireInstanceAuth
, processRequestBody
und action0Execute
.
Wir haben bereits requireInstanceAuth
behandelt. Der processRequestBody
-Handler führt eine vorwiegend uninteressante Vorverarbeitung durch, um bestimmte ungünstige Felder im Anfragetext von Looker in ein praktischeres Format zu bringen. Sie können sich aber in der vollständigen Codedatei darüber informieren.
Die action0Execute
-Funktion zeigt zuerst Beispiele für das Extrahieren nützlicher Informationen aus verschiedenen Teilen der Aktionsanfrage. In der Praxis können die Anfrageelemente, die in unserem Code als formParams
und actionParams
bezeichnet werden, je nach Deklaration in Ihren Eintrags- und Formularendpunkten unterschiedliche Felder enthalten.
async function action0Execute (req){
try{
// Prepare some data that we will insert
const scheduledPlanId = req.body.scheduled_plan && req.body.scheduled_plan.scheduled_plan_id
const formParams = req.body.form_params || {}
const actionParams = req.body.data || {}
const queryData = req.body.attachment.data //If using a standard "push" action
/*In case any fields require datatype-specific preparation, check this example:
https://github.com/googleapis/nodejs-bigquery-storage/blob/main/samples/append_rows_proto2.js
*/
const newRow = {
invoked_at: new Date(),
invoked_by: actionParams.email,
scheduled_plan_id: scheduledPlanId || null,
query_result_size: queryData.length,
choice: formParams.choice,
note: formParams.note,
}
Der Code wechselt dann zu Standard-BigQuery-Code, um die Daten tatsächlich einzufügen. Die BigQuery Storage Write APIs bieten andere, komplexere Varianten, die besser für eine persistente Streamingverbindung oder Bulk-Inserts vieler Datensätze geeignet sind. Für die Reaktion auf einzelne Nutzerinteraktionen im Kontext einer Cloud Run-Funktion ist dies jedoch die direkteste Variante.
await bigqueryConnectAndAppend(newRow)
...
async function bigqueryConnectAndAppend(row){
let writerClient
try{
const destinationTablePath = `projects/${projectId}/datasets/${datasetId}/tables/${tableId}`
const streamId = `${destinationTablePath}/streams/_default`
writerClient = new BQSManagedWriter.WriterClient({projectId})
const writeMetadata = await writerClient.getWriteStream({
streamId,
view: 'FULL',
})
const protoDescriptor = BigqueryStorage.adapt.convertStorageSchemaToProto2Descriptor(
writeMetadata.tableSchema,
'root'
)
const connection = await writerClient.createStreamConnection({
streamId,
destinationTablePath,
})
const writer = new BQSManagedWriter.JSONWriter({
streamId,
connection,
protoDescriptor,
})
let result
if(row){
// The API expects an array of rows, so wrap the single row in an array
const rowsToAppend = [row]
result = await writer.appendRows(rowsToAppend).getResult()
}
return {
streamId: connection.getStreamId(),
protoDescriptor,
result
}
}
catch (e) {throw e}
finally{
if(writerClient){writerClient.close()}
}
}
Der Democode enthält auch einen „status“-Endpunkt zur Fehlerbehebung. Dieser Endpunkt ist für die Integration der Action API jedoch nicht erforderlich.
Bereitstellungsanleitung
Abschließend finden Sie eine detaillierte Anleitung zum Bereitstellen der Demo. Dabei werden die Voraussetzungen, die Bereitstellung der Cloud Run-Funktion, die BigQuery-Konfiguration und die Looker-Konfiguration behandelt.
Projekt- und Dienstvoraussetzungen
Bevor Sie mit der Konfiguration beginnen, sehen Sie sich diese Liste an, um zu erfahren, welche Dienste und Richtlinien für die Lösung erforderlich sind:
- Neues Projekt:Sie benötigen ein neues Projekt, um die Ressourcen aus unserem Beispiel zu hosten.
- Dienste:Wenn Sie BigQuery- und Cloud Run-Funktionen in der Cloud Console-Benutzeroberfläche zum ersten Mal verwenden, werden Sie aufgefordert, die erforderlichen APIs für die erforderlichen Dienste zu aktivieren, darunter BigQuery, Artifact Registry, Cloud Build, Cloud Functions, Cloud Logging, Pub/Sub, Cloud Run Admin und Secret Manager.
- Richtlinie für nicht authentifizierte Aufrufe:Für diesen Anwendungsfall müssen wir Cloud Run-Funktionen bereitstellen, die nicht authentifizierte Aufrufe zulassen, da wir die Authentifizierung für eingehende Anfragen in unserem Code gemäß der Action API und nicht mit IAM verarbeiten. Dies ist zwar standardmäßig zulässig, wird aber häufig durch Organisationsrichtlinien eingeschränkt. Insbesondere schränkt die
constraints/iam.allowedPolicyMemberDomains
-Richtlinie ein, wem IAM-Berechtigungen gewährt werden können. Möglicherweise müssen Sie sie anpassen, um demallUsers
-Hauptkonto nicht authentifizierten Zugriff zu gewähren. Wenn Sie unauthentifizierte Aufrufe nicht zulassen können, finden Sie in diesem Leitfaden Öffentliche Cloud Run-Dienste erstellen, wenn die Freigabe der Domain beschränkt ist weitere Informationen. - Andere Richtlinien:Andere Google Cloud Einschränkungen von Organisationsrichtlinien können auch die Bereitstellung von Diensten verhindern, die ansonsten standardmäßig zulässig sind.
Cloud Run-Funktion bereitstellen
Nachdem Sie ein neues Projekt erstellt haben, führen Sie die folgenden Schritte aus, um die Cloud Run-Funktion bereitzustellen.
- Klicken Sie unter Cloud Run-Funktionen auf Funktion erstellen.
- Wählen Sie einen beliebigen Namen für die Funktion aus, z. B. „demo-bq-insert-action“.
- Unter Trigger:
- Der Triggertyp sollte bereits „HTTPS“ sein.
- Wählen Sie unter Authentifizierung die Option Nicht authentifizierte Aufrufe zulassen aus.
- Kopieren Sie den Wert URL in die Zwischenablage.
- Unter Laufzeit > Laufzeit-Umgebungsvariablen:
- Klicken Sie auf Variable hinzufügen.
- Legen Sie als Variablennamen
CALLBACK_URL_PREFIX
fest. - Fügen Sie als Wert die URL aus dem vorherigen Schritt ein.
- Klicken Sie auf Weiter.
- Klicken Sie auf die Datei
package.json
und fügen Sie den Inhalt ein. - Klicken Sie auf die Datei
index.js
und fügen Sie den Inhalt ein. - Weisen Sie der Variablen
projectId
oben in der Datei Ihre eigene Projekt-ID zu. - Legen Sie als Einstiegspunkt
httpHandler
fest. - Klicken Sie auf Bereitstellen.
- Gewähren Sie dem Build-Dienstkonto die angeforderten Berechtigungen (falls zutreffend).
- Warten Sie, bis die Bereitstellung abgeschlossen ist.
- Wenn Sie bei einem der nächsten Schritte eine Fehlermeldung erhalten, in der Sie aufgefordert werden, die Google Cloud Protokolle zu prüfen, können Sie auf dieser Seite auf dem Tab Protokolle auf die Protokolle für diese Funktion zugreifen.
- Bevor Sie die Seite Ihrer Cloud Run-Funktion verlassen, notieren Sie sich auf dem Tab Details das Dienstkonto der Funktion. Wir verwenden dies in späteren Schritten, um sicherzustellen, dass die Funktion die erforderlichen Berechtigungen hat.
- Sie können die Bereitstellung Ihrer Funktion direkt in Ihrem Browser testen, indem Sie die URL aufrufen. Sie sollten eine JSON-Antwort mit dem Eintrag Ihrer Integration sehen.
- Wenn Sie einen 403-Fehler erhalten, ist der Versuch, Nicht authentifizierte Aufrufe zulassen festzulegen, möglicherweise aufgrund einer Organisationsrichtlinie geräuschlos fehlgeschlagen. Prüfen Sie, ob für Ihre Funktion nicht authentifizierte Aufrufe zulässig sind, überprüfen Sie die Einstellung der Organisationsrichtlinie und versuchen Sie, die Einstellung zu aktualisieren.
Zugriff auf die BigQuery-Zieltabelle
In der Praxis kann sich die Zieltabelle, in die eingefügt werden soll, in einem anderen Google Cloud Projekt befinden. Zu Demonstrationszwecken erstellen wir jedoch eine neue Zieltabelle im selben Projekt. In beiden Fällen muss das Dienstkonto Ihrer Cloud Run-Funktion die Berechtigung zum Schreiben in die Tabelle haben.
- Rufen Sie die BigQuery-Konsole auf.
Erstellen Sie die Demotabelle:
- Klicken Sie in der Explorer-Leiste neben Ihrem Projekt auf das Dreipunkt-Menü und wählen Sie Dataset erstellen aus.
- Geben Sie dem Dataset die ID
demo_dataset
und klicken Sie auf Dataset erstellen. - Klicken Sie im Dreipunkt-Menü des neu erstellten Datasets auf Tabelle erstellen.
- Geben Sie der Tabelle den Namen
demo_table
. Wählen Sie unter Schema die Option Als Text bearbeiten aus, verwenden Sie das folgende Schema und klicken Sie dann auf Tabelle erstellen.
[ {"name":"invoked_at","type":"TIMESTAMP"}, {"name":"invoked_by","type":"STRING"}, {"name":"scheduled_plan_id","type":"STRING"}, {"name":"query_result_size","type":"INTEGER"}, {"name":"choice","type":"STRING"}, {"name":"note","type":"STRING"} ]
Weisen Sie Berechtigungen zu:
- Klicken Sie in der Leiste Explorer auf das Dataset.
- Klicken Sie auf der Seite Dataset auf Freigabe > Berechtigungen.
- Klicken Sie auf Hauptkonto hinzufügen.
- Legen Sie als Neuer Hauptbenutzer das Dienstkonto für Ihre Funktion fest, das Sie oben auf dieser Seite notiert haben.
- Weisen Sie die Rolle BigQuery-Datenbearbeiter zu.
- Klicken Sie auf Speichern.
Verbindung zu Looker herstellen
Nachdem Ihre Funktion bereitgestellt wurde, werden wir Looker damit verknüpfen.
- Für Ihre Aktion benötigen wir ein gemeinsames Secret, um zu authentifizieren, dass Anfragen von Ihrer Looker-Instanz stammen. Generieren Sie einen langen Zufallsstring und bewahren Sie ihn sicher auf. Wir verwenden ihn in den folgenden Schritten als Looker-Secret.
- Rufen Sie in der Cloud Console Secret Manager auf.
- Klicken Sie auf Secret erstellen.
- Legen Sie als Name
LOOKER_SECRET
fest. Dieser Wert ist im Code für diese Demo hartcodiert. Sie können jedoch bei der Arbeit mit Ihrem eigenen Code einen beliebigen Namen auswählen. - Legen Sie den Secret Value auf den von Ihnen generierten geheimen Wert fest.
- Klicken Sie auf Secret erstellen.
- Klicken Sie auf der Seite Secret auf den Tab Berechtigungen.
- Klicken Sie auf Zugriff gewähren.
- Legen Sie unter Neue Hauptkonten das Dienstkonto für Ihre Funktion fest, das Sie zuvor notiert haben.
- Weisen Sie die Rolle Secret Manager Secret Accessor zu.
- Klicken Sie auf Speichern.
- Sie können prüfen, ob Ihre Funktion auf das Geheimnis zugreift, indem Sie die Route
/status
aufrufen, die an Ihre Funktions-URL angehängt ist.
- In Ihrer Looker-Instanz:
- Gehen Sie zu „Verwaltung“ > „Plattform“ > „Aktionen“.
- Klicken Sie unten auf der Seite auf Action Hub hinzufügen.
- Geben Sie die URL Ihrer Funktion an (z. B. https://your-region-your-project.cloudfunctions.net/demo-bq-insert-action) und klicken Sie auf Action Hub hinzufügen, um die Funktion zu bestätigen.
- Sie sollten jetzt einen neuen Action Hub-Eintrag mit einer Aktion namens Demo BigQuery Insert sehen.
- Klicken Sie im Eintrag „Action Hub“ auf Autorisierung konfigurieren.
- Geben Sie das generierte Looker-Secret in das Feld Autorisierungstoken ein und klicken Sie auf Token aktualisieren.
- Klicken Sie bei der Aktion Demo BigQuery Insert auf Aktivieren.
- Aktivieren Sie den Schalter Aktiviert.
- Es sollte automatisch ein Test der Aktion ausgeführt werden, um zu bestätigen, dass Ihre Funktion die Anfrage von Looker akzeptiert und richtig auf den Formularendpunkt antwortet.
- Klicken Sie auf Speichern.
End-to-End-Test
Wir sollten jetzt unsere neue Aktion verwenden können. Diese Aktion ist für jede Abfrage konfiguriert. Wählen Sie also ein Explore aus (z. B. ein integriertes Explore für Systemaktivitäten), fügen Sie einer neuen Abfrage einige Felder hinzu, führen Sie sie aus und wählen Sie dann im Zahnradmenü Senden aus. Die Aktion sollte als eines der verfügbaren Ziele angezeigt werden und Sie werden aufgefordert, einige Felder auszufüllen:
Wenn Sie auf Senden klicken, sollte in Ihrer BigQuery-Tabelle eine neue Zeile eingefügt werden und die E-Mail-Adresse Ihres Looker-Nutzerkontos in der Spalte invoked_by
zu sehen sein.