redis_ui_rails 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.env.example +1 -0
- data/.envrc +3 -0
- data/.gitignore +10 -0
- data/.rspec.example +3 -0
- data/Gemfile +5 -0
- data/README.md +86 -0
- data/app/assets/config/manifest.js +1 -0
- data/app/assets/images/redis_ui_rails/.keep +0 -0
- data/app/assets/stylesheets/redis_ui_rails/application.css +26 -0
- data/app/controllers/redis_ui_rails/application_controller.rb +4 -0
- data/app/controllers/redis_ui_rails/configs_controller.rb +11 -0
- data/app/controllers/redis_ui_rails/dashboard_controller.rb +7 -0
- data/app/controllers/redis_ui_rails/instances_controller.rb +12 -0
- data/app/controllers/redis_ui_rails/keys_controller.rb +12 -0
- data/app/views/layouts/redis_ui_rails/application.html.erb +13 -0
- data/app/views/redis_ui_rails/configs/show.html.erb +18 -0
- data/app/views/redis_ui_rails/dashboard/index.html.erb +23 -0
- data/app/views/redis_ui_rails/instances/show.html.erb +35 -0
- data/app/views/redis_ui_rails/keys/show.html.erb +24 -0
- data/app/views/shared/_instance_hero.html.erb +13 -0
- data/config/routes.rb +8 -0
- data/lib/redis_ui_rails/config.rb +64 -0
- data/lib/redis_ui_rails/engine.rb +12 -0
- data/lib/redis_ui_rails/redis_instance.rb +54 -0
- data/lib/redis_ui_rails/version.rb +3 -0
- data/lib/redis_ui_rails.rb +24 -0
- data/redis_ui_rails.gemspec +30 -0
- data/spec/feature_spec_helper.rb +9 -0
- data/spec/integration/dashboard_spec.rb +12 -0
- data/spec/integration/instance_config_spec.rb +17 -0
- data/spec/integration/instance_keys_spec.rb +17 -0
- data/spec/redis_ui_rails/config_spec.rb +60 -0
- data/spec/redis_ui_rails/redis_instance_spec.rb +117 -0
- data/spec/redis_ui_rails_spec.rb +29 -0
- data/spec/spec_helper.rb +21 -0
- data/spec/support/dummy/app/assets/config/manifest.js +2 -0
- data/spec/support/dummy/app/assets/images/.keep +0 -0
- data/spec/support/dummy/app/assets/stylesheets/application.css +15 -0
- data/spec/support/dummy/app/controllers/application_controller.rb +2 -0
- data/spec/support/dummy/app/javascript/packs/application.js +14 -0
- data/spec/support/dummy/app/views/layouts/application.html.erb +15 -0
- data/spec/support/dummy/bin/rails +4 -0
- data/spec/support/dummy/bin/rake +4 -0
- data/spec/support/dummy/bin/setup +30 -0
- data/spec/support/dummy/config/application.rb +16 -0
- data/spec/support/dummy/config/boot.rb +5 -0
- data/spec/support/dummy/config/database.yml +11 -0
- data/spec/support/dummy/config/environment.rb +8 -0
- data/spec/support/dummy/config/environments/development.rb +76 -0
- data/spec/support/dummy/config/environments/production.rb +120 -0
- data/spec/support/dummy/config/environments/test.rb +59 -0
- data/spec/support/dummy/config/initializers/assets.rb +12 -0
- data/spec/support/dummy/config/initializers/backtrace_silencers.rb +8 -0
- data/spec/support/dummy/config/initializers/cookies_serializer.rb +5 -0
- data/spec/support/dummy/config/initializers/filter_parameter_logging.rb +6 -0
- data/spec/support/dummy/config/initializers/redis_ui_rails.rb +12 -0
- data/spec/support/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/support/dummy/config/locales/en.yml +33 -0
- data/spec/support/dummy/config/puma.rb +43 -0
- data/spec/support/dummy/config/routes.rb +3 -0
- data/spec/support/dummy/config.ru +6 -0
- data/spec/support/dummy/lib/assets/.keep +0 -0
- data/spec/support/dummy/log/.keep +0 -0
- data/spec/support/dummy/public/404.html +67 -0
- data/spec/support/dummy/public/422.html +67 -0
- data/spec/support/dummy/public/500.html +66 -0
- data/spec/support/dummy/public/apple-touch-icon-precomposed.png +0 -0
- data/spec/support/dummy/public/apple-touch-icon.png +0 -0
- data/spec/support/dummy/public/favicon.ico +0 -0
- metadata +279 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 29709da81ecbe44cd27fe2df64d974f2b3007ecbb5109ebb5174166e73d923d7
|
4
|
+
data.tar.gz: 3b7760666e5850d253e8c9e5db44f12ff2fd03383b3ccc331c37b9b5a0084dfe
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 868503307acb61f6aacbbd9614a1c13c9408bfc66c27f104a5d1049f16909fedf113a43cdcccfcc7a779fc97a65f571e67d3e7d8ebfb98f4fee0a37196de5ab7
|
7
|
+
data.tar.gz: 92c5d2236d3c3a34b927b976774aa2c070e36e0491f802047d775d952e789fdb0eafc15c59c09c15ecc4e682c5b23edbab50033a1169bf995588509d09546862
|
data/.env.example
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
LOG_LEVEL='debug'
|
data/.envrc
ADDED
data/.gitignore
ADDED
data/.rspec.example
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,86 @@
|
|
1
|
+
# RedisUiRails
|
2
|
+
|
3
|
+
A mountable UI Rails engine for inspecting your Redis instances. The teams that will get the most value out of this engine are teams that cannot use the Rails console to inspect their production Redis instances.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
1. Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
gem 'redis_ui_rails'
|
11
|
+
```
|
12
|
+
|
13
|
+
2. In `config/routes.rb`, mount the engine
|
14
|
+
|
15
|
+
```ruby
|
16
|
+
Rails.application.routes.draw do
|
17
|
+
mount RedisUiRails::Engine => "/redis_ui"
|
18
|
+
end
|
19
|
+
```
|
20
|
+
|
21
|
+
3. Precompile your assets
|
22
|
+
|
23
|
+
```bash
|
24
|
+
cd path/to/app/root
|
25
|
+
bundle exec rake assets:precompile
|
26
|
+
```
|
27
|
+
|
28
|
+
4. Configure your Redis UI engine.
|
29
|
+
|
30
|
+
Example:
|
31
|
+
|
32
|
+
```ruby
|
33
|
+
# config/initializers/redis_ui_rail.rb
|
34
|
+
|
35
|
+
# Each "instance" is a hash, with the following symbolized key structure:
|
36
|
+
# :id (required) The ID used in the URL for this instance.
|
37
|
+
# :name (required) The name that differentiates this Redis instance from others.
|
38
|
+
# :url (required) The URL of the redis instance.
|
39
|
+
# :resource_links (optional) Quick links to resources related to this instance.
|
40
|
+
# :enabled (optional) Allows enabling per environment. Defaults to true.
|
41
|
+
#
|
42
|
+
RedisUiRails.configure do |config|
|
43
|
+
config.redis_instances = [
|
44
|
+
{
|
45
|
+
id: :local,
|
46
|
+
name: "Local Queue and Cache", # many apps share a queue and cache Redis locally
|
47
|
+
url: ENV["REDIS_URL"],
|
48
|
+
enabled: Rails.env.development? || Rails.env.test?
|
49
|
+
},
|
50
|
+
{
|
51
|
+
id: :cache,
|
52
|
+
name: "Cache",
|
53
|
+
url: ENV.fetch("REDIS_CACHE_URL"), # many apps have separate queue and cache Redis instances in production
|
54
|
+
resource_links: [
|
55
|
+
{
|
56
|
+
label: "Custom Datadog Dashboard",
|
57
|
+
url: "https://myorg.datadoghq.com/path/to/your/dashhboard"
|
58
|
+
}
|
59
|
+
],
|
60
|
+
enabled: Rails.env.production?
|
61
|
+
}
|
62
|
+
]
|
63
|
+
end
|
64
|
+
```
|
65
|
+
|
66
|
+
## Local Development
|
67
|
+
|
68
|
+
1. Requirements:
|
69
|
+
|
70
|
+
- Ruby >= 3.0
|
71
|
+
- Direnv (don't forget your [rc file hook](https://direnv.net/docs/installation.html))
|
72
|
+
|
73
|
+
2. Initial setup
|
74
|
+
|
75
|
+
```
|
76
|
+
bundle install
|
77
|
+
cp .rspec.example .rspec
|
78
|
+
cp .env.example .env
|
79
|
+
direnv allow
|
80
|
+
```
|
81
|
+
|
82
|
+
3. Run tests
|
83
|
+
|
84
|
+
```
|
85
|
+
bundle exec rspec spec
|
86
|
+
```
|
@@ -0,0 +1 @@
|
|
1
|
+
//= link_directory ../stylesheets .css
|
File without changes
|
@@ -0,0 +1,26 @@
|
|
1
|
+
/*
|
2
|
+
* This is a manifest file that'll be compiled into application.css, which will include all the files
|
3
|
+
* listed below.
|
4
|
+
*
|
5
|
+
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
|
6
|
+
* or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
|
7
|
+
*
|
8
|
+
* You're free to add application-wide styles to this file and they'll appear at the bottom of the
|
9
|
+
* compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
|
10
|
+
* files in this directory. Styles in this file should be added after the last require_* statement.
|
11
|
+
* It is generally better to create a new file per style scope.
|
12
|
+
*
|
13
|
+
*= require_tree .
|
14
|
+
*= require_self
|
15
|
+
*/
|
16
|
+
.breadcrumb {
|
17
|
+
margin-bottom: 0 !important;
|
18
|
+
padding-top: 1rem;
|
19
|
+
padding-bottom: 1rem;
|
20
|
+
padding-left: 3rem;
|
21
|
+
padding-right: 3rem;
|
22
|
+
}
|
23
|
+
|
24
|
+
.vertical-align {
|
25
|
+
vertical-align: -webkit-baseline-middle
|
26
|
+
}
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module RedisUiRails
|
2
|
+
class ConfigsController < ApplicationController
|
3
|
+
def show
|
4
|
+
@instance = RedisUiRails.config.redis_instances.detect { |obj| params[:id].to_s == obj.id.to_s }
|
5
|
+
|
6
|
+
raise "Missing instance for params: #{params.inspect}. Options are: #{RedisUiRails.config.redis_instances.map(&:id)}" if @instance.nil?
|
7
|
+
|
8
|
+
@redis = Redis.new(url: @instance.url(unredacted: true))
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module RedisUiRails
|
2
|
+
class InstancesController < ApplicationController
|
3
|
+
def show
|
4
|
+
@instance = RedisUiRails.config.redis_instances.detect { |obj| params[:id].to_s == obj.id.to_s }
|
5
|
+
|
6
|
+
raise "Missing instance for params: #{params.inspect}. Options are: #{RedisUiRails.config.redis_instances.map(&:id)}" if @instance.nil?
|
7
|
+
|
8
|
+
@redis = Redis.new(url: @instance.url(unredacted: true))
|
9
|
+
@sample_keys = 50.times.map { @redis.randomkey }
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module RedisUiRails
|
2
|
+
class KeysController < ApplicationController
|
3
|
+
def show
|
4
|
+
@instance = RedisUiRails.config.redis_instances.detect { |obj| params[:id].to_s == obj.id.to_s }
|
5
|
+
|
6
|
+
raise "Missing instance for params: #{params.inspect}. Options are: #{RedisUiRails.config.redis_instances.map(&:id)}" if @instance.nil?
|
7
|
+
|
8
|
+
@redis = Redis.new(url: @instance.url(unredacted: true))
|
9
|
+
@sample_keys = 50.times.map { @redis.randomkey }.uniq
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>Redis UI</title>
|
5
|
+
<%= csrf_meta_tags %>
|
6
|
+
<%= csp_meta_tag %>
|
7
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@0.9.4/css/bulma.min.css">
|
8
|
+
<%= stylesheet_link_tag "redis_ui_rails/application", media: "all" %>
|
9
|
+
</head>
|
10
|
+
<body>
|
11
|
+
<%= yield %>
|
12
|
+
</body>
|
13
|
+
</html>
|
@@ -0,0 +1,18 @@
|
|
1
|
+
<nav class="breadcrumb" aria-label="breadcrumbs">
|
2
|
+
<ul>
|
3
|
+
<li><%= link_to "Dashboard", root_path %></li>
|
4
|
+
<li><%= link_to "Instance Overview", instance_path(@instance.id) %></li>
|
5
|
+
<li class="is-active"><a href="#" aria-current="page">Server Config</a></li>
|
6
|
+
</ul>
|
7
|
+
</nav>
|
8
|
+
|
9
|
+
<%= render "shared/instance_hero" %>
|
10
|
+
|
11
|
+
<section class="section">
|
12
|
+
<h1 class="title">Server Config</h1>
|
13
|
+
<ul>
|
14
|
+
<% @redis.info.except("redis_version").sort.each do |k, v| %>
|
15
|
+
<li><b><%= k %></b>: <%= v %></li>
|
16
|
+
<% end %>
|
17
|
+
</ul>
|
18
|
+
</section>
|
@@ -0,0 +1,23 @@
|
|
1
|
+
<nav class="breadcrumb" aria-label="breadcrumbs">
|
2
|
+
<ul>
|
3
|
+
<li>Dashboard</li>
|
4
|
+
</ul>
|
5
|
+
</nav>
|
6
|
+
|
7
|
+
<section class="hero is-primary">
|
8
|
+
<div class="hero-body">
|
9
|
+
<h1 class="title">
|
10
|
+
[<%= Rails.env %>] Redis Dashboard
|
11
|
+
</h1>
|
12
|
+
</div>
|
13
|
+
</section>
|
14
|
+
|
15
|
+
<section class="section">
|
16
|
+
<h1>Redis Instances</h1>
|
17
|
+
<ul>
|
18
|
+
<% @redis_instances.each do |instance| %>
|
19
|
+
<br>
|
20
|
+
<li><%= link_to "#{instance.name} - #{instance.url}", instance_path(instance.id) %></li>
|
21
|
+
<% end %>
|
22
|
+
</ul>
|
23
|
+
</section>
|
@@ -0,0 +1,35 @@
|
|
1
|
+
<nav class="breadcrumb" aria-label="breadcrumbs">
|
2
|
+
<ul>
|
3
|
+
<li><%= link_to "Dashboard", root_path %></li>
|
4
|
+
<li class="is-active"><a href="#" aria-current="page">Instance Overview</a></li>
|
5
|
+
</ul>
|
6
|
+
</nav>
|
7
|
+
|
8
|
+
<%= render "shared/instance_hero" %>
|
9
|
+
|
10
|
+
<section class="section">
|
11
|
+
<%= link_to instance_config_path(@instance.id) do %>
|
12
|
+
<div style="color: black;">
|
13
|
+
<button class="button is-info">Config</button>
|
14
|
+
<span class="vertical-align">View Redis server configuration details</span>
|
15
|
+
</div>
|
16
|
+
<% end %>
|
17
|
+
<br>
|
18
|
+
<%= link_to instance_keys_path(@instance.id) do %>
|
19
|
+
<div style="color: black;">
|
20
|
+
<button class="button is-warning">Keys</button>
|
21
|
+
<span class="vertical-align">View a sample of keys currently stored in this Redis.</span>
|
22
|
+
</div>
|
23
|
+
<% end %>
|
24
|
+
</section>
|
25
|
+
|
26
|
+
<section class="section">
|
27
|
+
<h2 class="title">Resource Links</h2>
|
28
|
+
<div class="content">
|
29
|
+
<ul>
|
30
|
+
<% @instance.resource_links.each do |resource_link| %>
|
31
|
+
<li><a href="<%= resource_link[:url] %>" target="_blank"><%= resource_link[:label] %></a></li>
|
32
|
+
<% end %>
|
33
|
+
</ul>
|
34
|
+
</div>
|
35
|
+
</section>
|
@@ -0,0 +1,24 @@
|
|
1
|
+
<nav class="breadcrumb" aria-label="breadcrumbs">
|
2
|
+
<ul>
|
3
|
+
<li><%= link_to "Dashboard", root_path %></li>
|
4
|
+
<li><%= link_to "Instance Overview", instance_path(@instance.id) %></li>
|
5
|
+
<li class="is-active"><a href="#" aria-current="page">Keys</a></li>
|
6
|
+
</ul>
|
7
|
+
</nav>
|
8
|
+
|
9
|
+
<%= render "shared/instance_hero" %>
|
10
|
+
|
11
|
+
<section class="section">
|
12
|
+
<h1 class="title">Sample keys</h1>
|
13
|
+
<%= link_to instance_keys_path(@instance.id) do %>
|
14
|
+
<div style="color: black;">
|
15
|
+
<button class="button is-info">Refresh</button>
|
16
|
+
</div>
|
17
|
+
<% end %>
|
18
|
+
<br>
|
19
|
+
<ul>
|
20
|
+
<% @sample_keys.sort.each do |key| %>
|
21
|
+
<li><%= key %></li>
|
22
|
+
<% end %>
|
23
|
+
</ul>
|
24
|
+
</section>
|
@@ -0,0 +1,13 @@
|
|
1
|
+
<section class="hero is-primary">
|
2
|
+
<div class="hero-body">
|
3
|
+
<h1 class="title">
|
4
|
+
[<%= Rails.env %>] Redis instance: '<%= @instance.name %>'
|
5
|
+
</h1>
|
6
|
+
<p class="subtitle">
|
7
|
+
redis v<%= @redis.info["redis_version"] %>
|
8
|
+
</p>
|
9
|
+
<p class="subtitle">
|
10
|
+
URL: </b><%= @instance.url %>
|
11
|
+
</p>
|
12
|
+
</div>
|
13
|
+
</section>
|
data/config/routes.rb
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
module RedisUiRails
|
2
|
+
class Config
|
3
|
+
include ActiveModel::Validations
|
4
|
+
|
5
|
+
validate :validate_redis_instances
|
6
|
+
validate :validate_unique_ids
|
7
|
+
validate :validate_at_least_one_configured
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
self.all_redis_instances = []
|
11
|
+
end
|
12
|
+
|
13
|
+
def redis_instances=(arr)
|
14
|
+
self.all_redis_instances = arr
|
15
|
+
end
|
16
|
+
|
17
|
+
def redis_instances
|
18
|
+
all_redis_instances.select(&:enabled?)
|
19
|
+
end
|
20
|
+
|
21
|
+
def ingest
|
22
|
+
self.redis_instances = Array(all_redis_instances).compact.map do |redis_instance|
|
23
|
+
RedisInstance.new(redis_instance.symbolize_keys)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
attr_accessor :all_redis_instances
|
30
|
+
|
31
|
+
def validate_redis_instances
|
32
|
+
unless all_redis_instances.is_a?(Array)
|
33
|
+
return errors.add(:redis_instances, "must be an array")
|
34
|
+
end
|
35
|
+
|
36
|
+
unless all_redis_instances.all?(&:valid?)
|
37
|
+
error_msgs = all_redis_instances.map(&:errors).flatten.map(&:full_messages).flatten
|
38
|
+
|
39
|
+
msg = <<~MSG
|
40
|
+
1 or more Redis UI instance hashes are not valid in the configuration.
|
41
|
+
#{error_msgs.join(", ")}
|
42
|
+
MSG
|
43
|
+
errors.add(:base, msg)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def validate_unique_ids
|
48
|
+
duplicate_ids = all_redis_instances.map(&:id)
|
49
|
+
.tally
|
50
|
+
.select { |id, count| count > 1 }
|
51
|
+
.map { |id, count| count }
|
52
|
+
|
53
|
+
return if duplicate_ids.empty?
|
54
|
+
|
55
|
+
errors.add(:base, "Duplicate Redis instance ids not allowed. Found: #{duplicate_ids.uniq}")
|
56
|
+
end
|
57
|
+
|
58
|
+
def validate_at_least_one_configured
|
59
|
+
return if all_redis_instances.size > 0
|
60
|
+
|
61
|
+
errors.add(:base, "No redis instances configured during initialization. At least one is required.")
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module RedisUiRails
|
2
|
+
class Engine < ::Rails::Engine
|
3
|
+
isolate_namespace RedisUiRails
|
4
|
+
|
5
|
+
initializer :assets, group: :all do |app|
|
6
|
+
config.assets.precompile << "redis_ui_rails/application.css"
|
7
|
+
config.assets.precompile << "redis_ui_rails/application.js"
|
8
|
+
config.assets.paths << root.join("assets", "stylesheets").to_s
|
9
|
+
config.assets.paths << root.join("assets", "javascripts").to_s
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module RedisUiRails
|
2
|
+
class RedisInstance
|
3
|
+
include ActiveModel::Validations
|
4
|
+
|
5
|
+
REQUIRED_OPTIONS_KEYS = [:url, :name, :id].freeze
|
6
|
+
|
7
|
+
validate :validate_options
|
8
|
+
validate :validate_resource_links
|
9
|
+
|
10
|
+
def initialize(hash)
|
11
|
+
self.options = hash.symbolize_keys
|
12
|
+
self.actual_url = options[:url]
|
13
|
+
self.name = options[:name]
|
14
|
+
self.id = options[:id]
|
15
|
+
self.resource_links = options[:resource_links] || []
|
16
|
+
self.enabled = options.key?(:enabled) ? options[:enabled] : true
|
17
|
+
end
|
18
|
+
attr_accessor :actual_url, :name, :id, :options, :resource_links
|
19
|
+
|
20
|
+
def enabled?
|
21
|
+
enabled
|
22
|
+
end
|
23
|
+
|
24
|
+
def url(unredacted: false)
|
25
|
+
return actual_url if unredacted
|
26
|
+
|
27
|
+
uri = URI(actual_url)
|
28
|
+
|
29
|
+
uri.host = uri.host.to_s.tr("0-9", "*") unless /localhost/.match?(uri.host.to_s)
|
30
|
+
|
31
|
+
uri.password = "*" if uri.user
|
32
|
+
|
33
|
+
uri.to_s
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
attr_accessor :enabled
|
39
|
+
|
40
|
+
def validate_options
|
41
|
+
return if (REQUIRED_OPTIONS_KEYS - options.keys).empty?
|
42
|
+
|
43
|
+
errors.add(:base, "Must have the following keys: '#{REQUIRED_OPTIONS_KEYS.join(", ")}'")
|
44
|
+
end
|
45
|
+
|
46
|
+
def validate_resource_links
|
47
|
+
return if resource_links.all? do |resource_link|
|
48
|
+
resource_link[:url].present? && resource_link[:label].present?
|
49
|
+
end
|
50
|
+
|
51
|
+
errors.add(:base, "All :resource_links must have :url and :label keys")
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require "singleton"
|
2
|
+
require "rails"
|
3
|
+
require "active_model"
|
4
|
+
require "forwardable"
|
5
|
+
require "uri"
|
6
|
+
require "redis"
|
7
|
+
|
8
|
+
require "redis_ui_rails/version"
|
9
|
+
require "redis_ui_rails/redis_instance"
|
10
|
+
require "redis_ui_rails/config"
|
11
|
+
require "redis_ui_rails/engine"
|
12
|
+
|
13
|
+
module RedisUiRails
|
14
|
+
def self.config
|
15
|
+
@config ||= Config.new
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.configure
|
19
|
+
yield(config)
|
20
|
+
|
21
|
+
config.ingest
|
22
|
+
config.validate!
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require "./lib/redis_ui_rails/version"
|
2
|
+
|
3
|
+
Gem::Specification.new do |spec|
|
4
|
+
spec.name = "redis_ui_rails"
|
5
|
+
spec.version = RedisUiRails::VERSION
|
6
|
+
spec.authors = ['Stitch Fix Engineering']
|
7
|
+
spec.email = ['eng@stitchfix.com']
|
8
|
+
spec.homepage = "https://github.com/stitchfix/redis_ui_rails"
|
9
|
+
spec.summary = "A drop-in Rails UI for Redis."
|
10
|
+
|
11
|
+
spec.files = `git ls-files`.split("\n")
|
12
|
+
spec.test_files = `git ls-files -- {spec}/*`.split("\n")
|
13
|
+
spec.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
14
|
+
spec.require_paths = ["lib"]
|
15
|
+
|
16
|
+
spec.add_dependency "rails", ">= 6.1.5.1"
|
17
|
+
spec.add_dependency "sprockets", ">= 3.7.2"
|
18
|
+
spec.add_dependency "sprockets-rails"
|
19
|
+
spec.add_dependency "redis"
|
20
|
+
spec.add_development_dependency "rspec"
|
21
|
+
spec.add_development_dependency "pry"
|
22
|
+
|
23
|
+
# For Dummy Rails app tests
|
24
|
+
spec.add_development_dependency "capybara"
|
25
|
+
spec.add_development_dependency "webdrivers"
|
26
|
+
spec.add_development_dependency "sqlite3"
|
27
|
+
spec.add_development_dependency "puma"
|
28
|
+
spec.add_development_dependency "net-smtp"
|
29
|
+
spec.add_development_dependency "mock_redis"
|
30
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require "feature_spec_helper"
|
2
|
+
|
3
|
+
RSpec.describe "Dashboard View", type: :feature do
|
4
|
+
# Just a simple smoke test to make sure we haven't broken anything.
|
5
|
+
# Testing details beyond this isn't worth the time given the current
|
6
|
+
# simplicity.
|
7
|
+
it "loads without error" do
|
8
|
+
visit "redis_ui/"
|
9
|
+
|
10
|
+
expect(page).to have_content "Redis Dashboard"
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require "feature_spec_helper"
|
2
|
+
|
3
|
+
RSpec.describe "Instance Config", type: :feature do
|
4
|
+
let(:mock_redis) { MockRedis.new }
|
5
|
+
# Just a simple smoke test to make sure we haven't broken anything.
|
6
|
+
# Testing details beyond this isn't worth the time given the current
|
7
|
+
# simplicity.
|
8
|
+
before do
|
9
|
+
allow(Redis).to receive(:new).and_return(mock_redis)
|
10
|
+
end
|
11
|
+
|
12
|
+
it "loads without error" do
|
13
|
+
visit "redis_ui/instance/dummy/config"
|
14
|
+
|
15
|
+
expect(page).to have_content "Server Config"
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require "feature_spec_helper"
|
2
|
+
|
3
|
+
RSpec.describe "Instance Keys", type: :feature do
|
4
|
+
let(:mock_redis) { MockRedis.new }
|
5
|
+
# Just a simple smoke test to make sure we haven't broken anything.
|
6
|
+
# Testing details beyond this isn't worth the time given the current
|
7
|
+
# simplicity.
|
8
|
+
before do
|
9
|
+
allow(Redis).to receive(:new).and_return(mock_redis)
|
10
|
+
end
|
11
|
+
|
12
|
+
it "loads without error" do
|
13
|
+
visit "redis_ui/instance/dummy/keys"
|
14
|
+
|
15
|
+
expect(page).to have_content "Sample keys"
|
16
|
+
end
|
17
|
+
end
|