seira 0.5.1 → 0.5.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|