cuboid 0.0.0 → 0.0.1alpha
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/CHANGELOG.md +0 -0
- data/Gemfile +20 -5
- data/LICENSE.md +22 -0
- data/README.md +158 -19
- data/Rakefile +56 -3
- data/config/paths.yml +15 -0
- data/cuboid.gemspec +61 -23
- data/lib/cuboid.rb +96 -4
- data/lib/cuboid/application.rb +326 -0
- data/lib/cuboid/application/parts/data.rb +18 -0
- data/lib/cuboid/application/parts/report.rb +29 -0
- data/lib/cuboid/application/parts/state.rb +274 -0
- data/lib/cuboid/application/runtime.rb +25 -0
- data/lib/cuboid/banner.rb +13 -0
- data/lib/cuboid/data.rb +86 -0
- data/lib/cuboid/data/application.rb +52 -0
- data/lib/cuboid/error.rb +9 -0
- data/lib/cuboid/option_group.rb +129 -0
- data/lib/cuboid/option_groups.rb +8 -0
- data/lib/cuboid/option_groups/datastore.rb +23 -0
- data/lib/cuboid/option_groups/dispatcher.rb +38 -0
- data/lib/cuboid/option_groups/output.rb +14 -0
- data/lib/cuboid/option_groups/paths.rb +184 -0
- data/lib/cuboid/option_groups/report.rb +39 -0
- data/lib/cuboid/option_groups/rpc.rb +105 -0
- data/lib/cuboid/option_groups/scheduler.rb +27 -0
- data/lib/cuboid/option_groups/snapshot.rb +13 -0
- data/lib/cuboid/option_groups/system.rb +10 -0
- data/lib/cuboid/options.rb +254 -0
- data/lib/cuboid/processes.rb +13 -0
- data/lib/cuboid/processes/dispatchers.rb +140 -0
- data/lib/cuboid/processes/executables/base.rb +54 -0
- data/lib/cuboid/processes/executables/dispatcher.rb +5 -0
- data/lib/cuboid/processes/executables/instance.rb +12 -0
- data/lib/cuboid/processes/executables/rest_service.rb +13 -0
- data/lib/cuboid/processes/executables/scheduler.rb +5 -0
- data/lib/cuboid/processes/helpers.rb +4 -0
- data/lib/cuboid/processes/helpers/dispatchers.rb +23 -0
- data/lib/cuboid/processes/helpers/instances.rb +39 -0
- data/lib/cuboid/processes/helpers/processes.rb +23 -0
- data/lib/cuboid/processes/helpers/schedulers.rb +23 -0
- data/lib/cuboid/processes/instances.rb +203 -0
- data/lib/cuboid/processes/manager.rb +262 -0
- data/lib/cuboid/processes/schedulers.rb +128 -0
- data/lib/cuboid/report.rb +220 -0
- data/lib/cuboid/rest/server.rb +165 -0
- data/lib/cuboid/rest/server/instance_helpers.rb +99 -0
- data/lib/cuboid/rest/server/routes/dispatcher.rb +41 -0
- data/lib/cuboid/rest/server/routes/grid.rb +41 -0
- data/lib/cuboid/rest/server/routes/instances.rb +131 -0
- data/lib/cuboid/rest/server/routes/scheduler.rb +140 -0
- data/lib/cuboid/rpc/client.rb +3 -0
- data/lib/cuboid/rpc/client/base.rb +58 -0
- data/lib/cuboid/rpc/client/dispatcher.rb +58 -0
- data/lib/cuboid/rpc/client/instance.rb +100 -0
- data/lib/cuboid/rpc/client/instance/service.rb +37 -0
- data/lib/cuboid/rpc/client/scheduler.rb +46 -0
- data/lib/cuboid/rpc/serializer.rb +92 -0
- data/lib/cuboid/rpc/server/active_options.rb +38 -0
- data/lib/cuboid/rpc/server/application_wrapper.rb +138 -0
- data/lib/cuboid/rpc/server/base.rb +63 -0
- data/lib/cuboid/rpc/server/dispatcher.rb +317 -0
- data/lib/cuboid/rpc/server/dispatcher/node.rb +247 -0
- data/lib/cuboid/rpc/server/dispatcher/service.rb +145 -0
- data/lib/cuboid/rpc/server/instance.rb +338 -0
- data/lib/cuboid/rpc/server/output.rb +92 -0
- data/lib/cuboid/rpc/server/scheduler.rb +482 -0
- data/lib/cuboid/ruby.rb +4 -0
- data/lib/cuboid/ruby/array.rb +17 -0
- data/lib/cuboid/ruby/hash.rb +41 -0
- data/lib/cuboid/ruby/object.rb +32 -0
- data/lib/cuboid/snapshot.rb +186 -0
- data/lib/cuboid/state.rb +94 -0
- data/lib/cuboid/state/application.rb +309 -0
- data/lib/cuboid/state/options.rb +27 -0
- data/lib/cuboid/support.rb +11 -0
- data/lib/cuboid/support/buffer.rb +3 -0
- data/lib/cuboid/support/buffer/autoflush.rb +61 -0
- data/lib/cuboid/support/buffer/base.rb +91 -0
- data/lib/cuboid/support/cache.rb +7 -0
- data/lib/cuboid/support/cache/base.rb +226 -0
- data/lib/cuboid/support/cache/least_cost_replacement.rb +77 -0
- data/lib/cuboid/support/cache/least_recently_pushed.rb +21 -0
- data/lib/cuboid/support/cache/least_recently_used.rb +31 -0
- data/lib/cuboid/support/cache/preference.rb +31 -0
- data/lib/cuboid/support/cache/random_replacement.rb +20 -0
- data/lib/cuboid/support/crypto.rb +2 -0
- data/lib/cuboid/support/crypto/rsa_aes_cbc.rb +86 -0
- data/lib/cuboid/support/database.rb +5 -0
- data/lib/cuboid/support/database/base.rb +177 -0
- data/lib/cuboid/support/database/categorized_queue.rb +195 -0
- data/lib/cuboid/support/database/hash.rb +300 -0
- data/lib/cuboid/support/database/queue.rb +149 -0
- data/lib/cuboid/support/filter.rb +3 -0
- data/lib/cuboid/support/filter/base.rb +110 -0
- data/lib/cuboid/support/filter/set.rb +29 -0
- data/lib/cuboid/support/glob.rb +27 -0
- data/lib/cuboid/support/mixins.rb +8 -0
- data/lib/cuboid/support/mixins/observable.rb +99 -0
- data/lib/cuboid/support/mixins/parts.rb +20 -0
- data/lib/cuboid/support/mixins/profiler.rb +93 -0
- data/lib/cuboid/support/mixins/spec_instances.rb +65 -0
- data/lib/cuboid/support/mixins/terminal.rb +57 -0
- data/lib/cuboid/system.rb +119 -0
- data/lib/cuboid/system/platforms.rb +84 -0
- data/lib/cuboid/system/platforms/linux.rb +26 -0
- data/lib/cuboid/system/platforms/mixins/unix.rb +46 -0
- data/lib/cuboid/system/platforms/osx.rb +25 -0
- data/lib/cuboid/system/platforms/windows.rb +81 -0
- data/lib/cuboid/system/slots.rb +143 -0
- data/lib/cuboid/ui/output.rb +52 -0
- data/lib/cuboid/ui/output_interface.rb +43 -0
- data/lib/cuboid/ui/output_interface/abstract.rb +68 -0
- data/lib/cuboid/ui/output_interface/controls.rb +84 -0
- data/lib/cuboid/ui/output_interface/error_logging.rb +119 -0
- data/lib/cuboid/ui/output_interface/implemented.rb +58 -0
- data/lib/cuboid/ui/output_interface/personalization.rb +62 -0
- data/lib/cuboid/utilities.rb +155 -0
- data/lib/cuboid/version.rb +4 -3
- data/lib/version +1 -0
- data/logs/placeholder +0 -0
- data/spec/cuboid/application/parts/data_spec.rb +12 -0
- data/spec/cuboid/application/parts/report_spec.rb +6 -0
- data/spec/cuboid/application/parts/state_spec.rb +192 -0
- data/spec/cuboid/application/runtime_spec.rb +21 -0
- data/spec/cuboid/application_spec.rb +37 -0
- data/spec/cuboid/data/application_spec.rb +22 -0
- data/spec/cuboid/data_spec.rb +47 -0
- data/spec/cuboid/error_spec.rb +23 -0
- data/spec/cuboid/option_groups/datastore_spec.rb +54 -0
- data/spec/cuboid/option_groups/dispatcher_spec.rb +12 -0
- data/spec/cuboid/option_groups/output_spec.rb +11 -0
- data/spec/cuboid/option_groups/paths_spec.rb +184 -0
- data/spec/cuboid/option_groups/report_spec.rb +26 -0
- data/spec/cuboid/option_groups/rpc_spec.rb +53 -0
- data/spec/cuboid/option_groups/snapshot_spec.rb +26 -0
- data/spec/cuboid/option_groups/system.rb +12 -0
- data/spec/cuboid/options_spec.rb +218 -0
- data/spec/cuboid/report_spec.rb +221 -0
- data/spec/cuboid/rest/server_spec.rb +1205 -0
- data/spec/cuboid/rpc/client/base_spec.rb +151 -0
- data/spec/cuboid/rpc/client/dispatcher_spec.rb +13 -0
- data/spec/cuboid/rpc/client/instance_spec.rb +38 -0
- data/spec/cuboid/rpc/server/active_options_spec.rb +21 -0
- data/spec/cuboid/rpc/server/base_spec.rb +60 -0
- data/spec/cuboid/rpc/server/dispatcher/node_spec.rb +222 -0
- data/spec/cuboid/rpc/server/dispatcher/service_spec.rb +112 -0
- data/spec/cuboid/rpc/server/dispatcher_spec.rb +317 -0
- data/spec/cuboid/rpc/server/instance_spec.rb +307 -0
- data/spec/cuboid/rpc/server/output_spec.rb +32 -0
- data/spec/cuboid/rpc/server/scheduler_spec.rb +400 -0
- data/spec/cuboid/ruby/array_spec.rb +77 -0
- data/spec/cuboid/ruby/hash_spec.rb +63 -0
- data/spec/cuboid/ruby/object_spec.rb +22 -0
- data/spec/cuboid/snapshot_spec.rb +123 -0
- data/spec/cuboid/state/application_spec.rb +538 -0
- data/spec/cuboid/state/options_spec.rb +37 -0
- data/spec/cuboid/state_spec.rb +53 -0
- data/spec/cuboid/support/buffer/autoflush_spec.rb +78 -0
- data/spec/cuboid/support/buffer/base_spec.rb +193 -0
- data/spec/cuboid/support/cache/least_cost_replacement_spec.rb +61 -0
- data/spec/cuboid/support/cache/least_recently_pushed_spec.rb +90 -0
- data/spec/cuboid/support/cache/least_recently_used_spec.rb +80 -0
- data/spec/cuboid/support/cache/preference_spec.rb +37 -0
- data/spec/cuboid/support/cache/random_replacement_spec.rb +42 -0
- data/spec/cuboid/support/crypto/rsa_aes_cbc_spec.rb +28 -0
- data/spec/cuboid/support/database/categorized_queue_spec.rb +327 -0
- data/spec/cuboid/support/database/hash_spec.rb +204 -0
- data/spec/cuboid/support/database/scheduler_spec.rb +325 -0
- data/spec/cuboid/support/filter/set_spec.rb +19 -0
- data/spec/cuboid/support/glob_spec.rb +75 -0
- data/spec/cuboid/support/mixins/observable_spec.rb +95 -0
- data/spec/cuboid/system/platforms/linux_spec.rb +31 -0
- data/spec/cuboid/system/platforms/osx_spec.rb +32 -0
- data/spec/cuboid/system/platforms/windows_spec.rb +41 -0
- data/spec/cuboid/system/slots_spec.rb +202 -0
- data/spec/cuboid/system_spec.rb +105 -0
- data/spec/cuboid/utilities_spec.rb +131 -0
- data/spec/spec_helper.rb +46 -0
- data/spec/support/factories/placeholder +0 -0
- data/spec/support/factories/scan_report.rb +18 -0
- data/spec/support/fixtures/empty/placeholder +0 -0
- data/spec/support/fixtures/executables/node.rb +50 -0
- data/spec/support/fixtures/mock_app.rb +61 -0
- data/spec/support/fixtures/mock_app/test_service.rb +64 -0
- data/spec/support/fixtures/services/echo.rb +64 -0
- data/spec/support/helpers/framework.rb +3 -0
- data/spec/support/helpers/matchers.rb +5 -0
- data/spec/support/helpers/misc.rb +3 -0
- data/spec/support/helpers/paths.rb +15 -0
- data/spec/support/helpers/request_helpers.rb +38 -0
- data/spec/support/helpers/requires.rb +8 -0
- data/spec/support/helpers/resets.rb +52 -0
- data/spec/support/helpers/web_server.rb +15 -0
- data/spec/support/lib/factory.rb +107 -0
- data/spec/support/lib/web_server_client.rb +41 -0
- data/spec/support/lib/web_server_dispatcher.rb +25 -0
- data/spec/support/lib/web_server_manager.rb +118 -0
- data/spec/support/logs/placeholder +0 -0
- data/spec/support/pems/cacert.pem +37 -0
- data/spec/support/pems/client/cert.pem +37 -0
- data/spec/support/pems/client/foo-cert.pem +39 -0
- data/spec/support/pems/client/foo-key.pem +51 -0
- data/spec/support/pems/client/key.pem +51 -0
- data/spec/support/pems/server/cert.pem +37 -0
- data/spec/support/pems/server/key.pem +51 -0
- data/spec/support/reports/placeholder +0 -0
- data/spec/support/shared/application.rb +10 -0
- data/spec/support/shared/component.rb +31 -0
- data/spec/support/shared/component/options/base.rb +187 -0
- data/spec/support/shared/option_group.rb +98 -0
- data/spec/support/shared/support/cache.rb +419 -0
- data/spec/support/shared/support/filter.rb +143 -0
- data/spec/support/shared/system/platforms/base.rb +25 -0
- data/spec/support/shared/system/platforms/mixins/unix.rb +37 -0
- data/spec/support/snapshots/placeholder +0 -0
- metadata +566 -21
- data/.gitignore +0 -8
- data/bin/console +0 -15
- data/bin/setup +0 -8
@@ -0,0 +1,39 @@
|
|
1
|
+
module Cuboid::OptionGroups
|
2
|
+
|
3
|
+
# @author Tasos "Zapotek" Laskos <tasos.laskos@gmail.com>
|
4
|
+
class Report < Cuboid::OptionGroup
|
5
|
+
|
6
|
+
# @return [String]
|
7
|
+
# Directory or file path where to store the scan report.
|
8
|
+
attr_accessor :path
|
9
|
+
|
10
|
+
def initialize
|
11
|
+
@default_path = self.path = default_path
|
12
|
+
end
|
13
|
+
|
14
|
+
def path=( path )
|
15
|
+
return @path = @default_path if !path
|
16
|
+
|
17
|
+
if path.end_with?( '/' ) && !File.exist?( path )
|
18
|
+
raise ArgumentError,
|
19
|
+
"Snapshot location does not exist: #{path}"
|
20
|
+
end
|
21
|
+
|
22
|
+
path = File.expand_path( path )
|
23
|
+
if File.directory? path
|
24
|
+
path += '/' if !path.end_with? '/'
|
25
|
+
end
|
26
|
+
|
27
|
+
@path = path
|
28
|
+
end
|
29
|
+
|
30
|
+
def default_path
|
31
|
+
Paths.config['reports']
|
32
|
+
end
|
33
|
+
|
34
|
+
def defaults
|
35
|
+
{ path: default_path }
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,105 @@
|
|
1
|
+
module Cuboid::OptionGroups
|
2
|
+
|
3
|
+
# Holds {Engine::RPC::Client} and {Engine::RPC::Server} options.
|
4
|
+
#
|
5
|
+
# @author Tasos "Zapotek" Laskos <tasos.laskos@gmail.com>
|
6
|
+
class RPC < Cuboid::OptionGroup
|
7
|
+
|
8
|
+
# @return [String]
|
9
|
+
# Path to the UNIX socket to use for RPC communication.
|
10
|
+
#
|
11
|
+
# @see RPC::Server::Base
|
12
|
+
attr_accessor :server_socket
|
13
|
+
|
14
|
+
# @return [String]
|
15
|
+
# Hostname or IP address for the RPC server.
|
16
|
+
#
|
17
|
+
# @see RPC::Server::Base
|
18
|
+
attr_accessor :server_address
|
19
|
+
|
20
|
+
# @return [String]
|
21
|
+
# External (hostname or IP) address for the RPC server to advertise.
|
22
|
+
attr_accessor :server_external_address
|
23
|
+
|
24
|
+
# @return [Integer]
|
25
|
+
# RPC server port.
|
26
|
+
#
|
27
|
+
# @see RPC::Server::Base
|
28
|
+
attr_accessor :server_port
|
29
|
+
|
30
|
+
# @return [String]
|
31
|
+
# Path to an SSL certificate authority file in PEM format.
|
32
|
+
#
|
33
|
+
# @see RPC::Server::Base
|
34
|
+
# @see RPC::Client::Base
|
35
|
+
attr_accessor :ssl_ca
|
36
|
+
|
37
|
+
# @return [String]
|
38
|
+
# Path to a server SSL private key in PEM format.
|
39
|
+
#
|
40
|
+
# @see RPC::Server::Base
|
41
|
+
attr_accessor :server_ssl_private_key
|
42
|
+
|
43
|
+
# @return [String]
|
44
|
+
# Path to server SSL certificate in PEM format.
|
45
|
+
#
|
46
|
+
# @see RPC::Server::Base
|
47
|
+
attr_accessor :server_ssl_certificate
|
48
|
+
|
49
|
+
# @return [String]
|
50
|
+
# Path to a client SSL private key in PEM format.
|
51
|
+
#
|
52
|
+
# @see RPC::Client::Base
|
53
|
+
attr_accessor :client_ssl_private_key
|
54
|
+
|
55
|
+
# @return [String]
|
56
|
+
# Path to client SSL certificate in PEM format.
|
57
|
+
#
|
58
|
+
# @see RPC::Client::Base
|
59
|
+
attr_accessor :client_ssl_certificate
|
60
|
+
|
61
|
+
# @return [Integer]
|
62
|
+
# Maximum retries for failed RPC calls.
|
63
|
+
#
|
64
|
+
# @see RPC::Client::Base
|
65
|
+
attr_accessor :client_max_retries
|
66
|
+
|
67
|
+
# @note This should be permanently set to `1`, otherwise it will cause issues
|
68
|
+
# with the scheduling of the workload distribution of multi-Instance scans.
|
69
|
+
#
|
70
|
+
# @return [Integer]
|
71
|
+
# Amount of concurrently open connections for each RPC client.
|
72
|
+
#
|
73
|
+
# @see RPC::Client::Base
|
74
|
+
attr_accessor :connection_pool_size
|
75
|
+
|
76
|
+
set_defaults(
|
77
|
+
connection_pool_size: 1,
|
78
|
+
server_address: '127.0.0.1',
|
79
|
+
server_port: 7331
|
80
|
+
)
|
81
|
+
|
82
|
+
def to_client_options
|
83
|
+
{
|
84
|
+
connection_pool_size: connection_pool_size,
|
85
|
+
max_retries: client_max_retries,
|
86
|
+
ssl_ca: ssl_ca,
|
87
|
+
ssl_pkey: client_ssl_private_key,
|
88
|
+
ssl_cert: client_ssl_certificate
|
89
|
+
}
|
90
|
+
end
|
91
|
+
|
92
|
+
def to_server_options
|
93
|
+
{
|
94
|
+
host: server_address,
|
95
|
+
external_address: server_external_address,
|
96
|
+
port: server_port,
|
97
|
+
socket: server_socket,
|
98
|
+
ssl_ca: ssl_ca,
|
99
|
+
ssl_pkey: server_ssl_private_key,
|
100
|
+
ssl_cert: server_ssl_certificate
|
101
|
+
}
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
105
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Cuboid::OptionGroups
|
2
|
+
|
3
|
+
# Holds options for {RPC::Server::Scheduler} servers.
|
4
|
+
#
|
5
|
+
# @author Tasos "Zapotek" Laskos <tasos.laskos@gmail.com>
|
6
|
+
class Scheduler < Cuboid::OptionGroup
|
7
|
+
|
8
|
+
# @return [String]
|
9
|
+
# URL of a {RPC::Server::Scheduler}.
|
10
|
+
attr_accessor :url
|
11
|
+
|
12
|
+
# @return [Array<Integer>]
|
13
|
+
# Range of ports to use when spawning instances, first entry should be
|
14
|
+
# the lowest port number, last the max port number.
|
15
|
+
attr_accessor :instance_port_range
|
16
|
+
|
17
|
+
# @return [Float]
|
18
|
+
# How regularly to check for scan statuses.
|
19
|
+
attr_accessor :ping_interval
|
20
|
+
|
21
|
+
set_defaults(
|
22
|
+
ping_interval: 5.0,
|
23
|
+
instance_port_range: [1025, 65535]
|
24
|
+
)
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,254 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
require 'singleton'
|
3
|
+
|
4
|
+
require_relative 'error'
|
5
|
+
require_relative 'utilities'
|
6
|
+
|
7
|
+
module Cuboid
|
8
|
+
|
9
|
+
# @author Tasos "Zapotek" Laskos <tasos.laskos@gmail.com>
|
10
|
+
# @see OptionGroups
|
11
|
+
class Options
|
12
|
+
include Singleton
|
13
|
+
|
14
|
+
def self.attr_accessor(*vars)
|
15
|
+
@attr_accessors ||= []
|
16
|
+
@attr_accessors |= vars
|
17
|
+
super( *vars )
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.attr_accessors
|
21
|
+
@attr_accessors
|
22
|
+
end
|
23
|
+
|
24
|
+
def attr_accessors
|
25
|
+
self.class.attr_accessors
|
26
|
+
end
|
27
|
+
|
28
|
+
# {Options} error namespace.
|
29
|
+
#
|
30
|
+
# All {Options} errors inherit from and live under it.
|
31
|
+
#
|
32
|
+
# @author Tasos "Zapotek" Laskos <tasos.laskos@gmail.com>
|
33
|
+
class Error < Cuboid::Error
|
34
|
+
end
|
35
|
+
|
36
|
+
class <<self
|
37
|
+
|
38
|
+
def method_missing( sym, *args, &block )
|
39
|
+
if instance.respond_to?( sym )
|
40
|
+
instance.send( sym, *args, &block )
|
41
|
+
else
|
42
|
+
super( sym, *args, &block )
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def respond_to?( *args )
|
47
|
+
super || instance.respond_to?( *args )
|
48
|
+
end
|
49
|
+
|
50
|
+
# Ruby 2.0 doesn't like my class-level method_missing for some reason.
|
51
|
+
# @private
|
52
|
+
public :allocate
|
53
|
+
|
54
|
+
# @return [Hash<Symbol,OptionGroup>]
|
55
|
+
# {OptionGroups Option group} classes by name.
|
56
|
+
def group_classes
|
57
|
+
@group_classes ||= {}
|
58
|
+
end
|
59
|
+
|
60
|
+
# Should be called by {OptionGroup.inherited}.
|
61
|
+
# @private
|
62
|
+
def register_group( group )
|
63
|
+
name = Utilities.caller_name
|
64
|
+
|
65
|
+
# Prepare an attribute reader for this group...
|
66
|
+
attr_reader name
|
67
|
+
|
68
|
+
# ... and initialize it.
|
69
|
+
instance_variable_set "@#{name}".to_sym, group.new
|
70
|
+
|
71
|
+
group_classes[name.to_sym] = group
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
# Load all {OptionGroups}.
|
76
|
+
require_relative 'option_groups'
|
77
|
+
|
78
|
+
TO_RPC_IGNORE = Set.new([
|
79
|
+
:instance, :rpc, :dispatcher, :queue, :paths,
|
80
|
+
:snapshot, :report, :output, :system
|
81
|
+
])
|
82
|
+
|
83
|
+
TO_HASH_IGNORE = Set.new([ :instance ])
|
84
|
+
|
85
|
+
|
86
|
+
# @return [String]
|
87
|
+
# E-mail address of the person that authorized the run.
|
88
|
+
#
|
89
|
+
# @see HTTP::Client#headers
|
90
|
+
attr_accessor :authorized_by
|
91
|
+
|
92
|
+
attr_accessor :application
|
93
|
+
|
94
|
+
def initialize
|
95
|
+
reset
|
96
|
+
end
|
97
|
+
|
98
|
+
# Restores everything to their default values.
|
99
|
+
#
|
100
|
+
# @return [Options] `self`
|
101
|
+
def reset
|
102
|
+
# nil everything out.
|
103
|
+
instance_variables.each { |var| instance_variable_set( var.to_s, nil ) }
|
104
|
+
|
105
|
+
# Set fresh option groups.
|
106
|
+
group_classes.each do |name, klass|
|
107
|
+
instance_variable_set "@#{name}".to_sym, klass.new
|
108
|
+
end
|
109
|
+
|
110
|
+
@authorized_by = nil
|
111
|
+
|
112
|
+
self
|
113
|
+
end
|
114
|
+
|
115
|
+
|
116
|
+
# Configures options via a Hash object.
|
117
|
+
#
|
118
|
+
# @param [Hash] options
|
119
|
+
# If the key refers to a class attribute, the attribute will be assigned
|
120
|
+
# the given value, if it refers to one of the {OptionGroups} the value
|
121
|
+
# should be a hash with data to update that {OptionGroup group} using
|
122
|
+
# {OptionGroup#update}.
|
123
|
+
#
|
124
|
+
# @return [Options]
|
125
|
+
#
|
126
|
+
# @see OptionGroups
|
127
|
+
def update( options )
|
128
|
+
options.each do |k, v|
|
129
|
+
k = k.to_sym
|
130
|
+
if group_classes.include? k
|
131
|
+
send( k ).update v
|
132
|
+
else
|
133
|
+
send( "#{k.to_s}=", v )
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
self
|
138
|
+
end
|
139
|
+
alias :set :update
|
140
|
+
|
141
|
+
# @return [Hash]
|
142
|
+
# Hash of errors with the name of the invalid options/groups as the keys.
|
143
|
+
def validate
|
144
|
+
errors = {}
|
145
|
+
group_classes.keys.each do |name|
|
146
|
+
next if (group_errors = send(name).validate).empty?
|
147
|
+
errors[name] = group_errors
|
148
|
+
end
|
149
|
+
errors
|
150
|
+
end
|
151
|
+
|
152
|
+
# @param [String] file
|
153
|
+
# Saves `self` to `file` using YAML.
|
154
|
+
def save( file )
|
155
|
+
File.open( file, 'w' ) do |f|
|
156
|
+
f.write to_save_data
|
157
|
+
f.path
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
def to_save_data
|
162
|
+
to_rpc_data.to_yaml
|
163
|
+
end
|
164
|
+
|
165
|
+
def to_save_data_without_defaults
|
166
|
+
to_rpc_data_without_defaults.to_yaml
|
167
|
+
end
|
168
|
+
|
169
|
+
# Loads a file created by {#save}.
|
170
|
+
#
|
171
|
+
# @param [String] filepath
|
172
|
+
# Path to the file created by {#save}.
|
173
|
+
#
|
174
|
+
# @return [Cuboid::Options]
|
175
|
+
def load( filepath )
|
176
|
+
update( YAML.load_file( filepath ) )
|
177
|
+
end
|
178
|
+
|
179
|
+
# @return [Hash]
|
180
|
+
# `self` converted to a Hash suitable for RPC transmission.
|
181
|
+
def to_rpc_data
|
182
|
+
hash = {}
|
183
|
+
instance_variables.each do |var|
|
184
|
+
val = instance_variable_get( var )
|
185
|
+
var = normalize_name( var )
|
186
|
+
|
187
|
+
next if TO_RPC_IGNORE.include?( var )
|
188
|
+
|
189
|
+
hash[var.to_s] = (val.is_a? OptionGroup) ? val.to_rpc_data : val
|
190
|
+
end
|
191
|
+
hash.deep_clone
|
192
|
+
end
|
193
|
+
|
194
|
+
def to_rpc_data_without_defaults
|
195
|
+
defaults = self.class.allocate.reset.to_rpc_data
|
196
|
+
to_rpc_data.reject { |k, v| defaults[k] == v }
|
197
|
+
end
|
198
|
+
|
199
|
+
# @return [Hash]
|
200
|
+
# `self` converted to a Hash.
|
201
|
+
def to_hash
|
202
|
+
hash = {}
|
203
|
+
instance_variables.each do |var|
|
204
|
+
val = instance_variable_get( var )
|
205
|
+
var = normalize_name( var )
|
206
|
+
|
207
|
+
next if TO_HASH_IGNORE.include?( var )
|
208
|
+
|
209
|
+
hash[var] = (val.is_a? OptionGroup) ? val.to_h : val
|
210
|
+
end
|
211
|
+
|
212
|
+
hash.deep_clone
|
213
|
+
end
|
214
|
+
alias :to_h :to_hash
|
215
|
+
|
216
|
+
# @param [Hash] hash
|
217
|
+
# Hash to convert into {#to_hash} format.
|
218
|
+
#
|
219
|
+
# @return [Hash]
|
220
|
+
# `hash` in {#to_hash} format.
|
221
|
+
def rpc_data_to_hash( hash )
|
222
|
+
self.class.allocate.reset.update( hash ).to_hash.
|
223
|
+
reject { |k| TO_RPC_IGNORE.include? k }
|
224
|
+
end
|
225
|
+
|
226
|
+
# @param [Hash] hash
|
227
|
+
# Hash to convert into {#to_rpc_data} format.
|
228
|
+
#
|
229
|
+
# @return [Hash]
|
230
|
+
# `hash` in {#to_rpc_data} format.
|
231
|
+
def hash_to_rpc_data( hash )
|
232
|
+
self.class.allocate.reset.update( hash ).to_rpc_data
|
233
|
+
end
|
234
|
+
|
235
|
+
def hash_to_save_data( hash )
|
236
|
+
self.class.allocate.reset.update( hash ).to_save_data
|
237
|
+
end
|
238
|
+
|
239
|
+
def dup
|
240
|
+
self.class.allocate.reset.update( self.to_h )
|
241
|
+
end
|
242
|
+
|
243
|
+
private
|
244
|
+
|
245
|
+
def group_classes
|
246
|
+
self.class.group_classes
|
247
|
+
end
|
248
|
+
|
249
|
+
def normalize_name( name )
|
250
|
+
name.to_s.gsub( '@', '' ).to_sym
|
251
|
+
end
|
252
|
+
|
253
|
+
end
|
254
|
+
end
|