knife-tidy 1.2.0 → 2.0.0
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/chef/knife/tidy_backup_clean.rb +87 -87
- data/lib/chef/knife/tidy_base.rb +11 -11
- data/lib/chef/knife/tidy_notify.rb +69 -69
- data/lib/chef/knife/tidy_server_clean.rb +23 -23
- data/lib/chef/knife/tidy_server_report.rb +40 -40
- data/lib/chef/tidy_acls.rb +33 -33
- data/lib/chef/tidy_common.rb +20 -20
- data/lib/chef/tidy_server.rb +1 -1
- data/lib/chef/tidy_substitutions.rb +11 -11
- data/lib/knife-tidy/version.rb +2 -2
- metadata +5 -101
- data/.gitignore +0 -52
- data/.travis.yml +0 -26
- data/CHANGELOG.md +0 -246
- data/Gemfile +0 -38
- data/README.md +0 -165
- data/Rakefile +0 -58
- data/TODO.md +0 -5
- data/conf/substitutions.json.example +0 -10
- data/knife-tidy.gemspec +0 -32
- data/spec/chef/knife/tidy_backup_clean_spec.rb +0 -0
- data/spec/chef/knife/tidy_base_spec.rb +0 -25
- data/spec/spec_helper.rb +0 -17
data/lib/chef/tidy_acls.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
1
|
+
require "ffi_yajl"
|
2
|
+
require "fileutils"
|
3
|
+
require "chef/log"
|
4
4
|
|
5
5
|
class Chef
|
6
6
|
class TidyOrgAcls
|
@@ -18,8 +18,8 @@ class Chef
|
|
18
18
|
end
|
19
19
|
|
20
20
|
def load_users
|
21
|
-
@tidy.ui.stdout.puts
|
22
|
-
Dir[::File.join(@tidy.users_path,
|
21
|
+
@tidy.ui.stdout.puts "INFO: Loading users"
|
22
|
+
Dir[::File.join(@tidy.users_path, "*.json")].each do |user|
|
23
23
|
@users.push(FFI_Yajl::Parser.parse(::File.read(user), symbolize_names: true))
|
24
24
|
end
|
25
25
|
end
|
@@ -31,14 +31,14 @@ class Chef
|
|
31
31
|
|
32
32
|
def load_clients
|
33
33
|
@tidy.ui.stdout.puts "INFO: Loading clients for #{@org}"
|
34
|
-
Dir[::File.join(@tidy.clients_path(@org),
|
34
|
+
Dir[::File.join(@tidy.clients_path(@org), "*.json")].each do |client|
|
35
35
|
@clients.push(FFI_Yajl::Parser.parse(::File.read(client), symbolize_names: true))
|
36
36
|
end
|
37
37
|
end
|
38
38
|
|
39
39
|
def load_groups
|
40
40
|
@tidy.ui.stdout.puts "INFO: Loading groups for #{@org}"
|
41
|
-
Dir[::File.join(@tidy.groups_path(@org),
|
41
|
+
Dir[::File.join(@tidy.groups_path(@org), "*.json")].each do |group|
|
42
42
|
@groups.push(FFI_Yajl::Parser.parse(::File.read(group), symbolize_names: true))
|
43
43
|
end
|
44
44
|
end
|
@@ -52,17 +52,17 @@ class Chef
|
|
52
52
|
end
|
53
53
|
|
54
54
|
def acl_ops
|
55
|
-
%w
|
55
|
+
%w{ create read update delete grant }
|
56
56
|
end
|
57
57
|
|
58
58
|
def acl_actors_groups(acl)
|
59
59
|
actors_seen = []
|
60
60
|
groups_seen = []
|
61
61
|
acl_ops.each do |op|
|
62
|
-
acl[op][
|
62
|
+
acl[op]["actors"].each do |actor|
|
63
63
|
actors_seen.push(actor) unless actors_seen.include?(actor)
|
64
64
|
end
|
65
|
-
acl[op][
|
65
|
+
acl[op]["groups"].each do |group|
|
66
66
|
groups_seen.push(group) unless groups_seen.include?(group)
|
67
67
|
end
|
68
68
|
end
|
@@ -83,7 +83,7 @@ class Chef
|
|
83
83
|
|
84
84
|
def invalid_group?(actor)
|
85
85
|
@groups.select { |group| group[:name] == actor }.empty? &&
|
86
|
-
actor !=
|
86
|
+
actor != "::server-admins" &&
|
87
87
|
actor != "::#{@org}_read_access_group"
|
88
88
|
end
|
89
89
|
|
@@ -100,8 +100,8 @@ class Chef
|
|
100
100
|
end
|
101
101
|
|
102
102
|
def org_acls
|
103
|
-
@org_acls ||= Dir[::File.join(@tidy.org_acls_path(@org),
|
104
|
-
|
103
|
+
@org_acls ||= Dir[::File.join(@tidy.org_acls_path(@org), "**.json")] +
|
104
|
+
Dir[::File.join(@tidy.org_acls_path(@org), "**", "*.json")]
|
105
105
|
end
|
106
106
|
|
107
107
|
def fix_ambiguous_actor(actor)
|
@@ -130,7 +130,7 @@ class Chef
|
|
130
130
|
@tidy.ui.stdout.puts "REPAIRING: Removing invalid group: #{group} from #{acl_file}"
|
131
131
|
acl = FFI_Yajl::Parser.parse(::File.read(acl_file), symbolize_names: false)
|
132
132
|
acl_ops.each do |op|
|
133
|
-
acl[op][
|
133
|
+
acl[op]["groups"].reject! { |the_group| the_group == group }
|
134
134
|
end
|
135
135
|
@tidy.write_new_file(acl, acl_file)
|
136
136
|
end
|
@@ -139,13 +139,13 @@ class Chef
|
|
139
139
|
def ensure_global_group_acls(acl_file)
|
140
140
|
acl = FFI_Yajl::Parser.parse(::File.read(acl_file), symbolize_names: false)
|
141
141
|
acl_ops.each do |op|
|
142
|
-
unless acl[op][
|
142
|
+
unless acl[op]["groups"].include? "::server-admins"
|
143
143
|
@tidy.ui.stdout.puts "REPAIRING: Adding #{op} acl for ::server-admins in #{acl_file}"
|
144
|
-
acl[op][
|
144
|
+
acl[op]["groups"].push("::server-admins")
|
145
145
|
end
|
146
|
-
if op ==
|
146
|
+
if op == "read" && !acl[op]["groups"].include?("::#{@org}_read_access_group")
|
147
147
|
@tidy.ui.stdout.puts "REPAIRING: Adding #{op} acl for ::#{@org}_read_access_group in #{acl_file}"
|
148
|
-
acl[op][
|
148
|
+
acl[op]["groups"].push("::#{@org}_read_access_group")
|
149
149
|
end
|
150
150
|
end
|
151
151
|
@tidy.write_new_file(acl, acl_file)
|
@@ -153,10 +153,10 @@ class Chef
|
|
153
153
|
|
154
154
|
def ensure_client_read_acls(acl_file)
|
155
155
|
acl = FFI_Yajl::Parser.parse(::File.read(acl_file), symbolize_names: false)
|
156
|
-
%w
|
157
|
-
unless acl[
|
156
|
+
%w{users admins}.each do |group|
|
157
|
+
unless acl["read"]["groups"].include? group
|
158
158
|
@tidy.ui.stdout.puts "REPAIRING: Adding read acl for #{group} in #{acl_file}"
|
159
|
-
acl[
|
159
|
+
acl["read"]["groups"].push(group)
|
160
160
|
end
|
161
161
|
end
|
162
162
|
@tidy.write_new_file(acl, acl_file)
|
@@ -167,7 +167,7 @@ class Chef
|
|
167
167
|
acl = FFI_Yajl::Parser.parse(::File.read(acl_file), symbolize_names: false)
|
168
168
|
actors_groups = acl_actors_groups(acl)
|
169
169
|
actors_groups[:actors].each do |actor|
|
170
|
-
next if actor ==
|
170
|
+
next if actor == "pivotal"
|
171
171
|
if ambiguous_actor?(actor)
|
172
172
|
fix_ambiguous_actor(actor)
|
173
173
|
elsif missing_from_members?(actor)
|
@@ -183,19 +183,19 @@ class Chef
|
|
183
183
|
end
|
184
184
|
|
185
185
|
def default_user_acl(client)
|
186
|
-
{ create: { actors: [
|
187
|
-
read: { actors: [
|
188
|
-
update: { actors: [
|
189
|
-
delete: { actors: [
|
190
|
-
grant: { actors: [
|
186
|
+
{ create: { actors: ["pivotal", client], groups: ["::server-admins"] },
|
187
|
+
read: { actors: ["pivotal", client], groups: ["::server-admins", "::#{@org}_read_access_group"] },
|
188
|
+
update: { actors: ["pivotal", client], groups: ["::server-admins"] },
|
189
|
+
delete: { actors: ["pivotal", client], groups: ["::server-admins"] },
|
190
|
+
grant: { actors: ["pivotal", client], groups: ["::server-admins"] } }
|
191
191
|
end
|
192
192
|
|
193
193
|
def default_client_acl(client_name)
|
194
|
-
{ create: { actors: [
|
195
|
-
read: { actors: [
|
196
|
-
update: { actors: [
|
197
|
-
delete: { actors: [
|
198
|
-
grant: { actors: [
|
194
|
+
{ create: { actors: ["pivotal", "#{@org}-validator", client_name], groups: ["admins"] },
|
195
|
+
read: { actors: ["pivotal", "#{@org}-validator", client_name], groups: %w{admins users} },
|
196
|
+
update: { actors: ["pivotal", client_name], groups: ["admins"] },
|
197
|
+
delete: { actors: ["pivotal", client_name], groups: %w{admins users} },
|
198
|
+
grant: { actors: ["pivotal", client_name], groups: ["admins"] } }
|
199
199
|
end
|
200
200
|
|
201
201
|
def validate_user_acls
|
@@ -218,7 +218,7 @@ class Chef
|
|
218
218
|
|
219
219
|
def validate_client_acls
|
220
220
|
@clients.each do |client|
|
221
|
-
client_acl_path = ::File.join(@tidy.org_acls_path(@org),
|
221
|
+
client_acl_path = ::File.join(@tidy.org_acls_path(@org), "clients", "#{client[:name]}.json")
|
222
222
|
begin
|
223
223
|
client_acl = FFI_Yajl::Parser.parse(::File.read(client_acl_path), symbolize_names: false)
|
224
224
|
rescue Errno::ENOENT
|
data/lib/chef/tidy_common.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
1
|
+
require "ffi_yajl"
|
2
|
+
require "fileutils"
|
3
|
+
require "chef/knife/core/ui"
|
4
4
|
|
5
5
|
class Chef
|
6
6
|
class TidyCommon
|
@@ -17,56 +17,56 @@ class Chef
|
|
17
17
|
end
|
18
18
|
|
19
19
|
def users_path
|
20
|
-
@users_path ||= ::File.expand_path(::File.join(@backup_path,
|
20
|
+
@users_path ||= ::File.expand_path(::File.join(@backup_path, "users"))
|
21
21
|
end
|
22
22
|
|
23
23
|
def members_path(org)
|
24
|
-
::File.expand_path(::File.join(@backup_path,
|
24
|
+
::File.expand_path(::File.join(@backup_path, "organizations", org, "members.json"))
|
25
25
|
end
|
26
26
|
|
27
27
|
def invitations_path(org)
|
28
|
-
::File.expand_path(::File.join(@backup_path,
|
28
|
+
::File.expand_path(::File.join(@backup_path, "organizations", org, "invitations.json"))
|
29
29
|
end
|
30
30
|
|
31
31
|
def clients_path(org)
|
32
|
-
::File.expand_path(::File.join(@backup_path,
|
32
|
+
::File.expand_path(::File.join(@backup_path, "organizations", org, "clients"))
|
33
33
|
end
|
34
34
|
|
35
35
|
def client_names(org)
|
36
|
-
Dir[::File.join(clients_path(org),
|
36
|
+
Dir[::File.join(clients_path(org), "*")].map { |dir| ::File.basename(dir, ".json") }
|
37
37
|
end
|
38
38
|
|
39
39
|
def groups_path(org)
|
40
|
-
::File.expand_path(::File.join(@backup_path,
|
40
|
+
::File.expand_path(::File.join(@backup_path, "organizations", org, "groups"))
|
41
41
|
end
|
42
42
|
|
43
43
|
def org_acls_path(org)
|
44
|
-
::File.expand_path(::File.join(@backup_path,
|
44
|
+
::File.expand_path(::File.join(@backup_path, "organizations", org, "acls"))
|
45
45
|
end
|
46
46
|
|
47
47
|
def user_acls_path
|
48
|
-
@user_acls_path ||= ::File.expand_path(::File.join(@backup_path,
|
48
|
+
@user_acls_path ||= ::File.expand_path(::File.join(@backup_path, "user_acls"))
|
49
49
|
end
|
50
50
|
|
51
51
|
def cookbooks_path(org)
|
52
|
-
::File.expand_path(::File.join(@backup_path,
|
52
|
+
::File.expand_path(::File.join(@backup_path, "organizations", org, "cookbooks"))
|
53
53
|
end
|
54
54
|
|
55
55
|
def roles_path(org)
|
56
|
-
::File.expand_path(::File.join(@backup_path,
|
56
|
+
::File.expand_path(::File.join(@backup_path, "organizations", org, "roles"))
|
57
57
|
end
|
58
58
|
|
59
59
|
def org_path(org)
|
60
|
-
::File.expand_path(::File.join(@backup_path,
|
60
|
+
::File.expand_path(::File.join(@backup_path, "organizations", org))
|
61
61
|
end
|
62
62
|
|
63
63
|
def unique_email
|
64
64
|
(0...8).map { (65 + rand(26)).chr }.join.downcase +
|
65
|
-
|
65
|
+
"@" + (0...8).map { (65 + rand(26)).chr }.join.downcase + ".com"
|
66
66
|
end
|
67
67
|
|
68
68
|
def save_user(user)
|
69
|
-
::File.open(::File.join(users_path, "#{user['username']}.json"),
|
69
|
+
::File.open(::File.join(users_path, "#{user['username']}.json"), "w+") do |f|
|
70
70
|
f.write(FFI_Yajl::Encoder.encode(user, pretty: true))
|
71
71
|
end
|
72
72
|
end
|
@@ -75,21 +75,21 @@ class Chef
|
|
75
75
|
if ::File.exist?(path) && backup
|
76
76
|
FileUtils.cp(path, "#{path}.orig") unless ::File.exist?("#{path}.orig")
|
77
77
|
end
|
78
|
-
::File.open(path,
|
78
|
+
::File.open(path, "w+") do |f|
|
79
79
|
f.write(FFI_Yajl::Encoder.encode(contents, pretty: true))
|
80
80
|
end
|
81
81
|
end
|
82
82
|
|
83
83
|
def cookbook_name_from_path(path)
|
84
|
-
::File.basename(path,
|
84
|
+
::File.basename(path, "-*")
|
85
85
|
end
|
86
86
|
|
87
87
|
def global_user_names
|
88
|
-
@global_user_names ||= Dir[::File.join(@backup_path,
|
88
|
+
@global_user_names ||= Dir[::File.join(@backup_path, "users", "*")].map { |dir| ::File.basename(dir, ".json") }
|
89
89
|
end
|
90
90
|
|
91
91
|
def reports_dir
|
92
|
-
@reports_dir ||= ::File.join(Dir.pwd,
|
92
|
+
@reports_dir ||= ::File.join(Dir.pwd, "reports")
|
93
93
|
end
|
94
94
|
end
|
95
95
|
end
|
data/lib/chef/tidy_server.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
4
|
-
require
|
1
|
+
require "ffi_yajl"
|
2
|
+
require "tempfile"
|
3
|
+
require "fileutils"
|
4
|
+
require "chef/log"
|
5
5
|
|
6
6
|
class Chef
|
7
7
|
class TidySubstitutions
|
@@ -23,14 +23,14 @@ class Chef
|
|
23
23
|
end
|
24
24
|
|
25
25
|
def boiler_plate
|
26
|
-
bp = ::File.join(File.dirname(__FILE__),
|
26
|
+
bp = ::File.join(File.dirname(__FILE__), "../../conf/substitutions.json.example")
|
27
27
|
@tidy.ui.stdout.puts "INFO: Creating boiler plate gsub file: 'substitutions.json'"
|
28
|
-
FileUtils.cp(bp, ::File.join(Dir.pwd,
|
28
|
+
FileUtils.cp(bp, ::File.join(Dir.pwd, "substitutions.json"))
|
29
29
|
end
|
30
30
|
|
31
31
|
def cookbook_version_from_path(path)
|
32
32
|
components = path.split(File::SEPARATOR)
|
33
|
-
name_version = components[components.index(
|
33
|
+
name_version = components[components.index("cookbooks") + 1]
|
34
34
|
name_version.match(/\d+\.\d+\.\d+/).to_s
|
35
35
|
end
|
36
36
|
|
@@ -38,9 +38,9 @@ class Chef
|
|
38
38
|
end
|
39
39
|
|
40
40
|
def sub_in_file(path, search, replace)
|
41
|
-
temp_file = Tempfile.new(
|
41
|
+
temp_file = Tempfile.new("tidy")
|
42
42
|
begin
|
43
|
-
File.open(path,
|
43
|
+
File.open(path, "r") do |file|
|
44
44
|
file.each_line do |line|
|
45
45
|
if line.match(search)
|
46
46
|
temp_file.puts replace
|
@@ -66,8 +66,8 @@ class Chef
|
|
66
66
|
@tidy.ui.stdout.puts "INFO: Running substitutions for #{entry} -> #{glob}"
|
67
67
|
Dir[::File.join(@backup_path, glob)].each do |file|
|
68
68
|
@data[entry][glob].each do |substitution|
|
69
|
-
search = Regexp.new(substitution[
|
70
|
-
replace = substitution[
|
69
|
+
search = Regexp.new(substitution["pattern"])
|
70
|
+
replace = substitution["replace"].dup
|
71
71
|
replace.gsub!(/\!COOKBOOK_VERSION\!/) { |_m| "'" + cookbook_version_from_path(file) + "'" }
|
72
72
|
sub_in_file(file, search, replace)
|
73
73
|
end
|
data/lib/knife-tidy/version.rb
CHANGED
metadata
CHANGED
@@ -1,99 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: knife-tidy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jeremy Miller
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
12
|
-
dependencies:
|
13
|
-
- !ruby/object:Gem::Dependency
|
14
|
-
name: rake
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
16
|
-
requirements:
|
17
|
-
- - "~>"
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: '11.0'
|
20
|
-
type: :development
|
21
|
-
prerelease: false
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
23
|
-
requirements:
|
24
|
-
- - "~>"
|
25
|
-
- !ruby/object:Gem::Version
|
26
|
-
version: '11.0'
|
27
|
-
- !ruby/object:Gem::Dependency
|
28
|
-
name: rspec
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
30
|
-
requirements:
|
31
|
-
- - "~>"
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: '3.4'
|
34
|
-
type: :development
|
35
|
-
prerelease: false
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
37
|
-
requirements:
|
38
|
-
- - "~>"
|
39
|
-
- !ruby/object:Gem::Version
|
40
|
-
version: '3.4'
|
41
|
-
- !ruby/object:Gem::Dependency
|
42
|
-
name: aruba
|
43
|
-
requirement: !ruby/object:Gem::Requirement
|
44
|
-
requirements:
|
45
|
-
- - "~>"
|
46
|
-
- !ruby/object:Gem::Version
|
47
|
-
version: '0.6'
|
48
|
-
type: :development
|
49
|
-
prerelease: false
|
50
|
-
version_requirements: !ruby/object:Gem::Requirement
|
51
|
-
requirements:
|
52
|
-
- - "~>"
|
53
|
-
- !ruby/object:Gem::Version
|
54
|
-
version: '0.6'
|
55
|
-
- !ruby/object:Gem::Dependency
|
56
|
-
name: simplecov
|
57
|
-
requirement: !ruby/object:Gem::Requirement
|
58
|
-
requirements:
|
59
|
-
- - "~>"
|
60
|
-
- !ruby/object:Gem::Version
|
61
|
-
version: '0.9'
|
62
|
-
type: :development
|
63
|
-
prerelease: false
|
64
|
-
version_requirements: !ruby/object:Gem::Requirement
|
65
|
-
requirements:
|
66
|
-
- - "~>"
|
67
|
-
- !ruby/object:Gem::Version
|
68
|
-
version: '0.9'
|
69
|
-
- !ruby/object:Gem::Dependency
|
70
|
-
name: simplecov-console
|
71
|
-
requirement: !ruby/object:Gem::Requirement
|
72
|
-
requirements:
|
73
|
-
- - "~>"
|
74
|
-
- !ruby/object:Gem::Version
|
75
|
-
version: '0.2'
|
76
|
-
type: :development
|
77
|
-
prerelease: false
|
78
|
-
version_requirements: !ruby/object:Gem::Requirement
|
79
|
-
requirements:
|
80
|
-
- - "~>"
|
81
|
-
- !ruby/object:Gem::Version
|
82
|
-
version: '0.2'
|
83
|
-
- !ruby/object:Gem::Dependency
|
84
|
-
name: chef
|
85
|
-
requirement: !ruby/object:Gem::Requirement
|
86
|
-
requirements:
|
87
|
-
- - ">="
|
88
|
-
- !ruby/object:Gem::Version
|
89
|
-
version: '0'
|
90
|
-
type: :development
|
91
|
-
prerelease: false
|
92
|
-
version_requirements: !ruby/object:Gem::Requirement
|
93
|
-
requirements:
|
94
|
-
- - ">="
|
95
|
-
- !ruby/object:Gem::Version
|
96
|
-
version: '0'
|
11
|
+
date: 2019-01-16 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
97
13
|
description: Report on stale Chef Server nodes and cookbooks and clean up data integrity
|
98
14
|
issues in a knife-ec-backup object based backup
|
99
15
|
email:
|
@@ -102,16 +18,7 @@ executables: []
|
|
102
18
|
extensions: []
|
103
19
|
extra_rdoc_files: []
|
104
20
|
files:
|
105
|
-
- ".gitignore"
|
106
|
-
- ".travis.yml"
|
107
|
-
- CHANGELOG.md
|
108
|
-
- Gemfile
|
109
21
|
- LICENSE
|
110
|
-
- README.md
|
111
|
-
- Rakefile
|
112
|
-
- TODO.md
|
113
|
-
- conf/substitutions.json.example
|
114
|
-
- knife-tidy.gemspec
|
115
22
|
- lib/chef/knife/tidy_backup_clean.rb
|
116
23
|
- lib/chef/knife/tidy_base.rb
|
117
24
|
- lib/chef/knife/tidy_notify.rb
|
@@ -122,12 +29,9 @@ files:
|
|
122
29
|
- lib/chef/tidy_server.rb
|
123
30
|
- lib/chef/tidy_substitutions.rb
|
124
31
|
- lib/knife-tidy/version.rb
|
125
|
-
- spec/chef/knife/tidy_backup_clean_spec.rb
|
126
|
-
- spec/chef/knife/tidy_base_spec.rb
|
127
|
-
- spec/spec_helper.rb
|
128
32
|
homepage: https://github.com/chef-customers/knife-tidy
|
129
33
|
licenses:
|
130
|
-
- Apache
|
34
|
+
- Apache-2.0
|
131
35
|
metadata: {}
|
132
36
|
post_install_message:
|
133
37
|
rdoc_options: []
|
@@ -137,7 +41,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
137
41
|
requirements:
|
138
42
|
- - ">="
|
139
43
|
- !ruby/object:Gem::Version
|
140
|
-
version: 2.
|
44
|
+
version: 2.3.0
|
141
45
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
142
46
|
requirements:
|
143
47
|
- - ">="
|