1. Introducción
Las soluciones de SaaS en Google Cloud Marketplace son soluciones de software que se ejecutan en tu infraestructura, sin importar la ubicación, pero que factura Google.
En este codelab, configurarás una solución de SaaS básica que se integra con Google Cloud Marketplace para hacer lo siguiente:
- Recibir notificaciones cuando un usuario se registre en la solución de muestra
- Aprueba a los clientes que quieran registrarse y agrégalos a tu base de datos.
- Maneja situaciones en las que los clientes quieren cambiar o cancelar sus planes de facturación.
- Enviar informes de uso a Google
En este codelab, te familiarizarás con las APIs de Service Control y de adquisición de Google Cloud Marketplace. Ten en cuenta que esta guía no proporciona un entorno de producto completo para las pruebas.
2. Antes de comenzar
- Usa Producer Portal para habilitar el codelab para tu proyecto, si aún no lo hiciste.
El vínculo directo a Producer Portal es el siguiente:
https://console.cloud.google.com/producer-portal?project=YOUR_PROJECT_ID
Para habilitar el codelab, haz clic en Habilitar en el panel de Codelabs que se encuentra en el lado derecho de la pantalla.
- Instala Python 3 en tu máquina con los siguientes módulos:
- Las APIs de cliente de Google para Python
- La biblioteca cliente de
google-cloud-pubsub
Para instalar los módulos de Python, usa el siguiente comando:
pip install --upgrade google-api-python-client google-cloud-pubsub
- Clona o descarga el repositorio de GitHub para este codelab con el siguiente comando:
git clone https://github.com/googlecodelabs/gcp-marketplace-integrated-saas.git cd gcp-marketplace-integrated-saas
- Establece la variable de entorno
GOOGLE_CLOUD_PROJECT
en el ID de este proyecto: - Linux:
export GOOGLE_CLOUD_PROJECT="YOUR_PROJECT_ID"
- Windows:
set GOOGLE_CLOUD_PROJECT=YOUR_PROJECT_ID
- Otorga el rol de editor de Pub/Sub a la cuenta de servicio
saas-codelab
. Para obtener información sobre cómo otorgar y administrar roles, consulta Otorga, cambia y revoca el acceso a los recursos. - Crea y descarga una clave JSON para la cuenta de servicio. Para obtener información sobre cómo crear la clave, consulta Crea y administra claves de cuentas de servicio.
- Establece la variable de entorno
GOOGLE_APPLICATION_CREDENTIALS
en la ruta completa al archivo descargado: - Linux:
export GOOGLE_APPLICATION_CREDENTIALS="[YOUR_MACHINE]/path/service-account-key.json"
- Windows:
set GOOGLE_APPLICATION_CREDENTIALS=[YOUR_MACHINE]/path/service-account-key.json
- Para ver una solución de muestra en Google Cloud Marketplace, visita Producer Portal y haz clic en Codelab product en el panel de Codelabs. También puedes acceder a la solución directamente en https://console.cloud.google.com/marketplace/product/DEMO-YOUR_PROJECT_ID/isaas-codelab
- En la consola de Google Cloud, en tu proyecto nuevo, habilita la API de Partner Procurement.
A continuación, configura el backend para la solución de ejemplo.
3. Integración con Google Cloud Marketplace
En un nivel alto, integras la solución de muestra en Google Cloud Marketplace de las siguientes maneras:
- Integra en Cloud Pub/Sub para recibir notificaciones de Google Cloud Marketplace, como cuando un usuario se registra para la solución. Tu ingeniero socio crea un tema de Cloud Pub/Sub al que te debes suscribir para recibir notificaciones.
- Integra la API de Partner Procurement para crear cuentas para clientes nuevos. Usas la API de Partner Procurement para actualizar las cuentas cuando los usuarios seleccionan, cambian o cancelan sus planes de suscripción. Para integrarte en la API, deberás compilar tu propia biblioteca cliente.
- Realiza la integración con el Control de servicios de Google para informar la información de uso.
4. Suscríbete al tema de Cloud Pub/Sub
Cuando un usuario elige un plan de suscripción, recibes una notificación de Google Cloud Marketplace a través de un tema de Cloud Pub/Sub.
Para escuchar mensajes en un tema de Cloud Pub/Sub, primero debes crear una suscripción.
Para crear una suscripción, usa la secuencia de comandos create_subscription.py
:
cd gcp-marketplace-integrated-saas/tools python create_subscription.py
Para ver la suscripción, abre el panel de Cloud Pub/Sub en la consola de Cloud:
https://console.cloud.google.com/cloudpubsub/subscriptions
Prueba una solicitud de suscripción de prueba
Para probar esta app de ejemplo como usuario, visita https://console.cloud.google.com/marketplace/product/DEMO-YOUR_PROJECT_ID/isaas-codelab y abre el producto del codelab en Marketplace. Asegúrate de tener seleccionado tu proyecto del codelab y elige un plan de suscripción.
Para ver los mensajes de Cloud Pub/Sub que se envían cuando eliges un plan, navega a la raíz del directorio python3
en el repositorio y ejecuta el siguiente comando:
~/gcp-marketplace-integrated-saas/python3$ python -m impl.step_1_pubsub.app
Para ver el código de muestra que detecta mensajes de Cloud Pub/Sub, consulta https://github.com/googlecodelabs/gcp-marketplace-integrated-saas/blob/master/python3/impl/step_1_pubsub/app.py.
En el mensaje de Cloud Pub/Sub, el campo eventType
muestra por qué se envió el mensaje. Cuando elijas un plan, deberías ver un mensaje para eventType: ENTITLEMENT_CREATION_REQUESTED
, que representa tu elección anterior del plan de suscripción.
Si cancelas tu plan mientras se ejecuta este script, verás un nuevo mensaje para eventType: ENTITLEMENT_CANCELLED
.
Ten en cuenta que la muestra anterior no confirma la recepción de los mensajes. Esto te permite realizar pruebas con mayor facilidad, ya que recibirás los mismos mensajes cada vez que ejecutes la app.
Para cerrar el script, presiona CTRL + \
.
5. Aprobar la solicitud de la cuenta
Ahora que puedes recibir mensajes de Google Cloud Marketplace, debes comenzar a controlar los recursos que el servicio de aprovisionamiento de Google Cloud Marketplace crea en nombre del cliente.
El primero es el recurso account. Una cuenta representa la conexión de un cliente con tu producto. Debes almacenar el ID de la cuenta de Adquisiciones del cliente en tu base de datos para asignar la relación entre su Cuenta de Google y su cuenta de tu servicio.
Cuando un cliente elige un plan, Google Cloud Marketplace envía una notificación de Cloud Pub/Sub que indica que el cliente solicita una cuenta. Tu app debe aprobar la solicitud. En este codelab, aprobarás las solicitudes de cuentas cuando se reciban los mensajes de Cloud Pub/Sub.
Crea la base de datos para la información de la cuenta
En este codelab, usaremos una base de datos JSON simple que puede hacer un seguimiento de las cuentas y las compras de los clientes.
Para probar este ejemplo, crea un archivo con un objeto JSON vacío en cualquier lugar de tu estación de trabajo:
{}
Establece la variable de entorno PROCUREMENT_CODELAB_DATABASE
en la ruta completa a este archivo:
- Linux:
export PROCUREMENT_CODELAB_DATABASE="YOUR_MACHINE/path/EMPTY_JSON_OBJECT.json"
- Windows:
set PROCUREMENT_CODELAB_DATABASE=YOUR_MACHINE/path/EMPTY_JSON_OBJECT.json
El módulo que lee y escribe en la base de datos se encuentra en python3/impl/database
.
La implementación de muestra usa un esquema que se puede extender si integras más de una oferta de productos con Google Cloud Marketplace. A continuación, se muestra un ejemplo de entrada de base de datos para un usuario que se suscribió al plan Very Good en la app de ejemplo:
{
"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"
}
}
}
}
En la implementación final, debes conectar tu app con tus propias bases de datos para vincular las cuentas de Google Cloud Marketplace de los clientes con tus propios recursos de clientes.
Aprobar la cuenta
Para aprobar la solicitud de la cuenta, ejecuta el siguiente comando:
~/gcp-marketplace-integrated-saas/python3$ python3 -m impl.step_2_account.app
El código de muestra para aprobar una cuenta se encuentra en impl/step_2_account.
La implementación de muestra usa la clase Procurement
, que controla las interacciones con la API de Procurement. Estos son sus métodos get_account()
y 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()
En este codelab, en el servicio de Procurement, el ID del proveedor es DEMO-
YOUR_PROJECT_ID
, donde YOUR_PROJECT_ID
es el proyecto que creaste. Cuando interactúes con la API de Procurement, el nombre de la cuenta debe usar el siguiente formato:
providers/DEMO-YOUR_PROJECT_ID/accounts/account-id
A continuación, aprobarás un derecho, que es un registro de la compra del cliente.
6. Aprobar el derecho
Cuando un cliente elige un plan de suscripción en Google Cloud Marketplace, se crea una cuenta y, luego, se crea de inmediato una nueva solicitud de autorización. El derecho representa la compra de un servicio. Antes de que el cliente pueda comenzar a usar el servicio, debes aprobar la solicitud de derechos y, luego, configurar el servicio para que el cliente pueda comenzar a usarlo.
Cuando la app de ejemplo recibe un mensaje de Cloud Pub/Sub con eventType
ENTITLEMENT_CREATION_REQUESTED
, se aprueba el derecho y la app debe esperar un mensaje ENTITLEMENT_ACTIVE
para registrar el derecho en la base de datos y, luego, configurar los recursos para el cliente.
Para crear el derecho, ejecuta el siguiente comando:
~/gcp-marketplace-integrated-saas/python3$ python3 -m impl.step_3_entitlement_create.app
El código para aprobar el derecho se encuentra en la implementación de muestra.
A continuación, abordarás situaciones en las que un cliente solicita un cambio en su plan de suscripción.
7. Cómo aprobar cambios en un derecho
Si tu servicio tiene varios planes, debes controlar las solicitudes de los clientes que deseen actualizar o cambiar a una versión inferior su plan existente.
Si tu servicio solo tiene un plan, ve a Controla las compras canceladas.
No hay diferencias técnicas entre que un derecho se active por primera vez y que se active después de un cambio de plan. Por este motivo, la implementación de muestra tiene un método handleActiveEntitlement()
compartido para ambos casos. Este método verifica los mensajes entrantes en busca de eventos relacionados con derechos:
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)
En el siguiente fragmento, se verifica si eventType
es 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
En tu implementación final, cuando el derecho vuelva al estado ENTITLEMENT_ACTIVE
, tu método de escucha deberá actualizar la base de datos para reflejar el cambio y realizar el aprovisionamiento necesario.
Según cómo configures tu producto con el ingeniero socio, es posible que tu servicio no permita cambios a una versión inferior ni cancelaciones hasta el final de un ciclo de facturación. En esos casos, el cambio de plan seguirá pendiente incluso después de la aprobación, pero el derecho no volverá al estado ENTITLEMENT_ACTIVE
hasta que se complete el cambio de plan.
Para ver el código que verifica y aprueba los cambios en los derechos, consulta la implementación de ejemplo.
A continuación, debes abordar las situaciones en las que los clientes cancelan sus compras.
8. Cómo controlar las compras canceladas
Los clientes pueden cancelar sus compras. Según cómo configures el producto con tu ingeniero socio, la cancelación puede entrar en vigencia de inmediato o al final del ciclo de facturación.
Cuando un cliente cancela su compra, se envía un mensaje con el eventType
ENTITLEMENT_PENDING_CANCELLATION
. Si configuraste tu producto para que procese las cancelaciones de inmediato, se enviará un mensaje con eventType
ENTITLEMENT_CANCELLED
poco despué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
Tu servicio debe esperar el mensaje ENTITLEMENT_CANCELLED
para quitar el derecho de tu base de datos y desactivar el servicio para el cliente.
Después de que se cancela el derecho, se borra de los sistemas de Google y se envía un mensaje 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
Para ver el código que cancela el derecho, consulta la implementación de muestra.
9. Envío de informes de uso
Algunos servicios tienen componentes basados en el uso, en los que Google necesita conocer el uso que hacen los clientes del servicio para cobrarles el importe correcto. Tu servicio debe informar el uso a través de la API de Google Service Control.
Si tu servicio no tiene componentes basados en el uso, omite esta sección.
Para obtener información detallada sobre el envío de informes de uso, consulta la documentación de incorporación.
Los informes de uso se deben enviar a la API de Control de servicios de Google cada hora. En este codelab, los informes se envían con una secuencia de comandos que podrías programar como un trabajo cron. La secuencia de comandos almacena la hora del último informe de uso en la base de datos y la usa como hora de inicio para medir el uso.
La secuencia de comandos verifica cada cliente activo del servicio y envía un informe de uso al Control de servicios de Google con el campo consumer_id
del derecho del cliente. Luego, la secuencia de comandos actualiza la entrada de la base de datos del cliente para que tenga un last_report_time
establecido en la hora de finalización del informe de uso que se acaba de enviar.
Google Service Control expone dos métodos: check
y report
. El primero siempre debe llamarse inmediatamente antes de una llamada al segundo. Si el primero tiene algún error, se debe inhabilitar el servicio del cliente hasta que se solucione.
Todo el uso de un derecho determinado se atribuye a un solo usageReportingId
. Sin embargo, en el caso de los productos de SaaS, este uso se asocia con el concepto [Charges not specific to a project]
en la facturación de Google Cloud. Si es posible que tu producto de SaaS se comparta ampliamente dentro de la organización de un cliente y deseas admitir la atribución de costos, te recomendamos que todos tus servicios incluyan el campo opcional userLabels
en su operación de informe de uso.
Google Cloud Marketplace reserva las claves de etiquetas cloudmarketplace.googleapis.com/resource_name y cloudmarketplace.googleapis.com/container_name. Estas etiquetas tienen como objetivo capturar el contexto del uso dentro de la jerarquía de recursos y servicios nativos. Los nombres asignados por el cliente a estos recursos se incluirían como valores de etiquetas en los informes de uso. Te recomendamos que incluyas estas etiquetas en tus informes de uso de forma predeterminada.
Clave de etiqueta | Valor de etiqueta | Descripción |
cloudmarketplace.googleapis.com/resource_name | RESOURCE_NAME | Es el nombre del recurso asociado a una métrica de uso. |
cloudmarketplace.googleapis.com/container_name | CONTAINER_NAME | Es el nombre de un contenedor de recursos. |
En el siguiente fragmento, se informa el uso de la app de demostración y se atribuye el uso del producto de SaaS al recurso asignado por el cliente llamado products_db
. En este codelab, el service_name
es 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)
Consulta la implementación de muestra de esta secuencia de comandos para ver el código completo. Para generar un informe de uso de muestra, ejecuta el siguiente comando:
~/gcp-marketplace-integrated-saas/python3$ python3 -m impl.step_6_usage_reporting.report isaas-codelab.mp-marketplace-partner-demos.appspot.com
10. ¡Felicitaciones!
Aprendiste cómo tu solución de SaaS puede integrarse en Google Cloud Marketplace para controlar las cuentas y los derechos de los clientes, y para informar el uso en relación con un servicio. Para ver los pasos de integración completos, consulta la documentación de la integración del backend.
Haz una limpieza
Si ya no planeas usarlos, borra los siguientes recursos:
- La suscripción a Cloud Pub/Sub
- La cuenta de servicio y sus claves
- De manera opcional, el proyecto que creaste
- Opcionalmente, la cuenta de facturación que creaste
¿Qué sigue?
Integra tu frontend
En los ejemplos de este codelab, se aprueban automáticamente las cuentas y los derechos. En la práctica, se debe dirigir a tus clientes a una página de registro que crees, en la que puedan crear cuentas en tu sistema. Después de que se registren correctamente, debes realizar las solicitudes a la API para aprobar sus cuentas y derechos.
Para obtener información sobre la integración del frontend de tu app, consulta la documentación de Google Cloud Marketplace.
Más información para ofrecer soluciones de SaaS
Para obtener una descripción general de la oferta de soluciones de SaaS en Google Cloud Marketplace, consulta Oferta de soluciones de SaaS.