Intégrer votre solution SaaS à l'API Google Cloud Marketplace à l'aide de Producer Portal (Python)

1. Introduction

Les solutions SaaS de Google Cloud Marketplace sont des solutions logicielles qui s'exécutent sur votre infrastructure, quel que soit leur emplacement, mais sont facturées par Google.

Dans cet atelier de programmation, vous allez configurer une solution SaaS de base qui s'intègre à Google Cloud Marketplace pour :

  • Recevez des notifications lorsqu'un utilisateur s'inscrit à la solution exemple.
  • Approuvez les clients qui souhaitent s'inscrire et ajoutez-les à votre base de données.
  • Gérez les scénarios dans lesquels les clients souhaitent modifier ou résilier leurs forfaits de facturation.
  • Envoyer des rapports d'utilisation à Google.

Cet atelier de programmation vous aide à vous familiariser avec les API Procurement et Service Control de Google Cloud Marketplace. Notez que ce guide ne fournit pas un environnement produit complet pour les tests.

2. Avant de commencer

  • Utilisez Producer Portal pour activer l'atelier de programmation pour votre projet, si vous ne l'avez pas déjà fait.

Le lien direct vers Producer Portal est le suivant :

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

Pour activer l'atelier de programmation, cliquez sur Enable (Activer) dans le panneau "Codelabs" (Ateliers de programmation) à droite de l'écran.

  • Installez Python 3 sur votre ordinateur, avec les modules suivants :
  • Les API Google Client pour Python.
  • La bibliothèque cliente google-cloud-pubsub.

Pour installer les modules Python, utilisez la commande suivante :

pip install --upgrade google-api-python-client google-cloud-pubsub
  • Clonez ou téléchargez le dépôt GitHub pour cet atelier de programmation à l'aide de la commande suivante :
git clone https://github.com/googlecodelabs/gcp-marketplace-integrated-saas.git
cd gcp-marketplace-integrated-saas

Télécharger le fichier ZIP

  • Définissez la variable d'environnement GOOGLE_CLOUD_PROJECT sur l'ID de ce projet :
  • Linux :
export GOOGLE_CLOUD_PROJECT="YOUR_PROJECT_ID"
  • Windows :
set GOOGLE_CLOUD_PROJECT=YOUR_PROJECT_ID
  • Définissez la variable d'environnement GOOGLE_APPLICATION_CREDENTIALS sur le chemin d'accès complet au fichier téléchargé :
  • Linux :
export GOOGLE_APPLICATION_CREDENTIALS="[YOUR_MACHINE]/path/service-account-key.json"
  • Windows :
set GOOGLE_APPLICATION_CREDENTIALS=[YOUR_MACHINE]/path/service-account-key.json
  • Pour afficher un exemple de solution dans Google Cloud Marketplace, accédez à Producer Portal et cliquez sur Produit de l'atelier de programmation dans le panneau "Ateliers de programmation". Vous pouvez également accéder directement à la solution à l'adresse https://console.cloud.google.com/marketplace/product/DEMO-YOUR_PROJECT_ID/isaas-codelab.
  • Dans Google Cloud Console, dans votre nouveau projet, activez l'API Partner Procurement.

Configurez ensuite le backend de l'exemple de solution.

3. Intégrer à Google Cloud Marketplace

En règle générale, vous intégrez l'exemple de solution à Google Cloud Marketplace en appliquant l'une des méthodes suivantes :

  • Effectuez l'intégration à Cloud Pub/Sub pour recevoir des notifications de Google Cloud Marketplace, par exemple lorsqu'un utilisateur s'inscrit à votre solution. Votre ingénieur partenaire crée un sujet Cloud Pub/Sub auquel vous devez vous abonner pour recevoir des notifications.
  • Intégrez l'API Partner Procurement pour créer des comptes pour les nouveaux clients. Vous utilisez l'API Partner Procurement pour mettre à jour les comptes lorsque les utilisateurs sélectionnent, modifient ou annulent leurs forfaits. Pour intégrer l'API, vous devrez créer votre propre bibliothèque cliente.
  • Intégrez-le à Google Service Control pour créer des rapports sur les informations d'utilisation.

4. S'abonner au sujet Cloud Pub/Sub

Lorsqu'un utilisateur choisit un forfait, vous recevez une notification de Google Cloud Marketplace via un sujet Cloud Pub/Sub.

Pour écouter les messages d'un sujet Cloud Pub/Sub, vous devez d'abord créer un abonnement.

Pour créer un abonnement, utilisez le script create_subscription.py :

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

Pour afficher l'abonnement, ouvrez le tableau de bord Cloud Pub/Sub dans la console Cloud :

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

Essayer une demande d'abonnement test

Pour tester cette application exemple en tant qu'utilisateur, ouvrez le produit de l'atelier de programmation sur Marketplace en accédant à https://console.cloud.google.com/marketplace/product/DEMO-YOUR_PROJECT_ID/isaas-codelab. Assurez-vous que votre projet d'atelier de programmation est sélectionné, puis choisissez un forfait.

Pour afficher les messages Cloud Pub/Sub envoyés lorsque vous choisissez un forfait, accédez à la racine du répertoire python3 dans le dépôt, puis exécutez la commande suivante :

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

Pour consulter l'exemple de code qui écoute les messages Cloud Pub/Sub, consultez https://github.com/googlecodelabs/gcp-marketplace-integrated-saas/blob/master/python3/impl/step_1_pubsub/app.py.

Dans le message Cloud Pub/Sub, le champ eventType indique la raison pour laquelle le message a été envoyé. Lorsque vous choisissez un forfait, un message eventType: ENTITLEMENT_CREATION_REQUESTED devrait s'afficher, correspondant à votre choix d'abonnement précédent.

Si vous résiliez votre forfait pendant l'exécution de ce script, un nouveau message s'affiche pour eventType: ENTITLEMENT_CANCELLED.

Notez que l'exemple ci-dessus ne reconnaît pas les messages. Cela vous permet de tester plus facilement en recevant les mêmes messages chaque fois que vous exécutez votre application.

Pour fermer le script, appuyez sur CTRL + \.

5. Approuver la demande de compte

Maintenant que vous pouvez recevoir des messages de Google Cloud Marketplace, vous devez commencer à gérer les ressources que le service d'approvisionnement Google Cloud Marketplace crée au nom du client.

La première est la ressource account. Un compte représente la connexion d'un client à votre produit. Vous devez stocker l'ID du compte d'achat du client dans votre base de données pour mapper la relation entre son compte Google et son compte pour votre service.

Lorsqu'un client choisit un forfait, Google Cloud Marketplace envoie une notification Cloud Pub/Sub indiquant que le client demande un compte. Votre application doit approuver la demande. Dans cet atelier de programmation, vous approuvez les demandes de compte lorsque les messages Cloud Pub/Sub sont reçus.

Créer la base de données pour les informations de compte

Pour cet atelier de programmation, nous utilisons une base de données JSON simple qui permet de suivre les comptes et les achats des clients.

Pour tester cet exemple, créez un fichier avec un objet JSON vide, n'importe où sur votre poste de travail :

{}

Définissez la variable d'environnement PROCUREMENT_CODELAB_DATABASE sur le chemin d'accès complet à ce fichier :

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

Le module qui lit et écrit dans la base de données se trouve dans python3/impl/database.

L'exemple d'implémentation utilise un schéma qui peut être étendu si vous intégrez plusieurs offres de produits à Google Cloud Marketplace. Voici un exemple d'entrée de base de données pour un utilisateur qui s'est abonné au forfait Très bien dans l'application exemple :

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

Dans votre implémentation finale, vous devez associer votre application à vos propres bases de données pour relier les comptes Google Cloud Marketplace des clients à vos propres ressources client.

Approuver le compte

Pour approuver la demande de compte, exécutez la commande suivante :

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

L'exemple de code permettant d'approuver un compte se trouve dans impl/step_2_account.

L'exemple d'implémentation utilise la classe Procurement, qui gère les interactions avec l'API Procurement. Voici ses méthodes get_account() et 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()

Dans cet atelier de programmation, l'ID du fournisseur dans le service d'approvisionnement est DEMO-YOUR_PROJECT_ID, où YOUR_PROJECT_ID correspond au projet que vous avez créé. Lorsque vous interagissez avec l'API Procurement, le nom du compte doit respecter le format suivant :

providers/DEMO-YOUR_PROJECT_ID/accounts/account-id

Ensuite, vous approuvez un droit d'accès, qui est un enregistrement de l'achat du client.

6. Approuver le droit d'accès

Lorsqu'un client choisit un forfait sur Google Cloud Marketplace, un compte est créé, puis une demande de droit est immédiatement créée. Le droit d'accès représente l'achat d'un service. Avant que le client puisse commencer à utiliser le service, vous devez approuver la demande de droit d'accès, puis configurer le service pour qu'il puisse l'utiliser.

Lorsque l'application exemple reçoit un message Cloud Pub/Sub avec eventType ENTITLEMENT_CREATION_REQUESTED, le droit d'accès est approuvé et l'application doit attendre un message ENTITLEMENT_ACTIVE pour enregistrer le droit d'accès dans la base de données, puis configurer les ressources pour le client.

Pour créer le droit d'accès, exécutez la commande suivante :

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

Le code permettant d'approuver le droit d'accès se trouve dans l'exemple d'implémentation.

Ensuite, vous gérez les situations où un client demande à modifier son forfait.

7. Approuver les modifications apportées à un droit d'accès

Si votre service propose plusieurs forfaits, vous devez gérer les demandes des clients qui souhaitent passer à un forfait supérieur ou inférieur.

Si votre service ne comporte qu'un seul forfait, passez à la section "Gérer les achats annulés".

Il n'y a aucune différence technique entre un droit d'accès qui devient actif pour la première fois et un droit d'accès qui devient actif après un changement de forfait. C'est pourquoi l'exemple d'implémentation comporte une méthode handleActiveEntitlement() partagée pour les deux cas. Cette méthode vérifie si les messages entrants contiennent des événements liés aux droits d'accès :

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)

L'extrait suivant vérifie si eventType est ENTITLEMENT_PLAN_CHANGE_REQUESTED ou 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

Dans votre implémentation finale, lorsque le droit d'accès repasse à l'état ENTITLEMENT_ACTIVE, votre méthode d'écouteur doit mettre à jour votre base de données pour refléter le changement et effectuer l'approvisionnement nécessaire.

Selon la façon dont vous avez configuré votre produit avec votre ingénieur partenaire, il est possible que votre service n'autorise pas les changements de forfait ou les résiliations avant la fin d'un cycle de facturation. Dans ce cas, la modification du forfait restera en attente même après l'approbation, mais le droit d'accès ne reviendra pas à l'état ENTITLEMENT_ACTIVE tant que la modification du forfait ne sera pas terminée.

Pour le code qui vérifie et approuve les modifications des droits d'accès, consultez l'exemple d'implémentation.

Ensuite, vous gérez les situations dans lesquelles les clients annulent leurs achats.

8. Gérer les achats annulés

Les clients peuvent choisir d'annuler leurs achats. Selon la façon dont vous avez configuré le produit avec votre ingénieur partenaire, la résiliation peut prendre effet immédiatement ou à la fin du cycle de facturation.

Lorsqu'un client annule son achat, un message avec le code eventType ENTITLEMENT_PENDING_CANCELLATION est envoyé. Si vous avez configuré votre produit pour traiter les résiliations immédiatement, un message avec eventType ENTITLEMENT_CANCELLED est envoyé peu de temps après.

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

Votre service doit attendre le message ENTITLEMENT_CANCELLED pour ensuite supprimer le droit d'accès de votre base de données et désactiver le service pour le client.

Une fois le droit d'accès résilié, il est supprimé des systèmes Google et un message avec le code eventType ENTITLEMENT_DELETED est envoyé :

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

Pour obtenir le code qui annule le droit d'accès, consultez l'exemple d'implémentation.

9. Envoyer des rapports d'utilisation

Certains services comportent des composants basés sur l'utilisation. Google doit donc connaître l'utilisation du service par les clients pour leur facturer le montant correct. Votre service doit signaler l'utilisation via l'API Google Service Control.

Si votre service ne comporte pas de composants basés sur l'utilisation, ignorez cette section.

Pour en savoir plus sur l'envoi de rapports d'utilisation, consultez la documentation d'intégration.

Les rapports d'utilisation doivent être envoyés à l'API Google Service Control toutes les heures. Dans cet atelier de programmation, les rapports sont envoyés à l'aide d'un script que vous pouvez planifier en tant que tâche Cron. Le script stocke l'heure du dernier rapport d'utilisation dans la base de données et l'utilise comme heure de début pour mesurer l'utilisation.

Le script vérifie chaque client actif du service et envoie un rapport d'utilisation à Google Service Control à l'aide du champ consumer_id du droit d'accès client. Le script met ensuite à jour l'entrée de base de données du client pour que last_report_time soit défini sur l'heure de fin du rapport d'utilisation qui vient d'être envoyé.

Google Service Control expose deux méthodes : check et report. Le premier doit toujours être appelé immédiatement avant un appel au second. Si le premier présente des erreurs, le service du client doit être désactivé jusqu'à ce qu'elles soient corrigées.

Toute l'utilisation d'un droit donné est attribuée à un seul usageReportingId. Toutefois, pour les produits SaaS, cette utilisation est associée au poste [Charges not specific to a project] dans Google Cloud Billing. Si votre produit SaaS est susceptible d'être largement partagé au sein de l'organisation d'un client et que vous souhaitez prendre en charge l'attribution des coûts, nous vous recommandons d'inclure le champ facultatif userLabels dans l'opération de rapport d'utilisation de tous vos services.

Google Cloud Marketplace réserve les clés de libellé cloudmarketplace.googleapis.com/resource_name et cloudmarketplace.googleapis.com/container_name. Ces libellés sont destinés à capturer le contexte de l'utilisation dans votre service natif et votre hiérarchie de ressources. Les noms attribués par le client à ces ressources seraient inclus en tant que valeurs de libellé dans les rapports sur l'utilisation. Nous vous recommandons d'inclure ces libellés dans vos rapports d'utilisation par défaut.

Clé du libellé

Valeur du libellé

Description

cloudmarketplace.googleapis.com/resource_name

RESOURCE_NAME

Nom de la ressource associée à une métrique d'utilisation.

cloudmarketplace.googleapis.com/container_name

CONTAINER_NAME

Nom d'un conteneur de ressources.

L'extrait suivant indique l'utilisation de l'application de démonstration et attribue l'utilisation du produit SaaS à la ressource attribuée au client nommée products_db. Pour cet atelier de programmation, le service_name est 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)

Consultez l'exemple d'implémentation de ce script pour obtenir le code complet. Pour générer un exemple de rapport sur l'utilisation, exécutez la commande suivante :

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

10. Félicitations !

Vous avez appris comment votre solution SaaS peut s'intégrer à Google Cloud Marketplace pour gérer les comptes et les droits des clients, et pour générer des rapports sur l'utilisation d'un service. Pour obtenir la procédure d'intégration complète, consultez la documentation sur l'intégration du backend.

Effectuer un nettoyage

Si vous ne prévoyez plus de les utiliser, supprimez les ressources suivantes :

  • Abonnement Cloud Pub/Sub
  • Le compte de service et ses clés
  • Facultatif : le projet que vous avez créé
  • (Facultatif) Le compte de facturation que vous avez créé

Étape suivante

Intégrer votre interface

Les exemples de cet atelier de programmation approuvent automatiquement les comptes et les droits d'accès. En pratique, vos clients doivent être redirigés vers une page d'inscription que vous avez créée, où ils peuvent créer des comptes dans votre système. Une fois l'inscription effectuée, vous devez envoyer les requêtes API pour approuver leurs comptes et leurs droits d'accès.

Pour en savoir plus sur l'intégration de l'interface de votre application, consultez la documentation Google Cloud Marketplace.

En savoir plus sur les offres de solutions SaaS

Pour obtenir une présentation des offres de solutions SaaS sur Google Cloud Marketplace, consultez Proposer des solutions SaaS.