gooddata 2.1.9-java → 2.1.14-java
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/.rubocop.yml +1 -0
- data/.travis.yml +1 -3
- data/CHANGELOG.md +49 -0
- data/Dockerfile +17 -7
- data/README.md +17 -0
- data/SDK_VERSION +1 -1
- data/VERSION +1 -1
- data/bin/run_brick.rb +3 -0
- data/bin/test_projects_cleanup.rb +6 -2
- data/ci/bigquery/pom.xml +54 -0
- data/ci/redshift/pom.xml +73 -0
- data/ci/snowflake/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 +4 -0
- data/gooddata.gemspec +3 -3
- data/k8s/charts/lcm-bricks/Chart.yaml +1 -1
- data/k8s/charts/lcm-bricks/templates/prometheus/alertingRules.yaml +22 -12
- data/lcm.rake +10 -6
- data/lib/gooddata/cloud_resources/bigquery/bigquery_client.rb +86 -0
- data/lib/gooddata/cloud_resources/bigquery/drivers/.gitkeepme +0 -0
- data/lib/gooddata/cloud_resources/redshift/redshift_client.rb +3 -2
- data/lib/gooddata/cloud_resources/snowflake/drivers/.gitkeepme +0 -0
- data/lib/gooddata/cloud_resources/snowflake/snowflake_client.rb +84 -0
- data/lib/gooddata/helpers/data_helper.rb +1 -1
- data/lib/gooddata/helpers/data_source_helpers.rb +47 -0
- data/lib/gooddata/helpers/global_helpers_params.rb +2 -2
- data/lib/gooddata/lcm/actions/collect_clients.rb +6 -6
- data/lib/gooddata/lcm/actions/collect_dynamic_schedule_params.rb +6 -6
- data/lib/gooddata/lcm/actions/collect_tagged_objects.rb +2 -1
- data/lib/gooddata/lcm/actions/collect_users_brick_users.rb +7 -6
- data/lib/gooddata/lcm/actions/migrate_gdc_date_dimension.rb +116 -0
- data/lib/gooddata/lcm/actions/set_master_project.rb +76 -0
- data/lib/gooddata/lcm/actions/synchronize_ldm.rb +10 -1
- data/lib/gooddata/lcm/actions/synchronize_user_filters.rb +2 -2
- data/lib/gooddata/lcm/actions/synchronize_users.rb +31 -30
- data/lib/gooddata/lcm/lcm2.rb +22 -1
- data/lib/gooddata/models/domain.rb +17 -15
- 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 +118 -29
- data/rubydev_public.gpg.encrypted +51 -51
- data/rubydev_secret_keys.gpg.encrypted +109 -109
- metadata +22 -10
@@ -105,6 +105,7 @@ module GoodData
|
|
105
105
|
d[:title] = date_dim['dateDimension']['title']
|
106
106
|
d[:urn] = date_dim['dateDimension']['urn']
|
107
107
|
d[:identifier_prefix] = date_dim['dateDimension']['identifierPrefix']
|
108
|
+
d[:identifier] = date_dim['dateDimension']['identifier'] if date_dim['dateDimension']['identifier']
|
108
109
|
d[:columns] = parse_bridges(date_dim)
|
109
110
|
end
|
110
111
|
end
|
@@ -118,11 +118,13 @@ module GoodData
|
|
118
118
|
GoodData.logger.info("Deploying #{path}") if verbose
|
119
119
|
|
120
120
|
deployed_path = Process.upload_package(path, files_to_exclude, client: client, project: project)
|
121
|
+
data_sources = options[:data_sources] || []
|
121
122
|
data = {
|
122
123
|
:process => {
|
123
124
|
:name => deploy_name,
|
124
125
|
:path => "/uploads/#{File.basename(deployed_path)}",
|
125
|
-
:type => type
|
126
|
+
:type => type,
|
127
|
+
:dataSources => data_sources
|
126
128
|
}
|
127
129
|
}
|
128
130
|
|
@@ -171,10 +173,12 @@ module GoodData
|
|
171
173
|
verbose = options[:verbose] || false
|
172
174
|
GoodData.logger.info("Deploying #{path}") if verbose
|
173
175
|
|
176
|
+
data_sources = options[:data_sources] || []
|
174
177
|
data = {
|
175
178
|
process: {
|
176
179
|
name: deploy_name,
|
177
180
|
path: path,
|
181
|
+
dataSources: data_sources,
|
178
182
|
type: 'RUBY'
|
179
183
|
}
|
180
184
|
}
|
@@ -185,7 +189,7 @@ module GoodData
|
|
185
189
|
def deploy_component(data, options = { client: GoodData.client, project: GoodData.project })
|
186
190
|
client, project = GoodData.get_client_and_project(options)
|
187
191
|
data = { process: data } unless data[:process]
|
188
|
-
data[:process] = GoodData::Helpers.symbolize_keys(data[:process]).select { |k| %i[type name component].include? k }
|
192
|
+
data[:process] = GoodData::Helpers.symbolize_keys(data[:process]).select { |k| %i[type name component dataSources].include? k }
|
189
193
|
data[:process][:component] = GoodData::Helpers.symbolize_keys(data[:process][:component]).select { |k| %i[name version configLocation config].include? k }
|
190
194
|
|
191
195
|
save(data, options)
|
@@ -266,7 +270,7 @@ module GoodData
|
|
266
270
|
# @option options [String] :name Readable name of the process
|
267
271
|
# @option options [Boolean] :verbose (false) Switch on verbose mode for detailed logging
|
268
272
|
def deploy(path, options = {})
|
269
|
-
Process.deploy(path, { client: client, process_id: process_id, :project => project, :name => name, :type => type }.merge(options))
|
273
|
+
Process.deploy(path, { client: client, process_id: process_id, :project => project, :name => name, :type => type, :data_sources => data_sources }.merge(options))
|
270
274
|
end
|
271
275
|
|
272
276
|
# Downloads the process from S3 in a zipped form.
|
@@ -326,6 +330,10 @@ module GoodData
|
|
326
330
|
process['component']
|
327
331
|
end
|
328
332
|
|
333
|
+
def data_sources
|
334
|
+
process['dataSources']
|
335
|
+
end
|
336
|
+
|
329
337
|
# Determines whether the process is an ADDv2 component.
|
330
338
|
# @return [Bool] True if the process is an ADDv2 component.
|
331
339
|
def add_v2_component?
|
@@ -261,21 +261,26 @@ module GoodData
|
|
261
261
|
# @option ads_output_stage_uri Uri of the source output stage. It must be in the same domain as the target project.
|
262
262
|
def transfer_processes(from_project, to_project, options = {})
|
263
263
|
options = GoodData::Helpers.symbolize_keys(options)
|
264
|
+
aliases = {}
|
264
265
|
to_project_processes = to_project.processes
|
265
266
|
additional_hidden_params = options[:additional_hidden_params] || {}
|
266
267
|
result = from_project.processes.uniq(&:name).map do |process|
|
267
|
-
fail "The process name #{process.name} must be unique in
|
268
|
+
fail "The process name #{process.name} must be unique in transferred project #{to_project}" if to_project_processes.count { |p| p.name == process.name } > 1
|
268
269
|
next if process.type == :dataload || process.add_v2_component?
|
270
|
+
collect_process_aliases(process.data, from_project.client, aliases)
|
269
271
|
|
270
272
|
to_process = to_project_processes.find { |p| p.name == process.name }
|
271
273
|
|
274
|
+
data_sources = GoodData::Helpers.symbolize_keys_recursively!(process.data_sources)
|
275
|
+
data_sources = replace_data_source_ids(data_sources, to_project.client, aliases)
|
272
276
|
to_process = if process.path
|
273
277
|
to_process.delete if to_process
|
274
|
-
|
278
|
+
Process.deploy_from_appstore(process.path, name: process.name, client: to_project.client, project: to_project, data_sources: data_sources)
|
275
279
|
elsif process.component
|
276
280
|
to_process.delete if to_process
|
277
281
|
process_hash = GoodData::Helpers::DeepMergeableHash[GoodData::Helpers.symbolize_keys(process.to_hash)].deep_merge(additional_hidden_params)
|
278
|
-
|
282
|
+
process_hash = replace_process_data_source_ids(process_hash, to_project.client, aliases)
|
283
|
+
Process.deploy_component(process_hash, project: to_project, client: to_project.client)
|
279
284
|
else
|
280
285
|
Dir.mktmpdir('etl_transfer') do |dir|
|
281
286
|
dir = Pathname(dir)
|
@@ -283,11 +288,10 @@ module GoodData
|
|
283
288
|
File.open(filename, 'w') do |f|
|
284
289
|
f << process.download
|
285
290
|
end
|
286
|
-
|
287
291
|
if to_process
|
288
|
-
to_process.deploy(filename, type: process.type, name: process.name)
|
292
|
+
to_process.deploy(filename, type: process.type, name: process.name, data_sources: data_sources)
|
289
293
|
else
|
290
|
-
to_project.deploy_process(filename, type: process.type, name: process.name)
|
294
|
+
to_project.deploy_process(filename, type: process.type, name: process.name, data_sources: data_sources)
|
291
295
|
end
|
292
296
|
end
|
293
297
|
end
|
@@ -318,6 +322,56 @@ module GoodData
|
|
318
322
|
result.compact
|
319
323
|
end
|
320
324
|
|
325
|
+
def collect_process_aliases(process_data, client, aliases)
|
326
|
+
data_sources = process_data.dig('process', 'dataSources')
|
327
|
+
unless data_sources.blank?
|
328
|
+
data_sources.map do |data_source|
|
329
|
+
get_data_source_alias(data_source['id'], client, aliases)
|
330
|
+
end
|
331
|
+
end
|
332
|
+
component = process_data.dig('process', 'component')
|
333
|
+
get_data_source_alias(component['configLocation']['dataSourceConfig']['id'], client, aliases) if component&.dig('configLocation', 'dataSourceConfig')
|
334
|
+
aliases
|
335
|
+
end
|
336
|
+
|
337
|
+
def get_data_source_alias(data_source_id, client, aliases)
|
338
|
+
unless aliases[data_source_id]
|
339
|
+
data_source = GoodData::Helpers.get_data_source_by_id(data_source_id, client)
|
340
|
+
if data_source&.dig('dataSource', 'alias')
|
341
|
+
aliases[data_source_id] = {
|
342
|
+
:type => get_data_source_type(data_source),
|
343
|
+
:alias => data_source['dataSource']['alias']
|
344
|
+
}
|
345
|
+
end
|
346
|
+
end
|
347
|
+
aliases[data_source_id]
|
348
|
+
end
|
349
|
+
|
350
|
+
def get_data_source_type(data_source_data)
|
351
|
+
data_source_data&.dig('dataSource', 'connectionInfo') ? data_source_data['dataSource']['connectionInfo'].first[0].upcase : ""
|
352
|
+
end
|
353
|
+
|
354
|
+
def replace_process_data_source_ids(process_data, client, aliases)
|
355
|
+
component = process_data.dig(:process, :component)
|
356
|
+
if component&.dig(:configLocation, :dataSourceConfig)
|
357
|
+
the_alias = aliases[component[:configLocation][:dataSourceConfig][:id]]
|
358
|
+
process_data[:process][:component][:configLocation][:dataSourceConfig][:id] = GoodData::Helpers.verify_data_source_alias(the_alias, client)
|
359
|
+
end
|
360
|
+
process_data[:process][:dataSources] = replace_data_source_ids(process_data[:process][:dataSources], client, aliases)
|
361
|
+
process_data
|
362
|
+
end
|
363
|
+
|
364
|
+
def replace_data_source_ids(data_sources, client, aliases)
|
365
|
+
array_data_sources = []
|
366
|
+
if data_sources && !data_sources.empty?
|
367
|
+
data_sources.map do |data_source|
|
368
|
+
new_id = GoodData::Helpers.verify_data_source_alias(aliases[data_source[:id]], client)
|
369
|
+
array_data_sources.push(:id => new_id)
|
370
|
+
end
|
371
|
+
end
|
372
|
+
array_data_sources
|
373
|
+
end
|
374
|
+
|
321
375
|
def transfer_user_groups(from_project, to_project)
|
322
376
|
from_project.user_groups.map do |ug|
|
323
377
|
# migrate groups
|
@@ -625,6 +679,7 @@ module GoodData
|
|
625
679
|
def blueprint(options = {})
|
626
680
|
options = { include_ca: true }.merge(options)
|
627
681
|
result = client.get("/gdc/projects/#{pid}/model/view", params: { includeDeprecated: true, includeGrain: true, includeCA: options[:include_ca] })
|
682
|
+
|
628
683
|
polling_url = result['asyncTask']['link']['poll']
|
629
684
|
model = client.poll_on_code(polling_url, options)
|
630
685
|
bp = GoodData::Model::FromWire.from_wire(model, options)
|
@@ -1546,26 +1601,28 @@ module GoodData
|
|
1546
1601
|
# @return [Array<GoodData::User>] List of users
|
1547
1602
|
def users(opts = {})
|
1548
1603
|
client = client(opts)
|
1549
|
-
|
1550
|
-
|
1551
|
-
|
1552
|
-
|
1553
|
-
|
1554
|
-
|
1555
|
-
|
1556
|
-
|
1557
|
-
|
1558
|
-
|
1559
|
-
|
1560
|
-
|
1561
|
-
|
1562
|
-
|
1563
|
-
end
|
1604
|
+
all_users = []
|
1605
|
+
offset = opts[:offset] || 0
|
1606
|
+
limit = opts[:limit] || 1_000
|
1607
|
+
loop do
|
1608
|
+
tmp = client.get("/gdc/projects/#{pid}/users", params: { offset: offset, limit: limit })
|
1609
|
+
tmp['users'].each do |user_data|
|
1610
|
+
user = client.create(GoodData::Membership, user_data, project: self)
|
1611
|
+
|
1612
|
+
if opts[:all]
|
1613
|
+
all_users << user
|
1614
|
+
elsif opts[:disabled]
|
1615
|
+
all_users << user if user&.disabled?
|
1616
|
+
else
|
1617
|
+
all_users << user if user&.enabled?
|
1564
1618
|
end
|
1565
|
-
break if tmp['users'].count < limit
|
1566
|
-
offset += limit
|
1567
1619
|
end
|
1620
|
+
break if tmp['users'].count < limit
|
1621
|
+
|
1622
|
+
offset += limit
|
1568
1623
|
end
|
1624
|
+
|
1625
|
+
all_users
|
1569
1626
|
end
|
1570
1627
|
|
1571
1628
|
alias_method :members, :users
|
@@ -1604,14 +1661,19 @@ module GoodData
|
|
1604
1661
|
def import_users(new_users, options = {})
|
1605
1662
|
role_list = roles
|
1606
1663
|
users_list = users
|
1607
|
-
new_users = new_users.map { |x| ((x.is_a?(Hash) && x[:user] && x[:user].to_hash.merge(role: x[:role])) || x.to_hash).tap { |u| u[:login].downcase! } }
|
1608
1664
|
|
1609
1665
|
GoodData.logger.warn("Importing users to project (#{pid})")
|
1666
|
+
new_users = new_users.map { |x| ((x.is_a?(Hash) && x[:user] && x[:user].to_hash.merge(role: x[:role])) || x.to_hash).tap { |u| u[:login].downcase! } }
|
1667
|
+
# First check that if groups are provided we have them set up
|
1668
|
+
user_groups_cache, change_groups = check_groups(new_users.map(&:to_hash).flat_map { |u| u[:user_group] || [] }.uniq, options[:user_groups_cache], options)
|
1610
1669
|
|
1611
|
-
|
1670
|
+
unless change_groups.empty?
|
1671
|
+
new_users.each do |user|
|
1672
|
+
user[:user_group].map! { |e| change_groups[e].nil? ? e : change_groups[e] }
|
1673
|
+
end
|
1674
|
+
end
|
1612
1675
|
|
1613
|
-
|
1614
|
-
user_groups_cache = check_groups(new_users.map(&:to_hash).flat_map { |u| u[:user_group] || [] }.uniq, options[:user_groups_cache], options)
|
1676
|
+
whitelisted_new_users, whitelisted_users = whitelist_users(new_users.map(&:to_hash), users_list, options[:whitelists])
|
1615
1677
|
|
1616
1678
|
# conform the role on list of new users so we can diff them with the users coming from the project
|
1617
1679
|
diffable_new_with_default_role = whitelisted_new_users.map do |u|
|
@@ -1758,7 +1820,20 @@ module GoodData
|
|
1758
1820
|
def check_groups(specified_groups, user_groups_cache = nil, options = {})
|
1759
1821
|
current_user_groups = user_groups if user_groups_cache.nil? || user_groups_cache.empty?
|
1760
1822
|
groups = current_user_groups.map(&:name)
|
1761
|
-
missing_groups =
|
1823
|
+
missing_groups = []
|
1824
|
+
change_groups = {}
|
1825
|
+
specified_groups.each do |group|
|
1826
|
+
found_group = groups.find { |name| name.casecmp(group).zero? }
|
1827
|
+
if found_group.nil?
|
1828
|
+
missing_groups << group
|
1829
|
+
else
|
1830
|
+
# Change groups when they have similar group name with difference of case sensitivity
|
1831
|
+
if found_group != group
|
1832
|
+
change_groups[group] = found_group
|
1833
|
+
GoodData.logger.warn("Group with name #{group} is existed in project with name #{found_group}.")
|
1834
|
+
end
|
1835
|
+
end
|
1836
|
+
end
|
1762
1837
|
if options[:create_non_existing_user_groups]
|
1763
1838
|
missing_groups.each do |g|
|
1764
1839
|
GoodData.logger.info("Creating group #{g}")
|
@@ -1771,7 +1846,7 @@ module GoodData
|
|
1771
1846
|
"#{groups.join(',')} and you asked for #{missing_groups.join(',')}"
|
1772
1847
|
end
|
1773
1848
|
end
|
1774
|
-
current_user_groups
|
1849
|
+
[current_user_groups, change_groups]
|
1775
1850
|
end
|
1776
1851
|
|
1777
1852
|
# Update user
|
@@ -1902,6 +1977,20 @@ module GoodData
|
|
1902
1977
|
[user, roles]
|
1903
1978
|
end
|
1904
1979
|
|
1980
|
+
def upgrade_custom_v2(message, options = {})
|
1981
|
+
uri = "/gdc/md/#{pid}/datedimension/upgrade"
|
1982
|
+
poll_result = client&.post(uri, message)
|
1983
|
+
|
1984
|
+
return poll_result['wTaskStatus']['status'] if poll_result['wTaskStatus'] && poll_result['wTaskStatus']['status']
|
1985
|
+
|
1986
|
+
polling_uri = poll_result['asyncTask']['link']['poll']
|
1987
|
+
result = client&.poll_on_response(polling_uri, options) do |body|
|
1988
|
+
body && body['wTaskStatus'] && body['wTaskStatus']['status'] == 'RUNNING'
|
1989
|
+
end
|
1990
|
+
|
1991
|
+
result['wTaskStatus']['status'] == 'OK' ? 'OK' : 'FAIL'
|
1992
|
+
end
|
1993
|
+
|
1905
1994
|
def add
|
1906
1995
|
@add ||= GoodData::AutomatedDataDistribution.new(self)
|
1907
1996
|
@add
|
@@ -1,51 +1,51 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
+
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
+
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
1
|
+
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
|
@@ -1,109 +1,109 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
+
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
+
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
1
|
+
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
|
109
|
+
3pSK3Q==
|