Crate grant

source ·
Expand description

An open-source project that aims to manage Redshift database roles and privileges in GitOps style, written in Rust.

Home | Documentation

This project is still in the early stages of development and is not ready for any kind of production use or any alpha/beta testing.

Usage

Install binary from crates.io

cargo install grant

Using grant tool:

$ grant --help

grant 0.0.1-beta.3
Manage database roles and privileges in GitOps style

USAGE:
    grant <SUBCOMMAND>

FLAGS:
    -h, --help       Prints help information
    -V, --version    Prints version information

SUBCOMMANDS:
    apply       Apply a configuration to a redshift by file name. Yaml format are accepted
    gen         Generate sample configuration file
    gen-pass    Generate random password
    help        Prints this message or the help of the given subcommand(s)
    inspect     Inspect current database cluster with connection info from configuration file
    validate    Validate a configuration file or a target directory that contains configuration files

Generate project structure

grant gen --target ./cluster

Creating path: "./cluster"
Generated: "./cluster/config.yml"

Apply privilege changes

Content of ./examples/example.yaml:

connection:
  type: "postgres"
  # support environment variables, e.g. postgres://${HOSTNAME}:5432
  url: "postgres://postgres@localhost:5432/postgres"

roles:
  - name: role_database_level
    type: database
    grants:
      - CREATE
      - TEMP
    databases:
      - postgres

  - name: role_schema_level
    type: schema
    grants:
      - CREATE
    databases:
      - postgres
    schemas:
      - public
  - name: role_all_schema
    type: table
    grants:
      - SELECT
      - INSERT
      - UPDATE
    databases:
      - postgres
    schemas:
      - public
    tables:
      - ALL # include all table
      - +public_table # can add `+` to mark included tables
      - -secret_table # add `-` to exclude this table

users:
  - name: duyet
    password: 1234567890 # password in plaintext
    roles:
      - role_database_level
      - role_all_schema
      - role_schema_level
  - name: duyet2
    password: md58243e8f5dfb84bbd851de920e28f596f # support md5 style: grant gen-pass -u duyet2
    roles:
      - role_database_level
      - role_all_schema
      - role_schema_level

Apply this config to cluster:

grant apply -f ./examples/example.yaml

[2021-12-06T14:37:03Z INFO  grant::connection] Connected to database: postgres://postgres@localhost:5432/postgres
[2021-12-06T14:37:03Z INFO  grant::apply] Summary:
    ┌────────────┬────────────────────────────┐
    │ User       │ Action                     │
    │ ---        │ ---                        │
    │ duyet      │ no action (already exists) │
    │ duyet2     │ no action (already exists) │
    └────────────┴────────────────────────────┘
[2021-12-12T13:48:22Z INFO  grant::apply] Success: GRANT CREATE, TEMP ON DATABASE postgres TO duyet;
[2021-12-12T13:48:22Z INFO  grant::apply] Success: GRANT CREATE ON SCHEMA public TO duyet;
[2021-12-12T13:48:22Z INFO  grant::apply] Success: GRANT SELECT, INSERT, UPDATE ON ALL TABLES IN SCHEMA public TO duyet;
[2021-12-12T13:48:22Z INFO  grant::apply] Success: GRANT CREATE, TEMP ON DATABASE postgres TO duyet2;
[2021-12-12T13:48:22Z INFO  grant::apply] Success: GRANT CREATE ON SCHEMA public TO duyet2;
[2021-12-12T13:48:22Z INFO  grant::apply] Success: GRANT SELECT, INSERT, UPDATE ON ALL TABLES IN SCHEMA public TO duyet2;
[2021-12-12T13:48:22Z INFO  grant::apply] Summary:
    ┌────────┬─────────────────────┬──────────────────────┬─────────┐
    │ User   │ Role Name           │ Detail               │ Status  │
    │ ---    │ ---                 │ ---                  │ ---     │
    │ duyet  │ role_database_level │ database["postgres"] │ updated │
    │ duyet  │ role_schema_level   │ schema["public"]     │ updated │
    │ duyet  │ role_table_level    │ table["ALL"]         │ updated │
    │ duyet2 │ role_database_level │ database["postgres"] │ updated │
    │ duyet2 │ role_schema_level   │ schema["public"]     │ updated │
    │ duyet2 │ role_table_level    │ table["ALL"]         │ updated │
    └────────┴─────────────────────┴──────────────────────┴─────────┘

Generate random password

$ grant gen-pass

Generated password: q)ItTjN$EXlkF@Tl
$ grant gen-pass --user duyet

Generated password: o^b3aD1L$xLm%#~U
Generated MD5 (user: duyet): md58243e8f5dfb84bbd851de920e28f596f

Inspect the current cluster

$ grant inspect -f examples/example.yaml

[2021-11-29T07:46:44Z INFO  grant::inspect] Current users in postgres://postgres@localhost:5432/postgres:
    ┌────────────┬──────────┬───────┬──────────┐
    │ User       │ CreateDB │ Super │ Password │
    │ ---        │ ---      │ ---   │ ---      │
    │ postgres   │ true     │ true  │ ******** │
    │ duyet      │ false    │ false │ ******** │
    └────────────┴──────────┴───────┴──────────┘

Developement

Clone the repo:

git clone https://github.com/duyet/grant.rs && cd grant.rs

Postgres is required for testing, you might need to use the docker-compose.yaml:

docker-compose up -d

Make sure you have connection to postgres://postgres:postgres@localhost:5432/postgres.

On the MacOS, the easiest way is install Postgres.app.

To run the unittest:

cargo test

TODO

  • Support reading connection info from environment variables
  • Support store encrypted password in Git
  • Support Postgres and Redshift
  • Support change password
  • Visuallization (who can see what?)
  • Apply show more detail about diff changes
  • Inspect show more detail about user privileges

LICENSE

MIT

Re-exports

Modules