Как подключить Google Cloud SQL из облачных функций?

Я пытаюсь использовать облачные функции для Firebase для создания API, который разговаривает с экземпляром Google Cloud SQL (PostgreSQL).

Я использую триггер HTTP(S).

когда я белый список IP-адрес моего рабочего стола, я могу подключиться к облачному SQL с узлом функции.код js с моей локальной машины. Но когда я развертываю, я не могу подключиться, и я не могу выяснить IP-адрес хоста сервера функции Firebase, в белый список.

Как вы поговорите с Google Cloud SQL из облачных функций для Firebase?

спасибо!

// Code Sample, of what's working on Localhost.
var functions = require('firebase-functions');

var pg = require('pg');
var pgConfig = {
  user: functions.config().pg.user,
  database: functions.config().pg.database,
  password: functions.config().pg.password,
  host: functions.config().pg.host
}

exports.helloSql = functions.https.onRequest((request, response) => {
  console.log('connecting...');
  try {
    client.connect(function(err) {
      if (err) throw err;

      console.log('connection success');
      console.log('querying...');

      client.query('SELECT * FROM guestbook;', function(err, result){
        if (err) throw err;

        console.log('querying success.');
        console.log('Results: ', result);
        console.log('Ending...');

        client.end(function(err){
          if (err) throw err;
          console.log('End success.');
          response.send(result);
        });
      });

    });
  } catch(er) {
    console.error(er.stack)
    response.status(500).send(er);
  }
});

6 ответов


в настоящее время невозможно. Однако это запрос функции на трекер проблем #36388165:

подключение к Cloud SQL из облачных функций в настоящее время не поддерживается, так как сокет UNIX не существует (вызывая ENOENT) и нет определенного диапазона IP для белого списка (вызывающего ETIMEDOUT). Один возможность состоит в том, чтобы белый список 0.0.0.0 / 0 из экземпляра Cloud SQL, но это не рекомендуется по соображениям безопасности.

Если это важная функция для вас я бы предложил вам посетить issuetracker и звезда запрос функции, чтобы помочь ему получить популярность.


Я нашел ответ в дальнейшем обсуждении #36388165.

отказ от ответственности: это, похоже, не объявлено официально, поэтому может измениться позже. также я тестирую только в mysql. но природа этого решения, я думаю, так же должна работать, как и в модуле pg (кажется,принять путь сокета домена как параметр хоста)

изменить(2017/12/7): google, кажется, предоставляет официальный ранний доступ, и такой же метод все еще завод.
изменить(2018/07/04): кажется, что кто-то просто копирует и вставляет мой пример кода и попадает в беду. как google говорит, вы должны использовать пул соединений, чтобы избежать утечки соединения SQL. (это вызывает ECONNREFUSE) поэтому я немного меняю пример кода.

в https://issuetracker.google.com/issues/36388165#comment44 Google guy говорит, что экземпляр облачной функции может разговаривать с облачным sql через доменный сокет по специальному пути '/cloudsql / $PROJECT_ID:$REGION:$DBNAME'.

Я действительно могу подключать и управлять облачным SQL снизу кода облачной функции.

const mysql = require('mysql');
const pool = mysql.createPool({
    connectionLimit : 1,
    socketPath: '/cloudsql/' + '$PROJECT_ID:$REGION:$DBNAME',
    user: '$USER',
    password: '$PASS',
    database: '$DATABASE'
});
exports.handler = function handler(req, res) {
    //using pool instead of creating connection with function call
    pool.query(`SELECT * FROM table where id = ?`, 
                                req.body.id, function (e, results) {
        //made reply here
    });
};

Я надеюсь, что это будет помощь для тех, кто не может ждать официального объявления от google.


найдите область базы данных и имя экземпляра на GCP > SQL > экземпляры страницы:

enter image description here

сохраните пароль базы данных в Firebase окружающей среды работает:

$ firebase functions:config:set \
    db.user="<username>" \
    db.password="<password>" \
    db.database="<database>"

затем...

db.js

const { Pool } = require('pg');
const { config } = require('firebase-functions');

const project = process.env.GCP_PROJECT;
const region = 'europe-west1';
const instance = 'db';

module.exports = new Pool({
  max: 1,
  host: `/cloudsql/${project}:${region}:${instance}`,
  ...config().db
});

someFunction.js

const { https } = require('firebase-functions');
const db = require('./db');

module.exports = https.onRequest((req, res) =>
  db
    .query('SELECT version()')
    .then(({ rows: [{ version }]) => {
      res.send(version);
    }));

см. также https://stackoverflow.com/a/48825037/82686 (используя современный синтаксис JavaScript через Babel)


теперь есть официальная документация для этого, все еще в бета-версии, хотя по состоянию на июль 2018

https://cloud.google.com/functions/docs/sql


Облачные Функции - Поддерживаемые Услуги - Я не вижу Cloud SQL в этом списке, поэтому, возможно, он еще не поддерживается.


вы также можете авторизовать диапазон IP-адресов Firebase поскольку мы действительно не знаем, какой IP-адрес Firebase использует извне.

я экспериментировал на нем. Google Cloud SQL не использует внутренние IP-адреса. Таким образом, вы не можете использовать 10.128.0.0/20 разрешить внутренние IP-адреса для вашего Google Cloud SQL.

ответ

Итак, с консоли перейдите в Google Cloud SQL > Instance > Authorization, вы можете добавить:

151.101.0.0/17

что позволит вам 151.101.0.0 to 151.101.127.255 диапазон IP-адресов, в котором домен сервера Firebase в настоящее время 151.101.1.195 и 151.101.65.195.

Я не уверен, что этот IP-адрес когда-либо изменится.

кроме того, убедитесь, что ваша база данных Cloud SQL использует us-central зоны. Firebase, похоже, доступна в us-central.