seira 0.5.1 → 0.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/seira/db/alter_proxyuser_roles.rb +42 -0
- data/lib/seira/db/create.rb +33 -59
- data/lib/seira/db.rb +25 -17
- data/lib/seira/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7064ff568c67e81e0cdb84bc98fe1420b392ab69174ad39a2d96c81ae59615f5
|
4
|
+
data.tar.gz: 41024bad248f6e8631587d0fd7d6bb0c6db49fd9ce8da58bd85330f46d321345
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 85ce01cc44b6d88ab6890a93d2228e323cb277f797b1fecdd3ca763d5a00668092949dcdcd1f1fc79bd5f6412e04d40486884b62dd8b0556e015442713b1bb27
|
7
|
+
data.tar.gz: 599e8c0a21b0e6f1df8dac190a1c6d12be34fc9f2eceaf425ac4b8ec7b78c4163d4e5ad6be35daf6ae8c206f66cc2e12017617be69944d8f7c5812122992fcb6
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module Seira
|
2
|
+
class Db
|
3
|
+
class AlterProxyuserRoles
|
4
|
+
include Seira::Commands
|
5
|
+
|
6
|
+
attr_reader :name, :root_password
|
7
|
+
|
8
|
+
def initialize(app:, action:, args:, context:)
|
9
|
+
if args.length != 2
|
10
|
+
puts 'Specify db name and root password as the positional arguments'
|
11
|
+
exit(1)
|
12
|
+
end
|
13
|
+
|
14
|
+
@name = args[0]
|
15
|
+
@root_password = args[1]
|
16
|
+
end
|
17
|
+
|
18
|
+
def run
|
19
|
+
# Connect to the instance and remove some of the default group memberships and permissions
|
20
|
+
# from proxyuser, leaving it with only what it needs to be able to do
|
21
|
+
expect_script = <<~BASH
|
22
|
+
set timeout 90
|
23
|
+
spawn gcloud sql connect #{name}
|
24
|
+
expect "Password for user postgres:"
|
25
|
+
send "#{root_password}\\r"
|
26
|
+
expect "postgres=>"
|
27
|
+
send "ALTER ROLE proxyuser NOCREATEDB NOCREATEROLE;\\r"
|
28
|
+
expect "postgres=>"
|
29
|
+
BASH
|
30
|
+
if system("expect <<EOF\n#{expect_script}EOF")
|
31
|
+
puts "Successfully removed unnecessary permissions from proxyuser"
|
32
|
+
else
|
33
|
+
puts "Failed to remove unnecessary permissions from proxyuser."
|
34
|
+
puts "You may need to whitelist the correct IP in the gcloud UI."
|
35
|
+
puts "You can get the correct IP from https://www.whatismyip.com/"
|
36
|
+
puts "Make sure to remove it from the whitelist after successfully running db alter-proxyuser-roles"
|
37
|
+
exit(1)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
data/lib/seira/db/create.rb
CHANGED
@@ -40,6 +40,8 @@ module Seira
|
|
40
40
|
set_secrets
|
41
41
|
write_pgbouncer_yaml
|
42
42
|
|
43
|
+
alter_proxy_user_roles if replica_for.nil?
|
44
|
+
|
43
45
|
puts "To use this database, deploy the pgbouncer config file that was created and use the ENV that was set."
|
44
46
|
puts "To make this database the primary, promote it using the CLI and update the DATABASE_URL."
|
45
47
|
end
|
@@ -79,6 +81,7 @@ module Seira
|
|
79
81
|
|
80
82
|
# Basic configs
|
81
83
|
create_command += " --database-version=#{version}"
|
84
|
+
create_command += " --network=default" # allow network to be configurable?
|
82
85
|
|
83
86
|
# A read replica cannot have HA, inherits the cpu, mem and storage of its primary
|
84
87
|
if replica_for.nil?
|
@@ -115,7 +118,7 @@ module Seira
|
|
115
118
|
# Set the root user's password to something secure
|
116
119
|
@root_password = SecureRandom.urlsafe_base64(32)
|
117
120
|
|
118
|
-
if gcloud("sql users set-password postgres
|
121
|
+
if gcloud("sql users set-password postgres --instance=#{name} --password=#{root_password}", context: context, format: :boolean)
|
119
122
|
puts "Set root password to #{root_password}"
|
120
123
|
else
|
121
124
|
puts "Failed to set root password"
|
@@ -127,30 +130,16 @@ module Seira
|
|
127
130
|
# Create proxyuser with secure password
|
128
131
|
@proxyuser_password = SecureRandom.urlsafe_base64(32)
|
129
132
|
|
130
|
-
if gcloud("sql users create proxyuser
|
133
|
+
if gcloud("sql users create proxyuser --instance=#{name} --password=#{proxyuser_password}", context: context, format: :boolean)
|
131
134
|
puts "Created proxyuser with password #{proxyuser_password}"
|
132
135
|
else
|
133
136
|
puts "Failed to create proxyuser"
|
134
137
|
exit(1)
|
135
138
|
end
|
139
|
+
end
|
136
140
|
|
137
|
-
|
138
|
-
|
139
|
-
expect_script = <<~BASH
|
140
|
-
set timeout 90
|
141
|
-
spawn gcloud sql connect #{name}
|
142
|
-
expect "Password for user postgres:"
|
143
|
-
send "#{root_password}\\r"
|
144
|
-
expect "postgres=>"
|
145
|
-
send "ALTER ROLE proxyuser NOCREATEDB NOCREATEROLE;\\r"
|
146
|
-
expect "postgres=>"
|
147
|
-
BASH
|
148
|
-
if system("expect <<EOF\n#{expect_script}EOF")
|
149
|
-
puts "Successfully removed unnecessary permissions from proxyuser"
|
150
|
-
else
|
151
|
-
puts "Failed to remove unnecessary permissions from proxyuser"
|
152
|
-
exit(1)
|
153
|
-
end
|
141
|
+
def alter_proxy_user_roles
|
142
|
+
Seira::Db::AlterProxyuserRoles.new(app: app, action: action, args: [name, root_password], context: context).run
|
154
143
|
end
|
155
144
|
|
156
145
|
def set_secrets
|
@@ -186,10 +175,6 @@ module Seira
|
|
186
175
|
"#{name}-pgbouncer-secrets"
|
187
176
|
end
|
188
177
|
|
189
|
-
def pgbouncer_configs_name
|
190
|
-
"#{name}-pgbouncer-configs"
|
191
|
-
end
|
192
|
-
|
193
178
|
def pgbouncer_service_name
|
194
179
|
"#{name}-pgbouncer-service"
|
195
180
|
end
|
@@ -202,11 +187,21 @@ module Seira
|
|
202
187
|
"#{app}_#{Helpers.rails_env(context: context)}"
|
203
188
|
end
|
204
189
|
|
190
|
+
def ips
|
191
|
+
@_ips ||= begin
|
192
|
+
describe_command = "sql instances describe #{name}"
|
193
|
+
json = JSON.parse(gcloud(describe_command, context: context, format: :json))
|
194
|
+
private_ip = json['ipAddresses'].find { |address| address['type'] == 'PRIVATE' }['ipAddress']
|
195
|
+
public_ip = json['ipAddresses'].find { |address| address['type'] == 'PRIMARY' }['ipAddress']
|
196
|
+
{ private: private_ip, public: public_ip }
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
205
200
|
def write_pgbouncer_yaml
|
206
201
|
# TODO: Clean this up by moving into a proper templated yaml file
|
207
202
|
pgbouncer_yaml = <<-FOO
|
208
203
|
---
|
209
|
-
apiVersion:
|
204
|
+
apiVersion: apps/v1
|
210
205
|
kind: Deployment
|
211
206
|
metadata:
|
212
207
|
name: #{name}-pgbouncer
|
@@ -217,6 +212,11 @@ metadata:
|
|
217
212
|
database: #{name}
|
218
213
|
spec:
|
219
214
|
replicas: 2
|
215
|
+
selector:
|
216
|
+
matchLabels:
|
217
|
+
app: #{app}
|
218
|
+
tier: #{pgbouncer_tier}
|
219
|
+
database: #{name}
|
220
220
|
strategy:
|
221
221
|
type: RollingUpdate
|
222
222
|
rollingUpdate:
|
@@ -236,8 +236,6 @@ spec:
|
|
236
236
|
- containerPort: 6432
|
237
237
|
protocol: TCP
|
238
238
|
envFrom:
|
239
|
-
- configMapRef:
|
240
|
-
name: #{pgbouncer_configs_name}
|
241
239
|
- secretRef:
|
242
240
|
name: #{pgbouncer_secret_name}
|
243
241
|
env:
|
@@ -246,7 +244,7 @@ spec:
|
|
246
244
|
- name: "PGDATABASE"
|
247
245
|
value: "#{@database_name || default_database_name}"
|
248
246
|
- name: "DB_HOST"
|
249
|
-
value: "
|
247
|
+
value: "#{ips[:private]}" # private IP for #{name}
|
250
248
|
- name: "DB_PORT"
|
251
249
|
value: "5432"
|
252
250
|
- name: "LISTEN_PORT"
|
@@ -287,33 +285,10 @@ spec:
|
|
287
285
|
requests:
|
288
286
|
cpu: 100m
|
289
287
|
memory: 300Mi
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
- --dir=/cloudsql
|
295
|
-
- -instances=#{context[:project]}:#{context[:region]}:#{name}=tcp:5432
|
296
|
-
- -credential_file=/secrets/cloudsql/credentials.json
|
297
|
-
ports:
|
298
|
-
- containerPort: 5432
|
299
|
-
protocol: TCP
|
300
|
-
volumeMounts:
|
301
|
-
- name: cloudsql-credentials
|
302
|
-
mountPath: /secrets/cloudsql
|
303
|
-
readOnly: true
|
304
|
-
- name: ssl-certs
|
305
|
-
mountPath: /etc/ssl/certs
|
306
|
-
- name: cloudsql
|
307
|
-
mountPath: /cloudsql
|
308
|
-
volumes:
|
309
|
-
- name: cloudsql-credentials
|
310
|
-
secret:
|
311
|
-
secretName: cloudsql-credentials
|
312
|
-
- name: cloudsql
|
313
|
-
emptyDir:
|
314
|
-
- name: ssl-certs
|
315
|
-
hostPath:
|
316
|
-
path: /etc/ssl/certs
|
288
|
+
lifecycle:
|
289
|
+
preStop:
|
290
|
+
exec:
|
291
|
+
command: ["/bin/sh", "-c", "killall -INT pgbouncer && sleep 20"]
|
317
292
|
---
|
318
293
|
apiVersion: v1
|
319
294
|
kind: Service
|
@@ -324,12 +299,11 @@ metadata:
|
|
324
299
|
app: #{app}
|
325
300
|
tier: #{pgbouncer_tier}
|
326
301
|
spec:
|
327
|
-
type:
|
302
|
+
type: ClusterIP
|
328
303
|
ports:
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
nodePort: 0
|
304
|
+
- protocol: TCP
|
305
|
+
port: 6432
|
306
|
+
targetPort: 6432
|
333
307
|
selector:
|
334
308
|
app: #{app}
|
335
309
|
tier: #{pgbouncer_tier}
|
data/lib/seira/db.rb
CHANGED
@@ -1,13 +1,14 @@
|
|
1
1
|
require 'securerandom'
|
2
2
|
require 'English'
|
3
3
|
|
4
|
+
require_relative 'db/alter_proxyuser_roles'
|
4
5
|
require_relative 'db/create'
|
5
6
|
|
6
7
|
module Seira
|
7
8
|
class Db
|
8
9
|
include Seira::Commands
|
9
10
|
|
10
|
-
VALID_ACTIONS = %w[help create delete list restart connect ps kill analyze create-readonly-user psql table-sizes index-sizes vacuum unused-indexes unused-indices user-connections info].freeze
|
11
|
+
VALID_ACTIONS = %w[help create delete list restart connect ps kill analyze create-readonly-user psql table-sizes index-sizes vacuum unused-indexes unused-indices user-connections info alter-proxyuser-roles].freeze
|
11
12
|
SUMMARY = "Manage your Cloud SQL Postgres databases.".freeze
|
12
13
|
|
13
14
|
attr_reader :app, :action, :args, :context
|
@@ -55,6 +56,8 @@ module Seira
|
|
55
56
|
run_user_connections
|
56
57
|
when 'info'
|
57
58
|
run_info
|
59
|
+
when 'alter-proxyuser-roles'
|
60
|
+
run_alter_proxyuser_roles
|
58
61
|
else
|
59
62
|
fail "Unknown command encountered"
|
60
63
|
end
|
@@ -78,22 +81,23 @@ module Seira
|
|
78
81
|
puts SUMMARY
|
79
82
|
puts "\n"
|
80
83
|
puts <<~HELPTEXT
|
81
|
-
analyze:
|
82
|
-
connect:
|
83
|
-
create:
|
84
|
-
create-readonly-user:
|
85
|
-
delete:
|
86
|
-
index-sizes:
|
87
|
-
info:
|
88
|
-
kill:
|
89
|
-
list:
|
90
|
-
ps:
|
91
|
-
psql:
|
92
|
-
restart:
|
93
|
-
table-sizes:
|
94
|
-
unused-indexes:
|
95
|
-
user-connections:
|
96
|
-
vacuum:
|
84
|
+
analyze: Display database performance information
|
85
|
+
connect: Open a psql command prompt via gcloud connect. You will be shown the password needed before the prompt opens.
|
86
|
+
create: Create a new postgres instance in cloud sql. Supports creating replicas and other numerous flags.
|
87
|
+
create-readonly-user: Create a database user named by --username=<name> with only SELECT access privileges
|
88
|
+
delete: Delete a postgres instance from cloud sql. Use with caution, and remove all kubernetes configs first.
|
89
|
+
index-sizes: List sizes of all indexes in the database
|
90
|
+
info: Summarize all database instances for the app
|
91
|
+
kill: Kill a query
|
92
|
+
list: List all postgres instances.
|
93
|
+
ps: List running queries
|
94
|
+
psql: Open a psql prompt via kubectl exec into a pgbouncer pod.
|
95
|
+
restart: Fully restart the database.
|
96
|
+
table-sizes: List sizes of all tables in the database
|
97
|
+
unused-indexes: Show indexes with zero or low usage
|
98
|
+
user-connections: List number of connections per user
|
99
|
+
vacuum: Run a VACUUM ANALYZE
|
100
|
+
alter-proxyuser-roles: Update NOCREATEDB and NOCREATEROLE roles for proxyuser in cloud sql.
|
97
101
|
HELPTEXT
|
98
102
|
end
|
99
103
|
|
@@ -101,6 +105,10 @@ module Seira
|
|
101
105
|
Seira::Db::Create.new(app: app, action: action, args: args, context: context).run(existing_instances)
|
102
106
|
end
|
103
107
|
|
108
|
+
def run_alter_proxyuser_roles
|
109
|
+
Seira::Db::AlterProxyuserRoles.new(app: app, action: action, args: args, context: context).run
|
110
|
+
end
|
111
|
+
|
104
112
|
def run_delete
|
105
113
|
name = "#{app}-#{args[0]}"
|
106
114
|
if gcloud("sql instances delete #{name}", context: context, format: :boolean)
|
data/lib/seira/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: seira
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.5.
|
4
|
+
version: 0.5.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Scott Ringwelski
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-12-
|
11
|
+
date: 2018-12-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: highline
|
@@ -124,6 +124,7 @@ files:
|
|
124
124
|
- lib/seira/commands/gcloud.rb
|
125
125
|
- lib/seira/commands/kubectl.rb
|
126
126
|
- lib/seira/db.rb
|
127
|
+
- lib/seira/db/alter_proxyuser_roles.rb
|
127
128
|
- lib/seira/db/create.rb
|
128
129
|
- lib/seira/jobs.rb
|
129
130
|
- lib/seira/memcached.rb
|