gooddata 2.1.11 → 2.1.17
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gdc-ii-config.yaml +1 -1
- data/.sonar.settings +4 -0
- data/.travis.yml +4 -3
- data/CHANGELOG.md +34 -0
- data/Dockerfile +9 -3
- data/LICENSE +30 -22
- data/LICENSE.rb +1 -1
- data/README.md +19 -1
- data/Rakefile +8 -1
- data/SDK_VERSION +1 -1
- data/VERSION +1 -1
- data/bin/run_brick.rb +3 -0
- data/bin/test_projects_cleanup.rb +7 -3
- data/ci/postgresql/pom.xml +57 -0
- data/dev-gooddata-sso.pub.encrypted +40 -40
- data/gdc_fossa_lcm.yaml +2 -0
- data/gdc_fossa_ruby_sdk.yaml +5 -0
- data/gooddata.gemspec +4 -5
- data/k8s/charts/lcm-bricks/Chart.yaml +1 -1
- data/k8s/charts/lcm-bricks/templates/prometheus/alertingRules.yaml +32 -12
- data/lib/gooddata.rb +2 -0
- data/lib/gooddata/cloud_resources/{cloud_resouce_factory.rb → cloud_resource_factory.rb} +8 -0
- data/lib/gooddata/cloud_resources/cloud_resources.rb +1 -1
- data/lib/gooddata/cloud_resources/postgresql/drivers/.gitkeepme +0 -0
- data/lib/gooddata/cloud_resources/postgresql/postgresql_client.rb +107 -0
- data/lib/gooddata/commands/scaffold.rb +9 -10
- data/lib/gooddata/core/nil_logger.rb +3 -1
- data/lib/gooddata/helpers/data_helper.rb +1 -2
- data/lib/gooddata/helpers/global_helpers.rb +6 -5
- data/lib/gooddata/helpers/global_helpers_params.rb +2 -2
- data/lib/gooddata/lcm/actions/base_action.rb +0 -2
- data/lib/gooddata/lcm/actions/collect_tagged_objects.rb +2 -1
- data/lib/gooddata/lcm/actions/migrate_gdc_date_dimension.rb +116 -0
- data/lib/gooddata/lcm/actions/synchronize_ldm.rb +10 -1
- data/lib/gooddata/lcm/actions/synchronize_user_filters.rb +4 -0
- data/lib/gooddata/lcm/actions/synchronize_users.rb +7 -6
- data/lib/gooddata/lcm/lcm2.rb +1 -2
- data/lib/gooddata/lcm/types/base_type.rb +0 -2
- data/lib/gooddata/mixins/md_object_query.rb +8 -6
- data/lib/gooddata/models/blueprint/project_blueprint.rb +0 -2
- data/lib/gooddata/models/client.rb +14 -12
- data/lib/gooddata/models/data_source.rb +664 -0
- data/lib/gooddata/models/domain.rb +1 -2
- data/lib/gooddata/models/from_wire.rb +1 -0
- data/lib/gooddata/models/metadata/scheduled_mail.rb +1 -1
- data/lib/gooddata/models/process.rb +11 -3
- data/lib/gooddata/models/project.rb +128 -19
- data/lib/gooddata/models/user_filters/user_filter_builder.rb +0 -1
- data/lib/gooddata/models/user_group.rb +0 -1
- data/lib/gooddata/rest/connection.rb +6 -4
- data/rubydev_public.gpg.encrypted +51 -51
- data/rubydev_secret_keys.gpg.encrypted +109 -109
- metadata +17 -25
- data/DEPENDENCIES.md +0 -880
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', '
|
58
|
+
s.add_dependency 'activesupport', '>= 6.0.3.1', '< 6.2'
|
59
59
|
else
|
60
|
-
s.add_dependency 'activesupport', '
|
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'
|
@@ -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
|
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:
|
32
|
-
team: lcm
|
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
|
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:
|
52
|
-
team: lcm
|
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:
|
62
|
-
team: lcm
|
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:
|
72
|
-
team: lcm
|
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:
|
81
|
-
team: lcm
|
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
@@ -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
|
|
File without changes
|
@@ -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 '
|
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
|
-
|
26
|
+
erb = ERB.new(input)
|
28
27
|
File.open('model.rb', 'w') do |f|
|
29
|
-
f.write(
|
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
|
-
|
38
|
+
erb = ERB.new(input)
|
40
39
|
File.open('Goodfile', 'w') do |f|
|
41
|
-
f.write(
|
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
|
-
|
53
|
+
erb = ERB.new(input)
|
55
54
|
File.open('brick.rb', 'w') do |f|
|
56
|
-
f.write(
|
55
|
+
f.write(erb.result)
|
57
56
|
end
|
58
57
|
|
59
58
|
input = File.read(TEMPLATES_PATH + 'bricks/main.rb.erb')
|
60
|
-
|
59
|
+
erb = ERB.new(input)
|
61
60
|
File.open('main.rb', 'w') do |f|
|
62
|
-
f.write(
|
61
|
+
f.write(erb.result)
|
63
62
|
end
|
64
63
|
end
|
65
64
|
end
|
@@ -1,4 +1,5 @@
|
|
1
|
-
#
|
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-
|
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(
|
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(
|
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(
|
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(
|
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(/\\\\/, /\\\$/, /\$\{(\
|
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 =~ /\$\{(\
|
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'
|