pghero 2.0.3 → 2.0.4

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of pghero might be problematic. Click here for more details.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a1a3cb7c5c2090aa6b4dcc0fb11aca000945a5a4
4
- data.tar.gz: 2304979bb7676c7a346bfbd490e697f16379f8bb
3
+ metadata.gz: e94afa4fd9aa4ce59b5a97d78b9d15ff48ebd669
4
+ data.tar.gz: 1974a3612f8eae97a888af4a25e965571a2e449e
5
5
  SHA512:
6
- metadata.gz: cb6cc9c80f2ea049225b3f8d4da5eefb7d3ac754a33ba6da644fff7adbb385626f4f5967fb9e91bb3328575d42e52a064c9d7d5cef43273b8d7ac894155c4197
7
- data.tar.gz: 964c90c704e2049d3d2a47cad1479146409a0ad49ffa7a1436dc913ac8cbb992dd101cf3021ba288dbfc45736bd2c3b4f687627fbd9b5373fe24bb54cb631a5e
6
+ metadata.gz: 6fe161c323e6916ea3fa9c19103cfb17b3403e313b6889ed7be15c2cd7a6d8ff86ab22e667a82a05f0cd2ee471f359097f9b6626e5ce94aa586cff5cf32e7042
7
+ data.tar.gz: 5f6db96bd7b69f7a889af3f30b24c8f2964b8b22b937426a067c78a49af5b89461a7cc2ee2be55f01f6406a756e65d5819eca478de9d13bee2b97682ac24fafa
data/CHANGELOG.md CHANGED
@@ -1,3 +1,8 @@
1
+ ## 2.0.4
2
+
3
+ - Fixed `AssetNotPrecompiled` error
4
+ - Do not silently ignore sequence danger when user does not have permissions
5
+
1
6
  ## 2.0.3
2
7
 
3
8
  - Added SQL to recreate invalid indexes
@@ -33,7 +33,16 @@ module PgHero
33
33
  @good_total_connections = @total_connections < @database.total_connections_threshold
34
34
 
35
35
  @transaction_id_danger = @database.transaction_id_danger(threshold: 1500000000)
36
- @sequence_danger = @database.sequence_danger(threshold: (params[:sequence_threshold] || 0.9).to_f)
36
+
37
+ begin
38
+ @sequence_danger = @database.sequence_danger(threshold: (params[:sequence_threshold] || 0.9).to_f)
39
+ rescue ActiveRecord::StatementInvalid => e
40
+ if (m = /permission denied for [^:]+/.match(e.message))
41
+ @sequence_danger_error = m[0]
42
+ else
43
+ raise
44
+ end
45
+ end
37
46
 
38
47
  @indexes = @database.indexes
39
48
  @invalid_indexes = @indexes.select { |i| !i[:valid] }
@@ -81,7 +90,7 @@ module PgHero
81
90
  @unused_index_names = Set.new(@unused_indexes.map { |r| r[:index] })
82
91
  @show_migrations = PgHero.show_migrations
83
92
  @system_stats_enabled = @database.system_stats_enabled?
84
- @index_bloat = @database.index_bloat
93
+ @index_bloat = [] # @database.index_bloat
85
94
  end
86
95
 
87
96
  def relation_space
@@ -226,7 +235,7 @@ module PgHero
226
235
  ""
227
236
  end
228
237
  @explanation = @database.explain("#{prefix}#{@query}")
229
- @suggested_index = @database.suggested_indexes(queries: [@query]).first
238
+ @suggested_index = @database.suggested_indexes(queries: [@query]).first if @database.suggested_indexes_enabled?
230
239
  @visualize = params[:commit] == "Visualize"
231
240
  rescue ActiveRecord::StatementInvalid => e
232
241
  @error = e.message
@@ -47,8 +47,10 @@
47
47
  Vacuuming healthy
48
48
  <% end %>
49
49
  </div>
50
- <div class="alert alert-<%= @sequence_danger.empty? ? "success" : "warning" %>">
51
- <% if @sequence_danger.any? %>
50
+ <div class="alert alert-<%= @sequence_danger && @sequence_danger.empty? ? "success" : "warning" %>">
51
+ <% if !@sequence_danger %>
52
+ Error checking for columns near integer overflow: <%= @sequence_danger_error %>
53
+ <% elsif @sequence_danger.any? %>
52
54
  <%= pluralize(@sequence_danger.size, "columns") %> approaching overflow
53
55
  <% else %>
54
56
  No columns near integer overflow
@@ -197,7 +199,7 @@
197
199
  </div>
198
200
  <% end %>
199
201
 
200
- <% if @sequence_danger.any? %>
202
+ <% if @sequence_danger && @sequence_danger.any? %>
201
203
  <div class="content">
202
204
  <h2>Columns Near Overflow</h2>
203
205
  <p>Consider changing columns to bigint to support a larger range of values.</p>
data/guides/Docker.md CHANGED
@@ -72,6 +72,18 @@ databases:
72
72
  url: postgres://...
73
73
  ```
74
74
 
75
+ ## Permissions
76
+
77
+ We recommend [setting up a dedicated user](Permissions.md) for PgHero.
78
+
79
+ ## Security
80
+
81
+ And basic authentication with:
82
+
83
+ ```sh
84
+ docker run -e PGHERO_USERNAME=link -e PGHERO_PASSWORD=hyrule ...
85
+ ```
86
+
75
87
  ## Credits
76
88
 
77
89
  Thanks to [Brian Morton](https://github.com/bmorton) for the [original Docker image](https://github.com/bmorton/pghero_solo).
data/guides/Linux.md CHANGED
@@ -187,6 +187,7 @@ Schedule the task below to run once a day.
187
187
 
188
188
  ```sh
189
189
  sudo pghero run rake pghero:capture_space_stats
190
+ ```
190
191
 
191
192
  ## System Stats
192
193
 
@@ -217,6 +218,10 @@ cat pghero.yml | sudo pghero run sh -c "cat > config/pghero.yml"
217
218
  sudo service pghero restart
218
219
  ```
219
220
 
221
+ ## Permissions
222
+
223
+ We recommend [setting up a dedicated user](Permissions.md) for PgHero.
224
+
220
225
  ## Customize
221
226
 
222
227
  Minimum time for long running queries
@@ -0,0 +1,57 @@
1
+ # Permissions
2
+
3
+ For security, Postgres doesn’t allow you to see queries from other users without being a superuser. However, you likely don’t want to run PgHero as a superuser. You can use `SECURITY DEFINER` to give non-superusers access to superuser functions.
4
+
5
+ With a superuser, run:
6
+
7
+ ```sql
8
+ CREATE SCHEMA pghero;
9
+
10
+ -- view queries
11
+ CREATE OR REPLACE FUNCTION pghero.pg_stat_activity() RETURNS SETOF pg_stat_activity AS
12
+ $$
13
+ SELECT * FROM pg_catalog.pg_stat_activity;
14
+ $$ LANGUAGE sql VOLATILE SECURITY DEFINER;
15
+
16
+ CREATE VIEW pghero.pg_stat_activity AS SELECT * FROM pghero.pg_stat_activity();
17
+
18
+ -- kill queries
19
+ CREATE OR REPLACE FUNCTION pghero.pg_terminate_backend(pid int) RETURNS boolean AS
20
+ $$
21
+ SELECT * FROM pg_catalog.pg_terminate_backend(pid);
22
+ $$ LANGUAGE sql VOLATILE SECURITY DEFINER;
23
+
24
+ -- query stats
25
+ CREATE OR REPLACE FUNCTION pghero.pg_stat_statements() RETURNS SETOF pg_stat_statements AS
26
+ $$
27
+ SELECT * FROM public.pg_stat_statements;
28
+ $$ LANGUAGE sql VOLATILE SECURITY DEFINER;
29
+
30
+ CREATE VIEW pghero.pg_stat_statements AS SELECT * FROM pghero.pg_stat_statements();
31
+
32
+ -- query stats reset
33
+ CREATE OR REPLACE FUNCTION pghero.pg_stat_statements_reset() RETURNS void AS
34
+ $$
35
+ SELECT public.pg_stat_statements_reset();
36
+ $$ LANGUAGE sql VOLATILE SECURITY DEFINER;
37
+
38
+ -- suggested indexes
39
+ CREATE OR REPLACE FUNCTION pghero.pg_stats() RETURNS
40
+ TABLE(schemaname name, tablename name, attname name, null_frac real, avg_width integer, n_distinct real) AS
41
+ $$
42
+ SELECT schemaname, tablename, attname, null_frac, avg_width, n_distinct FROM pg_catalog.pg_stats;
43
+ $$ LANGUAGE sql VOLATILE SECURITY DEFINER;
44
+
45
+ CREATE VIEW pghero.pg_stats AS SELECT * FROM pghero.pg_stats();
46
+
47
+ -- create user
48
+ CREATE ROLE pghero WITH LOGIN ENCRYPTED PASSWORD 'secret';
49
+ GRANT CONNECT ON DATABASE <dbname> TO pghero;
50
+ ALTER ROLE pghero SET search_path = pghero, pg_catalog, public;
51
+ GRANT USAGE ON SCHEMA pghero TO pghero;
52
+ GRANT SELECT ON ALL TABLES IN SCHEMA pghero TO pghero;
53
+ ```
54
+
55
+ ## Thanks
56
+
57
+ A big thanks to [pganalyze](https://github.com/pganalyze/collector#setting-up-a-restricted-monitoring-user) for coming up with this approach for their collector.
data/guides/Rails.md CHANGED
@@ -125,6 +125,10 @@ databases:
125
125
  url: <%= ENV["REPLICA_DATABASE_URL"] %>
126
126
  ```
127
127
 
128
+ ## Permissions
129
+
130
+ We recommend [setting up a dedicated user](Permissions.md) for PgHero.
131
+
128
132
  ## Customize
129
133
 
130
134
  Minimum time for long running queries
@@ -68,7 +68,13 @@ module PgHero
68
68
  def self.name
69
69
  "PgHero::Connection::Database#{object_id}"
70
70
  end
71
- establish_connection(url) if url
71
+ case url
72
+ when String
73
+ url = "#{url}#{url.include?("?") ? "&" : "?"}connect_timeout=2" unless url.include?("connect_timeout=")
74
+ when Hash
75
+ url[:connect_timeout] ||= 2
76
+ end
77
+ establish_connection url if url
72
78
  end
73
79
  end
74
80
  end
data/lib/pghero/engine.rb CHANGED
@@ -8,10 +8,12 @@ module PgHero
8
8
  if defined?(Sprockets) && Sprockets::VERSION >= "4"
9
9
  app.config.assets.precompile << "pghero/application.js"
10
10
  app.config.assets.precompile << "pghero/application.css"
11
+ app.config.assets.precompile << "pghero/favicon.png"
11
12
  else
12
13
  # use a proc instead of a string
13
14
  app.config.assets.precompile << proc { |path| path == "pghero/application.js" }
14
15
  app.config.assets.precompile << proc { |path| path == "pghero/application.css" }
16
+ app.config.assets.precompile << proc { |path| path == "pghero/favicon.png" }
15
17
  end
16
18
  end
17
19
 
@@ -4,21 +4,29 @@ module PgHero
4
4
  def sequences
5
5
  sequences = select_all <<-SQL
6
6
  SELECT
7
- sequence_schema AS schema,
8
- table_name AS table,
9
- column_name AS column,
10
- c.data_type AS column_type,
11
- CASE WHEN c.data_type = 'integer' THEN 2147483647::bigint ELSE maximum_value::bigint END AS max_value,
12
- sequence_name AS sequence
7
+ n.nspname AS schema,
8
+ c.relname AS table,
9
+ attname AS column,
10
+ format_type(a.atttypid, a.atttypmod) AS column_type,
11
+ CASE WHEN format_type(a.atttypid, a.atttypmod) = 'integer' THEN 2147483647::bigint ELSE (pg_sequence_parameters(s.oid)).maximum_value::bigint END AS max_value,
12
+ s.relname AS sequence
13
13
  FROM
14
- information_schema.columns c
14
+ pg_catalog.pg_attribute a
15
15
  INNER JOIN
16
- information_schema.sequences iss ON iss.sequence_name = regexp_replace(c.column_default, '^nextval\\(''(.*)''\\:\\:regclass\\)$', '\\1')
16
+ pg_catalog.pg_class c ON c.oid = a.attrelid
17
+ INNER JOIN
18
+ pg_catalog.pg_namespace n ON n.oid = c.relnamespace
19
+ LEFT JOIN
20
+ pg_catalog.pg_attrdef d ON (a.attrelid, a.attnum) = (d.adrelid, d.adnum)
21
+ INNER JOIN
22
+ pg_catalog.pg_class s ON s.relkind = 'S'
23
+ AND s.relname = regexp_replace(d.adsrc, '^nextval\\(''(.*)''\\:\\:regclass\\)$', '\\1')
17
24
  WHERE
18
- column_default LIKE 'nextval%'
19
- AND table_catalog = current_database()
25
+ NOT a.attisdropped
26
+ AND a.attnum > 0
27
+ AND d.adsrc LIKE 'nextval%'
20
28
  ORDER BY
21
- sequence_name ASC
29
+ s.relname ASC
22
30
  SQL
23
31
 
24
32
  select_all(sequences.map { |s| "SELECT last_value FROM #{s[:sequence]}" }.join(" UNION ALL ")).each_with_index do |row, i|
@@ -1,3 +1,3 @@
1
1
  module PgHero
2
- VERSION = "2.0.3"
2
+ VERSION = "2.0.4"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pghero
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.3
4
+ version: 2.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Kane
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-08-23 00:00:00.000000000 Z
11
+ date: 2017-08-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -156,6 +156,7 @@ files:
156
156
  - guides/Docker.md
157
157
  - guides/Heroku.md
158
158
  - guides/Linux.md
159
+ - guides/Permissions.md
159
160
  - guides/Query-Stats.md
160
161
  - guides/Rails.md
161
162
  - guides/Suggested-Indexes.md
@@ -222,6 +223,7 @@ test_files:
222
223
  - guides/Docker.md
223
224
  - guides/Heroku.md
224
225
  - guides/Linux.md
226
+ - guides/Permissions.md
225
227
  - guides/Query-Stats.md
226
228
  - guides/Rails.md
227
229
  - guides/Suggested-Indexes.md