Depois de algumas tentativas e erros, descobri que @google-cloud/storage
version 1.6.0
estava me dando esse comportamento. Eu fiz o downgrade para 1.5.2
e ele começou a funcionar.
Eu abri um problema no GitHub para isso: link
Estou usando o Google Cloud Functions com um gatilho de HTTP para criar um endpoint para uma chamada de API. Este endpoint está usando a função getSignedUrl
do pacote do Cloud Storage. Eu queria retornar uma URL assinada para que o cliente possa PUT
nessa URL para fazer o upload de um arquivo.
Estou recebendo um comportamento inconsistente com essa API. Às vezes recebo um URL da função. Então tentei atualizar o nome do intervalo e recebi este erro:
{ SigningError: Failure from metadata server.
at /user_code/node_modules/@google-cloud/storage/src/file.js:1715:16
at getCredentials (/user_code/node_modules/@google-cloud/storage/node_modules/google-auto-auth/index.js:264:9)
at googleAuthClient.getCredentials (/user_code/node_modules/@google-cloud/storage/node_modules/google-auto-auth/index.js:148:11)
at process._tickDomainCallback (internal/process/next_tick.js:135:7) message: 'Failure from metadata server.' }
Se eu alterar o nome do intervalo de volta, ainda vejo esse erro. Eu tentei coisas diferentes, como implantar a partir do terminal. Isso me deu o mesmo erro. Eu também criei a função com o navegador e isso começou a funcionar. Depois que eu tentei atualizar o nome do intervalo, ele parou de funcionar.
Ao pesquisar, acho que isso é um problema de permissão ou ACL, mas não tenho certeza de como confirmá-lo. A documentação diz que as funções são executadas usando <YOUR_PROJECT_ID>@appspot.gserviceaccount.com
service account, que posso confirmar na guia geral da função. Posso ver no IAM que essa conta de serviço tem o Service Account Token Creator
, que diz:
Impersonate service accounts (create OAuth2 access tokens, sign blobs or JWTs, etc).
A documentação para getSignedUrl
diz:
In those environments, we call the signBlob API to create a signed URL. That API requires either the https://www.googleapis.com/auth/iam or https://www.googleapis.com/auth/cloud-platform scope, so be sure they are enabled.
Eu sinto que isso deve ser suficiente para que funcione. Não sei como verificar explicitamente os escopos.
A única outra coisa que tentei é executar sign-blob
do terminal. Eu corri isto:
gcloud iam service-accounts sign-blob --iam-account=<my-project-id>@appspot.gserviceaccount.com input.file output.file
e eu recebo este erro:
ERROR: (gcloud.iam.service-accounts.sign-blob) PERMISSION_DENIED: Permission iam.serviceAccounts.signBlob is required to perform this operation on service account projects/-/serviceAccounts/[email protected].
Não sei como verificar se minha conta de serviço tem essa permissão. Tentei procurá-lo no IAM no site, no programa gcloud
terminal e nas permissões definidas nos meus blocos.
Aqui está o código da minha função:
const storage = require('@google-cloud/storage')();
exports.getSignedUrl = (req, res) => {
if(req.method === 'POST') {
// Perform any authorization checks here to assert
// that the end user is authorized to upload.
const myBucket = storage.bucket('my-bucket-name');
const myFile = myBucket.file(req.body.filename);
const contentType = req.body.contentType;
// This link should only last 5 minutes
const expiresAtMs = Date.now() + 300000;
const config = {
action: 'write',
expires: expiresAtMs,
contentType: contentType
};
myFile.getSignedUrl(config, function(err, url) {
if (err) {
console.error(err);
res.status(500).end();
return;
}
res.send(url);
});
} else {
res.status(405).end();
}
}
Alguém já viu isso antes ou sabe por que isso está acontecendo? Ou sabe como posso verificar se a minha conta de serviço tem essas permissões ou escopos? Eu sinto que isso pode ser um bug no GCP, mas é provável que eu esteja perdendo alguma coisa. Eu estive preso nisso por um tempo, e agradeço qualquer ajuda que você possa ter!
Depois de algumas tentativas e erros, descobri que @google-cloud/storage
version 1.6.0
estava me dando esse comportamento. Eu fiz o downgrade para 1.5.2
e ele começou a funcionar.
Eu abri um problema no GitHub para isso: link
Resolvi-o adicionando a função "Agente de serviço do Cloud Functions" à minha conta de serviço "Conta de serviço padrão do App Engine".
Acesse: link
ache "Agente de serviço de funções da nuvem"
gerenciar funções
Fui orientado com clipes de tela no comentário @rscotten: link