gooddata 2.1.10-java → 2.1.15-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/CHANGELOG.md +29 -0
- data/Dockerfile +5 -3
- 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/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 +3 -3
- 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/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/lcm2.rb +1 -2
- data/lib/gooddata/lcm/types/base_type.rb +0 -2
- data/lib/gooddata/models/blueprint/project_blueprint.rb +0 -2
- data/lib/gooddata/models/data_source.rb +662 -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 +121 -13
- data/lib/gooddata/models/user_filters/user_filter_builder.rb +0 -1
- data/lib/gooddata/models/user_group.rb +0 -1
- data/rubydev_public.gpg.encrypted +51 -51
- data/rubydev_secret_keys.gpg.encrypted +109 -109
- metadata +14 -10
@@ -5,7 +5,6 @@
|
|
5
5
|
# LICENSE file in the root directory of this source tree.
|
6
6
|
|
7
7
|
require 'cgi'
|
8
|
-
require 'active_support/core_ext/hash/compact'
|
9
8
|
|
10
9
|
require_relative 'profile'
|
11
10
|
require_relative '../extensions/enumerable'
|
@@ -241,7 +240,7 @@ module GoodData
|
|
241
240
|
|
242
241
|
all_users
|
243
242
|
else
|
244
|
-
find_user_by_login(domain, id)
|
243
|
+
find_user_by_login(domain, id, opts)
|
245
244
|
end
|
246
245
|
end
|
247
246
|
|
@@ -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?
|
@@ -13,7 +13,6 @@ require 'zip'
|
|
13
13
|
require 'net/smtp'
|
14
14
|
|
15
15
|
require 'active_support/core_ext/hash/except'
|
16
|
-
require 'active_support/core_ext/hash/compact'
|
17
16
|
require 'active_support/core_ext/hash/slice'
|
18
17
|
|
19
18
|
require_relative '../exceptions/no_project_error'
|
@@ -261,21 +260,26 @@ module GoodData
|
|
261
260
|
# @option ads_output_stage_uri Uri of the source output stage. It must be in the same domain as the target project.
|
262
261
|
def transfer_processes(from_project, to_project, options = {})
|
263
262
|
options = GoodData::Helpers.symbolize_keys(options)
|
263
|
+
aliases = {}
|
264
264
|
to_project_processes = to_project.processes
|
265
265
|
additional_hidden_params = options[:additional_hidden_params] || {}
|
266
266
|
result = from_project.processes.uniq(&:name).map do |process|
|
267
|
-
fail "The process name #{process.name} must be unique in
|
267
|
+
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
268
|
next if process.type == :dataload || process.add_v2_component?
|
269
|
+
collect_process_aliases(process.data, from_project.client, aliases)
|
269
270
|
|
270
271
|
to_process = to_project_processes.find { |p| p.name == process.name }
|
271
272
|
|
273
|
+
data_sources = GoodData::Helpers.symbolize_keys_recursively!(process.data_sources)
|
274
|
+
data_sources = replace_data_source_ids(data_sources, to_project.client, aliases)
|
272
275
|
to_process = if process.path
|
273
276
|
to_process.delete if to_process
|
274
|
-
|
277
|
+
Process.deploy_from_appstore(process.path, name: process.name, client: to_project.client, project: to_project, data_sources: data_sources)
|
275
278
|
elsif process.component
|
276
279
|
to_process.delete if to_process
|
277
280
|
process_hash = GoodData::Helpers::DeepMergeableHash[GoodData::Helpers.symbolize_keys(process.to_hash)].deep_merge(additional_hidden_params)
|
278
|
-
|
281
|
+
process_hash = replace_process_data_source_ids(process_hash, to_project.client, aliases)
|
282
|
+
Process.deploy_component(process_hash, project: to_project, client: to_project.client)
|
279
283
|
else
|
280
284
|
Dir.mktmpdir('etl_transfer') do |dir|
|
281
285
|
dir = Pathname(dir)
|
@@ -283,11 +287,10 @@ module GoodData
|
|
283
287
|
File.open(filename, 'w') do |f|
|
284
288
|
f << process.download
|
285
289
|
end
|
286
|
-
|
287
290
|
if to_process
|
288
|
-
to_process.deploy(filename, type: process.type, name: process.name)
|
291
|
+
to_process.deploy(filename, type: process.type, name: process.name, data_sources: data_sources)
|
289
292
|
else
|
290
|
-
to_project.deploy_process(filename, type: process.type, name: process.name)
|
293
|
+
to_project.deploy_process(filename, type: process.type, name: process.name, data_sources: data_sources)
|
291
294
|
end
|
292
295
|
end
|
293
296
|
end
|
@@ -318,6 +321,78 @@ module GoodData
|
|
318
321
|
result.compact
|
319
322
|
end
|
320
323
|
|
324
|
+
def collect_process_aliases(process_data, client, aliases)
|
325
|
+
data_sources = process_data.dig('process', 'dataSources')
|
326
|
+
unless data_sources.blank?
|
327
|
+
data_sources.map do |data_source|
|
328
|
+
get_data_source_alias(data_source['id'], client, aliases)
|
329
|
+
end
|
330
|
+
end
|
331
|
+
component = process_data.dig('process', 'component')
|
332
|
+
get_data_source_alias(component['configLocation']['dataSourceConfig']['id'], client, aliases) if component&.dig('configLocation', 'dataSourceConfig')
|
333
|
+
aliases
|
334
|
+
end
|
335
|
+
|
336
|
+
def get_data_source_alias(data_source_id, client, aliases)
|
337
|
+
unless aliases[data_source_id]
|
338
|
+
data_source = GoodData::DataSource.from_id(data_source_id, client: client)
|
339
|
+
if data_source&.dig('dataSource', 'alias')
|
340
|
+
aliases[data_source_id] = {
|
341
|
+
:type => get_data_source_type(data_source),
|
342
|
+
:alias => data_source['dataSource']['alias']
|
343
|
+
}
|
344
|
+
end
|
345
|
+
end
|
346
|
+
aliases[data_source_id]
|
347
|
+
end
|
348
|
+
|
349
|
+
def get_data_source_type(data_source_data)
|
350
|
+
data_source_data&.dig('dataSource', 'connectionInfo') ? data_source_data['dataSource']['connectionInfo'].first[0].upcase : ""
|
351
|
+
end
|
352
|
+
|
353
|
+
def replace_process_data_source_ids(process_data, client, aliases)
|
354
|
+
component = process_data.dig(:process, :component)
|
355
|
+
if component&.dig(:configLocation, :dataSourceConfig)
|
356
|
+
the_alias = aliases[component[:configLocation][:dataSourceConfig][:id]]
|
357
|
+
process_data[:process][:component][:configLocation][:dataSourceConfig][:id] = verify_data_source_alias(the_alias, client)
|
358
|
+
end
|
359
|
+
process_data[:process][:dataSources] = replace_data_source_ids(process_data[:process][:dataSources], client, aliases)
|
360
|
+
process_data
|
361
|
+
end
|
362
|
+
|
363
|
+
def replace_data_source_ids(data_sources, client, aliases)
|
364
|
+
array_data_sources = []
|
365
|
+
if data_sources && !data_sources.empty?
|
366
|
+
data_sources.map do |data_source|
|
367
|
+
new_id = verify_data_source_alias(aliases[data_source[:id]], client)
|
368
|
+
array_data_sources.push(:id => new_id)
|
369
|
+
end
|
370
|
+
end
|
371
|
+
array_data_sources
|
372
|
+
end
|
373
|
+
|
374
|
+
# Verify whether the data source exists in the domain using its alias
|
375
|
+
#
|
376
|
+
# @param [String] ds_alias The data source's alias
|
377
|
+
# @param [Object] client The Rest Client object
|
378
|
+
# @return [String] Id of the data source or failed with the reason
|
379
|
+
def verify_data_source_alias(ds_alias, client)
|
380
|
+
domain = client.connection.server.url
|
381
|
+
fail "The data source alias is empty, check your data source configuration." unless ds_alias
|
382
|
+
|
383
|
+
uri = "/gdc/dataload/dataSources/internal/availableAlias?alias=#{ds_alias[:alias]}"
|
384
|
+
res = client.get(uri)
|
385
|
+
fail "Unable to get information about the Data Source '#{ds_alias[:alias]}' in the domain '#{domain}'" unless res
|
386
|
+
fail "Unable to find the #{ds_alias[:type]} Data Source '#{ds_alias[:alias]}' in the domain '#{domain}'" if res['availableAlias']['available']
|
387
|
+
|
388
|
+
ds_type = res['availableAlias']['existingDataSource']['type']
|
389
|
+
if ds_type && ds_type != ds_alias[:type]
|
390
|
+
fail "Wrong Data Source type - the '#{ds_type}' type is expected but the Data Source '#{ds_alias[:alias]}' in the domain '#{domain}' has the '#{ds_alias[:type]}' type"
|
391
|
+
else
|
392
|
+
res['availableAlias']['existingDataSource']['id']
|
393
|
+
end
|
394
|
+
end
|
395
|
+
|
321
396
|
def transfer_user_groups(from_project, to_project)
|
322
397
|
from_project.user_groups.map do |ug|
|
323
398
|
# migrate groups
|
@@ -625,6 +700,7 @@ module GoodData
|
|
625
700
|
def blueprint(options = {})
|
626
701
|
options = { include_ca: true }.merge(options)
|
627
702
|
result = client.get("/gdc/projects/#{pid}/model/view", params: { includeDeprecated: true, includeGrain: true, includeCA: options[:include_ca] })
|
703
|
+
|
628
704
|
polling_url = result['asyncTask']['link']['poll']
|
629
705
|
model = client.poll_on_code(polling_url, options)
|
630
706
|
bp = GoodData::Model::FromWire.from_wire(model, options)
|
@@ -1606,14 +1682,19 @@ module GoodData
|
|
1606
1682
|
def import_users(new_users, options = {})
|
1607
1683
|
role_list = roles
|
1608
1684
|
users_list = users
|
1609
|
-
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! } }
|
1610
1685
|
|
1611
1686
|
GoodData.logger.warn("Importing users to project (#{pid})")
|
1687
|
+
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! } }
|
1688
|
+
# First check that if groups are provided we have them set up
|
1689
|
+
user_groups_cache, change_groups = check_groups(new_users.map(&:to_hash).flat_map { |u| u[:user_group] || [] }.uniq, options[:user_groups_cache], options)
|
1612
1690
|
|
1613
|
-
|
1691
|
+
unless change_groups.empty?
|
1692
|
+
new_users.each do |user|
|
1693
|
+
user[:user_group].map! { |e| change_groups[e].nil? ? e : change_groups[e] }
|
1694
|
+
end
|
1695
|
+
end
|
1614
1696
|
|
1615
|
-
|
1616
|
-
user_groups_cache = check_groups(new_users.map(&:to_hash).flat_map { |u| u[:user_group] || [] }.uniq, options[:user_groups_cache], options)
|
1697
|
+
whitelisted_new_users, whitelisted_users = whitelist_users(new_users.map(&:to_hash), users_list, options[:whitelists])
|
1617
1698
|
|
1618
1699
|
# conform the role on list of new users so we can diff them with the users coming from the project
|
1619
1700
|
diffable_new_with_default_role = whitelisted_new_users.map do |u|
|
@@ -1760,7 +1841,20 @@ module GoodData
|
|
1760
1841
|
def check_groups(specified_groups, user_groups_cache = nil, options = {})
|
1761
1842
|
current_user_groups = user_groups if user_groups_cache.nil? || user_groups_cache.empty?
|
1762
1843
|
groups = current_user_groups.map(&:name)
|
1763
|
-
missing_groups =
|
1844
|
+
missing_groups = []
|
1845
|
+
change_groups = {}
|
1846
|
+
specified_groups.each do |group|
|
1847
|
+
found_group = groups.find { |name| name.casecmp(group).zero? }
|
1848
|
+
if found_group.nil?
|
1849
|
+
missing_groups << group
|
1850
|
+
else
|
1851
|
+
# Change groups when they have similar group name with difference of case sensitivity
|
1852
|
+
if found_group != group
|
1853
|
+
change_groups[group] = found_group
|
1854
|
+
GoodData.logger.warn("Group with name #{group} is existed in project with name #{found_group}.")
|
1855
|
+
end
|
1856
|
+
end
|
1857
|
+
end
|
1764
1858
|
if options[:create_non_existing_user_groups]
|
1765
1859
|
missing_groups.each do |g|
|
1766
1860
|
GoodData.logger.info("Creating group #{g}")
|
@@ -1773,7 +1867,7 @@ module GoodData
|
|
1773
1867
|
"#{groups.join(',')} and you asked for #{missing_groups.join(',')}"
|
1774
1868
|
end
|
1775
1869
|
end
|
1776
|
-
current_user_groups
|
1870
|
+
[current_user_groups, change_groups]
|
1777
1871
|
end
|
1778
1872
|
|
1779
1873
|
# Update user
|
@@ -1904,6 +1998,20 @@ module GoodData
|
|
1904
1998
|
[user, roles]
|
1905
1999
|
end
|
1906
2000
|
|
2001
|
+
def upgrade_custom_v2(message, options = {})
|
2002
|
+
uri = "/gdc/md/#{pid}/datedimension/upgrade"
|
2003
|
+
poll_result = client&.post(uri, message)
|
2004
|
+
|
2005
|
+
return poll_result['wTaskStatus']['status'] if poll_result['wTaskStatus'] && poll_result['wTaskStatus']['status']
|
2006
|
+
|
2007
|
+
polling_uri = poll_result['asyncTask']['link']['poll']
|
2008
|
+
result = client&.poll_on_response(polling_uri, options) do |body|
|
2009
|
+
body && body['wTaskStatus'] && body['wTaskStatus']['status'] == 'RUNNING'
|
2010
|
+
end
|
2011
|
+
|
2012
|
+
result['wTaskStatus']['status'] == 'OK' ? 'OK' : 'FAIL'
|
2013
|
+
end
|
2014
|
+
|
1907
2015
|
def add
|
1908
2016
|
@add ||= GoodData::AutomatedDataDistribution.new(self)
|
1909
2017
|
@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
|
+
5UICsw==
|