Skip to content

Commit c335a05

Browse files
leszek-bqleszekamz
andauthored
Update Ruby-pg samples and README.md (#117)
* Update the Ruby-pg example. Include non-admin scenario * added CLUSTER_USER env variable to gh * added certificate download * addressing review comments * updated minimum ruby version to 3+ * Updated ruby version to 3.3 for integration tests --------- Co-authored-by: Leszek Kurzyna <lkurzyna@amazon.com>
1 parent 11e049c commit c335a05

5 files changed

Lines changed: 175 additions & 56 deletions

File tree

.github/workflows/ruby-rubypg-integ-tests.yml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,10 @@ jobs:
3434
- name: Checkout code
3535
uses: actions/checkout@v4
3636

37-
- name: Set up Ruby 2.5
37+
- name: Set up Ruby 3.3
3838
uses: ruby/setup-ruby@v1
3939
with:
40-
ruby-version: '2.5'
40+
ruby-version: '3.3'
4141
bundler-cache: true
4242

4343
- name: Configure AWS Credentials
@@ -51,6 +51,8 @@ jobs:
5151
env:
5252
CLUSTER_ENDPOINT: ${{ secrets.RUBY_RUBYPG_CLUSTER_ENDPOINT }}
5353
REGION: ${{ secrets.RUBY_RUBYPG_CLUSTER_REGION }}
54+
CLUSTER_USER: admin
5455
run: |
5556
bundle install
57+
wget https://www.amazontrust.com/repository/AmazonRootCA1.pem -O root.pem
5658
rspec

ruby/ruby-pg/Gemfile

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,4 @@ source "https://rubygems.org"
44

55
gem 'pg', '1.5.9'
66
gem 'rspec', '3.13.0'
7-
gem 'aws-sdk-core', '3.211.0'
8-
gem 'aws-sigv4', '1.10.1'
9-
10-
gem "aws-sdk-dsql", "~> 1"
7+
gem 'aws-sdk-dsql', '~> 1.6'

ruby/ruby-pg/README.md

Lines changed: 107 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,130 @@
1-
# Aurora DSQL Ruby-pg code examples
1+
# Ruby-pg with Aurora DSQL
22

33
## Overview
44

5-
The code examples in this topic show you how to use the Ruby-pg work with Aurora DSQL.
5+
This code example demonstrates how to use Ruby-pg to interact with Amazon Aurora DSQL (DSQL). The example shows you how
6+
to connect to an Aurora DSQL cluster and perform basic database operations.
67

7-
## Run the examples
8+
Aurora DSQL is a distributed SQL database service that provides high availability and scalability for
9+
your PostgreSQL-compatible applications. Ruby-pg is a popular PostgreSQL adapter for Ruby that allows
10+
you to interact with PostgreSQL databases using Ruby code.
11+
12+
## About the code example
13+
14+
The example demonstrates a flexible connection approach that works for both admin and non-admin users:
15+
16+
* When connecting as an **admin user**, the example uses the `public` schema and generates an admin authentication
17+
token.
18+
* When connecting as a **non-admin user**, the example uses a custom `myschema` schema and generates a standard
19+
authentication token. The `myschema` schema needs to be created prior to running the example and the **non-admin user** needs to be granted access to the schema.
20+
21+
The code automatically detects the user type and adjusts its behavior accordingly.
22+
The example contains comments explaining the code and the operations being performed.
23+
24+
## ⚠️ Important
25+
26+
* Running this code might result in charges to your AWS account.
27+
* We recommend that you grant your code least privilege. At most, grant only the
28+
minimum permissions required to perform the task. For more information, see
29+
[Grant least privilege](https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#grant-least-privilege).
30+
* This code is not tested in every AWS Region. For more information, see
31+
[AWS Regional Services](https://aws.amazon.com/about-aws/global-infrastructure/regional-product-services).
32+
33+
## Run the example
834

935
### Prerequisites
1036

11-
* Ruby version >=2.5 is needed
12-
* AWS credentials file is configured
37+
* You must have an AWS account, and have your default credentials and AWS Region
38+
configured as described in the
39+
[Globally configuring AWS SDKs and tools](https://docs.aws.amazon.com/credref/latest/refdocs/creds-config-files.html)
40+
guide.
41+
* You must have an Aurora DSQL cluster. For information about creating an Aurora DSQL cluster, see the
42+
[Getting started with Aurora DSQL](https://docs.aws.amazon.com/aurora-dsql/latest/userguide/getting-started.html)
43+
guide.
44+
* If connecting as a non-admin user, ensure the user is linked to an IAM role and is granted access to the `myschema`
45+
schema. See the
46+
[Using database roles with IAM roles](https://docs.aws.amazon.com/aurora-dsql/latest/userguide/using-database-and-iam-roles.html)
47+
guide.
1348

1449

15-
### Setup test running environment
50+
### Driver Dependencies
1651

17-
```sh
52+
Before using the Ruby-pg driver, ensure you have the following prerequisites installed:
53+
Ruby: Ensure you have ruby v3+ installed from the [official website](https://www.ruby-lang.org/en/documentation/installation/).
1854

19-
bundle install
55+
Verify install
2056

57+
```bash
58+
ruby --version
59+
```
60+
61+
### Libpq library
62+
63+
Libpq is required by Ruby-pg
64+
65+
#### Obtaining the libpq library
66+
67+
- It is installed with postgres installation. Therefore, if postgres is installed on the system the libpq is present in ../postgres_install_dir/lib, ../postgres_install_dir/include
68+
- It is installed when psql client program is installed, similarily as with postgres installation.
69+
- On some systems libpq can be installed through package manager e.g.
70+
- On Amazon Linux
71+
```
72+
sudo yum install libpq-devel
73+
```
74+
- On Mac libpq can be installed using brew
75+
```
76+
brew install libpq
77+
```
78+
- The [official website](https://www.postgresql.org/download/) may have a package for libpq or psql (which bundles libpq)
79+
- Ultimately, build from source which also can be obtained from [official website](https://www.postgresql.org/ftp/source/)
80+
81+
#### Add libpq to PATH
82+
83+
In some cases, it may be necessary to add the location of the libpq/bin directory to PATH
84+
85+
```
86+
export PATH="$PATH:<your installed location>/libpq/bin"
2187
```
2288
23-
### Run the example tests
89+
### Install Ruby-pg, Aurora DSQL SDK and other required dependencies
2490
25-
```sh
26-
# Use the account credentials dedicated for ruby
91+
- All the required dependencies are present in the `Gemfile` file. To get all the required dependencies, run the following command from the directory where the `Gemfile` is present.
2792
28-
# Download the Amazon root certificate from the official trust store
29-
# This example shows one of the available certs that can be used by the client;
30-
# other certs such as AmazonRootCA2.pem, AmazonRootCA3.pem, etc. can also be used.
93+
```bash
94+
bundle install
95+
```
96+
97+
### Download the Amazon root certificate from the official trust store
98+
99+
Download the Amazon root certificate from the official trust store.
100+
This example shows one of the available certs that can be used by the client.
101+
Other certs such as AmazonRootCA2.pem, AmazonRootCA3.pem, etc. can also be used.
102+
103+
```
31104
wget https://www.amazontrust.com/repository/AmazonRootCA1.pem -O root.pem
105+
```
106+
107+
Place the root.pem file in the same directory as the hello_dsql.rb example file or modify the path to it in the example file.
32108

109+
### Set the environmet variables specifying cluster endpoint, region and cluster user
110+
111+
```
112+
# e.g. 'admin' or a custom user
113+
export CLUSTER_USER=<your cluster user>
114+
115+
# e.g. "foo0bar1baz2quux3quuux4.dsql.us-east-1.on.aws"
33116
export CLUSTER_ENDPOINT="<your cluster endpoint>"
34-
export REGION="<your cluster region>"
35117
36-
rspec
118+
# e.g. "us-east-1"
119+
export REGION="<your cluster region>"
120+
```
121+
122+
### Run the example
123+
124+
Execute the following command:
125+
126+
```
127+
ruby hello_dsql.rb
37128
```
38129

39130
---

ruby/ruby-pg/lib/hello_dsql.rb

Lines changed: 61 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,40 @@
11
require 'pg'
22
require 'aws-sdk-dsql'
33

4-
def example(cluster_endpoint, region)
5-
credentials = Aws::SharedCredentials.new()
6-
7-
begin
8-
token_generator = Aws::DSQL::AuthTokenGenerator.new({
4+
def create_connection(cluster_user, cluster_endpoint, region)
5+
# Generate a fresh password token for each connection, to ensure the token is not expired
6+
# when the connection is established
7+
credentials = Aws::CredentialProviderChain.new.resolve
8+
token_generator = Aws::DSQL::AuthTokenGenerator.new({
99
:credentials => credentials
1010
})
11-
12-
# The token expiration time is optional, and the default value 900 seconds
13-
# if you are not using admin role, use generate_db_connect_auth_token instead
14-
token = token_generator.generate_db_connect_admin_auth_token({
15-
:endpoint => cluster_endpoint,
16-
:region => region
17-
})
1811

19-
conn = PG.connect(
20-
host: cluster_endpoint,
21-
user: 'admin',
22-
password: token,
23-
dbname: 'postgres',
24-
port: 5432,
25-
sslmode: 'require'
26-
)
27-
rescue => _error
28-
raise
29-
end
12+
auth_token_params = {
13+
endpoint: cluster_endpoint,
14+
region: region,
15+
expires_in: 15 * 60 # 15 minutes, optional
16+
}
17+
18+
case cluster_user
19+
when "admin"
20+
password_token = token_generator.generate_db_connect_admin_auth_token(auth_token_params)
21+
else
22+
password_token = token_generator.generate_db_connect_auth_token(auth_token_params)
23+
end
24+
25+
PG.connect(
26+
host: cluster_endpoint,
27+
user: cluster_user,
28+
password: password_token,
29+
dbname: 'postgres',
30+
port: 5432,
31+
sslmode: 'verify-full',
32+
sslrootcert: "./root.pem"
33+
)
34+
35+
end
36+
37+
def example(conn)
3038

3139
# Create the owner table
3240
conn.exec('CREATE TABLE IF NOT EXISTS owner (
@@ -50,13 +58,35 @@ def example(cluster_endpoint, region)
5058
# Delete data we just inserted
5159
conn.exec("DELETE FROM owner where name='John Doe'")
5260

53-
rescue => error
54-
puts error.full_message
55-
ensure
56-
unless conn.nil?
57-
conn.finish()
58-
end
5961
end
6062

61-
# Run the example
62-
example(ENV["CLUSTER_ENDPOINT"], ENV["REGION"])
63+
def main()
64+
# Use environment variables.
65+
cluster_endpoint = ENV["CLUSTER_ENDPOINT"]
66+
region = ENV["REGION"]
67+
cluster_user = ENV["CLUSTER_USER"]
68+
69+
# Raise errors if any of the variables are not set.
70+
raise "CLUSTER_ENDPOINT environment variable is not set" unless cluster_endpoint
71+
raise "REGION environment variable is not set" unless region
72+
raise "CLUSTER_USER environment variable is not set" unless cluster_user
73+
74+
begin
75+
conn = create_connection(cluster_user, cluster_endpoint, region)
76+
if cluster_user != 'admin'
77+
conn.exec("SET search_path = myschema")
78+
end
79+
example(conn)
80+
puts "Ruby test passed"
81+
rescue => error
82+
puts error.full_message
83+
puts "Ruby test failed"
84+
raise
85+
ensure
86+
conn.close if conn
87+
end
88+
end
89+
90+
if __FILE__ == $0
91+
main()
92+
end

ruby/ruby-pg/spec/smoke_spec.rb

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,8 @@
22

33
describe 'perform smoke tests' do
44
it 'does not raise any exception' do
5-
65
expect {
7-
example(ENV["CLUSTER_ENDPOINT"], ENV["REGION"])
6+
main()
87
}.not_to raise_error
98
end
10-
end
9+
end

0 commit comments

Comments
 (0)