redfish 0.2.1

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 63a5f49ae9aec43ee289df618ae519ab02fd1fa7
4
+ data.tar.gz: ed3f6ee4c6682869fbf9647b2f87b5bb2a0a4406
5
+ SHA512:
6
+ metadata.gz: 6eac43b7b5d6cea1854c1f8e4b61b316fd62e3408a40ae64d8065cc27103a3c754754660df373df70bee7aa9745890ca6f74c074c28e1b6083fcb89b1c87333e
7
+ data.tar.gz: b07ac9074eba420a45bb63adae6b0286f211fd27d67a43009027bde6a8bf74437a137aa356fe8521c18409cc074309b82053a009030bbdfd2900fdf1b817cc72
@@ -0,0 +1,30 @@
1
+ * -text
2
+ *.iml text -crlf -binary
3
+ *.axl text -crlf -binary
4
+ *.c text -crlf -binary
5
+ *.css text -crlf -binary
6
+ *.html text -crlf -binary
7
+ *.java text -crlf -binary
8
+ *.js text -crlf -binary
9
+ *.json text -crlf -binary
10
+ *.jsp text -crlf -binary
11
+ *.properties text -crlf -binary
12
+ *.txt text -crlf -binary
13
+ *.xml text -crlf -binary
14
+ *.xsd text -crlf -binary
15
+ *.xsl text -crlf -binary
16
+ *.rb text -crlf -binary
17
+ *.haml text -crlf -binary
18
+ *.rake text -crlf -binary
19
+ *.sass text -crlf -binary
20
+ *.yml text -crlf -binary
21
+ *.yaml text -crlf -binary
22
+ *.rhtml text -crlf -binary
23
+ *.jar binary
24
+ LICENSE text -crlf -binary
25
+ CHANGELOG text -crlf -binary
26
+ Rakefile text -crlf -binary
27
+ rakefile text -crlf -binary
28
+ Buildfile text -crlf -binary
29
+ buildfile text -crlf -binary
30
+ *.gemspec text -crlf -binary
@@ -0,0 +1,9 @@
1
+ .idea
2
+ pkg
3
+ pkg/*
4
+ rdoc
5
+ /*.iml
6
+ /*.ipr
7
+ /*.iws
8
+ /Gemfile.lock
9
+ /.rakeTasks
@@ -0,0 +1 @@
1
+ 2.1.3
@@ -0,0 +1,17 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.0.0
4
+ - 1.9.3
5
+ - jruby-19mode
6
+ jdk:
7
+ - openjdk6
8
+ - openjdk7
9
+ - oraclejdk7
10
+ matrix:
11
+ exclude:
12
+ - rvm: 1.9.3
13
+ jdk: openjdk7
14
+ - rvm: 1.9.2
15
+ jdk: oraclejdk7
16
+ git:
17
+ depth: 10
@@ -0,0 +1,26 @@
1
+ # How to Contribute
2
+
3
+ Pull requests are greatly appreciated and are what makes opensource great. Here's a quick guide:
4
+
5
+ * Fork it
6
+ * Create your feature branch (`git checkout -b my-new-feature`)
7
+ * Commit your changes (`git commit -am 'Add some feature'`)
8
+ * Push to the branch (`git push origin my-new-feature`)
9
+ * Create new Pull Request
10
+
11
+ Pester us if we don't get your Pull Requests merged in a timely fashion. :)
12
+
13
+ ## How to speed the merging of pull requests
14
+
15
+ * Describe your changes in the CHANGELOG.
16
+ * Give yourself some credit in the appropriate place (usually the CHANGELOG).
17
+ * Make commits of logical units.
18
+ * Ensure your commit messages help others understand what you are doing and why.
19
+ * Check for unnecessary whitespace with `git diff --check` before committing.
20
+ * Maintain the same code style.
21
+ * Maintain the same level of test coverage or improve it.
22
+
23
+ ## Additional Resources
24
+
25
+ * [General GitHub documentation](http://help.github.com/)
26
+ * [GitHub pull request documentation](http://help.github.com/send-pull-requests/)
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source 'http://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ gem 'rake'
6
+ gem 'rubyzip', '= 0.9.9'
data/LICENSE ADDED
@@ -0,0 +1,201 @@
1
+ Apache License
2
+ Version 2.0, January 2004
3
+ http://www.apache.org/licenses/
4
+
5
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6
+
7
+ 1. Definitions.
8
+
9
+ "License" shall mean the terms and conditions for use, reproduction,
10
+ and distribution as defined by Sections 1 through 9 of this document.
11
+
12
+ "Licensor" shall mean the copyright owner or entity authorized by
13
+ the copyright owner that is granting the License.
14
+
15
+ "Legal Entity" shall mean the union of the acting entity and all
16
+ other entities that control, are controlled by, or are under common
17
+ control with that entity. For the purposes of this definition,
18
+ "control" means (i) the power, direct or indirect, to cause the
19
+ direction or management of such entity, whether by contract or
20
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
21
+ outstanding shares, or (iii) beneficial ownership of such entity.
22
+
23
+ "You" (or "Your") shall mean an individual or Legal Entity
24
+ exercising permissions granted by this License.
25
+
26
+ "Source" form shall mean the preferred form for making modifications,
27
+ including but not limited to software source code, documentation
28
+ source, and configuration files.
29
+
30
+ "Object" form shall mean any form resulting from mechanical
31
+ transformation or translation of a Source form, including but
32
+ not limited to compiled object code, generated documentation,
33
+ and conversions to other media types.
34
+
35
+ "Work" shall mean the work of authorship, whether in Source or
36
+ Object form, made available under the License, as indicated by a
37
+ copyright notice that is included in or attached to the work
38
+ (an example is provided in the Appendix below).
39
+
40
+ "Derivative Works" shall mean any work, whether in Source or Object
41
+ form, that is based on (or derived from) the Work and for which the
42
+ editorial revisions, annotations, elaborations, or other modifications
43
+ represent, as a whole, an original work of authorship. For the purposes
44
+ of this License, Derivative Works shall not include works that remain
45
+ separable from, or merely link (or bind by name) to the interfaces of,
46
+ the Work and Derivative Works thereof.
47
+
48
+ "Contribution" shall mean any work of authorship, including
49
+ the original version of the Work and any modifications or additions
50
+ to that Work or Derivative Works thereof, that is intentionally
51
+ submitted to Licensor for inclusion in the Work by the copyright owner
52
+ or by an individual or Legal Entity authorized to submit on behalf of
53
+ the copyright owner. For the purposes of this definition, "submitted"
54
+ means any form of electronic, verbal, or written communication sent
55
+ to the Licensor or its representatives, including but not limited to
56
+ communication on electronic mailing lists, source code control systems,
57
+ and issue tracking systems that are managed by, or on behalf of, the
58
+ Licensor for the purpose of discussing and improving the Work, but
59
+ excluding communication that is conspicuously marked or otherwise
60
+ designated in writing by the copyright owner as "Not a Contribution."
61
+
62
+ "Contributor" shall mean Licensor and any individual or Legal Entity
63
+ on behalf of whom a Contribution has been received by Licensor and
64
+ subsequently incorporated within the Work.
65
+
66
+ 2. Grant of Copyright License. Subject to the terms and conditions of
67
+ this License, each Contributor hereby grants to You a perpetual,
68
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69
+ copyright license to reproduce, prepare Derivative Works of,
70
+ publicly display, publicly perform, sublicense, and distribute the
71
+ Work and such Derivative Works in Source or Object form.
72
+
73
+ 3. Grant of Patent License. Subject to the terms and conditions of
74
+ this License, each Contributor hereby grants to You a perpetual,
75
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76
+ (except as stated in this section) patent license to make, have made,
77
+ use, offer to sell, sell, import, and otherwise transfer the Work,
78
+ where such license applies only to those patent claims licensable
79
+ by such Contributor that are necessarily infringed by their
80
+ Contribution(s) alone or by combination of their Contribution(s)
81
+ with the Work to which such Contribution(s) was submitted. If You
82
+ institute patent litigation against any entity (including a
83
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
84
+ or a Contribution incorporated within the Work constitutes direct
85
+ or contributory patent infringement, then any patent licenses
86
+ granted to You under this License for that Work shall terminate
87
+ as of the date such litigation is filed.
88
+
89
+ 4. Redistribution. You may reproduce and distribute copies of the
90
+ Work or Derivative Works thereof in any medium, with or without
91
+ modifications, and in Source or Object form, provided that You
92
+ meet the following conditions:
93
+
94
+ (a) You must give any other recipients of the Work or
95
+ Derivative Works a copy of this License; and
96
+
97
+ (b) You must cause any modified files to carry prominent notices
98
+ stating that You changed the files; and
99
+
100
+ (c) You must retain, in the Source form of any Derivative Works
101
+ that You distribute, all copyright, patent, trademark, and
102
+ attribution notices from the Source form of the Work,
103
+ excluding those notices that do not pertain to any part of
104
+ the Derivative Works; and
105
+
106
+ (d) If the Work includes a "NOTICE" text file as part of its
107
+ distribution, then any Derivative Works that You distribute must
108
+ include a readable copy of the attribution notices contained
109
+ within such NOTICE file, excluding those notices that do not
110
+ pertain to any part of the Derivative Works, in at least one
111
+ of the following places: within a NOTICE text file distributed
112
+ as part of the Derivative Works; within the Source form or
113
+ documentation, if provided along with the Derivative Works; or,
114
+ within a display generated by the Derivative Works, if and
115
+ wherever such third-party notices normally appear. The contents
116
+ of the NOTICE file are for informational purposes only and
117
+ do not modify the License. You may add Your own attribution
118
+ notices within Derivative Works that You distribute, alongside
119
+ or as an addendum to the NOTICE text from the Work, provided
120
+ that such additional attribution notices cannot be construed
121
+ as modifying the License.
122
+
123
+ You may add Your own copyright statement to Your modifications and
124
+ may provide additional or different license terms and conditions
125
+ for use, reproduction, or distribution of Your modifications, or
126
+ for any such Derivative Works as a whole, provided Your use,
127
+ reproduction, and distribution of the Work otherwise complies with
128
+ the conditions stated in this License.
129
+
130
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
131
+ any Contribution intentionally submitted for inclusion in the Work
132
+ by You to the Licensor shall be under the terms and conditions of
133
+ this License, without any additional terms or conditions.
134
+ Notwithstanding the above, nothing herein shall supersede or modify
135
+ the terms of any separate license agreement you may have executed
136
+ with Licensor regarding such Contributions.
137
+
138
+ 6. Trademarks. This License does not grant permission to use the trade
139
+ names, trademarks, service marks, or product names of the Licensor,
140
+ except as required for reasonable and customary use in describing the
141
+ origin of the Work and reproducing the content of the NOTICE file.
142
+
143
+ 7. Disclaimer of Warranty. Unless required by applicable law or
144
+ agreed to in writing, Licensor provides the Work (and each
145
+ Contributor provides its Contributions) on an "AS IS" BASIS,
146
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147
+ implied, including, without limitation, any warranties or conditions
148
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149
+ PARTICULAR PURPOSE. You are solely responsible for determining the
150
+ appropriateness of using or redistributing the Work and assume any
151
+ risks associated with Your exercise of permissions under this License.
152
+
153
+ 8. Limitation of Liability. In no event and under no legal theory,
154
+ whether in tort (including negligence), contract, or otherwise,
155
+ unless required by applicable law (such as deliberate and grossly
156
+ negligent acts) or agreed to in writing, shall any Contributor be
157
+ liable to You for damages, including any direct, indirect, special,
158
+ incidental, or consequential damages of any character arising as a
159
+ result of this License or out of the use or inability to use the
160
+ Work (including but not limited to damages for loss of goodwill,
161
+ work stoppage, computer failure or malfunction, or any and all
162
+ other commercial damages or losses), even if such Contributor
163
+ has been advised of the possibility of such damages.
164
+
165
+ 9. Accepting Warranty or Additional Liability. While redistributing
166
+ the Work or Derivative Works thereof, You may choose to offer,
167
+ and charge a fee for, acceptance of support, warranty, indemnity,
168
+ or other liability obligations and/or rights consistent with this
169
+ License. However, in accepting such obligations, You may act only
170
+ on Your own behalf and on Your sole responsibility, not on behalf
171
+ of any other Contributor, and only if You agree to indemnify,
172
+ defend, and hold each Contributor harmless for any liability
173
+ incurred by, or claims asserted against, such Contributor by reason
174
+ of your accepting any such warranty or additional liability.
175
+
176
+ END OF TERMS AND CONDITIONS
177
+
178
+ APPENDIX: How to apply the Apache License to your work.
179
+
180
+ To apply the Apache License to your work, attach the following
181
+ boilerplate notice, with the fields enclosed by brackets "[]"
182
+ replaced with your own identifying information. (Don't include
183
+ the brackets!) The text should be enclosed in the appropriate
184
+ comment syntax for the file format. We also recommend that a
185
+ file or class name and description of purpose be included on the
186
+ same "printed page" as the copyright notice for easier
187
+ identification within third-party archives.
188
+
189
+ Copyright [yyyy] [name of copyright owner]
190
+
191
+ Licensed under the Apache License, Version 2.0 (the "License");
192
+ you may not use this file except in compliance with the License.
193
+ You may obtain a copy of the License at
194
+
195
+ http://www.apache.org/licenses/LICENSE-2.0
196
+
197
+ Unless required by applicable law or agreed to in writing, software
198
+ distributed under the License is distributed on an "AS IS" BASIS,
199
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200
+ See the License for the specific language governing permissions and
201
+ limitations under the License.
@@ -0,0 +1,5 @@
1
+ # Redfish
2
+
3
+ [![Build Status](https://secure.travis-ci.org/realityforge/redfish.png?branch=master)](http://travis-ci.org/realityforge/redfish)
4
+
5
+ Redfish is a lightweight ruby library for configuring GlassFish or Payara servers.
@@ -0,0 +1,18 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ require 'rake'
5
+ require 'rubygems/package_task'
6
+ require 'rake/testtask'
7
+
8
+ desc 'Default Task'
9
+ task :default => :test
10
+
11
+ desc 'Test Task'
12
+ Rake::TestTask.new do |t|
13
+ files = FileList['test/helper.rb', 'test/test_*.rb', 'test/*/test_*.rb']
14
+ t.loader = :rake
15
+ t.test_files = files
16
+ t.libs << '.'
17
+ t.warning = true
18
+ end
@@ -0,0 +1,10 @@
1
+ require 'etc'
2
+
3
+ require 'redfish/version'
4
+ require 'redfish/property_cache'
5
+ require 'redfish/context'
6
+ require 'redfish/executor'
7
+ require 'redfish/task'
8
+
9
+ require 'redfish/tasks/property_cache'
10
+ require 'redfish/tasks/property'
@@ -0,0 +1,65 @@
1
+ module Redfish
2
+ class Context
3
+ # The directory in which glassfish has been installed.
4
+ attr_reader :install_dir
5
+
6
+ # The name of the domain.
7
+ attr_reader :domain_name
8
+ # The port on which the management application is bound.
9
+ attr_reader :domain_admin_port
10
+ # If true use SSL when communicating with the domain for administration. Assumes the domain is in secure mode.
11
+ attr_reader :domain_secure
12
+ # The username to use when communicating with the domain.
13
+ attr_reader :domain_username
14
+ # The password file used when connecting to glassfish.
15
+ attr_reader :domain_password_file
16
+
17
+ # Use terse output from the underlying asadmin.
18
+ def terse?
19
+ !!@terse
20
+ end
21
+
22
+ #If true, echo commands supplied to asadmin.
23
+ def echo?
24
+ !!@echo
25
+ end
26
+
27
+ # The user that the asadmin command executes as.
28
+ attr_reader :system_user
29
+ # The group that the asadmin command executes as.
30
+ attr_reader :system_group
31
+
32
+ def initialize(executor, install_dir, domain_name, domain_admin_port, domain_secure, domain_username, domain_password_file, options = {})
33
+ @executor, @install_dir, @domain_name, @domain_admin_port, @domain_secure, @domain_username, @domain_password_file =
34
+ executor, install_dir, domain_name, domain_admin_port, domain_secure, domain_username, domain_password_file
35
+ @echo = options[:echo].nil? ? false : !!options[:echo]
36
+ @terse = options[:terse].nil? ? false : !!options[:terse]
37
+ @system_user = options[:system_user]
38
+ @system_group = options[:system_group]
39
+ @property_cache = nil
40
+ end
41
+
42
+ def property_cache?
43
+ !@property_cache.nil?
44
+ end
45
+
46
+ def property_cache
47
+ raise 'Property cache not defined' unless property_cache?
48
+ @property_cache
49
+ end
50
+
51
+ def cache_properties(properties)
52
+ raise 'Property cache already defined' if property_cache?
53
+ @property_cache = PropertyCache.new(properties)
54
+ end
55
+
56
+ def remove_property_cache
57
+ raise 'No property cache to remove' unless property_cache?
58
+ @property_cache = nil
59
+ end
60
+
61
+ def exec(asadmin_command, args, options = {})
62
+ @executor.exec(self, asadmin_command, args, options)
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,65 @@
1
+ module Redfish
2
+ class Executor
3
+ def exec(context, asadmin_command, args = [], options = {})
4
+ raise 'args should be an array' unless args.is_a?(Array)
5
+
6
+ cmd = build_command(context, asadmin_command, args, options)
7
+
8
+ output = nil
9
+ IO.popen(cmd,'r') do |pipe|
10
+ output = pipe.read
11
+ end
12
+
13
+ raise "Asadmin command failed #{asadmin_command} with exist status #{last_exitstatus}" if 0 != last_exitstatus
14
+ output
15
+ end
16
+
17
+ private
18
+
19
+ def last_exitstatus
20
+ $?.exitstatus
21
+ end
22
+
23
+ def build_command(context, asadmin_command, args, options)
24
+ cmd = []
25
+
26
+ if needs_user_change?(context)
27
+ cmd << '/usr/bin/sudo'
28
+ cmd << '-u' << context.system_user.to_s unless context.system_user.nil?
29
+ cmd << '-g' << context.system_group.to_s unless context.system_group.nil?
30
+ end
31
+
32
+ cmd << asadmin_script(context)
33
+ cmd += asadmin_command_prefix(context, options)
34
+ cmd << asadmin_command
35
+ cmd += args
36
+
37
+ cmd
38
+ end
39
+
40
+ def needs_user_change?(context)
41
+ (context.system_user.nil? ? false : Etc.getlogin.to_s != context.system_user.to_s) ||
42
+ (context.system_group.nil? ? false : Etc.group.name.to_s != context.system_group.to_s)
43
+ end
44
+
45
+ def asadmin_command_prefix(context, options = {})
46
+ terse = options[:terse].nil? ? context.terse? : options[:terse]
47
+ echo = options[:echo].nil? ? context.echo? : options[:echo]
48
+ remote_command = options[:remote_command].nil? || !!options[:remote_command]
49
+
50
+ args = []
51
+ args << "--terse=#{terse}"
52
+ args << "--echo=#{echo}"
53
+ args << '--user' << context.domain_username.to_s if context.domain_username
54
+ args << "--passwordfile=#{context.domain_password_file}" if context.domain_password_file
55
+ if remote_command
56
+ args << '--secure' if context.domain_secure
57
+ args << '--port' << context.domain_admin_port.to_s
58
+ end
59
+ end
60
+
61
+ def asadmin_script(context)
62
+ "#{context.install_dir}/glassfish/bin/asadmin"
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,31 @@
1
+ module Redfish
2
+ class PropertyCache
3
+
4
+ def initialize(properties)
5
+ @properties = properties.dup
6
+ end
7
+
8
+ def any_property_start_with?(prefix)
9
+ regex = /^#{Regexp.escape(prefix)}/
10
+ raw_properties.keys.any? { |k| k =~ regex }
11
+ end
12
+
13
+ def []=(key, value)
14
+ raw_properties[key] = value
15
+ end
16
+
17
+ def [](key)
18
+ raw_properties[key] || ''
19
+ end
20
+
21
+ def properties
22
+ raw_properties.dup
23
+ end
24
+
25
+ private
26
+
27
+ def raw_properties
28
+ @properties
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,70 @@
1
+ module Redfish
2
+ module MetaDataHelper
3
+ def self.included(base)
4
+ class << base
5
+
6
+ def action(key, &block)
7
+ define_method("perform_#{key}") do
8
+ instance_eval(&block)
9
+ end
10
+ end
11
+
12
+ def attribute(key, options)
13
+ define_method("#{key}=") do |value|
14
+ kind_of = ([options[:kind_of]] || []).compact.flatten
15
+ if !kind_of.empty? && !kind_of.any?{|k| value.is_a?(k)}
16
+ raise "Invalid value passed to attribute '#{key}' expected to be one of #{kind_of.inspect} but is of type #{value.class.name}"
17
+ end
18
+ equal_to = options[:equal_to] || []
19
+ if !equal_to.empty? && !equal_to.any?{|v| value == v}
20
+ raise "Invalid value passed to attribute '#{key}' expected to be one of #{equal_to.inspect} but is #{value.inspect}"
21
+ end
22
+ instance_variable_set("@#{key}", value)
23
+ end
24
+
25
+ define_method(key) do
26
+ if instance_variable_defined?("@#{key}")
27
+ instance_variable_get("@#{key}")
28
+ elsif !options[:required].nil? && options[:required]
29
+ raise "Required attribute '#{key}' not specified"
30
+ else
31
+ options[:default]
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+
39
+ class Task
40
+ include MetaDataHelper
41
+
42
+ attr_writer :context
43
+
44
+ def initialize
45
+ @updated_by_last_action = false
46
+ yield self if block_given?
47
+ end
48
+
49
+ def context
50
+ raise 'No context associated with task' unless @context
51
+ @context
52
+ end
53
+
54
+ def perform_action(action)
55
+ method_name = "perform_#{action}"
56
+ raise "No such action #{action}" unless self.respond_to?(method_name)
57
+ self.send method_name
58
+ end
59
+
60
+ def updated_by_last_action?
61
+ !!@updated_by_last_action
62
+ end
63
+
64
+ protected
65
+
66
+ def updated_by_last_action
67
+ @updated_by_last_action = true
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,25 @@
1
+ module Redfish
2
+ module Tasks
3
+ class Property < Task
4
+
5
+ attribute :key, :kind_of => String, :required => true
6
+ attribute :value, :kind_of => String, :required => true
7
+
8
+ private
9
+
10
+ action :set do
11
+ cache_present = context.property_cache?
12
+ may_need_update = cache_present ? self.value != context.property_cache[self.key] : true
13
+ if may_need_update
14
+ if cache_present || !(/^#{Regexp.escape("#{self.key}=#{self.value}")}$/ =~ context.exec('get', ["#{self.key}"], :terse => true, :echo => false))
15
+ context.exec('set', ["#{self.key}=#{self.value}"], :terse => true, :echo => false)
16
+ updated_by_last_action
17
+ if cache_present
18
+ context.property_cache[self.key] = self.value
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,41 @@
1
+ module Redfish
2
+ module Tasks
3
+ class PropertyCache < Task
4
+
5
+ private
6
+
7
+ action :create do
8
+ output = context.exec('get', %w(*), :terse => true, :echo => false)
9
+
10
+ properties = {}
11
+ output.split("\n").each do |line|
12
+ index = line.index('=')
13
+ key = line[0, index]
14
+ value = line[index + 1, line.size]
15
+ properties[key] = value
16
+ end
17
+
18
+ skip = false
19
+ if context.property_cache?
20
+ if context.property_cache.properties != properties
21
+ context.remove_property_cache
22
+ else
23
+ skip = true
24
+ end
25
+ end
26
+
27
+ unless skip
28
+ context.cache_properties(properties)
29
+ updated_by_last_action
30
+ end
31
+ end
32
+
33
+ action :destroy do
34
+ if context.property_cache?
35
+ context.remove_property_cache
36
+ updated_by_last_action
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,3 @@
1
+ module Redfish
2
+ VERSION = '0.2.1'
3
+ end
@@ -0,0 +1,30 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path('../lib', __FILE__)
3
+ require 'redfish/version'
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = %q{redfish}
7
+ s.version = Redfish::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+
10
+ s.authors = ['Peter Donald']
11
+ s.email = %q{peter@realityforge.org}
12
+
13
+ s.homepage = %q{https://github.com/realityforge/redfish}
14
+ s.summary = %q{A lightweight library for configuring GlassFish/Payara servers.}
15
+ s.description = %q{A lightweight library for configuring GlassFish/Payara servers.}
16
+
17
+ s.rubyforge_project = %q{redfish}
18
+
19
+ s.files = `git ls-files`.split("\n")
20
+ s.test_files = `git ls-files -- {spec}/*`.split("\n")
21
+ s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
22
+ s.default_executable = []
23
+ s.require_paths = %w(lib)
24
+
25
+ s.has_rdoc = false
26
+ s.rdoc_options = %w(--line-numbers --inline-source --title redfish)
27
+
28
+ s.add_development_dependency(%q<minitest>, ['= 5.0.2'])
29
+ s.add_development_dependency(%q<mocha>, ['= 0.14.0'])
30
+ end
@@ -0,0 +1,16 @@
1
+ $:.unshift File.expand_path('../../lib', __FILE__)
2
+
3
+ require 'minitest/autorun'
4
+ require 'test/unit/assertions'
5
+ require 'mocha/setup'
6
+ require 'redfish'
7
+
8
+ class Redfish::TestCase < Minitest::Test
9
+ include Test::Unit::Assertions
10
+
11
+ def setup
12
+ end
13
+
14
+ def teardown
15
+ end
16
+ end
@@ -0,0 +1,69 @@
1
+ require File.expand_path('../../helper', __FILE__)
2
+
3
+ class Redfish::Tasks::TestProperty < Redfish::TestCase
4
+ def test_property_no_cache_and_not_set
5
+ executor = Redfish::Executor.new
6
+ t = new_property(executor)
7
+
8
+ executor.expects(:exec).with(equals(t.context),equals('get'),equals(%w(configs.config.server-config.security-service.activate-default-principal-to-role-mapping)),equals(:terse => true, :echo => false)).returns('')
9
+ executor.expects(:exec).with(equals(t.context),equals('set'),equals(%w(configs.config.server-config.security-service.activate-default-principal-to-role-mapping=true)),equals(:terse => true, :echo => false)).returns('')
10
+
11
+ t.key = 'configs.config.server-config.security-service.activate-default-principal-to-role-mapping'
12
+ t.value = 'true'
13
+ t.perform_action(:set)
14
+
15
+ assert_equal t.updated_by_last_action?, true
16
+ end
17
+
18
+ def test_property_no_cache_and_already_set
19
+ executor = Redfish::Executor.new
20
+ t = new_property(executor)
21
+
22
+ executor.expects(:exec).with(equals(t.context),equals('get'),equals(%w(configs.config.server-config.security-service.activate-default-principal-to-role-mapping)),equals(:terse => true, :echo => false)).returns('configs.config.server-config.security-service.activate-default-principal-to-role-mapping=true')
23
+
24
+ t.key = 'configs.config.server-config.security-service.activate-default-principal-to-role-mapping'
25
+ t.value = 'true'
26
+ t.perform_action(:set)
27
+
28
+ assert_equal t.updated_by_last_action?, false
29
+ end
30
+
31
+ def test_property_cache_and_not_set
32
+ executor = Redfish::Executor.new
33
+ t = new_property(executor)
34
+
35
+ t.context.cache_properties('configs.config.server-config.security-service.activate-default-principal-to-role-mapping' => 'false')
36
+
37
+ executor.expects(:exec).with(equals(t.context),equals('set'),equals(%w(configs.config.server-config.security-service.activate-default-principal-to-role-mapping=true)),equals(:terse => true, :echo => false)).returns('')
38
+
39
+ t.key = 'configs.config.server-config.security-service.activate-default-principal-to-role-mapping'
40
+ t.value = 'true'
41
+ t.perform_action(:set)
42
+
43
+ assert_equal t.updated_by_last_action?, true
44
+ assert_equal t.context.property_cache['configs.config.server-config.security-service.activate-default-principal-to-role-mapping'], 'true'
45
+ end
46
+
47
+ def test_property_cache_and_set
48
+ executor = Redfish::Executor.new
49
+ t = new_property(executor)
50
+
51
+ t.context.cache_properties('configs.config.server-config.security-service.activate-default-principal-to-role-mapping' => 'true')
52
+
53
+ t.key = 'configs.config.server-config.security-service.activate-default-principal-to-role-mapping'
54
+ t.value = 'true'
55
+ t.perform_action(:set)
56
+
57
+ assert_equal t.updated_by_last_action?, false
58
+ end
59
+
60
+ def new_property(executor)
61
+ t = Redfish::Tasks::Property.new
62
+ t.context = new_context(executor)
63
+ t
64
+ end
65
+
66
+ def new_context(executor)
67
+ Redfish::Context.new(executor, '/opt/payara-4.1.151/', 'domain1', 4848, false, 'admin', nil)
68
+ end
69
+ end
@@ -0,0 +1,89 @@
1
+ require File.expand_path('../../helper', __FILE__)
2
+
3
+ class Redfish::Tasks::TestPropertyCache < Redfish::TestCase
4
+ def test_create_no_existing
5
+ executor = Redfish::Executor.new
6
+ t = new_property_cache(executor)
7
+
8
+ executor.
9
+ expects(:exec).
10
+ with(equals(t.context),equals('get'),equals(%w(*)),equals(:terse => true, :echo => false)).
11
+ returns("a=1\nb=2\nc.d.e=345")
12
+
13
+ assert_equal t.context.property_cache?, false
14
+ t.perform_action(:create)
15
+ assert_equal t.updated_by_last_action?, true
16
+ assert_equal t.context.property_cache?, true
17
+ assert_equal t.context.property_cache['a'], '1'
18
+ assert_equal t.context.property_cache['b'], '2'
19
+ assert_equal t.context.property_cache['c.d.e'], '345'
20
+ end
21
+
22
+ def test_create_existing_no_match
23
+ executor = Redfish::Executor.new
24
+ t = new_property_cache(executor)
25
+
26
+ t.context.cache_properties('a' => '-1')
27
+
28
+ executor.
29
+ expects(:exec).
30
+ with(equals(t.context),equals('get'),equals(%w(*)),equals(:terse => true, :echo => false)).
31
+ returns("a=1\nb=2\nc.d.e=345")
32
+
33
+ assert_equal t.context.property_cache?, true
34
+ t.perform_action(:create)
35
+ assert_equal t.updated_by_last_action?, true
36
+ assert_equal t.context.property_cache?, true
37
+ assert_equal t.context.property_cache['a'], '1'
38
+ assert_equal t.context.property_cache['b'], '2'
39
+ assert_equal t.context.property_cache['c.d.e'], '345'
40
+ end
41
+
42
+ def test_create_existing_match
43
+ executor = Redfish::Executor.new
44
+ t = new_property_cache(executor)
45
+
46
+ t.context.cache_properties('a' => '1', 'b' => '2', 'c.d.e' => '345')
47
+
48
+ executor.
49
+ expects(:exec).
50
+ with(equals(t.context),equals('get'),equals(%w(*)),equals(:terse => true, :echo => false)).
51
+ returns("a=1\nb=2\nc.d.e=345")
52
+
53
+ assert_equal t.context.property_cache?, true
54
+ t.perform_action(:create)
55
+ assert_equal t.updated_by_last_action?, false
56
+ assert_equal t.context.property_cache?, true
57
+ assert_equal t.context.property_cache['a'], '1'
58
+ assert_equal t.context.property_cache['b'], '2'
59
+ assert_equal t.context.property_cache['c.d.e'], '345'
60
+ end
61
+
62
+ def test_destroy
63
+ executor = Redfish::Executor.new
64
+ t = new_property_cache(executor)
65
+
66
+ t.context.cache_properties('a' => '1', 'b' => '2', 'c.d.e' => '345')
67
+
68
+ assert_equal t.context.property_cache?, true
69
+ t.perform_action(:destroy)
70
+ assert_equal t.updated_by_last_action?, true
71
+ assert_equal t.context.property_cache?, false
72
+ end
73
+
74
+ def test_destroy_no_existing
75
+ executor = Redfish::Executor.new
76
+ t = new_property_cache(executor)
77
+
78
+ assert_equal t.context.property_cache?, false
79
+ t.perform_action(:destroy)
80
+ assert_equal t.updated_by_last_action?, false
81
+ assert_equal t.context.property_cache?, false
82
+ end
83
+
84
+ def new_property_cache(executor)
85
+ t = Redfish::Tasks::PropertyCache.new
86
+ t.context = Redfish::Context.new(executor, '/opt/payara-4.1.151/', 'domain1', 4848, false, 'admin', nil)
87
+ t
88
+ end
89
+ end
@@ -0,0 +1,70 @@
1
+ require File.expand_path('../helper', __FILE__)
2
+
3
+ class TestContext < Redfish::TestCase
4
+
5
+ def test_basic_workflow
6
+ install_dir = '/opt/glassfish'
7
+ domain_name = 'appserver'
8
+ domain_admin_port = 4848
9
+ domain_secure = true
10
+ domain_username = 'admin'
11
+ domain_password_file = '/etc/glassfish/password'
12
+ system_user = 'glassfish'
13
+ system_group = 'glassfish_group'
14
+
15
+ context = Redfish::Context.new(Redfish::Executor.new,
16
+ install_dir,
17
+ domain_name,
18
+ domain_admin_port,
19
+ domain_secure,
20
+ domain_username,
21
+ domain_password_file,
22
+ :system_user => system_user,
23
+ :system_group => system_group,
24
+ :terse => true,
25
+ :echo => true)
26
+
27
+ assert_equal context.domain_name, domain_name
28
+ assert_equal context.domain_admin_port, domain_admin_port
29
+ assert_equal context.domain_secure, domain_secure
30
+ assert_equal context.domain_username, domain_username
31
+ assert_equal context.domain_password_file, domain_password_file
32
+
33
+ assert_equal context.terse?, true
34
+ assert_equal context.echo?, true
35
+ assert_equal context.system_user, system_user
36
+ assert_equal context.system_group, system_group
37
+
38
+ assert !context.property_cache?
39
+ end
40
+
41
+ def test_property_caching
42
+ context = Redfish::Context.new(Redfish::Executor.new, '/opt/glassfish', 'appserver', 4848, true, 'admin', nil)
43
+
44
+ assert !context.property_cache?
45
+ context.cache_properties('a' => '1', 'b' => '2')
46
+ assert context.property_cache?
47
+ assert_equal context.property_cache['a'], '1'
48
+ assert_equal context.property_cache['b'], '2'
49
+
50
+ error = false
51
+ begin
52
+ context.cache_properties('a' => '1', 'b' => '2')
53
+ rescue
54
+ error = true
55
+ end
56
+ fail('Expected to fail to re-cache properties') unless error
57
+
58
+ context.remove_property_cache
59
+
60
+ assert !context.property_cache?
61
+
62
+ error = false
63
+ begin
64
+ context.remove_property_cache
65
+ rescue
66
+ error = true
67
+ end
68
+ fail('Expected to fail to remove property cache') unless error
69
+ end
70
+ end
@@ -0,0 +1,89 @@
1
+ require File.expand_path('../helper', __FILE__)
2
+
3
+ class TestExecutor < Redfish::TestCase
4
+ def test_asadmin_script
5
+ executor = Redfish::Executor.new
6
+ assert_equal '/opt/payara-4.1.151//glassfish/bin/asadmin', executor.send(:asadmin_script, new_context(executor))
7
+ end
8
+
9
+ def test_build_command
10
+ executor = Redfish::Executor.new
11
+ assert_equal %w(/opt/payara-4.1.151//glassfish/bin/asadmin --terse=true --echo=false --user admin --port 4848 set a=b),
12
+ executor.send(:build_command, new_context(executor), 'set', ['a=b'], :terse => true, :echo => false)
13
+
14
+ Etc.expects(:getlogin).returns('bob')
15
+ assert_equal %w(/usr/bin/sudo -u glassfish -g glassfish-group /opt/payara-4.1.151//glassfish/bin/asadmin --terse=false --echo=false --user admin --passwordfile=/etc/pass --secure --port 4848 set a=b),
16
+ executor.send(:build_command,
17
+ Redfish::Context.new(executor,
18
+ '/opt/payara-4.1.151/',
19
+ 'domain1',
20
+ 4848,
21
+ true,
22
+ 'admin',
23
+ '/etc/pass',
24
+ :system_user => 'glassfish',
25
+ :system_group => 'glassfish-group'),
26
+ 'set',
27
+ ['a=b'],
28
+ {})
29
+ end
30
+
31
+ def test_asadmin_command_prefix
32
+ executor = Redfish::Executor.new
33
+ assert_equal %w(--terse=false --echo=true --user admin --port 4848),
34
+ executor.send(:asadmin_command_prefix, new_context(executor))
35
+ assert_equal %w(--terse=true --echo=false --user admin --port 4848),
36
+ executor.send(:asadmin_command_prefix, new_context(executor), :terse => true, :echo => false)
37
+ assert_equal %w(--terse=false --echo=false --user admin --passwordfile=/etc/pass --secure --port 4848),
38
+ executor.send(:asadmin_command_prefix,
39
+ Redfish::Context.new(executor, '/opt/payara-4.1.151/', 'domain1', 4848, true, 'admin', '/etc/pass'))
40
+ end
41
+
42
+ def test_needs_user_change?
43
+ executor = Redfish::Executor.new
44
+ assert_equal false, executor.send(:needs_user_change?, new_context(executor))
45
+ context_with_users =
46
+ Redfish::Context.new(executor,
47
+ '/opt/payara-4.1.151/',
48
+ 'domain1',
49
+ 4848,
50
+ false,
51
+ 'admin',
52
+ nil,
53
+ :system_user => 'glassfish',
54
+ :system_group => 'glassfish-group')
55
+
56
+ Etc.expects(:getlogin).returns('bob')
57
+
58
+ assert_equal true, executor.send(:needs_user_change?, context_with_users)
59
+
60
+
61
+ Etc.expects(:getlogin).returns('glassfish')
62
+ group = 'group'
63
+ group.expects(:name).returns(group)
64
+ Etc.expects(:group).returns(group)
65
+
66
+ assert_equal true, executor.send(:needs_user_change?, context_with_users)
67
+
68
+ Etc.expects(:getlogin).returns('glassfish')
69
+ group = 'glassfish-group'
70
+ group.expects(:name).returns(group)
71
+ Etc.expects(:group).returns(group)
72
+
73
+ assert_equal false, executor.send(:needs_user_change?, context_with_users)
74
+ end
75
+
76
+ def test_exec
77
+ executor = Redfish::Executor.new
78
+
79
+ cmd = ['/opt/payara-4.1.151//glassfish/bin/asadmin', '--terse=false', '--echo=true', '--user', 'admin', '--port', '4848', 'set', 'a=1:b=2']
80
+ IO.expects(:popen).with(equals(cmd),equals('r'),anything)
81
+ executor.expects(:last_exitstatus).returns(0)
82
+
83
+ executor.exec(new_context(executor), 'set', ['a=1:b=2'])
84
+ end
85
+
86
+ def new_context(executor)
87
+ Redfish::Context.new(executor, '/opt/payara-4.1.151/', 'domain1', 4848, false, 'admin', nil, :terse => false, :echo => true)
88
+ end
89
+ end
@@ -0,0 +1,33 @@
1
+ require File.expand_path('../helper', __FILE__)
2
+
3
+ class TestPropertyCache < Redfish::TestCase
4
+ def test_properties_are_duplicated
5
+ input_data = {'a' => '1', 'b' => '2'}
6
+
7
+ cache = Redfish::PropertyCache.new(input_data)
8
+
9
+ # Data should be identical
10
+ assert_equal cache.properties, input_data
11
+
12
+ # Ensure input can not be modified to modify cache
13
+ input_data['a'] = '3'
14
+ assert_equal cache['a'], '1'
15
+
16
+ # Ensure cache does not modify input
17
+ cache['b'] = '4'
18
+ assert_equal input_data['b'], '2'
19
+
20
+ # properties accessor does a dup
21
+ cache.properties['b'] = '5'
22
+ assert_equal cache['b'], '4'
23
+ end
24
+
25
+ def test_any_property_start_with?
26
+ cache = Redfish::PropertyCache.new('a.b.c' => '1', 'a.b.d' => '2', 'a.c.e' => '2', 'xx' => '2')
27
+
28
+ assert cache.any_property_start_with?('a.b')
29
+ assert cache.any_property_start_with?('a.b.d')
30
+ assert !cache.any_property_start_with?('x.')
31
+ assert cache.any_property_start_with?('x')
32
+ end
33
+ end
@@ -0,0 +1,142 @@
1
+ require File.expand_path('../helper', __FILE__)
2
+
3
+ class TestTask < Redfish::TestCase
4
+ class MyTestTask < Redfish::Task
5
+ attribute :a, :kind_of => String, :required => true
6
+ attribute :b, :kind_of => [TrueClass, FalseClass], :default => false
7
+ attribute :c, :equal_to => [true, false, 'true', 'false'], :default => 'false'
8
+ attribute :d, :kind_of => String
9
+
10
+ attr_accessor :action1_ran
11
+ attr_accessor :action2_ran
12
+
13
+ private
14
+
15
+ action :action1 do
16
+ @action1_ran = true
17
+ end
18
+
19
+ action :action2 do
20
+ @action2_ran = true
21
+ updated_by_last_action
22
+ end
23
+
24
+ end
25
+
26
+ def test_required_raises_exception_if_unset
27
+ begin
28
+ new_task.a
29
+ rescue
30
+ return
31
+ end
32
+
33
+ fail('Expected to fail when accessing a before setting')
34
+ end
35
+
36
+
37
+ def test_invalid_value_by_kind_of
38
+ begin
39
+ new_task.a = 1
40
+ rescue => e
41
+ assert_equal e.to_s, "Invalid value passed to attribute 'a' expected to be one of [String] but is of type Fixnum"
42
+ return
43
+ end
44
+
45
+ fail('Expected to fail due to bad type')
46
+ end
47
+
48
+ def test_invalid_value_by_equal_to
49
+ begin
50
+ new_task.c = 1
51
+ rescue => e
52
+ assert_equal e.to_s, "Invalid value passed to attribute 'c' expected to be one of [true, false, \"true\", \"false\"] but is 1"
53
+ return
54
+ end
55
+
56
+ fail('Expected to fail due to bad type')
57
+ end
58
+
59
+ def test_invalid_value_by_kind_of_array
60
+ begin
61
+ new_task.b = 1
62
+ rescue => e
63
+ assert_equal e.to_s, "Invalid value passed to attribute 'b' expected to be one of [TrueClass, FalseClass] but is of type Fixnum"
64
+ return
65
+ end
66
+
67
+ fail('Expected to fail due to bad type')
68
+ end
69
+
70
+ def test_set
71
+ mt = new_task do |t|
72
+ t.a = 'a'
73
+ t.b = true
74
+ t.c = 'true'
75
+ t.d = 'XXX'
76
+ end
77
+
78
+ assert_equal mt.a, 'a'
79
+ assert_equal mt.b, true
80
+ assert_equal mt.c, 'true'
81
+ assert_equal mt.d, 'XXX'
82
+ end
83
+
84
+ def test_defaults
85
+ mt = new_task do |t|
86
+ t.a = 'a'
87
+ end
88
+
89
+ assert_equal mt.a, 'a'
90
+ assert_equal mt.b, false
91
+ assert_equal mt.c, 'false'
92
+ assert_equal mt.d, nil
93
+ end
94
+
95
+ def test_non_existent_action
96
+ mt = new_task do |t|
97
+ t.a = 'a'
98
+ end
99
+
100
+ begin
101
+ mt.perform_action(:B)
102
+ rescue => e
103
+ assert_equal e.to_s, "No such action B"
104
+ return
105
+ end
106
+
107
+ fail('Expected to fail due to bad action')
108
+ end
109
+
110
+ def test_action
111
+ mt = new_task do |t|
112
+ t.a = 'a'
113
+ end
114
+
115
+ assert_equal mt.action1_ran, nil
116
+ mt.perform_action(:action1)
117
+ assert_equal mt.action1_ran, true
118
+ assert_equal mt.updated_by_last_action?, false
119
+ end
120
+
121
+ def test_action_that_causes_update
122
+ mt = new_task do |t|
123
+ t.a = 'a'
124
+ end
125
+
126
+ assert_equal mt.action2_ran, nil
127
+ mt.perform_action(:action2)
128
+ assert_equal mt.action2_ran, true
129
+ assert_equal mt.updated_by_last_action?, true
130
+ end
131
+
132
+ def new_task
133
+ MyTestTask.new do |t|
134
+ t.context = new_context
135
+ yield t if block_given?
136
+ end
137
+ end
138
+
139
+ def new_context
140
+ Redfish::Context.new(Redfish::Executor.new, '/opt/payara-4.1.151/', 'domain1', 4848, false, 'admin', nil, :terse => false, :echo => true)
141
+ end
142
+ end
metadata ADDED
@@ -0,0 +1,99 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: redfish
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.1
5
+ platform: ruby
6
+ authors:
7
+ - Peter Donald
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-04-17 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: minitest
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '='
18
+ - !ruby/object:Gem::Version
19
+ version: 5.0.2
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '='
25
+ - !ruby/object:Gem::Version
26
+ version: 5.0.2
27
+ - !ruby/object:Gem::Dependency
28
+ name: mocha
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '='
32
+ - !ruby/object:Gem::Version
33
+ version: 0.14.0
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '='
39
+ - !ruby/object:Gem::Version
40
+ version: 0.14.0
41
+ description: A lightweight library for configuring GlassFish/Payara servers.
42
+ email: peter@realityforge.org
43
+ executables: []
44
+ extensions: []
45
+ extra_rdoc_files: []
46
+ files:
47
+ - ".gitattributes"
48
+ - ".gitignore"
49
+ - ".ruby-version"
50
+ - ".travis.yml"
51
+ - CONTRIBUTING.md
52
+ - Gemfile
53
+ - LICENSE
54
+ - README.md
55
+ - Rakefile
56
+ - lib/redfish.rb
57
+ - lib/redfish/context.rb
58
+ - lib/redfish/executor.rb
59
+ - lib/redfish/property_cache.rb
60
+ - lib/redfish/task.rb
61
+ - lib/redfish/tasks/property.rb
62
+ - lib/redfish/tasks/property_cache.rb
63
+ - lib/redfish/version.rb
64
+ - redfish.gemspec
65
+ - test/helper.rb
66
+ - test/tasks/test_property.rb
67
+ - test/tasks/test_property_cache.rb
68
+ - test/test_context.rb
69
+ - test/test_executor.rb
70
+ - test/test_property_cache.rb
71
+ - test/test_task.rb
72
+ homepage: https://github.com/realityforge/redfish
73
+ licenses: []
74
+ metadata: {}
75
+ post_install_message:
76
+ rdoc_options:
77
+ - "--line-numbers"
78
+ - "--inline-source"
79
+ - "--title"
80
+ - redfish
81
+ require_paths:
82
+ - lib
83
+ required_ruby_version: !ruby/object:Gem::Requirement
84
+ requirements:
85
+ - - ">="
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ required_rubygems_version: !ruby/object:Gem::Requirement
89
+ requirements:
90
+ - - ">="
91
+ - !ruby/object:Gem::Version
92
+ version: '0'
93
+ requirements: []
94
+ rubyforge_project: redfish
95
+ rubygems_version: 2.2.2
96
+ signing_key:
97
+ specification_version: 4
98
+ summary: A lightweight library for configuring GlassFish/Payara servers.
99
+ test_files: []