Integra la tua soluzione SaaS con l'API Google Cloud Marketplace utilizzando Producer Portal (Python)

1. Introduzione

Le soluzioni SaaS su Google Cloud Marketplace sono soluzioni software eseguite sulla tua infrastruttura, a prescindere dalla località, ma fatturate da Google.

In questo codelab, configurerai una soluzione SaaS di base che si integra con Google Cloud Marketplace per:

  • Ricevi notifiche quando un utente si registra per la soluzione di esempio.
  • Approva i clienti che vogliono registrarsi e aggiungili al tuo database.
  • Gestisci gli scenari in cui i clienti vogliono modificare o annullare i piani di fatturazione.
  • Invia a Google report sull'utilizzo.

Questo codelab ti aiuta ad acquisire familiarità con le API Procurement e Service Control di Google Cloud Marketplace. Tieni presente che questa guida non fornisce un ambiente di prodotto completo per i test.

2. Prima di iniziare

  • Utilizza Producer Portal per attivare il codelab per il tuo progetto, se non l'hai già fatto.

Il link diretto al Producer Portal è:

https://console.cloud.google.com/producer-portal?project=YOUR_PROJECT_ID

Per attivare il codelab, fai clic su Attiva nel riquadro Codelab sul lato destro dello schermo.

Per installare i moduli Python, utilizza il seguente comando:

pip install --upgrade google-api-python-client google-cloud-pubsub
  • Clona o scarica il repository GitHub per questo codelab utilizzando il seguente comando:
git clone https://github.com/googlecodelabs/gcp-marketplace-integrated-saas.git
cd gcp-marketplace-integrated-saas

  • Imposta la variabile di ambiente GOOGLE_CLOUD_PROJECT sull'ID di questo progetto:
  • Linux:
export GOOGLE_CLOUD_PROJECT="YOUR_PROJECT_ID"
  • Windows:
set GOOGLE_CLOUD_PROJECT=YOUR_PROJECT_ID
  • Imposta la variabile di ambiente GOOGLE_APPLICATION_CREDENTIALS sul percorso completo del file scaricato:
  • Linux:
export GOOGLE_APPLICATION_CREDENTIALS="[YOUR_MACHINE]/path/service-account-key.json"
  • Windows:
set GOOGLE_APPLICATION_CREDENTIALS=[YOUR_MACHINE]/path/service-account-key.json
  • Per visualizzare una soluzione di esempio in Google Cloud Marketplace, visita Producer Portal e fai clic su Prodotto Codelab nel riquadro Codelab. Puoi anche accedere direttamente alla soluzione all'indirizzo https://console.cloud.google.com/marketplace/product/DEMO-YOUR_PROJECT_ID/isaas-codelab
  • Nella console Google Cloud, nel nuovo progetto, attiva l'API Partner Procurement.

Quindi, configura il backend per la soluzione di esempio.

3. Integrazione con Google Cloud Marketplace

A livello generale, l'integrazione della soluzione di esempio con Google Cloud Marketplace avviene nei seguenti modi:

  • Esegui l'integrazione con Cloud Pub/Sub per ricevere notifiche da Google Cloud Marketplace, ad esempio quando un utente si registra alla tua soluzione. Il Partner Engineer crea un argomento Cloud Pub/Sub a cui devi abbonarti per ricevere le notifiche.
  • Esegui l'integrazione con l'API Partner Procurement per creare account per nuovi clienti. Utilizzi l'API Partner Procurement per aggiornare gli account quando gli utenti selezionano, modificano o annullano i loro piani di abbonamento. Per l'integrazione con l'API, dovrai creare la tua libreria client.
  • Esegui l'integrazione con Google Service Control per generare report sulle informazioni sull'utilizzo.

4. Iscriviti all'argomento Cloud Pub/Sub

Quando un utente sceglie un piano di abbonamento, ricevi una notifica da Google Cloud Marketplace tramite un argomento Cloud Pub/Sub.

Per ascoltare i messaggi in un argomento Cloud Pub/Sub, devi prima creare un abbonamento.

Per creare un abbonamento, utilizza lo script create_subscription.py:

cd gcp-marketplace-integrated-saas/tools
python create_subscription.py

Per visualizzare l'abbonamento, apri la dashboard di Cloud Pub/Sub in Cloud Console:

https://console.cloud.google.com/cloudpubsub/subscriptions

Prova una richiesta di abbonamento di prova

Per testare questa app di esempio come utente, apri il prodotto codelab in Marketplace visitando la pagina https://console.cloud.google.com/marketplace/product/DEMO-YOUR_PROJECT_ID/isaas-codelab. Assicurati di aver selezionato il progetto del codelab e scegli un piano di abbonamento.

Per visualizzare i messaggi Cloud Pub/Sub inviati quando scegli un piano, vai alla radice della directory python3 nel repository ed esegui il comando seguente:

~/gcp-marketplace-integrated-saas/python3$ python -m impl.step_1_pubsub.app

Per visualizzare il codice di esempio che rileva i messaggi Cloud Pub/Sub, vedi https://github.com/googlecodelabs/gcp-marketplace-integrated-saas/blob/master/python3/impl/step_1_pubsub/app.py.

Nel messaggio Cloud Pub/Sub, il campo eventType mostra il motivo per cui è stato inviato. Quando scegli un piano, dovresti visualizzare un messaggio per eventType: ENTITLEMENT_CREATION_REQUESTED, che rappresenta la tua precedente scelta del piano di abbonamento.

Se annulli il piano mentre questo script è in esecuzione, visualizzerai un nuovo messaggio per eventType: ENTITLEMENT_CANCELLED.

Tieni presente che l'esempio riportato sopra non conferma i messaggi. In questo modo puoi eseguire più facilmente i test ricevendo gli stessi messaggi ogni volta che esegui l'app.

Per chiudere lo script, premi CTRL + \.

5. Approvare la richiesta di account

Ora che puoi ricevere messaggi da Google Cloud Marketplace, devi iniziare a gestire le risorse che il servizio di approvvigionamento di Google Cloud Marketplace crea per conto del cliente.

Il primo è la risorsa account. Un account rappresenta la connessione di un cliente al tuo prodotto. Devi memorizzare l'ID account acquisti del cliente nel tuo database per mappare la relazione tra il suo Account Google e il suo account per il tuo servizio.

Quando un cliente sceglie un piano, Google Cloud Marketplace invia una notifica Cloud Pub/Sub che indica che il cliente sta richiedendo un account. La tua app deve approvare la richiesta. In questo codelab, approvi le richieste di account quando vengono ricevuti i messaggi Cloud Pub/Sub.

Crea il database per le informazioni sull'account

Per questo codelab, utilizziamo un semplice database JSON in grado di tenere traccia degli account e degli acquisti dei clienti.

Per testare questo esempio, crea un file con un oggetto JSON vuoto, in qualsiasi posizione della tua workstation:

{}

Imposta la variabile di ambiente PROCUREMENT_CODELAB_DATABASE sul percorso completo di questo file:

  • Linux:
export PROCUREMENT_CODELAB_DATABASE="YOUR_MACHINE/path/EMPTY_JSON_OBJECT.json"
  • Windows:
set PROCUREMENT_CODELAB_DATABASE=YOUR_MACHINE/path/EMPTY_JSON_OBJECT.json

Il modulo che legge e scrive il database si trova in python3/impl/database.

L'implementazione di esempio utilizza uno schema che può essere esteso se integri più di un'offerta di prodotti con Google Cloud Marketplace. Di seguito è riportata una voce di database di esempio per un utente che ha sottoscritto l'abbonamento al piano Molto buono nell'app di esempio:

{
   "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"
         }
      }
   }
}

Nell'implementazione finale, devi connettere la tua app ai tuoi database per collegare gli account Google Cloud Marketplace dei clienti alle tue risorse cliente.

Approvazione dell'account

Per approvare la richiesta di account, esegui questo comando:

~/gcp-marketplace-integrated-saas/python3$ python3 -m impl.step_2_account.app

Il codice campione per approvare un account si trova in impl/step_2_account.

L'implementazione di esempio utilizza la classe Procurement, che gestisce le interazioni con l'API Procurement. Ecco i metodi get_account() e approve_account():

step_2_account/app.py

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

Per questo codelab, nel servizio di approvvigionamento, l'ID fornitore è DEMO-YOUR_PROJECT_ID, dove YOUR_PROJECT_ID è il progetto che hai creato. Quando interagisci con l'API Procurement, il nome dell'account deve utilizzare il seguente formato:

providers/DEMO-YOUR_PROJECT_ID/accounts/account-id

Successivamente, approvi un diritto, ovvero un record dell'acquisto del cliente.

6. Approva il diritto

Quando un cliente sceglie un piano di abbonamento in Google Cloud Marketplace, viene creato un account e subito dopo viene creata una nuova richiesta di diritto. Il diritto rappresenta l'acquisto di un servizio. Prima che il cliente possa iniziare a utilizzare il servizio, devi approvare la richiesta di diritto e poi configurare il servizio in modo che il cliente possa iniziare a utilizzarlo.

Quando l'app di esempio riceve un messaggio Cloud Pub/Sub con eventType ENTITLEMENT_CREATION_REQUESTED, il diritto viene approvato e l'app deve attendere un messaggio ENTITLEMENT_ACTIVE per registrare il diritto nel database, quindi configurare le risorse per il cliente.

Per creare il diritto, esegui questo comando:

~/gcp-marketplace-integrated-saas/python3$ python3 -m impl.step_3_entitlement_create.app

Il codice per approvare il diritto si trova nell'implementazione di esempio.

Successivamente, gestisci le situazioni in cui un cliente richiede una modifica al proprio piano di abbonamento.

7. Approvare le modifiche a un diritto

Se il tuo servizio offre più piani, devi gestire le richieste dei clienti che potrebbero voler eseguire l'upgrade o il downgrade del piano esistente.

Se il tuo servizio ha un solo piano, vai a Gestire gli acquisti annullati.

Non esiste alcuna differenza tecnica tra l'attivazione di un diritto per la prima volta e l'attivazione dopo una modifica del piano. Per questo motivo, l'implementazione di esempio ha un metodo handleActiveEntitlement() condiviso per entrambi i casi. Questo metodo controlla i messaggi in arrivo per rilevare eventi correlati ai diritti:

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)

Il seguente snippet controlla se eventType è ENTITLEMENT_PLAN_CHANGE_REQUESTED o ENTITLEMENT_PLAN_CHANGED:

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

Nell'implementazione finale, quando il diritto torna allo stato ENTITLEMENT_ACTIVE, il metodo di ascolto deve aggiornare il database per riflettere la modifica ed eseguire il provisioning necessario.

A seconda di come hai configurato il prodotto con il tuo Partner Engineer, il tuo servizio potrebbe non consentire downgrade o annullamenti fino alla fine di un ciclo di fatturazione. In questi casi, la modifica del piano continuerà a essere in attesa anche dopo l'approvazione, ma il diritto non tornerà allo stato ENTITLEMENT_ACTIVE finché la modifica del piano non sarà completata.

Per il codice che verifica e approva le modifiche ai diritti, consulta l'implementazione di esempio.

Successivamente, gestisci le situazioni in cui i clienti annullano gli acquisti.

8. Gestire gli acquisti annullati

I clienti possono scegliere di annullare i loro acquisti. A seconda di come hai configurato il prodotto con il Partner Engineer, l'annullamento può diventare effettivo immediatamente o alla fine del ciclo di fatturazione.

Quando un cliente annulla l'acquisto, viene inviato un messaggio con il eventType ENTITLEMENT_PENDING_CANCELLATION. Se hai configurato il prodotto per elaborare immediatamente le cancellazioni, poco dopo viene inviato un messaggio con eventType ENTITLEMENT_CANCELLED.

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

Il tuo servizio deve attendere il messaggio ENTITLEMENT_CANCELLED per rimuovere il diritto dal tuo database e disattivare il servizio per il cliente.

Dopo l'annullamento del diritto, questo viene eliminato dai sistemi di Google e viene inviato un messaggio con eventType ENTITLEMENT_DELETED:

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

Per il codice che annulla il diritto, consulta l'implementazione di esempio.

9. Invio di report sull'utilizzo

Alcuni servizi hanno componenti basati sull'utilizzo, per cui Google deve conoscere l'utilizzo del servizio da parte dei clienti per addebitare l'importo corretto. Il tuo servizio deve segnalare l'utilizzo tramite l'API Service Control di Google.

Se il tuo servizio non ha componenti basati sull'utilizzo, salta questa sezione.

Per informazioni dettagliate sull'invio dei report sull'utilizzo, consulta la documentazione di onboarding.

I report di utilizzo devono essere inviati all'API Service Control di Google ogni ora. In questo codelab, i report vengono inviati utilizzando uno script che puoi pianificare come cron job. Lo script memorizza l'ora dell'ultimo report sull'utilizzo nel database e la utilizza come ora di inizio per misurare l'utilizzo.

Lo script controlla ogni cliente attivo del servizio e invia un report sull'utilizzo a Google Service Control utilizzando il campo consumer_id del diritto del cliente. Lo script aggiorna quindi la voce del database per il cliente in modo che last_report_time sia impostato sull'ora di fine del report sull'utilizzo appena inviato.

Google Service Control espone due metodi: check e report. Il primo deve essere sempre chiamato immediatamente prima di una chiamata al secondo. Se il primo presenta errori, il servizio del cliente deve essere disattivato finché non vengono corretti.

Tutto l'utilizzo di un determinato diritto viene attribuito a un singolo usageReportingId. Tuttavia, per i prodotti SaaS, questo utilizzo è associato alla voce di fatturazione [Charges not specific to a project] in Google Cloud Billing. Se il tuo prodotto SaaS potrebbe essere condiviso su larga scala all'interno dell'organizzazione di un cliente e vuoi supportare l'attribuzione dei costi, ti consigliamo di includere il campo facoltativo userLabels nell'operazione del report sull'utilizzo di tutti i tuoi servizi.

Google Cloud Marketplace riserva le chiavi di etichetta cloudmarketplace.googleapis.com/resource_name e cloudmarketplace.googleapis.com/container_name. Queste etichette hanno lo scopo di acquisire il contesto dell'utilizzo all'interno della gerarchia di servizi e risorse nativi. I nomi assegnati dal cliente a queste risorse sarebbero inclusi come valori delle etichette nei report sull'utilizzo. Ti consigliamo di includere queste etichette nei report sull'utilizzo per impostazione predefinita.

Chiave di etichetta

Valore etichetta

Descrizione

cloudmarketplace.googleapis.com/resource_name

RESOURCE_NAME

Il nome della risorsa associata a una metrica di utilizzo.

cloudmarketplace.googleapis.com/container_name

CONTAINER_NAME

Il nome di un contenitore di risorse.

Il seguente snippet riporta l'utilizzo dell'app demo e attribuisce l'utilizzo del prodotto SaaS alla risorsa assegnata dal cliente denominata products_db. Per questo codelab, service_name è isaas-codelab.mp-marketplace-partner-demos.appspot.com.

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)

Per il codice completo, consulta l'implementazione di esempio di questo script. Per creare un report sull'utilizzo di esempio, esegui il comando seguente:

~/gcp-marketplace-integrated-saas/python3$ python3 -m impl.step_6_usage_reporting.report isaas-codelab.mp-marketplace-partner-demos.appspot.com

10. Complimenti!

Hai scoperto come la tua soluzione SaaS può integrarsi con Google Cloud Marketplace per gestire account e diritti dei clienti e per generare report sull'utilizzo rispetto a un servizio. Per la procedura completa di integrazione, consulta la documentazione sull'integrazione del backend.

Esegui la pulizia

Se non prevedi più di utilizzarli, elimina le seguenti risorse:

  • La sottoscrizione Cloud Pub/Sub
  • Il service account e le relative chiavi
  • (Facoltativo) Il progetto che hai creato
  • (Facoltativo) L'account di fatturazione che hai creato

Passaggi successivi

Integra il frontend

Gli esempi in questo codelab approvano automaticamente account e diritti. In pratica, i tuoi clienti devono essere indirizzati a una pagina di registrazione creata da te, dove possono creare account nel tuo sistema. Una volta completata la registrazione, devi effettuare le richieste API per approvare i loro account e diritti.

Per informazioni sull'integrazione del frontend dell'app, consulta la documentazione di Google Cloud Marketplace.

Scopri di più sull'offerta di soluzioni SaaS

Per una panoramica dell'offerta di soluzioni SaaS su Google Cloud Marketplace, consulta Offerta di soluzioni SaaS.