1. Descripción general
La serie de codelabs Serverless Migration Station (instructivos prácticos y autoaprendizaje) y los videos relacionados tienen como objetivo ayudar a los desarrolladores de Google Cloud sin servidores a modernizar sus apps guiándolos a través de una o más migraciones, en especial al alejarse de los servicios heredados. De esta manera, tus apps serán más portátiles, y tendrás más opciones y flexibilidad, lo que te permitirá integrarlas con una variedad más amplia de productos de Cloud y acceder a ella, y actualizar con mayor facilidad a versiones de idiomas más recientes. Aunque inicialmente se enfoca en los primeros usuarios de Cloud, principalmente los desarrolladores de App Engine (entorno estándar), esta serie es lo suficientemente amplia como para incluir otras plataformas sin servidores como Cloud Functions y Cloud Run, o cualquier otra, si corresponde.
El propósito de este codelab es mostrarles a los desarrolladores de App Engine de Python 2 cómo migrar de la API o el servicio de usuarios de App Engine a Cloud Identity Platform (GCIP). También hay una migración implícita de App Engine NDB a Cloud NDB para el acceso a Datastore (que se aborda principalmente en el Módulo de migración 2), así como una actualización a Python 3.
El módulo 20 explica cómo agregar el uso de la API de usuarios a la app de ejemplo del módulo 1. En este módulo, tomarás la app finalizada del Módulo 20 y migrarás su uso a Cloud Identity Platform.
En un próximo lab,
- Reemplaza el uso del servicio de usuarios de App Engine por Cloud Identity Platform.
- Reemplaza el uso de App Engine NDB por Cloud NDB (consulta también el Módulo 2).
- Configura diferentes proveedores de identidad de autenticación con Firebase Auth
- Usa la API de Cloud Resource Manager para obtener información de IAM del proyecto
- Usa el SDK de Firebase Admin para obtener información de los usuarios
- Cómo migrar la aplicación de ejemplo a Python 3
Requisitos
- Un proyecto de Google Cloud Platform con una cuenta de facturación de GCP activa
- Habilidades básicas de Python
- Conocimiento práctico de los comandos comunes de Linux
- Conocimientos básicos sobre el desarrollo y la implementación de aplicaciones de App Engine
- Una app de ejemplo del módulo 20 de App Engine en funcionamiento
Encuesta
¿Cómo usarás este instructivo?
¿Cómo calificarías tu experiencia en Python?
¿Cómo calificarías tu experiencia en el uso de los servicios de Google Cloud?
2. Información general
El servicio de usuarios de App Engine es un sistema de autenticación de usuarios para que lo usen las apps de App Engine. Proporciona Acceso con Google como su proveedor de identidad, proporciona vínculos de acceso y salida convenientes para usar en apps y admite el concepto de usuarios administradores y funcionalidad exclusiva de administrador. Para mejorar la portabilidad de la aplicación, Google Cloud recomienda migrar de servicios empaquetados de App Engine heredados a servicios independientes de Cloud, por ejemplo, del servicio de usuarios a Cloud Identity Platform, entre otros.
Identity Platform se basa en Firebase Authentication y agrega una serie de funciones empresariales, como la autenticación de varios factores, OIDC y Compatibilidad con SSO de SAML, multiusuario, ANS del 99.95% y mucho más. Estas diferencias también se destacan en la página de comparación de productos de Identity Platform y Firebase Authentication. Ambos productos tienen muchas más funciones que la funcionalidad proporcionada por el servicio de usuarios.
Este codelab del módulo 21 muestra cómo cambiar la autenticación de usuarios de la app del servicio de usuarios a las funciones de Identity Platform que reflejan con mayor precisión la funcionalidad que se demostró en el módulo 20. En el módulo 21, también se presenta una migración de App Engine NBS a Cloud Datastore para el acceso a Datastore, en la que se repite la migración del Módulo 2.
Mientras que el código del módulo 20 está “anunciado” Como app de ejemplo de Python 2, la fuente en sí es compatible con Python 2 y 3, y se mantiene así incluso después de migrar a Identity Platform (y Cloud NDB) en el módulo 21. Es posible seguir usando el servicio de usuarios mientras actualizas a Python 3, ya que migrar a Identity Platform es opcional. Consulta el codelab del módulo 17 y el video para aprender a seguir usando los servicios en paquetes mientras actualizas a entornos de ejecución de 2a generación, como Python 3.
En este instructivo, se muestran los siguientes pasos:
- Configurar/trabajo previo
- Actualizar configuración
- Modifica el código de la aplicación
3. Configurar/trabajo previo
Esta sección explica cómo:
- Configura el proyecto de Cloud
- Obtén app de ejemplo del modelo de referencia
- (Re)Implementa y valida la app de referencia
- Habilitar nuevas APIs o servicios de Google Cloud
Estos pasos garantizan que comiences con un código funcional que está listo para migrar a servicios de Cloud independientes.
1. Configura el proyecto
Si completaste el codelab del módulo 20, vuelve a usar ese mismo proyecto (y código). Como alternativa, crea un proyecto completamente nuevo o reutiliza otro proyecto existente. Asegúrate de que el proyecto tenga una cuenta de facturación activa y una app de App Engine habilitada. Busca tu ID del proyecto, tenlo a mano durante este codelab y úsalo cuando encuentres la variable PROJ_ID
.
2. Obtén app de ejemplo del modelo de referencia
Uno de los requisitos previos es contar con una app de App Engine del Módulo 20 que funcione, así que completa el codelab (se recomienda incluir el vínculo anterior) o copia el código del módulo 20 del repositorio. Ya sea que use el suyo o el nuestro, aquí es por donde comenzaremos ("COMENZAR"). En este codelab, se explica la migración y se concluye con un código similar al que hay en la carpeta del repositorio del Módulo 21 (“FINISH”).
- INICIO: Carpeta del módulo 20 (Python 2)
- FIN: Carpetas del módulo 21 ( Python 2 o Python 3)
- Repositorio completo (para clonar o descargar un archivo ZIP)
Copia la carpeta del repositorio del módulo 20. Debería verse como el siguiente resultado, y es posible que tenga una carpeta lib
si realizaste el codelab del módulo 20:
$ ls README.md appengine_config.py templates app.yaml main.py requirements.txt
3. (Re)Implementa y valida la app de referencia
Ejecuta los siguientes pasos para implementar la app del módulo 20:
- Borra la carpeta
lib
si hay una y ejecutapip install -t lib -r requirements.txt
para volver a propagarla. Es posible que debas usarpip2
si tienes instalados Python 2 y 3. - Asegúrate de haber instalado e inicializado la herramienta de línea de comandos de
gcloud
y de haber revisado su uso. - Si no quieres ingresar tu
PROJ_ID
con cada comandogcloud
emitido, configura el proyecto de Cloud congcloud config set project
PROJ_ID
primero. - Implementa la app de ejemplo con
gcloud app deploy
- Confirma que la app se ejecute como se espera y sin errores. Si completaste el codelab del módulo 20, la app mostrará la información de acceso del usuario (correo electrónico del usuario, posible “insignia de administrador” y botón para acceder y salir) en la parte superior junto con las visitas más recientes (que se ilustran a continuación).
Al acceder como usuario normal, se muestra la dirección de correo electrónico del usuario y la opción "Acceder" del botón cambia a “Salir” :
Al acceder como usuario administrador, la dirección de correo electrónico del usuario aparece junto con "(administrador)" junto a él:
4. Habilitar nuevos servicios o APIs de Google Cloud
Introducción
La app del Módulo 20 usa las API de App Engine NDB y Users, servicios agrupados que no requieren una configuración adicional, pero los servicios independientes de Cloud sí lo hacen. La app actualizada empleará Cloud Identity Platform y Cloud Datastore (a través de la biblioteca cliente de Cloud NDB). Además, la necesidad de determinar los usuarios administradores de App Engine también requiere el uso de la API de Cloud Resource Manager.
Costo
- App Engine y Cloud Datastore tienen la opción "Siempre gratuito" nivel y, siempre que te mantengas por debajo de esos límites, no se generarán cargos si completas este instructivo. Consulta también la página de precios de App Engine y la página de precios de Cloud Datastore para obtener más detalles.
- El uso de Cloud Identity Platform se factura según la cantidad de usuarios activos por mes (MAU) o verificaciones de autenticación. alguna versión de "gratis" está disponible para cada modelo de uso. Consulta su página de precios para obtener más detalles. Además, si bien App Engine y Cloud Datastore requieren facturación, el uso de GCIP por sí solo no requiere que se habilite la facturación, siempre y cuando no se excedan las cuotas diarias sin instrumentación, por lo que debes tener esto en cuenta para los proyectos de Cloud que no incluyen APIs o servicios de Cloud que requieren facturación.
- El uso de la API de Cloud Resource Manager es gratuito en su mayor parte según su página de precios.
Los usuarios habilitan las APIs de Cloud desde la consola de Cloud o desde la línea de comandos (a través del comando gcloud
, que forma parte del SDK de Cloud), según tus preferencias. Comencemos con las APIs de Cloud Datastore y Cloud Resource Manager.
Desde la consola de Cloud
Ve a la página Biblioteca del Administrador de APIs (para el proyecto correcto) en la consola de Cloud y busca una API con la barra de búsqueda.
Habilita estas APIs:
Busca el botón Habilitar para cada API por separado y haz clic en él. Es posible que se te soliciten datos de facturación. Por ejemplo, esta es la página de la API de Resource Manager:
El botón cambia a Administrar cuando se habilita (por lo general, después de unos segundos):
Habilita Cloud Datastore de la misma manera:
Desde la línea de comandos
Aunque resulta visualmente informativo habilitar las APIs desde la consola, algunos prefieren la línea de comandos. Tienes la ventaja adicional de poder habilitar cualquier cantidad de APIs a la vez. Ejecuta este comando para habilitar las APIs de Cloud Datastore y Cloud Resource Manager, y espera a que se complete la operación, como se muestra aquí:
$ gcloud services enable cloudresourcemanager.googleapis.com datastore.googleapis.com Operation "operations/acat.p2-aaa-bbb-ccc-ddd-eee-ffffff" finished successfully.
Es posible que se le soliciten datos de facturación.
Las "URL" de cada API usada en el comando anterior se denominan nombres de servicios de API y se encuentran al final de la página de la biblioteca para cada API. Si quieres habilitar otras APIs de Cloud para tus propias apps, puedes encontrar sus nombres de servicio correspondientes en las páginas de las APIs correspondientes. Con este comando, se enumeran todos los nombres de servicios para las APIs que puedes habilitar:
gcloud services list
--available --filter="name:googleapis.com"
Ya sea en la consola de Cloud o en la línea de comandos, una vez que hayas completado los pasos anteriores, nuestra muestra podrá acceder a esas APIs. Los próximos pasos son habilitar Cloud Identity Platform y realizar los cambios de código necesarios.
Habilita y configura Cloud Identity Platform (solo la consola de Cloud)
Cloud Identity Platform es un servicio de Marketplace porque se conecta a un recurso fuera de Google Cloud o depende de él, por ejemplo, Firebase Authentication. En este momento, solo puedes habilitar los servicios de Marketplace en la consola de Cloud. Siga los pasos que se indican a continuación:
- Ve a la página de Cloud Identity Platform en Cloud Marketplace y haz clic en el botón Habilitar. Actualiza desde Firebase Authentication si se te solicita. Con esta acción, desbloqueas funciones adicionales, como las que se describieron antes en la sección Segundo plano. Esta es la página de Marketplace en la que se destaca el botón Habilitar:
- Una vez que se habilite Identity Platform, es posible que se te dirija automáticamente a la página Proveedores de identidad. De lo contrario, usa este vínculo conveniente para acceder.
- Habilita el proveedor de Google Auth. Si no se configuraron proveedores, haz clic en Agregar un proveedor y selecciona Google. Cuando regreses a esta pantalla, la entrada Google debería estar habilitada. Google es el único proveedor de autenticación que usamos en este instructivo para duplicar el servicio de usuarios de App Engine como un servicio ligero de Acceso con Google. En tus propias apps, puedes habilitar proveedores de autenticación adicionales.
- Una vez que hayas seleccionado y configurado Google y otros proveedores de autenticación deseados, haz clic en Detalles de configuración de la aplicación y, en la ventana de diálogo de garantía, copia
apiKey
yauthDomain
en el objetoconfig
de la pestaña Web, y guarda ambos en un lugar seguro. ¿Por qué no copiarlo todo? El fragmento de este diálogo está codificado y tiene una fecha, por lo que solo debes guardar los bits más importantes y usarlos en nuestro código con un uso más simultáneo de Firebase Auth. Después de copiar los valores y guardarlos en un lugar seguro, haz clic en el botón Cerrar para completar toda la configuración necesaria.
4. Actualizar configuración
Las actualizaciones de la configuración incluyen el cambio de varios archivos de configuración y la creación del equivalente de App Engine, pero dentro del ecosistema de Cloud Identity Platform.
appengine_config.py
- Si actualizas a Python 3, borra
appengine_config.py
. - Si planeas modernizar a Identity Platform, pero te quedaste en Python 2, no borres el archivo. En su lugar, lo actualizaremos más adelante durante la portabilidad a versiones anteriores de Python 2.
requirements.txt
El archivo requirements.txt
del módulo 20 solo mostraba Flask. Para el módulo 21, agrega los siguientes paquetes:
El contenido de requirements.txt
debería verse de la siguiente manera:
flask
google-auth
google-cloud-ndb
google-cloud-resource-manager
firebase-admin
app.yaml
- La actualización a Python 3 implica simplificar el archivo
app.yaml
. Quita todo excepto la directiva del entorno de ejecución y configúralo en una versión compatible actual de Python 3. Actualmente, el ejemplo usa la versión 3.10. - Si te quedas con Python 2, aún no debes realizar ninguna acción aquí.
ANTES:
runtime: python27
threadsafe: yes
api_version: 1
handlers:
- url: /.*
script: main.app
La app de muestra del módulo 20 no tiene controladores de archivos estáticos. Si tus apps lo hacen, déjalas intactas. Si lo deseas, puedes quitar todos los controladores de secuencia de comandos o dejarlos allí como referencia, siempre y cuando los cambies a auto
, como se describe en la guía de migración de app.yaml
. Con estos cambios, el app.yaml
actualizado para Python 3 se simplifica a:
DESPUÉS:
runtime: python310
Otras actualizaciones de configuración
Ya sea que permanezcas en Python 2 o tengan portabilidad a Python 3, si tienes una carpeta lib
, bórrala.
5. Modifica el código de la aplicación
En esta sección, se incluyen actualizaciones para el archivo principal de la aplicación, main.py
, que reemplazan el uso del servicio de usuarios de App Engine por Cloud Identity Platform. Después de actualizar la aplicación principal, actualizarás la plantilla web templates/index.html
.
Actualizar las importaciones y la inicialización
Sigue los pasos que se indican a continuación para actualizar las importaciones y, además, inicializar los recursos de la aplicación:
- Para las importaciones, reemplaza App Engine NDB por Cloud NDB.
- Junto con Cloud NDB, también importa Cloud Resource Manager.
- Identity Platform se basa en Firebase Auth, así que importa el SDK de Firebase Admin.
- Las APIs de Cloud requieren el uso de un cliente de API, así que inícialo para Cloud NDB justo debajo de inicializar Flask.
Si bien el paquete de Cloud Resource Manager se importa aquí, lo usaremos en una etapa posterior de la inicialización de la app. A continuación, se muestran las importaciones y la inicialización del módulo 20, seguidas de cómo deberían verse las secciones después de implementar los cambios anteriores:
ANTES:
from flask import Flask, render_template, request
from google.appengine.api import users
from google.appengine.ext import ndb
app = Flask(__name__)
DESPUÉS:
from flask import Flask, render_template, request
from google.auth import default
from google.cloud import ndb, resourcemanager
from firebase_admin import auth, initialize_app
# initialize Flask and Cloud NDB API client
app = Flask(__name__)
ds_client = ndb.Client()
Asistencia para usuarios administradores de App Engine
Hay dos componentes para agregar a la app que admiten el reconocimiento de usuarios administradores:
_get_gae_admins()
: Recopila un conjunto de usuarios administradores. llamado una vez y guardóis_admin()
: Verifica si un usuario que accedió es un usuario administrador. con cualquier sesión de usuario
La función de utilidad, _get_gae_admins()
, llama a la API de Resource Manager para recuperar la política de permiso de Cloud IAM actual. La política de permisos define y aplica qué roles se otorgan a qué principales (usuarios humanos, cuentas de servicio, etcétera). La configuración incluye lo siguiente:
- Recuperando el ID del proyecto de Cloud (
PROJ_ID
) - Crea un cliente de la API de Resource Manager (
rm_client
) - Crear un conjunto (de solo lectura) de funciones de administrador de App Engine (
_TARGETS
)
Resource Manager requiere el ID del proyecto de Cloud, así que importa google.auth.default()
y llama a esa función para obtener el ID del proyecto. Esa llamada incluye un parámetro que parece una URL, pero es un alcance de permiso OAuth2. Cuando se ejecutan apps en la nube, por ejemplo, en una VM de Compute Engine o en una app de App Engine, se proporciona una cuenta de servicio predeterminada con amplios privilegios. De acuerdo con la práctica recomendada de privilegio mínimo, te sugerimos que crees tus propias cuentas de servicio administradas por el usuario.
Para las llamadas a la API, es mejor reducir aún el alcance de tus apps al nivel mínimo necesario para funcionar correctamente. La llamada a la API de Resource Manager que realizaremos es get_iam_policy()
, que necesita uno de los siguientes permisos para funcionar:
https://www.googleapis.com/auth/cloud-platform
https://www.googleapis.com/auth/cloud-platform.read-only
https://www.googleapis.com/auth/cloudplatformprojects
https://www.googleapis.com/auth/cloudplatformprojects.readonly
La app de ejemplo solo necesita acceso de solo lectura a la política allow-policy. No modifica la política ni necesita acceso a todo el proyecto. Eso significa que la app no necesita ninguno de los tres primeros permisos necesarios. El último es todo lo que se requiere, y eso es lo que implementaremos para la app de ejemplo.
El cuerpo principal de la función crea un conjunto vacío de usuarios administradores (admins
), recupera el allow_policy
a través de get_iam_policy()
y recorre todas sus vinculaciones en busca de roles de administrador de App Engine específicamente:
roles/viewer
roles/editor
roles/owner
roles/appengine.appAdmin
Por cada rol objetivo encontrado, se recopilan los usuarios que pertenecen a ese rol y se los agrega al conjunto general de usuarios administradores. Termina mostrando todos los usuarios administradores encontrados y almacenados en caché como una constante (_ADMINS
) durante la vida útil de esta instancia de App Engine. En breve, veremos esa llamada.
Agrega la siguiente definición de función _get_gae_admins()
a main.py
justo debajo para crear una instancia del cliente de la API de Cloud NDB (ds_client
):
def _get_gae_admins():
'return set of App Engine admins'
# setup constants for calling Cloud Resource Manager API
_, PROJ_ID = default( # Application Default Credentials and project ID
['https://www.googleapis.com/auth/cloudplatformprojects.readonly'])
rm_client = resourcemanager.ProjectsClient()
_TARGETS = frozenset(( # App Engine admin roles
'roles/viewer',
'roles/editor',
'roles/owner',
'roles/appengine.appAdmin',
))
# collate users who are members of at least one GAE admin role (_TARGETS)
admins = set() # set of all App Engine admins
allow_policy = rm_client.get_iam_policy(resource='projects/%s' % PROJ_ID)
for b in allow_policy.bindings: # bindings in IAM allow-policy
if b.role in _TARGETS: # only look at GAE admin roles
admins.update(user.split(':', 1).pop() for user in b.members)
return admins
Cuando los usuarios acceden a la app, ocurre lo siguiente:
- Se realiza una verificación rápida a partir de la plantilla web después de que un usuario accede a Firebase.
- Cuando cambia el estado de autenticación en la plantilla, se realiza una llamada
fetch()
de estilo Ajax a/is_admin
cuyo controlador es la siguiente función,is_admin()
. - El token de ID de Firebase se pasa en el cuerpo de POST a
is_admin()
, que lo quita de los encabezados y llama al SDK de Firebase Admin para validarlo. Si es un usuario válido, extrae su dirección de correo electrónico y verifica si es un usuario administrador. - El resultado booleano se devuelve a la plantilla como un número 200 correcto.
Agrega is_admin()
a main.py
justo después de _get_gae_admins()
:
@app.route('/is_admin', methods=['POST'])
def is_admin():
'check if user (via their Firebase ID token) is GAE admin (POST) handler'
id_token = request.headers.get('Authorization')
email = auth.verify_id_token(id_token).get('email')
return {'admin': email in _ADMINS}, 200
Todo el código de ambas funciones es necesario para replicar la funcionalidad disponible en el servicio de usuarios, específicamente su función is_current_user_admin()
. Esta llamada a función del módulo 20 se encargó de todo el trabajo pesado, a diferencia del módulo 21, en el que implementamos una solución de reemplazo. La buena noticia es que la app ya no depende de un servicio exclusivo de App Engine, lo que significa que puedes mover tus apps a Cloud Run o a otros servicios. Además, puedes cambiar la definición de “usuario administrador” para tus propias apps con solo cambiar a los roles deseados en _TARGETS
, mientras que el servicio de usuarios está codificado para los roles de administrador de App Engine.
Inicializa Firebase Auth y almacena en caché los usuarios administradores de App Engine.
Podríamos haber inicializado Firebase Auth en la parte superior, cerca del mismo punto en el que se inicializa la app de Flask y se crea el cliente de la API de Cloud NDB, pero no fue necesario hacerlo hasta que se definió todo el código de administrador, que es donde estamos ahora. De manera similar, ahora que se definió _get_gae_admins()
, llámalo para almacenar en caché la lista de usuarios administradores.
Agrega estas líneas justo debajo del cuerpo de la función de is_admin()
:
# initialize Firebase and fetch set of App Engine admins
initialize_app()
_ADMINS = _get_gae_admins()
Visitar las actualizaciones de modelos de datos
El modelo de datos de Visit
no cambia. El acceso a Datastore requiere el uso explícito de ds_client.context()
, el administrador de contexto del cliente de la API de Cloud NDB. En el código, esto significa que unes las llamadas de Datastore en store_visit()
y fetch_visits()
dentro de los bloques with
de Python. Esta actualización es idéntica al Módulo 2. Realiza los cambios de la siguiente manera:
ANTES:
class Visit(ndb.Model):
'Visit entity registers visitor IP address & timestamp'
visitor = ndb.StringProperty()
timestamp = ndb.DateTimeProperty(auto_now_add=True)
def store_visit(remote_addr, user_agent):
'create new Visit entity in Datastore'
Visit(visitor='{}: {}'.format(remote_addr, user_agent)).put()
def fetch_visits(limit):
'get most recent visits'
return Visit.query().order(-Visit.timestamp).fetch(limit)
DESPUÉS:
class Visit(ndb.Model):
'Visit entity registers visitor IP address & timestamp'
visitor = ndb.StringProperty()
timestamp = ndb.DateTimeProperty(auto_now_add=True)
def store_visit(remote_addr, user_agent):
'create new Visit entity in Datastore'
with ds_client.context():
Visit(visitor='{}: {}'.format(remote_addr, user_agent)).put()
def fetch_visits(limit):
'get most recent visits'
with ds_client.context():
return Visit.query().order(-Visit.timestamp).fetch(limit)
Mueve la lógica de acceso del usuario a la plantilla web
El servicio de usuarios de App Engine funciona del servidor, mientras que Firebase Auth y Cloud Identity Platform son principalmente del cliente. Como resultado, gran parte del código de administración de usuarios de la app del Módulo 20 se traslada a la plantilla web del Módulo 21.
En main.py
, el contexto web pasa cinco datos esenciales a la plantilla. Los primeros cuatro están vinculados a la administración de usuarios y difieren en función de si el usuario accedió o no:
who
: Es el correo electrónico del usuario si accedió a su cuenta o es el usuario de otra manera.admin
: Es la insignia (administrador) si el usuario que accedió es un administrador.sign
: Mostrar el botón Acceder o Salirlink
: Vínculos de acceso o salida cuando se hace clic en un botónvisits
: visitas más recientes
ANTES:
@app.route('/')
def root():
'main application (GET) handler'
store_visit(request.remote_addr, request.user_agent)
visits = fetch_visits(10)
# put together users context for web template
user = users.get_current_user()
context = { # logged in
'who': user.nickname(),
'admin': '(admin)' if users.is_current_user_admin() else '',
'sign': 'Logout',
'link': '/_ah/logout?continue=%s://%s/' % (
request.environ['wsgi.url_scheme'],
request.environ['HTTP_HOST'],
), # alternative to users.create_logout_url()
} if user else { # not logged in
'who': 'user',
'admin': '',
'sign': 'Login',
'link': users.create_login_url('/'),
}
# add visits to context and render template
context['visits'] = visits # display whether logged in or not
return render_template('index.html', **context)
Toda la administración de usuarios se trasladará a la plantilla web, por lo que solo quedan las visitas para que el controlador principal vuelva a lo que teníamos en la app del Módulo 1:
DESPUÉS:
@app.route('/')
def root():
'main application (GET) handler'
store_visit(request.remote_addr, request.user_agent)
visits = fetch_visits(10)
return render_template('index.html', visits=visits)
Actualizar plantilla web
¿Cómo se ven todas las actualizaciones de la sección anterior en la plantilla? Principalmente, se traslada la administración de usuarios de la app a Firebase Auth que se ejecuta en la plantilla y una portabilidad parcial de todo el código que trasladamos a JavaScript. main.py
se redujo bastante, por lo que se espera un crecimiento similar en templates/index.html
.
ANTES:
<!doctype html>
<html>
<head>
<title>VisitMe Example</title>
</head>
<body>
<p>
Welcome, {{ who }} <code>{{ admin }}</code>
<button id="logbtn">{{ sign }}</button>
</p><hr>
<h1>VisitMe example</h1>
<h3>Last 10 visits</h3>
<ul>
{% for visit in visits %}
<li>{{ visit.timestamp.ctime() }} from {{ visit.visitor }}</li>
{% endfor %}
</ul>
<script>
document.getElementById("logbtn").onclick = () => {
window.location.href = '{{ link }}';
};
</script>
</body>
</html>
Reemplaza toda la plantilla web con el siguiente contenido:
DESPUÉS:
<!doctype html>
<html>
<head>
<title>VisitMe Example</title>
<script type="module">
// import Firebase module attributes
import {
initializeApp
} from "https://www.gstatic.com/firebasejs/9.10.0/firebase-app.js";
import {
GoogleAuthProvider,
getAuth,
onAuthStateChanged,
signInWithPopup,
signOut
} from "https://www.gstatic.com/firebasejs/9.10.0/firebase-auth.js";
// Firebase config:
// 1a. Go to: console.cloud.google.com/customer-identity/providers
// 1b. May be prompted to enable GCIP and upgrade from Firebase
// 2. Click: "Application Setup Details" button
// 3. Copy: 'apiKey' and 'authDomain' from 'config' variable
var firebaseConfig = {
apiKey: "YOUR_API_KEY",
authDomain: "YOUR_AUTH_DOMAIN",
};
// initialize Firebase app & auth components
initializeApp(firebaseConfig);
var auth = getAuth();
var provider = new GoogleAuthProvider();
//provider.setCustomParameters({prompt: 'select_account'});
// define login and logout button functions
function login() {
signInWithPopup(auth, provider);
};
function logout() {
signOut(auth);
};
// check if admin & switch to logout button on login; reset everything on logout
onAuthStateChanged(auth, async (user) => {
if (user && user != null) {
var email = user.email;
who.innerHTML = email;
logbtn.onclick = logout;
logbtn.innerHTML = "Logout";
var idToken = await user.getIdToken();
var rsp = await fetch("/is_admin", {
method: "POST",
headers: {Authorization: idToken}
});
var data = await rsp.json();
if (data.admin) {
admin.style.display = "inline";
}
} else {
who.innerHTML = "user";
admin.style.display = "none";
logbtn.onclick = login;
logbtn.innerHTML = "Login";
}
});
</script>
</head>
<body>
<p>
Welcome, <span id="who"></span> <span id="admin"><code>(admin)</code></span>
<button id="logbtn"></button>
</p><hr>
<h1>VisitMe example</h1>
<h3>Last 10 visits</h3>
<ul>
{% for visit in visits %}
<li>{{ visit.timestamp.ctime() }} from {{ visit.visitor }}</li>
{% endfor %}
</ul>
<script>
var who = document.getElementById("who");
var admin = document.getElementById("admin");
var logbtn = document.getElementById("logbtn");
</script>
</body>
</html>
Hay muchos componentes en este cuerpo HTML, así que vamos a analizarlos una parte a la vez.
Importaciones de Firebase
Mientras se encuentra en el encabezado del documento HTML, una vez que pase el título de la página, importa los componentes de Firebase necesarios. Los componentes de Firebase ahora están divididos en varios módulos para mayor eficiencia. El código para inicializar Firebase se importa desde el módulo principal de la app de Firebase, mientras que las funciones que administran la autenticación de Firebase, Google como proveedor de autenticación, el acceso y la salida, y el estado de autenticación cambian la “devolución de llamada”. se importan desde el módulo de Firebase Auth:
<!doctype html>
<html>
<head>
<title>VisitMe Example</title>
<script type="module">
// import Firebase module attributes
import {
initializeApp
} from "https://www.gstatic.com/firebasejs/9.10.0/firebase-app.js";
import {
GoogleAuthProvider,
getAuth,
onAuthStateChanged,
signInWithPopup,
signOut
} from "https://www.gstatic.com/firebasejs/9.10.0/firebase-auth.js";
Configuración de Firebase
Antes, durante la parte de configuración de Identity Platform de este instructivo, guardaste apiKey
y authDomain
del diálogo Detalles de configuración de la aplicación. Agrega esos valores a la variable firebaseConfig
en la siguiente sección. Puedes encontrar un vínculo con instrucciones más detalladas en los comentarios:
// Firebase config:
// 1a. Go to: console.cloud.google.com/customer-identity/providers
// 1b. May be prompted to enable GCIP and upgrade from Firebase
// 2. Click: "Application Setup Details" button
// 3. Copy: 'apiKey' and 'authDomain' from 'config' variable
var firebaseConfig = {
apiKey: "YOUR_API_KEY",
authDomain: "YOUR_AUTH_DOMAIN",
};
Inicialización de Firebase
En la siguiente sección, se inicializa Firebase con esta información de configuración.
// initialize Firebase app & auth components
initializeApp(firebaseConfig);
var auth = getAuth();
var provider = new GoogleAuthProvider();
//provider.setCustomParameters({prompt: 'select_account'});
Esto establece la capacidad de usar Google como proveedor de autenticación y proporciona una opción marcada para mostrar el selector de cuentas, incluso si solo hay una Cuenta de Google registrada en la sesión del navegador. En otras palabras, si tienes varias cuentas, verás este "selector de cuentas". como se esperaba: Sin embargo, si solo hay un usuario en la sesión, el proceso de acceso se completa automáticamente sin ninguna interacción del usuario. (Aparecerá la ventana emergente y luego desaparecerá). Puedes hacer que el diálogo del selector de cuentas se muestre para un usuario (en lugar de acceder de inmediato a la aplicación). Para ello, quita el comentario de la línea del parámetro personalizado. Si está habilitada, incluso los accesos de un solo usuario muestran el selector de cuentas:
Funciones de acceso y salida
Las siguientes líneas de código conforman las funciones para los clics en los botones de acceso o cierre de sesión:
// define login and logout button functions
function login() {
signInWithPopup(auth, provider);
};
function logout() {
signOut(auth);
};
Acciones de acceso y salida
La última sección importante de este bloque <script>
es la función a la que se llama para cada cambio de Auth (acceder o salir).
// check if admin & switch to logout button on login; reset everything on logout
onAuthStateChanged(auth, async (user) => {
if (user && user != null) {
var email = user.email;
who.innerHTML = email;
logbtn.onclick = logout;
logbtn.innerHTML = "Logout";
var idToken = await user.getIdToken();
var rsp = await fetch("/is_admin", {
method: "POST",
headers: {Authorization: idToken}
});
var data = await rsp.json();
if (data.admin) {
admin.style.display = "inline";
}
} else {
who.innerHTML = "user";
admin.style.display = "none";
logbtn.onclick = login;
logbtn.innerHTML = "Login";
}
});
</script>
</head>
El código del módulo 20 que determina si se debe enviar a un usuario que accedió el contexto de la plantilla en comparación con “el usuario salió” del contexto se traslada aquí. El condicional de la parte superior genera true
si el usuario accedió correctamente, lo que activa las siguientes acciones:
- Se configuró la dirección de correo electrónico del usuario para su visualización.
- El botón Acceder cambia a Salir.
- Se realiza una llamada de estilo Ajax a
/is_admin
para determinar si se muestra la insignia de usuario administrador de(admin)
.
Cuando el usuario sale de su cuenta, se ejecuta la cláusula else
para restablecer toda la información del usuario:
- Nombre de usuario configurado como user
- Se quitó cualquier insignia de administrador
- El botón Salir cambió de nuevo a Acceder
Variables de plantilla
Una vez finalizada la sección del encabezado, el cuerpo principal comienza con las variables de la plantilla que se reemplazan por elementos HTML que cambian según sea necesario:
- Nombre de usuario visible
- Insignia de administrador de
(admin)
(si corresponde) - Botón Acceder o Salir
<body>
<p>
Welcome, <span id="who"></span> <span id="admin"><code>(admin)</code></span>
<button id="logbtn"></button>
</p><hr>
Visitas más recientes y variables de elementos HTML
El código de visitas más recientes no cambia, y el bloque <script>
final establece las variables de los elementos HTML que cambian para acceder y salir de la lista anterior:
<h1>VisitMe example</h1>
<h3>Last 10 visits</h3>
<ul>
{% for visit in visits %}
<li>{{ visit.timestamp.ctime() }} from {{ visit.visitor }}</li>
{% endfor %}
</ul>
<script>
var who = document.getElementById("who");
var admin = document.getElementById("admin");
var logbtn = document.getElementById("logbtn");
</script>
</body>
</html>
Con esto concluye los cambios necesarios en la aplicación y la plantilla web para cambiar de App Engine NDB y las APIs de usuarios a Cloud NDB e Identity Platform, así como para actualizar a Python 3. Felicitaciones por llegar a tu nueva app de ejemplo del Módulo 21. Nuestra versión está disponible para su revisión en la carpeta del repositorio del módulo 21b.
La siguiente parte del codelab es opcional (*) y solo para usuarios cuyas apps deben permanecer en Python 2, y te guiará a través de los pasos necesarios para llegar a una app de Python 2 Módulo 21 que funcione.
6. *Portabilidad a versiones anteriores de Python 2
Esta sección opcional está destinada a desarrolladores que realizan una migración de Identity Platform, pero que deben continuar ejecutándose en el entorno de ejecución de Python 2. Si esto no es un problema para ti, omite esta sección.
Para crear una versión de Python 2 funcional de la app del Módulo 21, necesitas lo siguiente:
- Requisitos del entorno de ejecución: Archivos de configuración compatibles con Python 2 y cambios necesarios en la aplicación principal para evitar incompatibilidades con Python 3
- Cambio menor en la biblioteca: Python 2 dejó de estar disponible antes de que se agregaran algunas funciones necesarias a la biblioteca cliente de Resource Manager. Como resultado, necesitas una forma alternativa de acceder a esa funcionalidad faltante.
Comencemos con la configuración.
Restablecer appengine_config.py
Anteriormente en este instructivo, se te indicó que borraras appengine_config.py
, ya que no lo usa el entorno de ejecución de App Engine de Python 3. En el caso de Python 2, no solo se debe preservar, sino que también se debe actualizar el appengine_config.py
del módulo 20 para que admita el uso de bibliotecas de terceros integradas, es decir, grpcio
y setuptools
. Esos paquetes son necesarios cada vez que tu aplicación de App Engine usa bibliotecas cliente de Cloud, como las de Cloud NDB y Cloud Resource Manager.
Agregarás esos paquetes a app.yaml
por un momento, pero para que tu app acceda a ellos, se debe llamar a la función pkg_resources.working_set.add_entry()
de setuptools
. Esto permite que las bibliotecas de terceros copiadas (agrupadas automáticamente o de proveedores) instaladas en la carpeta lib
puedan comunicarse con las bibliotecas integradas.
Implementa las siguientes actualizaciones en tu archivo appengine_config.py
para aplicar estos cambios:
ANTES:
from google.appengine.ext import vendor
# Set PATH to your libraries folder.
PATH = 'lib'
# Add libraries installed in the PATH folder.
vendor.add(PATH)
Este código por sí solo no es suficiente para admitir el uso de setuptools
y grpcio
. Necesitan algunas líneas más, así que actualiza appengine_config.py
para que se vea de la siguiente manera:
DESPUÉS:
import pkg_resources
from google.appengine.ext import vendor
# Set PATH to your libraries folder.
PATH = 'lib'
# Add libraries installed in the PATH folder.
vendor.add(PATH)
# Add libraries to pkg_resources working set to find the distribution.
pkg_resources.working_set.add_entry(PATH)
Puedes encontrar más detalles sobre los cambios necesarios para admitir las bibliotecas cliente de Cloud en la documentación sobre migración de servicios en paquetes.
app.yaml
Al igual que appengine_config.py
, el archivo app.yaml
debe revertirse a uno compatible con Python 2. Comencemos con el módulo 20 app.yaml
original:
ANTES:
runtime: python27
threadsafe: yes
api_version: 1
handlers:
- url: /.*
script: main.app
Además de setuptools
y grpcio
, como se mencionó anteriormente, hay una dependencia (no relacionada de forma explícita con la migración de Identity Platform) que requiere el uso de la biblioteca cliente de Cloud Storage y que necesita otro paquete integrado de terceros, ssl
. Agrégalos en una nueva sección libraries
y selecciona la opción “más reciente”. versiones disponibles de esos paquetes a app.yaml
:
DESPUÉS:
runtime: python27
threadsafe: yes
api_version: 1
handlers:
- url: /.*
script: main.app
libraries:
- name: grpcio
version: latest
- name: setuptools
version: latest
- name: ssl
version: latest
requirements.txt
En el módulo 21, agregamos Google Auth, Cloud NDB, Cloud Resource Manager y el SDK de Firebase Admin al requirements.txt
de Python 3. La situación de Python 2 es más compleja:
- La API de Resource Manager proporciona la funcionalidad de política de permisos necesaria para la app de ejemplo. Lamentablemente, esta compatibilidad aún no estaba disponible en la versión final de Python 2 de la biblioteca cliente de Cloud Resource Manager. (solo está disponible en la versión de Python 3).
- Como resultado, se requiere una forma alternativa de acceder a esta función desde la API. La solución es utilizar la biblioteca cliente de las APIs de Google de nivel inferior para comunicarse con la API. Para cambiar a esta biblioteca cliente, reemplaza
google-cloud-resource-manager
con el paquetegoogle-api-python-client
de nivel inferior. - Debido a que Python 2 dejó de estar disponible, el gráfico de dependencias que admite el Módulo 21 requiere que ciertos paquetes se bloqueen en versiones específicas. Algunos paquetes deben llamarse incluso si no se especifican en el
app.yaml
de Python 3.
ANTES:
flask
A partir del requirements.txt
del Módulo 20, actualízalo a lo siguiente para una app del Módulo 21 que funcione:
DESPUÉS:
grpcio==1.0.0
protobuf<3.18.0
six>=1.13.0
flask
google-gax<0.13.0
google-api-core==1.31.1
google-api-python-client<=1.11.0
google-auth<2.0dev
google-cloud-datastore==1.15.3
google-cloud-firestore==1.9.0
google-cloud-ndb
google-cloud-pubsub==1.7.0
firebase-admin
Los números de paquete y versión se actualizarán en el repositorio a medida que cambien las dependencias, pero este app.yaml
es suficiente para una app en funcionamiento en el momento en que se redactó este documento.
Otras actualizaciones de configuración
Si no borraste la carpeta lib
de antes en este codelab, hazlo ahora. Con el requirements.txt
recientemente actualizado, ejecuta este comando conocido para instalar los siguientes requisitos en lib
:
pip install -t lib -r requirements.txt # or pip2
Si tienes Python 2 y 3 instalados en tu sistema de desarrollo, es posible que debas usar pip2
en lugar de pip
.
Modifica el código de la aplicación
Afortunadamente, la mayoría de los cambios necesarios están en los archivos de configuración. El único cambio necesario en el código de la aplicación es una actualización menor para usar la biblioteca cliente de la API de Google de nivel inferior en lugar de la biblioteca cliente de Resource Manager para acceder a la API. No hay actualizaciones necesarias para la plantilla web templates/index.html
.
Actualiza las importaciones y la inicialización
Reemplaza la biblioteca cliente de Resource Manager (google.cloud.resourcemanager
) por la biblioteca cliente de las APIs de Google (googleapiclient.discovery
), como se ilustra a continuación:
ANTES:
from flask import Flask, render_template, request
from google.auth import default
from google.cloud import ndb, resourcemanager
from firebase_admin import auth, initialize_app
DESPUÉS:
from flask import Flask, render_template, request
from google.auth import default
from google.cloud import ndb
from googleapiclient import discovery
from firebase_admin import auth, initialize_app
Asistencia para usuarios administradores de App Engine
Se necesitan algunos cambios en _get_gae_admins()
para admitir el uso de la biblioteca cliente de nivel inferior. Primero, analicemos qué cambiará y, luego, te daremos todo el código para actualizar.
El código de Python 2 requiere el uso de las credenciales y del ID del proyecto que muestra google.auth.default()
. Las credenciales no se usan en Python 3, por lo que se asignó a una variable ficticia genérica ( _
). Como es necesario para la versión de Python 2, cambia el guion bajo a CREDS
. Además, en lugar de crear un cliente de la API de Resource Manager, crearás un extremo de servicio de API, un concepto similar al de un cliente de API, por lo que mantendremos el mismo nombre de variable (rm_client
). Una diferencia es que para crear una instancia de extremo de servicio se requieren credenciales (CREDS
).
Estos cambios se reflejan en el siguiente código:
ANTES:
_, PROJ_ID = default( # Application Default Credentials and project ID
['https://www.googleapis.com/auth/cloudplatformprojects.readonly'])
rm_client = resourcemanager.ProjectsClient()
DESPUÉS:
CREDS, PROJ_ID = default( # Application Default Credentials and project ID
['https://www.googleapis.com/auth/cloud-platform'])
rm_client = discovery.build('cloudresourcemanager', 'v1', credentials=CREDS)
La otra diferencia es que la biblioteca cliente de Resource Manager muestra objetos allow-policy que usan notación de atributos con puntos, mientras que la biblioteca cliente de nivel inferior muestra diccionarios de Python en los que se usan corchetes ( [ ]
). Por ejemplo, usa binding.role
para la biblioteca cliente de Resource Manager frente a binding['role']
para la biblioteca de nivel inferior. El primero también usa “separado por guion bajo” en comparación con la biblioteca de nivel inferior que prefiere "CamelCased" más una forma ligeramente diferente de pasar parámetros de API.
Estas diferencias de uso se muestran a continuación:
ANTES:
allow_policy = rm_client.get_iam_policy(resource='projects/%s' % PROJ_ID)
for b in allow_policy.bindings: # bindings in IAM allow-policy
if b.role in _TARGETS: # only look at GAE admin roles
admins.update(user.split(':', 1).pop() for user in b.members)
DESPUÉS:
allow_policy = rm_client.projects().getIamPolicy(resource=PROJ_ID).execute()
for b in allow_policy['bindings']: # bindings in IAM allow-policy
if b['role'] in _TARGETS: # only look at GAE admin roles
admins.update(user.split(':', 1).pop() for user in b['members'])
Después de unir todos estos cambios, reemplaza el _get_gae_admins()
de Python 3 por esta versión equivalente de Python 2:
def _get_gae_admins():
'return set of App Engine admins'
# setup constants for calling Cloud Resource Manager API
CREDS, PROJ_ID = default( # Application Default Credentials and project ID
['https://www.googleapis.com/auth/cloud-platform'])
rm_client = discovery.build('cloudresourcemanager', 'v1', credentials=CREDS)
_TARGETS = frozenset(( # App Engine admin roles
'roles/viewer',
'roles/editor',
'roles/owner',
'roles/appengine.appAdmin',
))
# collate users who are members of at least one GAE admin role (_TARGETS)
admins = set() # set of all App Engine admins
allow_policy = rm_client.projects().getIamPolicy(resource=PROJ_ID).execute()
for b in allow_policy['bindings']: # bindings in IAM allow-policy
if b['role'] in _TARGETS: # only look at GAE admin roles
admins.update(user.split(':', 1).pop() for user in b['members'])
return admins
La función is_admin()
no requiere ninguna actualización porque se basa en _get_gae_admins()
, que ya se actualizó.
Con esto concluye los cambios necesarios para aplicar portabilidad a versiones anteriores de la app del módulo 21 de Python 3 a Python 2. Felicitaciones por llegar a la app de ejemplo actualizada del Módulo 21. Encontrarás todo el código en la carpeta del repositorio del módulo 21a.
7. Resumen/limpieza
Los últimos pasos del codelab son garantizar que las principales (usuarios o cuentas de servicio) que ejecuten esta app tengan los permisos adecuados para hacerlo. Luego, implementa la app para confirmar que funcione según lo previsto y que los cambios se reflejen en el resultado.
Capacidad de leer políticas de permisos de IAM
Anteriormente, te presentamos las cuatro funciones necesarias para que te reconozcan como usuario administrador de App Engine, pero ahora hay una quinta con la que debes familiarizarte:
roles/viewer
roles/editor
roles/owner
roles/appengine.appAdmin
roles/resourcemanager.projectIamAdmin
(para las principales que acceden a la política de permisos de IAM)
El rol roles/resourcemanager.projectIamAdmin
permite a las principales determinar si un usuario final es miembro de alguno de los roles de administrador de App Engine. Sin la membresía en roles/resourcemanager.projectIamAdmin
, fallarán las llamadas a la API de Cloud Resource Manager para obtener la política de permiso.
No es necesario que realices ninguna acción explícita aquí, ya que la app se ejecutará con la cuenta de servicio predeterminada de App Engine, a la que se le otorga automáticamente la membresía en este rol. Incluso si usas la cuenta de servicio predeterminada durante la fase de desarrollo, te recomendamos que crees y uses una cuenta de servicio administrada por el usuario con los permisos mínimos necesarios para que la app funcione correctamente. Para otorgar membresía a una cuenta de servicio de este tipo, ejecuta el siguiente comando:
$ gcloud projects add-iam-policy-binding PROJ_ID --member="serviceAccount:USR_MGD_SVC_ACCT@PROJ_ID.iam.gserviceaccount.com" --role=roles/resourcemanager.projectIamAdmin
PROJ_ID
es el ID del proyecto de Cloud y USR_MGD_SVC_ACCT@PROJ_ID.iam.gserviceaccount.com
es la cuenta de servicio administrada por el usuario que creas para tu app. Este comando genera la política de IAM actualizada para tu proyecto, en la que puedes confirmar que la cuenta de servicio tiene membresía de roles/resourcemanager.projectIamAdmin
. Para obtener más información, consulta la documentación de referencia. Para repetir, no es necesario que emitas ese comando en este codelab, pero guárdalo como referencia para modernizar tus propias apps.
Implementa y verifica la aplicación
Sube la app a la nube con el comando gcloud app deploy
estándar. Una vez implementado, deberías ver una funcionalidad casi idéntica a la de la app del Módulo 20, con la excepción de que reemplazaste correctamente el servicio Usuarios de App Engine con Cloud Identity Platform (y Firebase Auth) para la administración de usuarios:
Una diferencia que notarás en comparación con el Módulo 20 es que, si haces clic en el panel de acceso, se mostrará una ventana emergente en lugar de un redireccionamiento, como se muestra en algunas de las siguientes capturas de pantalla. Sin embargo, al igual que el módulo 20, el comportamiento difiere un poco según la cantidad de Cuentas de Google que se hayan registrado en el navegador.
Si no hay usuarios registrados en el navegador o solo un usuario que no haya accedido aún, aparecerá una ventana emergente genérica de Acceso con Google:
Si un solo usuario está registrado en tu navegador, pero accede desde otro lugar, no aparecerá ningún diálogo (o aparecerá y se cerrará de inmediato), y la aplicación entra en un estado de acceso (muestra el correo electrónico del usuario y el botón Salir).
Es posible que algunos desarrolladores deseen proporcionar un selector de cuentas, incluso para un solo usuario:
Para implementar esto, quita el comentario de la línea provider.setCustomParameters({prompt: 'select_account'});
en la plantilla web como se describió anteriormente.
Si hay varios usuarios, aparecerá el diálogo del selector de cuentas (consulta a continuación). Si aún no accedió, se le preguntará al usuario. Si ya accediste, la ventana emergente desaparece y la app entra en un estado de acceso.
El estado de acceso del Módulo 21 es idéntico al de la interfaz de usuario del Módulo 20:
Lo mismo sucede cuando accede un usuario administrador:
A diferencia del módulo 21, el módulo 20 siempre accede a la lógica para el contenido de la plantilla web desde la app (código del servidor). Una falla del Módulo 20 es que se registra una visita cuando el usuario final accede a la app por primera vez y otra se registra cuando el usuario accede.
Para el módulo 21, la lógica de acceso se lleva a cabo solo en la plantilla web (código del cliente). No es necesario realizar un viaje del servidor para determinar qué contenido mostrar. La única llamada que se hace al servidor es la verificación de los usuarios administradores después de que accede un usuario final. Esto significa que los accesos y las salidas no registran visitas adicionales, de modo que la lista de visitas más recientes se mantiene igual para las acciones de administración de usuarios. Observa que las capturas de pantalla anteriores muestran el mismo conjunto de cuatro visitas a través de múltiples accesos de usuario.
Las capturas de pantalla del módulo 20 demuestran el “error de visita doble” al comienzo de este codelab. Se muestran registros de visitas separados para cada acción de acceso o salida. Revisa las marcas de tiempo de la visita más reciente en cada captura de pantalla que muestren el orden cronológico.
Limpia
General
Si ya terminaste, te recomendamos que inhabilites la aplicación de App Engine para evitar que se te facture. Sin embargo, si deseas probar o experimentar un poco más, la plataforma de App Engine tiene una cuota gratuita y, siempre y cuando no superes ese nivel de uso, no se te debería cobrar. Eso es para procesamiento, pero es posible que también se apliquen cargos por servicios relevantes de App Engine, así que consulta la página de precios para obtener más información. Si esta migración implica otros servicios de Cloud, estos se facturan por separado. En ambos casos, si corresponde, consulta la sección "Específico de este codelab" a continuación.
Para una divulgación completa, la implementación en una plataforma de procesamiento sin servidores de Google Cloud, como App Engine, genera costos menores de compilación y almacenamiento. Cloud Build tiene su propia cuota gratuita, al igual que Cloud Storage. El almacenamiento de esa imagen ocupa parte de esa cuota. Sin embargo, es posible que vivas en una región que no cuenta con ese nivel gratuito, así que ten en cuenta el uso que haces del almacenamiento para minimizar posibles costos. “Carpetas” específicas de Cloud Storage que debes revisar incluyen
console.cloud.google.com/storage/browser/LOC.artifacts.PROJECT_ID.appspot.com/containers/images
console.cloud.google.com/storage/browser/staging.PROJECT_ID.appspot.com
- Los vínculos de almacenamiento anteriores dependen de tu
PROJECT_ID
y tuLOC
; por ejemplo, "us
" si tu app está alojada en EE.UU.
Por otro lado, si no vas a continuar con esta aplicación o algún otro codelab de migración relacionado y quieres borrar todo por completo, cierra tu proyecto.
Información específica de este codelab
Los servicios que se indican a continuación son exclusivos de este codelab. Consulta la documentación de cada producto para obtener más información:
- El servicio de App Engine Datastore lo proporciona Cloud Datastore (Cloud Firestore en modo Datastore), que también tiene un nivel gratuito. consulta su página de precios para obtener más información.
- El uso de Cloud Identity Platform tiene algún nivel de según el servicio que uses. Consulta su página de precios para obtener más detalles.
- El uso de la API de Cloud Resource Manager es gratuito en su mayor parte según su página de precios.
Próximos pasos
Más allá de este instructivo, otros módulos de migración que se enfocan en alejarse de los servicios en paquetes heredados que se deben considerar incluyen los siguientes:
- Módulo 2: migrar de
ndb
de App Engine a Cloud NDB - Módulos del 7 al 9: Migra de la lista de tareas en cola de App Engine (tareas push) a Cloud Tasks
- Módulos del 12 al 13: Migra de Memcache de App Engine a Cloud Memorystore
- Módulos del 15 al 16: Migra de Blobstore de App Engine a Cloud Storage
- Módulos del 18 al 19: Migra de la lista de tareas en cola de App Engine (tareas de extracción) a Cloud Pub/Sub.
App Engine ya no es la única plataforma sin servidores en Google Cloud. Si tienes una aplicación pequeña de App Engine o una con funcionalidad limitada y deseas convertirla en un microservicio independiente, o si deseas dividir una aplicación monolítica en varios componentes reutilizables, estas son buenas razones para considerar cambiar a Cloud Functions. Si la creación de contenedores se volvió parte del flujo de trabajo de desarrollo de tu aplicación, en especial si consta de una canalización de CI/CD (integración continua/entrega o implementación continuas), considera migrar a Cloud Run. Estas situaciones se abordan en los siguientes módulos:
- Migra de App Engine a Cloud Functions: consulta el Módulo 11.
- Migra de App Engine a Cloud Run. Consulta el Módulo 4 para alojar tu app en contenedores con Docker, o el Módulo 5 para hacerlo sin contenedores, conocimiento sobre Docker ni
Dockerfile
.
Cambiar a otra plataforma sin servidores es opcional, y te recomendamos que consideres las mejores opciones para tus apps y casos de uso antes de realizar cualquier cambio.
Independientemente del módulo de migración que consideres a continuación, puedes acceder a todo el contenido de Serverless Migration Station (codelabs, videos, código fuente [si está disponible]) a través de su repositorio de código abierto. El README
del repositorio también proporciona orientación sobre qué migraciones considerar y cualquier "orden" relevante. de los módulos de migración.
8. Recursos adicionales
A continuación, se incluyen recursos adicionales para los desarrolladores que exploran este módulo o los módulos de migración relacionados en mayor detalle. A continuación, puedes proporcionar comentarios sobre este contenido, encontrar vínculos al código y varios documentos que te pueden resultar útiles.
Problemas o comentarios sobre Codelabs
Si encuentras algún problema con este Codelab, primero busca el problema antes de enviarlo. Vínculos para buscar y crear problemas nuevos:
Recursos de migración
En la siguiente tabla, encontrarás los vínculos a las carpetas de repo del Módulo 20 (COMENZAR) y Módulo 21 (FINALIZAR).
Codelab | Python 2 | Python 3 |
(n/a) | ||
Módulo 21 (este codelab) |
Referencias en línea
A continuación, hay recursos relevantes para este instructivo:
Cloud Identity Platform y Cloud Marketplace
- Página de producto de Identity Platform
- Firebase Authentication
- Página de comparación de productos de Identity Platform y Firebase Auth
- Información de precios de Identity Platform
- Cuotas de Identity Platform (y uso sin instrumentos)
- Configuración de proveedores de Identity Platform
- Página de producto de Cloud Marketplace
- Página de Identity Platform en Marketplace
Cloud Resource Manager, Cloud IAM y SDK de Firebase Admin
- Página de producto de Resource Manager
- Información de precios de Resource Manager
- Biblioteca cliente de Resource Manager
- Descripción general de Cloud IAM (roles, allow-policy, etcétera)
- SDK de Firebase Admin (Python)
Usuarios de App Engine, App Engine NDB, Cloud NDB y Cloud Datastore
- Descripción general de los usuarios de App Engine
- Documentación de App Engine NDB
- Repositorio de App Engine NDB
- Biblioteca cliente de Cloud NDB
- Repositorio de Cloud NDB
- Página de producto de Cloud Datastore
- Información de precios de Cloud Datastore
Otras referencias del módulo de migración
- Introducción al módulo de migración
- Toda la "Estación de migración sin servidores" recursos
- Migra a la documentación de Python 3
- Módulo de migración 17, “Usa servicios en paquetes en entornos de ejecución de 2a gen.” codelab
- Módulo de migración 20: “Agrega un servicio de usuarios de App Engine a las apps de Flask” codelab
Migración de App Engine
- Usa bibliotecas de terceros en apps de Python 2
- Cambios a
app.yaml
en entornos de ejecución de 2a gen. (Python 3) - Guía de migración de Cloud NDB
- Contenido de la migración de Cloud NDB
Plataforma de App Engine
- Documentación de App Engine
- Entorno de ejecución de App Engine (entorno estándar) para Python 2
- Usa las bibliotecas integradas de App Engine en Python 2 de App Engine
- Entorno de ejecución de App Engine (entorno estándar) para Python 3
- Diferencias entre Python 2 y 3 entornos de ejecución de App Engine (entorno estándar)
- Guía de migración de Python 2 a 3 de App Engine (entorno estándar)
- Información de precios y cuotas de App Engine
- Lanzamiento de la plataforma de App Engine de segunda generación (2018)
- Comparación primero y plataformas de segunda generación
- Asistencia a largo plazo para entornos de ejecución heredados
- Ejemplos de migración de documentación
- Ejemplos de migración aportados por la comunidad
SDK de Cloud
- SDK de Google Cloud
- Herramienta de línea de comandos de
gcloud
del SDK de Cloud - Habilita (e inhabilita) las APIs de Google
- Administrador de APIs de la consola de Cloud (habilita o inhabilita APIs)
- Habilita las APIs de Google con
gcloud
- Enumera las APIs de Google con
gcloud
Otra información de Cloud
- Python en Google Cloud
- Documentación de las bibliotecas cliente de Python
- Repositorios de bibliotecas cliente de Python
- "Siempre gratuito" nivel
- SDK de Cloud
- Herramienta de línea de comandos de
gcloud
del SDK de Cloud - Toda la documentación de Google Cloud
Videos
- Estación de migración sin servidores
- Expediciones sin servidores
- Suscríbete a Google Cloud Tech
- Suscríbete a Google Developers.
Licencia
Este trabajo cuenta con una licencia Atribución 2.0 Genérica de Creative Commons.