1. Einführung
SaaS-Lösungen auf dem Google Cloud Marketplace sind Softwarelösungen, die unabhängig vom Standort auf Ihrer Infrastruktur ausgeführt werden, jedoch von Google in Rechnung gestellt werden.
In diesem Codelab richten Sie eine grundlegende SaaS-Lösung ein, die in Google Cloud Marketplace eingebunden ist, um:
- Benachrichtigungen erhalten, wenn sich ein Nutzer für die Beispiellösung registriert.
- Genehmigen Sie Kunden, die sich registrieren möchten, und fügen Sie sie Ihrer Datenbank hinzu.
- Szenarien bearbeiten, in denen Kunden ihre Abrechnungsmodelle ändern oder kündigen möchten.
- Nutzungsberichte an Google senden.
In diesem Codelab lernen Sie die Google Cloud Marketplace Procurement API und Service Control API kennen. Hinweis: In diesem Leitfaden wird keine vollständige Produktumgebung für Tests beschrieben.
2. Hinweis
- Aktivieren Sie das Codelab für Ihr Projekt im Producer Portal, falls Sie es noch nicht aktiviert haben.
Der Link zu Producer Portal lautet:
https://console.cloud.google.com/producer-portal?project=YOUR_PROJECT_ID
Klicken Sie im Codelabs-Bereich auf der rechten Seite des Bildschirms auf Aktivieren, um das Codelab zu aktivieren.
- Installieren Sie Python 3 auf Ihrem Computer mit den folgenden Modulen:
- Die Python Google Client APIs.
- Die Clientbibliothek
google-cloud-pubsub
Verwenden Sie den folgenden Befehl, um die Python-Module zu installieren:
pip install --upgrade google-api-python-client google-cloud-pubsub
- Klonen oder laden Sie das GitHub-Repository für dieses Codelab mit dem folgenden Befehl herunter:
git clone https://github.com/googlecodelabs/gcp-marketplace-integrated-saas.git cd gcp-marketplace-integrated-saas
- Legen Sie die Umgebungsvariable
GOOGLE_CLOUD_PROJECT
auf die ID dieses Projekts fest: - Linux:
export GOOGLE_CLOUD_PROJECT="YOUR_PROJECT_ID"
- Windows:
set GOOGLE_CLOUD_PROJECT=YOUR_PROJECT_ID
- Weisen Sie dem Dienstkonto
saas-codelab
die Rolle Pub/Sub-Bearbeiter zu. Eine Anleitung zum Zuweisen und Verwalten von Rollen finden Sie unter Zugriff auf Ressourcen erteilen, ändern und entziehen. - Erstellen Sie einen JSON-Schlüssel für das Dienstkonto und laden Sie ihn herunter. Eine Anleitung zum Erstellen des Schlüssels finden Sie unter Dienstkontoschlüssel erstellen und verwalten.
- Legen Sie die Umgebungsvariable
GOOGLE_APPLICATION_CREDENTIALS
auf den vollständigen Pfad zur heruntergeladenen Datei fest: - Linux:
export GOOGLE_APPLICATION_CREDENTIALS="[YOUR_MACHINE]/path/service-account-key.json"
- Windows:
set GOOGLE_APPLICATION_CREDENTIALS=[YOUR_MACHINE]/path/service-account-key.json
- Wenn Sie sich eine Beispiellösung in Google Cloud Marketplace ansehen möchten, rufen Sie das Producer Portal auf und klicken Sie im Bereich „Codelabs“ auf Codelab-Produkt. Sie können auch direkt unter https://console.cloud.google.com/marketplace/product/DEMO-YOUR_PROJECT_ID/isaas-codelab auf die Lösung zugreifen.
- Aktivieren Sie in der Google Cloud Console in Ihrem neuen Projekt die Partner Procurement API.
Richten Sie als Nächstes das Backend für die Beispiellösung ein.
3. Einbindung in Google Cloud Marketplace
Das Einbinden der Beispiellösung in den Google Cloud Marketplace funktioniert im Wesentlichen so:
- In Cloud Pub/Sub, um Benachrichtigungen von Google Cloud Marketplace zu erhalten, z. B. wenn sich ein Nutzer für Ihre Lösung anmeldet. Ihr Partnerentwickler erstellt ein Cloud Pub/Sub-Thema, das Sie für Benachrichtigungen abonnieren müssen.
- In die Partner Procurement API, um Konten für neue Kunden zu erstellen. Sie verwenden die Partner Procurement API, um die Konten zu aktualisieren, wenn Nutzer ihre Abos auswählen, ändern oder kündigen. Um die API zu nutzen, müssen Sie eine eigene Clientbibliothek erstellen.
- Binden Sie Google Service Control ein, um Nutzungsinformationen zu melden.
4. Cloud Pub/Sub-Thema abonnieren
Wenn ein Nutzer ein Abo auswählt, erhalten Sie über ein Cloud Pub/Sub-Thema eine Benachrichtigung von Google Cloud Marketplace.
Wenn Sie Nachrichten zu einem Cloud Pub/Sub-Thema empfangen möchten, müssen Sie zuerst ein Abo erstellen.
Verwenden Sie zum Erstellen eines Abos das Skript create_subscription.py
:
cd gcp-marketplace-integrated-saas/tools python create_subscription.py
So rufen Sie das Abo auf: Öffnen Sie das Cloud Pub/Sub-Dashboard in der Cloud Console:
https://console.cloud.google.com/cloudpubsub/subscriptions
Testaboanfrage ausprobieren
Wenn Sie diese Beispiel-App als Nutzer testen möchten, öffnen Sie das Codelab-Produkt im Marketplace unter https://console.cloud.google.com/marketplace/product/DEMO-YOUR_PROJECT_ID/isaas-codelab. Achten Sie darauf, dass Ihr Codelab-Projekt ausgewählt ist, und wählen Sie ein Abo aus.
Wenn Sie die Cloud Pub/Sub-Nachrichten sehen möchten, die gesendet werden, wenn Sie einen Tarif auswählen, rufen Sie das Stammverzeichnis des python3
-Verzeichnisses im Repository auf und führen Sie den folgenden Befehl aus:
~/gcp-marketplace-integrated-saas/python3$ python -m impl.step_1_pubsub.app
Den Beispielcode, der auf Cloud Pub/Sub-Nachrichten wartet, finden Sie unter https://github.com/googlecodelabs/gcp-marketplace-integrated-saas/blob/master/python3/impl/step_1_pubsub/app.py.
Im Feld eventType
der Cloud Pub/Sub-Nachricht wird der Grund für das Senden der Nachricht angegeben. Wenn Sie einen Tarif auswählen, sollte eine Meldung für eventType: ENTITLEMENT_CREATION_REQUESTED
angezeigt werden, die für Ihre frühere Auswahl des Abos steht.
Wenn Sie Ihr Abo kündigen, während dieses Skript ausgeführt wird, wird eine neue Meldung für eventType: ENTITLEMENT_CANCELLED
angezeigt.
Im obigen Beispiel werden keine Nachrichten bestätigt. So können Sie leichter testen, da Sie bei jedem Ausführen Ihrer App dieselben Nachrichten erhalten.
Drücken Sie CTRL + \
, um das Skript zu schließen.
5. Kontoanfrage genehmigen
Nachdem Sie jetzt Nachrichten vom Google Cloud Marketplace empfangen können, müssen Sie die Ressourcen verarbeiten, die vom Google Cloud Marketplace Procurement-Dienst im Namen des Kunden erstellt werden.
Die erste ist die account-Ressource. Ein Konto stellt die Verbindung eines Kunden zu Ihrem Produkt dar. Sie müssen die Beschaffungskonto-ID des Kunden in Ihrer Datenbank speichern, um die Beziehung zwischen seinem Google-Konto und seinem Konto für Ihren Dienst zuzuordnen.
Wenn ein Kunde einen Tarif auswählt, sendet Google Cloud Marketplace eine Cloud Pub/Sub-Benachrichtigung, dass der Kunde ein Konto anfordert. Ihre App muss die Anfrage genehmigen. In diesem Codelab genehmigen Sie die Kontoanfragen, wenn die Cloud Pub/Sub-Nachrichten empfangen werden.
Datenbank für die Kontoinformationen erstellen
In diesem Codelab verwenden wir eine einfache JSON-Datenbank, in der Kundenkonten und Käufe erfasst werden können.
Erstellen Sie zum Testen dieses Beispiels eine Datei mit einem leeren JSON-Objekt auf Ihrer Workstation:
{}
Legen Sie die Umgebungsvariable PROCUREMENT_CODELAB_DATABASE
auf den vollständigen Pfad zu dieser Datei fest:
- Linux:
export PROCUREMENT_CODELAB_DATABASE="YOUR_MACHINE/path/EMPTY_JSON_OBJECT.json"
- Windows:
set PROCUREMENT_CODELAB_DATABASE=YOUR_MACHINE/path/EMPTY_JSON_OBJECT.json
Das Modul, das die Datenbank liest und schreibt, befindet sich in python3/impl/database
.
In der Beispielimplementierung wird ein Schema verwendet, das erweitert werden kann, wenn Sie mehr als ein Produktangebot in Google Cloud Marketplace einbinden. Im Folgenden finden Sie ein Beispiel für einen Datenbankeintrag für einen Nutzer, der das Abo Very Good in der Beispiel-App abgeschlossen hat:
{
"a2b3c4d5-b3f1-4dea-b134-generated_id":{
"procurement_account_id":"generated-b3f1-4dea-b134-4a1d100c0335",
"internal_account_id":"generated-45b7-4f4d-1bcd-2abb114f77de",
"products":{
"isaas-codelab":{
"start_time":"2019-01-04T01:21:16.188Z",
"plan_id":"very-good",
"product_id":"isaas-codelab",
"consumer_id":"project_number:123123345345"
}
}
}
}
In Ihrer endgültigen Implementierung müssen Sie Ihre App mit Ihren eigenen Datenbanken verbinden, um die Google Cloud Marketplace-Konten von Kunden mit Ihren eigenen Kundenressourcen zu verknüpfen.
Konto genehmigen
Führen Sie den folgenden Befehl aus, um die Kontoanfrage zu genehmigen:
~/gcp-marketplace-integrated-saas/python3$ python3 -m impl.step_2_account.app
Der Beispielcode zum Genehmigen eines Kontos befindet sich unter impl/step_2_account.
In der Beispielimplementierung wird die Procurement
-Klasse verwendet, die die Interaktionen mit der Procurement API verarbeitet. Hier sind die Methoden get_account()
und approve_account()
:
def _get_account_name(self, account_id):
return 'providers/DEMO-{}/accounts/{}'.format(PROJECT_ID,
account_id)
def get_account(self, account_id):
"""Gets an account from the Procurement Service."""
name = self._get_account_name(account_id)
request = self.service.providers().accounts().get(name=name)
try:
response = request.execute()
return response
except HttpError as err:
if err.resp.status == 404:
return None
def approve_account(self, account_id):
"""Approves the account in the Procurement Service."""
name = self._get_account_name(account_id)
request = self.service.providers().accounts().approve(
name=name, body={'approvalName': 'signup'})
request.execute()
In diesem Codelab ist die Anbieter-ID im Beschaffungsdienst DEMO-
YOUR_PROJECT_ID
, wobei YOUR_PROJECT_ID
das von Ihnen erstellte Projekt ist. Bei der Interaktion mit der Procurement API muss der Kontoname das folgende Format haben:
providers/DEMO-YOUR_PROJECT_ID/accounts/account-id
Als Nächstes genehmigen Sie eine Berechtigung, die einen Datensatz des Kaufs des Kunden darstellt.
6. Berechtigung genehmigen
Wenn ein Kunde ein Abo im Google Cloud Marketplace auswählt, wird ein Konto erstellt und dann sofort eine neue Berechtigungsanfrage erstellt. Die Berechtigung stellt den Kauf eines Dienstes dar. Bevor der Kunde den Dienst verwenden kann, müssen Sie die Berechtigungsanfrage genehmigen und den Dienst dann für den Kunden einrichten.
Wenn die Beispiel-App eine Cloud Pub/Sub-Nachricht mit dem eventType
ENTITLEMENT_CREATION_REQUESTED
erhält, wird die Berechtigung genehmigt. Die App muss auf eine ENTITLEMENT_ACTIVE
-Nachricht warten, um die Berechtigung in der Datenbank zu erfassen und dann die Ressourcen für den Kunden einzurichten.
Führen Sie den folgenden Befehl aus, um die Berechtigung zu erstellen:
~/gcp-marketplace-integrated-saas/python3$ python3 -m impl.step_3_entitlement_create.app
Der Code zum Genehmigen der Berechtigung befindet sich in der Beispielimplementierung.
Als Nächstes gehen Sie auf Situationen ein, in denen ein Kunde eine Änderung seines Abos anfordert.
7. Änderungen an einer Berechtigung genehmigen
Wenn Ihr Dienst mehrere Tarife hat, müssen Sie Anfragen von Kunden bearbeiten, die ihren bestehenden Tarif möglicherweise upgraden oder downgraden möchten.
Wenn Ihr Dienst nur einen Tarif hat, fahren Sie mit „Abgebrochene Käufe verarbeiten“ fort.
Es gibt keinen technischen Unterschied zwischen einem Anspruch, der zum ersten Mal aktiviert wird, und einem Anspruch, der nach einer Planänderung aktiviert wird. Aus diesem Grund hat die Beispielimplementierung für beide Fälle eine gemeinsame handleActiveEntitlement()
-Methode. Mit dieser Methode werden eingehende Nachrichten auf berechtigungsbezogene Ereignisse geprüft:
step_4_entitlement_change/app.py
def handleActiveEntitlement(self, entitlement, customer, accountId):
"""Updates the database to match the active entitlement."""
product = {
'product_id': entitlement['product'],
'plan_id': entitlement['plan'],
}
if 'consumerId' in entitlement:
product['consumer_id'] = entitlement['consumerId']
customer['products'][entitlement['product']] = product
self.db.write(accountId, customer)
Das folgende Snippet prüft, ob eventType
ENTITLEMENT_PLAN_CHANGE_REQUESTED
oder ENTITLEMENT_PLAN_CHANGED
ist:
step_4_entitlement_change/app.py
elif eventType == 'ENTITLEMENT_PLAN_CHANGE_REQUESTED':
if state == 'ENTITLEMENT_PENDING_PLAN_CHANGE_APPROVAL':
# Don't write anything to our database until the entitlement becomes
# active within the Procurement Service.
self.approveEntitlementPlanChange(id, entitlement['newPendingPlan'])
return True
elif eventType == 'ENTITLEMENT_PLAN_CHANGED':
if state == 'ENTITLEMENT_ACTIVE':
# Handle an active entitlement after a plan change.
self.handleActiveEntitlement(entitlement, customer, accountId)
return True
Wenn in Ihrer endgültigen Implementierung das Abo wieder in den Status ENTITLEMENT_ACTIVE
wechselt, sollte Ihre Listener-Methode Ihre Datenbank aktualisieren, um die Änderung zu berücksichtigen, und alle erforderlichen Bereitstellungen vornehmen.
Je nachdem, wie Sie Ihr Produkt mit Ihrem Partnerentwickler eingerichtet haben, sind Downgrades oder Kündigungen Ihres Dienstes möglicherweise erst am Ende eines Abrechnungszeitraums möglich. In solchen Fällen bleibt der Tarifwechsel auch nach der Genehmigung ausstehend. Die Berechtigung wechselt jedoch erst dann wieder in den Status ENTITLEMENT_ACTIVE
, wenn der Tarifwechsel abgeschlossen ist.
Den Code, mit dem Berechtigungsänderungen geprüft und genehmigt werden, finden Sie in der Beispielimplementierung.
Als Nächstes geht es um Situationen, in denen Kunden ihre Käufe stornieren.
8. Stornierte Käufe verarbeiten
Kunden können ihre Käufe stornieren. Je nachdem, wie Sie das Produkt mit Ihrem Partnerentwickler eingerichtet haben, kann die Kündigung sofort oder am Ende des Abrechnungszeitraums wirksam werden.
Wenn ein Kunde seinen Kauf storniert, wird eine Nachricht mit dem eventType
ENTITLEMENT_PENDING_CANCELLATION
gesendet. Wenn Sie Ihr Produkt so eingerichtet haben, dass Kündigungen sofort verarbeitet werden, wird kurz danach eine Nachricht mit dem eventType
ENTITLEMENT_CANCELLED
gesendet.
step_5_entitlement_cancel/app.py
elif eventType == 'ENTITLEMENT_CANCELLED':
# Clear out our records of the customer's plan.
if entitlement['product'] in customer['products']:
del customer['products'][entitlement['product']]
### TODO: Turn off customer's service. ###
self.db.write(accountId, customer)
return True
elif eventType == 'ENTITLEMENT_PENDING_CANCELLATION':
# Do nothing. We want to cancel once it's truly canceled. For now it's
# just set to not renew at the end of the billing cycle.
return True
elif eventType == 'ENTITLEMENT_CANCELLATION_REVERTED':
# Do nothing. The service was already active, but now it's set to renew
# automatically at the end of the billing cycle.
return True
Ihr Dienst muss auf die ENTITLEMENT_CANCELLED
-Nachricht warten, um dann die Berechtigung aus Ihrer Datenbank zu entfernen und den Dienst für den Kunden zu deaktivieren.
Nachdem die Berechtigung gekündigt wurde, wird sie aus den Systemen von Google gelöscht und eine Nachricht mit dem eventType
ENTITLEMENT_DELETED
wird gesendet:
step_5_entitlement_cancel/app.py
elif eventType == 'ENTITLEMENT_DELETED':
# Do nothing. Entitlements can only be deleted when they are already
# cancelled, so our state is already up-to-date.
return True
Den Code zum Kündigen von Berechtigungen finden Sie in der Beispielimplementierung.
9. Nutzungsberichte senden
Einige Dienste haben nutzungsbasierte Komponenten, bei denen Google die Nutzung des Dienstes durch den Kunden kennen muss, um ihm den richtigen Betrag in Rechnung zu stellen. Ihr Dienst muss die Nutzung über die Google Service Control API melden.
Wenn Ihr Dienst keine nutzungsbasierten Komponenten hat, überspringen Sie diesen Abschnitt.
Ausführliche Informationen zum Senden von Nutzungsberichten finden Sie in der Onboarding-Dokumentation.
Nutzungsberichte sollten stündlich an die Google Service Control API gesendet werden. In diesem Codelab werden die Berichte mit einem Skript gesendet, das Sie als Cronjob planen können. Das Skript speichert die Uhrzeit des letzten Nutzungsberichts in der Datenbank und verwendet diese als Startzeit für die Messung der Nutzung.
Das Skript prüft jeden aktiven Kunden des Dienstes und sendet einen Nutzungsbericht an Google Service Control. Dabei wird das Feld consumer_id
der Kundenberechtigung verwendet. Das Skript aktualisiert dann den Datenbankeintrag für den Kunden, sodass last_report_time
auf die Endzeit des gerade gesendeten Nutzungsberichts festgelegt wird.
Google Service Control stellt zwei Methoden bereit: check
und report
. Die erste Methode sollte immer unmittelbar vor einem Aufruf der zweiten Methode aufgerufen werden. Wenn bei der ersten Methode Fehler auftreten, sollte der Dienst des Kunden deaktiviert werden, bis das Problem behoben ist.
Die gesamte Nutzung einer bestimmten Berechtigung wird einem einzelnen usageReportingId
zugeordnet. Bei SaaS-Produkten ist diese Nutzung jedoch mit der Position [Charges not specific to a project]
in der Google Cloud-Abrechnung verknüpft. Wenn Ihr SaaS-Produkt möglicherweise in der Organisation eines Kunden weit verbreitet ist und Sie die Kostenzuordnung unterstützen möchten, empfehlen wir, dass alle Ihre Dienste das optionale Feld userLabels
in ihrem Nutzungsbericht operation enthalten.
Google Cloud Marketplace reserviert die Label-Schlüssel cloudmarketplace.googleapis.com/resource_name und cloudmarketplace.googleapis.com/container_name. Mit diesen Labels soll der Kontext der Nutzung in Ihrer nativen Dienst- und Ressourcenhierarchie erfasst werden. Die vom Kunden zugewiesenen Namen dieser Ressourcen sind als Labelwerte in Nutzungsberichten enthalten. Wir empfehlen, diese Labels standardmäßig in Ihre Nutzungsberichte aufzunehmen.
Labelschlüssel | Labelwert | Beschreibung |
cloudmarketplace.googleapis.com/resource_name | RESOURCE_NAME | Der Name der Ressource, die einem Nutzungsmesswert zugeordnet ist. |
cloudmarketplace.googleapis.com/container_name | CONTAINER_NAME | Der Name eines Ressourcencontainers. |
Im folgenden Snippet wird die Nutzung der Demo-App gemeldet und die Nutzung des SaaS-Produkts der vom Kunden zugewiesenen Ressource mit dem Namen products_db
zugeordnet. In diesem Codelab ist isaas-codelab.mp-marketplace-partner-demos.appspot.com
die service_name
.
operation = {
'operationId': '<UUID>',
'operationName': 'Codelab Usage Report',
'consumerId': 'project_number:<Project Number>',
'startTime': '<Timestamp>',
'endTime': '<Timestamp>',
'metricValues': [{
'int64Value': 100,
}],
'userLabels': {
'cloudmarketplace.googleapis.com/container_name': 'saas-storage-solutions',
'cloudmarketplace.googleapis.com/resource_name': 'products_db'
}
}
service.services().report(
serviceName=service_name, body={
'operations': [operation]
}).execute()
product['last_report_time'] = end_time
database.write(customer_id, customer)
Den vollständigen Code finden Sie in der Beispielimplementierung dieses Skripts. Führen Sie den folgenden Befehl aus, um einen Beispielnutzungsbericht zu erstellen:
~/gcp-marketplace-integrated-saas/python3$ python3 -m impl.step_6_usage_reporting.report isaas-codelab.mp-marketplace-partner-demos.appspot.com
10. Glückwunsch!
Sie haben erfahren, wie Ihre SaaS-Lösung in Google Cloud Marketplace eingebunden werden kann, um Kundenkonten und Berechtigungen zu verwalten und die Nutzung eines Dienstes zu erfassen. Eine vollständige Anleitung zur Einbindung finden Sie in der Dokumentation zur Backend-Einbindung.
Bereinigen
Wenn Sie sie nicht mehr verwenden möchten, löschen Sie die folgenden Ressourcen:
- Das Cloud Pub/Sub-Abo
- Das Dienstkonto und seine Schlüssel
- Optional: das von Ihnen erstellte Projekt
- Optional: Das von Ihnen erstellte Rechnungskonto
Nächste Schritte
Frontend einbinden
In den Beispielen in diesem Codelab werden Konten und Berechtigungen automatisch genehmigt. In der Praxis müssen Ihre Kunden zu einer von Ihnen erstellten Anmeldeseite weitergeleitet werden, auf der sie Konten in Ihrem System erstellen können. Nach der erfolgreichen Registrierung müssen Sie die API-Anfragen senden, um ihre Konten und Berechtigungen zu genehmigen.
Informationen zum Einbinden des Front-Ends Ihrer Anwendung finden Sie in der Google Cloud Marketplace-Dokumentation.
Weitere Informationen zum Anbieten von SaaS-Lösungen
Eine Übersicht über das Anbieten von SaaS-Lösungen auf dem Google Cloud Marketplace finden Sie unter SaaS-Lösungen anbieten.