cube-js / cube

📊 Cube — The Semantic Layer for Building Data Applications
https://cube.dev
Other
17.93k stars 1.78k forks source link

Automatically retrieve Redshift cluster credentials #306

Open hassankhan opened 4 years ago

hassankhan commented 4 years ago

Is your feature request related to a problem? Please describe. The AWS Redshift SDK allows retrieving credentials via an API:

import Redshift, { ClusterCredentials } from 'aws-sdk/clients/redshift';

const getCredentials = async () => {
  const creds = await redshift.getClusterCredentials({
    ClusterIdentifier: process.env.CUBEJS_DB_HOST,
    DbUser: process.env.CUBEJS_DB_USER,
  }).promise();

  if (!creds.DbUser && !creds.DbPassword) {
    throw new Error('Unable to retrieve Redshift credentials');
  }

  return creds as Required<ClusterCredentials>;
};

getCredentials()
  .then((credentials) => {
    const config = {
      database : process.env.CUBEJS_DB_NAME,
      host: process.env.CUBEJS_DB_HOST,
      password : creds.DbPassword,
      port: process.env.CUBEJS_DB_PORT,
      user: creds.DbUser,
    };
  })

Describe the solution you'd like

It would be great if CubeJS would automatically attempt to do the above if the CUBEJS_DB_PASS environment variable is omitted for Redshift projects.

Additional context A Serverless project using Redshift would require additional permissions to the IAM role:

iamRoleStatements:
    - Effect: 'Allow'
      Action:
        - 'redshift:GetClusterCredentials'
      Resource:
        - '<REDSHIFT_CLUSTER_ARN>/<REDSHIFT_USER>'
paveltiunov commented 4 years ago

@hassankhan Hey Hassan! Thanks for posting this! I think it would be great to support this in case credentials aren't passed in environment or options.

hassankhan commented 4 years ago

I could take this on, would love a little bit of guidance though ... the code snippet I pasted above expects to run asynchronously, however looking through the Postgres driver source, it seems that the pool is instantiated in the constructor. How would you recommend approaching this, @paveltiunov?

paveltiunov commented 4 years ago

@hassankhan Sounds great! I believe you can instantiate it lazily when pool is accessed in query() or testConnection() methods. I also believe we should create separate package @cubejs-backed/redshift-driver for this and extend PostgresDriver there.