leap_cli 1.8.1 → 1.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (65) hide show
  1. checksums.yaml +4 -4
  2. data/bin/leap +6 -12
  3. data/lib/leap_cli.rb +3 -23
  4. data/lib/leap_cli/bootstrap.rb +36 -12
  5. data/lib/leap_cli/commands/common.rb +88 -46
  6. data/lib/leap_cli/commands/new.rb +24 -17
  7. data/lib/leap_cli/commands/pre.rb +3 -1
  8. data/lib/leap_cli/core_ext/hash.rb +19 -0
  9. data/lib/leap_cli/leapfile.rb +47 -32
  10. data/lib/leap_cli/log.rb +196 -88
  11. data/lib/leap_cli/path.rb +5 -5
  12. data/lib/leap_cli/util.rb +28 -18
  13. data/lib/leap_cli/version.rb +8 -3
  14. data/vendor/acme-client/lib/acme-client.rb +1 -0
  15. data/vendor/acme-client/lib/acme/client.rb +122 -0
  16. data/vendor/acme-client/lib/acme/client/certificate.rb +30 -0
  17. data/vendor/acme-client/lib/acme/client/certificate_request.rb +111 -0
  18. data/vendor/acme-client/lib/acme/client/crypto.rb +98 -0
  19. data/vendor/acme-client/lib/acme/client/error.rb +16 -0
  20. data/vendor/acme-client/lib/acme/client/faraday_middleware.rb +123 -0
  21. data/vendor/acme-client/lib/acme/client/resources.rb +5 -0
  22. data/vendor/acme-client/lib/acme/client/resources/authorization.rb +44 -0
  23. data/vendor/acme-client/lib/acme/client/resources/challenges.rb +6 -0
  24. data/vendor/acme-client/lib/acme/client/resources/challenges/base.rb +43 -0
  25. data/vendor/acme-client/lib/acme/client/resources/challenges/dns01.rb +19 -0
  26. data/vendor/acme-client/lib/acme/client/resources/challenges/http01.rb +18 -0
  27. data/vendor/acme-client/lib/acme/client/resources/challenges/tls_sni01.rb +24 -0
  28. data/vendor/acme-client/lib/acme/client/resources/registration.rb +37 -0
  29. data/vendor/acme-client/lib/acme/client/self_sign_certificate.rb +60 -0
  30. data/vendor/acme-client/lib/acme/client/version.rb +7 -0
  31. data/vendor/base32/lib/base32.rb +67 -0
  32. data/vendor/certificate_authority/lib/certificate_authority.rb +2 -1
  33. data/vendor/certificate_authority/lib/certificate_authority/certificate.rb +4 -4
  34. data/vendor/certificate_authority/lib/certificate_authority/certificate_revocation_list.rb +7 -5
  35. data/vendor/certificate_authority/lib/certificate_authority/core_extensions.rb +46 -0
  36. data/vendor/certificate_authority/lib/certificate_authority/distinguished_name.rb +6 -2
  37. data/vendor/certificate_authority/lib/certificate_authority/extensions.rb +10 -3
  38. data/vendor/certificate_authority/lib/certificate_authority/key_material.rb +11 -9
  39. data/vendor/certificate_authority/lib/certificate_authority/ocsp_handler.rb +3 -3
  40. data/vendor/certificate_authority/lib/certificate_authority/pkcs11_key_material.rb +0 -2
  41. data/vendor/certificate_authority/lib/certificate_authority/serial_number.rb +8 -2
  42. data/vendor/certificate_authority/lib/certificate_authority/validations.rb +31 -0
  43. data/vendor/rsync_command/lib/rsync_command.rb +49 -12
  44. metadata +50 -91
  45. data/lib/leap/platform.rb +0 -90
  46. data/lib/leap_cli/config/environment.rb +0 -180
  47. data/lib/leap_cli/config/filter.rb +0 -178
  48. data/lib/leap_cli/config/manager.rb +0 -419
  49. data/lib/leap_cli/config/node.rb +0 -77
  50. data/lib/leap_cli/config/object.rb +0 -428
  51. data/lib/leap_cli/config/object_list.rb +0 -209
  52. data/lib/leap_cli/config/provider.rb +0 -22
  53. data/lib/leap_cli/config/secrets.rb +0 -87
  54. data/lib/leap_cli/config/sources.rb +0 -11
  55. data/lib/leap_cli/config/tag.rb +0 -25
  56. data/lib/leap_cli/lib_ext/capistrano_connections.rb +0 -16
  57. data/lib/leap_cli/logger.rb +0 -237
  58. data/lib/leap_cli/remote/leap_plugin.rb +0 -192
  59. data/lib/leap_cli/remote/puppet_plugin.rb +0 -26
  60. data/lib/leap_cli/remote/rsync_plugin.rb +0 -35
  61. data/lib/leap_cli/remote/tasks.rb +0 -51
  62. data/lib/leap_cli/ssh_key.rb +0 -195
  63. data/lib/leap_cli/util/remote_command.rb +0 -158
  64. data/lib/leap_cli/util/secret.rb +0 -55
  65. data/lib/leap_cli/util/x509.rb +0 -33
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: leap_cli
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.8.1
4
+ version: '1.9'
5
5
  platform: ruby
6
6
  authors:
7
7
  - LEAP Encryption Access Project
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-09-01 00:00:00.000000000 Z
11
+ date: 2016-10-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: minitest
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '5.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '11.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '11.0'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: gli
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -45,75 +59,53 @@ dependencies:
45
59
  - !ruby/object:Gem::Version
46
60
  version: 2.12.0
47
61
  - !ruby/object:Gem::Dependency
48
- name: command_line_reporter
62
+ name: sshkit
49
63
  requirement: !ruby/object:Gem::Requirement
50
64
  requirements:
51
65
  - - "~>"
52
66
  - !ruby/object:Gem::Version
53
- version: '3.3'
67
+ version: '1.11'
54
68
  type: :runtime
55
69
  prerelease: false
56
70
  version_requirements: !ruby/object:Gem::Requirement
57
71
  requirements:
58
72
  - - "~>"
59
73
  - !ruby/object:Gem::Version
60
- version: '3.3'
74
+ version: '1.11'
61
75
  - !ruby/object:Gem::Dependency
62
- name: highline
76
+ name: fog-aws
63
77
  requirement: !ruby/object:Gem::Requirement
64
78
  requirements:
65
79
  - - "~>"
66
80
  - !ruby/object:Gem::Version
67
- version: '1.6'
81
+ version: '0.11'
68
82
  type: :runtime
69
83
  prerelease: false
70
84
  version_requirements: !ruby/object:Gem::Requirement
71
85
  requirements:
72
86
  - - "~>"
73
87
  - !ruby/object:Gem::Version
74
- version: '1.6'
88
+ version: '0.11'
75
89
  - !ruby/object:Gem::Dependency
76
- name: paint
90
+ name: faraday
77
91
  requirement: !ruby/object:Gem::Requirement
78
92
  requirements:
79
93
  - - "~>"
80
94
  - !ruby/object:Gem::Version
81
95
  version: '0.9'
82
- type: :runtime
83
- prerelease: false
84
- version_requirements: !ruby/object:Gem::Requirement
85
- requirements:
86
- - - "~>"
87
- - !ruby/object:Gem::Version
88
- version: '0.9'
89
- - !ruby/object:Gem::Dependency
90
- name: net-ssh
91
- requirement: !ruby/object:Gem::Requirement
92
- requirements:
93
- - - "~>"
96
+ - - ">="
94
97
  - !ruby/object:Gem::Version
95
- version: '2.7'
98
+ version: 0.9.1
96
99
  type: :runtime
97
100
  prerelease: false
98
101
  version_requirements: !ruby/object:Gem::Requirement
99
102
  requirements:
100
103
  - - "~>"
101
104
  - !ruby/object:Gem::Version
102
- version: '2.7'
103
- - !ruby/object:Gem::Dependency
104
- name: capistrano
105
- requirement: !ruby/object:Gem::Requirement
106
- requirements:
107
- - - "~>"
108
- - !ruby/object:Gem::Version
109
- version: '2.15'
110
- type: :runtime
111
- prerelease: false
112
- version_requirements: !ruby/object:Gem::Requirement
113
- requirements:
114
- - - "~>"
105
+ version: '0.9'
106
+ - - ">="
115
107
  - !ruby/object:Gem::Version
116
- version: '2.15'
108
+ version: 0.9.1
117
109
  - !ruby/object:Gem::Dependency
118
110
  name: ya2yaml
119
111
  requirement: !ruby/object:Gem::Requirement
@@ -142,40 +134,6 @@ dependencies:
142
134
  - - "~>"
143
135
  - !ruby/object:Gem::Version
144
136
  version: '1.8'
145
- - !ruby/object:Gem::Dependency
146
- name: base32
147
- requirement: !ruby/object:Gem::Requirement
148
- requirements:
149
- - - "~>"
150
- - !ruby/object:Gem::Version
151
- version: '0.3'
152
- type: :runtime
153
- prerelease: false
154
- version_requirements: !ruby/object:Gem::Requirement
155
- requirements:
156
- - - "~>"
157
- - !ruby/object:Gem::Version
158
- version: '0.3'
159
- - !ruby/object:Gem::Dependency
160
- name: activemodel
161
- requirement: !ruby/object:Gem::Requirement
162
- requirements:
163
- - - "~>"
164
- - !ruby/object:Gem::Version
165
- version: '3.0'
166
- - - ">="
167
- - !ruby/object:Gem::Version
168
- version: 3.0.6
169
- type: :runtime
170
- prerelease: false
171
- version_requirements: !ruby/object:Gem::Requirement
172
- requirements:
173
- - - "~>"
174
- - !ruby/object:Gem::Version
175
- version: '3.0'
176
- - - ">="
177
- - !ruby/object:Gem::Version
178
- version: 3.0.6
179
137
  description: The command "leap" can be used to manage a bevy of servers running the
180
138
  LEAP platform from the comfort of your own home.
181
139
  email: root@leap.se
@@ -185,22 +143,11 @@ extensions: []
185
143
  extra_rdoc_files: []
186
144
  files:
187
145
  - bin/leap
188
- - lib/leap/platform.rb
189
146
  - lib/leap_cli.rb
190
147
  - lib/leap_cli/bootstrap.rb
191
148
  - lib/leap_cli/commands/common.rb
192
149
  - lib/leap_cli/commands/new.rb
193
150
  - lib/leap_cli/commands/pre.rb
194
- - lib/leap_cli/config/environment.rb
195
- - lib/leap_cli/config/filter.rb
196
- - lib/leap_cli/config/manager.rb
197
- - lib/leap_cli/config/node.rb
198
- - lib/leap_cli/config/object.rb
199
- - lib/leap_cli/config/object_list.rb
200
- - lib/leap_cli/config/provider.rb
201
- - lib/leap_cli/config/secrets.rb
202
- - lib/leap_cli/config/sources.rb
203
- - lib/leap_cli/config/tag.rb
204
151
  - lib/leap_cli/core_ext/boolean.rb
205
152
  - lib/leap_cli/core_ext/deep_dup.rb
206
153
  - lib/leap_cli/core_ext/hash.rb
@@ -211,27 +158,36 @@ files:
211
158
  - lib/leap_cli/core_ext/yaml.rb
212
159
  - lib/leap_cli/exceptions.rb
213
160
  - lib/leap_cli/leapfile.rb
214
- - lib/leap_cli/lib_ext/capistrano_connections.rb
215
161
  - lib/leap_cli/lib_ext/gli.rb
216
162
  - lib/leap_cli/load_paths.rb
217
163
  - lib/leap_cli/log.rb
218
- - lib/leap_cli/logger.rb
219
164
  - lib/leap_cli/markdown_document_listener.rb
220
165
  - lib/leap_cli/override/json.rb
221
166
  - lib/leap_cli/path.rb
222
- - lib/leap_cli/remote/leap_plugin.rb
223
- - lib/leap_cli/remote/puppet_plugin.rb
224
- - lib/leap_cli/remote/rsync_plugin.rb
225
- - lib/leap_cli/remote/tasks.rb
226
- - lib/leap_cli/ssh_key.rb
227
167
  - lib/leap_cli/util.rb
228
- - lib/leap_cli/util/remote_command.rb
229
- - lib/leap_cli/util/secret.rb
230
- - lib/leap_cli/util/x509.rb
231
168
  - lib/leap_cli/version.rb
169
+ - vendor/acme-client/lib/acme-client.rb
170
+ - vendor/acme-client/lib/acme/client.rb
171
+ - vendor/acme-client/lib/acme/client/certificate.rb
172
+ - vendor/acme-client/lib/acme/client/certificate_request.rb
173
+ - vendor/acme-client/lib/acme/client/crypto.rb
174
+ - vendor/acme-client/lib/acme/client/error.rb
175
+ - vendor/acme-client/lib/acme/client/faraday_middleware.rb
176
+ - vendor/acme-client/lib/acme/client/resources.rb
177
+ - vendor/acme-client/lib/acme/client/resources/authorization.rb
178
+ - vendor/acme-client/lib/acme/client/resources/challenges.rb
179
+ - vendor/acme-client/lib/acme/client/resources/challenges/base.rb
180
+ - vendor/acme-client/lib/acme/client/resources/challenges/dns01.rb
181
+ - vendor/acme-client/lib/acme/client/resources/challenges/http01.rb
182
+ - vendor/acme-client/lib/acme/client/resources/challenges/tls_sni01.rb
183
+ - vendor/acme-client/lib/acme/client/resources/registration.rb
184
+ - vendor/acme-client/lib/acme/client/self_sign_certificate.rb
185
+ - vendor/acme-client/lib/acme/client/version.rb
186
+ - vendor/base32/lib/base32.rb
232
187
  - vendor/certificate_authority/lib/certificate_authority.rb
233
188
  - vendor/certificate_authority/lib/certificate_authority/certificate.rb
234
189
  - vendor/certificate_authority/lib/certificate_authority/certificate_revocation_list.rb
190
+ - vendor/certificate_authority/lib/certificate_authority/core_extensions.rb
235
191
  - vendor/certificate_authority/lib/certificate_authority/distinguished_name.rb
236
192
  - vendor/certificate_authority/lib/certificate_authority/extensions.rb
237
193
  - vendor/certificate_authority/lib/certificate_authority/key_material.rb
@@ -241,6 +197,7 @@ files:
241
197
  - vendor/certificate_authority/lib/certificate_authority/serial_number.rb
242
198
  - vendor/certificate_authority/lib/certificate_authority/signing_entity.rb
243
199
  - vendor/certificate_authority/lib/certificate_authority/signing_request.rb
200
+ - vendor/certificate_authority/lib/certificate_authority/validations.rb
244
201
  - vendor/rsync_command/lib/rsync_command.rb
245
202
  - vendor/rsync_command/lib/rsync_command/ssh_options.rb
246
203
  - vendor/rsync_command/lib/rsync_command/thread_pool.rb
@@ -260,6 +217,8 @@ require_paths:
260
217
  - lib
261
218
  - vendor/certificate_authority/lib
262
219
  - vendor/rsync_command/lib
220
+ - vendor/base32/lib
221
+ - vendor/acme-client/lib
263
222
  required_ruby_version: !ruby/object:Gem::Requirement
264
223
  requirements:
265
224
  - - ">="
data/lib/leap/platform.rb DELETED
@@ -1,90 +0,0 @@
1
- module Leap
2
-
3
- class Platform
4
- class << self
5
- #
6
- # configuration
7
- #
8
-
9
- attr_reader :version
10
- attr_reader :compatible_cli
11
- attr_accessor :facts
12
- attr_accessor :paths
13
- attr_accessor :node_files
14
- attr_accessor :monitor_username
15
- attr_accessor :reserved_usernames
16
-
17
- attr_accessor :hiera_dir
18
- attr_accessor :hiera_path
19
- attr_accessor :files_dir
20
- attr_accessor :leap_dir
21
- attr_accessor :init_path
22
-
23
- attr_accessor :default_puppet_tags
24
-
25
- def define(&block)
26
- # some defaults:
27
- @reserved_usernames = []
28
- @hiera_dir = '/etc/leap'
29
- @hiera_path = '/etc/leap/hiera.yaml'
30
- @leap_dir = '/srv/leap'
31
- @files_dir = '/srv/leap/files'
32
- @init_path = '/srv/leap/initialized'
33
- @default_puppet_tags = []
34
-
35
- self.instance_eval(&block)
36
-
37
- @version ||= Gem::Version.new("0.0")
38
- end
39
-
40
- def version=(version)
41
- @version = Gem::Version.new(version)
42
- end
43
-
44
- def compatible_cli=(range)
45
- @compatible_cli = range
46
- @minimum_cli_version = Gem::Version.new(range.first)
47
- @maximum_cli_version = Gem::Version.new(range.last)
48
- end
49
-
50
- #
51
- # return true if the cli_version is compatible with this platform.
52
- #
53
- def compatible_with_cli?(cli_version)
54
- cli_version = Gem::Version.new(cli_version)
55
- cli_version >= @minimum_cli_version && cli_version <= @maximum_cli_version
56
- end
57
-
58
- #
59
- # return true if the platform version is within the specified range.
60
- #
61
- def version_in_range?(range)
62
- if range.is_a? String
63
- range = range.split('..')
64
- end
65
- minimum_platform_version = Gem::Version.new(range.first)
66
- maximum_platform_version = Gem::Version.new(range.last)
67
- @version >= minimum_platform_version && @version <= maximum_platform_version
68
- end
69
-
70
- def major_version
71
- if @version.segments.first == 0
72
- @version.segments[0..1].join('.')
73
- else
74
- @version.segments.first
75
- end
76
- end
77
-
78
- def method_missing(method, *args)
79
- puts
80
- puts "WARNING:"
81
- puts " leap_cli is out of date and does not understand `#{method}`."
82
- puts " called from: #{caller.first}"
83
- puts " please upgrade to a newer leap_cli"
84
- end
85
-
86
- end
87
-
88
- end
89
-
90
- end
@@ -1,180 +0,0 @@
1
- #
2
- # All configurations files can be isolated into separate environments.
3
- #
4
- # Each config json in each environment inherits from the default environment,
5
- # which in term inherits from the "_base_" environment:
6
- #
7
- # _base_ -- base provider in leap_platform
8
- # '- default -- environment in provider dir when no env is set
9
- # '- production -- example environment
10
- #
11
-
12
- module LeapCli; module Config
13
-
14
- class Environment
15
- # the String name of the environment
16
- attr_accessor :name
17
-
18
- # the shared Manager object
19
- attr_accessor :manager
20
-
21
- # hashes of {name => Config::Object}
22
- attr_accessor :services, :tags, :partials
23
-
24
- # a Config::Provider
25
- attr_accessor :provider
26
-
27
- # a Config::Object
28
- attr_accessor :common
29
-
30
- # shared, non-inheritable
31
- def nodes; @@nodes; end
32
- def secrets; @@secrets; end
33
-
34
- def initialize(manager, name, search_dir, parent, options={})
35
- @@nodes ||= nil
36
- @@secrets ||= nil
37
-
38
- @manager = manager
39
- @name = name
40
-
41
- load_provider_files(search_dir, options)
42
-
43
- if parent
44
- @services.inherit_from! parent.services, self
45
- @tags.inherit_from! parent.tags , self
46
- @partials.inherit_from! parent.partials, self
47
- @common.inherit_from! parent.common
48
- @provider.inherit_from! parent.provider
49
- end
50
-
51
- if @provider
52
- @provider.set_env(name)
53
- @provider.validate!
54
- end
55
- end
56
-
57
- def load_provider_files(search_dir, options)
58
- #
59
- # load empty environment if search_dir doesn't exist
60
- #
61
- if search_dir.nil? || !Dir.exist?(search_dir)
62
- @services = Config::ObjectList.new
63
- @tags = Config::ObjectList.new
64
- @partials = Config::ObjectList.new
65
- @provider = Config::Provider.new
66
- @common = Config::Object.new
67
- return
68
- end
69
-
70
- #
71
- # inheritable
72
- #
73
- if options[:scope]
74
- scope = options[:scope]
75
- @services = load_all_json(Path.named_path([:service_env_config, '*', scope], search_dir), Config::Tag, options)
76
- @tags = load_all_json(Path.named_path([:tag_env_config, '*', scope], search_dir), Config::Tag, options)
77
- @partials = load_all_json(Path.named_path([:service_env_config, '_*', scope], search_dir), Config::Tag, options)
78
- @provider = load_json( Path.named_path([:provider_env_config, scope], search_dir), Config::Provider, options)
79
- @common = load_json( Path.named_path([:common_env_config, scope], search_dir), Config::Object, options)
80
- else
81
- @services = load_all_json(Path.named_path([:service_config, '*'], search_dir), Config::Tag, options)
82
- @tags = load_all_json(Path.named_path([:tag_config, '*'], search_dir), Config::Tag, options)
83
- @partials = load_all_json(Path.named_path([:service_config, '_*'], search_dir), Config::Tag, options)
84
- @provider = load_json( Path.named_path(:provider_config, search_dir), Config::Provider, options)
85
- @common = load_json( Path.named_path(:common_config, search_dir), Config::Object, options)
86
- end
87
-
88
- # remove 'name' from partials, since partials get merged with nodes
89
- @partials.values.each {|partial| partial.delete('name'); }
90
-
91
- #
92
- # shared: currently non-inheritable
93
- # load the first ones we find, and only those.
94
- #
95
- if @@nodes.nil? || @@nodes.empty?
96
- @@nodes = load_all_json(Path.named_path([:node_config, '*'], search_dir), Config::Node, options)
97
- end
98
- if @@secrets.nil? || @@secrets.empty?
99
- @@secrets = load_json(Path.named_path(:secrets_config, search_dir), Config::Secrets, options)
100
- end
101
- end
102
-
103
- #
104
- # Loads a json template file as a Hash (used only when creating a new node .json
105
- # file for the first time).
106
- #
107
- def template(template)
108
- path = Path.named_path([:template_config, template], Path.provider_base)
109
- if File.exists?(path)
110
- return load_json(path, Config::Object)
111
- else
112
- return nil
113
- end
114
- end
115
-
116
- private
117
-
118
- def load_all_json(pattern, object_class, options={})
119
- results = Config::ObjectList.new
120
- Dir.glob(pattern).each do |filename|
121
- next if options[:no_dots] && File.basename(filename) !~ /^[^\.]*\.json$/
122
- obj = load_json(filename, object_class)
123
- if obj
124
- name = File.basename(filename).force_encoding('utf-8').sub(/^([^\.]+).*\.json$/,'\1')
125
- obj['name'] ||= name
126
- if options[:env]
127
- obj.environment = options[:env]
128
- end
129
- results[name] = obj
130
- end
131
- end
132
- results
133
- end
134
-
135
- def load_json(filename, object_class, options={})
136
- if !File.exists?(filename)
137
- return object_class.new(self)
138
- end
139
-
140
- Util::log :loading, filename, 3
141
-
142
- #
143
- # Read a JSON file, strip out comments.
144
- #
145
- # UTF8 is the default encoding for JSON, but others are allowed:
146
- # https://www.ietf.org/rfc/rfc4627.txt
147
- #
148
- buffer = StringIO.new
149
- File.open(filename, "rb", :encoding => 'UTF-8') do |f|
150
- while (line = f.gets)
151
- next if line =~ /^\s*\/\//
152
- buffer << line
153
- end
154
- end
155
-
156
- #
157
- # force UTF-8
158
- #
159
- if $ruby_version >= [1,9]
160
- string = buffer.string.force_encoding('utf-8')
161
- else
162
- string = Iconv.conv("UTF-8//IGNORE", "UTF-8", buffer.string)
163
- end
164
-
165
- # parse json
166
- begin
167
- hash = JSON.parse(string, :object_class => Hash, :array_class => Array) || {}
168
- rescue SyntaxError, JSON::ParserError => exc
169
- Util::log 0, :error, 'in file "%s":' % filename
170
- Util::log 0, exc.to_s, :indent => 1
171
- return nil
172
- end
173
- object = object_class.new(self)
174
- object.deep_merge!(hash)
175
- return object
176
- end
177
-
178
- end # end Environment
179
-
180
- end; end