gooddata 2.1.11 → 2.1.17

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.
Files changed (55) hide show
  1. checksums.yaml +4 -4
  2. data/.gdc-ii-config.yaml +1 -1
  3. data/.sonar.settings +4 -0
  4. data/.travis.yml +4 -3
  5. data/CHANGELOG.md +34 -0
  6. data/Dockerfile +9 -3
  7. data/LICENSE +30 -22
  8. data/LICENSE.rb +1 -1
  9. data/README.md +19 -1
  10. data/Rakefile +8 -1
  11. data/SDK_VERSION +1 -1
  12. data/VERSION +1 -1
  13. data/bin/run_brick.rb +3 -0
  14. data/bin/test_projects_cleanup.rb +7 -3
  15. data/ci/postgresql/pom.xml +57 -0
  16. data/dev-gooddata-sso.pub.encrypted +40 -40
  17. data/gdc_fossa_lcm.yaml +2 -0
  18. data/gdc_fossa_ruby_sdk.yaml +5 -0
  19. data/gooddata.gemspec +4 -5
  20. data/k8s/charts/lcm-bricks/Chart.yaml +1 -1
  21. data/k8s/charts/lcm-bricks/templates/prometheus/alertingRules.yaml +32 -12
  22. data/lib/gooddata.rb +2 -0
  23. data/lib/gooddata/cloud_resources/{cloud_resouce_factory.rb → cloud_resource_factory.rb} +8 -0
  24. data/lib/gooddata/cloud_resources/cloud_resources.rb +1 -1
  25. data/lib/gooddata/cloud_resources/postgresql/drivers/.gitkeepme +0 -0
  26. data/lib/gooddata/cloud_resources/postgresql/postgresql_client.rb +107 -0
  27. data/lib/gooddata/commands/scaffold.rb +9 -10
  28. data/lib/gooddata/core/nil_logger.rb +3 -1
  29. data/lib/gooddata/helpers/data_helper.rb +1 -2
  30. data/lib/gooddata/helpers/global_helpers.rb +6 -5
  31. data/lib/gooddata/helpers/global_helpers_params.rb +2 -2
  32. data/lib/gooddata/lcm/actions/base_action.rb +0 -2
  33. data/lib/gooddata/lcm/actions/collect_tagged_objects.rb +2 -1
  34. data/lib/gooddata/lcm/actions/migrate_gdc_date_dimension.rb +116 -0
  35. data/lib/gooddata/lcm/actions/synchronize_ldm.rb +10 -1
  36. data/lib/gooddata/lcm/actions/synchronize_user_filters.rb +4 -0
  37. data/lib/gooddata/lcm/actions/synchronize_users.rb +7 -6
  38. data/lib/gooddata/lcm/lcm2.rb +1 -2
  39. data/lib/gooddata/lcm/types/base_type.rb +0 -2
  40. data/lib/gooddata/mixins/md_object_query.rb +8 -6
  41. data/lib/gooddata/models/blueprint/project_blueprint.rb +0 -2
  42. data/lib/gooddata/models/client.rb +14 -12
  43. data/lib/gooddata/models/data_source.rb +664 -0
  44. data/lib/gooddata/models/domain.rb +1 -2
  45. data/lib/gooddata/models/from_wire.rb +1 -0
  46. data/lib/gooddata/models/metadata/scheduled_mail.rb +1 -1
  47. data/lib/gooddata/models/process.rb +11 -3
  48. data/lib/gooddata/models/project.rb +128 -19
  49. data/lib/gooddata/models/user_filters/user_filter_builder.rb +0 -1
  50. data/lib/gooddata/models/user_group.rb +0 -1
  51. data/lib/gooddata/rest/connection.rb +6 -4
  52. data/rubydev_public.gpg.encrypted +51 -51
  53. data/rubydev_secret_keys.gpg.encrypted +109 -109
  54. metadata +17 -25
  55. data/DEPENDENCIES.md +0 -880
@@ -0,0 +1,5 @@
1
+ ---
2
+ generate_attribution_file: true
3
+ fossa_project: "gooddata-ruby-sdk"
4
+ ignored_paths:
5
+ - 'ci/.*'
data/gooddata.gemspec CHANGED
@@ -5,7 +5,7 @@ require 'gooddata/version'
5
5
  Gem::Specification.new do |s|
6
6
  s.name = 'gooddata'
7
7
  s.version = GoodData::VERSION
8
- s.licenses = ['BSD']
8
+ s.licenses = ['BSD-3-Clause']
9
9
  s.platform = 'java' if RUBY_PLATFORM =~ /java/
10
10
 
11
11
  s.required_rubygems_version = Gem::Requirement.new('>= 0') if s.respond_to? :required_rubygems_version=
@@ -24,7 +24,7 @@ Gem::Specification.new do |s|
24
24
  s.email = 'lcm@gooddata.com'
25
25
  s.extra_rdoc_files = %w(LICENSE README.md)
26
26
 
27
- s.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
27
+ s.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR).map { |f| f unless %w(NOTICES.txt LICENSE_FOR_RUBY_SDK_COMPONENT.txt).include?(f) }
28
28
  s.files.reject! { |fn| fn.start_with? 'spec/' }
29
29
  s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
30
30
 
@@ -55,14 +55,13 @@ Gem::Specification.new do |s|
55
55
  s.add_development_dependency 'sqlite3' if RUBY_PLATFORM != 'java'
56
56
 
57
57
  if RUBY_VERSION >= '2.5'
58
- s.add_dependency 'activesupport', '> 4.2.9', '< 6.1'
58
+ s.add_dependency 'activesupport', '>= 6.0.3.1', '< 6.2'
59
59
  else
60
- s.add_dependency 'activesupport', '> 4.2.9', '< 6.0'
60
+ s.add_dependency 'activesupport', '>= 5.2.4.3', '< 6.0'
61
61
  end
62
62
 
63
63
  s.add_dependency 'aws-sdk-s3', '~> 1.16'
64
64
  s.add_dependency 'docile', '~> 1.1'
65
- s.add_dependency 'erubis', '~> 2.7'
66
65
  s.add_dependency 'gli', '~> 2.15'
67
66
  s.add_dependency 'gooddata_datawarehouse', '~> 0.0.10' if RUBY_PLATFORM == 'java'
68
67
  s.add_dependency 'highline', '= 2.0.0.pre.develop.14'
@@ -1,4 +1,4 @@
1
1
  apiVersion: v1
2
2
  name: lcm-bricks
3
3
  description: LCM Bricks
4
- version: 2.0.1
4
+ version: 2.0.6
@@ -20,7 +20,7 @@ data:
20
20
  expr: container_pod:lcm_pod_container_status_restarts:increase10m >= 1
21
21
  labels:
22
22
  severity: warning
23
- team: lcm # switch to msf in production
23
+ team: lcm
24
24
  cluster_id: {{ .Values.clusterId }}
25
25
  annotations:
26
26
  description: "There is more than 0 restarts of {{`{{ $labels.pod }}`}} pod in the last 10 minutes"
@@ -28,8 +28,8 @@ data:
28
28
  - alert: "[LCM] Pod has too many restarts on cluster={{ .Values.clusterId }}"
29
29
  expr: container_pod:lcm_pod_container_status_restarts:increase10m >= 2
30
30
  labels:
31
- severity: critical
32
- team: lcm # switch to msf in production
31
+ severity: warning
32
+ team: lcm
33
33
  cluster_id: {{ .Values.clusterId }}
34
34
  annotations:
35
35
  description: "There is more than 1 restart of {{`{{ $labels.pod }}`}} pod in the last 10 minutes"
@@ -40,7 +40,7 @@ data:
40
40
  expr: container_pod:lcm_pod_container_status_oomkilled:increase10m >= 1
41
41
  labels:
42
42
  severity: warning
43
- team: lcm # switch to msf in production
43
+ team: lcm
44
44
  cluster_id: {{ .Values.clusterId }}
45
45
  annotations:
46
46
  description: "{{`{{ $labels.pod }}`}} was OOMKilled in the last 30 minutes. Investigate and/or increase memoryRequest or memoryLimit."
@@ -48,8 +48,8 @@ data:
48
48
  - alert: "[LCM] OOMKill occured on cluster={{ .Values.clusterId }}"
49
49
  expr: container_pod:lcm_pod_container_status_oomkilled:increase10m >= 2
50
50
  labels:
51
- severity: critical
52
- team: lcm # switch to msf in production
51
+ severity: warning
52
+ team: lcm
53
53
  cluster_id: {{ .Values.clusterId }}
54
54
  annotations:
55
55
  description: "{{`{{ $labels.pod }}`}} was OOMKilled in the last 10 minutes. Investigate and/or increase memoryRequest or memoryLimit."
@@ -58,8 +58,8 @@ data:
58
58
  expr: rate(container_cpu_cfs_throttled_seconds_total{namespace='{{ .Release.Namespace }}'}[1m]) > 1
59
59
  for: 5m
60
60
  labels:
61
- severity: critical
62
- team: lcm # switch to msf in production
61
+ severity: warning
62
+ team: lcm
63
63
  cluster_id: {{ .Values.clusterId }}
64
64
  annotations:
65
65
  description: "{{`{{ $labels.pod_name }}`}} container is beeing throttled and probably hit CPU limit. Investigate root cause and increase limit and/or number of replicas if necessary."
@@ -68,8 +68,8 @@ data:
68
68
  expr: rate(jvm_gc_pause_seconds_sum{kubernetes_namespace='{{ .Release.Namespace }}'}[1m]) > 1
69
69
  for: 5m
70
70
  labels:
71
- severity: critical
72
- team: lcm # switch to msf in production
71
+ severity: warning
72
+ team: lcm
73
73
  cluster_id: {{ .Values.clusterId }}
74
74
  annotations:
75
75
  description: "{{`{{ $labels.kubernetes_pod_name }}`}} container is spending too much time in pause garbage collector. Investigate root cause and increase heap size and/or number of replicas if necessary."
@@ -77,9 +77,29 @@ data:
77
77
  - alert: "[LCM] there is more than 100 jobs on cluster={{ .Values.clusterId }}"
78
78
  expr: count(kube_job_info{namespace="lcm"}) > 100
79
79
  labels:
80
- severity: critical
81
- team: lcm # switch to msf in production
80
+ severity: warning
81
+ team: lcm
82
82
  cluster_id: {{ .Values.clusterId }}
83
83
  annotations:
84
84
  description: "There is more than 100 jobs in LCM namespace. They are likely not deleted."
85
85
  summary: "There is more than 100 jobs in LCM namespace."
86
+ - alert: "[LCM] Resource quotas hit CPU limit on cluster={{ .Values.clusterId }}"
87
+ expr: kube_resourcequota{namespace='{{ .Release.Namespace }}',resource="limits.cpu",type="hard"} - ignoring(type) kube_resourcequota{namespace='{{ .Release.Namespace }}',resource="limits.cpu",type="used"} == 0
88
+ labels:
89
+ severity: warning
90
+ team: lcm
91
+ cluster_id: {{ .Values.clusterId }}
92
+ annotations:
93
+ description: "We are hitting CPU limit in LCM namespace."
94
+ summary: "We are hitting CPU limit in LCM namespace."
95
+ - alert: "[LCM] POD is in undesirable state on cluster={{ .Values.clusterId }}"
96
+ expr: kube_pod_status_phase{namespace='{{ .Release.Namespace }}', phase!~"Running|Succeeded|Failed"} > 0
97
+ for: 5m
98
+ labels:
99
+ cluster_id: {{ .Values.clusterId }}
100
+ severity: critical
101
+ team: lcm
102
+ annotations:
103
+ description: "POD {{`{{ $labels.pod }}`}} is not in desirable state"
104
+ summary: "POD is not in desirable state"
105
+ runbook: "https://confluence.intgdc.com/display/plat/Generic+runbooks#Genericrunbooks-Podisinundesirablestate"
data/lib/gooddata.rb CHANGED
@@ -37,3 +37,5 @@ require 'backports/2.1.0/array/to_h'
37
37
 
38
38
  # Helpers
39
39
  require 'gooddata/helpers/global_helpers'
40
+
41
+ require 'active_support/core_ext/hash/compact' unless RUBY_VERSION >= '2.5'
@@ -11,7 +11,15 @@ module GoodData
11
11
  module CloudResources
12
12
  class CloudResourceFactory
13
13
  class << self
14
+ def load_cloud_resource(type)
15
+ base = "#{Pathname(__FILE__).dirname.expand_path}#{File::SEPARATOR}#{type}#{File::SEPARATOR}"
16
+ Dir.glob(base + '**/*.rb').each do |file|
17
+ require file
18
+ end
19
+ end
20
+
14
21
  def create(type, data = {}, opts = {})
22
+ load_cloud_resource(type)
15
23
  clients = CloudResourceClient.descendants.select { |c| c.respond_to?("accept?") && c.send("accept?", type) }
16
24
  raise "DataSource does not support type \"#{type}\"" if clients.empty?
17
25
 
@@ -7,6 +7,6 @@
7
7
  require 'pathname'
8
8
 
9
9
  base = Pathname(__FILE__).dirname.expand_path
10
- Dir.glob(base + '**/*.rb').each do |file|
10
+ Dir.glob(base + '*.rb').each do |file|
11
11
  require file
12
12
  end
@@ -0,0 +1,107 @@
1
+ # encoding: UTF-8
2
+ # frozen_string_literal: true
3
+ #
4
+ # Copyright (c) 2021 GoodData Corporation. All rights reserved.
5
+ # This source code is licensed under the BSD-style license found in the
6
+ # LICENSE file in the root directory of this source tree.
7
+
8
+ require 'securerandom'
9
+ require 'java'
10
+ require 'pathname'
11
+ require_relative '../cloud_resource_client'
12
+
13
+ base = Pathname(__FILE__).dirname.expand_path
14
+ Dir.glob(base + 'drivers/*.jar').each do |file|
15
+ require file unless file.start_with?('lcm-postgresql-driver')
16
+ end
17
+
18
+ module GoodData
19
+ module CloudResources
20
+ class PostgresClient < CloudResourceClient
21
+ JDBC_POSTGRES_PATTERN = %r{jdbc:postgresql:\/\/([^:^\/]+)(:([0-9]+))?(\/)?}
22
+ POSTGRES_DEFAULT_PORT = 5432
23
+ JDBC_POSTGRES_PROTOCOL = 'jdbc:postgresql://'
24
+ SSL_JAVA_FACTORY = '&sslfactory=org.postgresql.ssl.DefaultJavaSSLFactory'
25
+ VERIFY_FULL = 'verify-full'
26
+ PREFER = 'prefer'
27
+ REQUIRE = 'require'
28
+ POSTGRES_SET_SCHEMA_COMMAND = "set search_path to"
29
+ POSTGRES_FETCH_SIZE = 1000
30
+
31
+ class << self
32
+ def accept?(type)
33
+ type == 'postgresql'
34
+ end
35
+ end
36
+
37
+ def initialize(options = {})
38
+ raise("Data Source needs a client to Postgres to be able to query the storage but 'postgresql_client' is empty.") unless options['postgresql_client']
39
+
40
+ if options['postgresql_client']['connection'].is_a?(Hash)
41
+ @database = options['postgresql_client']['connection']['database']
42
+ @schema = options['postgresql_client']['connection']['schema'] || 'public'
43
+ @authentication = options['postgresql_client']['connection']['authentication']
44
+ @ssl_mode = options['postgresql_client']['connection']['sslMode']
45
+ raise "SSL Mode should be prefer, require and verify-full" unless @ssl_mode == 'prefer' || @ssl_mode == 'require' || @ssl_mode == 'verify-full'
46
+
47
+ @url = build_url(options['postgresql_client']['connection']['url'])
48
+ else
49
+ raise('Missing connection info for Postgres client')
50
+ end
51
+
52
+ Java.org.postgresql.Driver
53
+ end
54
+
55
+ def realize_query(query, _params)
56
+ GoodData.gd_logger.info("Realize SQL query: type=postgresql status=started")
57
+
58
+ connect
59
+ filename = "#{SecureRandom.urlsafe_base64(6)}_#{Time.now.to_i}.csv"
60
+ measure = Benchmark.measure do
61
+ statement = @connection.create_statement
62
+ statement.set_fetch_size(POSTGRES_FETCH_SIZE)
63
+ has_result = statement.execute(query)
64
+ if has_result
65
+ result = statement.get_result_set
66
+ metadata = result.get_meta_data
67
+ col_count = metadata.column_count
68
+ CSV.open(filename, 'wb') do |csv|
69
+ csv << Array(1..col_count).map { |i| metadata.get_column_name(i) } # build the header
70
+ csv << Array(1..col_count).map { |i| result.get_string(i)&.to_s } while result.next
71
+ end
72
+ end
73
+ end
74
+ GoodData.gd_logger.info("Realize SQL query: type=postgresql status=finished duration=#{measure.real}")
75
+ filename
76
+ ensure
77
+ @connection&.close
78
+ @connection = nil
79
+ end
80
+
81
+ def connect
82
+ GoodData.logger.info "Setting up connection to Postgresql #{@url}"
83
+
84
+ prop = java.util.Properties.new
85
+ prop.setProperty('user', @authentication['basic']['userName'])
86
+ prop.setProperty('password', @authentication['basic']['password'])
87
+ prop.setProperty('schema', @schema)
88
+
89
+ @connection = java.sql.DriverManager.getConnection(@url, prop)
90
+ statement = @connection.create_statement
91
+ statement.execute("#{POSTGRES_SET_SCHEMA_COMMAND} #{@schema}")
92
+ @connection.set_auto_commit(false)
93
+ end
94
+
95
+ def build_url(url)
96
+ matches = url.scan(JDBC_POSTGRES_PATTERN)
97
+ raise 'Cannot reach the url' unless matches
98
+
99
+ host = matches[0][0]
100
+ port = matches[0][2]&.to_i || POSTGRES_DEFAULT_PORT
101
+ raise "Custom port #{port} is not supported. Remove it or use the default port '5432'" if POSTGRES_DEFAULT_PORT != port
102
+
103
+ "#{JDBC_POSTGRES_PROTOCOL}#{host}:#{port}/#{@database}?sslmode=#{@ssl_mode}#{VERIFY_FULL == @ssl_mode ? SSL_JAVA_FACTORY : ''}"
104
+ end
105
+ end
106
+ end
107
+ end
@@ -4,7 +4,7 @@
4
4
  # This source code is licensed under the BSD-style license found in the
5
5
  # LICENSE file in the root directory of this source tree.
6
6
 
7
- require 'erubis'
7
+ require 'erb'
8
8
  require 'fileutils'
9
9
  require 'pathname'
10
10
 
@@ -18,15 +18,14 @@ module GoodData
18
18
  # TODO: Add option for custom output dir
19
19
  def project(name)
20
20
  fail ArgumentError, 'No name specified' if name.nil?
21
-
22
21
  FileUtils.mkdir(name)
23
22
  FileUtils.cd(name) do
24
23
  FileUtils.mkdir('model')
25
24
  FileUtils.cd('model') do
26
25
  input = File.read(TEMPLATES_PATH + 'project/model/model.rb.erb')
27
- eruby = Erubis::Eruby.new(input)
26
+ erb = ERB.new(input)
28
27
  File.open('model.rb', 'w') do |f|
29
- f.write(eruby.result(:name => name))
28
+ f.write(erb.result_with_hash(:name => name))
30
29
  end
31
30
  end
32
31
 
@@ -36,9 +35,9 @@ module GoodData
36
35
  end
37
36
 
38
37
  input = File.read(TEMPLATES_PATH + 'project/Goodfile.erb')
39
- eruby = Erubis::Eruby.new(input)
38
+ erb = ERB.new(input)
40
39
  File.open('Goodfile', 'w') do |f|
41
- f.write(eruby.result)
40
+ f.write(erb.result)
42
41
  end
43
42
  end
44
43
  end
@@ -51,15 +50,15 @@ module GoodData
51
50
  FileUtils.mkdir(name)
52
51
  FileUtils.cd(name) do
53
52
  input = File.read(TEMPLATES_PATH + 'bricks/brick.rb.erb')
54
- eruby = Erubis::Eruby.new(input)
53
+ erb = ERB.new(input)
55
54
  File.open('brick.rb', 'w') do |f|
56
- f.write(eruby.result)
55
+ f.write(erb.result)
57
56
  end
58
57
 
59
58
  input = File.read(TEMPLATES_PATH + 'bricks/main.rb.erb')
60
- eruby = Erubis::Eruby.new(input)
59
+ erb = ERB.new(input)
61
60
  File.open('main.rb', 'w') do |f|
62
- f.write(eruby.result)
61
+ f.write(erb.result)
63
62
  end
64
63
  end
65
64
  end
@@ -1,4 +1,5 @@
1
- # Copyright (c) 2010-2017 GoodData Corporation. All rights reserved.
1
+ # frozen_string_literal: true
2
+ # Copyright (c) 2010-2021 GoodData Corporation. All rights reserved.
2
3
  # This source code is licensed under the BSD-style license found in the
3
4
  # LICENSE file in the root directory of this source tree.
4
5
 
@@ -11,6 +12,7 @@ module GoodData
11
12
  @level = nil
12
13
  end
13
14
 
15
+ # No body define need for dummy logger
14
16
  def debug(*_args)
15
17
  end
16
18
 
@@ -44,9 +44,8 @@ module GoodData
44
44
  realize_link
45
45
  when 's3'
46
46
  realize_s3(params)
47
- when 'redshift', 'snowflake', 'bigquery'
47
+ when 'redshift', 'snowflake', 'bigquery', 'postgresql'
48
48
  raise GoodData::InvalidEnvError, "DataSource does not support type \"#{source}\" on the platform #{RUBY_PLATFORM}" unless RUBY_PLATFORM =~ /java/
49
-
50
49
  require_relative '../cloud_resources/cloud_resources'
51
50
  realize_cloud_resource(source, params)
52
51
  else
@@ -1,6 +1,6 @@
1
1
  # encoding: UTF-8
2
2
  #
3
- # Copyright (c) 2010-2017 GoodData Corporation. All rights reserved.
3
+ # Copyright (c) 2010-2021 GoodData Corporation. All rights reserved.
4
4
  # This source code is licensed under the BSD-style license found in the
5
5
  # LICENSE file in the root directory of this source tree.
6
6
 
@@ -34,6 +34,7 @@ module GoodData
34
34
  end
35
35
 
36
36
  set_const :GD_MAX_RETRY, (ENV['GD_MAX_RETRY'] && ENV['GD_MAX_RETRY'].to_i) || 12
37
+ AES_256_CBC_CIPHER = 'aes-256-cbc'
37
38
 
38
39
  class << self
39
40
  def error(msg)
@@ -222,7 +223,7 @@ module GoodData
222
223
  # encrypts data with the given key. returns a binary data with the
223
224
  # unhashed random iv in the first 16 bytes
224
225
  def encrypt(data, key)
225
- cipher = OpenSSL::Cipher::Cipher.new('aes-256-cbc')
226
+ cipher = OpenSSL::Cipher::Cipher.new(AES_256_CBC_CIPHER)
226
227
  cipher.encrypt
227
228
  cipher.key = key = Digest::SHA256.digest(key)
228
229
  random_iv = cipher.random_iv
@@ -236,7 +237,7 @@ module GoodData
236
237
 
237
238
  # Simple encrypt data with given key
238
239
  def simple_encrypt(data, key)
239
- cipher = OpenSSL::Cipher::Cipher.new('aes-256-cbc')
240
+ cipher = OpenSSL::Cipher::Cipher.new(AES_256_CBC_CIPHER)
240
241
  cipher.encrypt
241
242
  cipher.key = key
242
243
  encrypted = cipher.update(data)
@@ -253,7 +254,7 @@ module GoodData
253
254
 
254
255
  data = Base64.decode64(database64)
255
256
 
256
- cipher = OpenSSL::Cipher::Cipher.new('aes-256-cbc')
257
+ cipher = OpenSSL::Cipher::Cipher.new(AES_256_CBC_CIPHER)
257
258
  cipher.decrypt
258
259
  cipher.key = cipher_key = Digest::SHA256.digest(key)
259
260
  random_iv = data[0..15] # extract iv from first 16 bytes
@@ -273,7 +274,7 @@ module GoodData
273
274
 
274
275
  data = Base64.decode64(database64)
275
276
 
276
- cipher = OpenSSL::Cipher::Cipher.new('aes-256-cbc')
277
+ cipher = OpenSSL::Cipher::Cipher.new(AES_256_CBC_CIPHER)
277
278
  cipher.decrypt
278
279
  cipher.key = key
279
280
  decrypted = cipher.update(data)
@@ -242,7 +242,7 @@ module GoodData
242
242
 
243
243
  def resolve_reference_params(data_params, params)
244
244
  reference_values = []
245
- regexps = Regexp.union(/\\\\/, /\\\$/, /\$\{(\w+)\}/)
245
+ regexps = Regexp.union(/\\\\/, /\\\$/, /\$\{([^\n\{\}]+)\}/)
246
246
  resolve_reference = lambda do |v|
247
247
  if v.is_a? Hash
248
248
  Hash[
@@ -262,7 +262,7 @@ module GoodData
262
262
  data_params.is_a?(Hash) ? '\\' : '\\\\' # rubocop: disable Metrics/BlockNesting
263
263
  elsif match =~ /\\\$/
264
264
  '$'
265
- elsif match =~ /\$\{(\w+)\}/
265
+ elsif match =~ /\$\{([^\n\{\}]+)\}/
266
266
  val = params["#{$1}"]
267
267
  if val
268
268
  reference_values << val
@@ -8,8 +8,6 @@ require 'gooddata/extensions/integer'
8
8
  require 'gooddata/extensions/string'
9
9
  require 'gooddata/extensions/nil'
10
10
 
11
- require 'active_support/core_ext/hash/compact'
12
-
13
11
  require_relative '../dsl/dsl'
14
12
  require_relative '../helpers/helpers'
15
13
  require_relative '../types/types'