Giter VIP home page Giter VIP logo

steampipe-plugin-postgres's Introduction

Postgres Plugin for Steampipe

Use SQL to query data from plain PostgreSQL databases.

This repo contains a Steampipe plugin that exposes plain PostgreSQL databases as Steampipe tables, much like the CSV plugin does for CSV files, or like a reverse proxy does for HTTP. This can be used to join API data with semi-static data that is hosted on databases.

See below for an example that mixes data from a static DB (contact information for the teams that own Kubernetes namespaces) and data from Kubernetes (which namespaces have Failed pods). This may be part of an automated alerting system that runs periodically and sends emails.

Alt text

Steampipe currently has no such functionality, with an alternative being exporting a copy of the Postgres DB as a CSV and then using the CSV plugin. However, the CSV file may be out of date, and you're responsible for keeping it updated. This plugin, instead, will always have up-to-date results, since it queries the backing Postgres DB whenever a query comes in to Steampipe. Another alternative is to manually install and configure the postgres-fdw module on Steampipe, which requires connecting to the DB as root, is not documented and doesn't play too well with Dockerized deployments.

Quick start

Download and install the latest Postgres plugin:

steampipe plugin install jreyesr/postgres

Installing the latest Postgres plugin will create a config file (~/.steampipe/config/postgres.spc) with a single connection named postgres:

connection "postgres" {
  plugin = "jreyesr/postgres"

  # A connection string (https://pkg.go.dev/github.com/jackc/pgx/v5#hdr-Establishing_a_Connection), in the form that is 
  # expected by the pgx package. Required. 
  # Can also be set with the `DATABASE_URL` environment variable.
  # connection_string = "postgres://username:password@localhost:5432/database_name"

  # The remote DB's schema that this plugin will expose. If you leave this unset, it'll default to `public`.
  # schema = "public"

  # List of tables that will be exposed from the remote DB. No dynamic tables will be created if this arg is empty or not set.
  # Wildcard based searches are supported.
  # For example:
  #  - "*" will expose every table in the remote DB
  #  - "auth-*" will expose tables whose names start with "auth-"
  #  - "users" will only expose the specific table "users"
  # You can have several items (for example, ["auth-*", "users"] will expose 
  # all the tables that start with "auth-", PLUS the table "users")
  # Defaults to all tables
  # tables_to_expose = ["*"]
}

Alternatively, you can also use the following environment variable to obtain credentials only if the other argument (connection_string) is not specified in the connection:

export DATABASE_URL=postgres://username:password@localhost:5432/database_name

Run Steampipe:

steampipe query

Run a query for whatever table the Postgres DB has:

select
  attr1,
  attr2
from
  postgres.some_table;

This plugin forwards all conditions that are supported by Steampipe to the remote DB. For example, a WHERE col=1 condition will be forwarded, so the remote DB can optimize its searches. More complex operators (such as JSONB operations) can't be forwarded and will thus result in a full table scan on the remote DB. In this case, the filtering will be applied by Steampipe.

Developing

Prerequisites:

Clone:

git clone https://github.com/jreyesr/steampipe-plugin-postgres.git
cd steampipe-plugin-postgres

Build, which automatically installs the new version to your ~/.steampipe/plugins directory:

make

Configure the plugin:

cp config/* ~/.steampipe/config
vi ~/.steampipe/config/postgres.spc

Try it!

steampipe query
> .inspect postgres

Further reading:

Contributing

Please see the contribution guidelines and our code of conduct. All contributions are subject to the Apache 2.0 open source license.

help wanted issues:

steampipe-plugin-postgres's People

Contributors

jreyesr avatar

Stargazers

Jan Weitz avatar Johan Denoyer avatar Lalit Bhardwaj avatar Nathan Wallace avatar Ved misra avatar

Watchers

 avatar  avatar Ved misra avatar

Forkers

tektite-io

steampipe-plugin-postgres's Issues

Initial suggestions for plugin release

Thanks @jreyesr for this new plugin. Great work ๐ŸŽ‰ !!

The basic structure looks good so far. While using the plugin, we did come up with a few suggestions based on our best practices:

postgres.spc

  • Could you please update the postgres.spc file to follow the format of the namecheap plugin
  • We should mention the config arguments however commented out and the values should be in the format of the actual values (however incorrect)
  • For instance: There are only a few formatting issues that have been resolved in this example:
connection "postgres" {
  plugin = "jreyesr/postgres"

    # A connection string (https://pkg.go.dev/github.com/jackc/pgx/v5#hdr-Establishing_a_Connection), in the form that is 
    expected by the pgx package. Required. 
    # Can also be set with the `DATABASE_URL` environment variable.
    # connection_string = "postgres://username:password@localhost:5432/database_name"
  
    # The remote DB's schema that this plugin will expose. If you leave this unset, it'll default to `public`.
    # schema = "public"
  
    # List of tables that will be exposed from the remote DB. No dynamic tables will be created if this arg is empty or not set.
    # Wildcard-based searches are supported.
    # For example:
    #  - "*" will expose every table in the remote DB
    #  - "auth-*" will expose tables whose names start with "auth-"
    #  - "users" will only expose the specific table "users"
    # You can have several items (for example, ["auth-*", "users"] will expose 
    # all the tables that start with "auth-", PLUS the table "users")
    # Defaults to all tables
    # tables_to_expose = ["*"]
  }
  • Is the environment variable name correct?

docs/tables

select 
  name,
  id 
from
  aws_s3_bucket
where 
  region = 'us-east-1';
  • We generally do not include the example query output in the docs, is there a particular reason for keeping them here?
  • The example queries in the doc look a bit light. Could you please add 2 to 3 more example queries wherever possible?

docs/index.md

  • The description should be updated to "description: Steampipe plugin for proxying queries to plain Postgres databases."
  • The og_description should be updated to "Query any Postgres table from Steampipe with SQL! Open source CLI. No DB required."
  • The formatting of the query should be updated using https://www.freeformatter.com/sql-formatter.html#before-output (2 indent spaces)
  • The query is not correctly formatted. They should end with a ;.
  • We generally do not include the example query output in the docs, is there a particular reason for keeping them here?
  • One example query is enough in the index.md file we do not have to keep multiple examples here.
  • The documentation and install sections are overlapping with the query section, I believe there are some issues with the "``" usage, please check that.
  • Also please make sure that the Configuration section is in sync with the changes suggested for the config/postgres.spc file.
  • We need a slight change in the way we include details of the environment variable, can you please change the section after the connection as follows:
    Alternatively, you can also use the standard Postgres environment variables to obtain credentials only if the other argument (connection_string) is not specified in the connection:
    export DATABASE_URL=postgres://username:password@localhost:5432/database_name
  • Is the environment variable name correct?
  • Under Get Involved we should include the links in - rather than * for instance
- Open source: https://github.com/jreyesr/steampipe-plugin-postgres
- Community: [Join #steampipe on Slack โ†’](https://turbot.com/community/join)
  • postgres
    • Please rename the config.go to connection_config.go
    • plugin.go
      • The function has some extra unnecessary spaces we can restructure it as follows
       func Plugin(ctx context.Context) *plugin.Plugin {
           p := &plugin.Plugin{
               Name: "steampipe-plugin-postgres",
               DefaultTransform: transform.FromGo().NullIfZero(),
               ConnectionConfigSchema: &plugin.ConnectionConfigSchema{
         	      NewInstance: ConfigInstance,
         	      Schema:      ConfigSchema,
               },
               SchemaMode:   plugin.SchemaModeDynamic,
               TableMapFunc: PluginTables,
           }
           return p
       }
      

README

  • We can update Install the plugin with [Steampipe](https://steampipe.io) to Download and install the latest Postgres plugin:
  • Also please make sure that the Configuration section is in sync with the changes suggested for the config/postgres.spc file.
  • Please include the details of authentication via environment variable using the EXPORT command
  • Please include the following inder contribution section:
`help wanted` issues:

- [Steampipe](https://github.com/turbot/steampipe/labels/help%20wanted)
- [Postgres Plugin](https://github.com/jreyesr/steampipe-plugin-postgres/labels/help%20wanted)

go.mod

  • We should recompile the plugin with steampipe-plugin-sdk v5.6.1 and GO version 1.21

  • A couple of follow-up questions:

    • How are we handling the resource not found errors?
    • Do the APIs support pagination? I did not find any reference to it, but I want to make sure that we have checked that box before releasing it.
    • While working with the APIs did you encounter rate limit errors?
    • Please refer to https://steampipe.io/docs/develop/plugin-release-checklist#data-ingestion for more information

Please let us know if you have questions, happy to help ๐Ÿ‘

failed to initialise

Warning:
    failed to start plugin 'hub.steampipe.io/plugins/jreyesr/postgres@latest': failed to plugin initialise plugin 'steampipe-plugin-postgres': TableMapFunc 'PluginTables' had unhandled error: interface conversion: interface is nil, not hclog.LoggerUpdatedConnections: true

I figured this must be a connection string problem, but I'm not seeing it.

My .spc:

 connection "postgres" {
  plugin = "jreyesr/postgres"

  # Write a connection string, in the form that is expected by the pgx package:
  # https://pkg.go.dev/github.com/jackc/pgx/v5#hdr-Establishing_a_Connection
  # Required
  connection_string = "postgres://jon:jon@localhost:5432/postgres"

  # The remote DB's schema that this plugin will expose
  # If you leave this unset, it'll default to `public`
  # schema = "public"
}

This works: psql -d postgres -U jon -W

I instrumented GetConfig like so:

func GetConfig(connection *plugin.Connection) PostgresConfig {
	logger.Debug("GetConfig", "connection", connection, "connection.Config", connection.Config)
	if connection == nil || connection.Config == nil {
		return PostgresConfig{}
	}
	config, other := connection.Config.(PostgresConfig)
	logger.Debug("GetConfig returning", "config", config, "other", other)
	return config
}

The output:

2023-09-11T10:40:59.563-0700 [DEBUG] plugin: postgres.PluginTables
2023-09-11T10:40:59.563-0700 [DEBUG] plugin: GetConfig: connection="&{postgres %!v(PANIC=String method: runtime error: invalid memory address or nil pointer d
ereference)}" connection.Config="%!v(PANIC=String method: runtime error: invalid memory address or nil pointer dereference)"
2023-09-11T10:40:59.563-0700 [DEBUG] plugin: GetConfig returning: config="%!v(PANIC=String method: runtime error: invalid memory address or nil pointer dereference)" other=true

I feel like I'm missing something really dumb?

Add config param to choose which tables will be exposed

Per the Plugin Release Checklist,

If the plugin can generate dynamic tables, a configuration argument should allow users to specify which tables the plugin will generate. This configuration argument typically accepts a list of strings and should support filesystem glob patterns like in the CSV plugin.

If this configuration argument is not set or is explicitly empty, e.g., paths = [], then no dynamic tables should be generated.

Add a configuration param to ignore some tables, such as those that have non-handled columns.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.