1. Visão geral
A série de codelabs da estação de migração sem servidor (tutoriais práticos e individualizados) e os vídeos relacionados têm como objetivo ajudar desenvolvedores sem servidor do Google Cloud a modernizar apps, orientando-os em uma ou mais migrações, principalmente para evitar serviços legados. Isso torna seus apps mais portáteis e oferece mais opções e flexibilidade, o que permite a integração e o acesso a uma variedade maior de produtos do Cloud e o upgrade para versões de idiomas mais recentes com mais facilidade. Embora inicialmente voltada para os primeiros usuários do Cloud, principalmente desenvolvedores do App Engine (ambiente padrão), esta série é ampla o suficiente para incluir outras plataformas sem servidor, como o Cloud Functions e o Cloud Run, ou outros lugares, se aplicável.
O objetivo deste codelab é mostrar aos desenvolvedores de Python 2 do App Engine como migrar da API/serviço de usuários do App Engine para o Cloud Identity Platform (GCIP). Há também uma migração implícita do App Engine MapReduce para o Cloud NBS no acesso ao Datastore (abordada principalmente no Módulo de migração 2), bem como um upgrade para o Python 3.
O módulo 20 mostra como adicionar o uso da API Users ao app de exemplo do Módulo 1. Neste módulo, você vai migrar o app do Módulo 20 para o Cloud Identity Platform.
Você vai aprender a
- Substitua o serviço Usuários do App Engine pelo Cloud Identity Platform.
- Substitua o uso do App Engine NDK pelo Cloud NBS (consulte também o módulo 2).
- Configurar diferentes provedores de identidade de autenticação usando o Firebase Auth
- Usar a API Cloud Resource Manager para receber informações do IAM do projeto
- Usar o SDK Admin do Firebase para receber informações do usuário
- Transferir o aplicativo de amostra para o Python 3
O que é necessário
- Um projeto do Google Cloud Platform com uma conta de faturamento ativa do GCP.
- Habilidades básicas em Python
- Conhecimento prático de comandos comuns do Linux
- Conhecimento básico sobre desenvolvimento e implantação de apps no App Engine
- Um app de exemplo do App Engine do Módulo 20 funcional
Pesquisa
Como você usará este tutorial?
Como você classificaria sua experiência com Python?
Como você classificaria sua experiência de uso dos serviços do Google Cloud?
2. Contexto
O serviço Usuários do App Engine é um sistema de autenticação de usuários para uso por aplicativos do App Engine. Ele fornece o Login do Google como provedor de identidade, fornece links convenientes de login e logout para uso em apps e é compatível com o conceito de usuários administradores e a funcionalidade somente para administradores. Para melhorar a portabilidade de aplicativos, o Google Cloud recomenda migrar de serviços agrupados do App Engine legados para serviços independentes do Cloud, por exemplo, do serviço Usuários para o Cloud Identity Platform, entre outros.
O Identity Platform é baseado no Firebase Authentication e adiciona vários recursos empresariais, incluindo autenticação multifator, OIDC e Compatibilidade com SSO SAML, multilocação, SLA de 99, 95% e mais. Essas diferenças também estão destacadas na página de comparação dos produtos Identity Platform e Firebase Authentication. Ambos os produtos têm significativamente mais recursos do que a funcionalidade fornecida pelo serviço Usuários.
Este codelab do Módulo 21 demonstra como mudar a autenticação do usuário do app do serviço Usuários para os recursos do Identity Platform que refletem melhor a funcionalidade demonstrada no Módulo 20. O módulo 21 também apresenta uma migração do App Engine Node para o Cloud Firestore para acesso ao Datastore, repetindo a migração do Módulo 2.
Enquanto o código do Módulo 20 é "anunciado" como um app de exemplo em Python 2, a origem é compatível com Python 2 e 3 e permanece assim mesmo após a migração para o Identity Platform (e o Cloud NBS) no módulo 21. É possível continuar usando o serviço Usuários durante o upgrade para o Python 3, já que a migração para o Identity Platform é opcional. Consulte o codelab do módulo 17 e o vídeo para saber como continuar usando os serviços em pacote ao fazer upgrade para ambientes de execução de 2a geração, como o Python 3.
Este tutorial apresenta as seguintes etapas:
- Configuração/Pré-trabalho
- Atualizar a configuração
- Modificar o código do aplicativo
3. Configuração/Pré-trabalho
Esta seção explica como:
- Configurar seu projeto do Cloud
- Receber app de amostra do valor de referência
- (Re)implantar e validar o app de referência
- Ativar novos serviços/APIs do Google Cloud
Estas etapas garantem que você esteja começando com um código de trabalho pronto para a migração para serviços independentes do Cloud.
1. Configurar projeto
Se você concluiu o codelab do Módulo 20, reutilize o mesmo projeto e código. Outra opção é criar um novo projeto ou reutilizar um projeto existente. Verifique se o projeto tem uma conta de faturamento ativa e um aplicativo do App Engine ativado. Encontre o ID do projeto e tenha-o à mão durante este codelab. Use-o sempre que encontrar a variável PROJ_ID
.
2. Receber app de amostra do valor de referência
Um dos pré-requisitos é um app funcional do Módulo 20 do App Engine. Portanto, conclua o codelab (recomendado, link acima) ou copie o código do módulo 20 do repositório. Não importa se você usa o seu ou o nosso, é aqui que vamos começar ("INICIAR"). Este codelab orienta você durante a migração e conclui com um código semelhante ao da pasta de repositórios do Módulo 21 ("FINISH").
- INÍCIO: pasta do módulo 20 (Python 2)
- FINISH: pastas do módulo 21 ( Python 2 ou Python 3)
- Repositório inteiro (para clonar ou fazer o download do arquivo ZIP)
Copie a pasta do repositório do módulo 20. Ele será parecido com o resultado abaixo e poderá ter uma pasta lib
se você tiver feito o codelab do Módulo 20:
$ ls README.md appengine_config.py templates app.yaml main.py requirements.txt
3. (Re)implantar e validar o app de referência
Execute as etapas abaixo para implantar o app Module 20:
- Exclua a pasta
lib
, se houver uma, e executepip install -t lib -r requirements.txt
para preenchê-la novamente. Pode ser necessário usarpip2
se você tiver o Python 2 e o 3 instalados. - Verifique se você instalou e inicializou a ferramenta de linha de comando
gcloud
e analisou o uso dela. - Se você não quiser inserir o
PROJ_ID
com cada comandogcloud
emitido, defina o projeto do Cloud comgcloud config set project
PROJ_ID
primeiro. - Implante o app de exemplo com
gcloud app deploy
- Confirme se o app é executado como esperado sem erros. Se você concluiu o codelab do Módulo 20, o app vai mostrar informações de login do usuário (e-mail do usuário, possível "selo de administrador" e botão de login/logout) na parte de cima com as visitas mais recentes (ilustradas abaixo).
O login como usuário normal faz com que o endereço de e-mail do usuário seja exibido e o botão "Login" muda para "Logout" botão:
O login como usuário administrador faz com que o endereço de e-mail do usuário seja exibido com "(admin)". ao lado dele:
4. Ativar novos serviços/APIs do Google Cloud
Introdução
O app do Módulo 20 usa as APIs do App Engine e do Node.js, que são pacotes de serviços que não exigem configuração adicional, mas os serviços independentes do Cloud exigem. O aplicativo atualizado empregará o Cloud Identity Platform e o Cloud Datastore (por meio da biblioteca de cliente do Cloud NBS). Além disso, nossa necessidade de determinar os usuários administradores do App Engine também exige o uso da API Cloud Resource Manager.
Custo
- O App Engine e o Cloud Datastore têm a opção "Sempre sem custo financeiro" nível. Assim, enquanto você permanecer abaixo desses limites, não haverá cobranças ao concluir este tutorial. Consulte também as páginas de preços do App Engine e do Cloud Datastore.
- O uso do Cloud Identity Platform é faturado de acordo com o número de usuários ativos por mês (MAUs) ou as verificações de autenticação. alguma versão de "sem custo financeiro" está disponível para cada modelo de uso. Confira mais detalhes na página de preços. Além disso, embora o App Engine e o Cloud Datastore exijam faturamento, o uso do GCIP por si só não exige a ativação do faturamento, desde que você não exceda as cotas diárias sem instrumento. Portanto, considere isso para projetos do Cloud que não envolvem APIs/serviços do Cloud que exigem faturamento.
- O uso da API Cloud Resource Manager é sem custo financeiro, na maioria das vezes, de acordo com a página de preços.
Os usuários ativam as APIs do Cloud no console do Cloud ou na linha de comando (com o comando gcloud
, parte do SDK do Cloud), dependendo da preferência. Vamos começar com as APIs Cloud Datastore e Cloud Resource Manager.
No Console do Cloud
Acesse a página da biblioteca do gerenciador de APIs (para o projeto correto) no console do Cloud e procure uma API usando a barra de pesquisa.
Ative estas APIs:
Encontre e clique no botão Ativar para cada API separadamente. Talvez você precise fornecer informações de faturamento. Por exemplo, esta é a página da API Resource Manager:
O botão muda para "Gerenciar" quando é ativado (geralmente após alguns segundos):
Ative o Cloud Datastore da mesma maneira:
Na linha de comando,
Embora seja visualmente informativo ativar APIs no console, alguns preferem a linha de comando. Você ainda tem o bônus de ativar quantas APIs quiser ao mesmo tempo. Emita este comando para ativar as APIs do Cloud Datastore e do Cloud Resource Manager e aguardar a conclusão da operação, conforme ilustrado aqui:
$ gcloud services enable cloudresourcemanager.googleapis.com datastore.googleapis.com Operation "operations/acat.p2-aaa-bbb-ccc-ddd-eee-ffffff" finished successfully.
Talvez você precise fornecer informações de faturamento.
Os "URLs" para cada API usada no comando acima são chamados de nomes de serviço da API e podem ser encontrados na parte inferior da página da biblioteca de cada API. Se você quiser ativar outras APIs do Cloud para seus próprios aplicativos, encontre os respectivos nomes de serviço nas páginas das APIs correspondentes. Este comando lista todos os nomes de serviço das APIs que podem ser ativadas:
gcloud services list
--available --filter="name:googleapis.com"
.
Seja no console do Cloud ou na linha de comando, depois de concluir as etapas acima, nosso exemplo poderá acessar essas APIs. As próximas etapas são ativar o Cloud Identity Platform e fazer as mudanças necessárias no código.
Ativar e configurar o Cloud Identity Platform (somente no console do Cloud)
O Cloud Identity Platform é um serviço do Marketplace porque se conecta ou depende de um recurso fora do Google Cloud, como o Firebase Authentication. No momento, só é possível ativar os serviços do Marketplace no console do Cloud. Siga as etapas abaixo:
- Acesse a página do Cloud Identity Platform no Cloud Marketplace e clique no botão Ativar. Faça upgrade do Firebase Authentication, se solicitado. Isso desbloqueia recursos adicionais, como aqueles descritos anteriormente na seção Segundo plano. Esta é a página do Marketplace destacando o botão Ativar:
- Depois que o Identity Platform for ativado, a página Identity Providers poderá ser aberta automaticamente. Caso contrário, acesse este link.
- Ative o provedor do Google Auth. Se nenhum provedor tiver sido configurado, clique em Adicionar um provedor e selecione Google. Quando você voltar a esta tela, a entrada Google deverá estar ativada. O Google é o único provedor de autenticação que estamos usando neste tutorial para espelhar o serviço Usuários do App Engine como um serviço leve de Login do Google. Nos seus próprios apps, ative provedores de autenticação adicionais.
- Depois de selecionar e configurar o Google e outros provedores de autenticação desejados, clique em Detalhes da configuração do aplicativo e, na janela de diálogo de garantia, copie
apiKey
eauthDomain
no objetoconfig
na guia "Web", salvando ambos em um lugar seguro. Por que não copiar tudo? O snippet nesta caixa de diálogo está fixado no código e é datado, então salve os trechos mais importantes e use no nosso código com mais uso simultâneo do Firebase Auth. Depois de copiar os valores e salvá-los em um lugar seguro, clique no botão Fechar, concluindo toda a configuração necessária.
4. Atualizar a configuração
As atualizações na configuração incluem a alteração de vários arquivos de configuração, bem como a criação do equivalente do App Engine, mas no ecossistema do Cloud Identity Platform.
appengine_config.py
- Se estiver fazendo upgrade para o Python 3, exclua
appengine_config.py
- Se você planeja modernizar para o Identity Platform, mas continua no Python 2, não exclua o arquivo. Em vez disso, vamos atualizá-lo mais tarde durante o backport do Python 2.
requirements.txt
O arquivo requirements.txt
do módulo 20 lista apenas o Flask. No módulo 21, adicione os pacotes abaixo:
O conteúdo de requirements.txt
agora ficará assim:
flask
google-auth
google-cloud-ndb
google-cloud-resource-manager
firebase-admin
app.yaml
- Fazer upgrade para o Python 3 significa simplificar o arquivo
app.yaml
. Remova tudo, exceto a diretiva de tempo de execução, e defina-o como uma versão atualmente compatível do Python 3. O exemplo usa atualmente a versão 3.10. - Se você estiver usando o Python 2, não faça nada ainda.
ANTES:
runtime: python27
threadsafe: yes
api_version: 1
handlers:
- url: /.*
script: main.app
O app de exemplo do módulo 20 não tem gerenciadores de arquivos estáticos. Se seus apps tiverem, deixe-os intactos. Você pode remover todos os gerenciadores de script se quiser ou apenas deixá-los lá para referência, desde que mude os identificadores para auto
, conforme descrito no guia de migração do app.yaml
. Com essas mudanças, o app.yaml
atualizado para Python 3 foi simplificado para:
DEPOIS:
runtime: python310
Outras atualizações de configuração
Seja permanecendo no Python 2 ou fazendo a portabilidade para o Python 3, se você tiver uma pasta lib
, exclua-a.
5. Modificar o código do aplicativo
Esta seção apresenta atualizações para o arquivo principal do aplicativo, main.py
, que substitui o serviço Usuários do App Engine pelo Cloud Identity Platform. Depois de atualizar o aplicativo principal, você atualizará o modelo da Web, templates/index.html
.
Atualizar importações e inicialização
Siga as etapas abaixo para atualizar as importações e inicializar os recursos do aplicativo:
- Para as importações, substitua o App Engine NBS pelo Cloud NBS.
- Além disso, importe o Cloud Resource Manager com o Cloud NBS.
- O Identity Platform é baseado no Firebase Auth. Portanto, importe o SDK Admin do Firebase.
- As APIs do Cloud exigem o uso de um cliente de API. Portanto, inicie-as para o Cloud NBS logo abaixo de inicializar o Flask.
Embora o pacote do Cloud Resource Manager seja importado aqui, será usado em uma etapa posterior na inicialização do aplicativo. Confira abaixo as importações e a inicialização do módulo 20, seguidas de como as seções vão ficar após a implementação das mudanças acima:
ANTES:
from flask import Flask, render_template, request
from google.appengine.api import users
from google.appengine.ext import ndb
app = Flask(__name__)
DEPOIS:
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()
Suporte para usuários administradores do App Engine
Há dois componentes que podem ser adicionados ao app para o reconhecimento de usuários administradores:
_get_gae_admins()
: reúne um conjunto de usuários administradores. chamado uma vez e salvois_admin()
: verifica se o usuário que fez login é um administrador; chamado em qualquer login de usuário
A função utilitária, _get_gae_admins()
, chama a API Resource Manager para buscar a allow-policy atual do Cloud IAM. A política de permissão define e aplica quais papéis são concedidos a quais principais (usuários humanos, contas de serviço etc.). A configuração inclui:
- Buscando o ID do projeto do Cloud (
PROJ_ID
) - Criando um cliente da API Resource Manager (
rm_client
) - Criando um conjunto (somente leitura) de papéis de administrador do App Engine (
_TARGETS
)
O Resource Manager exige o ID do projeto do Cloud. Portanto, importe google.auth.default()
e chame essa função para conseguir o ID do projeto. Essa chamada apresenta um parâmetro que se parece com um URL, mas é um escopo de permissão OAuth2. Ao executar apps na nuvem, por exemplo, em uma VM do Compute Engine ou um app do App Engine, é fornecida uma conta de serviço padrão com amplos privilégios. Para seguir a prática recomendada de privilégio mínimo, crie suas próprias contas de serviço gerenciadas pelo usuário.
Para chamadas de API, é melhor reduzir ainda mais o escopo dos apps para um nível mínimo necessário para funcionar corretamente. A chamada da API Resource Manager que vamos fazer é get_iam_policy()
, que precisa de um dos seguintes escopos 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
O app de exemplo só precisa de acesso somente leitura à política allow-policy. Ela não modifica a política nem precisa de acesso ao projeto inteiro. Isso significa que o app não precisa das três primeiras permissões necessárias. A última opção é só a necessária, que é o que estamos implementando para o app de exemplo.
O corpo principal da função cria um conjunto vazio de usuários administradores (admins
), busca o allow_policy
via get_iam_policy()
e percorre todas as vinculações dele procurando especificamente por papéis de administrador do App Engine:
roles/viewer
roles/editor
roles/owner
roles/appengine.appAdmin
Para cada função de destino encontrada, ele lista os usuários que pertencem a ela, adicionando-os ao conjunto geral de usuários administradores. Ele termina com o retorno de todos os usuários administradores encontrados e armazenados em cache como uma constante (_ADMINS
) durante a vida útil da instância do App Engine. Vamos receber uma ligação em breve.
Adicione a seguinte definição da função _get_gae_admins()
a main.py
logo abaixo para instanciar o cliente da API Cloud NBS (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
Quando os usuários fazem login no app, ocorre o seguinte:
- Uma verificação rápida é feita a partir do modelo da Web depois que um usuário faz login no Firebase.
- Quando o estado de autenticação muda no modelo, uma chamada
fetch()
no estilo Ajax é feita para/is_admin
, cujo gerenciador é a próxima função,is_admin()
. - O token de ID do Firebase é transmitido no corpo do POST para
is_admin()
, que o remove dos cabeçalhos e chama o SDK Admin do Firebase para validá-lo. Se o usuário for válido, extraia o endereço de e-mail dele e verifique se é um usuário administrador. - O resultado booleano é retornado ao modelo como 200 bem-sucedido.
Adicione is_admin()
a main.py
logo após _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 o código das duas funções é necessário para replicar a funcionalidade disponível no serviço Usuários, especificamente a função is_current_user_admin()
. Essa chamada de função no módulo 20 fez todo o trabalho pesado, ao contrário do módulo 21, em que implementamos uma solução substituta. A boa notícia é que o app não depende mais de um serviço exclusivo do App Engine, o que significa que você pode movê-los para o Cloud Run ou outros serviços. Além disso, também é possível alterar a definição de "usuário administrador" para seus próprios aplicativos apenas alternando para as funções desejadas em _TARGETS
, enquanto o serviço Usuários está fixado no código para as funções de administrador do App Engine.
Inicializar o Firebase Auth e armazenar em cache os usuários administradores do App Engine
Poderíamos inicializar o Firebase Auth no topo, perto do mesmo local em que o app Flask foi inicializado e o cliente da API Cloud NBS foi criado, mas não foi necessário fazer isso até que todo o código de administrador tivesse sido definido, que é onde estamos agora. Da mesma forma, agora que _get_gae_admins()
está definido, chame-o para armazenar em cache a lista de usuários administradores.
Adicione estas linhas logo abaixo do corpo da função de is_admin()
:
# initialize Firebase and fetch set of App Engine admins
initialize_app()
_ADMINS = _get_gae_admins()
Atualizações do modelo de dados da visita
O modelo de dados Visit
não muda. O acesso ao Datastore requer o uso explícito do gerenciador de contexto do cliente da API Cloud NBS, ds_client.context()
. No código, isso significa que você envolve as chamadas do Datastore em store_visit()
e fetch_visits()
dentro de blocos with
do Python. Essa atualização é idêntica ao Módulo 2. Faça as alterações da seguinte forma:
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)
DEPOIS:
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)
Mover a lógica de login do usuário para o modelo da Web
O serviço Usuários do App Engine é executado no servidor, enquanto o Firebase Auth e o Cloud Identity Platform são predominantemente no lado do cliente. Como resultado, grande parte do código de gerenciamento de usuários do app Módulo 20 é movido para o modelo da Web do Módulo 21.
No main.py
, o contexto da Web transmite cinco dados essenciais para o modelo. Os quatro primeiros listados estão vinculados ao gerenciamento de usuários e diferem dependendo se o usuário fez login ou não:
who
: o e-mail do usuário se tiver feito login ou user, caso contrárioadmin
: selo (administrador) se o usuário que fez login for um administradorsign
: mostrar o botão Login ou Sairlink
: links de login ou login ao clicar no botãovisits
: visitas mais recentes
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)
Todo o gerenciamento de usuários será movido para o modelo da Web, então restam apenas as visitas, trazendo o gerenciador principal de volta ao que tínhamos no aplicativo Módulo 1:
DEPOIS:
@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)
Atualizar modelo da Web
Como estão todas as atualizações da seção anterior no modelo? Principalmente mover o gerenciamento de usuários do app para o Firebase Auth em execução no modelo e uma porta parcial de todo o código que movemos para JavaScript. Notamos que o main.py
diminuiu um pouco, então espere um crescimento semelhante em 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>
Substitua todo o modelo da Web pelo conteúdo abaixo:
DEPOIS:
<!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>
Há muitos componentes nesse corpo HTML, então vamos analisar uma parte de cada vez.
Importações do Firebase
Ainda no cabeçalho do documento HTML, depois do título da página, importe os componentes do Firebase necessários. Os componentes do Firebase agora estão divididos em vários módulos para aumentar a eficiência. O código para inicializar o Firebase é importado do módulo principal do app do Firebase, enquanto as funções que gerenciam o Firebase Auth, o Google como provedor de autenticação, o login e a saída e o estado de autenticação alteram o "callback" são todos importados do módulo do 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";
Configuração do Firebase
Durante a configuração do Identity Platform deste tutorial, você salvou apiKey
e authDomain
na caixa de diálogo Detalhes da configuração do aplicativo. Adicione esses valores à variável firebaseConfig
na próxima seção. Você encontra um link nos comentários com mais instruções:
// 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",
};
Inicialização do Firebase
A próxima seção inicializa o Firebase com essas informações de configuração.
// initialize Firebase app & auth components
initializeApp(firebaseConfig);
var auth = getAuth();
var provider = new GoogleAuthProvider();
//provider.setCustomParameters({prompt: 'select_account'});
Isso configura a capacidade de usar o Google como um provedor de autenticação e fornece uma opção comentada para mostrar o seletor de contas mesmo se houver apenas uma Conta do Google registrada na sessão do navegador. Em outras palavras, quando você tem várias contas, esse "seletor de contas" é exibido conforme esperado: No entanto, se houver apenas um usuário na sessão, o processo de login será concluído automaticamente sem nenhuma interação do usuário. O pop-up aparece e depois desaparece. Para forçar a caixa de diálogo do seletor de conta a aparecer para um usuário (em vez de fazer login imediatamente no app), remova a marca de comentário da linha do parâmetro personalizado. Se ativado, até mesmo logins de usuário único exibem o seletor de conta:
Funções de login e logout
As próximas linhas de código compõem as funções para os cliques nos botões de login ou logout:
// define login and logout button functions
function login() {
signInWithPopup(auth, provider);
};
function logout() {
signOut(auth);
};
Ações de login e logout
A última seção principal neste bloco <script>
é a função chamada para cada mudança de autenticação (login ou logout).
// 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>
O código no Módulo 20 determina se é necessário enviar um "usuário conectado" contexto do modelo x "usuário desconectado" o contexto será transferido aqui. A condicional na parte superior resulta em true
se o usuário tiver feito login, acionando as seguintes ações:
- O endereço de e-mail do usuário está definido para exibição.
- O botão Fazer login mudará para Sair.
- Uma chamada no estilo Ajax para
/is_admin
é feita para determinar se o selo de usuário administrador(admin)
será mostrado.
Quando o usuário sai, a cláusula else
é executada para redefinir todas as informações do usuário:
- Nome de usuário definido como user
- Todos os selos de administrador foram removidos
- O botão Sair voltou a ser Login
Variáveis de modelo
Após o término da seção do cabeçalho, o corpo principal começa com as variáveis de modelo que são substituídas por elementos HTML que mudam conforme necessário:
- Nome de usuário exibido
- Selo de administrador do
(admin)
(se aplicável) - Botão Fazer login ou Sair
<body>
<p>
Welcome, <span id="who"></span> <span id="admin"><code>(admin)</code></span>
<button id="logbtn"></button>
</p><hr>
Visitas mais recentes e variáveis de elementos HTML
O código de visitas mais recente não muda, e o bloco <script>
final define as variáveis para os elementos HTML que mudam para login e logout listados acima:
<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>
Isso conclui as mudanças necessárias no aplicativo e no modelo da Web para alternar entre as APIs do App Engine e do Node.js e das APIs de usuários para o Cloud NBS e o Identity Platform, além do upgrade para o Python 3. Parabéns por chegar ao novo app de exemplo do Módulo 21. Nossa versão está disponível para revisão na pasta de repositório do módulo 21b.
A próxima parte do codelab é opcional (*) e apenas para usuários com apps que precisam permanecer no Python 2, levando você às etapas necessárias para chegar a um app Python 2 Módulo 21 funcional.
6. *Backport Python 2
Esta seção opcional é destinada a desenvolvedores que realizam uma migração do Identity Platform, mas precisam continuar a execução no ambiente de execução do Python 2. Se isso não for seu caso, pule esta seção.
Para criar uma versão Python 2 funcional do app Módulo 21, você precisa do seguinte:
- Requisitos de tempo de execução: arquivos de configuração com suporte ao Python 2 e mudanças necessárias no aplicativo principal para evitar incompatibilidades do Python 3
- Pequena mudança na biblioteca:o Python 2 foi descontinuado antes da adição de alguns recursos obrigatórios à biblioteca de cliente do Resource Manager. Como resultado, você precisa de uma maneira alternativa de acessar essa funcionalidade ausente.
Vamos seguir essas etapas agora, começando pela configuração.
Restaurar appengine_config.py
Anteriormente neste tutorial, você foi orientado a excluir appengine_config.py
, porque ele não é usado pelo ambiente de execução do App Engine para Python 3. No Python 2, ele não só precisa ser preservado, mas o appengine_config.py
do Módulo 20 precisa ser atualizado para oferecer suporte ao uso de bibliotecas integradas de terceiros, ou seja, grpcio
e setuptools
. Esses pacotes são necessários sempre que o aplicativo do App Engine usa bibliotecas de cliente do Cloud, como as do Cloud NBS e do Cloud Resource Manager.
Você vai adicionar esses pacotes a app.yaml
em breve. No entanto, para que o app tenha acesso a eles, a função pkg_resources.working_set.add_entry()
de setuptools
precisa ser chamada. Isso permite que bibliotecas de terceiros copiadas (autoagrupadas ou fornecidas) instaladas na pasta lib
possam se comunicar com bibliotecas integradas.
Implemente as seguintes atualizações no arquivo appengine_config.py
para aplicar essas mudanças:
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)
Esse código por si só não é suficiente para oferecer suporte ao uso de setuptools
e grpcio
. São necessárias mais algumas linhas, então atualize appengine_config.py
para que fique assim:
DEPOIS:
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)
Mais detalhes sobre as mudanças necessárias para oferecer suporte às bibliotecas de cliente do Cloud podem ser encontrados na documentação sobre a migração de serviços em pacote.
app.yaml
Semelhante a appengine_config.py
, o arquivo app.yaml
precisa ser revertido para um que seja compatível com o Python 2. Vamos começar com o app.yaml
do Módulo 20 original:
ANTES:
runtime: python27
threadsafe: yes
api_version: 1
handlers:
- url: /.*
script: main.app
Além de setuptools
e grpcio
, como mencionado anteriormente, há uma dependência (não explicitamente relacionada à migração do Identity Platform) que exige o uso da biblioteca de cliente do Cloud Storage e que precisa de outro pacote integrado de terceiros, ssl
. Adicione os três em uma nova seção de libraries
, selecionando a opção "Mais recente". disponíveis desses pacotes para app.yaml
:
DEPOIS:
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
No Módulo 21, adicionamos o Google Auth, o Cloud Firestore, o Cloud Resource Manager e o SDK Admin do Firebase ao requirements.txt
do Python 3. A situação do Python 2 é mais complexa:
- A API Resource Manager fornece a funcionalidade allow-policy necessária para o app de exemplo. Infelizmente, esse suporte ainda não estava disponível na versão final do Python 2 da biblioteca de cliente do Cloud Resource Manager. Disponível apenas na versão do Python 3.
- Como resultado, é necessária uma maneira alternativa de acessar esse recurso pela API. A solução é usar a biblioteca de cliente de APIs do Google de nível inferior para se comunicar com a API. Para alternar para essa biblioteca de cliente, substitua
google-cloud-resource-manager
pelo pacotegoogle-api-python-client
de nível inferior. - Como o Python 2 foi desativado, o gráfico de dependência compatível com o Módulo 21 exige o bloqueio de determinados pacotes em versões específicas. Alguns pacotes precisam ser chamados mesmo que não sejam especificados no
app.yaml
do Python 3.
ANTES:
flask
A partir do requirements.txt
do Módulo 20, atualize para o seguinte em um app do Módulo 21 que funcione:
DEPOIS:
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
Os números do pacote e da versão serão atualizados no repositório conforme as dependências mudarem, mas esse app.yaml
é suficiente para um app em funcionamento no momento da criação deste codelab.
Outras atualizações de configuração
Se você não excluiu a pasta lib
anteriormente neste codelab, faça isso agora. Com o requirements.txt
recém-atualizado, emita este comando conhecido para instalar esses requisitos no lib
:
pip install -t lib -r requirements.txt # or pip2
Se você tiver o Python 2 e o 3 instalados no seu sistema de desenvolvimento, talvez seja necessário usar pip2
em vez de pip
.
Modificar o código do aplicativo
Felizmente, a maioria das mudanças necessárias estão nos arquivos de configuração. A única alteração necessária no código do aplicativo é uma pequena atualização para usar a biblioteca de cliente de nível inferior da API do Google em vez da biblioteca de cliente do Resource Manager para acessar a API. Não é necessário atualizar o modelo da Web templates/index.html
.
Atualizar importações e inicialização
Substitua a biblioteca de cliente do Resource Manager (google.cloud.resourcemanager
) pela biblioteca de cliente de APIs do Google (googleapiclient.discovery
), conforme ilustrado abaixo:
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
DEPOIS:
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
Suporte para usuários administradores do App Engine
Algumas mudanças são necessárias em _get_gae_admins()
para oferecer suporte ao uso da biblioteca de cliente de nível inferior. Primeiro, vamos discutir o que está mudando e depois fornecer todo o código que precisa ser atualizado.
O código Python 2 requer o uso das credenciais e do ID do projeto retornado de google.auth.default()
. As credenciais não são usadas no Python 3, por isso foram atribuídas a uma variável fictícia de sublinhado genérica ( _
). Como ele é necessário para a versão do Python 2, mude o sublinhado para CREDS
. Além disso, em vez de criar um cliente da API Resource Manager, você criará um endpoint de serviço da API, que é semelhante ao conceito de um cliente de API. Por isso, vamos manter o mesmo nome de variável (rm_client
). Uma diferença é que instanciar um endpoint de serviço requer credenciais (CREDS
).
Essas mudanças são refletidas no código abaixo:
ANTES:
_, PROJ_ID = default( # Application Default Credentials and project ID
['https://www.googleapis.com/auth/cloudplatformprojects.readonly'])
rm_client = resourcemanager.ProjectsClient()
DEPOIS:
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)
A outra diferença é que a biblioteca de cliente do Resource Manager retorna objetos allow-policy que usam a notação de atributo pontilhado, enquanto a biblioteca de cliente de nível inferior retorna dicionários Python em que os colchetes ( [ ]
) são usados. Por exemplo, use binding.role
para a biblioteca de cliente do Resource Manager e binding['role']
para a biblioteca de nível inferior. O primeiro também usa "underscore_level" em vez de uma biblioteca de nível inferior que preferem "CamelCased" além de uma maneira um pouco diferente de passar os parâmetros da API.
Essas diferenças de uso são mostradas abaixo:
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)
DEPOIS:
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'])
Juntando todas essas mudanças, substitua o _get_gae_admins()
do Python 3 por esta versão equivalente do 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
A função is_admin()
não precisa de atualizações porque depende de _get_gae_admins()
, que já foi atualizado.
Isso conclui as mudanças necessárias para fazer o backport do app Módulo 21 do Python 3 para o Python 2. Parabéns por chegar ao app de exemplo atualizado do Módulo 21. Você vai encontrar todo o código na pasta de repositório do módulo 21a.
7. Resumo/limpeza
As últimas etapas do codelab são para garantir que os principais (usuários ou contas de serviço) que executam o app tenham as permissões adequadas. Depois, implante o app para confirmar se ele funciona conforme o esperado e se as mudanças são refletidas na saída.
Capacidade de ler a política allow-policy do IAM
Anteriormente, apresentamos as quatro funções necessárias para ser reconhecido como um usuário administrador do App Engine, mas agora há uma quinta para se familiarizar:
roles/viewer
roles/editor
roles/owner
roles/appengine.appAdmin
roles/resourcemanager.projectIamAdmin
(para os principais que acessam a política de permissão do IAM)
O papel roles/resourcemanager.projectIamAdmin
permite que os principais determinem se um usuário final é membro de alguma função de administrador do App Engine. Sem a assinatura em roles/resourcemanager.projectIamAdmin
, as chamadas para a API Cloud Resource Manager para conseguir a allow-policy vão falhar.
Não é necessário realizar nenhuma ação explícita aqui, já que o aplicativo será executado na conta de serviço padrão do App Engine, que recebe automaticamente a associação a esse papel. Mesmo que você use a conta de serviço padrão durante a fase de desenvolvimento, recomendamos criar e usar uma conta de serviço gerenciada pelo usuário com as permissões mínimas necessárias para que seu app funcione corretamente. Para conceder associação a essa conta de serviço, execute o seguinte 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
é o ID do projeto do Cloud e USR_MGD_SVC_ACCT@PROJ_ID.iam.gserviceaccount.com
é a conta de serviço gerenciada pelo usuário que você cria para o app. Esse comando gera a política do IAM atualizada para seu projeto, em que é possível confirmar se a conta de serviço é associada a roles/resourcemanager.projectIamAdmin
. Para mais informações, consulte a documentação de referência. Repetindo: não é necessário emitir esse comando neste codelab, mas salve-o como referência para modernizar seus próprios apps.
Implante e verifique o aplicativo
Faça upload do seu app para a nuvem com o comando gcloud app deploy
padrão. Após a implantação, a funcionalidade será quase idêntica à do app do Módulo 20, mas você substituiu o serviço Usuários do App Engine pelo Cloud Identity Platform e pelo Firebase Auth para gerenciamento de usuários:
Uma diferença que você notará em comparação com o Módulo 20 é que clicar no login resulta em um pop-up em vez de um redirecionamento, capturado em algumas das capturas de tela abaixo. No entanto, assim como no Módulo 20, o comportamento difere um pouco dependendo de quantas Contas do Google foram registradas no navegador.
Se não houver usuários registrados no navegador ou um único usuário que ainda não tenha feito login, um pop-up genérico de Login do Google vai aparecer:
Se um único usuário estiver registrado no seu navegador, mas fizer login em outro lugar, nenhuma caixa de diálogo vai aparecer (ou ela aparecerá e fechará imediatamente), e o app entrará no estado conectado (mostrando o e-mail do usuário e o botão Sair).
Alguns desenvolvedores podem querer fornecer um seletor de conta, mesmo para um único usuário:
Para implementar isso, remova a marca de comentário da linha provider.setCustomParameters({prompt: 'select_account'});
no modelo da Web, conforme descrito anteriormente.
Se houver vários usuários, a caixa de diálogo do seletor de conta será exibida (veja abaixo). Se ainda não tiver feito login, o usuário receberá uma solicitação. Se você já tiver feito login, o pop-up vai desaparecer e o app vai entrar no estado conectado.
O estado de login do Módulo 21 é idêntico à interface do usuário do Módulo 20:
O mesmo acontece quando um usuário administrador faz login:
Ao contrário do Módulo 21, o Módulo 20 sempre acessa a lógica para o conteúdo do modelo da Web no app (código do lado do servidor). Uma falha do Módulo 20 é que uma visita é registrada quando o usuário final acessa o aplicativo pela primeira vez, e outra é registrada quando um usuário faz login.
No Módulo 21, a lógica de login ocorre apenas no modelo da Web (código do lado do cliente). Não há uma viagem do lado do servidor necessária para determinar o conteúdo a ser exibido. A única chamada feita para o servidor é a verificação de usuários administradores após o login de um usuário final. Isso significa que logins e logouts não registram visitas adicionais. Assim, a lista de visitas mais recentes permanece constante para ações de gerenciamento de usuários. Observe que as capturas de tela acima mostram o mesmo conjunto de quatro visitas em vários logins de usuário.
As capturas de tela do Módulo 20 demonstram o "bug de visita dupla". no início deste codelab. Registros de visitas separados são exibidos para cada ação de login ou logout. Verifique os carimbos de data/hora da visita mais recente para cada captura de tela mostrando a ordem cronológica.
Limpar
Geral
Se você já tiver terminado por enquanto, recomendamos que desative seu aplicativo do App Engine para evitar cobranças. No entanto, se você quiser fazer mais testes, saiba que a plataforma do App Engine tem uma cota sem custo financeiro e, desde que você não exceda esse nível de uso, não haverá cobranças. Isso é para computação, mas também pode haver cobranças por serviços relevantes do App Engine. Portanto, consulte a página de preços para mais informações. Se essa migração envolver outros serviços do Cloud, eles serão faturados separadamente. Em ambos os casos, se aplicável, consulte a seção "Específico para este codelab". seção abaixo.
Para divulgação completa, a implantação em uma plataforma de computação sem servidor do Google Cloud, como o App Engine, incorre em menores custos de criação e armazenamento. O Cloud Build tem a própria cota sem custo financeiro, assim como o Cloud Storage. O armazenamento da imagem consome parte da cota. No entanto, talvez você more em uma região que não tenha esse nível sem custo financeiro, portanto, esteja ciente do uso do armazenamento para minimizar os possíveis custos. "Pastas" específicas do Cloud Storage que você deve analisar incluem:
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
- Os links de armazenamento acima dependem do
PROJECT_ID
e daLOC
ação, por exemplo, "us
" caso seu app esteja hospedado nos EUA.
Por outro lado, se você não for continuar com este aplicativo ou outros codelabs de migração relacionados e quiser excluir tudo completamente, encerre seu projeto.
Específicos deste codelab
Os serviços listados abaixo são exclusivos deste codelab. Consulte a documentação de cada produto para mais informações:
- o serviço App Engine Datastore é fornecido pelo Cloud Datastore (Cloud Firestore no modo Datastore), que também tem um nível sem custo financeiro; consulte a página de preços para mais informações.
- O uso do Cloud Identity Platform tem um nível de "gratuidade", de acordo com os serviços que você usa. Confira mais detalhes na página de preços.
- O uso da API Cloud Resource Manager é sem custo financeiro, na maioria das vezes, de acordo com a página de preços.
Próximas etapas
Além deste tutorial, outros módulos de migração que se concentram em abandonar os serviços em pacote legados a considerar incluem:
- Módulo 2: migrar do App Engine
ndb
para o Cloud NBS - Módulos 7 a 9: migrar da fila de tarefas do App Engine (tarefas push) para o Cloud Tasks
- Módulos 12 a 13: migrar do Memcache do App Engine para o Cloud Memorystore
- Módulos 15 a 16: migrar do App Engine Blobstore para o Cloud Storage
- Módulos 18 a 19: migrar da fila de tarefas do App Engine (tarefas pull) para o Cloud Pub/Sub
O App Engine não é mais a única plataforma sem servidor do Google Cloud. Se você tem um aplicativo pequeno do App Engine ou com funcionalidade limitada e quer transformá-lo em um microsserviço independente ou quer dividir um aplicativo monolítico em vários componentes reutilizáveis, estes são bons motivos para migrar para o Cloud Functions. Se a conteinerização se tornou parte do fluxo de trabalho de desenvolvimento de aplicativos, principalmente se consistir em um pipeline de CI/CD (integração/entrega contínua ou implantação), considere migrar para o Cloud Run. Esses cenários são abordados nos seguintes módulos:
- Migrar do App Engine para o Cloud Functions: consulte o Módulo 11
- Migrar do App Engine para o Cloud Run: consulte o Módulo 4 para conteinerizar seu app com o Docker ou o Módulo 5 para fazer isso sem contêineres, conhecimento do Docker ou
Dockerfile
s
A mudança para outra plataforma sem servidor é opcional. Recomendamos considerar as melhores opções para seus apps e casos de uso antes de fazer qualquer mudança.
Seja qual for o módulo de migração que você considerar a seguir, todo o conteúdo da estação de migração sem servidor (codelabs, vídeos, código-fonte [quando disponível]) pode ser acessado no repositório de código aberto. O README
do repositório também fornece orientações sobre quais migrações considerar e qualquer "ordem" relevante. de módulos de migração.
8. Outros recursos
Abaixo estão listados recursos adicionais para desenvolvedores que querem explorar esse ou outros módulos de migração relacionados. Abaixo, você pode fornecer feedback sobre esse conteúdo, encontrar links para o código e vários documentos que podem ser úteis.
Problemas/feedback sobre codelabs
Se você encontrar problemas com este codelab, pesquise seu problema antes de preenchê-lo. Links para pesquisar e criar novos problemas:
Recursos de migração
Os links para as pastas do repositório do Módulo 20 (INÍCIO) e do Módulo 21 (FINISH) podem ser encontrados na tabela abaixo.
Codelab | Python 2 | Python 3 |
(n/a) | ||
Módulo 21 (este codelab) |
Referências on-line
Confira abaixo os recursos relevantes para este tutorial:
Cloud Identity Platform e Cloud Marketplace
- Página do produto do Identity Platform
- Firebase Authentication
- Página de comparação dos produtos Identity Platform e Firebase Auth
- Informações sobre os preços do Identity Platform
- Cotas do Identity Platform (e uso sem instrumentos)
- Configuração dos provedores do Identity Platform
- Página do produto do Cloud Marketplace
- Página do Identity Platform no Marketplace
Cloud Resource Manager, Cloud IAM, SDK Admin do Firebase
- Página do produto do Resource Manager
- Informações sobre preços do Resource Manager
- Biblioteca de cliente do Resource Manager
- Visão geral do Cloud IAM (papéis, allow-policy etc.)
- SDK Admin do Firebase (Python)
Usuários do App Engine, App Engine MapReduce, Cloud NFS e Cloud Datastore
- Visão geral de usuários do App Engine
- Documentos do App Engine MapReduce
- Repositório do App Engine do App Engine
- Biblioteca de cliente do Cloud NBS
- Repositório do Cloud NBS
- Página do produto do Cloud Datastore
- Informações sobre preços do Cloud Datastore
Outras referências do módulo de migração
- Introdução ao módulo de migração
- Todas as "Estações de migração sem servidor" recursos
- Documentação sobre como migrar para o Python 3
- Módulo de migração 17: "Como usar serviços agrupados em ambientes de execução de 2a geração" codelab
- Módulo de migração 20: "Adicionar o serviço de usuários do App Engine a aplicativos Flask" codelab
Migração do App Engine
- Como usar bibliotecas de terceiros em apps Python 2
- Mudanças no
app.yaml
em ambientes de execução de 2a geração (Python 3) - Guia de migração do Cloud NBS
- Conteúdo de migração do Cloud NFS
Plataforma do App Engine
- Documentação do App Engine
- Ambiente de execução do App Engine para Python 2 (ambiente padrão)
- Como usar as bibliotecas integradas do App Engine no App Engine para Python 2
- Ambiente de execução do App Engine para Python 3 (ambiente padrão)
- Diferenças entre o Python 2 e o Três ambientes de execução do App Engine (ambiente padrão)
- Guia de migração do App Engine (ambiente padrão) Python 2 para 3
- Informações de preços e cotas do App Engine
- Lançamento da plataforma App Engine de segunda geração (2018)
- Comparação entre a primeira e plataformas de segunda geração
- Suporte de longo prazo para ambientes de execução legados
- Amostras de migração de documentação (em inglês)
- Amostras de migração criadas com a colaboração da comunidade
SDK do Cloud
- SDK do Google Cloud
- Ferramenta de linha de comando
gcloud
do SDK Cloud - Como ativar (e desativar) APIs do Google
- Gerenciador de APIs do console do Cloud (ativar/desativar APIs)
- Como ativar as APIs do Google com o
gcloud
- Como listar APIs do Google com
gcloud
Outras informações sobre a nuvem
- Python no Google Cloud
- Documentação das bibliotecas de cliente do Python
- Repositórios de bibliotecas de cliente do Python
- "Sempre sem custo financeiro" nível
- SDK do Cloud
- Ferramenta de linha de comando
gcloud
do SDK Cloud - Toda a documentação do Google Cloud
Vídeos
- Estação de migração sem servidor
- Expedições sem servidor
- Inscreva-se no Google Cloud Tech
- Inscreva-se no Google Developers
Licença
Este conteúdo está sob a licença Atribuição 2.0 Genérica da Creative Commons.